From: tomo Date: Thu, 1 Oct 1998 00:09:43 +0000 (+0000) Subject: This commit was manufactured by cvs2svn to create branch X-Git-Url: http://git.chise.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=413d2dc6ed4b4ccd961d79c9a52ba5c23714eea1;p=elisp%2Fgnus.git- This commit was manufactured by cvs2svn to create branch 'unlabeled-1.10.2.1.2.9.2'. --- diff --git a/ChangeLog b/ChangeLog deleted file mode 100644 index 79ba6f2..0000000 --- a/ChangeLog +++ /dev/null @@ -1,1414 +0,0 @@ -1998-09-30 MORIOKA Tomohiko - - * lisp/gnus-sum.el: Abolish variable - `gnus-structured-field-decoder' and - `gnus-unstructured-field-decoder'. - (gnus-nov-parse-line): Don't decode from and subject. - (gnus-get-newsgroup-headers): Likewise. - - * lisp/nnheader.el (make-full-mail-header): Decode subject and - from; changed to inline function. - -1998-09-30 MORIOKA Tomohiko - - * lisp/gnus-sum.el (gnus-get-newsgroup-headers): Store - content-type. - -1998-09-30 MORIOKA Tomohiko - - * lisp/gnus.el (gnus-version-number): Update to 6.9.2. - - * lisp/mmgnus.el: New module. - - * lisp/gnus-art.el (gnus-article-prepare): Use content of - `gnus-current-headers' as mime-message-structure. - -1998-09-30 MORIOKA Tomohiko - - * lisp/gnus.el (gnus-version-number): Update to 6.9.1. - (gnus-version): Modify for Chao 1.11. - - * lisp/nnheader.el (make-full-mail-header): Changed to macro. - -1998-09-30 MORIOKA Tomohiko - - * lisp/gnus.el (gnus-version): Modify for Chao 1.10. - - * lisp/gnus-score.el (gnus-header-index): Modify to use - mime-entity structure as gnus-header structure. - - * lisp/nnheader.el: Use `mime-entity' as gnus-header structure. - (mail-header-number): Use `mime-entity-location-internal'. - (mail-header-set-number): Use `mime-entity-set-location-internal'. - - Change other `mail-header-*' and `mail-header-set-*' to alias of - reference and set functions for mime-entity-internal. - (make-full-mail-header): Use `make-mime-entity-internal'. - -1998-09-30 MORIOKA Tomohiko - - * lisp/message.el (message-reply): Use `make-full-mail-header'. - (message-followup): Likewise. - - * lisp/nnheader.el (mail-header-references): Use - `mime-fetch-field' and `mail-header-entity'. - (mail-header-set-references): Use `mail-header-set-field'. - Define mm-backend `nil' and its method `fetch-field'. - (make-full-mail-header): Modify data structure to store References - to mime-entity. - -1998-09-29 MORIOKA Tomohiko - - * lisp/nnheader.el (mail-header-id): Use `mime-fetch-field' and - `mail-header-entity'. - (mail-header-set-id): Use `mail-header-set-field'. - (make-full-mail-header): Modify data structure to store Message-Id - to mime-entity. - -1998-09-29 MORIOKA Tomohiko - - * lisp/nnheader.el (mail-header-entity): New macro. - (mail-header-set-entity): New macro. - (mail-header-set-field): New macro. - (mail-header-set-parsed-field): New macro. - (mail-header-subject): Use `mail-header-entity'. - (mail-header-set-subject): Use `mail-header-set-parsed-field'. - (mail-header-from): Use `mail-header-entity'. - (mail-header-set-from): Use `mail-header-set-parsed-field'. - (mail-header-date): Use `mime-fetch-field' and - `mail-header-entity'. - (mail-header-set-date): Use `mail-header-set-field'. - (make-full-mail-header): Modify data structure to store Date to - mime-entity. - (make-mail-header): Use `make-full-mail-header'. - -1998-09-29 MORIOKA Tomohiko - - * lisp/nnheader.el (mail-header-from): Use `mime-read-field'. - (mail-header-set-from): Store to mime-entity. - (make-full-mail-header): Modify data structure to store Subject to - mime-entity. - -1998-09-29 MORIOKA Tomohiko - - * lisp/nnheader.el (mail-header-subject): Use `mime-read-field'. - (mail-header-set-subject): Store to mime-entity. - (make-full-mail-header): Modify data structure to store Subject to - mime-entity. - -1998-09-29 MORIOKA Tomohiko - - * lisp/gnus-sum.el (gnus-update-summary-mark-positions): Use - `make-full-mail-header'. - -1998-09-30 MORIOKA Tomohiko - - * lisp/message.el (message-make-user-agent): New implementation. - -1998-08-25 Shuhei KOBAYASHI - - * lisp/gnus-msg.el (gnus-bug-message): About Semi-gnus. - (gnus-extended-version): Return gnus version only. - (gnus-bug): Add Semi-gnus developers to recipients. - - * lisp/message.el (message-make-user-agent): New function. - (message-generate-headers): Use it. - -1998-06-12 Shuhei KOBAYASHI - - * lisp/message.el (message-required-news-headers): `X-Newsreader' - was replaced by `User-Agent'. - (message-required-mail-headers): `X-Mailer' was replaced by - `User-Agent'. - (message-header-format-alist): `X-Mailer' and `X-Newsreader' were - replaced by `User-Agent'. - (message-generate-headers): Ditto. - - (message-user-agent): New variable. - (message-newsreader): Replaced by `message-user-agent'. - (message-mailer): Ditto. - (message-mode): `message-mailer' and `message-newsreader' were - replaced by `message-user-agent'. - - * lisp/gnus-msg.el (gnus-inews-add-send-actions): `message-mailer' - and `message-newsreader' were replaced by `message-user-agent'. - (gnus-extended-version): Generate "PRODUCT/VERSION" style strings. - - * lisp/gnus-soup.el (gnus-soup-send-packet): `message-mailer' and - `message-newsreader' were replaced by `message-user-agent'. - -1998-09-29 MORIOKA Tomohiko - - * lisp/gnus-sum.el (gnus-get-newsgroup-headers): Use - `make-full-mail-header'. - -1998-09-26 Katsumi Yamaoka - - * lisp/gnus.el (gnus-version-number): Update to 6.8.19. - - * Sync up with Gnus 5.6.44. - -1998-09-16 Katsumi Yamaoka - - * Makefile.in: Add entry `info-ja'. - * texi/Makefile.in: Add entry `ja'. - -1998-09-11 MORIOKA Tomohiko - - * lisp/message.el (message-send): Don't call - `message-fix-before-sending' before `message-encode-function' is - called. - -1998-09-06 Tatsuya Ichikawa - - * lisp/pop3-fma.el: Add error handle and fix typo. - -1998-08-28 Keiichi Suzuki - - * lisp/message.el: Repair `multi frame control'. - -1998-08-27 Tatsuya Ichikawa - - * lisp/gnus.el (gnus-version-number): Update to 6.8.16. - - * Sync up with Gnus 5.6.41. - -1998-08-26 Katsumi Yamaoka - - * lisp/gnus-spec.el (gnus-parse-simple-format): Use - `gnus-tilde-pad-form' instead of the padding faculty of `format' - under XEmacs-mule. - - * lisp/gnus-xmas.el - (gnus-xmas-redefine): Redifine `gnus-truncate-string', - `gnus-tilde-max-form' and `gnus-tilde-cut-form' for XEmacs-mule. - (gnus-xmas-define): New function 'gnus-tilde-pad-form' for - XEmacs-mule. - -1998-08-26 Shuhei KOBAYASHI - - * lisp/gnus-art.el (gnus-article-narrow-to-signature): - Removed TM stuff. - (gnus-article-display-mime-message): - Set `mime-button-mother-dispatcher' in correct buffer. - (gnus-url-mailto): Use `gnus-setup-message'. - (gnus-button-mailto): Ditto. - (gnus-button-reply): Ditto. - - * lisp/gnus-ems.el (gnus-mule-max-width-function): Removed. - (gnus-truncate-string): Use `truncate-string-to-width' if available. - (gnus-tilde-max-form): New implementation. - (gnus-tilde-cut-form): Ditto. - - * lisp/gnus-msg.el (gnus-summary-mail-digest): New function. - (gnus-summary-post-digest): New function. - - * lisp/gnus-sum.el (gnus-summary-make-menu-bar): Use - `gnus-summary-mail-digest' and `gnus-summary-post-digest' instead - of `gnus-uu-digest-mail-forward' and `gnus-uu-digest-post-forward'. - - * lisp/gnus-util.el (gnus-truncate-string): Ignore more than two - arguments. - - * lisp/message.el (message-forward-end-separator): Use - `text/plain' tag. - -1998-08-23 Shuhei KOBAYASHI - - * lisp/message.el: Suppress some byte-compile warnings. - (message-make-forward-subject): Failed to sync. - (message-setup): Ditto. - (message-clone-locals): Modify regexp. - -1998-08-23 Shuhei KOBAYASHI - - * lisp/gnus-agent.el (gnus-agent-braid-nov): Use - `nnheader-insert-file-contents'. - - * lisp/gnus-i18n.el (gnus-set-summary-default-charset): Sync up - with "akr" branch. - -1998-08-23 Tatsuya Ichikawa - - * lisp/gnus.el (gnus-version-number): Update to 6.8.15. - - * Sync up with Gnus 5.6.39. - - * lisp/pop3-fma.el (pop3-fma-movemail): Enable to get from APOP server. - (pop3-fma-set-pop3-password) Enable to get from APOP server. - -1998-08-20 Yoshiki Hayashi - - * lisp/message.el (message-clone-locals): Add `user-full-name' - and `user-mail-address' to regexp. - -1998-08-20 Tatsuya Ichikawa - - * lisp/gnus.el (gnus-version-number): Update to 6.8.14. - - * Sync up with Gnus 5.6.38. - -1998-08-20 Keiichi Suzuki - - * lisp/message.el (message-frames): New custom group. - (message-original-frame): New variable. - (message-use-multi-frames): New variable. - (message-delete-frame-on-exit): New variable. - (message-send-and-exit): Delete frame which made for editing - message. - (message-kill-buffer): Ditto. - (message-delete-frame): New function. - (message-pop-to-buffer): Make new frame when edit message. - -1998-08-18 Tatsuya Ichikawa - - * lisp/gnus.el (gnus-version-number): Update to 6.8.13. - - * Sync up with Gnus 5.6.37. - -1998-08-16 Yoshiki Hayashi - - * lisp/gnus-sum.el (gnus-summary-scroll-down): Failed to sync. - -1998-08-16 Tatsuya Ichikawa - - * lisp/gnus.el (gnus-version-number): Update to 6.8.12. - - * Sync up with Gnus 5.6.36. - -1998-08-15 Yoshiki Hayashi - - * texi/gnus-ja.texi: Update. - -1998-08-14 Katsumi Yamaoka - - * lisp/gnus-start.el (gnus-save-newsrc-file): Bind - `coding-system-for-write' by `gnus-startup-file-coding-system' - while saving the quick newsrc file. - - * lisp/gnus-start.el (gnus-startup-file-coding-system): Change - default value to `ctext'. - -1998-08-13 Tatsuya Ichikawa - - * lisp/gnus.el (gnus-version-number): Fix typo. - - * lisp/gnus.el (gnus-version-number): Update to 6.8.11. - - * Sync up with Gnus 5.6.34. - -1998-08-12 Tatsuya Ichikawa - - * lisp/gnus.el (gnus-version-number): Update to 6.8.10. - - * Sync up with Gnus 5.6.33. - -1998-08-11 Tatsuya Ichikawa - - * lisp/gnus.el (gnus-version-number): Update to 6.8.9. - - * Sync up with Gnus 5.6.31. - -1998-08-10 Tatsuya Ichikawa - - * lisp/gnus.el (gnus-version-number): Update to 6.8.8. - - * Sync up with Gnus 5.6.30. - -1998-08-10 Keiichi Suzuki - - * lisp/message.el (message-yank-original): For citing any message. - -1998-08-10 Shuhei KOBAYASHI - - * lisp/gnus.el (gnus-version-number): Update to 6.8.7. - -1998-08-06 Katsumi Yamaoka - - *lisp/smtp.el: Do not insert empty line at the end of message. - -1998-08-06 Tatsuya Ichikawa - - * lisp/gnus.el (gnus-version-number): Update to 6.8.6. - - * Sync up with Gnus 5.6.29. - -1998-08-05 Tatsuya Ichikawa - - * lisp/gnus-start.el (gnus-read-init-file): Fix indent. - * lisp/gnus-ems.el (gnus-tilde-max-form): Redefine instead of - (gnus-summary-line-format-spec) to display Japanese character - correctly in Gnus summaly. - -1998-08-05 Keiichi Suzuki - - * lisp/gnus-start.el (gnus-read-init-file): Don't restrict - `coding-system-for-read' by `binary' when loading `.gnus'. - -1998-08-04 Tatsuya Ichikawa - - * lisp/gnus.el (gnus-version-number): Update to 6.8.5. - - * Sync up with Gnus 5.6.28. - -1998-07-27 Tatsuya Ichikawa - - * lisp/gnus.el (gnus-version-number): Update to 6.8.4. - - * Sync up with Gnus 5.6.27. - -1998-07-27 Yoshiki Hayashi - - * texi/message-ja.texi: Japanese translation of "message.texi". - -1998-07-26 Tatsuya Ichikawa - - * lisp/gnus.el (gnus-version-number): Update to 6.8.3. - - * Sync up with Gnus 5.6.26. - -1998-07-23 Shuhei KOBAYASHI - - * lisp/gnus.el (gnus-version-number): Update to 6.8.2. - (gnus-version): Change to "Semi-gnus". Change comment format. - -1998-07-21 Keisuke Mori - - * texi/gnus-ja.texi: Add "Appendices". - -1998-07-21 Yoshiki Hayashi - - * texi/gnus-ja.texi: Add "Appendices". - -1998-07-16 Shuhei KOBAYASHI - - * lisp/gnus.el (gnus-version-number): Update to 6.8.1. - - * Sync up with Gnus 5.6.24. - -1998-07-10 Keiichi Suzuki - - * lisp/gnus-ems.el (gnus-mule-cite-add-face): Fix problem when multi - bytes charactors are used in cite prefix. (for Emacs 20.1 and 20.2) - (gnus-ems-redefine): for Emacs 20.1 and 20.2 - - * lisp/gnus-cite.el (gnus-cite-add-face): Abolish my last bogus change. - -1998-07-09 Keiichi Suzuki - - * lisp/gnus-cite.el (gnus-cite-add-face): Fix problem when multi - bytes charactors are used in cite prefix. - -1998-07-07 Yoshiki Hayashi - - * texi/gnus-ja.texi: Add "The End". - -1998-07-06 Keisuke Mori - - * texi/gnus-ja.texi: Add "Various". - -1998-07-06 Yoshiki Hayashi - - * texi/gnus-ja.texi: Add "Various". - * texi/gnus-ja.texi: Sync up with Gnus 5.6.22 - -1998-07-02 MORIOKA Tomohiko - - * lisp/message.el (message-header-format-alist): Repair to use - `message-fill-references' for References. - -1998-07-01 MORIOKA Tomohiko - - * lisp/gnus-art.el (gnus-article-header-presentation-method): - Delete nil optional arguments. - - Delete setting for `mime-raw-representation-type-alist'. - -1998-07-01 MORIOKA Tomohiko - - * lisp/gnus.el (gnus-version-number): Update to 6.8.0. - (gnus-version): Modify for FLIM 1.8. - - * lisp/gnus-art.el (gnus-article-header-presentation-method): - Modify for FLIM 1.8. - -1998-06-30 Keisuke Mori - - * texi/gnus-ja.texi: Add "Scroing". - -1998-06-30 Yoshiki Hayashi - - * texi/gnus-ja.texi: Add "Scoring". - -1998-06-30 Tatsuya Ichikawa - - * Sync up with Gnus 5.6.22 - * lisp/gnus.el (gnus-version-number): Update to 6.7.8. - * lisp/pop3-fma.el : Enable to get localhost mail spool. - -1998-06-29 MORIOKA Tomohiko - - * lisp/gnus.el (gnus-version-number): Update to 6.7.7. - - * lisp/gnus-art.el (gnus-article-prepare): Set up - `gnus-article-current-summary' of gnus-article-buffer. - (gnus-request-article-this-buffer): Don't set up - `gnus-article-current-summary'. - -1998-06-27 MORIOKA Tomohiko - - * lisp/gnus.el (gnus-version-number): Update to 6.7.6. - -1998-06-27 MORIOKA Tomohiko - - * lisp/gnus-art.el (gnus-mime-preview-quitting-method): Renamed - from `mime-preview-quitting-method-for-gnus'. - -1998-06-27 MORIOKA Tomohiko - - * lisp/gnus-sum.el (gnus-summary-preview-mime-message): New - implementation. - - * lisp/gnus-art.el (mime-preview-quitting-method-for-gnus): Use - `gnus-article-show-summary' is `gnus-show-mime' is not nil. - -1998-06-27 MORIOKA Tomohiko - - * texi/ChangeLog, texi/gnus.texi, texi/message.texi, - lisp/ChangeLog, lisp/gnus.el, lisp/nngateway.el, lisp/nnfolder.el, - lisp/message.el, lisp/gnus-sum.el, lisp/gnus-soup.el: Sync up with - Gnus 5.6.20. - -1998-06-26 MORIOKA Tomohiko - - * README, texi/ChangeLog, texi/gnus.texi, texi/message.texi, - lisp/ChangeLog, lisp/nnweb.el, lisp/nnmail.el, lisp/nndoc.el, - lisp/message.el, lisp/lpath.el, lisp/gnus.el, lisp/gnus-util.el, - lisp/gnus-topic.el, lisp/gnus-sum.el, lisp/gnus-score.el, - lisp/gnus-group.el, lisp/gnus-ems.el, lisp/gnus-demon.el, - lisp/gnus-art.el: Sync up with Gnus 5.6.16. - -1998-06-26 MORIOKA Tomohiko - - * lisp/gnus.el (gnus-version-number): Update to 6.7.3. - - * lisp/gnus-sum.el (gnus-summary-move-article): Use - `gnus-request-article-this-buffer'. - (gnus-request-partial-message): Likewise. - - * lisp/gnus-art.el (gnus-article-prepare): Use - `gnus-request-article-this-buffer'. - (gnus-request-article-this-buffer): Renamed from - `gnus-request-original-article'; abolish conventional - implementation. - - Abolish unused setting for `mime-view-show-summary-method'. - -1998-06-26 MORIOKA Tomohiko - - * readme, texi/ChangeLog, texi/gnus.texi, texi/message.texi, - lisp/ChangeLog, lisp/gnus.el, lisp/nnmail.el, lisp/nnheader.el, - lisp/nngateway.el, lisp/nnfolder.el, lisp/nnagent.el, - lisp/message.el, lisp/gnus-sum.el, lisp/gnus-score.el, - lisp/gnus-salt.el, lisp/gnus-msg.el, lisp/gnus-cus.el, - lisp/gnus-cache.el, lisp/gnus-art.el: Sync up with Gnus 5.6.15. - -1998-06-24 MORIOKA Tomohiko - - * texi/gnus.texi, texi/message.texi, texi/ChangeLog: Sync up with - Gnus 5.6.13. - -1998-06-14 Tatsuya Ichikawa - - * Sync up with Gnus 5.6.13. - -1998-06-24 MORIOKA Tomohiko - - * lisp/gnus-art.el (gnus-article-display-mime-message): Don't - `save-excursion'. - (gnus-article-prepare): Use `mime-fetch-field' instead of - `mime-entity-fetch-field'. - -1998-06-19 MORIOKA Tomohiko - - * lisp/gnus-art.el (gnus-article-display-mime-message): Use - `mime-display-message' instead of `mime-view-buffer'. - (gnus-article-display-traditional-message): Set - `gnus-article-buffer'. - (gnus-article-display-message-with-encoded-word): Modify for - `gnus-article-display-traditional-message'. - (gnus-article-prepare): Use `mime-parse-buffer' and - `mime-entity-fetch-field'; don't set gnus-article-buffer. - -1998-06-19 MORIOKA Tomohiko - - * lisp/gnus-sum.el (gnus-summary-move-article): Use - `gnus-request-original-article' instead of - `gnus-request-article-this-buffer'. - -1998-06-19 MORIOKA Tomohiko - - * texi/gnus-ja.texi, texi/gnus.texi (Using MIME): Modify - description about new display mechanism. - -1998-06-19 MORIOKA Tomohiko - - * lisp/gnus.el (gnus-version-number): Update to 6.6.0. - (gnus-version): Modify for this branch. - - * lisp/gnus-art.el (gnus-article-display-method-for-mime): New - variable; abolish `gnus-show-mime-method'. - (gnus-article-display-method-for-encoded-word): New variable; - abolish `gnus-decode-encoded-word-method'. - (gnus-article-display-method-for-traditional): New variable. - (gnus-article-display-mime-message): New function; abolish - `gnus-article-preview-mime-message'. - (gnus-article-display-traditional-message): New function. - (gnus-article-display-message-with-encoded-word): New function; - abolish `gnus-article-decode-encoded-word'. - (gnus-article-prepare): Change display mechanism; use - `gnus-request-original-article' instead of - `gnus-request-article-this-buffer'. - (gnus-request-original-article): New function. - -1998-06-22 MORIOKA Tomohiko - - * lisp/gnus.el (gnus-version-number): Update to 6.6.0. - (gnus-version): Modify for SEMI 1.8. - - * lisp/gnus-sum.el: Modify for interface change in SEMI 1.8 about - automatic message/partial combining. - -1998-06-19 MORIOKA Tomohiko - - * lisp/gnus.el (gnus-version-number): Update to 6.5.0. - (gnus-version): Modify for SEMI 1.7. - - * lisp/gnus-sum.el: Rename - `mime-method-to-combine-message/partial-pieces' to - `mime-combine-message/partial-pieces-automatically'. - - * lisp/gnus-art.el (gnus-article-preview-mime-message): Use - `mime-view-buffer'. - (gnus-article-decode-encoded-word): Fix DOC-string. - (gnus-article-header-presentation-method): New function; abolish - `gnus-content-header-filter'. - Modify for SEMI 1.7. - -1998-06-18 Keisuke Mori - - * texi/gnus-ja.texi: Add "Select Methods". - -1998-06-18 Yoshiki Hayashi - - * texi/gnus-ja.texi: Add "Select Methods". - -1998-06-17 Tatsuya Ichikawa - - * lisp/pop3-fma.el: Small bug fix. - - * lisp/pop3-fma.el: Delete variable pop3-fma-cypher-key - Use base64-encode-string , base64-decode-string instead. - Both change by Yasuo OKABE - -1998-06-13 Tatsuya Ichikawa - - * lisp/pop3-fma.el: New function pop3-fma-cypher-string - New variable pop3-fma-cypher-key - -1998-06-07 MORIOKA Tomohiko - - * lisp/gnus-art.el: Delete setting for - `article-de-quoted-unreadable' and - `article-mime-decode-quoted-printable' because they have been - already abolished. - -1998-06-07 MORIOKA Tomohiko - - * texi/gnus-ja.texi: Sync up with latest gnus.texi. - - * texi/gnus.texi: Modify for Semi-gnus 6.4.0. - -1998-06-06 MORIOKA Tomohiko - - * lisp/gnus.el (gnus-extract-address-components): Add - `std11-extract-address-components' as a choice. - -1998-06-06 Yoshiki Hayashi - - * texi/gnus-ja.texi: Add "Composing Messages". - -1998-06-04 MORIOKA Tomohiko - - * lisp/gnus-ems.el (gnus-ems-redefine): Must require 'path-util - before call `module-installed-p'. - - * lisp/gnus.el (gnus-version-number): Update to 6.4.0. - (gnus-version): Modify for SEMI 1.5. - - * lisp/gnus-art.el: Modify for SEMI 1.5 API. - -1998-06-04 Tatsuya Ichikawa - - * lisp/pop3-fma.el: New file. To handle multiple POP account. - - * lisp/gnus.el (gnus-version-number): Update to 6.3.4. - And fix typo 5.6.10 -> 5.6.11. - -1998-06-03 Shuhei KOBAYASHI - - * lisp/gnus.el (gnus-version-number): Update to 6.3.3. - - * Sync up with Gnus 5.6.11. - -1998-06-03 Keisuke Mori - - * texi/gnus-ja.texi: Add "The Article Buffer". - -1998-06-03 Yoshiki Hayashi - - * texi/gnus-ja.texi: Add "The Summary Buffer". - -1998-06-02 Tatsuya Ichikawa - - * lisp/gnus.el (gnus-version-number): Update to 6.3.2. - - * Sync up with Gnus 5.6.10. - -1998-05-30 Shuhei KOBAYASHI - - * README.semi: Add description of `shuhei-k' branch. - -1998-05-17 MORIOKA Tomohiko - - * lisp/gnus.el (gnus-version-number): Update to 6.3.1. - -1998-05-17 MORIOKA Tomohiko - - * lisp/gnus-util.el (gnus-output-to-rmail): Guard as binary. - - * lisp/gnus-util.el (gnus-output-to-mail): Guard as binary. - -1998-04-24 Yoshiki Hayashi - - * texi/gnus-ja.texi: Add "The Active File". - -1998-05-04 MORIOKA Tomohiko - - * lisp/gnus.el (gnus-version-number): Update to 6.3.0. - (gnus-version): Modify for SEMI 1.4. - - * lisp/gnus-sum.el: Use 'mime-add-condition to set up - acting-condition. - -1998-05-04 MORIOKA Tomohiko - - * lisp/lpath.el: Must add "flim" instead of "mel" to load-path. - -1998-05-03 MORIOKA Tomohiko - - * lisp/gnus.el (gnus-version-number): Update to 6.2.5. - - * texi/gnus.texi, lisp/ChangeLog: Sync up with Gnus v5.6.9. - - * lisp/gnus.el, lisp/message.el, lisp/gnus-sum.el, - lisp/gnus-msg.el, lisp/gnus-draft.el, lisp/gnus-agent.el: Sync up - with Gnus v5.6.9. - -1998-04-30 MORIOKA Tomohiko - - * lisp/gnus.el (gnus-version-number): Update to 6.2.4. - - * texi/gnus.texi, lisp/ChangeLog: Sync up with Gnus 5.6.7. - - * lisp/gnus.el, lisp/message.el, lisp/gnus-sum.el, - lisp/gnus-msg.el, lisp/gnus-cache.el, lisp/gnus-art.el: Sync up - with Gnus 5.6.7. - -1998-04-28 Shuhei KOBAYASHI - - * lisp/gnus.el (gnus-version-number): Update to 6.2.3. - - * Sync up with Gnus 5.6.6. - -1998-04-27 MORIOKA Tomohiko - - * lisp/nnheader.el: Sync up with Gnus 5.6.5. - -1998-04-26 Shuhei KOBAYASHI - - * lisp/gnus.el (gnus-version-number): Update to 6.2.2. - - * Sync up with Gnus 5.6.5. - - * texi/custom.texi, texi/widget.texi: Removed from Semi-gnus. - -1998-04-25 MORIOKA Tomohiko - - * README.semi (How to get? (via CVS)): Modify descriptions about - TAG. - -1998-04-23 MORIOKA Tomohiko - - * lisp/gnus.el (gnus-version-number): Update to 6.2.1. - -1998-04-23 MORIOKA Tomohiko - - * lisp/message.el (message-make-forward-subject): Use - `eword-decode-unstructured-field-body' for subject. - - * lisp/gnus-msg.el (gnus-summary-mail-forward): Make local - variable `default-mime-charset' of `gnus-original-article-buffer' - and set up by `default-mime-charset' of `gnus-summary-buffer'. - -1998-04-23 MORIOKA Tomohiko - - * texi/gnus-ja.texi: Fix typos. - - * texi/gnus.texi: Modify for Semi-gnus. - -1998-04-23 Yoshiki Hayashi - - * texi/gnus-ja.texi: Add "Auto Save". - -1998-04-22 Yoshiki Hayashi - - * texi/gnus-ja.texi: Add "Startup Files". - -1998-04-21 MORIOKA Tomohiko - - * lisp/gnus.el (gnus-version-number): Update to 6.2.0. - (gnus-version): Modify for SEMI 1.3. - - * lisp/gnus-sum.el: Use 'ctree-set-calist-strictly instead of - 'set-atype to set up for 'mime-acting-condition. - -1998-04-21 Yoshiki Hayashi - - * texi/gnus-ja.texi: Add "Changing Servers". - -1998-04-20 MORIOKA Tomohiko - - * texi/gnus-ja.texi: Modify styles. - - * texi/gnus.texi: Modify for Semi-gnus (sync up with - gnus-ja.texi). - -1998-04-20 Yoshiki Hayashi - - * texi/gnus-ja.texi: Add "New Groups". - -1998-04-20 Yoshiki Hayashi - - * texi/gnus-ja.texi: Modify styles. - -1998-04-18 MORIOKA Tomohiko - - * texi/gnus-ja.texi: Check and modify for Semi-gnus. - -1998-04-18 Yoshiki Hayashi - - * texi/gnus-ja.texi: New file. - -1998-04-19 MORIOKA Tomohiko - - * lisp/gnus.el (gnus-version-number): Update to 6.1.3. - -1998-04-19 MORIOKA Tomohiko - - * lisp/gnus-art.el (gnus-following-method): New function; set up - for 'mime-view-following-method-alist. - -1998-04-18 MORIOKA Tomohiko - - * texi/gnus.texi: Add and modify description for Semi-gnus. - -1998-04-16 MORIOKA Tomohiko - - * texi/gnus.texi: "Gnus 5.6.4" -> "Semi-gnus 6.1.2". - (Top): "Gnus" -> "gnus". - (Starting Up): "Gnus" -> "gnus". - -1998-04-10 Shuhei KOBAYASHI - - * lisp/ChangeLog, lisp/gnus-agent.el: Sync up with Gnus 5.6.4. - -1998-04-08 MORIOKA Tomohiko - - * lisp/gnus.el (gnus-version-number): Update to 6.1.2. - (gnus-version): Include corresponding SEMI version. - - * lisp/gnus.el, lisp/nnkiboze.el, lisp/message.el, - lisp/gnus-sum.el, lisp/gnus-agent.el: Sync up with Gnus 5.6.4. - -1998-03-27 Shuhei KOBAYASHI - - * README.semi: Change descriptions of sending bug report. - -1998-03-20 Shuhei KOBAYASHI - - * lisp/gnus.el (gnus-version-number): Update to 6.1.1. - (gnus-version): Include corresponding SEMI version. - - * Sync up with Gnus 5.6.3. - -1998-03-15 Shuhei KOBAYASHI - - * lisp/gnus-agent.el (gnus-agent-crosspost): Use - `nnheader-insert-file-contents'. - (gnus-agent-braid-nov): Ditto. - (gnus-agent-expire): Ditto. - - * lisp/gnus-cache.el (gnus-cache-request-article): Ditto. - (gnus-cache-retrieve-headers): Ditto. - (gnus-cache-change-buffer): Ditto. - (gnus-cache-braid-nov): Ditto. - - * lisp/gnus-sum.el (gnus-summary-import-article): Ditto. - - * lisp/nnkiboze.el (nnkiboze-retrieve-headers): Ditto. - - * lisp/message.el (message-generate-headers): Fix regexp. - (cf. [semi-gnus-ja:107]) - -1998-03-14 MORIOKA Tomohiko - - * lisp/gnus-art.el: Add setting for - `mime-raw-buffer-coding-system-alist'. - -1998-03-13 MORIOKA Tomohiko - - * lisp/gnus-art.el: Rename `mime-view-quitting-method-for-gnus' -> - `mime-preview-quitting-method-for-gnus'. - - * lisp/gnus-art.el: Rename `mime-view-quitting-method-alist' -> - `mime-preview-quitting-method-alist'. - - * lisp/gnus-art.el: Rename `mime-view-kill-buffer' -> - `mime-preview-kill-buffer'. - - * lisp/gnus.el (gnus-version-number): Update to 6.0.10. - - * lisp/gnus-sum.el: Add code to check latest SEMI. - (mime-acting-condition): Separate type and subtype; rename - `mime-combine-message/partials-automatically' -> - `mime-method-to-combine-message/partial-pieces'. - -1998-03-08 Shuhei KOBAYASHI - - * lisp/gnus.el (gnus-version-number): Update to 6.0.9. - - * README.semi (How to get?): Add description of daily snapshot. - (How to join development): Change mailing list command address. - - * Sync up with Gnus 5.6.2. - -1998-03-01 Tatsuya Ichikawa - - * lisp/gnus-ems.el: Change variable name - gnus-bdf-image-file to gnus-mule-bitmap-image-file. - -1998-02-28 MORIOKA Tomohiko - - * lisp/gnus.el (gnus-version-number): Update to 6.0.8. - - * lisp/gnus.el: Sync up with qgnus-0.34. - -1998-02-28 MORIOKA Tomohiko - - * lisp/message.el: Sync up with qgnus-0.33. - - * lisp/gnus-ems.el (gnus-bdf-image-file): New variable; moved from - gnus.el. - (gnus-mule-group-startup-message): New function; moved and renamed - from `gnus-group-startup-message' of gnus.el. - - * lisp/gnus.el, lisp/gnus-sum.el, lisp/gnus-art.el, - lisp/gnus-agent.el: Sync up with qgnus-0.33. - -1998-02-28 Tatsuya Ichikawa - - * lisp/gnus.el (gnus-bdf-image-file): New variable. - (gnus-mule-group-startup-message): Display bitmap image using - bitmap.el running with Emacs 20. - - * lisp/gnus-agent.el (gnus-agent-fetch-headers): Fix problem when - Xref field is not exist. - -1998-02-26 MORIOKA Tomohiko - - * README.semi (How to join development): Modify for Semi-gnus - mailing list. - - * lisp/gnus.el (gnus-version-number): Update to 6.0.7. - - * lisp/gnus.el (gnus-article-display-hook): Delete - `gnus-article-de-quoted-unreadable' from options. - - * lisp/gnus-sum.el (gnus-article-make-menu-bar): Delete key for - `gnus-article-de-quoted-unreadable'. - (gnus-summary-make-menu-bar): Delete menu for - `gnus-article-de-quoted-unreadable'. - - * lisp/gnus-art.el (gnus-article-make-menu-bar): Delete menu for - `gnus-article-de-quoted-unreadable'. - -1998-02-24 MORIOKA Tomohiko - - * lisp/gnus.el, lisp/message.el: Sync up with qgnus-0.32. - -1998-02-23 MORIOKA Tomohiko - - * lisp/gnus.el (gnus-version-number): Update to 6.0.6. - - * lisp/message.el (message-fill-references): Abolish unused local - variables. - - * lisp/pop3.el, lisp/message.el, lisp/gnus.el, lisp/gnus-sum.el, - lisp/gnus-art.el: Sync up with qgnus-0.31. - - * lisp/gnus.el, lisp/message.el, lisp/gnus-sum.el, - lisp/gnus-art.el: Sync up with qgnus-0.30. - -1998-02-20 Christophe Broult - - * README.semi (How to get?): The command `update' must come before - `-r semi-gnus'. (cf. [tm-en:1559]) - -1998-02-17 MORIOKA Tomohiko - - * lisp/gnus.el: Sync up with qgnus-0.29. - - * lisp/gnus.el, lisp/message.el: Sync up with qgnus-0.28. - - * lisp/message.el: Abolish variable - `message-references-generator'. Abolish function - `message-generate-filled-references', - `message-generate-folded-references' and - `message-generate-unfolded-references'. - (message-reply): Don't use `message-references-generator'. - (message-followup): Don't use `message-references-generator'. - - (message-fill-references): New function. - (message-header-format-alist): Use `message-fill-references' for - References. - -1998-02-17 MORIOKA Tomohiko - - * lisp/gnus.el (gnus-version-number): Update to 6.0.5. - -1998-02-17 MORIOKA Tomohiko - - * lisp/gnus-sum.el: Check SEMI-0.118.2 (Otomaru) or later. - (gnus-structured-field-decoder): Use - `eword-decode-and-unfold-structured-field'. - - * lisp/gnus-art.el (gnus-article-decode-rfc1522): Use charset - conversion option of `eword-decode-header'. - (gnus-article-decode-encoded-word): Use charset conversion option - of `eword-decode-header'; use `gnus-run-hooks'. - (gnus-content-header-filter): Use charset conversion option of - `eword-decode-header'. - - * README.semi (How to get?): Should specify "-r semi-gnus". - -1998-02-16 MORIOKA Tomohiko - - * lisp/gnus-art.el (gnus-article-decode-rfc1522): Decode header by - localized code. - -1998-02-16 MORIOKA Tomohiko - - * lisp/gnus-msg.el: Delete commented-out function - `gnus-inews-insert-mime-headers'. - - * lisp/gnus.el, lisp/message.el, lisp/gnus-sum.el, - lisp/gnus-art.el: Sync up with qgnus-0.27. - -1998-02-16 MORIOKA Tomohiko - - * lisp/nnheader.el: Use original. - - * lisp/gnus.el, lisp/pop3.el, lisp/message.el, lisp/gnus-sum.el, - lisp/gnus-msg.el, lisp/gnus-draft.el, lisp/gnus-art.el: Sync up - with qgnus-0.26. - -1998-02-15 MORIOKA Tomohiko - - * lisp/nnmail.el, lisp/nnmh.el: Use original. - - * lisp/gnus.el, lisp/gnus-draft.el, lisp/gnus-sum.el, - lisp/message.el, lisp/gnus-art.el: Sync up with qgnus-0.25. - -1998-02-11 Shuhei Kobayashi - - * texi/message.texi, texi/gnus.texi, texi/ChangeLog, - lisp/message.el, lisp/gnus.el, lisp/gnus-uu.el, - lisp/gnus-topic.el, lisp/gnus-sum.el, lisp/gnus-start.el, - lisp/gnus-score.el, lisp/gnus-group.el, lisp/gnus-art.el, - lisp/gnus-agent.el, lisp/ChangeLog: Importing qgnus-0.24 - -1998-02-10 MORIOKA Tomohiko - - * lisp/gnus-art.el (gnus-article-prepare): Don't bind coding - systems. - - * lisp/gnus.el (gnus-version-number): Update to 6.0.4. - (gnus-version): Sync with qgnus-0.23. - - * lisp/pop3.el, lisp/nnmh.el, lisp/nnheader.el, lisp/message.el, - lisp/gnus-sum.el, lisp/gnus-msg.el, lisp/gnus-draft.el, - lisp/gnus-art.el: Merge qgnus-0.23. - -1998-02-09 Shuhei Kobayashi - - * texi/message.texi, texi/gnus.texi, texi/ChangeLog, lisp/nntp.el, - lisp/nnheader.el, lisp/message.el, lisp/gnus.el, - lisp/gnus-xmas.el, lisp/gnus-sum.el, lisp/gnus-start.el, - lisp/gnus-msg.el, lisp/gnus-group.el, lisp/gnus-draft.el, - lisp/gnus-art.el, lisp/gnus-agent.el, lisp/ChangeLog: Importing - qgnus-0.23 - -1998-02-04 MORIOKA Tomohiko - - * lisp/message.el (message-references-generator): New variable. - (message-generate-filled-references): New function. - (message-generate-folded-references): New function. - (message-generate-unfolded-references): New function. - (message-reply): Refer `message-references-generator'. - (message-followup): Refer `message-references-generator'. - -1998-01-17 MORIOKA Tomohiko - - * lisp/message.el (message-send-mail-with-sendmail): Guard - `coding-system-for-write' by binary. - (message-send-mail-with-qmail): Likewise. - -1998-01-16 MORIOKA Tomohiko - - * lisp/lpath.el: Require path-util; add load-path of APEL, MEL and - SEMI. - -1998-01-12 MORIOKA Tomohiko - - * lisp/message.el: Require smtp.el when compile. - - * lisp/message.el (message-send-mail-with-smtp): Use - `(current-buffer)' instead of `tembuf'; rename - `smtp-recipient-address-list' -> `recipient-address-list'. - -1998-01-12 MORIOKA Tomohiko - - * lisp/smtp.el (smtp-deduce-address-list): Don't use - `smtp-recipient-address-list' as global variable. - - * lisp/message.el (message-send-mail-with-smtp): Don't use - `smtp-recipient-address-list' as global variable. - - * lisp/smtpmail.el (smtpmail-recipient-address-list): New - variable; renamed from `smtp-recipient-address-list'. - (smtpmail-send-it): Remove `(not (null ...))'. - (smtpmail-send-queued-mail): Likewise. - -1998-01-12 MORIOKA Tomohiko - - * lisp/message.el (message-send-mail-with-smtp): Don't generate - temporary buffer for message; don't generate and kill - `smtp-address-buffer' for `smtp-deduce-address-list'. - - * lisp/smtpmail.el (smtpmail-send-it): Don't generate and kill - `smtp-address-buffer' for `smtp-deduce-address-list'. - - * lisp/smtp.el (smtp-deduce-address-list): Bind and generate - `smtp-address-buffer' in itself. - -1998-01-12 MORIOKA Tomohiko - - * lisp/gnus.el (gnus-version-number): Update to version 6.0.3. - -1998-01-11 MORIOKA Tomohiko - - * lisp/smtp.el: New file. - - * lisp/smtpmail.el: Split basic features into smtp.el. - - * lisp/message.el (message-send-mail-function): Add - `message-send-mail-with-smtp' as an item. - (message-send-mail-with-smtp): New function. - - * ChangeLog: New file. - -1998-01-08 MORIOKA Tomohiko - - * lisp/smtpmail.el (smtpmail-via-smtp): Bind - `coding-system-for-read' by `smtpmail-coding-system' to avoid - dead-locking in Emacs 20. - - * lisp/gnus.el: gnus.el (gnus-version-number): Update to version - 6.0.2. - -1998-01-07 MORIOKA Tomohiko - - * lisp/nnmail.el, lisp/message.el: Sync with Quassia Gnus v0.22. - - * lisp/gnus.el: Delete autoload setting for `metamail-buffer'. - - * lisp/gnus.el, lisp/gnus-sum.el: Sync with Quassia Gnus v0.22. - - * lisp/gnus-msg.el: Abolish function - `gnus-inews-insert-mime-headers'. - - * lisp/gnus-msg.el, lisp/gnus-draft.el, lisp/gnus-art.el: Sync - with Quassia Gnus v0.22. - - * lisp/smtpmail.el (smtpmail-coding-system): New variable; abolish - `smtpmail-code-conv-from'. - (smtpmail-via-smtp): Guard `coding-system-for-write' by - `smtpmail-coding-system'. - - * lisp/smtpmail.el: Imported from Emacs 20.2. - - * lisp/pop3.el (pop3-movemail-file-coding-system): Change default - value to `binary'. - (pop3-open-server): Guard `coding-system-for-read' by `binary'. - -1998-01-06 Shuhei Kobayashi - - * texi/message.texi, texi/gnus.texi, texi/ChangeLog, lisp/nnoo.el, - lisp/nnml.el, lisp/message.el, lisp/gnus.el, lisp/gnus-sum.el, - lisp/gnus-start.el, lisp/gnus-ems.el, lisp/gnus-draft.el, - lisp/gnus-agent.el, lisp/ChangeLog: Importing qgnus-0.22 - - * texi/message.texi, texi/gnus.texi, lisp/gnus.el, lisp/ChangeLog: - Importing qgnus-0.21 - - * texi/message.texi, texi/gnus.texi, texi/ChangeLog, - lisp/nnvirtual.el, lisp/nnsoup.el, lisp/nnoo.el, lisp/nnmh.el, - lisp/nnmail.el, lisp/nndraft.el, lisp/gnus.el, lisp/gnus-xmas.el, - lisp/gnus-sum.el, lisp/gnus-start.el, lisp/gnus-score.el, - lisp/gnus-msg.el, lisp/gnus-group.el, lisp/gnus-draft.el, - lisp/gnus-art.el, lisp/ChangeLog: Importing qgnus-0.20 - - * texi/message.texi, texi/gnus.texi, texi/ChangeLog, lisp/pop3.el, - lisp/nntp.el, lisp/nnml.el, lisp/nnmail.el, lisp/nndoc.el, - lisp/message.el, lisp/gnus.el, lisp/gnus-uu.el, - lisp/gnus-topic.el, lisp/gnus-sum.el, lisp/gnus-start.el, - lisp/gnus-score.el, lisp/gnus-group.el, lisp/gnus-cache.el, - lisp/gnus-agent.el, lisp/ChangeLog: Importing qgnus-0.19 - -1997-12-27 MORIOKA Tomohiko - - * lisp/gnus.el (gnus-version-number): Update to version 6.0.1. - - * lisp/message.el (message-resend): Enclose `message-setup' with - `(let (message-setup-hook) ...)' to avoid to `turn-on-mime-edit'; - must setup `message-encoding-buffer' and `message-edit-buffer' for - `message-send-mail'. - -1997-12-08 Shuhei Kobayashi - - * lisp/pop3.el, lisp/message.el, lisp/gnus.el, lisp/gnus-sum.el, - lisp/gnus-art.el, lisp/ChangeLog: Synch'ed up to qgnus-0.18. - - * texi/message.texi, texi/gnus.texi, texi/ChangeLog, - lisp/smiley.el, lisp/pop3.el, lisp/nnweb.el, lisp/nntp.el, - lisp/nnml.el, lisp/nnmail.el, lisp/nnheader.el, lisp/nndraft.el, - lisp/message.el, lisp/lpath.el, lisp/gnus.el, lisp/gnus-util.el, - lisp/gnus-sum.el, lisp/gnus-start.el, lisp/gnus-picon.el, - lisp/gnus-nocem.el, lisp/gnus-mh.el, lisp/gnus-group.el, - lisp/gnus-ems.el, lisp/gnus-cite.el, lisp/gnus-art.el, - lisp/gnus-agent.el, lisp/dgnushack.el, lisp/ChangeLog: Importing - qgnus-0.18 - -1997-11-29 MORIOKA Tomohiko - - * README.semi: New file. - - * lisp/gnus.el (gnus-version): Rename to "Semi-gnus". - -1997-11-28 MORIOKA Tomohiko - - * lisp/gnus-draft.el (gnus-draft-decoding-function): New variable. - (gnus-draft-setup): Use `gnus-draft-decoding-function'. - -1997-11-27 MORIOKA Tomohiko - - * lisp/nnmail.el, lisp/nnheader.el, lisp/message.el, lisp/gnus.el, - lisp/gnus-sum.el, lisp/gnus-msg.el, lisp/gnus-art.el: sync with - qgnus-0.17. - - * texi/message.texi, texi/gnus.texi, lisp/smiley.el, lisp/nnoo.el, - lisp/nnml.el, lisp/nnmail.el, lisp/nnheader.el, - lisp/messagexmas.el, lisp/message.el, lisp/gnus.el, - lisp/gnus-xmas.el, lisp/gnus-util.el, lisp/gnus-sum.el, - lisp/gnus-start.el, lisp/gnus-spec.el, lisp/gnus-score.el, - lisp/gnus-picon.el, lisp/gnus-move.el, lisp/gnus-msg.el, - lisp/gnus-kill.el, lisp/gnus-group.el, lisp/gnus-draft.el, - lisp/gnus-demon.el, lisp/gnus-cite.el, lisp/gnus-art.el, - lisp/ChangeLog: Quassia Gnus v0.17. - - * lisp/gnus-i18n.el: New file. - - * lisp/nnmail.el (nnmail-file-coding-system): Use `raw-text' in - default. - - * lisp/nnheader.el (nnheader-file-coding-system): Use `raw-text' - in default. - - * lisp/message.el (message-encode-function): New variable. - (message-forward-start-separator): Modify for mime-edit. - (message-forward-end-separator): Modify for mime-edit. - (message-setup-hook): Use `(message-maybe-setup-default-charset - turn-on-mime-edit)' in default. - (message-header-hook): Use `(eword-encode-header)' in default. - - (message-send): Use local variable `message-encoding-buffer', - `message-edit-buffer' and `message-mime-mode' as public variables; - use `message-encode-function'. - (message-send-mail): Use `message-encoding-buffer' to get contents - of body; abolish `message-encode-mail-hook'; use - `mime-edit-maybe-split-and-send'; use `message-edit-buffer' to - refer original editing buffer. - (message-send-news): Use `message-encoding-buffer' to get contents - of body; abolish `message-encode-news-hook'; use - `mime-edit-maybe-split-and-send'; use `message-edit-buffer' to - refer original editing buffer. - (message-check-news-syntax): Call `message-check-news-body-syntax' - in `mime-edit-buffer'. - (message-do-fcc): Use `message-encoding-buffer' to get contents; - run `message-header-hook'. - (message-cancel-news): Use `std11-extract-address-components' - instead of `mail-extract-address-components'; bind - `message-encoding-buffer' and `message-edit-buffer'. - - (message-maybe-setup-default-charset): New function. - (message-maybe-encode): New function. - (message-mime-insert-article): New function. - Add setting for mime-view. - - * lisp/gnus.el (gnus-version-number): for version number for Open - gnus. - (gnus-version): Modify for Open gnus. - - * lisp/gnus-sum.el: Autoload gnus-i18n. - - (gnus-show-mime): `t' in default. - (gnus-structured-field-decoder): Use - `eword-decode-structured-field-body' in default. - (gnus-unstructured-field-decoder): Use - `eword-decode-unstructured-field-body' in default. - - (gnus-parse-headers-hook): Use - `(gnus-set-summary-default-charset)' in default. - - (gnus-summary-mode-map): Add binding for - `gnus-summary-scroll-down' and - `gnus-summary-preview-mime-message'. - - (gnus-summary-preview-mime-message): New function. - (gnus-mime-partial-preview-function): New function. - Add setting for mime-view. - - * lisp/gnus-msg.el (gnus-summary-cancel-article): Display - `gnus-article-buffer' instead ofb `gnus-original-article-buffer'. - (gnus-extended-version): Don't return version of emacsen. - (gnus-inews-do-gcc): Refer `message-encoding-buffer'. - - * lisp/gnus-art.el (gnus-show-mime-method): Use - `gnus-article-preview-mime-message' instead of `metamail-buffer' - in default. - (gnus-decode-encoded-word-method): Use - `gnus-article-decode-encoded-word' instead of - `gnus-article-de-quoted-unreadable' in default. - - Abolish `gnus-hack-decode-rfc1522', `gnus-decode-rfc1522', - `article-decode-rfc1522', `article-de-quoted-unreadable', - `article-mime-decode-quoted-printable-buffer' and - `article-mime-decode-quoted-printable'. - (gnus-article-decode-rfc1522): New implementation (use - `eword-decode-header'). - - (gnus-article-preview-mime-message): New function. - (gnus-article-decode-encoded-word): New function. - (gnus-content-header-filter): New function. - (mime-view-quitting-method-for-gnus): New function. - Add setting for mime-view. - - * lisp/message.el: Abolish `message-max-size' because it is not - used. - - * lisp/message.el: sync with qgnus-0.16. - - * texi/Makefile, texi/message.texi, texi/gnus.texi, lisp/nnweb.el, - lisp/nnmh.el, lisp/nnheader.el, lisp/nnfolder.el, lisp/message.el, - lisp/gnus.el, lisp/gnus-xmas.el, lisp/gnus-uu.el, - lisp/gnus-sum.el, lisp/gnus-srvr.el, lisp/gnus-picon.el, - lisp/gnus-group.el, lisp/gnus-cite.el, lisp/gnus-art.el: Quassia - Gnus v0.16. - - * lisp/nnmh.el (nnmh-request-list-1): fix maybe. - - * lisp/message.el (message-do-fcc): Guard - `coding-system-for-write' by `raw-text'; run - `message-before-do-fcc-hook'. - - * lisp/gnus-msg.el (gnus-inews-do-gcc): Guard - `coding-system-for-write' by `raw-text'; run - `gnus-before-do-gcc-hook'. - - * texi/message.texi, texi/gnus.texi, texi/ChangeLog, lisp/nntp.el, - lisp/nnoo.el, lisp/nnml.el, lisp/nndraft.el, lisp/nnbabyl.el, - lisp/message.el, lisp/gnus.el, lisp/gnus-xmas.el, lisp/gnus-uu.el, - lisp/gnus-util.el, lisp/gnus-sum.el, lisp/gnus-start.el, - lisp/gnus-spec.el, lisp/gnus-soup.el, lisp/gnus-score.el, - lisp/gnus-msg.el, lisp/gnus-gl.el, lisp/gnus-ems.el, - lisp/gnus-draft.el, lisp/gnus-cache.el, lisp/gnus-audio.el, - lisp/gnus-art.el, lisp/gnus-agent.el, lisp/ChangeLog: Quassia Gnus - v0.15. - - * lisp/message.el, lisp/ChangeLog: sync with qgnus-0.14. - - * texi/Makefile, texi/gnus.texi: Quassia Gnus v0.14. - - * texi/dir: New file. - - * texi/dir, lisp/pop3.el, lisp/nntp.el, lisp/nnml.el, - lisp/nnmail.el, lisp/nnfolder.el, lisp/message.el, lisp/lpath.el, - lisp/gnus.el, lisp/gnus-win.el, lisp/gnus-util.el, - lisp/gnus-topic.el, lisp/gnus-sum.el, lisp/gnus-start.el, - lisp/gnus-score.el, lisp/gnus-msg.el, lisp/gnus-mh.el, - lisp/gnus-cus.el, lisp/gnus-art.el, lisp/gnus-agent.el, - lisp/ChangeLog: Quassia Gnus v0.14. - - * lisp/message.el, lisp/ChangeLog: sync with qgnus-0.13. - - * texi/gnus.texi, texi/ChangeLog, lisp/pop3.el, lisp/nnweb.el, - lisp/nnmail.el: Quassia Gnus v0.13. - - * lisp/nnlistserv.el: New file. - - * lisp/nnlistserv.el, lisp/message.el, lisp/md5.el, lisp/lpath.el, - lisp/gnus.el, lisp/gnus-topic.el, lisp/gnus-sum.el, - lisp/gnus-score.el, lisp/gnus-picon.el, lisp/gnus-msg.el, - lisp/gnus-group.el, lisp/gnus-art.el, lisp/gnus-agent.el, - lisp/dgnushack.el, lisp/ChangeLog, GNUS-NEWS: Quassia Gnus v0.13. - - * lisp/message.el: sync with qgnus-0.12. - - * texi/message.texi, texi/gnus.texi, texi/gnus-faq.texi, - texi/ChangeLog, lisp/nntp.el, lisp/nnmh.el, lisp/nnmail.el, - lisp/nndraft.el, lisp/messcompat.el, lisp/message.el, - lisp/gnus.el, lisp/gnus-xmas.el, lisp/gnus-uu.el, - lisp/gnus-sum.el, lisp/gnus-score.el, lisp/gnus-salt.el, - lisp/gnus-msg.el, lisp/gnus-int.el, lisp/gnus-group.el, - lisp/gnus-demon.el, lisp/gnus-cache.el, lisp/gnus-art.el, - lisp/gnus-agent.el, lisp/ChangeLog, GNUS-NEWS: Quassia Gnus v0.12. - - * lisp/message.el (message-send-news-function): Use - `message-send-news-with-gnus' in default. - (message-send-via-news): Use `message-send-news' instead of - `message-send-news-function'. - (message-send-mail): Don't avoid text properties; run - `message-encode-mail-hook'. - (message-send-news): Don't avoid text properties; run - `message-encode-news-hook'; use `message-send-news-function'. - (message-send-news-with-gnus): New function. - (message-cancel-news): Use `message-send-news' instead of - `message-send-news-function'. diff --git a/GNUS-NEWS b/GNUS-NEWS deleted file mode 100644 index 0c5b11a..0000000 --- a/GNUS-NEWS +++ /dev/null @@ -1,102 +0,0 @@ -** Gnus changes. - -*** The Gnus distribution no longer bundles Custom and Widget. -If your Emacs doesn't come with these libraries, fetch them from -. You also then need to -add the following to the lisp/dgnushack.el file: - - (push "~/lisp/custom" load-path) - -Modify to suit your needs. - -*** New functionality for using Gnus as an offline newsreader has been -added. A plethora of new commands and modes have been added. See the -Gnus manual for the full story. - -*** The nndraft backend has returned, but works differently than -before. All Message buffers are now also articles in the nndraft -group, which is created automatically. - -*** `gnus-alter-header-function' can now be used to alter header -values. - -*** `gnus-summary-goto-article' now accept Message-ID's. - -*** A new Message command for deleting text in the body of a message -outside the region: `C-c C-v'. - -*** You can now post to component group in nnvirtual groups with -`C-u C-c C-c'. - -*** `nntp-rlogin-program' -- new variable to ease customization. - -*** `C-u C-c C-c' in `gnus-article-edit-mode' will now inhibit -re-highlighting of the article buffer. - -*** New element in `gnus-boring-article-headers' -- `long-to'. - -*** `M-i' symbolic prefix command. See the section "Symbolic -Prefixes" in the Gnus manual for details. - -*** `L' and `I' in the summary buffer now take the symbolic prefix -`a' to add the score rule to the "all.SCORE" file. - -*** `gnus-simplify-subject-functions' variable to allow greater -control over simplification. - -*** `A T' -- new command for fetching the current thread. - -*** `/ T' -- new command for including the current thread in the -limit. - -*** `M-RET' is a new Message command for breaking cited text. - -*** \\1-expressions are now valid in `nnmail-split-methods'. - -*** The `custom-face-lookup' function has been removed. -If you used this function in your initialization files, you must -rewrite them to use `face-spec-set' instead. - -*** Cancelling now uses the current select method. Symbolic prefix -`a' forces normal posting method. - -*** New command to translate M******** sm*rtq**t*s into proper text --- `W d'. - -*** For easier debugging of nntp, you can set `nntp-record-commands' -to a non-nil value. - -*** nntp now uses ~/.authinfo, a .netrc-like file, for controlling -where and how to send AUTHINFO to NNTP servers. - -*** A command for editing group parameters from the summary buffer -has been added. - -*** A history of where mails have been split is available. - -*** A new article date command has been added -- `article-date-iso8601'. - -*** Subjects can be simplified when threading by setting -`gnus-score-thread-simplify'. - -*** A new function for citing in Message has been added -- -`message-cite-original-without-signature'. - -*** `article-strip-all-blank-lines' -- new article command. - -*** A new Message command to kill to the end of the article has -been added. - -*** A minimum adaptive score can be specified by using the -`gnus-adaptive-word-minimum' variable. - -*** The "lapsed date" article header can be kept continually -updated by the `gnus-start-date-timer' command. - -*** Web listserv archives can be read with the nnlistserv backend. - -*** Old dejanews archives can now be read by nnweb. - -*** Byte-compilation of user-specs now works under XEmacs. - -*** `gnus-posting-styles' has been re-activated. diff --git a/Makefile.in b/Makefile.in deleted file mode 100644 index f486fd0..0000000 --- a/Makefile.in +++ /dev/null @@ -1,61 +0,0 @@ -prefix = @prefix@ -datadir = @datadir@ -lispdir = @lispdir@ -srcdir = @srcdir@ - -@SET_MAKE@ -EMACS = @EMACS@ -XEMACS = xemacs - -all: lick info - -lick: - cd lisp && $(MAKE) EMACS=$(EMACS) lispdir=$(lispdir) all - -install: - cd lisp && $(MAKE) EMACS=$(EMACS) lispdir=$(lispdir) install - cd texi && $(MAKE) EMACS=$(EMACS) install - -# Rule for Lars and nobody else. -some: - cd lisp && $(MAKE) EMACS=$(EMACS) some -l: - cd lisp && $(MAKE) EMACS=$(EMACS) clever - -info: - cd texi && $(MAKE) EMACS=$(EMACS) all - -info-ja: - cd texi && $(MAKE) EMACS=$(EMACS) MAKEINFO=no ja - -clean: - rm -f */*.orig */*.rej *.orig *.rej - -xsome: - cd lisp && $(MAKE) EMACS=$(XEMACS) some - -elclean: - rm lisp/*.elc - -x: - make EMACS=xemacs - -distclean: - make clean - rm -rf *~ - for i in lisp texi; do (cd $$i; make distclean); done - rm -f config.log config.status Makefile - -osome: - make EMACS=emacs-19.34 some - -config.status: $(srcdir)/configure - $(SHELL) ./config.status --recheck -$(srcdir)/configure: $(srcdir)/configure.in - cd $(srcdir) && autoconf -Makefile: $(srcdir)/Makefile.in config.status - CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/README b/README deleted file mode 100644 index 9d9d843..0000000 --- a/README +++ /dev/null @@ -1,52 +0,0 @@ -This package contains a beta version of Gnus. The lisp directory -contains the source lisp files, and the texi directory contains a -draft of the Gnus info pages. - -To use Gnus you first have to unpack the files, which you've obviously -done, because you are reading this. - -You should definitely byte-compile the source files. To do that, you -can simply say "./configure && make" in this directory. If you are -using XEmacs, you *must* say "make EMACS=xemacs". In that case you -may also want to pull down the package of nice glyphs from -. It should be installed -into the "gnus-5.6.53/etc" directory. - -Then you have to tell Emacs where Gnus is. You might put something -like - - (setq load-path (cons (expand-file-name "~/gnus-5.6.53/lisp") load-path)) - -in your .emacs file, or wherever you keep such things. - -To enable reading the Gnus manual, you could say something like: - - (setq Info-default-directory-list - (cons "~/gnus-5.6.53/texi" Info-default-directory-list)) - -Note that Gnus and GNUS can't coexist in a single Emacs. They both use -the same function and variable names. If you have been running GNUS -in your Emacs, you should probably exit that Emacs and start a new one -to fire up Gnus. - -Gnus does absolutely not work with anything older than Emacs 19.33 or -XEmacs 19.14. So you definitely need a new Emacs. - -Then you do a `M-x gnus', and everything should... uhm... it should -work, but it might not. Set `debug-on-error' to t, and mail me the -backtraces, or, better yet, find out why Gnus does something wrong, -fix it, and send me the diffs. :-) - -There are four main things I want your help and input on: - -1) Startup. Does everything go smoothly, and why not? - -2) Any errors while you read news normally? - -3) Any errors if you do anything abnormal? - -4) Features you do not like, or do like, but would like to tweak a - bit, and features you would like to see. - -Send any comments and all your bug fixes/complaints to -`bugs@gnus.org'. diff --git a/README.semi b/README.semi deleted file mode 100644 index b297fe7..0000000 --- a/README.semi +++ /dev/null @@ -1,95 +0,0 @@ -This package contains Semi-gnus. - -What is Semi-gnus? -================== - - Semi-gnus is a replacement of Gnus with gnus-mime for SEMI. It has -all features of Gnus and gnus-mime, so there are no need to install -Gnus to use it, and you must not use gnus-mime for SEMI. - - It requires SEMI package, so please get and install SEMI package -before to install it. - - -How to get? (via CVS) -===================== - -(0) cvs login - - % cvs -d :pserver:anonymous@chamonix.jaist.ac.jp:/hare/cvs/root \ - login - - CVS password: [CR] # NULL string - -(1) checkout - - % cvs -d :pserver:anonymous@chamonix.jaist.ac.jp:/hare/cvs/root \ - checkout [-r TAG] gnus - -(2) compile - - % cd gnus - % make EMACS= - -(3) update - - % cvs update [-r TAG] - -Major tags are following: - - semi-gnus assigned to the latest stable version. It is - very conservative. - - for-semi-N1_N2 assigned to the latest stable version for SEMI - API N1.N2 (N1 and N2 are natural number). - (e.g. `for-semi-1_3' is for SEMI API 1.3) - - gnus-N1_N2_N3 assigned to gnus(Gnus) N1.N2.N3 - (e.g. `gnus-6_2_1' means gnus 6.2.1). - - larsi Original Gnus - - himi himi branch - - ichikawa ichikawa branch - - akr akr branch - - shuhei-k shuhei-k branch - Mail-Followup-To/Mail-Reply-To, gnus-cache fix. - - -How to get? (via ftp) -===================== - - Semi-daily snapshots are also available from - - ftp://ftp.jaist.ac.jp/pub/GNU/elisp/semi-gnus/ - - NOTE: These snapshots are automatically created from our repository -if something was changed within a day, and will usually not be tested. - - -How to join development -======================= - - If you have found a bug in Gnus proper, please do `M-x gnus-bug' and -send a bug report to the Gnus maintainers. - - If you have found a bug in Semi-gnus, or if you're not sure whether it -is a Gnus proper, please send a bug report to the Semi-gnus mailing list: - - semi-gnus-en@meadow.scphys.kyoto-u.ac.jp (English) - semi-gnus-ja@meadow.scphys.kyoto-u.ac.jp (Japanese) - -Suggestions for Semi-gnus improvements are also welcome. - - Via the Semi-gnus ML, you can report Semi-gnus related bugs, obtain -the latest release of Semi-gnus, and discuss future enhancements to -Semi-gnus. To join the Semi-gnus ML, send an empty e-mail to - - semi-gnus-en-help@meadow.scphys.kyoto-u.ac.jp (English) - semi-gnus-ja-help@meadow.scphys.kyoto-u.ac.jp (Japanese) - - In addition, we need developers. If you would like to develop it, -please send mail to cvs@chamonix.jaist.ac.jp. diff --git a/aclocal.m4 b/aclocal.m4 deleted file mode 100644 index b56880a..0000000 --- a/aclocal.m4 +++ /dev/null @@ -1,31 +0,0 @@ -# serial 1 - -AC_DEFUN(AM_PATH_LISPDIR, - [# If set to t, that means we are running in a shell under Emacs. - # If you have an Emacs named "t", then use the full path. - test "$EMACS" = t && EMACS= - AC_PATH_PROG(EMACS, emacs xemacs, no) - if test $EMACS != "no"; then - AC_MSG_CHECKING([where .elc files should go]) - dnl Set default value - lispdir="\$(datadir)/emacs/site-lisp" - if test "x$prefix" = "xNONE"; then - if test -d $ac_default_prefix/share/emacs/site-lisp; then - lispdir="\$(prefix)/share/emacs/site-lisp" - else - if test -d $ac_default_prefix/lib/emacs/site-lisp; then - lispdir="\$(prefix)/lib/emacs/site-lisp" - fi - fi - else - if test -d $prefix/share/emacs/site-lisp; then - lispdir="\$(prefix)/share/emacs/site-lisp" - else - if test -d $prefix/lib/emacs/site-lisp; then - lispdir="\$(prefix)/lib/emacs/site-lisp" - fi - fi - fi - AC_MSG_RESULT($lispdir) - fi - AC_SUBST(lispdir)]) diff --git a/configure b/configure deleted file mode 100755 index 41263dc..0000000 --- a/configure +++ /dev/null @@ -1,978 +0,0 @@ -#! /bin/sh - -# Guess values for system-dependent variables and create Makefiles. -# Generated automatically using autoconf version 2.12 -# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc. -# -# This configure script is free software; the Free Software Foundation -# gives unlimited permission to copy, distribute and modify it. - -# Defaults: -ac_help= -ac_default_prefix=/usr/local -# Any additions from configure.in: - -# Initialize some variables set by options. -# The variables have the same names as the options, with -# dashes changed to underlines. -build=NONE -cache_file=./config.cache -exec_prefix=NONE -host=NONE -no_create= -nonopt=NONE -no_recursion= -prefix=NONE -program_prefix=NONE -program_suffix=NONE -program_transform_name=s,x,x, -silent= -site= -srcdir= -target=NONE -verbose= -x_includes=NONE -x_libraries=NONE -bindir='${exec_prefix}/bin' -sbindir='${exec_prefix}/sbin' -libexecdir='${exec_prefix}/libexec' -datadir='${prefix}/share' -sysconfdir='${prefix}/etc' -sharedstatedir='${prefix}/com' -localstatedir='${prefix}/var' -libdir='${exec_prefix}/lib' -includedir='${prefix}/include' -oldincludedir='/usr/include' -infodir='${prefix}/info' -mandir='${prefix}/man' - -# Initialize some other variables. -subdirs= -MFLAGS= MAKEFLAGS= -# Maximum number of lines to put in a shell here document. -ac_max_here_lines=12 - -ac_prev= -for ac_option -do - - # If the previous option needs an argument, assign it. - if test -n "$ac_prev"; then - eval "$ac_prev=\$ac_option" - ac_prev= - continue - fi - - case "$ac_option" in - -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;; - *) ac_optarg= ;; - esac - - # Accept the important Cygnus configure options, so we can diagnose typos. - - case "$ac_option" in - - -bindir | --bindir | --bindi | --bind | --bin | --bi) - ac_prev=bindir ;; - -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) - bindir="$ac_optarg" ;; - - -build | --build | --buil | --bui | --bu) - ac_prev=build ;; - -build=* | --build=* | --buil=* | --bui=* | --bu=*) - build="$ac_optarg" ;; - - -cache-file | --cache-file | --cache-fil | --cache-fi \ - | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) - ac_prev=cache_file ;; - -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ - | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) - cache_file="$ac_optarg" ;; - - -datadir | --datadir | --datadi | --datad | --data | --dat | --da) - ac_prev=datadir ;; - -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ - | --da=*) - datadir="$ac_optarg" ;; - - -disable-* | --disable-*) - ac_feature=`echo $ac_option|sed -e 's/-*disable-//'` - # Reject names that are not valid shell variable names. - if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then - { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } - fi - ac_feature=`echo $ac_feature| sed 's/-/_/g'` - eval "enable_${ac_feature}=no" ;; - - -enable-* | --enable-*) - ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'` - # Reject names that are not valid shell variable names. - if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then - { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } - fi - ac_feature=`echo $ac_feature| sed 's/-/_/g'` - case "$ac_option" in - *=*) ;; - *) ac_optarg=yes ;; - esac - eval "enable_${ac_feature}='$ac_optarg'" ;; - - -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ - | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ - | --exec | --exe | --ex) - ac_prev=exec_prefix ;; - -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ - | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ - | --exec=* | --exe=* | --ex=*) - exec_prefix="$ac_optarg" ;; - - -gas | --gas | --ga | --g) - # Obsolete; use --with-gas. - with_gas=yes ;; - - -help | --help | --hel | --he) - # Omit some internal or obsolete options to make the list less imposing. - # This message is too long to be a string in the A/UX 3.1 sh. - cat << EOF -Usage: configure [options] [host] -Options: [defaults in brackets after descriptions] -Configuration: - --cache-file=FILE cache test results in FILE - --help print this message - --no-create do not create output files - --quiet, --silent do not print \`checking...' messages - --version print the version of autoconf that created configure -Directory and file names: - --prefix=PREFIX install architecture-independent files in PREFIX - [$ac_default_prefix] - --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX - [same as prefix] - --bindir=DIR user executables in DIR [EPREFIX/bin] - --sbindir=DIR system admin executables in DIR [EPREFIX/sbin] - --libexecdir=DIR program executables in DIR [EPREFIX/libexec] - --datadir=DIR read-only architecture-independent data in DIR - [PREFIX/share] - --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc] - --sharedstatedir=DIR modifiable architecture-independent data in DIR - [PREFIX/com] - --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var] - --libdir=DIR object code libraries in DIR [EPREFIX/lib] - --includedir=DIR C header files in DIR [PREFIX/include] - --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include] - --infodir=DIR info documentation in DIR [PREFIX/info] - --mandir=DIR man documentation in DIR [PREFIX/man] - --srcdir=DIR find the sources in DIR [configure dir or ..] - --program-prefix=PREFIX prepend PREFIX to installed program names - --program-suffix=SUFFIX append SUFFIX to installed program names - --program-transform-name=PROGRAM - run sed PROGRAM on installed program names -EOF - cat << EOF -Host type: - --build=BUILD configure for building on BUILD [BUILD=HOST] - --host=HOST configure for HOST [guessed] - --target=TARGET configure for TARGET [TARGET=HOST] -Features and packages: - --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) - --enable-FEATURE[=ARG] include FEATURE [ARG=yes] - --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] - --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) - --x-includes=DIR X include files are in DIR - --x-libraries=DIR X library files are in DIR -EOF - if test -n "$ac_help"; then - echo "--enable and --with options recognized:$ac_help" - fi - exit 0 ;; - - -host | --host | --hos | --ho) - ac_prev=host ;; - -host=* | --host=* | --hos=* | --ho=*) - host="$ac_optarg" ;; - - -includedir | --includedir | --includedi | --included | --include \ - | --includ | --inclu | --incl | --inc) - ac_prev=includedir ;; - -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ - | --includ=* | --inclu=* | --incl=* | --inc=*) - includedir="$ac_optarg" ;; - - -infodir | --infodir | --infodi | --infod | --info | --inf) - ac_prev=infodir ;; - -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) - infodir="$ac_optarg" ;; - - -libdir | --libdir | --libdi | --libd) - ac_prev=libdir ;; - -libdir=* | --libdir=* | --libdi=* | --libd=*) - libdir="$ac_optarg" ;; - - -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ - | --libexe | --libex | --libe) - ac_prev=libexecdir ;; - -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ - | --libexe=* | --libex=* | --libe=*) - libexecdir="$ac_optarg" ;; - - -localstatedir | --localstatedir | --localstatedi | --localstated \ - | --localstate | --localstat | --localsta | --localst \ - | --locals | --local | --loca | --loc | --lo) - ac_prev=localstatedir ;; - -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ - | --localstate=* | --localstat=* | --localsta=* | --localst=* \ - | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) - localstatedir="$ac_optarg" ;; - - -mandir | --mandir | --mandi | --mand | --man | --ma | --m) - ac_prev=mandir ;; - -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) - mandir="$ac_optarg" ;; - - -nfp | --nfp | --nf) - # Obsolete; use --without-fp. - with_fp=no ;; - - -no-create | --no-create | --no-creat | --no-crea | --no-cre \ - | --no-cr | --no-c) - no_create=yes ;; - - -no-recursion | --no-recursion | --no-recursio | --no-recursi \ - | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) - no_recursion=yes ;; - - -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ - | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ - | --oldin | --oldi | --old | --ol | --o) - ac_prev=oldincludedir ;; - -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ - | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ - | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) - oldincludedir="$ac_optarg" ;; - - -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) - ac_prev=prefix ;; - -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) - prefix="$ac_optarg" ;; - - -program-prefix | --program-prefix | --program-prefi | --program-pref \ - | --program-pre | --program-pr | --program-p) - ac_prev=program_prefix ;; - -program-prefix=* | --program-prefix=* | --program-prefi=* \ - | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) - program_prefix="$ac_optarg" ;; - - -program-suffix | --program-suffix | --program-suffi | --program-suff \ - | --program-suf | --program-su | --program-s) - ac_prev=program_suffix ;; - -program-suffix=* | --program-suffix=* | --program-suffi=* \ - | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) - program_suffix="$ac_optarg" ;; - - -program-transform-name | --program-transform-name \ - | --program-transform-nam | --program-transform-na \ - | --program-transform-n | --program-transform- \ - | --program-transform | --program-transfor \ - | --program-transfo | --program-transf \ - | --program-trans | --program-tran \ - | --progr-tra | --program-tr | --program-t) - ac_prev=program_transform_name ;; - -program-transform-name=* | --program-transform-name=* \ - | --program-transform-nam=* | --program-transform-na=* \ - | --program-transform-n=* | --program-transform-=* \ - | --program-transform=* | --program-transfor=* \ - | --program-transfo=* | --program-transf=* \ - | --program-trans=* | --program-tran=* \ - | --progr-tra=* | --program-tr=* | --program-t=*) - program_transform_name="$ac_optarg" ;; - - -q | -quiet | --quiet | --quie | --qui | --qu | --q \ - | -silent | --silent | --silen | --sile | --sil) - silent=yes ;; - - -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) - ac_prev=sbindir ;; - -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ - | --sbi=* | --sb=*) - sbindir="$ac_optarg" ;; - - -sharedstatedir | --sharedstatedir | --sharedstatedi \ - | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ - | --sharedst | --shareds | --shared | --share | --shar \ - | --sha | --sh) - ac_prev=sharedstatedir ;; - -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ - | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ - | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ - | --sha=* | --sh=*) - sharedstatedir="$ac_optarg" ;; - - -site | --site | --sit) - ac_prev=site ;; - -site=* | --site=* | --sit=*) - site="$ac_optarg" ;; - - -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) - ac_prev=srcdir ;; - -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) - srcdir="$ac_optarg" ;; - - -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ - | --syscon | --sysco | --sysc | --sys | --sy) - ac_prev=sysconfdir ;; - -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ - | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) - sysconfdir="$ac_optarg" ;; - - -target | --target | --targe | --targ | --tar | --ta | --t) - ac_prev=target ;; - -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) - target="$ac_optarg" ;; - - -v | -verbose | --verbose | --verbos | --verbo | --verb) - verbose=yes ;; - - -version | --version | --versio | --versi | --vers) - echo "configure generated by autoconf version 2.12" - exit 0 ;; - - -with-* | --with-*) - ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'` - # Reject names that are not valid shell variable names. - if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then - { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } - fi - ac_package=`echo $ac_package| sed 's/-/_/g'` - case "$ac_option" in - *=*) ;; - *) ac_optarg=yes ;; - esac - eval "with_${ac_package}='$ac_optarg'" ;; - - -without-* | --without-*) - ac_package=`echo $ac_option|sed -e 's/-*without-//'` - # Reject names that are not valid shell variable names. - if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then - { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } - fi - ac_package=`echo $ac_package| sed 's/-/_/g'` - eval "with_${ac_package}=no" ;; - - --x) - # Obsolete; use --with-x. - with_x=yes ;; - - -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ - | --x-incl | --x-inc | --x-in | --x-i) - ac_prev=x_includes ;; - -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ - | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) - x_includes="$ac_optarg" ;; - - -x-libraries | --x-libraries | --x-librarie | --x-librari \ - | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) - ac_prev=x_libraries ;; - -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ - | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) - x_libraries="$ac_optarg" ;; - - -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; } - ;; - - *) - if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then - echo "configure: warning: $ac_option: invalid host type" 1>&2 - fi - if test "x$nonopt" != xNONE; then - { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } - fi - nonopt="$ac_option" - ;; - - esac -done - -if test -n "$ac_prev"; then - { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; } -fi - -trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 - -# File descriptor usage: -# 0 standard input -# 1 file creation -# 2 errors and warnings -# 3 some systems may open it to /dev/tty -# 4 used on the Kubota Titan -# 6 checking for... messages and results -# 5 compiler messages saved in config.log -if test "$silent" = yes; then - exec 6>/dev/null -else - exec 6>&1 -fi -exec 5>./config.log - -echo "\ -This file contains any messages produced by compilers while -running configure, to aid debugging if configure makes a mistake. -" 1>&5 - -# Strip out --no-create and --no-recursion so they do not pile up. -# Also quote any args containing shell metacharacters. -ac_configure_args= -for ac_arg -do - case "$ac_arg" in - -no-create | --no-create | --no-creat | --no-crea | --no-cre \ - | --no-cr | --no-c) ;; - -no-recursion | --no-recursion | --no-recursio | --no-recursi \ - | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;; - *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*) - ac_configure_args="$ac_configure_args '$ac_arg'" ;; - *) ac_configure_args="$ac_configure_args $ac_arg" ;; - esac -done - -# NLS nuisances. -# Only set these to C if already set. These must not be set unconditionally -# because not all systems understand e.g. LANG=C (notably SCO). -# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'! -# Non-C LC_CTYPE values break the ctype check. -if test "${LANG+set}" = set; then LANG=C; export LANG; fi -if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi -if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi -if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi - -# confdefs.h avoids OS command line length limits that DEFS can exceed. -rm -rf conftest* confdefs.h -# AIX cpp loses on an empty file, so make sure it contains at least a newline. -echo > confdefs.h - -# A filename unique to this package, relative to the directory that -# configure is in, which we can look for to find out if srcdir is correct. -ac_unique_file=lisp/gnus.el - -# Find the source files, if location was not specified. -if test -z "$srcdir"; then - ac_srcdir_defaulted=yes - # Try the directory containing this script, then its parent. - ac_prog=$0 - ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'` - test "x$ac_confdir" = "x$ac_prog" && ac_confdir=. - srcdir=$ac_confdir - if test ! -r $srcdir/$ac_unique_file; then - srcdir=.. - fi -else - ac_srcdir_defaulted=no -fi -if test ! -r $srcdir/$ac_unique_file; then - if test "$ac_srcdir_defaulted" = yes; then - { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; } - else - { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; } - fi -fi -srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'` - -# Prefer explicitly selected file to automatically selected ones. -if test -z "$CONFIG_SITE"; then - if test "x$prefix" != xNONE; then - CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" - else - CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" - fi -fi -for ac_site_file in $CONFIG_SITE; do - if test -r "$ac_site_file"; then - echo "loading site script $ac_site_file" - . "$ac_site_file" - fi -done - -if test -r "$cache_file"; then - echo "loading cache $cache_file" - . $cache_file -else - echo "creating cache $cache_file" - > $cache_file -fi - -ac_ext=c -# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. -ac_cpp='$CPP $CPPFLAGS' -ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' -ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' -cross_compiling=$ac_cv_prog_cc_cross - -if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then - # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu. - if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then - ac_n= ac_c=' -' ac_t=' ' - else - ac_n=-n ac_c= ac_t= - fi -else - ac_n= ac_c='\c' ac_t= -fi - - -echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6 -echo "configure:523: checking whether ${MAKE-make} sets \${MAKE}" >&5 -set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'` -if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - cat > conftestmake <<\EOF -all: - @echo 'ac_maketemp="${MAKE}"' -EOF -# GNU make sometimes prints "make[1]: Entering...", which would confuse us. -eval `${MAKE-make} -f conftestmake 2>/dev/null | grep temp=` -if test -n "$ac_maketemp"; then - eval ac_cv_prog_make_${ac_make}_set=yes -else - eval ac_cv_prog_make_${ac_make}_set=no -fi -rm -f conftestmake -fi -if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then - echo "$ac_t""yes" 1>&6 - SET_MAKE= -else - echo "$ac_t""no" 1>&6 - SET_MAKE="MAKE=${MAKE-make}" -fi - -ac_aux_dir= -for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do - if test -f $ac_dir/install-sh; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/install-sh -c" - break - elif test -f $ac_dir/install.sh; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/install.sh -c" - break - fi -done -if test -z "$ac_aux_dir"; then - { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; } -fi -ac_config_guess=$ac_aux_dir/config.guess -ac_config_sub=$ac_aux_dir/config.sub -ac_configure=$ac_aux_dir/configure # This should be Cygnus configure. - -# Find a good install program. We prefer a C program (faster), -# so one script is as good as another. But avoid the broken or -# incompatible versions: -# SysV /etc/install, /usr/sbin/install -# SunOS /usr/etc/install -# IRIX /sbin/install -# AIX /bin/install -# AFS /usr/afsws/bin/install, which mishandles nonexistent args -# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" -# ./install, which can be erroneously created by make from ./install.sh. -echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 -echo "configure:579: checking for a BSD compatible install" >&5 -if test -z "$INSTALL"; then -if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS="${IFS}:" - for ac_dir in $PATH; do - # Account for people who put trailing slashes in PATH elements. - case "$ac_dir/" in - /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;; - *) - # OSF1 and SCO ODT 3.0 have their own names for install. - for ac_prog in ginstall installbsd scoinst install; do - if test -f $ac_dir/$ac_prog; then - if test $ac_prog = install && - grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then - # AIX install. It has an incompatible calling convention. - # OSF/1 installbsd also uses dspmsg, but is usable. - : - else - ac_cv_path_install="$ac_dir/$ac_prog -c" - break 2 - fi - fi - done - ;; - esac - done - IFS="$ac_save_IFS" - -fi - if test "${ac_cv_path_install+set}" = set; then - INSTALL="$ac_cv_path_install" - else - # As a last resort, use the slow shell script. We don't cache a - # path for INSTALL within a source directory, because that will - # break other packages using the cache if that directory is - # removed, or if the path is relative. - INSTALL="$ac_install_sh" - fi -fi -echo "$ac_t""$INSTALL" 1>&6 - -# Use test -z because SunOS4 sh mishandles braces in ${var-val}. -# It thinks the first close brace ends the variable substitution. -test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' - -test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' - -# If set to t, that means we are running in a shell under Emacs. - # If you have an Emacs named "t", then use the full path. - test "$EMACS" = t && EMACS= - # Extract the first word of "emacs xemacs", so it can be a program name with args. -set dummy emacs xemacs; ac_word=$2 -echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:634: checking for $ac_word" >&5 -if eval "test \"`echo '$''{'ac_cv_path_EMACS'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - case "$EMACS" in - /*) - ac_cv_path_EMACS="$EMACS" # Let the user override the test with a path. - ;; - *) - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" - for ac_dir in $PATH; do - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/$ac_word; then - ac_cv_path_EMACS="$ac_dir/$ac_word" - break - fi - done - IFS="$ac_save_ifs" - test -z "$ac_cv_path_EMACS" && ac_cv_path_EMACS="no" - ;; -esac -fi -EMACS="$ac_cv_path_EMACS" -if test -n "$EMACS"; then - echo "$ac_t""$EMACS" 1>&6 -else - echo "$ac_t""no" 1>&6 -fi - - if test $EMACS != "no"; then - echo $ac_n "checking where .elc files should go""... $ac_c" 1>&6 -echo "configure:665: checking where .elc files should go" >&5 - lispdir="\$(datadir)/emacs/site-lisp" - if test "x$prefix" = "xNONE"; then - if test -d $ac_default_prefix/share/emacs/site-lisp; then - lispdir="\$(prefix)/share/emacs/site-lisp" - else - if test -d $ac_default_prefix/lib/emacs/site-lisp; then - lispdir="\$(prefix)/lib/emacs/site-lisp" - fi - fi - else - if test -d $prefix/share/emacs/site-lisp; then - lispdir="\$(prefix)/share/emacs/site-lisp" - else - if test -d $prefix/lib/emacs/site-lisp; then - lispdir="\$(prefix)/lib/emacs/site-lisp" - fi - fi - fi - echo "$ac_t""$lispdir" 1>&6 - fi - -# Extract the first word of "makeinfo", so it can be a program name with args. -set dummy makeinfo; ac_word=$2 -echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:690: checking for $ac_word" >&5 -if eval "test \"`echo '$''{'ac_cv_path_MAKEINFO'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - case "$MAKEINFO" in - /*) - ac_cv_path_MAKEINFO="$MAKEINFO" # Let the user override the test with a path. - ;; - *) - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" - for ac_dir in $PATH; do - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/$ac_word; then - ac_cv_path_MAKEINFO="$ac_dir/$ac_word" - break - fi - done - IFS="$ac_save_ifs" - test -z "$ac_cv_path_MAKEINFO" && ac_cv_path_MAKEINFO="no" - ;; -esac -fi -MAKEINFO="$ac_cv_path_MAKEINFO" -if test -n "$MAKEINFO"; then - echo "$ac_t""$MAKEINFO" 1>&6 -else - echo "$ac_t""no" 1>&6 -fi - -trap '' 1 2 15 -cat > confcache <<\EOF -# This file is a shell script that caches the results of configure -# tests run on this system so they can be shared between configure -# scripts and configure runs. It is not useful on other systems. -# If it contains results you don't want to keep, you may remove or edit it. -# -# By default, configure uses ./config.cache as the cache file, -# creating it if it does not exist already. You can give configure -# the --cache-file=FILE option to use a different cache file; that is -# what configure does when it calls configure scripts in -# subdirectories, so they share the cache. -# Giving --cache-file=/dev/null disables caching, for debugging configure. -# config.status only pays attention to the cache file if you give it the -# --recheck option to rerun configure. -# -EOF -# The following way of writing the cache mishandles newlines in values, -# but we know of no workaround that is simple, portable, and efficient. -# So, don't put newlines in cache variables' values. -# Ultrix sh set writes to stderr and can't be redirected directly, -# and sets the high bit in the cache file unless we assign to the vars. -(set) 2>&1 | - case `(ac_space=' '; set) 2>&1` in - *ac_space=\ *) - # `set' does not quote correctly, so add quotes (double-quote substitution - # turns \\\\ into \\, and sed turns \\ into \). - sed -n \ - -e "s/'/'\\\\''/g" \ - -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p" - ;; - *) - # `set' quotes correctly as required by POSIX, so do not add quotes. - sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p' - ;; - esac >> confcache -if cmp -s $cache_file confcache; then - : -else - if test -w $cache_file; then - echo "updating cache $cache_file" - cat confcache > $cache_file - else - echo "not updating unwritable cache $cache_file" - fi -fi -rm -f confcache - -trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 - -test "x$prefix" = xNONE && prefix=$ac_default_prefix -# Let make expand exec_prefix. -test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' - -# Any assignment to VPATH causes Sun make to only execute -# the first set of double-colon rules, so remove it if not needed. -# If there is a colon in the path, we need to keep it. -if test "x$srcdir" = x.; then - ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d' -fi - -trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15 - -# Transform confdefs.h into DEFS. -# Protect against shell expansion while executing Makefile rules. -# Protect against Makefile macro expansion. -cat > conftest.defs <<\EOF -s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%-D\1=\2%g -s%[ `~#$^&*(){}\\|;'"<>?]%\\&%g -s%\[%\\&%g -s%\]%\\&%g -s%\$%$$%g -EOF -DEFS=`sed -f conftest.defs confdefs.h | tr '\012' ' '` -rm -f conftest.defs - - -# Without the "./", some shells look in PATH for config.status. -: ${CONFIG_STATUS=./config.status} - -echo creating $CONFIG_STATUS -rm -f $CONFIG_STATUS -cat > $CONFIG_STATUS </dev/null | sed 1q`: -# -# $0 $ac_configure_args -# -# Compiler output produced by configure, useful for debugging -# configure, is in ./config.log if it exists. - -ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]" -for ac_option -do - case "\$ac_option" in - -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) - echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion" - exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;; - -version | --version | --versio | --versi | --vers | --ver | --ve | --v) - echo "$CONFIG_STATUS generated by autoconf version 2.12" - exit 0 ;; - -help | --help | --hel | --he | --h) - echo "\$ac_cs_usage"; exit 0 ;; - *) echo "\$ac_cs_usage"; exit 1 ;; - esac -done - -ac_given_srcdir=$srcdir -ac_given_INSTALL="$INSTALL" - -trap 'rm -fr `echo "Makefile lisp/Makefile texi/Makefile" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15 -EOF -cat >> $CONFIG_STATUS < conftest.subs <<\\CEOF -$ac_vpsub -$extrasub -s%@CFLAGS@%$CFLAGS%g -s%@CPPFLAGS@%$CPPFLAGS%g -s%@CXXFLAGS@%$CXXFLAGS%g -s%@DEFS@%$DEFS%g -s%@LDFLAGS@%$LDFLAGS%g -s%@LIBS@%$LIBS%g -s%@exec_prefix@%$exec_prefix%g -s%@prefix@%$prefix%g -s%@program_transform_name@%$program_transform_name%g -s%@bindir@%$bindir%g -s%@sbindir@%$sbindir%g -s%@libexecdir@%$libexecdir%g -s%@datadir@%$datadir%g -s%@sysconfdir@%$sysconfdir%g -s%@sharedstatedir@%$sharedstatedir%g -s%@localstatedir@%$localstatedir%g -s%@libdir@%$libdir%g -s%@includedir@%$includedir%g -s%@oldincludedir@%$oldincludedir%g -s%@infodir@%$infodir%g -s%@mandir@%$mandir%g -s%@SET_MAKE@%$SET_MAKE%g -s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g -s%@INSTALL_DATA@%$INSTALL_DATA%g -s%@EMACS@%$EMACS%g -s%@lispdir@%$lispdir%g -s%@MAKEINFO@%$MAKEINFO%g - -CEOF -EOF - -cat >> $CONFIG_STATUS <<\EOF - -# Split the substitutions into bite-sized pieces for seds with -# small command number limits, like on Digital OSF/1 and HP-UX. -ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script. -ac_file=1 # Number of current file. -ac_beg=1 # First line for current file. -ac_end=$ac_max_sed_cmds # Line after last line for current file. -ac_more_lines=: -ac_sed_cmds="" -while $ac_more_lines; do - if test $ac_beg -gt 1; then - sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file - else - sed "${ac_end}q" conftest.subs > conftest.s$ac_file - fi - if test ! -s conftest.s$ac_file; then - ac_more_lines=false - rm -f conftest.s$ac_file - else - if test -z "$ac_sed_cmds"; then - ac_sed_cmds="sed -f conftest.s$ac_file" - else - ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file" - fi - ac_file=`expr $ac_file + 1` - ac_beg=$ac_end - ac_end=`expr $ac_end + $ac_max_sed_cmds` - fi -done -if test -z "$ac_sed_cmds"; then - ac_sed_cmds=cat -fi -EOF - -cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF -for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then - # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". - case "$ac_file" in - *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` - ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; - *) ac_file_in="${ac_file}.in" ;; - esac - - # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories. - - # Remove last slash and all that follows it. Not all systems have dirname. - ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` - if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then - # The file is in a subdirectory. - test ! -d "$ac_dir" && mkdir "$ac_dir" - ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`" - # A "../" for each directory in $ac_dir_suffix. - ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'` - else - ac_dir_suffix= ac_dots= - fi - - case "$ac_given_srcdir" in - .) srcdir=. - if test -z "$ac_dots"; then top_srcdir=. - else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;; - /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;; - *) # Relative path. - srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix" - top_srcdir="$ac_dots$ac_given_srcdir" ;; - esac - - case "$ac_given_INSTALL" in - [/$]*) INSTALL="$ac_given_INSTALL" ;; - *) INSTALL="$ac_dots$ac_given_INSTALL" ;; - esac - - echo creating "$ac_file" - rm -f "$ac_file" - configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure." - case "$ac_file" in - *Makefile*) ac_comsub="1i\\ -# $configure_input" ;; - *) ac_comsub= ;; - esac - - ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` - sed -e "$ac_comsub -s%@configure_input@%$configure_input%g -s%@srcdir@%$srcdir%g -s%@top_srcdir@%$top_srcdir%g -s%@INSTALL@%$INSTALL%g -" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file -fi; done -rm -f conftest.s* - -EOF -cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF - -exit 0 -EOF -chmod +x $CONFIG_STATUS -rm -fr confdefs* $ac_clean_files -test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1 - diff --git a/configure.in b/configure.in deleted file mode 100644 index 675635b..0000000 --- a/configure.in +++ /dev/null @@ -1,6 +0,0 @@ -AC_INIT(lisp/gnus.el) -AC_SET_MAKE -AC_PROG_INSTALL -AM_PATH_LISPDIR -AC_PATH_PROG(MAKEINFO, makeinfo, no) -AC_OUTPUT(Makefile lisp/Makefile texi/Makefile) diff --git a/etc/gnus-tut.txt b/etc/gnus-tut.txt deleted file mode 100644 index 94e9500..0000000 --- a/etc/gnus-tut.txt +++ /dev/null @@ -1,294 +0,0 @@ -From lars Thu Feb 23 23:20:38 1995 -From: larsi@ifi.uio.no (ding) -Date: Fri Feb 24 13:40:45 1995 -Subject: So you want to use the new Gnus -Message-ID: - -Actually, since you are reading this, chances are you are already -using the new Gnus. Congratulations. - -This entire newsgroup you are reading is, in fact, no real newsgroup -at all, in the traditional sense. It is an example of one of the -"foreign" select methods that Gnus may use. - -The text you are now reading is stored in the "etc" directory with the -rest of the Emacs sources. You are using the "nndoc" backend for -accessing it. Scary, isn't it? - -This isn't the real documentation. `M-x info', `m gnus ' to read -that. This "newsgroup" is intended as a kinder, gentler way of getting -people started. - -Gnus is a rewrite of GNUS 4.1, written by Masanobu Umeda. The rewrite -was done by moi, yours truly, your humble servant, Lars Magne -Ingebrigtsen. If you have a WWW browser, you can investigate to your -heart's delight at . - -;; Copyright (C) 1995 Free Software Foundation, Inc. - -;; Author: Lars Magne Ingebrigtsen -;; Keywords: news - -;; This file is part of GNU Emacs. - -;; GNU Emacs is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 2, or (at your option) -;; any later version. - -;; GNU Emacs is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs; see the file COPYING. If not, write to the -;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. - -From lars Thu Feb 23 23:20:38 1995 -From: larsi@ifi.uio.no (ding) -Date: Fri Feb 24 13:40:45 1995 -Subject: Starting up -Message-ID: - -If you are having problems with Gnus not finding your server, you have -to set `gnus-select-method'. A "method" is a way of specifying *how* -the news is to be found, and from *where*. - -Say you want to read news from you local, friendly nntp server -"news.my.local.server". - -(setq gnus-select-method '(nntp "news.my.local.server")) - -Quite easy, huh? - -From the news spool: - -(setq gnus-select-method '(nnspool "")) - -From your mh-e spool: - -(setq gnus-select-method '(nnmh "")) - -There's a whole bunch of other methods for reading mail and news, see -the "Foreign groups" article for that. - - -From lars Thu Feb 23 23:20:38 1995 -From: larsi@ifi.uio.no (ding) -Date: Fri Feb 24 13:40:45 1995 -Subject: Where are all the groups, then? -Message-ID: - -If this is the first time you have used a newsreader, you won't have a -.newsrc file. This means that Gnus will think that all the newsgroups -on the server are "new", and kill them all. - -If you have a .newsrc file, the new groups will be processed with the -function in the `gnus-subscribe-newsgroup-method' variable, which is -`gnus-subscribe-zombies' by default. - -This means that all the groups have been made into "zombies" - not -quite dead, but not exactly alive, either. - -Jump back to the *Group* buffer, and type `A z' to list all the zombie -groups. Look though the list, and subscribe to the groups you want to -read by pressing `u' on the one you think look interesting. - -If all the groups have been killed, type `A k' to list all the killed -groups. Subscribe to them the same way. - -When you are satisfied, press `S z' to kill all the zombie groups. - -Now you should have a nice list of all groups you are interested in. - -(If you later want to subscribe to more groups, press `A k' to -list all the kill groups, and repeat. You can also type `U' and be -prompted for groups to subscribe to.) - - -From lars Thu Feb 23 23:20:38 1995 -From: larsi@ifi.uio.no (ding) -Date: Fri Feb 24 13:40:45 1995 -Subject: I want to read my mail! -Message-ID: - -Yes, Virginia, you can read mail with Gnus. - -First you have to decide which mail backend you want to use. You have -nnml, which is a one-file-one-mail backend, which is quite nice, but -apt to make your systems administrator go crazy and come after you -with a shotgun. - -nnmbox uses a Unix mail box to store mail. Nice, but slow. - -nnmh uses mh-e folders, which is also a one-file-one-mail thingie, but -slower than nnml. (It doesn't support NOV files.) - -So if you want to go with nnmbox, you can simply say: - -(setq gnus-secondary-select-methods '((nnmbox ""))) - -(The same for the other methods, kind of.) - -You should also set `nnmail-split-methods' to something sensible: - -(setq nnmail-split-methods - '(("mail.junk" "From:.*Lars") - ("mail.misc ""))) - -This will put all mail from me in you junk mail group, and the rest in -"mail.misc". - -These groups will be subscribe the same way as the normal groups, so -you will probably find them among the zombie groups after you set -these variables and re-start Gnus. - - -From lars Thu Feb 23 23:20:38 1995 -From: larsi@ifi.uio.no (ding) -Date: Fri Feb 24 13:40:45 1995 -Subject: Foreign newsgroups -Message-ID: - -These are groups that do not come from `gnus-select-method'. - -Say you want to read "alt.furniture.couches" from "news.funet.fi". You -can then either type `B news.funet.fi ' to browse that server and -subscribe to that group, or you can type -`G m alt.furniture.couchesnntpnews.funet.fi', if you -like to type a lot. - -If you want to read a directory as a newsgroup, you can create an -nndir group, much the same way. There's a shorthand for that, -though. If, for instance, you want to read the (ding) list archives, -you could type `G d /ftp '. - -There's lots more to know about foreign groups, but you have to read -the info pages to find out more. - - -From lars Thu Feb 23 23:20:38 1995 -From: larsi@ifi.uio.no (ding) -Date: Fri Feb 24 13:40:45 1995 -Subject: Low level changes in GNUS, or, Wrong type argument: stringp, nil -Message-ID: - -Gnus really isn't GNUS, even though it looks like it. If you scrape -the surface, you'll find that most things have changed. - -This means that old code that relies on GNUS internals will fail. - -In particular, `gnus-newsrc-hashtb', `gnus-newsrc-assoc', -`gnus-killed-list', the `nntp-header-' macros and the display formats -have all changed. If you have some code lying around that depend on -these, or change these, you'll have to re-write your code. - -Old hilit19 code does not work at all. In fact, you should probably -remove all hilit code from all the Gnus hooks -(`gnus-group-prepare-hook', `gnus-summary-prepare-hook' and -`gnus-summary-article-hook'). (Well, at the very least the first -two.) Gnus provides various integrated functions for highlighting, -which are both faster and more accurated. - -There is absolutely no chance, whatsoever, of getting Gnus to work -with Emacs 18. It won't even work on Emacsen older than Emacs -19.30/XEmacs 19.13. Upgrade your Emacs or die. - - -From lars Thu Feb 23 23:20:38 1995 -From: larsi@ifi.uio.no (ding) -Date: Fri Feb 24 13:40:45 1995 -Subject: How do I re-scan my mail groups? -Message-ID: - -Reading the active file from the nntp server is a drag. - -Just press `M-g' on the mail groups, and they will be re-scanned. - -You can also re-scan all the mail groups by putting them on level 1 -(`S l 1'), and saying `1 g' to re-scan all level 1 groups. - - -From lars Thu Feb 23 23:20:38 1995 -From: larsi@ifi.uio.no (ding) -Date: Fri Feb 24 13:40:45 1995 -Subject: How do I set up virtual newsgroups? -Message-ID: - -Virtual newsgroups are collections of other newsgroups. Why people -want this is beyond me, but here goes: - -Create the group by saying - -`M-a my.virtual.newsgroupnnvirtual^rec\.aquaria\.*' - -This will create the group "nnvirtual:my.virtual.newsgroup", which -will collect all articles from all the groups in the "rec.aquaria" -hierarchy. - -If you want to edit the regular expression, just type `M-e' on the -group line. - -Note that all the groups that are part of the virtual group have to be -alive. This means that the cannot, absolutely not, be zombie or -killed. They can be unsubscribed; that's no problem. - -You can combine groups from different servers in the same virtual -newsgroup, something that may actually be useful. Say you have the -group "comp.headers" on the server "news.server.no" and the same group -on "news.server.edu". If people have posted articles with Distribution -headers that stop propagation of their articles, combining these two -newsgroups into one virtual newsgroup should give you a better view of -what's going on. - -One caveat, though: The virtual group article numbers from the first -source group (group A) will always be lower than the article numbers -from the second (group B). This means that Gnus will believe that -articles from group A are older than articles from group B. Threading -will lessen these problems, but it might be a good idea to sort the -threads over the date of the articles to get a correct feel for the -flow of the groups: - -(setq gnus-thread-sort-functions '(gnus-thread-sort-by-date)) - -If you only want this in virtual groups, you could say something along -the lines of: - -(setq gnus-select-group-hook - (lambda () - (if (eq 'nnvirtual (car (gnus-find-method-for-group - gnus-newsgroup-name))) - (progn - (make-local-variable 'gnus-thread-sort-functions) - (setq gnus-thread-sort-functions '(gnus-thread-sort-by-date)))))) - - -From lars Thu Feb 23 23:20:38 1995 -From: larsi@ifi.uio.no (ding) -Date: Fri Feb 24 13:40:45 1995 -Subject: Bugs & stuff -Message-ID: - -If you want to report a bug, please type `M-x gnus-bug'. This will -give me a precise overview of your Gnus and Emacs version numbers, -along with a look at all Gnus variables you have changed. - -Du not expect a reply back, but your bug should be fixed in the next -version. If the bug persists, please re-submit your bug report. - -When a bug occurs, I need a recipe for how to trigger the bug. You -have to tell me exactly what you do to uncover the bug, and you should -(setq debug-on-error t) and send me the backtrace along with the bug -report. - -If I am not able to reproduce the bug, I won't be able to fix it. - -I would, of course, prefer that you locate the bug, fix it, and mail -me the patches, but one can't have everything. - -If you have any questions on usage, the "ding@ifi.uio.no" mailing list -is where to post the questions. - - diff --git a/install-sh b/install-sh deleted file mode 100644 index e843669..0000000 --- a/install-sh +++ /dev/null @@ -1,250 +0,0 @@ -#!/bin/sh -# -# install - install a program, script, or datafile -# This comes from X11R5 (mit/util/scripts/install.sh). -# -# Copyright 1991 by the Massachusetts Institute of Technology -# -# Permission to use, copy, modify, distribute, and sell this software and its -# documentation for any purpose is hereby granted without fee, provided that -# the above copyright notice appear in all copies and that both that -# copyright notice and this permission notice appear in supporting -# documentation, and that the name of M.I.T. not be used in advertising or -# publicity pertaining to distribution of the software without specific, -# written prior permission. M.I.T. makes no representations about the -# suitability of this software for any purpose. It is provided "as is" -# without express or implied warranty. -# -# Calling this script install-sh is preferred over install.sh, to prevent -# `make' implicit rules from creating a file called install from it -# when there is no Makefile. -# -# This script is compatible with the BSD install script, but was written -# from scratch. It can only install one file at a time, a restriction -# shared with many OS's install programs. - - -# set DOITPROG to echo to test this script - -# Don't use :- since 4.3BSD and earlier shells don't like it. -doit="${DOITPROG-}" - - -# put in absolute paths if you don't have them in your path; or use env. vars. - -mvprog="${MVPROG-mv}" -cpprog="${CPPROG-cp}" -chmodprog="${CHMODPROG-chmod}" -chownprog="${CHOWNPROG-chown}" -chgrpprog="${CHGRPPROG-chgrp}" -stripprog="${STRIPPROG-strip}" -rmprog="${RMPROG-rm}" -mkdirprog="${MKDIRPROG-mkdir}" - -transformbasename="" -transform_arg="" -instcmd="$mvprog" -chmodcmd="$chmodprog 0755" -chowncmd="" -chgrpcmd="" -stripcmd="" -rmcmd="$rmprog -f" -mvcmd="$mvprog" -src="" -dst="" -dir_arg="" - -while [ x"$1" != x ]; do - case $1 in - -c) instcmd="$cpprog" - shift - continue;; - - -d) dir_arg=true - shift - continue;; - - -m) chmodcmd="$chmodprog $2" - shift - shift - continue;; - - -o) chowncmd="$chownprog $2" - shift - shift - continue;; - - -g) chgrpcmd="$chgrpprog $2" - shift - shift - continue;; - - -s) stripcmd="$stripprog" - shift - continue;; - - -t=*) transformarg=`echo $1 | sed 's/-t=//'` - shift - continue;; - - -b=*) transformbasename=`echo $1 | sed 's/-b=//'` - shift - continue;; - - *) if [ x"$src" = x ] - then - src=$1 - else - # this colon is to work around a 386BSD /bin/sh bug - : - dst=$1 - fi - shift - continue;; - esac -done - -if [ x"$src" = x ] -then - echo "install: no input file specified" - exit 1 -else - true -fi - -if [ x"$dir_arg" != x ]; then - dst=$src - src="" - - if [ -d $dst ]; then - instcmd=: - else - instcmd=mkdir - fi -else - -# Waiting for this to be detected by the "$instcmd $src $dsttmp" command -# might cause directories to be created, which would be especially bad -# if $src (and thus $dsttmp) contains '*'. - - if [ -f $src -o -d $src ] - then - true - else - echo "install: $src does not exist" - exit 1 - fi - - if [ x"$dst" = x ] - then - echo "install: no destination specified" - exit 1 - else - true - fi - -# If destination is a directory, append the input filename; if your system -# does not like double slashes in filenames, you may need to add some logic - - if [ -d $dst ] - then - dst="$dst"/`basename $src` - else - true - fi -fi - -## this sed command emulates the dirname command -dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` - -# Make sure that the destination directory exists. -# this part is taken from Noah Friedman's mkinstalldirs script - -# Skip lots of stat calls in the usual case. -if [ ! -d "$dstdir" ]; then -defaultIFS=' -' -IFS="${IFS-${defaultIFS}}" - -oIFS="${IFS}" -# Some sh's can't handle IFS=/ for some reason. -IFS='%' -set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` -IFS="${oIFS}" - -pathcomp='' - -while [ $# -ne 0 ] ; do - pathcomp="${pathcomp}${1}" - shift - - if [ ! -d "${pathcomp}" ] ; - then - $mkdirprog "${pathcomp}" - else - true - fi - - pathcomp="${pathcomp}/" -done -fi - -if [ x"$dir_arg" != x ] -then - $doit $instcmd $dst && - - if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && - if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && - if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && - if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi -else - -# If we're going to rename the final executable, determine the name now. - - if [ x"$transformarg" = x ] - then - dstfile=`basename $dst` - else - dstfile=`basename $dst $transformbasename | - sed $transformarg`$transformbasename - fi - -# don't allow the sed command to completely eliminate the filename - - if [ x"$dstfile" = x ] - then - dstfile=`basename $dst` - else - true - fi - -# Make a temp file name in the proper directory. - - dsttmp=$dstdir/#inst.$$# - -# Move or copy the file name to the temp name - - $doit $instcmd $src $dsttmp && - - trap "rm -f ${dsttmp}" 0 && - -# and set any options; do chmod last to preserve setuid bits - -# If any of these fail, we abort the whole thing. If we want to -# ignore errors from any of these, just make sure not to ignore -# errors from the above "$doit $instcmd $src $dsttmp" command. - - if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && - if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && - if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && - if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && - -# Now rename the file to the real destination. - - $doit $rmcmd -f $dstdir/$dstfile && - $doit $mvcmd $dsttmp $dstdir/$dstfile - -fi && - - -exit 0 diff --git a/lisp/ChangeLog b/lisp/ChangeLog deleted file mode 100644 index 881cffe..0000000 --- a/lisp/ChangeLog +++ /dev/null @@ -1,3595 +0,0 @@ -Thu Sep 24 19:29:43 1998 Lars Magne Ingebrigtsen - - * gnus.el: Gnus v5.6.44 is released. - -1998-09-23 20:34:27 Markus Rost - - * gnus.el: Extend autoloads. - -1998-09-15 18:57:48 Lars Magne Ingebrigtsen - - * gnus-draft.el (gnus-draft-send): Bind required headers to nil. - (gnus-draft-send): No. - -1998-09-14 15:16:42 Lars Magne Ingebrigtsen - - * message.el (message-fix-before-sending): Comment out invisible - text things. - -1998-09-14 14:30:09 Tatsuya Ichikawa - - * gnus-agent.el (gnus-agent-file-coding-system): Renamed. - -1998-09-13 Mike McEwan - - * gnus-agent.el (gnus-agent-expire): Stop expiry barfing on killed - groups. - -1998-09-13 07:02:04 Lars Magne Ingebrigtsen - - * gnus-agent.el (gnus-agent-save-group-info): Create proper active - lines. - -1998-09-10 02:40:28 Lars Magne Ingebrigtsen - - * gnus-draft.el (gnus-draft-edit-message): Save the buffer. - -Sun Sep 6 20:09:36 1998 Lars Magne Ingebrigtsen - - * gnus.el: Gnus v5.6.43 is released. - -1998-09-06 19:41:54 Lars Magne Ingebrigtsen - - * gnus-sum.el (gnus-remove-thread): Unhide threads before - removing. - (gnus-data-compute-positions): Ditto. - -1998-08-31 11:40:13 Shuhei KOBAYASHI - - * nnmail.el (nnmail-date-to-time): Parse time locally if no - timezone. - -1998-08-31 11:21:53 Lars Magne Ingebrigtsen - - * gnus-srvr.el (gnus-browse-foreign-server): Protect against - out-of-range articles. - - * gnus-msg.el (gnus-summary-reply): Don't inhibit posting styles. - -1998-08-30 22:33:33 Lars Magne Ingebrigtsen - - * gnus-score.el (gnus-summary-increase-score): Temporary third - majuscle. - -1998-08-30 22:32:31 Dan Christensen - - * gnus-score.el (gnus-summary-increase-score): Score thread on - Message-ID. - -1998-08-29 02:46:00 Simon Josefsson - - * gnus-sum.el (gnus-summary-mark-article-as-read): - (gnus-summary-mark-article-as-unread): - (gnus-summary-mark-article): Call gnus-request-update-mark. - -1998-08-29 Mike McEwan - - * gnus-agent.el (gnus-agent-fetch-headers): Cater for when there's - no .agentview, all articles have been expired, or everything bar a - few downloaded arts have been expired. - (gnus-agent-expire): Mark *all* expired articles as read. - -Sat Aug 29 19:17:19 1998 Lars Magne Ingebrigtsen - - * gnus.el: Gnus v5.6.42 is released. - -1998-08-29 17:06:27 Simon Josefsson - - * gnus-sum.el (gnus-summary-make-menu-bar): Typo. - -1998-08-29 12:47:42 Tatsuya Ichikawa - - * gnus-agent.el: Use nnheader-insert-file-contents. - -1998-08-29 12:18:18 Lars Magne Ingebrigtsen - - * nnvirtual.el (nnvirtual-request-group): Update the right group. - -1998-08-27 16:46:38 Lars Magne Ingebrigtsen - - * gnus-sum.el (gnus-data-compute-positions): Didn't work on hidden - threads. - - * nnvirtual.el (nnvirtual-request-group): Work when always - updating. - (nnvirtual-always-rescan): Default to t. - -Thu Aug 27 11:03:59 1998 Lars Magne Ingebrigtsen - - * gnus.el: Gnus v5.6.41 is released. - -1998-08-27 Mike McEwan - - * gnus-agent.el (gnus-agent-fetch-group-1): Leave the calculation - of `articles' to `gnus-agent-fetch-headers'. - (gnus-agent-fetch-headers): We only want headers that are after - the last entry in `gnus-group-alist'. - -1998-08-27 09:45:42 Lars Magne Ingebrigtsen - - * Makefile.in (warn): New. - - * gnus.el: Removed unreferenced bound variables all over. - - * gnus-group.el (gnus-update-group-mark-positions): Removed topic. - - * gnus-cus.el (gnus-group-customize): No part. - - * gnus-agent.el (gnus-category-line-format-alist): Renamed specs. - (gnus-category-insert-line): Use it. - -Thu Aug 27 09:29:53 1998 Lars Magne Ingebrigtsen - - * gnus.el: Gnus v5.6.40 is released. - -1998-08-27 09:19:31 Lars Magne Ingebrigtsen - - * gnus-agent.el (gnus-agent-mode): Only toggle plugged in group - mode. - -1998-08-27 07:25:47 Lars Balker Rasmussen - - * message.el (message-supersede): Check the right headers. - -1998-08-26 13:51:18 Lars Magne Ingebrigtsen - - * gnus-sum.el (gnus-sort-threads): Changed level. - -1998-08-26 Mike McEwan - - * gnus-sum.el (gnus-build-all-threads): `save-excursion' and - `set-buffer' back to `gnus-summary-buffer' in order to access - buffer-local variables. - -1998-08-26 06:00:44 Lars Magne Ingebrigtsen - - * gnus-sum.el (gnus-data-compute-positions): More and faster. - -1998-08-26 05:41:15 Matt Pharr - - * message.el (message-wash-subject): Remove more. - -1998-08-25 11:33:28 Tatsuya Ichikawa - - * gnus-cache.el (gnus-cache-overview-coding-system): New - variable. - -1998-08-25 08:23:05 Albert L. Ting - - * gnus-group.el (gnus-fetch-group-other-frame): New command. - -1998-08-25 07:24:51 Lars Magne Ingebrigtsen - - * gnus-uu.el (gnus-uu-grab-articles): Check for pseudos. - - * gnus-art.el (gnus-ignored-headers): More headers. - - * gnus-sum.el (gnus-summary-move-article): Update the right - group. - -1998-08-23 14:31:31 Lars Magne Ingebrigtsen - - * gnus-art.el (gnus-ignored-headers): More headers. - -1998-08-23 Mike McEwan - - * gnus-agent.el (gnus-agent-copy-nov-line): Return to beginning of - line before next read. - (gnus-agent-braid-nov): Remove redundant `let'. - -1998-08-22 10:40:54 Lars Magne Ingebrigtsen - - * gnus-art.el (article-display-x-face): Allow multiple X-Faces - under XEmacs. - -Sat Aug 22 10:28:25 1998 Lars Magne Ingebrigtsen - - * gnus.el: Gnus v5.6.39 is released. - -1998-08-22 10:06:03 Lars Magne Ingebrigtsen - - * gnus-art.el (gnus-ignored-headers): Added more headers. - -1998-08-21 02:49:56 Lars Magne Ingebrigtsen - - * nnweb.el (nnweb-type): Doc fix. - - * gnus-sum.el (gnus-summary-set-process-mark): Move to the right - article. - -1998-08-20 23:10:01 Lars Magne Ingebrigtsen - - * nnmail.el (nnmail-spool-file): Allow lists of files. - -1998-08-20 Per Starback - - * gnus/gnus-start.el (gnus-check-first-time-used): Change current - buffer before creating help group. - -1998-08-20 01:33:08 Lars Magne Ingebrigtsen - - * gnus-msg.el (gnus-message-style-insertions): New variable. - (gnus-message-insert-stylings): New function. - (gnus-configure-posting-styles): Use them. - - * gnus-topic.el (gnus-topic-mode): Don't alter summary-exit-hook. - - * gnus-sum.el (gnus-select-newsgroup): Don't update group. - - * gnus-msg.el (gnus-setup-message): Bind message-mode-hook. - (gnus-inhibit-posting-styles): New variable. - (gnus-summary-reply): Use it. - (gnus-configure-posting-styles): Ditto. - - * gnus-group.el (gnus-group-suspend): Don't kill dribble buffer. - -Thu Aug 20 00:28:35 1998 Lars Magne Ingebrigtsen - - * gnus.el: Gnus v5.6.38 is released. - -1998-08-20 00:02:50 Lars Magne Ingebrigtsen - - * message.el (message-mail): Doc fix. - -1998-08-19 23:22:02 Bill Pringlemeir - - * messcompat.el (message-send-mail-function): Initialized from - send-mail-function. - -1998-08-19 23:20:42 Martin Larose - - * message.el (message-send-coding-system): New variable. - -1998-08-19 19:00:37 Lars Magne Ingebrigtsen - - * gnus-msg.el (gnus-configure-posting-styles): Reinstated most of - old code. - - * gnus-start.el (gnus-save-newsrc-file): Use coding system. - -1980-06-08 03:53:56 Mike McEwan - - * gnus-agent.el (gnus-agent-braid-nov): Go to right place. - -1980-06-08 03:01:48 Shuhei KOBAYASHI - - * gnus-group.el (gnus-group-suspend): Fix. - -1998-08-18 00:25:11 Lars Magne Ingebrigtsen - - * gnus-cite.el (gnus-cited-opened-text-button-line-format-alist): - New n spec. - - * gnus-group.el (gnus-group-suspend): Use mapcar. - -1998-08-17 14:35:33 Lars Magne Ingebrigtsen - - * gnus-ems.el (gnus-add-minor-mode): Set mode var. - - * gnus-start.el (gnus-slave-mode): New function. - - * gnus-msg.el (gnus-post-method): Work with current in nndraft. - -1998-08-16 23:30:14 Lars Magne Ingebrigtsen - - * gnus-art.el (gnus-request-article-this-buffer): Allow recursive - selection of nneething groups. - - * nneething.el (nneething-address): Renamed from directory. - -Sun Aug 16 18:59:41 1998 Lars Magne Ingebrigtsen - - * gnus.el: Gnus v5.6.37 is released. - -1998-08-16 14:52:43 Lars Magne Ingebrigtsen - - * gnus.el: Autoload gnus-summary-wide-reply. - - * gnus-sum.el (gnus-get-newsgroup-headers): Return the value of - In-Reply-To. - - * gnus-msg.el (gnus-setup-message): Posting styles have to be - configured in message-mode-hook. - - * nntp.el (nntp-connection-timeout): Restored. - (nntp-open-connection): Use it. - -1998-08-15 22:46:49 Lars Magne Ingebrigtsen - - * gnus-group.el (gnus-group-make-useful-group): Doc fix. - - * gnus-art.el (gnus-article-push-button): Place point where you - click. - -1998-08-15 Mike McEwan - - * gnus-agent.el (gnus-agent-save-group-info): Update "groups" file - if `nntp-server-list-active-group' is nil. - -1998-08-15 00:35:03 Lars Magne Ingebrigtsen - - * gnus-score.el (gnus-summary-increase-score): Swap t and r. - - * gnus-sum.el (gnus-remove-thread): Didn't work with sparse - threads. - -1998-08-14 François Pinard - - * nndoc.el (nndoc-generate-mime-parts-head): Use original Subject, - Message-ID, and References in fully blown articles. - -Fri Aug 14 23:03:51 1998 Lars Magne Ingebrigtsen - - * gnus.el: Gnus v5.6.36 is released. - -1998-08-14 21:49:22 Lars Magne Ingebrigtsen - - * gnus.el (load): Push onto list. - - * gnus-group.el (gnus-group-get-new-news-this-group): Store active - info. - -Fri Aug 14 21:41:59 1998 Lars Magne Ingebrigtsen - - * gnus.el: Gnus v5.6.35 is released. - -1998-08-14 00:00:15 Lars Magne Ingebrigtsen - - * gnus-srvr.el (gnus-server-scan-server): Error better. - - * nndir.el: Make independent of nnmh. - Revert. - - * message.el (message-remove-text-with-property): New function. - (message-fix-before-sending): Check for invisible text. - - * gnus.el (load): Create the Gnus buffer even when no splash. - - * gnus-msg.el (gnus-setup-message): Add buffer to list. - - * gnus-win.el (gnus-remove-some-windows): Use new buffer system. - (gnus-delete-windows-in-gnusey-frames): Ditto. - - * gnus.el (gnus-add-buffer): New function. - -1998-08-13 23:38:21 Lars Magne Ingebrigtsen - - * gnus-xmas.el (gnus-buffer-list): Removed. - - * gnus.el (gnus-buffers): New variable. - (gnus-get-buffer-create): New function; used throughout. - (gnus-buffers): New function. - - * gnus-msg.el (gnus-configure-posting-styles): Go to eoh - reliably. - - * message.el (message-goto-eoh): New command. - -1998-08-13 23:13:53 Simon Josefsson - - * gnus-msg.el (gnus-setup-message): use message-setup-hook - instead - (gnus-configure-posting-styles): new posting-style 'body - (gnus-configure-posting-styles): insert headers immediately - -1998-08-13 13:05:36 Lars Magne Ingebrigtsen - - * gnus-score.el (gnus-summary-increase-score): Change thread to - "r". - - * gnus-sum.el (gnus-summary-scroll-down): New command and - keystroke. - - * gnus-agent.el (gnus-agent-expire): Check that directories - exist. - -1998-08-12 20:56:41 Simon Josefsson - - * gnus-cache.el (gnus-uncacheable-groups): doc change - (gnus-cacheable-groups): new variable - (gnus-cache-possibly-enter-article): use it - -1998-08-12 22:30:16 Lars Magne Ingebrigtsen - - * nntp.el (nntp-encode-text): Too much text. - -1998-08-12 21:58:50 Matt Pharr - - * message.el (message-make-forward-subject-function): New - variable. - (message-wash-forwarded-subjects): Ditto. - -Wed Aug 12 21:09:58 1998 Lars Magne Ingebrigtsen - - * gnus.el: Gnus v5.6.34 is released. - -1998-08-12 13:32:38 Lars Magne Ingebrigtsen - - * gnus-msg.el (gnus-post-method): Don't use `current' in drafts. - - * gnus-score.el (gnus-summary-increase-score): Changed T to h and - downcase. - -Tue Aug 11 20:46:25 1998 Lars Magne Ingebrigtsen - - * gnus.el: Gnus v5.6.33 is released. - -1998-08-11 20:07:55 Lars Magne Ingebrigtsen - - * gnus-group.el (gnus-group-apropos): Check symbol value. - - * gnus-cite.el (gnus-cited-closed-text-button-line-format): - Changed. - -Tue Aug 11 19:42:42 1998 Lars Magne Ingebrigtsen - - * gnus.el: Gnus v5.6.32 is released. - -1998-08-11 13:36:56 Lars Magne Ingebrigtsen - - * nndoc.el (nndoc-type-alist): Do MIME digests before multiparts. - - * gnus.el (gnus-predefined-server-alist): Expand vars. - -1998-08-09 Dave Love - - * gnus-art.el (article-display-x-face): Don't try (and fail) to - display multiple faces. - -1998-08-11 11:41:43 Lars Magne Ingebrigtsen - - * gnus-art.el (gnus-header-newsgroups-face): Don't bold so much. - - * gnus-group.el (gnus-group-rename-group): Remove old group name - from list of killed groups. - - * gnus-int.el (gnus-get-function): Error better. - - * gnus-art.el (gnus-article-narrow-to-signature): Inhibit motion - hooks. - (article-hide-pgp): Delete text instead of hiding it. - - * gnus-group.el (gnus-group-find-new-groups): Ditto. - - * gnus-start.el (gnus-find-new-newsgroups): Accept C-u C-u as a - total query. - -1998-08-10 09:31:36 Lars Magne Ingebrigtsen - - * gnus-art.el (gnus-article-prepare): Place point at the beginning - of the body. - - * gnus-cite.el (gnus-cite-attribution-face): Changed to italic. - - * gnus-art.el (gnus-article-edit-article): Delete "annotation" - text. - (gnus-insert-prev-page-button): Mark as annotation. - (gnus-insert-next-page-button): Ditto. - - * gnus-cite.el (gnus-cited-closed-text-button-line-format): New - variable. - (gnus-cited-closed-text-button-line-format-alist): Ditto. - (gnus-article-toggle-cited-text): Toggle between different - symbols. - -1998-08-09 19:58:36 Lars Magne Ingebrigtsen - - * gnus.el (gnus-version): Remove backend info. - -Sun Aug 9 19:37:40 1998 Lars Magne Ingebrigtsen - - * gnus.el: Gnus v5.6.31 is released. - -1998-08-09 François Pinard - - * nndoc.el: Split MIME multipart messages, maybe recursively. - (nndoc-mime-parts-type-p, nndoc-transform-mime-parts, - nndoc-generate-mime-parts-head, nndoc-dissect-mime-parts, - nndoc-dissect-mime-parts-sub): New functions. - - * nndoc.el: Quoting boundaries is optional, for multipart digests. - -1998-08-09 17:51:25 Lars Magne Ingebrigtsen - - * gnus-agent.el (gnus-agent-save-group-info): Check whether file - exists. - - * message.el (message-goto-signature): Return nil if no sig. - (message-delete-not-region): Delete properly if no sig. - -1998-08-09 17:26:30 Simon Josefsson - - * gnus-srvr.el (gnus-browse-make-menu-bar): select did read - -1998-08-09 15:51:43 Lars Magne Ingebrigtsen - - * gnus-sum.el (t): Added keystroke for W W C. - - * gnus-cite.el (gnus-article-hide-citation-maybe): hiden->hidden. - -Sun Aug 9 15:46:16 1998 Lars Magne Ingebrigtsen - - * gnus.el: Gnus v5.6.30 is released. - -1998-08-09 10:48:31 Lars Magne Ingebrigtsen - - * message.el (message-cite-original-without-signature): Peel off - blank lines. - - * gnus-art.el (gnus-article-maybe-highlight): Doc fix. - - * gnus-sum.el (gnus-data-enter-list): Threw away all new list data - at the beginning of the buffer. - -1998-08-07 01:41:29 Gareth Jones - - * gnus-score.el (gnus-summary-increase-score): Don't downcase - before lookin in char-to-header. - -1998-08-07 01:33:22 Lars Magne Ingebrigtsen - - * gnus.el (gnus-predefined-server-alist): Too many parentheses. - -1998-08-06 11:20:08 Lars Magne Ingebrigtsen - - * gnus.el (gnus-continuum-version): Include quassia. - - * gnus-sum.el (gnus-data-enter-list): Check before entering list. - -1998-08-06 11:13:56 Francois Felix Ingrand - - * gnus-salt.el (gnus-generate-vertical-tree): Don't go too far to - the left. - -Thu Aug 6 07:58:17 1998 Lars Magne Ingebrigtsen - - * gnus.el: Gnus v5.6.29 is released. - -1998-08-06 07:10:31 Lars Magne Ingebrigtsen - - * gnus-agent.el (gnus-agent-expire): Check whether (caar - gnus-agent-article-alist) is nil. - - * gnus.el (gnus-read-method): Allow selecting predefined servers. - - * gnus-topic.el (gnus-topic-update-topic-line): Compute right - number when inserting missing topic lines. - - * gnus-start.el (gnus-get-unread-articles): Check that the group - is alive. - - * gnus-score.el (gnus-score-load-score-alist): Better error - messaging. - -Tue Aug 4 09:42:31 1998 Kurt Swanson - - * gnus-salt.el (gnus-pick-mouse-pick-region): Fix picking bug due - to use of gnus-read-event-char. - -1998-07-28 Dave Love - - * gnus-group.el (gnus-group-fetch-faq): Don't mung dots in group - name. - -1998-07-27 Dave Love - - * gnus-topic.el (gnus-topic-mode-map): Provide Emacs tty - alternatives to [tab], [(meta tab)]. - -1998-08-06 04:41:38 Lars Magne Ingebrigtsen - - * gnus-start.el (gnus-startup-file-coding-system): New variable. - (gnus-read-init-file): Use it. - (gnus-read-newsrc-el-file): Ditto. - - * gnus-sum.el (gnus-thread-ignore-subject): Changed default. - -1998-08-06 04:38:02 Richard Stallman - - * message.el (sendmail): Required. - -1998-08-06 02:11:37 Lars Magne Ingebrigtsen - - * gnus-sum.el (gnus-auto-select-same): Dix fix. - -1998-08-04 Mike McEwan - - * gnus-sum.el (gnus-select-newsgroup): Set - `gnus-newsgroup-unselected' when selecting specific articles via - SELECT-ARTICLE - there may be more headers to fetch if - `gnus-fetch-old-headers' is non-nil. - (gnus-summary-read-group): pass SELECT-ARTICLE to - `gnus-summary-read-group-1' and reset to nil when going to next group. - (gnus-summary-read-group): Change `select-article' to - `select-articles' for consistency. - -Tue Aug 4 05:25:01 1998 Lars Magne Ingebrigtsen - - * gnus.el: Gnus v5.6.28 is released. - -1998-08-03 22:00:25 Lars Magne Ingebrigtsen - - * nndoc.el (nndoc-set-delims): Removed article-end. - (nndoc-dissect-buffer): Use eobp. - -1998-08-03 19:59:36 Trung Tran-Duc - - * nntp.el (nntp-open-connection): Bind coding-system-for-write. - -1998-07-31 16:45:36 Lars Magne Ingebrigtsen - - * gnus-group.el (gnus-group-read-ephemeral-group): Make the server - unique. - -1998-07-28 François Pinard - - * gnus-uu.el (gnus-uu-reginize-string): Consider the number of - parts as part of the fixed subject, instead of a wild quantity. - -1998-07-30 21:47:23 Lars Magne Ingebrigtsen - - * gnus-cache.el (gnus-summary-insert-cached-articles): Sort - articles. - - * nndir.el (nndir): Use nnml functions. - -Mon Jul 27 03:26:00 1998 Lars Magne Ingebrigtsen - - * gnus.el: Gnus v5.6.27 is released. - -1998-07-27 02:27:11 Lars Magne Ingebrigtsen - - * gnus-topic.el (gnus-topic-update-unreads): New function. - - * gnus-sum.el (gnus-summary-limit): Update mode line. - - * gnus-soup.el (gnus-soup-add-article): Update mode line. - - * gnus-group.el (gnus-group-make-menu-bar): Bug. - - * gnus-art.el (gnus-article-make-menu-bar): Menu. - - * gnus-sum.el (gnus-summary-make-menu-bar): Bug reports. - - * gnus-topic.el (gnus-topic-mode-map): h -> H. - -1998-07-19 16:59 Simon Josefsson - - * gnus-util.el (gnus-netrc-syntax-table): @ is whitespace - -1998-07-17 Gordon Matzigkeit - - * gnus-uu.el (gnus-uu-reginize-string): Simplify by looking - from back to front for part numbers, rather than skipping - leading ``version numbers.'' - - (gnus-uu-part-number): Make consistent with - gnus-uu-reginize-string. - -1998-07-26 19:01:58 Lars Magne Ingebrigtsen - - * gnus-art.el (gnus-request-article-this-buffer): Pass along - header. - - * gnus-sum.el (gnus-summary-update-article): Don't pass along - iheader to regeneration routine. - -1998-07-27 KOSEKI Yoshinori - - * nnmail.el (nnmail-move-inbox): Clear nnmail-internal-password, - when supplied Password is incorrect. - -Sat Jul 25 19:31:36 1998 Lars Magne Ingebrigtsen - - * gnus.el: Gnus v5.6.26 is released. - -1998-07-25 14:53:24 Lars Magne Ingebrigtsen - - * gnus-salt.el (gnus-pick-mouse-pick-region): Use - gnus-read-event-char. - -Sat Jul 25 02:43:35 1998 Lars Magne Ingebrigtsen - - * gnus.el: Gnus v5.6.25 is released. - -1998-07-25 00:03:24 Lars Magne Ingebrigtsen - - * gnus-group.el (gnus-group-read-ephemeral-group): Ditto. - - * gnus-sum.el (gnus-summary-read-group-1): Ditto. - - * gnus-group.el (gnus-group-read-group): Accept article list. - -1998-07-24 14:35:02 Lars Magne Ingebrigtsen - - * gnus-msg.el (gnus-configure-posting-styles): Quote some. - - * message.el (message-ignored-supersedes-headers): Added X-Trace - and X-Complaints-To. - - * nnmail.el (gnus-util): Required. - -1998-07-21 23:03:13 Lars Magne Ingebrigtsen - - * gnus.el (gnus-news-group-p): Bogosity in params. - -1998-07-21 16:14:32 Robert Bihlmeyer - - * gnus-util.el (gnus-globalify-regexp): New function. - -1998-07-18 21:49:01 Lars Magne Ingebrigtsen - - * gnus-sum.el (gnus-list-of-unread-articles): Peel off articles - outside active range. - -1998-07-15 10:47:39 Lars Magne Ingebrigtsen - - * nnvirtual.el (nnvirtual-request-type): Handle non-numerical - articles. - - * gnus.el (gnus-news-group-p): Do something sensible with negative - articlies. - -Wed Jul 15 10:27:05 1998 Lars Magne Ingebrigtsen - - * gnus-salt.el (gnus-tree-minimize-window): Allow numbers. - -Wed Jul 15 10:25:29 1998 Lars Magne Ingebrigtsen - - * gnus-agent.el (gnus-agent-expire): Ignored ticks. - -Wed Jul 15 10:15:28 1998 Hallvard B. Furuseth - - * nntp.el (nntp-send-authinfo): Message better and stuff. - -Wed Jul 15 10:10:07 1998 Lars Magne Ingebrigtsen - - * gnus.el (gnus-message-archive-group): Allow sexp. - -Wed Jul 15 09:56:47 1998 Lars Magne Ingebrigtsen - - * gnus-sum.el (gnus-select-newsgroup): Accept select-articles - para, - -1998-07-13 Mike McEwan - - * gnus-sum.el (gnus-select-newsgroup): Don't call the Agent to - mark articles as read until *all* headers have been retrieved. - -Wed Jul 15 09:06:18 1998 Lars Magne Ingebrigtsen - - * nndir.el (nndir): Use nnml to request article. - -1998-07-11 SL Baur - - * gnus-topic.el (gnus-topic-mode-map): Use modern key syntax. - -Sun Jul 12 04:01:22 1998 Lars Magne Ingebrigtsen - - * gnus-score.el (gnus-current-home-score-file): New function. - -1998-07-11 Mike McEwan - - * gnus-agent.el (gnus-agent-fetch-headers): Note last fetched - headers per sesion to aid expiry in `headers only' groups. - - * gnus-agent.el (gnus-agent-expire): Update group info to add - expired articles to list of read articles and prevent - re-fetching. - -1998-07-12 Lars Magne Ingebrigtsen - - * nnmail.el (nnmail-active-file-coding-system): Changed to - binary. - -Sun Jul 12 03:16:18 1998 Lars Magne Ingebrigtsen - - * gnus-score.el (gnus-score-load-file): Specify which alist to - decay. - -1998-07-12 Lars Magne Ingebrigtsen - - * gnus-start.el (gnus-startup-file-coding-system): New variable. - (gnus-read-newsrc-el-file): Use it. - -Sat Jul 11 03:03:53 1998 Lars Magne Ingebrigtsen - - * gnus.el: Gnus v5.6.24 is released. - -Fri Jul 10 04:23:24 1998 Hallvard B. Furuseth - - * gnus-util.el (gnus-parse-netrc): Allow "default" values. - -Fri Jul 10 04:15:35 1998 Lars Magne Ingebrigtsen - - * nntp.el (nntp-server-opened-hook): Doc change. - -Fri Jul 10 03:03:48 1998 François Pinard - - * gnus-sum.el (gnus-summary-respool-trace): New command and - keystroke. - -Fri Jul 10 02:18:01 1998 Lars Magne Ingebrigtsen - - * gnus-util.el (gnus-prin1): Bind print-escape-multibyte to nil. - -Mon Jul 6 01:02:59 1998 Simon Josefsson - - * gnus-range.el (gnus-sorted-complement): Fix comments. - -Thu Jul 2 11:16:14 1998 Lars Magne Ingebrigtsen - - * gnus-sum.el (gnus-summary-iterate): New macro. - - * message.el (message-pop-to-buffer): Clone locals. - - * gnus-msg.el (gnus-posting-styles): Reinstated. - (gnus-posting-style-alist): Ditto. - -Wed Jul 1 18:02:31 1998 Lars Magne Ingebrigtsen - - * gnus-int.el (gnus-get-function): Set funct to nil. - -1998-07-01 16:57:38 Simon Josefsson - - * gnus-int.el (gnus-get-function): returned non-nil when - function wasn't bound, if noerror=t - -Wed Jul 1 17:30:41 1998 Lars Magne Ingebrigtsen - - * gnus-topic.el (gnus-topic-mode-map): Bind TAB and M-TAB. - - * gnus-sum.el (gnus-build-sparse-threads): Make sure no dates are - nil. - (gnus-summary-limit-mark-excluded-as-read): Use the intersection. - - * gnus-msg.el (gnus-setup-message): Clone all local variables from - the summary buffer. - -Wed Jul 1 14:03:52 1998 Richard Stallman - - * message.el (message-cite-original): Use mail-citation-hook. - (message-cite-function): Ditto. - -Wed Jul 1 14:00:53 1998 Rajappa Iyer - - * gnus-salt.el (gnus-pick-mode-map): Changed keymap. - -Wed Jul 1 13:33:26 1998 Lars Magne Ingebrigtsen - - * gnus.el: Gnus v5.6.23 is released. - -Wed Jul 1 12:52:32 1998 Lars Magne Ingebrigtsen - - * nntp.el (nntp-record-command): Give more precise time info. - (nntp-next-result-arrived-p): Look for the end of error lines. - -Wed Jul 1 12:24:06 1998 François Pinard - - * gnus-util.el (gnus-delete-if): Would do the opposite. - -Wed Jul 1 01:53:31 1998 Lars Magne Ingebrigtsen - - * gnus-sum.el (gnus-build-sparse-threads): Didn't work at all. - -Tue Jun 30 15:56:54 1998 Lars Magne Ingebrigtsen - - * nntp.el (nntp-send-authinfo): Store the user name. - (nntp-authinfo-user): New variable. - - * gnus-sum.el (gnus-summary-limit-mark-excluded-as-read): Would - mark some articles as unread. - - * gnus-agent.el (gnus-agent-expire): Don't sort lines. - -Tue Jun 30 15:56:31 1998 Mike McEwan - - * gnus-agent.el (gnus-agent-expire): Use a fresh hash table. - -Mon Jun 29 22:49:49 1998 Lars Magne Ingebrigtsen - - * gnus.el: Gnus v5.6.22 is released. - -Mon Jun 29 21:22:46 1998 Lars Magne Ingebrigtsen - - * gnus-salt.el (gnus-pick-mode-map): Remove gnus-mouse. - - * gnus-sum.el (gnus-dependencies-add-header): `debug' left in. - Eh. Eh. - - * gnus-salt.el (gnus-summary-pick-line-format): Missing %.- - - * gnus-topic.el (gnus-topic-rename): Fix error message. - -Sun Jun 28 14:32:08 1998 Lars Magne Ingebrigtsen - - * gnus-spec.el (gnus-face-face-function): Double quoting removed. - -Sun Jun 28 09:54:52 1998 Lars Magne Ingebrigtsen - - * gnus.el: Gnus v5.6.21 is released. - -Sun Jun 28 08:51:39 1998 Lars Magne Ingebrigtsen - - * gnus-sum.el (gnus-summary-edit-article-done): Copy the buffer to - a temp buffer before replacing. - - * gnus-msg.el (gnus-post-news): Treat broken-reply-to in - followups. - - * gnus-sum.el (gnus-summary-goto-subject): Position point. - -Sat Jun 27 09:19:20 1998 Lars Magne Ingebrigtsen - - * gnus-demon.el (gnus-util): Required. - - * gnus-score.el (gnus-score-body): Message fix. - - * gnus-group.el (gnus-group-highlight-line): Use it. - - * gnus-util.el - (gnus-put-text-properties-excluding-characters-with-faces): New - function. - -Sat Jun 27 08:56:08 1998 Lars Magne Ingebrigtsen - - * gnus.el: Gnus v5.6.20 is released. - -Sat Jun 27 08:49:51 1998 Arne Georg Gleditsch - - * gnus-sum.el (gnus-parent-headers): Check better for headers. - -Sat Jun 27 08:45:09 1998 Lars Magne Ingebrigtsen - - * message.el (message-check-news-body-syntax): Buggy checksum - check. - -Sat Jun 27 07:59:22 1998 Lars Magne Ingebrigtsen - - * gnus.el: Gnus v5.6.19 is released. - -Sat Jun 27 07:50:50 1998 Lars Magne Ingebrigtsen - - * gnus.el: Gnus v5.6.18 is released. - -Sat Jun 27 03:18:57 1998 Lars Magne Ingebrigtsen - - * gnus-soup.el (gnus-soup-save-areas): Made interactive. - - * nnfolder.el (nnfolder-request-replace-article): Check all X-From - headers. - - * gnus-sum.el (gnus-update-marks): Don't nix out cache lists. - - * nngateway.el (nngateway-mail2news-header-transformation): - Changed semantics. - - * message.el (message-check-news-body-syntax): Don't look at - buffer size to see whether text has been added. - -Fri Jun 26 15:46:05 1998 Lars Magne Ingebrigtsen - - * gnus.el: Gnus v5.6.16 is released. - -Fri Jun 26 15:36:25 1998 Lars Magne Ingebrigtsen - - * gnus-util.el (gnus-delete-assq): Removed. - (gnus-delete-assoc): Ditto. - - * gnus.el: Use throughout. - - * gnus-util.el (gnus-pull): New macro. - -1998-06-26 Simon Josefsson - - * gnus-sum.el (gnus-get-newsgroup-headers): parse Chars: headers - -Fri Jun 26 13:45:24 1998 Lars Magne Ingebrigtsen - - * gnus-sum.el (gnus-update-marks): Use it. - - * gnus-util.el (gnus-delete-alist): New function. - - * gnus-sum.el (gnus-update-marks): Don't save list of cached - articles. - - * message.el (message-mode-menu): Include kill-buffer. - - * nnmail.el (nnmail-purge-split-history): Use it. - - * gnus-util.el (gnus-delete-if): New function. - - * nnmail.el (nnmail-article-group): Use gnus-remove-duplicates. - -Fri Jun 26 13:45:09 1998 Richard Stallman - - * gnus-util.el (gnus-remove-duplicates): New function. - -Fri Jun 26 13:30:42 1998 Kevin Christian - - * gnus-score.el (gnus-score-string): Do updating of scores after - fuzzies. - -Fri Jun 26 07:26:03 1998 Lars Magne Ingebrigtsen - - * message.el (message-mode): Don't do the intern dance. - -Fri Jun 26 07:13:49 1998 Richard Stallman - - * message.el (message-mode): Adaptive fill changes. - -Fri Jun 26 04:29:44 1998 Lars Magne Ingebrigtsen - - * gnus-sum.el (gnus-summary-mode-line-format-alist): Allow article - score. - - * gnus-score.el (gnus-score-load-file): Would ignore all score - files without un-advanced rules. - - * gnus-ems.el ((fboundp 'split-string)): Use it where it exists. - -Fri Jun 26 04:23:12 1998 Lars Magne Ingebrigtsen - - * gnus.el: Gnus v5.6.15 is released. - -Fri Jun 26 03:39:32 1998 Lars Magne Ingebrigtsen - - * nnfolder.el (nnfolder-request-replace-article): Delete old - delimiter. - - * gnus-msg.el (gnus-summary-reply): Use it. - - * message.el (message-reply): Removed parameter. - (message-wide-reply): Ditto. - - * gnus-msg.el (gnus-msg-treat-broken-reply-to): New function. - - * gnus-art.el (gnus-check-group-server): New function. - (gnus-request-article-this-buffer): Don't try to waken the server - before needing to. - -Thu Jun 25 10:35:48 1998 Lars Magne Ingebrigtsen - - * gnus-sum.el (gnus-summary-delete-article): Sort the articles - before deleting. - - * nngateway.el (nngateway-request-post): Return success. - - * nnheader.el (nnheader-insert-file-contents): Bind more hooks. - - * gnus-sum.el (gnus-summary-limit-to-age): Reverse logic. - - * gnus-score.el (gnus-summary-score-entry): Removed interactive - spec. - ((gnus-summary-score-map "V" gnus-summary-mode-map)): Removed - keystroke. - - * gnus-art.el (gnus-article-show-summary): Position point. - - * gnus-cache.el (gnus-cache-update-article): Change group first. - - * gnus.el (gnus-short-group-name): Collapse more. - -Thu Jun 25 08:48:06 1998 Lars Magne Ingebrigtsen - - * gnus.el: Gnus v5.6.14 is released. - -Thu Jun 25 05:13:31 1998 Lars Magne Ingebrigtsen - - * gnus-sum.el (gnus-rebuild-thread): Accept a line argument. - (gnus-rebuild-thread): Would skip around a lot when `P'-ing past - the beginning. - - * gnus-msg.el (gnus-post-method): Present all known servers if - `C-u 0'. - - * gnus-salt.el (gnus-pick-mode-map): Reinstated keymap. - - * gnus-sum.el (gnus-build-sparse-threads): Put the proper date - in. - -Wed Jun 24 07:52:30 1998 Lars Magne Ingebrigtsen - - * gnus.el: Gnus v5.6.13 is released. - -Wed Jun 24 07:47:04 1998 Lars Magne Ingebrigtsen - - * gnus-topic.el (gnus-topic-rename): Disallow "nil". - -Wed Jun 24 07:33:17 1998 Vladimir Alexiev - - * nnvirtual.el (nnvirtual-update-xref-header): Regexp-quote group - name. - -Wed Jun 24 06:15:27 1998 Lars Magne Ingebrigtsen - - * gnus-sum.el (gnus-build-sparse-threads): Give all the sparse - articles the date of the current child. - - * gnus-topic.el (gnus-group-topic-parameters): Didn't compute. - -Wed Jun 24 03:27:44 1998 Lars Magne Ingebrigtsen - - * gnus.el: Gnus v5.6.12 is released. - -Wed Jun 10 11:06:35 1998 Andreas Schwab - - * message.el (message-mail-other-window): Bind message-this-is-mail. - (message-mail-other-frame): Likewise. - (message-news-other-window): Bind message-this-is-news. - (message-news-other-frame): Likewise. - -1998-06-09 Sam Steingold - - * gnus-uu.el (gnus-uu-default-view-rules): make sed kill ^M only - at the end of line. - -1998-06-05 Hrvoje Niksic - - * nnmail.el (nnmail-get-split-group): Don't regexp-quote - nnmail-procmail-suffix. - -Wed Jun 24 03:04:05 1998 Kim-Minh Kaplan - - * gnus-sum.el (gnus-build-get-header): Fix obarray. - -Wed Jun 24 02:49:57 1998 Castor - - * nntp.el (nntp-open-ssl-stream): - -Wed Jun 24 02:31:46 1998 Lars Magne Ingebrigtsen - - * gnus-sum.el (gnus-nov-parse-line): Cleaned up. - (gnus-build-all-threads): Put things in the wrong obarray. - -Wed Jun 24 01:43:26 1998 Decklin Foster - - * nngateway.el (nngateway-mail2news-header-transformation): New - function. - -Wed Jun 24 00:25:45 1998 Lars Magne Ingebrigtsen - - * message.el (message-shorten-references): New function. - (message-header-format-alist): Use it. - - * gnus-start.el (gnus-always-read-dribble-file): Customized. - - * message.el (message-generate-new-buffers): Dox fox. - -Tue Jun 23 23:58:48 1998 Lars Magne Ingebrigtsen - - * gnus-topic.el (gnus-topic-prepare-topic): Respect visible topic - param. - (gnus-topic-hierarchical-parameters): New function. - -1998-06-02 Didier Verna - - * gnus-picon.el (gnus-get-buffer-name): use get-buffer-create - instead of get-buffer - -Wed Jun 3 04:41:45 1998 Lars Magne Ingebrigtsen - - * nnkiboze.el (nnkiboze-request-delete-group): Delete .newsrc - file. - - * nnmail.el (nnmail-article-group): Nuke looong lines. - - * gnus-art.el (gnus-button-alist): Buggy default. - -Wed Jun 3 04:03:37 1998 Lars Magne Ingebrigtsen - - * gnus.el: Gnus v5.6.11 is released. - -Wed Jun 3 03:33:50 1998 Lars Magne Ingebrigtsen - - * gnus.el: Checked doc string syntax throughout. - - * message.el (message-subject-re-regexp): Renamed. - -Wed Jun 3 03:33:05 1998 Simon Josefsson - - * message.el (message-ignored-subject-re): New variable. - -Wed Jun 3 03:25:13 1998 Sam Steingold - - * gnus-msg.el (gnus-bug-create-help-buffer): New variable. - (gnus-bug): Use it. - -1998-05-07 Hrvoje Niksic - - * nnmail.el: (nnmail-get-split-group): Use `regexp-quote' - when file name is a part of pattern. - - * nnmail.el (nnmail-crosspost-link-function): Ditto. - - * gnus-ems.el: Use `symbol-name' instead of `(format "%s" ...)'. - - * gnus-score.el (gnus-score-load-file): Use `regexp-quote' - when file name is a part of pattern. - -1998-05-06 Hrvoje Niksic - - * gnus-cache.el (gnus-cache-generate-active): Use `regexp-quote' - when file name is a part of pattern. - -Wed Jun 3 03:13:34 1998 Lars Magne Ingebrigtsen - - * nnfolder.el (nnfolder-delete-mail): Changed parameters. - (nnfolder-request-replace-article): Rename X-From-Line. - -Wed Jun 3 03:10:04 1998 Dan Christensen - - * nnfolder.el (nnfolder-adjust-min-active): Work. - -Mon Jun 1 05:27:28 1998 Lars Magne Ingebrigtsen - - * gnus-sum.el (gnus-summary-limit-to-age): Reversed time and - almost collapsed space! - - * nnmail.el (nnmail-days-to-time): Computed wrong time. - -Mon Jun 1 05:19:46 1998 Kim-Minh Kaplan - - * gnus-sum.el (gnus-dependencies-add-header): Break loops. - -Mon Jun 1 05:13:34 1998 Fabrice POPINEAU - - * gnus-cache.el (gnus-cache-generate-active): Regexp-quote. - -Mon Jun 1 04:31:23 1998 Lars Magne Ingebrigtsen - - * gnus.el: Gnus v5.6.10 is released. - -Mon Jun 1 03:25:33 1998 Lars Magne Ingebrigtsen - - * gnus-art.el (gnus-button-alist): Recognize bare mailto buttons - for Gnus. - - * nntp.el: Replaced all `message' calls. - -Mon Jun 1 03:13:46 1998 Wolfgang Rupprecht - - * nntp.el (nntp-encode-text): Removed spurious forward-line. - -Sat May 23 19:44:43 1998 Lars Magne Ingebrigtsen - - * gnus-agent.el (gnus-agent-fetch-session): Would infloop if - opening failed. - -Tue May 19 04:11:33 1998 Yoshiki Hayashi - - * nnheader.el (nnheader-translate-file-chars): Don't change - string. - -Tue May 19 03:07:45 1998 P. E. Jareth Hein - - * gnus-util.el (gnus-dd-mmm): New version. - -Tue May 19 03:00:39 1998 Lars Magne Ingebrigtsen - - * gnus.el: Changed address. - -Tue May 12 06:12:42 1998 Lars Magne Ingebrigtsen - - * gnus-agent.el (gnus-agent-expire): Delete more. - -Sun May 10 19:08:28 1998 Lars Magne Ingebrigtsen - - * gnus-group.el (gnus-group-read-ephemeral-group): Don't add - `address'. - -Sun May 3 18:01:01 1998 Lars Magne Ingebrigtsen - - * nnmail.el (nnmail-within-headers-p): Renamed. - - * message.el (message-cancel-news): If a Sender header doesn't - exist, compare From against `message-make-from'. - -Sun May 3 15:07:25 1998 Lars Balker Rasmussen - - * gnus-agent.el (gnus-agent-save-group-info): Fix - re-search-forward params. - -Sun May 3 15:04:02 1998 Lars Magne Ingebrigtsen - - * gnus-agent.el (gnus-agent-expire): Check for the size. - -Sat May 2 01:50:20 1998 Dan Christensen - - * nnfolder.el (nnfolder-goto-article): New version. - (nnfolder-read-folder): Fix. - - * nnmail.el (nnmail-within-headers): New function. - -Sat May 2 01:36:37 1998 Lars Magne Ingebrigtsen - - * nnfolder.el (nnfolder-goto-article): Thinkotypo search arguments. - - * nnheader.el (nnheader-find-file-noselect): Also bind - `find-file-hooks' to nil. - - * nnmail.el (nnmail-process-unix-mail-format): Don't use - `find-file-noselect'. - - * gnus-group.el (gnus-group-make-menu-bar): Typo. - -Fri May 1 21:59:35 1998 Lars Magne Ingebrigtsen - - * gnus.el: Gnus v5.6.9 is released. - -Fri May 1 21:54:30 1998 Lars Magne Ingebrigtsen - - * nnfolder.el (nnfolder-goto-article): Would infloop. - -Fri May 1 19:45:50 1998 Lars Magne Ingebrigtsen - - * gnus.el: Gnus v5.6.8 is released. - -Fri May 1 18:51:21 1998 Lars Magne Ingebrigtsen - - * nntp.el (nntp-request-newgroups): Use format-time-string. - - * message.el (message-fetch-field): Inhibit point-motion hooks. - -Fri May 1 18:33:06 1998 Wes Hardaker - - * gnus-score.el (gnus-adaptive-word-no-group-words): New variable. - -Fri May 1 16:56:32 1998 Lars Magne Ingebrigtsen - - * gnus-agent.el (gnus-agent-expire): Put point at the start of the - buffer. - - * gnus-soup.el (gnus-soup-parse-areas): Check whether the file - exists. - - * gnus-draft.el (gnus-draft-send): Use meta-information. - - * nnagent.el (nnagent-request-post): Store meta-information. - - * gnus-agent.el (gnus-agent-meta-information-header): New variable. - (gnus-agent-insert-meta-information): New function. - -Fri May 1 16:43:35 1998 Paul Franklin - - * message.el (message-generate-headers): Insert Sender when - required. - -Fri May 1 15:28:55 1998 Lars Magne Ingebrigtsen - - * gnus-util.el (gnus-dd-mmm): Accept "" dates. - - * gnus-cite.el (gnus-article-hide-citation): Don't remove button - when hiding. - - * gnus-msg.el (gnus-post-method): Allow ARG to override - `current'. - - * gnus-sum.el (gnus-remove-thread): Remove the dummy root - properly. - - * nnfolder.el (nnfolder-goto-article): New function. - (nnfolder-retrieve-headers): Use it. - (nnfolder-request-article): Ditto. - -Wed Apr 29 22:48:33 1998 Lars Magne Ingebrigtsen - - * gnus.el: Gnus v5.6.7 is released. - -Wed Apr 29 20:54:35 1998 Lars Magne Ingebrigtsen - - * gnus-sum.el (gnus-summary-update-info): Bind - gnuis-newsgroup-scored later. - (gnus-summary-prepare-threads): Check some more before inserting - dummy roots. - - * gnus-cache.el (gnus-cache-enter-article): Update marks - properly. - - * gnus-xmas.el (gnus-xmas-draft-menu-add): New function. - - * nntp.el (nntp-connection-timeout): Removed. - - * gnus-move.el (gnus-move-group-to-server): Delete nils. - - * nntp.el (nntp-close-server): Close more connections. - - * gnus-art.el (gnus-button-alist): Accept white space after colons - in things. - -Wed Apr 29 20:18:45 1998 Kurt Swanson - - * gnus-art.el (article-update-date-lapsed): Bind - `deactivate-mark'. - - * gnus-salt.el (gnus-pick-mode-map): Moved keys around to avoid - shadowing. - - * gnus-art.el (gnus-article-read-summary-keys): New version. - - * gnus-sum.el (gnus-summary-make-menu-bar): New for article mode. - - * gnus-msg.el (gnus-post-method): `current' custom. - -Wed Apr 29 19:04:27 1998 Lars Magne Ingebrigtsen - - * gnus-sum.el (gnus-summary-set-local-parameters): Ignore - quit-config. - (gnus-select-newsgroup): Use the value of gnus-fetch-old-headers. - - * message.el (message-post-method): Doc fix. - - * gnus.el (gnus-directory): dox fix. - -Tue Apr 28 03:32:17 1998 Lars Magne Ingebrigtsen - - * gnus-group.el (gnus-group-timestamp): Really get timestamp. - - * gnus.el (gnus-group-parameter-value): Use explicit iteration. - -Tue Apr 28 03:15:50 1998 Hallvard B. Furuseth - - * gnus-util.el (gnus-alive-p): Check for binding. - -Tue Apr 28 03:00:16 1998 Lars Magne Ingebrigtsen - - * gnus-sum.el (gnus-parent-headers): Don't infloop on nil - References. - - * gnus-art.el (gnus-article-mode): Don't kill local vars. - - * score-mode.el (score-mode-syntax-table): Change syntax. - -Mon Apr 27 00:26:01 1998 Lars Magne Ingebrigtsen - - * gnus.el: Gnus v5.6.6 is released. - -Mon Apr 27 00:07:11 1998 Lars Magne Ingebrigtsen - - * gnus-art.el (gnus-request-article-this-buffer): Viewing pseudos - in nneething groups bugged. - - * gnus-sum.el (gnus-summary-prepare-threads): Dummy roots and - dormants and stuff. - -Sun Apr 26 23:34:40 1998 Lars Magne Ingebrigtsen - - * gnus-cache.el (gnus-cache-file-name): Use FULL. - - * nnheader.el (nnheader-translate-file-chars): Allow FULL - parameter. - - * gnus-cache.el (gnus-cache-file-name): Translate all colons. - -Sun Apr 26 19:27:56 1998 Justin Sheehy - - * nntp.el (nntp-rlogin-parameters): Doc fix. - -Sun Apr 26 19:21:12 1998 Lars Magne Ingebrigtsen - - * gnus-art.el (gnus-summary-save-in-mail): Not a command. - -Sun Apr 26 19:16:03 1998 James Troup - - * gnus-sum.el (gnus-summary-expire-articles-now): Work. - -Sun Apr 26 14:34:06 1998 Lars Magne Ingebrigtsen - - * gnus-sum.el (gnus-build-sparse-threads): Break loops. - (gnus-summary-print-article): Save excursion to try to preserve - local/bound variable messup. - - * gnus-salt.el (gnus-tree-read-summary-keys): Put point in article - buffer. - - * gnus-undo.el (gnus-undo): New group. - (gnus-undo-limit): New variable. - (gnus-undo-register-1): Use it. - - * gnus-sum.el (gnus-summary-update-info): Don't nix out scores. - - * gnus-start.el (gnus-active-to-gnus-format): Removed "." from - quoting. - - * gnus.el (gnus-cache-directory): Moved here. - (gnus-predefined-server-alist): Use. - - * message.el (message-autosave-directory): Put back in. - (message-set-auto-save-file-name): Use if Gnus isn't running. - - * gnus-util.el (gnus-alive-p): Moved here. - - * message.el (message-autosave-directory): Removed. - (message-set-auto-save-file-name): Don't use it. - - * gnus.el: Use gnus-buffer-exists-p throughout. - - * gnus-uu.el (gnus-uu-save-article): Use gnus-kill-buffer. - - * message.el (message-make-in-reply-to): Check more for strange - From lines. - - * gnus-art.el (gnus-article-mode): Don't nix out vars. - -Sun Apr 26 14:05:40 1998 Frank Bennett - - * nnmail.el (nnmail-move-inbox): Push error'ed mailboxes onto the - list. - -Sun Apr 26 13:01:53 1998 Lars Magne Ingebrigtsen - - * gnus-score.el (gnus-score-save): Use it. - - * score-mode.el (score-mode-syntax-table): New table. - - * nnmbox.el: Commentary fix. - -Sun Apr 26 12:59:00 1998 Richard Stallman - - * message.el (message-mode): New adaptive fill defaults. - -Sun Apr 26 12:50:38 1998 Jim Radford - - * gnus-start.el (gnus-active-to-gnus-format): Groups that start - with dots. - -1998-04-11 Richard Stallman - - * gnus/gnus-art.el (gnus-emphasis-alist): Use nth, not caddr. - -Sat Apr 25 15:33:57 1998 Kim-Minh Kaplan - - * gnus-sum.el (gnus-build-sparse-threads): Handle loops. - -Sat Apr 25 15:09:54 1998 Lars Magne Ingebrigtsen - - * gnus.el (gnus-valid-select-methods): nngateway is post-mail. - -Fri Apr 24 21:32:14 1998 Lars Magne Ingebrigtsen - - * gnus.el: Gnus v5.6.5 is released. - -Fri Apr 24 21:19:21 1998 Lars Magne Ingebrigtsen - - * gnus-msg.el (gnus-post-method): Doc fix. - (gnus-post-method): Reversed semantics. - -1998-04-01 Jan Vroonhof - - * gnus-msg.el (gnus-post-method): Customized. Added 'native - option. In the function, added support for new value. - -Fri Apr 24 20:04:15 1998 Lars Magne Ingebrigtsen - - * nnmbox.el (nnmbox-request-create-group): New function. - -Sun Apr 12 07:55:16 1998 Lars Magne Ingebrigtsen - - * gnus-agent.el (gnus-agent-save-group-info): Only do those that - are covered. - -Tue Apr 7 11:26:31 1998 Lars Magne Ingebrigtsen - - * nntp.el (nntp-authinfo-file): Doc fix. - -1998-03-31 Ken Raeburn - - * nnml.el (nnml-request-expire-articles): Sort active-articles, - then only expire the intersection of that set with the requested - articles. - -Wed Apr 1 16:01:44 1998 Lars Magne Ingebrigtsen - - * message.el (message-supersede): Check Sender. - (message-cancel-news): Fix Sender check. - -Sun Mar 29 11:54:33 1998 Lars Magne Ingebrigtsen - - * nnkiboze.el (nnkiboze-generate-group): Would mess up newsrs - hashtb. - (nnkiboze-enter-nov): Created bogus Xrefs headers. - - * gnus-agent.el (gnus-agent-save-group-info): New function. - - * gnus-start.el (gnus-get-unread-articles): Use it. - - * message.el (message-expand-group): Allow completion from in the - middle of strings. - (message-font-lock-keywords): Work when mail-header-separator is - "". - -Sun Mar 29 09:56:00 1998 Lars Magne Ingebrigtsen - - * gnus.el: Gnus v5.6.4 is released. - -Sun Mar 29 09:47:58 1998 Lars Magne Ingebrigtsen - - * nnkiboze.el (nnkiboze-request-delete-group): Would bug out when - deleting files. - -Sat Mar 28 08:48:31 1998 Lars Magne Ingebrigtsen - - * nntp.el (nntp-encode-text): Use `nntp-end-of-line'. - -Thu Mar 26 15:29:51 1998 Lars Magne Ingebrigtsen - - * gnus-agent.el (gnus-agent-expire): Check size of history file. - - * message.el (message-mode): Doc fix. - -Mon Mar 23 14:21:34 1998 Mike McEwan - - * gnus-score.el (gnus-score-default-type): Doc fix. - -Mon Mar 23 14:12:01 1998 Lars Magne Ingebrigtsen - - * gnus-int.el (gnus-request-body): Do the same as HEAD. - - * gnus-art.el (gnus-article-edit-article-hook): Removed. - -Mon Mar 23 14:09:56 1998 jari aalto - - * gnus-art.el (gnus-article-edit-article-hook): New hook. - -1998-03-19 Jan Vroonhof - - * nntp.el (nntp-open-rlogin): Wrap in save-excursion - -Thu Mar 19 16:43:59 1998 Joe Buehler - - * gnus-util.el (gnus-date-iso8601): Use simple string. - -Thu Mar 19 15:18:00 1998 Lars Magne Ingebrigtsen - - * gnus.el: Gnus v5.6.3 is released. - -Thu Mar 19 15:09:14 1998 Wes Hardaker - - * gnus-win.el (gnus-delete-windows-in-gnusey-frames): Make sure - there are no nil buffers. - -1998-03-17 Per Abrahamsen - - * gnus-uu.el (gnus-uu-digest-headers): Add `Content-Type' and - `Content-Transfer-Encoding'. - -1998-03-18 Per Abrahamsen - - * message.el (message-header-lines): Added `:format'. - -1998-03-18 Simon Josefsson - - * nndoc.el: dummy request-accept-article - -Thu Mar 19 14:10:25 1998 Lars Magne Ingebrigtsen - - * gnus-sum.el (gnus-summary-next-subject): Expand threads. - - * gnus-agent.el (gnus-agent-group-mode-hook, - gnus-agent-summary-mode-hook): New variables. - (gnus-agent-mode): Run them. - -1998-03-14 SL Baur - - * gnus-xmas.el (gnus-xmas-group-startup-message): Tell gnus-start - we've already drawn the pretty Gnu graphic. - -Thu Mar 19 12:44:12 1998 Lars Magne Ingebrigtsen - - * gnus-msg.el: Would use nil group names. - - * nntp.el (nntp-send-authinfo): Send authinfo to "force"d - servers. - - * gnus-util.el (gnus-parse-netrc): Accept the "force" token. - - * message.el (message-cancel-news): Compare Sender header, not - From header. - -Tue Mar 17 15:07:18 1998 Lars Magne Ingebrigtsen - - * gnus-art.el (article-hide-headers): Fold case. - -Sat Mar 14 17:57:35 1998 Lars Magne Ingebrigtsen - - * gnus-util.el (gnus-horizontal-recenter): New window-end may - return nil. - -Fri Mar 13 22:12:30 1998 Lars Magne Ingebrigtsen - - * gnus-agent.el (gnus-agent-fetch-session): Check whether server - is up before fetching. - - * gnus-win.el (gnus-window-frame-focus): New variable. - (gnus-configure-windows): Use it. - - * gnus-sum.el (gnus-summary-catchup-and-exit): Don't select next - when in an ephemeral group. - - * gnus-agent.el (gnus-agent-expire): Message end. - (gnus-agent-expire-all): New variable. - (gnus-agent-expire): Use it. - -Fri Mar 13 22:07:17 1998 Shenghuo ZHU - - * gnus-agent.el (gnus-agent-high-scored-p): Wrong value. - -Fri Mar 13 21:10:24 1998 Lars Magne Ingebrigtsen - - * nnvirtual.el (nnvirtual-request-group): Force updating of info. - -Sun Mar 8 20:46:51 1998 Lars Magne Ingebrigtsen - - * nnmail.el (nnmail-delete-incoming): Changed default. - -Sun Mar 8 14:05:25 1998 Lars Magne Ingebrigtsen - - * gnus.el: Gnus v5.6.2 is released. - -Sun Mar 8 00:35:09 1998 Lars Magne Ingebrigtsen - - * gnus-picon.el (gnus-get-buffer-name): Look in the assoc for the - variable. - - * nntp.el (nntp-wait-for): Check more for dead connections. - - * gnus-eform.el (gnus-edit-form-buffer): Moved back here. - - * gnus-win.el (gnus-window-to-buffer-helper): Return nil when - buffers don't exist. - - * nndraft.el (nndraft-request-restore-buffer): Remove Xref header, - not Xrefs. - -Sun Mar 8 00:00:04 1998 Lars Magne Ingebrigtsen - - * gnus.el: Gnus v5.6.1 is released. - -Sat Mar 7 22:15:46 1998 Lars Magne Ingebrigtsen - - * gnus.el (gnus-edit-form-buffer): Moved here. - - * gnus-agent.el (gnus-agent-expire-old): Removed. - (gnus-agent-expire-directory): Ditto. - (gnus-agent-expire-group): Even more ditto. - -Sat Mar 7 21:59:18 1998 Lars Magne Ingebrigtsen - - * gnus.el: Quassia Gnus v0.37 is released. - -Sat Mar 7 20:10:42 1998 Lars Magne Ingebrigtsen - - * gnus-agent.el (gnus-agent-expire-days): New variable. - (gnus-agent-expire): New function. - -Sat Mar 7 17:35:53 1998 Lars Magne Ingebrigtsen - - * gnus.el: Quassia Gnus v0.36 is released. - -Sat Mar 7 17:29:20 1998 Lars Magne Ingebrigtsen - - * nntp.el (nntp-wait-for): Reversed logic. - -Sat Mar 7 17:19:04 1998 Lars Magne Ingebrigtsen - - * gnus.el: Quassia Gnus v0.35 is released. - -Sat Mar 7 15:01:57 1998 Lars Magne Ingebrigtsen - - * gnus-picon.el (gnus-picons-x-face-sentinel): Check whether - gnus-picons-x-face-file-name exists. - - * gnus-art.el (gnus-article-read-summary-keys): Move window point - in the summary buffer. - - * nndoc.el (nndoc-type-alist): Allow spaces around separator. - - * gnus-sum.el (gnus-summary-edit-parameters): Interactive. - -Sat Mar 7 15:00:05 1998 Wes Hardaker - - * gnus-art.el (gnus-article-prepare): Mark articles as - downloadable. - -Wed Mar 4 22:33:27 1998 Ken Raeburn - - * gnus-int.el (gnus-get-function): New version, caches symbol - names. - -Fri Mar 6 01:10:22 1998 Ken Raeburn - - * nnml.el (nnml-article-to-file): Build pathname using - expand-file-name. (Thanks, Colin Rafferty, for catching - this.) - -Sat Feb 28 23:33:40 1998 Ken Raeburn - - * nnml.el (nnml-article-to-file): Don't add extra "/" when - building pathname. - - * nnheader.el (nnheader-file-to-number): Check value of - nnheader-numerical-short-files instead of checking if jka-compr is - loaded. - -1998-03-03 Dave Love - - * nnheader.el (nnheader-parse-head): Fix in-reply-to code. Return - nil consistently if not found. - -Sat Mar 7 13:50:44 1998 Lars Magne Ingebrigtsen - - * nntp.el: Check whether the connection died. - -1998-03-01 Kim-Minh Kaplan - - * gnus.texi (Easy Picons): Removed references to - `gnus-group-display-picons'. - (Hard Picons): Ditto. - -Mon Mar 2 16:17:36 1998 Lars Magne Ingebrigtsen - - * gnus-sum.el (gnus-summary-exit-no-update): Run - gnus-summary-prepare-exit-hook here as well. - -Sat Feb 28 13:35:26 1998 Lars Magne Ingebrigtsen - - * nntp.el (nntp-authinforc-file): Changed default. - (nntp-authinfo-file): Changed name. - (nntp-record-commands): New variable. - (nntp-record-command): New function. - - * gnus-agent.el (gnus-agent-group-path): Use real name of group. - - * gnus-sum.el (gnus-summary-insert-subject): Don't allow nil - articles. - (gnus-summary-read-group): Respect backward movement. - -1998-03-01 Kim-Minh Kaplan - - * gnus-win.el (gnus-window-to-buffer): change "*Picons*" to - `gnus-picons-buffer'. - (gnus-window-to-buffer-helper): Support dynamic picon buffer - name (i.e a symbol that names a function to be called). - (gnus-configure-frame): Use it. - (gnus-delete-windows-in-gnusey-frames): Use it. - (gnus-all-windows-visible-p): Use it. - (gnus-remove-some-windows): Use it. - - * gnus-picon.el (gnus-get-buffer-name): Use it. - (gnus-picons-kill-buffer): New function. - (gnus-picons-setup-buffer): New function. - (gnus-picons-set-buffer): Use them. - (gnus-picons-display-x-face): Put back the `buf' binding: it is - needed when `gnus-picons-display-where' is not set to article. - Also move the X-Face to the left, near the address. It seems more - logical. - -Sat Feb 28 08:27:20 1998 Lars Magne Ingebrigtsen - - * gnus.el: Quassia Gnus v0.34 is released. - -Sat Feb 28 08:17:37 1998 Lars Magne Ingebrigtsen - - * gnus.el: Quassia Gnus v0.33 is released. - -Sat Feb 28 08:10:27 1998 Lars Magne Ingebrigtsen - - * gnus-picon.el (gnus-picons-display-x-face): `buf' -- unbound - var. - -Sat Feb 28 08:03:23 1998 François Pinard - - * gnus: configure'd. - -Sat Feb 28 07:43:00 1998 Nelson Jose dos Santos Ferreira - - * nnsoup.el (nnsoup-store-reply): Fix double sep error. - -Sat Feb 28 07:01:17 1998 Lasse Rasinen - - * gnus-start.el (gnus-ask-server-for-new-groups): Message more. - -Fri Feb 27 13:26:34 1998 Lars Magne Ingebrigtsen - - * message.el (message-resend): Allow arbitrary Also's. - -1998-02-27 Dave Love - - * gnus-sum.el (gnus-simplify-subject-functions): Fix - customization, doc. - -1998-02-25 Dave Love - - * gnus-art.el (gnus-article-x-face-command): Replace leading `{'. - -Mon Feb 23 18:26:48 1998 Lars Magne Ingebrigtsen - - * gnus-agent.el (gnus-plugged): New command and keystroke. - - * gnus-ems.el (gnus-ems-redefine): Define - 'gnus-summary-set-display-table as a function that takes no - params. - - * gnus.el (gnus-interactive): Don't use gnus-sum macros. - (gnus-valid-select-methods): Include nnlistserv. - - * gnus.el: Autoloaded things to make byte-comp silent. - -Mon Feb 23 18:06:47 1998 Lars Magne Ingebrigtsen - - * gnus.el: Quassia Gnus v0.32 is released. - -Mon Feb 23 17:48:42 1998 Lars Magne Ingebrigtsen - - * gnus-cite.el (gnus-article-hide-citation-maybe): Wrong - interactive specs. - (gnus-cite-toggle): Maybe parse. - -Mon Feb 23 05:26:11 1998 Rui-Tao Dong ~{6-HpLN~} - - * nnweb.el (nnweb-type-definition): Fixed. - -Sun Feb 22 18:10:53 1998 Lars Magne Ingebrigtsen - - * gnus-agent.el (gnus-agent-group-path): Translate right chars. - (gnus-agent-toggle-plugged): Allow proper closing. - - * gnus-srvr.el (gnus-browse-read-group): Allow entering - non-ephemeral groups. - -Sun Feb 22 04:21:15 1998 Lars Magne Ingebrigtsen - - * gnus.el: Quassia Gnus v0.31 is released. - -Sun Feb 22 02:09:35 1998 Lars Magne Ingebrigtsen - - * gnus-sum.el (gnus-summary-highlight): Give undownloaded marks a - better face. - - * gnus-score.el (gnus-score-set): Take optional "warn". - (gnus-summary-score-entry): Use it. - - * gnus.el: Removed spurious * in defcustoms. - - * gnus-score.el (gnus-score-load-file): Reverse logic. - - * gnus-cite.el (gnus-article-hide-citation): Use markers to make - things work when wrapping. - - * gnus-sum.el (gnus-summary-exit): Stop prefetch. - -Sat Feb 21 02:12:42 1998 Lars Magne Ingebrigtsen - - * gnus-sum.el (gnus-get-newsgroup-headers): Buggy regexp. - -Sat Feb 21 00:51:22 1998 Lars Magne Ingebrigtsen - - * gnus.el: Quassia Gnus v0.30 is released. - -Sat Feb 21 00:09:14 1998 Lars Magne Ingebrigtsen - - * gnus-sum.el (gnus-summary-mark-article): Don't do anything if - the mark doesn't change. - - * gnus-art.el (gnus-article-prepare): Don't enter article into - cache. - - * gnus-sum.el (gnus-summary-reparent-thread): Don't mark as read. - (gnus-summary-mark-article): Don't do cache things here. - - * gnus-util.el (gnus-parse-netrc): Skip past macdefs. - -Fri Feb 20 22:56:22 1998 Lars Magne Ingebrigtsen - - * gnus-srvr.el (gnus-browse-unsubscribe-group): Wouldn't allow - unsubscription. - - * gnus-sum.el (gnus-summary-insert-subject): Allow inserting - articles outside limits. - - * gnus-start.el (gnus-dribble-enter): Update mode line. - - * gnus-srvr.el (gnus-browse-unsubscribe-group): Allow - unsubscription. - - * gnus-picon.el (gnus-article-display-picons): Check that the - extents are live first. - -Thu Feb 19 15:13:44 1998 Lars Magne Ingebrigtsen - - * gnus-group.el (gnus-useful-groups): Include gnus-bug. - -Thu Feb 19 02:28:17 1998 Jens-Ulrik Holger Petersen - - * gnus.el (gnus-group-history): Defined twice. - -Thu Feb 19 01:58:47 1998 Lars Magne Ingebrigtsen - - * gnus-sum.el (gnus-get-newsgroup-headers): Just use the header - value. - (gnus-summary-exit): Set global vars. - -Tue Feb 17 07:17:49 1998 Lars Magne Ingebrigtsen - - * gnus-sum.el (gnus-summary-stop-page-breaking): Mark page as no - longer broken. - (gnus-summary-exit): Purge the real name. - -Tue Feb 17 07:00:43 1998 Lars Magne Ingebrigtsen - - * gnus.el: Quassia Gnus v0.29 is released. - -Tue Feb 17 06:15:03 1998 Lars Magne Ingebrigtsen - - * nnmail.el (nnmail-purge-split-history): List of alists, not - alist. - -Mon Feb 16 20:22:04 1998 Lars Magne Ingebrigtsen - - * gnus.el: Quassia Gnus v0.28 is released. - -1998-02-16 Lars Magne Ingebrigtsen - - * message.el (message-dont-send): Make sure the article really is - saved. - - * nnmail.el (nnmail-purge-split-history): Alist; not a list of - alists. - -1998-02-16 Hrvoje Niksic - - * message.el (message-kill-to-signature): Do the right thing when - there is no signature. - -1998-02-16 Hrvoje Niksic - - * message.el (message-elide-elipsis): Add type and group. - (message-elide-region): Docfix. - -1998-02-16 Lars Magne Ingebrigtsen - - * gnus-util.el (gnus-run-hooks): Use unwind-protect instead of - save-excursion. - -1998-02-16 Per Abrahamsen - - * nntp.el (nntp-authinforc-file): Customized. - -Mon Feb 16 03:18:33 1998 Lars Magne Ingebrigtsen - - * gnus-nocem.el (gnus-nocem-unwanted-article-p): Don't look if the - hashtable doesn't exist. - - * gnus-start.el (gnus-ask-server-for-new-groups): Make sure the - killed groups hashtable exists. - -Sun Feb 15 23:02:11 1998 Lars Magne Ingebrigtsen - - * nntp.el (nntp-authinforc-file): Changed name and default. - (nntp-send-authinfo): Use it. - -Sun Feb 15 19:50:10 1998 Lars Magne Ingebrigtsen - - * gnus.el: Quassia Gnus v0.27 is released. - -Sun Feb 15 19:41:14 1998 Lars Magne Ingebrigtsen - - * gnus.el (gnus-ephemeral-servers): New variable. - * gnus-srvr.el (gnus-server-prepare): Use it. - * gnus-group.el (gnus-group-read-ephemeral-group): Ditto. - -Sun Feb 15 19:35:11 1998 Kurt Swanson - - * gnus-art.el (gnus-article-read-summary-keys): Go to top on - some. - -Sun Feb 15 19:26:21 1998 SeokChan LEE - - * message.el (message-ignored-supersedes-headers): Fix. - -Sun Feb 15 18:39:15 1998 Lars Magne Ingebrigtsen - - * gnus-salt.el (gnus-tree-close): Start killing buffer again. - - * gnus-sum.el (gnus-mark-article-as-read): Return t. - - * gnus-art.el (gnus-article-edit-mode): Run text mode hook. - -Sun Feb 15 17:31:19 1998 Roland Roberts - - * gnus-sum.el (gnus-nov-parse-line): Would bug out on bogus - References headers. - -Sun Feb 15 14:23:51 1998 Lars Magne Ingebrigtsen - - * gnus-art.el (gnus-article-current-summary): New variable. - (gnus-article-mode): Make it local. - - * gnus-score.el (gnus-summary-increase-score): Find the right - global score file. - - * gnus-start.el (gnus-setup-news): Don't find new newsgroups - unless plugged. - - * message.el (message-mode): Set font-lock things before running - mode hook. - - * gnus-agent.el (gnus-agent-group-path): Respect long file names. - -Sat Feb 14 21:31:25 1998 Lars Magne Ingebrigtsen - - * gnus-sum.el (gnus-summary-goto-last-article): Force jumping to - articles outside limit. - - * gnus-agent.el (gnus-agent-toggle-plugged): un/plug before hook. - -Sat Feb 14 21:08:03 1998 Kim-Minh Kaplan - - * gnus-xmas.el (gnus-xmas-article-display-xface): t t would make - faces disappear. - -Sat Feb 14 20:52:34 1998 Lars Magne Ingebrigtsen - - * nntp.el (nntp-netrc-file): New variable. - -Sat Feb 14 19:28:01 1998 Lars Magne Ingebrigtsen - - * gnus.el: Quassia Gnus v0.26 is released. - -Sat Feb 14 18:40:55 1998 Lars Magne Ingebrigtsen - - * gnus-agent.el (gnus-agent-directory): Translate file chars. - - * gnus-sum.el (gnus-summary-print-article): Don't display all - headers. - (gnus-summary-edit-parameters): New command and keystroke. - - * gnus-group.el (gnus-group-rename-group): Mark dribble. - -Sat Feb 14 18:39:45 1998 Fred Oberhauser - - * nnmail.el (nnmail-process-babyl-mail-format): Fix point - movement. - -Sat Feb 14 18:31:39 1998 Lars Magne Ingebrigtsen - - * gnus.el (gnus-group-get-parameter): Dix fix. - -Sat Feb 14 18:29:12 1998 Kim-Minh Kaplan - - * gnus-picon.el: Updated documentation. - -Sat Feb 14 18:26:53 1998 Joev Dubach - - * nntp.el (nntp-send-authinfo-from-file): Doc fix. - -Sun Jan 11 23:44:12 1998 Ken Raeburn - - * nnagent.el (nnagent-request-update-info): New no-op fn. - -Sat Feb 14 17:41:44 1998 Lars Magne Ingebrigtsen - - * gnus-srvr.el (gnus-browse-unsubscribe-group): Wouldn't allow - subscription of visited groups. - - * gnus-util.el (gnus-run-hooks): New function. - Use it everywhere. - - * nntp.el (nntp-authinfo-password): New variable. - (nntp-send-authinfo): Cache authinfo password. - - * gnus-sum.el (gnus-summary-mark-article-as-unread): Don't do - anything if the mark doesn't change. - -1998-01-17 Simon Josefsson - - * gnus-sum.el (gnus-summary-work-articles): change buffer - before looking at marked articles - (gnus-summary-work-articles): better check of marked articles - -Sat Feb 14 15:10:36 1998 Lars Magne Ingebrigtsen - - * nntp.el (nntp-send-authinfo): Use new .netrc functionality. - - * gnus-util.el (gnus-netrc-syntax-table): New variable. - (gnus-parse-netrc): New function. - (gnus-netrc-machine): Ditto. - (gnus-netrc-get): Ditto. - - * gnus-draft.el (gnus-draft-make-menu-bar): Added deletion. - - * gnus.el (gnus-expert-user): Dix fox. - - * nnmail.el (nnmail-article-group): Remove duplicates from split. - - * message.el (message-check-news-header-syntax): Check more on - Message-ID. - - * nnmh.el: Don't call nnmail-activate. - - * gnus.el: User-variabelize all custom vars. - -Fri Feb 13 22:40:39 1998 Lars Magne Ingebrigtsen - - * gnus.el: Quassia Gnus v0.25 is released. - -Fri Feb 13 19:01:19 1998 Lars Magne Ingebrigtsen - - * nndoc.el (nndoc-type-alist): Allow blank lines to separate - headers from bodies. - - * gnus-art.el (gnus-article-edit): Restore Date header. - - * gnus-async.el (gnus-asynch-obarray): New variable. - (gnus-async-prefetched-article-entry): Use it. - (gnus-async-set-buffer): Use it. - - * nnmh.el (nnmh-active-number): Create parent dirs. - - * nntp.el (nntp-last-command): New variable. - (nntp-handle-authinfo): New function. - - * gnus-sum.el (gnus-summary-exit): Call purging function. - -Fri Feb 13 18:59:16 1998 François Pinard - - * nnmail.el (nnmail-get-new-mail): Don't clear split-history. - (nnmail-purge-split-history): New function. - -Fri Feb 13 18:36:16 1998 Lars Magne Ingebrigtsen - - * nntp.el (nntp-telnet-shell-prompt): Renamed. - -Fri Feb 13 18:35:23 1998 Sam Falkner - - * nntp.el (nntp-open-telnet-envuser): New variable. - -Fri Feb 13 18:29:23 1998 Lars Magne Ingebrigtsen - - * message.el (message-send-mail-function): Added smtpmail-send-it. - -1998-02-11 Dave Love - - * gnus-art.el (gnus-button-url): Don't lose in Emacs 20 with - browse-url-browser-function an alist, not a function. - (gnus-button-embedded-url): Likewise. - -Fri Feb 13 17:10:31 1998 Lars Magne Ingebrigtsen - - * gnus-cite.el (gnus-cite-localize): New function. - (gnus-cite-close): Renamed. - (gnus-cite-parse-maybe): Use it. - - * gnus-sum.el (gnus-summary-move-article): Move back to summary - buffer. - - * nnfolder.el (nnfolder-request-accept-article): Save excursion. - (nnfolder-request-move-article): Ditto. - - * nntp.el (nntp-find-connection): Don't message. - -Fri Feb 13 14:51:56 1998 MORIOKA Tomohiko - - * message.el (message-send-mail-with-qmail): Fix. - -1998-02-13 Per Abrahamsen - - * gnus-draft.el (gnus-draft-make-menu-bar): Added missing commands. - -1998-01-06 Per Abrahamsen - - * gnus/gnus-cus.el (gnus-score-parameters): Make `files' and - `exclude-files' widgets inline. - -Fri Feb 13 12:46:23 1998 Lars Magne Ingebrigtsen - - * gnus-sum.el (gnus-article-mark): Dox dox. - -Wed Feb 11 15:05:03 1998 Lars Magne Ingebrigtsen - - * gnus.el: Quassia Gnus v0.24 is released. - -Tue Feb 10 21:59:53 1998 Lars Magne Ingebrigtsen - - * gnus-agent.el (gnus-agent-fetch-session): Reversed reversal. - - * gnus-topic.el (gnus-topic-rename): Check whether the new name - exists. - -Tue Feb 10 21:39:47 1998 dave edmondson - - * message.el (message-font-lock-keywords): Allow : as a citation - ending. - -Tue Feb 10 20:09:02 1998 Lars Magne Ingebrigtsen - - * message.el (message-send): Removed dead code. - -Mon Feb 9 17:02:09 1998 Lars Magne Ingebrigtsen - - * message.el (message-fill-header): Fill to column 990. - - * gnus-score.el (gnus-score-load-file): Exclude all excluded - files. - -Mon Feb 9 16:55:41 1998 jari aalto - - * gnus-art.el (gnus-article-time-format): Extended variable. - -Mon Feb 9 16:27:59 1998 Lars Magne Ingebrigtsen - - * gnus-art.el (article-make-date-line): Make 8601 Dates. - (article-date-iso8601): New command and keystroke. - -Sun Feb 8 21:19:15 1998 Lars Magne Ingebrigtsen - - * message.el (message-ignored-mail-headers): Remove Xrefs. - - * nndoc.el (nndoc-open-document-hook): New variable. - -Sun Feb 8 21:01:33 1998 Istvan Marko - - * gnus-agent.el (gnus-unplugged): Typo fix. - -Sun Feb 8 18:34:31 1998 Kurt Swanson - - * gnus-score.el (gnus-score-thread-simplify): New variable. - -Sun Feb 8 18:31:35 1998 Lars Magne Ingebrigtsen - - * gnus-uu.el (gnus-uu-post-encode-mime): Call mmencode with - correct params. - -Sun Feb 8 18:13:58 1998 Lars Magne Ingebrigtsen - - * gnus.el: Quassia Gnus v0.23 is released. - -Sun Feb 8 17:20:40 1998 Lars Magne Ingebrigtsen - - * gnus-group.el (gnus-update-group-mark-positions): Bind `topic'. - - * message.el (message-expand-group): Added doc string. - - * nntp.el (nntp-wait-for): Don't change limit until after - accepting output. - -Sun Feb 8 16:44:36 1998 Richard Hoskins - - * message.el (message-kill-to-signature): Don't kill the - delimiter. - -Sun Feb 8 16:15:33 1998 Lars Magne Ingebrigtsen - - * gnus-sum.el (gnus-summary-prepared-hook): New hook. - (gnus-summary-read-group-1): Use it. - - * message.el (message-cite-original-without-signature): New - function. - (message-cite-function): Added to custom. - -1998-01-13 Per Abrahamsen - - * gnus/message.el (message-cite-original): Don't quote signature. - -Sun Feb 8 15:50:20 1998 Lars Magne Ingebrigtsen - - * gnus-group.el (gnus-group-unsubscribe-group): Protest against - empty group names. - -Mon Feb 2 18:56:22 1998 Lars Magne Ingebrigtsen - - * gnus-draft.el (gnus-draft-setup): Associate with drafts group. - - * message.el (message-header-format-alist): Fill references. - - * gnus-agent.el (gnus-category-read): Changed default. - (gnus-agent-handle-level): New variable. - (gnus-agent-fetch-session): Use it. - - * gnus-art.el (article-strip-all-blank-lines): New command and - keystroke. - -Sun Feb 1 18:00:54 1998 Lars Magne Ingebrigtsen - - * gnus-msg.el (gnus-inews-reject-message): Removed function. - (gnus-sent-message-ids-file): Removed. - (gnus-sent-message-ids-length): Ditto. - - * gnus-xmas.el (gnus-xmas-summary-set-display-table): Ditto. - - * gnus-sum.el (gnus-simplify-subject-fuzzy): Respect - `gnus-simplify-ignored-prefixes'. - (gnus-summary-set-display-table): Keep TAB. - -Thu Jan 15 22:47:38 1998 - - * gnus-art.el (gnus-request-article-this-buffer): Put it into the - backlog. - -Mon Jan 12 23:30:59 1998 Lars Magne Ingebrigtsen - - * gnus-sum.el (gnus-get-newsgroup-headers): Use the longest ID. - - * nnheader.el (nnheader-parse-head): Ditto. - -Thu Jan 8 09:47:18 1998 Lars Magne Ingebrigtsen - - * gnus-start.el (gnus-1): Use gnus-alive-p. - -Tue Jan 6 11:53:09 1998 Lars Magne Ingebrigtsen - - * gnus-art.el (gnus-article-prepare): Bind coding systems. - -Tue Jan 6 07:45:39 1998 Lars Magne Ingebrigtsen - - * gnus.el: Quassia Gnus v0.22 is released. - -Tue Jan 6 07:32:02 1998 Lars Magne Ingebrigtsen - - * message.el (message-kill-to-signature): Don't use mark. - -Tue Jan 6 07:30:46 1998 Russ Allbery - - * message.el (message-kill-to-signature): New command and keystroke. - -Tue Jan 6 06:39:29 1998 Lars Magne Ingebrigtsen - - * gnus-sum.el (gnus-summary-print-article): New defaults for - headers and stuff. - - * gnus-agent.el (gnus-agent-batch): New command. - - * nnoo.el (nnoo-execute): Copy vars from parent into child. - (nnoo-parent-function): Ditto. - - * gnus-draft.el (gnus-draft-setup): Removed message. - - * gnus-start.el (gnus-read-descriptions-file): Naked muleism. - -Mon Jan 5 05:20:16 1998 Lars Magne Ingebrigtsen - - * nnml.el (nnml-generate-nov-databases-1): Fix lower bound on - empty groups. - -Sun Jan 4 14:38:36 1998 Lars Magne Ingebrigtsen - - * gnus.el: Quassia Gnus v0.21 is released. - -Sun Jan 4 14:28:35 1998 Lars Magne Ingebrigtsen - - * gnus.el: Quassia Gnus v0.20 is released. - -1997-12-10 Per Abrahamsen - - * gnus/gnus-msg.el (gnus-inews-insert-mime-headers): Added - documentation. - (gnus-inews-insert-mime-headers): Made it work with Emacs MULE. - (gnus-inews-insert-mime-headers): Added as option to - `message-header-hook'. - -1997-12-22 Per Abrahamsen - - * gnus/gnus-art.el (gnus-button-alist): Assume msg-id after "in - message". - -1997-12-22 Simon Josefsson - - * nnmail.el (nnmail-get-new-mail): Make nnmail-tmp-directory - -1997-12-28 Per Abrahamsen - - * gnus/gnus-group.el (gnus-group-fetch-faq): Convert `.' in group - name to `/'. - -Sun Jan 4 13:35:14 1998 Lars Magne Ingebrigtsen - - * nndraft.el (nndraft-request-associate-buffer): Open the damn - server first. Sheesh. - - * gnus-draft.el (gnus-draft-send): Bind message-send-hook to nil. - - * gnus-sum.el (gnus-summary-catchup): Don't nix out downloadable. - (gnus-summary-highlight): Highlight down/un as unread. - -Sun Jan 4 13:27:31 1998 Kim-Minh Kaplan - - * gnus-start.el (gnus-strip-killed-list): Fix syntax. - -Sun Jan 4 13:18:04 1998 Lars Magne Ingebrigtsen - - * nnsoup.el (nnsoup-store-reply): Bind mail-header-separator to - "". - - * gnus-xmas.el (gnus-xmas-agent-server-menu-add): New. - - * nnoo.el (nnoo-change-server): Get the right values. - -1998-01-04 Aki Vehtari - - * gnus-art.el (gnus-signature-limit): Add default values for - choices suggested by Per Abrahamsen . - (gnus-prompt-before-saving): Add :value t for sexp tag. - (gnus-split-methods): Add default values for choices. - - * gnus-score.el (gnus-home-score-file): Add non-nil default for - function. - (gnus-home-adapt-file): Ditto. - - * gnus-sum.el (gnus-move-split-methods): Add default values for - choices. - - * nnmail.el (nnmail-list-identifiers): Add default values for - choices suggested by Per Abrahamsen . - -Sun Jan 4 11:31:42 1998 Lars Magne Ingebrigtsen - - * gnus.el: Quassia Gnus v0.19 is released. - -Sun Jan 4 10:42:53 1998 Felix Lee - - * nntp.el (nntp-open-rlogin): Use a list of parameters. - -Sun Jan 4 10:25:05 1998 Lars Magne Ingebrigtsen - - * gnus-agent.el (gnus-agent-fetch-groups): New command. - - * gnus-sum.el (gnus-summary-print-article): Changed order of - parameters. - -Sun Jan 4 10:24:07 1998 Michael R. Cook - - * gnus-sum.el (gnus-summary-print-article): Use process/prefix. - -Sun Jan 4 05:29:38 1998 Lars Magne Ingebrigtsen - - * gnus-uu.el: Changed spurious defconsts to defvars. - - * nnmail.el (nnmail-get-spool-files): Quote group name. - - * gnus-agent.el (gnus-agent-fetch-group-1): Fetch ticked articles. - (gnus-agent-fetch-group-1): Never mind. - -Sat Dec 20 22:33:17 1997 Pete Ware - - * message.el (message-rename-buffer): Check for nil dirs. - -Fri Dec 19 21:45:59 1997 Lars Magne Ingebrigtsen - - * nnml.el (nnml-request-create-group): Check for files. - -Fri Dec 19 21:39:43 1997 Hrvoje Niksic - - * message.el (message-mode): Fixed font-lock. - -Fri Dec 19 21:26:08 1997 Lars Magne Ingebrigtsen - - * gnus-cache.el (gnus-cache-read-active): Check for empty files. - -Sun Dec 14 11:46:50 1997 Lars Magne Ingebrigtsen - - * gnus-uu.el (gnus-uu-save-article): Quote all lines beginning - with a dash. - -1997-12-10 SL Baur - - * gnus-start.el (gnus-read-descriptions-file): Really bind and gag - Mule. - -Fri Dec 5 15:15:05 1997 Danny Siu - - * nndoc.el (nndoc-babyl-body-begin): quote the regexp for the - string "*** EOOH ***" properly. - (nndoc-babyl-head-begin): Same as above. - -Sun Dec 14 11:11:22 1997 Lars Magne Ingebrigtsen - - * gnus-uu.el (gnus-uu-pre-uudecode-hook): New hook. - - * gnus-sum.el (gnus-summary-read-group-1): Set mode line after - configuring. - -Sun Dec 14 11:03:26 1997 Wes Hardaker - - * gnus-score.el (gnus-adaptive-word-minimum): New variable. - (gnus-score-adaptive): Use it. - -Sun Dec 14 09:19:18 1997 Roland B. Roberts - - * gnus-group.el: Fixed hardcoded levels. - -Sat Dec 6 17:40:33 1997 Lars Magne Ingebrigtsen - - * gnus.el: Quassia Gnus v0.18 is released. - -Sat Dec 6 17:27:04 1997 Kim-Minh Kaplan - - * gnus-picon.el (gnus-picons-remove): Race condition. - -Sat Dec 6 17:23:26 1997 Christian von Roques - - * gnus-start.el (gnus-read-descriptions-file): Fix - enable-multibyte-characters. - -1997-12-05 Dave Love - - * gnus-nocem.el (gnus-nocem-message-wanted-p): Fix paren typpo. - (gnus-nocem-issuers): Allow sexp alternative in :type for alists. - -1997-12-05 Dave Love - - * gnus-art.el (gnus-visible-headers): Add X-sent:. - -Sat Dec 6 17:16:28 1997 Lars Balker Rasmussen - - * gnus-art.el (article-make-date-line): Don't add extra newlines. - -1997-11-27 MORIOKA Tomohiko - - * nnmail.el (nnmail-file-coding-system): Use `raw-text' in - default. - - * nnheader.el (nnheader-file-coding-system): Use `raw-text' in - default. - -Sat Dec 6 17:04:40 1997 Kim-Minh Kaplan - - * nnml.el (nnml-parse-head): Out-of-bounds fix. - - * nndraft.el (nndraft-request-associate-buffer): Get proper file - name. - -Sat Dec 6 15:35:37 1997 Gary D. Foster - - * gnus-group.el: Added backspace. - -Thu Nov 27 19:56:59 1997 Lars Magne Ingebrigtsen - - * gnus-agent.el (gnus-summary-set-agent-mark): Remove marks - properly. - -1997-11-27 Christoph Wedler - - * smiley.el (smiley-buffer): Provide `help-echo'. - -Thu Nov 27 17:33:45 1997 Lars Magne Ingebrigtsen - - * gnus-util.el (gnus-output-to-rmail): Always save buffer. - - * nntp.el (nntp-close-server): Don't sleep for me, Argentina. - (nntp-request-close): You neither. - -1997-11-19 Per Abrahamsen - - * message.el (message-header-lines): New widget. - (message-default-headers): Use it. - (message-default-mail-headers): Use it. - (message-default-news-headers): Use it. - -1997-11-24 Andreas Jaeger - - * gnus-start.el (gnus-read-descriptions-file): Add missing quote. - -Wed Nov 26 18:19:29 1997 Lars Magne Ingebrigtsen - - * nnweb.el (nnweb-type-definition): Rescued dejanewsold. - - * gnus-mh.el (gnus-summary-save-in-folder): Reverted to old - version. - - * gnus-sum.el (gnus-kill-or-deaden-summary): Save excursion. - - * gnus.el: Only require gnus-load in Emacsen 19. - - * gnus-start.el (gnus-setup-news): Always push archive server. - - * gnus-sum.el (gnus-read-header): Would bug out on sparse - articles. - -Wed Nov 26 17:50:41 1997 Kurt Swanson - - * gnus-ems.el (gnus-mule-cite-add-face): Work. - -Wed Nov 26 17:40:57 1997 Lars Magne Ingebrigtsen - - * gnus.el: Quassia Gnus v0.17 is released. - -Wed Nov 26 16:04:25 1997 Lars Magne Ingebrigtsen - - * gnus-sum.el (gnus-summary-move-article): Don't work on canceled - articles. - - * gnus-start.el (gnus-subscribe-hierarchical-interactive): Use - `read-char-exclusive'. - - * gnus-sum.el (gnus-summary-mode): Localize - gnus-summary-dummy-line-format. - - * nnml.el (nnml-open-nov): Check that the file exists before - inserting it. - - * gnus-art.el (article-date-ut): Insert a newline if needed. - - * gnus-score.el (gnus-score-edit-current-scores): Protect against - nil score files. - - * gnus-start.el (gnus-newsrc-parse-options): Be more correct -- - match only hierarchies. - (gnus-gnus-to-quick-newsrc-format): Changed warning. - -Wed Nov 26 15:47:40 1997 Greg Klanderman - - * messagexmas.el (message-xmas-maybe-fontify): New definition. - -Wed Nov 26 15:43:53 1997 Lars Magne Ingebrigtsen - - * gnus-start.el (gnus-setup-news): Protect against nil - gnus-message-archive-method. - -1997-11-26 Christoph Wedler - - * gnus-art.el (gnus-article-edit-done): Update headers "Lines:", - "Content-Length:" and "X-Content-Length:" when present. - -Wed Nov 26 15:08:17 1997 Lars Magne Ingebrigtsen - - * nnmail.el (nnmail-process-unix-mail-format): Pop to the right - buffer on error. - (nnmail-process-mmdf-mail-format): Ditto. - -Wed Nov 26 13:54:04 1997 Joe Reiss - - * gnus-art.el (gnus-summary-save-in-rmail): Return the name of the - file. - -Wed Nov 26 13:50:01 1997 Alastair Burt - - * smiley.el: Balloon help, etc. - -Wed Nov 26 13:45:35 1997 Lars Magne Ingebrigtsen - - * gnus-util.el (gnus-kill-all-overlays): Remove check for XEmacs. - -1997-09-30 Dave Love - - * message.el: Don't require rmail. - -Wed Nov 26 13:37:50 1997 Kurt Swanson - - * gnus-group.el (gnus-group-setup-buffer): set-buffer. - -Wed Nov 26 13:31:54 1997 Lars Magne Ingebrigtsen - - * gnus-score.el (gnus-score-load-file): Don't create empty score - files when doing decays. - -Wed Nov 26 13:28:04 1997 Renaud Rioboo - - * nnmail.el (nnmail-move-inbox): Only bind default-directory when - calling external function. - -Wed Nov 26 13:03:45 1997 IWAMURO Motonori - - * gnus-kill.el (gnus-batch-score): Newsrc thinko. - -Wed Nov 26 10:31:17 1997 Lars Magne Ingebrigtsen - - * nnheader.el (nnheader-parse-head): Would break on Message-ID's - that spanned several lines. - - * gnus-util.el (gnus-date-iso8601): Didn't pick out the date - header. - - * gnus-demon.el (gnus-demon-scan-mail): Clean inboxes. - -1997-11-25 Christoph Wedler - - * gnus-picon.el (gnus-picons-x-face-sentinel): Would bug out in - headers with two X-Face lines. - -Wed Nov 26 08:54:26 1997 Lars Magne Ingebrigtsen - - * gnus-sum.el (gnus-summary-update-info): Would use wrong group - name. - -1997-11-26 Hrvoje Niksic - - * gnus-spec.el (gnus-compile): Avoid multiple `c*addr's. - (gnus-compile): Require `bytecomp'. - -1997-11-25 Hrvoje Niksic - - * gnus-util.el (gnus-prin1): Bind `print-readably' to t. - - * gnus-xmas.el (gnus-xmas-kill-all-overlays): New function. - (gnus-xmas-define): Use it. - - * gnus-art.el (gnus-stop-date-timer): Use `nnheader-cancel-timer'. - - * message.el (message-header-lines): Specify format. - - * gnus-xmas.el (gnus-xmas-move-overlay): Use BUFFER. - (gnus-byte-code): Use `indirect-function'. - - * gnus-cite.el (gnus-cite-add-face): Would assign free variable. - -Wed Nov 26 08:31:28 1997 Lars Magne Ingebrigtsen - - * gnus-art.el (gnus-stop-date-timer): Cancel instead of delete. - (gnus-start-date-timer): Use the numerical prefix. - -Tue Nov 25 20:03:34 1997 Lars Magne Ingebrigtsen - - * gnus-draft.el (gnus-group-send-drafts): Activate group first. - -Tue Nov 25 19:57:55 1997 Dan Christensen - - * gnus-group.el (gnus-group-process-prefix): Skip topics. - -Tue Nov 25 19:54:00 1997 Lars Magne Ingebrigtsen - - * gnus-move.el (gnus-move-group-to-server): Protect agains - nil-ness. - -Tue Nov 25 19:03:38 1997 Lars Magne Ingebrigtsen - - * gnus.el: Quassia Gnus v0.16 is released. - -Tue Nov 25 16:05:01 1997 Lars Magne Ingebrigtsen - - * gnus-sum.el (gnus-read-header): Remove thread entry before - rebuilding. - - * gnus-cite.el (gnus-cite-add-face): Keep track of all overlays. - - * gnus-art.el (article-update-date-lapsed): New function. - (gnus-start-date-timer): New command. - (article-date-ut): Put the face in the right place. - (article-date-ut): Would move around. - - * gnus-group.el (gnus-group-read-ephemeral-group): Accept server - names. - - * gnus-srvr.el (gnus-browse-foreign-server): Use proper server - names. - - * gnus.el (gnus-group-prefixed-name): Give the right result for - native groups. - - * nnheader.el (nnheader-directory-files): New function. - - * nnmh.el (nnmh-request-list-1): Reversed check. - - * nnfolder.el (nnfolder-delete-mail): Would skip backwards one - line too much. - -Tue Nov 25 14:44:02 1997 SeokChan LEE - - * message.el (message-ignored-supersedes-headers): Typo. - -Mon Nov 24 18:46:37 1997 Lars Magne Ingebrigtsen - - * gnus.el: Quassia Gnus v0.15 is released. - -Mon Nov 24 18:07:21 1997 Lars Magne Ingebrigtsen - - * gnus-ems.el: Also check major version names. - -1997-10-05 SL Baur - - * message.el (require 'rmail): Put guard around. - * nnbabyl.el (require 'rmail): Ditto. - -Mon Nov 24 17:36:00 1997 Lars Magne Ingebrigtsen - - * message.el (message-reply): Respect Mail-Copies-To even when - `to-address'. - -Mon Nov 24 17:32:47 1997 Thor Kristoffersen - - * nntp.el (nntp-request-close): Sleep one second. - -Mon Nov 24 16:18:19 1997 Lars Magne Ingebrigtsen - - * gnus-sum.el (gnus-summary-read-group-1): Update marks when not - entering group. - - * gnus-start.el (gnus-setup-news): Get correct value of archive - server. - -Wed Oct 8 20:29:35 1997 Robert Bihlmeyer - - * message.el (message-make-organization): Don't let the - environment variable override a user-set organization. - -Mon Nov 24 14:09:00 1997 Lars Magne Ingebrigtsen - - * nnml.el (nnml-open-nov): Don't use find-file. - - * gnus-sum.el (gnus-last-newsgroup-variables-set): New variable. - (gnus-set-global-variables): Don't do to much; gets run off of - pre-command-hook. - Got rid of gnus-set-global-variables throughout. - (gnus-summary-exit): Update adaptive scoring here. - (gnus-summary-isearch-article): Widen. - - * nnml.el (nnml-parse-head): Work in empty buffers. - -1997-10-14 Hrvoje Niksic - - * gnus-xmas.el (gnus-xmas-group-startup-message): Check for image - formats correctly. - (gnus-xmas-modeline-glyph): Ditto. - -Mon Nov 24 13:58:12 1997 Hrvoje Niksic - - * gnus-spec.el (gnus-compile): Work under XEmacs. - -Mon Nov 24 07:15:45 1997 Lars Magne Ingebrigtsen - - * nnoo.el (nnoo-change-server): Push the right parent packend onto - the alist. - -Sun Nov 23 16:21:41 1997 Lars Magne Ingebrigtsen - - * gnus.el: Quassia Gnus v0.14 is released. - -Sun Nov 23 14:04:07 1997 Lars Magne Ingebrigtsen - - * gnus-start.el (gnus-read-descriptions-file): Make sure Mule is - bound. And gagged. - - * message.el (message-send-mail-with-mh): Use - `mh-new-draft-name'. - - * nnfolder.el (nnfolder-read-folder): Save new buffers. - - * gnus-sum.el (gnus-summary-make-menu-bar): Removed "write to - file". - - * gnus-util.el (gnus-byte-code): Use indirect-function. - - * nntp.el (nntp-open-telnet): Also accept 201. - - * gnus-sum.el (gnus-summary-reparent-thread): Update thread. - - * gnus-score.el (gnus-all-score-files): Don't do anything unless - GROUP. - - * nnmail.el (nnmail-split-it): Save-excursion. - (nnmail-group-pathname): Translate file chars. - -Sun Nov 23 13:41:10 1997 Gunnar Horrigmo - - * gnus-sum.el (gnus-summary-exit): Don't skip if group - disappeared. - -Sun Nov 23 13:32:55 1997 Lars Magne Ingebrigtsen - - * nnfolder.el (nnfolder-normalize-buffer): New function. - (nnfolder-save-mail): Use it. - (nnfolder-request-replace-article): Ditto. - -1997-11-19 Per Abrahamsen - - * message.el (message-header-lines): New widget. - (message-default-headers): Use it. - (message-default-mail-headers): Use it. - (message-default-news-headers): Use it. - -Sun Nov 23 12:44:38 1997 Lars Magne Ingebrigtsen - - * gnus-win.el (gnus-remove-some-windows): Also delete dead summary - windows. - - * gnus-score.el (gnus-score-adaptive): Check whether functions are - bound. - -Sun Nov 23 12:15:00 1997 Hallvard B. Furuseth - - * gnus-sum.el (gnus-summary-limit-include-thread): Interactive - fix. - -Sun Nov 23 07:06:58 1997 Lars Magne Ingebrigtsen - - * gnus-sum.el (gnus-summary-reparent-thread): Insert Message-ID in - proper place. - -Sat Nov 22 18:30:33 1997 Lars Magne Ingebrigtsen - - * gnus-cus.el (gnus-group-parameters): Add visible. - -Sat Nov 22 18:19:39 1997 Kim-Minh Kaplan - - * message.el (message-setup): Add a newline, if necessary. - -Sat Nov 22 18:04:34 1997 Lars Magne Ingebrigtsen - - * gnus-mh.el (gnus-summary-save-in-folder): Fix for default. - -Sat Nov 22 18:01:26 1997 Didier Verna - - * gnus-sum.el (gnus-summary-remove-bookmark): Interactive spec. - -Mon Nov 17 23:50:51 1997 Lars Magne Ingebrigtsen - - * gnus-art.el (article-display-x-face): Fold case. - -Thu Nov 13 22:57:23 1997 Kenichi Handa - - * gnus/gnus-start.el (gnus-read-descriptions-file): Decode - description if necessary. - - * gnus/nntp.el (nntp-coding-system-for-read): Set default value to - binary. - (nntp-coding-system-for-write): Likewise. - -Thu Nov 13 22:30:19 1997 seokchan lee - - * message.el (message-ignored-supersedes-headers): Ignore more - headers. - -Thu Nov 13 22:28:13 1997 Lars Magne Ingebrigtsen - - * message.el (message-separator-face): Lightened up. - (message-header-other-face): Ditto. - -Thu Nov 13 22:22:11 1997 jari aalto - - * nnmail.el (nnmail-process-mmdf-mail-format): Pop to buffer. - -Thu Nov 13 22:09:39 1997 Lars Magne Ingebrigtsen - - * gnus-start.el (gnus-start-draft-setup): Always create group. - - * gnus-agent.el (gnus-agent-fetch-headers): Translate file chars. - -Thu Nov 6 20:43:05 1997 Lars Magne Ingebrigtsen - - * gnus.el: Quassia Gnus v0.13 is released. - -Thu Nov 6 20:30:14 1997 Lars Magne Ingebrigtsen - - * nnlistserv.el: New backend. - -Thu Nov 6 01:53:51 1997 Stefan Waldherr - - * nnweb.el (nnweb-dejanewsold-search): New function. - -Thu Nov 6 01:52:43 1997 Lars Magne Ingebrigtsen - - * gnus-topic.el (gnus-topic-change-level): Really delete multiple - instances. - -Wed Nov 5 14:04:54 1997 Lars Magne Ingebrigtsen - - * gnus-topic.el (gnus-topic-update-topic-line): Possibly fix nil - numbers. - - * gnus-sum.el (gnus-summary-show-article): New command and - keystroke. - -Tue Nov 4 06:29:58 1997 Lars Magne Ingebrigtsen - - * gnus-score.el (gnus-score-adaptive): Use the home score file. - -Sat Oct 25 05:52:22 1997 Lars Magne Ingebrigtsen - - * gnus-art.el (gnus-article-save): Hide headers in the right - buffer. - - * gnus-picon.el (gnus-picons-xbm-face): New face. - -Sat Oct 25 00:39:42 1997 Lars Balker Rasmussen - - * gnus-art.el (gnus-article-fill-paragraph): New command and - keystroke. - -1997-10-16 Colin Rafferty - - * message.el (message-make-fqdn): Made certain that user-mail is - not nil. - -Sat Oct 25 00:18:32 1997 David S. Goldberg - - * gnus-art.el (article-hide-boring-headers): Use many-to. - -Fri Oct 24 23:48:39 1997 Lars Magne Ingebrigtsen - - * gnus-picon.el (gnus-picons-display-pairs): Don't add two bars. - (gnus-picons-try-face): Set the foreground color on the bar. - (gnus-picons-group-exluded-groups): New variable. - (gnus-group-display-picons): Use it. - -Mon Oct 13 00:01:35 1997 Lars Magne Ingebrigtsen - - * gnus-agent.el (gnus-agent-group-path): Translate file chars. - (gnus-agent-batch-fetch): New command. - (gnus-agent-fetch-group): Message. - -Sun Oct 12 23:54:55 1997 ISO-2022-JP - - * gnus-agent.el (gnus-agent-article-file-coding-system): New - variable. - -Sun Oct 12 16:46:11 1997 Lars Magne Ingebrigtsen - - * dgnushack.el (lpath): Reversed. - - * gnus-msg.el (gnus-summary-cancel-article): Use sym prefix. - - * gnus-art.el (article-translate-characters): New function. - (article-treat-dumbquotes): New command and keystroke. - -Sun Oct 5 20:09:31 1997 Lars Magne Ingebrigtsen - - * gnus-art.el (gnus-button-alist): No ' and " in News:. - - * gnus-msg.el (gnus-inews-insert-archive-gcc): Comp warn. - -Sat Oct 4 00:53:55 1997 Lars Magne Ingebrigtsen - - * gnus.el: Quassia Gnus v0.12 is released. - -Sat Oct 4 00:16:39 1997 Lars Magne Ingebrigtsen - - * gnus.el (gnus-plugged): Moved here. - - * nnmail.el (nnmail-delete-incoming): Changed default to nil. - - * gnus-int.el (gnus-request-scan): Don't do anything if - unplugged. - -Fri Oct 3 21:09:19 1997 Lars Magne Ingebrigtsen - - * gnus-art.el (gnus-ignored-headers): Doc fix. - - * gnus-demon.el (gnus-demon-add-nntp-close-connection): New - function. - (gnus-demon-nntp-close-connection): Ditto. - - * nntp.el (nntp-last-command-time): New variable. - (nntp-retrieve-data): Use it. - - * message.el (message-news-p): Messages with Posted-To aren't - news. - (message-mode): Heed message-yank-prefix when filling. - - * nndraft.el (nndraft-request-restore-buffer): Remove Xrefs and - Lines headers. - - * nntp.el (nntp-encode-text): Encode according to RFC977. - -Wed Oct 1 18:27:26 1997 Lars Magne Ingebrigtsen - - * gnus-msg.el (gnus-inews-insert-archive-gcc): gcc-self didn't - work if `gnus-message-archive-method' was nil. - - * nnmail.el (nnmail-article-group): Allow \\1 substitution. - -Sat Sep 27 12:57:44 1997 Lars Magne Ingebrigtsen - - * gnus-salt.el (gnus-pick-mouse-pick-region): Use it. - - * gnus-xmas.el (gnus-xmas-window-edges): New function. - - * gnus-score.el (gnus-score-edit-current-scores): Don't select - window. - -Sat Sep 27 12:52:31 1997 Hallvard B. Furuseth - - * messcompat.el ((boundp 'mail-mode-hook)): Check. - -Sat Sep 27 09:22:15 1997 Lars Magne Ingebrigtsen - - * nndraft.el (nndraft-possibly-change-group): Always open server. - - * gnus-sum.el (gnus-summary-pop-article): Force. - - * gnus-art.el (gnus-article-prepare): Push the article onto the - history. - - * gnus-sum.el (gnus-summary-pop-article): Pop to the right - article. - - * gnus-demon.el (gnus-demon-scan-news): Save excursion. - -Sat Sep 27 09:06:55 1997 Hallvard B. Furuseth - - * gnus-cache.el (gnus-summary-limit-include-cached): New command - and keystroke. - -Sat Sep 27 06:45:58 1997 Lars Magne Ingebrigtsen - - * gnus-uu.el (gnus-uu-invert-processable): Make interactive. - -Sat Sep 27 06:43:38 1997 Kim-Minh Kaplan - - * gnus-picon.el: Doc fixes. - -1997-09-23 Hrvoje Niksic - - * gnus.el: Removed definition of `custom-face-lookup'. - -Sat Sep 27 05:36:11 1997 Lars Magne Ingebrigtsen - - * nndraft.el: Would block nnmh. - - * gnus-sum.el (gnus-mark-article-as-unread): Don't allow marking - negative articles. - - * gnus-group.el (gnus-fetch-group): Use `gnus-no-server'. - - * gnus-agent.el (gnus-agent-with-fetch): Moved. - - * gnus-sum.el (gnus-nov-read-integer): Really skip to next field. - -Sat Sep 27 04:32:45 1997 Lars Magne Ingebrigtsen - - * gnus.el: Quassia Gnus v0.11 is released. - -Sat Sep 27 03:50:12 1997 Lars Magne Ingebrigtsen - - * message.el (message-send): Post without asking. - (message-mode): Modify paragraphs-start and paragraph-separate. - (message-newline-and-reformat): New command and keystroke. - -Thu Sep 25 00:13:41 1997 Lars Magne Ingebrigtsen - - * nnmail.el (nnmail-activate): Init server buffer. - -Wed Sep 24 04:11:59 1997 Lars Magne Ingebrigtsen - - * gnus-draft.el (gnus-draft-setup): Inexplicable binding problem - worked around. - - * nnsoup.el (nnsoup-always-save): Renamed. - -Wed Sep 24 04:11:02 1997 Nelson Jose dos Santos Ferreira - - * nnsoup.el (nnsoup-commit-reply-now): New variable. - (nnsoup-store-reply): Use it. - -Wed Sep 24 02:30:44 1997 Lars Magne Ingebrigtsen - - * gnus-ems.el (gnus-deactivate-mark): New alias. - -Tue Sep 23 07:56:07 1997 Lars Magne Ingebrigtsen - - * gnus.el: Win-away! - - * gnus-msg.el (gnus-setup-message): Don't trust make-symbol. - -Tue Sep 23 07:45:11 1997 Lars Magne Ingebrigtsen - - * gnus.el: Quassia Gnus v0.10 is released. - -Tue Sep 23 01:41:04 1997 Lars Magne Ingebrigtsen - - * gnus-sum.el (gnus-read-all-headers): New function. - (gnus-select-newsgroup): Use it. - (gnus-summary-refer-thread): Ditto. - (gnus-refer-thread-limit): New variable. - (gnus-summary-refer-thread): Use it. - - * gnus-nocem.el (gnus-nocem-message-wanted-p): New function. - (gnus-nocem-check-article): Use it. - (gnus-nocem-issuers): Dox ofx. - - * dgnushack.el (dgnushack-compile): Check for cus-edit. - - * message.el (message-included-forward-headers): Include Mime - headers. - (message-send): Allow posting without confirming from Agent. - -Mon Sep 22 05:43:14 1997 Lars Magne Ingebrigtsen - - * dgnushack.el (byte-compile-warnings): Don't warn about obsolete - variables. - - * gnus-sum.el (gnus-summary-refer-thread): New command and - keystroke. - (gnus-summary-limit-include-thread): New command and keystroke. - (gnus-summary-articles-in-thread): New function. - (gnus-articles-in-thread): Renamed. - -Sun Sep 21 23:54:50 1997 Lars Magne Ingebrigtsen - - * gnus.el: Quassia Gnus v0.9 is released. - -Sun Sep 21 23:38:46 1997 Lars Magne Ingebrigtsen - - * gnus.el (gnus-splash-face): ForestGreen everywhere. - - * gnus-sum.el (gnus-simplify-subject-fully): Use new variable. - (gnus-general-simplify-subject): Ditto. - -Sun Sep 21 23:34:13 1997 Kurt Swanson - - * gnus-sum.el (gnus-simplify-subject-functions): New variable. - (gnus-simplify-whitespace): New function. - - * gnus-util.el (gnus-map-function): New function. - -Sun Sep 21 23:22:04 1997 Michelangelo Grigni - - * gnus-score.el (gnus-score-regexp-bad-p): New function. - -Sun Sep 21 00:14:40 1997 Lars Magne Ingebrigtsen - - * gnus-score.el (gnus-summary-lower-score): Use sym pref. - (gnus-summary-increase-score): Use it. - - * gnus.el (gnus-current-prefix-symbol): New variable. - (gnus-current-prefix-symbols): New variable. - - * gnus-score.el (gnus-summary-increase-score): Take symbolic - prefix. - - * gnus.el (gnus-interactive): Removed. - (gnus-interactive): Renamed from gnus-interactive-1. - (gnus-symbolic-argument): New command. - - * gnus-draft.el (gnus-draft-send-message): Disable message - checks. - (gnus-draft-send): Ditto. - (gnus-draft-setup): Don't save buffer. - - * dgnushack.el (dgnushack-compile): Warn people about Custom. - - * gnus-group.el (gnus-group-iterate): Use gensymmed variables. - - * pop3.el (pop3-md5): `with-temp-buffer' doesn't exist in Emacs - 19.34. - - * nneething.el (nneething-directory): Defvarred. - - * message.el: Autoloaded nndraft things. - (message-set-auto-save-file-name): Use it. - - * dgnushack.el (dgnushack-compile): Warn about things. - - * gnus-art.el: Autoload w3-region. - - * gnus-vm.el (gnus-summary-save-in-vm): Simplified. - - * gnus.el: Changed `compiled-function-p' to `byte-code-function-p' - throughout. - - * gnus-sum.el (gnus-summary-edit-article): Supply additional - param. - - * gnus-group.el (gnus-group-iterate): Undo bogus change. - - * gnus-agent.el (gnus-agentize): Just call gnus-open-agent - directly. - - * gnus.el (gnus-interactive): New macro. - (gnus-interactive-1): New function. - - * gnus-sum.el (gnus-fetch-old-headers): Allow `invisible'. - (gnus-cut-thread): Use it. - (gnus-cut-threads): Ditto. - (gnus-summary-initial-limit): Ditto. - (gnus-summary-limit-children): Ditto. - - * gnus-art.el (gnus-article-edit-done): Accept a prefix arg. - (gnus-boring-article-headers): Allow `long-to' param. - (article-hide-boring-headers): Use it. - - * gnus-sum.el (gnus-summary-edit-article-done): Accept a - no-highlight param. - - * nntp.el (nntp-rlogin-program): New variable. - (nntp-open-rlogin): Use it. - - * nnvirtual.el (nnvirtual-request-post): New function. - - * gnus-msg.el (gnus-message-group-art): New variable. - - * gnus-draft.el (gnus-draft-setup): Don't use message-setup. - - * nndraft.el (nndraft): Allow editing articles. - - * gnus-ems.el (gnus-x-splash): Ditto. - - * gnus.el (gnus-splash-face): Darker face. - - * gnus-draft.el (gnus-draft-setup): Clobbered variables. - -Sat Sep 20 23:23:49 1997 Lars Magne Ingebrigtsen - - * gnus.el: Quassia Gnus v0.8 is released. - -Sat Sep 20 20:41:16 1997 Lars Magne Ingebrigtsen - - * gnus-start.el (gnus-setup-news-hook): New hook. - - * gnus-agent.el (gnus-agentize): Really set up queue group. - (gnus-open-agent): Setup queue here. - -Sat Sep 20 20:23:07 1997 Matt Simmons - - * message.el (message-set-auto-save-file-name): Make things work - without drafts. - -Sat Sep 20 18:32:02 1997 Lars Magne Ingebrigtsen - - * nnmh.el (nnmh-request-list-1): Check for links to ".". - - * nndraft.el (nndraft-possibly-change-group): New function. - - * gnus-agent.el (gnus-agent-queue-setup): New function. - -Thu Sep 18 04:54:59 1997 Lars Magne Ingebrigtsen - - * gnus.el: Quassia Gnus v0.7 is released. - -Thu Sep 18 03:33:54 1997 Lars Magne Ingebrigtsen - - * gnus-msg.el (gnus-setup-message): Slap a progn around forms. - - * nndraft.el (nndraft-articles): Make sure directory exists. - - * message.el (message-mode): Don't delete article. - - * nnmh.el (nnmh-request-accept-article): Don't save when - noinsert. - -Wed Sep 17 03:37:59 1997 Lars Magne Ingebrigtsen - - * nndraft.el (nndraft-directory): Changed defaults. - - * gnus-agent.el (gnus-agent-fetch-session): Bind command method. - -Wed Sep 17 03:28:36 1997 Lars Magne Ingebrigtsen - - * gnus.el: Quassia Gnus v0.6 is released. - -1997-08-17 SL Baur - - * dgnushack.el (dgnushack-compile): Ignore .el files beginning - with an `=' character. - -Wed Sep 17 02:30:04 1997 Lars Magne Ingebrigtsen - - * gnus-sum.el (gnus-build-sparse-threads): Allow display of looped - References. - - * gnus-agent.el (gnus-agent-fetch-group-1): Separated out into - function. - - * message.el (message-delete-not-region): New command and - keystroke. - -Tue Sep 16 00:58:26 1997 Lars Magne Ingebrigtsen - - * nndraft.el (nndraft-directory): Changed value. - - * message.el (message-kill-buffer): Disassociate draft. - (message-mode): Use kill hook to disassociate. - (message-disassociate-draft): Double-check. - - * gnus-agent.el (gnus-agentize): Don't set twice. - - * gnus-art.el (gnus-article-prepare): Go to the right line before - marking. - - * gnus-start.el: Renamed the drafts group. - - * gnus-agent.el (gnus-agent-lib-file): Changed name of directory. - - * gnus-draft.el (gnus-draft-mode): Simplify. - -Tue Sep 16 00:18:11 1997 Lars Magne Ingebrigtsen - - * gnus.el: Quassia Gnus v0.5 is released. - -Mon Sep 15 00:53:50 1997 Lars Magne Ingebrigtsen - - * gnus-sum.el (gnus-alter-header-function): New variable. - (gnus-nov-parse-line): Use it. - (gnus-get-newsgroup-headers): Ditto. - - * gnus-draft.el (gnus-group-send-drafts): Don't send when - unplugged. - - * gnus-sum.el (gnus-summary-read-group): Don't show-all when - skipping groups. - - * gnus-start.el (gnus-start-draft-setup): Changed name. - -Mon Sep 15 00:40:09 1997 Lars Magne Ingebrigtsen - - * gnus.el: Quassia Gnus v0.4 is released. - -Mon Sep 15 00:19:07 1997 Lars Magne Ingebrigtsen - - * gnus-sum.el (gnus-summary-goto-article): Accept Message-ID's. - -Sun Sep 14 21:41:35 1997 Lars Magne Ingebrigtsen - - * gnus-sum.el (gnus-group-make-articles-read): No params. - - * nndraft.el (nndraft-status-string): Fix. - - * gnus-draft.el (gnus-group-send-drafts): New command. - - * gnus-sum.el (gnus-compute-read-articles): Separated. - (gnus-update-read-articles): Allow computation. - - * nndraft.el (nndraft-articles): New function. - - * message.el (message-send): Disabled test. - -Sun Sep 14 21:17:34 1997 Lars Magne Ingebrigtsen - - * gnus.el: Quassia Gnus v0.3 is released. - -Sun Sep 14 01:51:45 1997 Lars Magne Ingebrigtsen - - * gnus-agent.el (gnus-agent-short-article): New variables. - - * message.el (message-set-auto-save-file-name): Use drafts. - - * nndraft.el (nndraft-request-expire-articles): Use it. - - * nnmh.el (nnmh-deletable-article-p): Change. - (nnmh-allow-delete-final): New variable. - - * gnus-msg.el (gnus-summary-send-draft): Removed. - - * gnus.el (gnus-article-mark-lists): Save unsendable marks. - - * gnus-sum.el (gnus-newsgroup-unsendable): New variable. - - * gnus-draft.el: New file. - - * gnus-sum.el (gnus-unsendable-mark): New variable. - - * nndraft.el (nndraft-execute-nnmh-command): Cleanup. - - * message.el (message-send-news): Use `gnus-request-post'. - - * gnus-agent.el (gnus-agentize): New command. - - * gnus-bcklg.el (gnus-backlog-remove-article): Remove the ident - from the list. - -Sun Sep 14 00:26:47 1997 Lars Magne Ingebrigtsen - - * gnus.el: Quassia Gnus v0.2 is released. - -Sun Sep 14 00:24:52 1997 Lars Magne Ingebrigtsen - - * gnus-score.el (gnus-score-headers): Make sure the summary buffer - exists. - -Sat Sep 13 23:35:28 1997 Greg Stark - - * gnus-ems.el (gnus-x-splash): New function. - -Sat Sep 13 22:46:16 1997 Lars Magne Ingebrigtsen - - * gnus-start.el (gnus-1): Use it. - - * gnus-ems.el (gnus-decode-coding-string): New alias. - - * message.el (message-unix-mail-delimiter): Dox fox. - - * nnmh.el (nnmh-request-list-1): Don't use coding system. - - * gnus-sum.el (gnus-summary-catchup): Reverse logic. - -Sat Sep 13 21:21:38 1997 Lars Magne Ingebrigtsen - - * gnus.el: Quassia Gnus v0.1 is released. diff --git a/lisp/Makefile.in b/lisp/Makefile.in deleted file mode 100644 index d143e8f..0000000 --- a/lisp/Makefile.in +++ /dev/null @@ -1,67 +0,0 @@ -datadir = @datadir@ -lispdir = @lispdir@ -prefix = @prefix@ -srcdir = @srcdir@ -subdir = lisp -top_srcdir = @top_srcdir@ - -EMACS = @EMACS@ -FLAGS = -batch -q -no-site-file -l ./dgnushack.el -INSTALL = @INSTALL@ -INSTALL_DATA = @INSTALL_DATA@ -SHELL = /bin/sh -VPATH = @srcdir@ - -total: - rm -f *.elc ; $(EMACS) $(FLAGS) -f dgnushack-compile - -all: - rm -f *.elc ; $(EMACS) $(FLAGS) -f dgnushack-compile - -warn: - rm -f *.elc ; $(EMACS) $(FLAGS) --eval '(dgnushack-compile t)' 2>&1 | egrep -v "variable G|inhibit-point-motion-hooks|coding-system|temp-results|variable gnus|variable nn|scroll-in-place|deactivate-mark|filladapt-mode|byte-code-function-p|print-quoted|ps-right-header|ps-left-header|article-inhibit|print-escape|ssl-program-arguments|message-log-max" - -clever: - $(EMACS) $(FLAGS) -f dgnushack-compile - -some: - $(EMACS) $(FLAGS) -f dgnushack-compile - -install: clever - $(SHELL) $(top_srcdir)/mkinstalldirs $(lispdir) - for p in *.elc; do \ - echo " $(INSTALL_DATA) $$p $(lispdir)/$$p"; \ - $(INSTALL_DATA) $$p $(lispdir)/$$p; \ - done - -tags: - etags *.el - -separately: - rm -f *.elc ; for i in *.el; do $(EMACS) $(FLAGS) -f batch-byte-compile $$i; done - -pot: - xpot -drgnus -r`cat ./version` *.el > rgnus.pot - -gnus-load.el: - echo ";;; gnus-load.el --- automatically extracted custom dependencies" > gnus-load.el - echo ";;" >> gnus-load.el - echo ";;; Code:" >> gnus-load.el - echo >> gnus-load.el - $(EMACS) $(FLAGS) -l ./dgnushack.el -l cus-edit.el *.el \ - -f custom-make-dependencies >> gnus-load.el - echo >> gnus-load.el - echo "(provide 'gnus-load)" >> gnus-load.el - echo >> gnus-load.el - echo ";;; gnus-load.el ends here" >> gnus-load.el - -distclean: - rm -f *.orig *.rej *.elc *~ Makefile - -Makefile: $(srcdir)/Makefile.in ../config.status - cd .. \ - && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/lisp/dgnushack.el b/lisp/dgnushack.el deleted file mode 100644 index a5d1d65..0000000 --- a/lisp/dgnushack.el +++ /dev/null @@ -1,88 +0,0 @@ -;;; dgnushack.el --- a hack to set the load path for byte-compiling -;; Copyright (C) 1994,95,96,97,98 Free Software Foundation, Inc. - -;; Author: Lars Magne Ingebrigtsen -;; Version: 4.19 -;; Keywords: news, path - -;; This file is part of GNU Emacs. - -;; GNU Emacs is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 2, or (at your option) -;; any later version. - -;; GNU Emacs is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs; see the file COPYING. If not, write to the -;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. - -;;; Commentary: - -;;; Code: - -(fset 'facep 'ignore) - -(require 'cl) -(require 'bytecomp) -(push "~/lisp/custom" load-path) -(push "." load-path) -(load "./lpath.el" nil t) - -(defalias 'device-sound-enabled-p 'ignore) -(defalias 'play-sound-file 'ignore) -(defalias 'nndb-request-article 'ignore) -(defalias 'efs-re-read-dir 'ignore) -(defalias 'ange-ftp-re-read-dir 'ignore) -(defalias 'define-mail-user-agent 'ignore) - -(eval-and-compile - (unless (string-match "XEmacs" emacs-version) - (fset 'get-popup-menu-response 'ignore) - (fset 'event-object 'ignore) - (fset 'x-defined-colors 'ignore) - (fset 'read-color 'ignore))) - -(defun dgnushack-compile (&optional warn) - ;;(setq byte-compile-dynamic t) - (unless warn - (setq byte-compile-warnings - '(free-vars unresolved callargs redefine))) - (unless (locate-library "cus-edit") - (error "You do not seem to have Custom installed. -Fetch it from . -You also then need to add the following to the lisp/dgnushack.el file: - - (push \"~/lisp/custom\" load-path) - -Modify to suit your needs.")) - (let ((files (directory-files "." nil "^[^=].*\\.el$")) - (xemacs (string-match "XEmacs" emacs-version)) - ;;(byte-compile-generate-call-tree t) - file elc) - (condition-case () - (require 'w3-forms) - (error (setq files (delete "nnweb.el" (delete "nnlistserv.el" files))))) - (while (setq file (pop files)) - (when (or (and (not xemacs) - (not (member file '("gnus-xmas.el" "gnus-picon.el" - "messagexmas.el" "nnheaderxm.el" - "smiley.el" "x-overlay.el")))) - (and xemacs - (not (member file '("md5.el"))))) - (when (or (not (file-exists-p (setq elc (concat file "c")))) - (file-newer-than-file-p file elc)) - (ignore-errors - (byte-compile-file file))))))) - -(defun dgnushack-recompile () - (require 'gnus) - (byte-recompile-directory "." 0)) - -;;; dgnushack.el ends here - diff --git a/lisp/earcon.el b/lisp/earcon.el deleted file mode 100644 index 4302182..0000000 --- a/lisp/earcon.el +++ /dev/null @@ -1,240 +0,0 @@ -;;; earcon.el --- Sound effects for messages -;; Copyright (C) 1996 Free Software Foundation - -;; Author: Steven L. Baur -;; GNU Emacs is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 2, or (at your option) -;; any later version. - -;; GNU Emacs is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs; see the file COPYING. If not, write to the -;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. - -;;; Commentary: -;; This file provides access to sound effects in Gnus. - -;;; Code: - -(if (null (boundp 'running-xemacs)) - (defvar running-xemacs (string-match "XEmacs\\|Lucid" emacs-version))) - -(eval-when-compile (require 'cl)) -(require 'gnus) -(require 'gnus-audio) -(require 'gnus-art) - -(defgroup earcon nil - "Turn ** sounds ** into noise." - :group 'gnus-visual) - -(defcustom earcon-auto-play nil - "*When True, automatically play sounds as well as buttonize them." - :type 'boolean - :group 'earcon) - -(defcustom earcon-prefix "**" - "*String denoting the start of an earcon." - :type 'string - :group 'earcon) - -(defcustom earcon-suffix "**" - "String denoting the end of an earcon." - :type 'string - :group 'earcon) - -(defcustom earcon-regexp-alist - '(("boring" 1 "Boring.au") - ("evil[ \t]+laugh" 1 "Evil_Laugh.au") - ("gag\\|puke" 1 "Puke.au") - ("snicker" 1 "Snicker.au") - ("meow" 1 "catmeow.au") - ("sob\\|boohoo" 1 "cry.wav") - ("drum[ \t]*roll" 1 "drumroll.au") - ("blast" 1 "explosion.au") - ("flush\\|plonk!*" 1 "flush.au") - ("kiss" 1 "kiss.wav") - ("tee[ \t]*hee" 1 "laugh.au") - ("shoot" 1 "shotgun.wav") - ("yawn" 1 "snore.wav") - ("cackle" 1 "witch.au") - ("yell\\|roar" 1 "yell2.au") - ("whoop-de-doo" 1 "whistle.au")) - "*A list of regexps to map earcons to real sounds." - :type '(repeat (list regexp - (integer :tag "Match") - (string :tag "Sound"))) - :group 'earcon) -(defvar earcon-button-marker-list nil) -(make-variable-buffer-local 'earcon-button-marker-list) - - - -;;; FIXME!! clone of code from gnus-vis.el FIXME!! -(defun earcon-article-push-button (event) - "Check text under the mouse pointer for a callback function. -If the text under the mouse pointer has a `earcon-callback' property, -call it with the value of the `earcon-data' text property." - (interactive "e") - (set-buffer (window-buffer (posn-window (event-start event)))) - (let* ((pos (posn-point (event-start event))) - (data (get-text-property pos 'earcon-data)) - (fun (get-text-property pos 'earcon-callback))) - (if fun (funcall fun data)))) - -(defun earcon-article-press-button () - "Check text at point for a callback function. -If the text at point has a `earcon-callback' property, -call it with the value of the `earcon-data' text property." - (interactive) - (let* ((data (get-text-property (point) 'earcon-data)) - (fun (get-text-property (point) 'earcon-callback))) - (if fun (funcall fun data)))) - -(defun earcon-article-prev-button (n) - "Move point to N buttons backward. -If N is negative, move forward instead." - (interactive "p") - (earcon-article-next-button (- n))) - -(defun earcon-article-next-button (n) - "Move point to N buttons forward. -If N is negative, move backward instead." - (interactive "p") - (let ((function (if (< n 0) 'previous-single-property-change - 'next-single-property-change)) - (inhibit-point-motion-hooks t) - (backward (< n 0)) - (limit (if (< n 0) (point-min) (point-max)))) - (setq n (abs n)) - (while (and (not (= limit (point))) - (> n 0)) - ;; Skip past the current button. - (when (get-text-property (point) 'earcon-callback) - (goto-char (funcall function (point) 'earcon-callback nil limit))) - ;; Go to the next (or previous) button. - (gnus-goto-char (funcall function (point) 'earcon-callback nil limit)) - ;; Put point at the start of the button. - (when (and backward (not (get-text-property (point) 'earcon-callback))) - (goto-char (funcall function (point) 'earcon-callback nil limit))) - ;; Skip past intangible buttons. - (when (get-text-property (point) 'intangible) - (incf n)) - (decf n)) - (unless (zerop n) - (gnus-message 5 "No more buttons")) - n)) - -(defun earcon-article-add-button (from to fun &optional data) - "Create a button between FROM and TO with callback FUN and data DATA." - (and (boundp gnus-article-button-face) - gnus-article-button-face - (gnus-overlay-put (gnus-make-overlay from to) - 'face gnus-article-button-face)) - (gnus-add-text-properties - from to - (nconc (and gnus-article-mouse-face - (list gnus-mouse-face-prop gnus-article-mouse-face)) - (list 'gnus-callback fun) - (and data (list 'gnus-data data))))) - -(defun earcon-button-entry () - ;; Return the first entry in `gnus-button-alist' matching this place. - (let ((alist earcon-regexp-alist) - (case-fold-search t) - (entry nil)) - (while alist - (setq entry (pop alist)) - (if (looking-at (car entry)) - (setq alist nil) - (setq entry nil))) - entry)) - - -(defun earcon-button-push (marker) - ;; Push button starting at MARKER. - (save-excursion - (set-buffer gnus-article-buffer) - (goto-char marker) - (let* ((entry (earcon-button-entry)) - (inhibit-point-motion-hooks t) - (fun 'gnus-audio-play) - (args (list (nth 2 entry)))) - (cond - ((fboundp fun) - (apply fun args)) - ((and (boundp fun) - (fboundp (symbol-value fun))) - (apply (symbol-value fun) args)) - (t - (gnus-message 1 "You must define `%S' to use this button" - (cons fun args))))))) - -;;; FIXME!! clone of code from gnus-vis.el FIXME!! - -;;;###interactive -(defun earcon-region (beg end) - "Play Sounds in the region between point and mark." - (interactive "r") - (earcon-buffer (current-buffer) beg end)) - -;;;###interactive -(defun earcon-buffer (&optional buffer st nd) - (interactive) - (save-excursion - ;; clear old markers. - (if (boundp 'earcon-button-marker-list) - (while earcon-button-marker-list - (set-marker (pop earcon-button-marker-list) nil)) - (setq earcon-button-marker-list nil)) - (and buffer (set-buffer buffer)) - (let ((buffer-read-only nil) - (inhibit-point-motion-hooks t) - (case-fold-search t) - (alist earcon-regexp-alist) - beg entry regexp) - (goto-char (point-min)) - (setq beg (point)) - (while (setq entry (pop alist)) - (setq regexp (concat (regexp-quote earcon-prefix) - ".*\\(" - (car entry) - "\\).*" - (regexp-quote earcon-suffix))) - (goto-char beg) - (while (re-search-forward regexp nil t) - (let* ((start (and entry (match-beginning 1))) - (end (and entry (match-end 1))) - (from (match-beginning 1))) - (earcon-article-add-button - start end 'earcon-button-push - (car (push (set-marker (make-marker) from) - earcon-button-marker-list))) - (gnus-audio-play (caddr entry)))))))) - -;;;###autoload -(defun gnus-earcon-display () - "Play sounds in message buffers." - (interactive) - (save-excursion - (set-buffer gnus-article-buffer) - (goto-char (point-min)) - ;; Skip headers - (unless (search-forward "\n\n" nil t) - (goto-char (point-max))) - (sit-for 0) - (earcon-buffer (current-buffer) (point)))) - -;;;*** - -(provide 'earcon) - -(run-hooks 'earcon-load-hook) - -;;; earcon.el ends here diff --git a/lisp/gnus-agent.el b/lisp/gnus-agent.el deleted file mode 100644 index d9c1be9..0000000 --- a/lisp/gnus-agent.el +++ /dev/null @@ -1,1417 +0,0 @@ -;;; gnus-agent.el --- unplugged support for Semi-gnus -;; Copyright (C) 1997,98 Free Software Foundation, Inc. - -;; Author: Lars Magne Ingebrigtsen -;; This file is part of GNU Emacs. - -;; GNU Emacs is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 2, or (at your option) -;; any later version. - -;; GNU Emacs is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs; see the file COPYING. If not, write to the -;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. - -;;; Commentary: - -;;; Code: - -(require 'gnus) -(require 'gnus-cache) -(require 'nnvirtual) -(require 'gnus-sum) -(eval-when-compile (require 'cl)) - -(defcustom gnus-agent-directory (nnheader-concat gnus-directory "agent/") - "Where the Gnus agent will store its files." - :group 'gnus-agent - :type 'directory) - -(defcustom gnus-agent-plugged-hook nil - "Hook run when plugging into the network." - :group 'gnus-agent - :type 'hook) - -(defcustom gnus-agent-unplugged-hook nil - "Hook run when unplugging from the network." - :group 'gnus-agent - :type 'hook) - -(defcustom gnus-agent-handle-level gnus-level-subscribed - "Groups on levels higher than this variable will be ignored by the Agent." - :group 'gnus-agent - :type 'integer) - -(defcustom gnus-agent-expire-days 7 - "Read articles older than this will be expired." - :group 'gnus-agent - :type 'integer) - -(defcustom gnus-agent-expire-all nil - "If non-nil, also expire unread, ticked and dormant articles. -If nil, only read articles will be expired." - :group 'gnus-agent - :type 'boolean) - -(defcustom gnus-agent-group-mode-hook nil - "Hook run in Agent group minor modes." - :group 'gnus-agent - :type 'hook) - -(defcustom gnus-agent-summary-mode-hook nil - "Hook run in Agent summary minor modes." - :group 'gnus-agent - :type 'hook) - -(defcustom gnus-agent-server-mode-hook nil - "Hook run in Agent summary minor modes." - :group 'gnus-agent - :type 'hook) - -;;; Internal variables - -(defvar gnus-agent-meta-information-header "X-Gnus-Agent-Meta-Information") - -(defvar gnus-agent-history-buffers nil) -(defvar gnus-agent-buffer-alist nil) -(defvar gnus-agent-article-alist nil) -(defvar gnus-agent-group-alist nil) -(defvar gnus-agent-covered-methods nil) -(defvar gnus-category-alist nil) -(defvar gnus-agent-current-history nil) -(defvar gnus-agent-overview-buffer nil) -(defvar gnus-category-predicate-cache nil) -(defvar gnus-category-group-cache nil) -(defvar gnus-agent-spam-hashtb nil) -(defvar gnus-agent-file-name nil) -(defvar gnus-agent-send-mail-function nil) -(defvar gnus-agent-file-coding-system 'no-conversion) - -;; Dynamic variables -(defvar gnus-headers) -(defvar gnus-score) - -;;; -;;; Setup -;;; - -(defun gnus-open-agent () - (setq gnus-agent t) - (gnus-agent-read-servers) - (gnus-category-read) - (setq gnus-agent-overview-buffer - (gnus-get-buffer-create " *Gnus agent overview*")) - (add-hook 'gnus-group-mode-hook 'gnus-agent-mode) - (add-hook 'gnus-summary-mode-hook 'gnus-agent-mode) - (add-hook 'gnus-server-mode-hook 'gnus-agent-mode)) - -(gnus-add-shutdown 'gnus-close-agent 'gnus) - -(defun gnus-close-agent () - (setq gnus-agent-covered-methods nil - gnus-category-predicate-cache nil - gnus-category-group-cache nil - gnus-agent-spam-hashtb nil) - (gnus-kill-buffer gnus-agent-overview-buffer)) - -;;; -;;; Utility functions -;;; - -(defun gnus-agent-read-file (file) - "Load FILE and do a `read' there." - (nnheader-temp-write nil - (ignore-errors - (nnheader-insert-file-contents file) - (goto-char (point-min)) - (read (current-buffer))))) - -(defsubst gnus-agent-method () - (concat (symbol-name (car gnus-command-method)) "/" - (if (equal (cadr gnus-command-method) "") - "unnamed" - (cadr gnus-command-method)))) - -(defsubst gnus-agent-directory () - "Path of the Gnus agent directory." - (nnheader-concat gnus-agent-directory - (nnheader-translate-file-chars (gnus-agent-method)) "/")) - -(defun gnus-agent-lib-file (file) - "The full path of the Gnus agent library FILE." - (concat (gnus-agent-directory) "agent.lib/" file)) - -;;; Fetching setup functions. - -(defun gnus-agent-start-fetch () - "Initialize data structures for efficient fetching." - (gnus-agent-open-history) - (setq gnus-agent-current-history (gnus-agent-history-buffer))) - -(defun gnus-agent-stop-fetch () - "Save all data structures and clean up." - (gnus-agent-save-history) - (gnus-agent-close-history) - (setq gnus-agent-spam-hashtb nil) - (save-excursion - (set-buffer nntp-server-buffer) - (widen))) - -(defmacro gnus-agent-with-fetch (&rest forms) - "Do FORMS safely." - `(unwind-protect - (progn - (gnus-agent-start-fetch) - ,@forms) - (gnus-agent-stop-fetch))) - -(put 'gnus-agent-with-fetch 'lisp-indent-function 0) -(put 'gnus-agent-with-fetch 'edebug-form-spec '(body)) - -;;; -;;; Mode infestation -;;; - -(defvar gnus-agent-mode-hook nil - "Hook run when installing agent mode.") - -(defvar gnus-agent-mode nil) -(defvar gnus-agent-mode-status '(gnus-agent-mode " Plugged")) - -(defun gnus-agent-mode () - "Minor mode for providing a agent support in Gnus buffers." - (let* ((buffer (progn (string-match "^gnus-\\(.*\\)-mode$" - (symbol-name major-mode)) - (match-string 1 (symbol-name major-mode)))) - (mode (intern (format "gnus-agent-%s-mode" buffer)))) - (set (make-local-variable 'gnus-agent-mode) t) - (set mode nil) - (set (make-local-variable mode) t) - ;; Set up the menu. - (when (gnus-visual-p 'agent-menu 'menu) - (funcall (intern (format "gnus-agent-%s-make-menu-bar" buffer)))) - (unless (assq 'gnus-agent-mode minor-mode-alist) - (push gnus-agent-mode-status minor-mode-alist)) - (unless (assq mode minor-mode-map-alist) - (push (cons mode (symbol-value (intern (format "gnus-agent-%s-mode-map" - buffer)))) - minor-mode-map-alist)) - (when (eq major-mode 'gnus-group-mode) - (gnus-agent-toggle-plugged gnus-plugged)) - (gnus-run-hooks 'gnus-agent-mode-hook - (intern (format "gnus-agent-%s-mode-hook" buffer))))) - -(defvar gnus-agent-group-mode-map (make-sparse-keymap)) -(gnus-define-keys gnus-agent-group-mode-map - "Ju" gnus-agent-fetch-groups - "Jc" gnus-enter-category-buffer - "Jj" gnus-agent-toggle-plugged - "Js" gnus-agent-fetch-session - "JS" gnus-group-send-drafts - "Ja" gnus-agent-add-group) - -(defun gnus-agent-group-make-menu-bar () - (unless (boundp 'gnus-agent-group-menu) - (easy-menu-define - gnus-agent-group-menu gnus-agent-group-mode-map "" - '("Agent" - ["Toggle plugged" gnus-agent-toggle-plugged t] - ["List categories" gnus-enter-category-buffer t] - ["Send drafts" gnus-group-send-drafts gnus-plugged] - ("Fetch" - ["All" gnus-agent-fetch-session gnus-plugged] - ["Group" gnus-agent-fetch-group gnus-plugged]))))) - -(defvar gnus-agent-summary-mode-map (make-sparse-keymap)) -(gnus-define-keys gnus-agent-summary-mode-map - "Jj" gnus-agent-toggle-plugged - "J#" gnus-agent-mark-article - "J\M-#" gnus-agent-unmark-article - "@" gnus-agent-toggle-mark - "Jc" gnus-agent-catchup) - -(defun gnus-agent-summary-make-menu-bar () - (unless (boundp 'gnus-agent-summary-menu) - (easy-menu-define - gnus-agent-summary-menu gnus-agent-summary-mode-map "" - '("Agent" - ["Toggle plugged" gnus-agent-toggle-plugged t] - ["Mark as downloadable" gnus-agent-mark-article t] - ["Unmark as downloadable" gnus-agent-unmark-article t] - ["Toggle mark" gnus-agent-toggle-mark t] - ["Catchup undownloaded" gnus-agent-catchup t])))) - -(defvar gnus-agent-server-mode-map (make-sparse-keymap)) -(gnus-define-keys gnus-agent-server-mode-map - "Jj" gnus-agent-toggle-plugged - "Ja" gnus-agent-add-server - "Jr" gnus-agent-remove-server) - -(defun gnus-agent-server-make-menu-bar () - (unless (boundp 'gnus-agent-server-menu) - (easy-menu-define - gnus-agent-server-menu gnus-agent-server-mode-map "" - '("Agent" - ["Toggle plugged" gnus-agent-toggle-plugged t] - ["Add" gnus-agent-add-server t] - ["Remove" gnus-agent-remove-server t])))) - -(defun gnus-agent-toggle-plugged (plugged) - "Toggle whether Gnus is unplugged or not." - (interactive (list (not gnus-plugged))) - (if plugged - (progn - (setq gnus-plugged plugged) - (gnus-run-hooks 'gnus-agent-plugged-hook) - (setcar (cdr gnus-agent-mode-status) " Plugged")) - (gnus-agent-close-connections) - (setq gnus-plugged plugged) - (gnus-run-hooks 'gnus-agent-unplugged-hook) - (setcar (cdr gnus-agent-mode-status) " Unplugged")) - (set-buffer-modified-p t)) - -(defun gnus-agent-close-connections () - "Close all methods covered by the Gnus agent." - (let ((methods gnus-agent-covered-methods)) - (while methods - (gnus-close-server (pop methods))))) - -;;;###autoload -(defun gnus-unplugged () - "Start Gnus unplugged." - (interactive) - (setq gnus-plugged nil) - (gnus)) - -;;;###autoload -(defun gnus-plugged () - "Start Gnus plugged." - (interactive) - (setq gnus-plugged t) - (gnus)) - -;;;###autoload -(defun gnus-agentize () - "Allow Gnus to be an offline newsreader. -The normal usage of this command is to put the following as the -last form in your `.gnus.el' file: - -\(gnus-agentize) - -This will modify the `gnus-before-startup-hook', `gnus-post-method', -and `message-send-mail-function' variables, and install the Gnus -agent minor mode in all Gnus buffers." - (interactive) - (gnus-open-agent) - (add-hook 'gnus-setup-news-hook 'gnus-agent-queue-setup) - (unless gnus-agent-send-mail-function - (setq gnus-agent-send-mail-function message-send-mail-function - message-send-mail-function 'gnus-agent-send-mail)) - (unless gnus-agent-covered-methods - (setq gnus-agent-covered-methods (list gnus-select-method)))) - -(defun gnus-agent-queue-setup () - "Make sure the queue group exists." - (unless (gnus-gethash "nndraft:queue" gnus-newsrc-hashtb) - (gnus-request-create-group "queue" '(nndraft "")) - (let ((gnus-level-default-subscribed 1)) - (gnus-subscribe-group "nndraft:queue" nil '(nndraft ""))) - (gnus-group-set-parameter - "nndraft:queue" 'gnus-dummy '((gnus-draft-mode))))) - -(defun gnus-agent-send-mail () - (if gnus-plugged - (funcall gnus-agent-send-mail-function) - (goto-char (point-min)) - (re-search-forward - (concat "^" (regexp-quote mail-header-separator) "\n")) - (replace-match "\n") - (gnus-agent-insert-meta-information 'mail) - (gnus-request-accept-article "nndraft:queue"))) - -(defun gnus-agent-insert-meta-information (type &optional method) - "Insert meta-information into the message that says how it's to be posted. -TYPE can be either `mail' or `news'. If the latter METHOD can -be a select method." - (save-excursion - (message-remove-header gnus-agent-meta-information-header) - (goto-char (point-min)) - (insert gnus-agent-meta-information-header ": " - (symbol-name type) " " (format "%S" method) - "\n") - (forward-char -1) - (while (search-backward "\n" nil t) - (replace-match "\\n" t t)))) - -;;; -;;; Group mode commands -;;; - -(defun gnus-agent-fetch-groups (n) - "Put all new articles in the current groups into the Agent." - (interactive "P") - (gnus-group-iterate n 'gnus-agent-fetch-group)) - -(defun gnus-agent-fetch-group (group) - "Put all new articles in GROUP into the Agent." - (interactive (list (gnus-group-group-name))) - (unless group - (error "No group on the current line")) - (let ((gnus-command-method (gnus-find-method-for-group group))) - (gnus-agent-with-fetch - (gnus-agent-fetch-group-1 group gnus-command-method) - (gnus-message 5 "Fetching %s...done" group)))) - -(defun gnus-agent-add-group (category arg) - "Add the current group to an agent category." - (interactive - (list - (intern - (completing-read - "Add to category: " - (mapcar (lambda (cat) (list (symbol-name (car cat)))) - gnus-category-alist) - nil t)) - current-prefix-arg)) - (let ((cat (assq category gnus-category-alist)) - c groups) - (gnus-group-iterate arg - (lambda (group) - (when (cadddr (setq c (gnus-group-category group))) - (setf (cadddr c) (delete group (cadddr c)))) - (push group groups))) - (setf (cadddr cat) (nconc (cadddr cat) groups)) - (gnus-category-write))) - -;;; -;;; Server mode commands -;;; - -(defun gnus-agent-add-server (server) - "Enroll SERVER in the agent program." - (interactive (list (gnus-server-server-name))) - (unless server - (error "No server on the current line")) - (let ((method (gnus-server-get-method nil (gnus-server-server-name)))) - (when (member method gnus-agent-covered-methods) - (error "Server already in the agent program")) - (push method gnus-agent-covered-methods) - (gnus-agent-write-servers) - (message "Entered %s into the Agent" server))) - -(defun gnus-agent-remove-server (server) - "Remove SERVER from the agent program." - (interactive (list (gnus-server-server-name))) - (unless server - (error "No server on the current line")) - (let ((method (gnus-server-get-method nil (gnus-server-server-name)))) - (unless (member method gnus-agent-covered-methods) - (error "Server not in the agent program")) - (setq gnus-agent-covered-methods - (delete method gnus-agent-covered-methods)) - (gnus-agent-write-servers) - (message "Removed %s from the agent" server))) - -(defun gnus-agent-read-servers () - "Read the alist of covered servers." - (setq gnus-agent-covered-methods - (gnus-agent-read-file - (nnheader-concat gnus-agent-directory "lib/servers")))) - -(defun gnus-agent-write-servers () - "Write the alist of covered servers." - (nnheader-temp-write (nnheader-concat gnus-agent-directory "lib/servers") - (prin1 gnus-agent-covered-methods (current-buffer)))) - -;;; -;;; Summary commands -;;; - -(defun gnus-agent-mark-article (n &optional unmark) - "Mark the next N articles as downloadable. -If N is negative, mark backward instead. If UNMARK is non-nil, remove -the mark instead. The difference between N and the actual number of -articles marked is returned." - (interactive "p") - (let ((backward (< n 0)) - (n (abs n))) - (while (and - (> n 0) - (progn - (gnus-summary-set-agent-mark - (gnus-summary-article-number) unmark) - (zerop (gnus-summary-next-subject (if backward -1 1) nil t)))) - (setq n (1- n))) - (when (/= 0 n) - (gnus-message 7 "No more articles")) - (gnus-summary-recenter) - (gnus-summary-position-point) - n)) - -(defun gnus-agent-unmark-article (n) - "Remove the downloadable mark from the next N articles. -If N is negative, unmark backward instead. The difference between N and -the actual number of articles unmarked is returned." - (interactive "p") - (gnus-agent-mark-article n t)) - -(defun gnus-agent-toggle-mark (n) - "Toggle the downloadable mark from the next N articles. -If N is negative, toggle backward instead. The difference between N and -the actual number of articles toggled is returned." - (interactive "p") - (gnus-agent-mark-article n 'toggle)) - -(defun gnus-summary-set-agent-mark (article &optional unmark) - "Mark ARTICLE as downloadable." - (let ((unmark (if (and (not (null unmark)) (not (eq t unmark))) - (memq article gnus-newsgroup-downloadable) - unmark))) - (if unmark - (progn - (setq gnus-newsgroup-downloadable - (delq article gnus-newsgroup-downloadable)) - (push article gnus-newsgroup-undownloaded)) - (setq gnus-newsgroup-undownloaded - (delq article gnus-newsgroup-undownloaded)) - (push article gnus-newsgroup-downloadable)) - (gnus-summary-update-mark - (if unmark gnus-undownloaded-mark gnus-downloadable-mark) - 'unread))) - -(defun gnus-agent-get-undownloaded-list () - "Mark all unfetched articles as read." - (let ((gnus-command-method (gnus-find-method-for-group gnus-newsgroup-name))) - (when (and (not gnus-plugged) - (gnus-agent-method-p gnus-command-method)) - (gnus-agent-load-alist gnus-newsgroup-name) - (let ((articles gnus-newsgroup-unreads) - article) - (while (setq article (pop articles)) - (unless (or (cdr (assq article gnus-agent-article-alist)) - (memq article gnus-newsgroup-downloadable)) - (push article gnus-newsgroup-undownloaded))))))) - -(defun gnus-agent-catchup () - "Mark all undownloaded articles as read." - (interactive) - (save-excursion - (while gnus-newsgroup-undownloaded - (gnus-summary-mark-article - (pop gnus-newsgroup-undownloaded) gnus-catchup-mark))) - (gnus-summary-position-point)) - -;;; -;;; Internal functions -;;; - -(defun gnus-agent-save-active (method) - (when (gnus-agent-method-p method) - (let* ((gnus-command-method method) - (file (gnus-agent-lib-file "active"))) - (gnus-make-directory (file-name-directory file)) - (let ((coding-system-for-write gnus-agent-file-coding-system)) - (write-region (point-min) (point-max) file nil 'silent)) - (when (file-exists-p (gnus-agent-lib-file "groups")) - (delete-file (gnus-agent-lib-file "groups")))))) - -(defun gnus-agent-save-groups (method) - (let* ((gnus-command-method method) - (file (gnus-agent-lib-file "groups"))) - (gnus-make-directory (file-name-directory file)) - (let ((coding-system-for-write gnus-agent-file-coding-system)) - (write-region (point-min) (point-max) file nil 'silent)) - (when (file-exists-p (gnus-agent-lib-file "active")) - (delete-file (gnus-agent-lib-file "active"))))) - -(defun gnus-agent-save-group-info (method group active) - (when (gnus-agent-method-p method) - (let* ((gnus-command-method method) - (file (if nntp-server-list-active-group - (gnus-agent-lib-file "active") - (gnus-agent-lib-file "groups")))) - (gnus-make-directory (file-name-directory file)) - (nnheader-temp-write file - (when (file-exists-p file) - (nnheader-insert-file-contents file)) - (goto-char (point-min)) - (if nntp-server-list-active-group - (progn - (when (re-search-forward - (concat "^" (regexp-quote group) " ") nil t) - (gnus-delete-line)) - (insert group " " (number-to-string (cdr active)) " " - (number-to-string (car active)) " y\n")) - (when (re-search-forward (concat (regexp-quote group) " ") nil t) - (gnus-delete-line)) - (insert-buffer-substring nntp-server-buffer)))))) - -(defun gnus-agent-group-path (group) - "Translate GROUP into a path." - (if nnmail-use-long-file-names - (gnus-group-real-name group) - (nnheader-replace-chars-in-string - (nnheader-translate-file-chars (gnus-group-real-name group)) - ?. ?/))) - - - -(defun gnus-agent-method-p (method) - "Say whether METHOD is covered by the agent." - (member method gnus-agent-covered-methods)) - -(defun gnus-agent-get-function (method) - (if (and (not gnus-plugged) - (gnus-agent-method-p method)) - (progn - (require 'nnagent) - 'nnagent) - (car method))) - -;;; History functions - -(defun gnus-agent-history-buffer () - (cdr (assoc (gnus-agent-method) gnus-agent-history-buffers))) - -(defun gnus-agent-open-history () - (save-excursion - (push (cons (gnus-agent-method) - (set-buffer (gnus-get-buffer-create - (format " *Gnus agent %s history*" - (gnus-agent-method))))) - gnus-agent-history-buffers) - (erase-buffer) - (insert "\n") - (let ((file (gnus-agent-lib-file "history"))) - (when (file-exists-p file) - (insert-file file)) - (set (make-local-variable 'gnus-agent-file-name) file)))) - -(defun gnus-agent-save-history () - (save-excursion - (set-buffer gnus-agent-current-history) - (gnus-make-directory (file-name-directory gnus-agent-file-name)) - (let ((coding-system-for-write gnus-agent-file-coding-system)) - (write-region (1+ (point-min)) (point-max) - gnus-agent-file-name nil 'silent)))) - -(defun gnus-agent-close-history () - (when (gnus-buffer-live-p gnus-agent-current-history) - (kill-buffer gnus-agent-current-history) - (setq gnus-agent-history-buffers - (delq (assoc (gnus-agent-method) gnus-agent-history-buffers) - gnus-agent-history-buffers)))) - -(defun gnus-agent-enter-history (id group-arts date) - (save-excursion - (set-buffer gnus-agent-current-history) - (goto-char (point-max)) - (insert id "\t" (number-to-string date) "\t") - (while group-arts - (insert (caar group-arts) " " (number-to-string (cdr (pop group-arts))) - " ")) - (insert "\n"))) - -(defun gnus-agent-article-in-history-p (id) - (save-excursion - (set-buffer (gnus-agent-history-buffer)) - (goto-char (point-min)) - (search-forward (concat "\n" id "\t") nil t))) - -(defun gnus-agent-history-path (id) - (save-excursion - (set-buffer (gnus-agent-history-buffer)) - (goto-char (point-min)) - (when (search-forward (concat "\n" id "\t") nil t) - (let ((method (gnus-agent-method))) - (let (paths group) - (while (not (numberp (setq group (read (current-buffer))))) - (push (concat method "/" group) paths)) - (nreverse paths)))))) - -;;; -;;; Fetching -;;; - -(defun gnus-agent-fetch-articles (group articles) - "Fetch ARTICLES from GROUP and put them into the Agent." - (when articles - ;; Prune off articles that we have already fetched. - (while (and articles - (cdr (assq (car articles) gnus-agent-article-alist))) - (pop articles)) - (let ((arts articles)) - (while (cdr arts) - (if (cdr (assq (cadr arts) gnus-agent-article-alist)) - (setcdr arts (cddr arts)) - (setq arts (cdr arts))))) - (when articles - (let ((dir (concat - (gnus-agent-directory) - (gnus-agent-group-path group) "/")) - (date (gnus-time-to-day (current-time))) - (case-fold-search t) - pos crosses id elem) - (gnus-make-directory dir) - (gnus-message 7 "Fetching articles for %s..." group) - ;; Fetch the articles from the backend. - (if (gnus-check-backend-function 'retrieve-articles group) - (setq pos (gnus-retrieve-articles articles group)) - (nnheader-temp-write nil - (let (article) - (while (setq article (pop articles)) - (when (gnus-request-article article group) - (goto-char (point-max)) - (push (cons article (point)) pos) - (insert-buffer-substring nntp-server-buffer))) - (copy-to-buffer nntp-server-buffer (point-min) (point-max)) - (setq pos (nreverse pos))))) - ;; Then save these articles into the Agent. - (save-excursion - (set-buffer nntp-server-buffer) - (while pos - (narrow-to-region (cdar pos) (or (cdadr pos) (point-max))) - (goto-char (point-min)) - (when (search-forward "\n\n" nil t) - (when (search-backward "\nXrefs: " nil t) - ;; Handle crossposting. - (skip-chars-forward "^ ") - (skip-chars-forward " ") - (setq crosses nil) - (while (looking-at "\\([^: \n]+\\):\\([0-9]+\\) +") - (push (cons (buffer-substring (match-beginning 1) - (match-end 1)) - (buffer-substring (match-beginning 2) - (match-end 2))) - crosses) - (goto-char (match-end 0))) - (gnus-agent-crosspost crosses (caar pos)))) - (goto-char (point-min)) - (if (not (re-search-forward "^Message-ID: *<\\([^>\n]+\\)>" nil t)) - (setq id "No-Message-ID-in-article") - (setq id (buffer-substring (match-beginning 1) (match-end 1)))) - (let ((coding-system-for-write - gnus-agent-file-coding-system)) - (write-region (point-min) (point-max) - (concat dir (number-to-string (caar pos))) - nil 'silent)) - (when (setq elem (assq (caar pos) gnus-agent-article-alist)) - (setcdr elem t)) - (gnus-agent-enter-history - id (or crosses (list (cons group (caar pos)))) date) - (widen) - (pop pos))) - (gnus-agent-save-alist group))))) - -(defun gnus-agent-crosspost (crosses article) - (let (gnus-agent-article-alist group alist beg end) - (save-excursion - (set-buffer gnus-agent-overview-buffer) - (when (nnheader-find-nov-line article) - (forward-word 1) - (setq beg (point)) - (setq end (progn (forward-line 1) (point))))) - (while crosses - (setq group (caar crosses)) - (unless (setq alist (assoc group gnus-agent-group-alist)) - (push (setq alist (list group (gnus-agent-load-alist (caar crosses)))) - gnus-agent-group-alist)) - (setcdr alist (cons (cons (cdar crosses) t) (cdr alist))) - (save-excursion - (set-buffer (gnus-get-buffer-create (format " *Gnus agent overview %s*" - group))) - (when (= (point-max) (point-min)) - (push (cons group (current-buffer)) gnus-agent-buffer-alist) - (ignore-errors - (nnheader-insert-file-contents - (gnus-agent-article-name ".overview" group)))) - (nnheader-find-nov-line (string-to-number (cdar crosses))) - (insert (string-to-number (cdar crosses))) - (insert-buffer-substring gnus-agent-overview-buffer beg end)) - (pop crosses)))) - -(defun gnus-agent-flush-cache () - (save-excursion - (while gnus-agent-buffer-alist - (set-buffer (cdar gnus-agent-buffer-alist)) - (let ((coding-system-for-write - gnus-agent-file-coding-system)) - (write-region (point-min) (point-max) - (gnus-agent-article-name ".overview" - (caar gnus-agent-buffer-alist)) - nil 'silent)) - (pop gnus-agent-buffer-alist)) - (while gnus-agent-group-alist - (nnheader-temp-write (caar gnus-agent-group-alist) - (princ (cdar gnus-agent-group-alist)) - (insert "\n")) - (pop gnus-agent-group-alist)))) - -(defun gnus-agent-fetch-headers (group &optional force) - (let ((articles (if (gnus-agent-load-alist group) - (gnus-sorted-intersection - (gnus-list-of-unread-articles group) - (gnus-uncompress-range - (cons (1+ (caar (last gnus-agent-article-alist))) - (cdr (gnus-active group))))) - (gnus-list-of-unread-articles group)))) - ;; Fetch them. - (when articles - (gnus-message 7 "Fetching headers for %s..." group) - (save-excursion - (set-buffer nntp-server-buffer) - (unless (eq 'nov (gnus-retrieve-headers articles group)) - (nnvirtual-convert-headers)) - ;; Save these headers for later processing. - (copy-to-buffer gnus-agent-overview-buffer (point-min) (point-max)) - (let (file) - (when (file-exists-p - (setq file (gnus-agent-article-name ".overview" group))) - (gnus-agent-braid-nov group articles file)) - (gnus-make-directory (nnheader-translate-file-chars - (file-name-directory file))) - (let ((coding-system-for-write - gnus-agent-file-coding-system)) - (write-region (point-min) (point-max) file nil 'silent)) - (gnus-agent-save-alist group articles nil) - (gnus-agent-enter-history - "last-header-fetched-for-session" - (list (cons group (nth (- (length articles) 1) articles))) - (gnus-time-to-day (current-time))) - articles))))) - -(defsubst gnus-agent-copy-nov-line (article) - (let (b e) - (set-buffer gnus-agent-overview-buffer) - (setq b (point)) - (if (eq article (read (current-buffer))) - (setq e (progn (forward-line 1) (point))) - (progn - (beginning-of-line) - (setq e b))) - (set-buffer nntp-server-buffer) - (insert-buffer-substring gnus-agent-overview-buffer b e))) - -(defun gnus-agent-braid-nov (group articles file) - (set-buffer gnus-agent-overview-buffer) - (goto-char (point-min)) - (set-buffer nntp-server-buffer) - (erase-buffer) - (nnheader-insert-file-contents file) - (goto-char (point-max)) - (if (or (= (point-min) (point-max)) - (progn - (forward-line -1) - (< (read (current-buffer)) (car articles)))) - ;; We have only headers that are after the older headers, - ;; so we just append them. - (progn - (goto-char (point-max)) - (insert-buffer-substring gnus-agent-overview-buffer)) - ;; We do it the hard way. - (nnheader-find-nov-line (car articles)) - (gnus-agent-copy-nov-line (car articles)) - (pop articles) - (while (and articles - (not (eobp))) - (while (and (not (eobp)) - (< (read (current-buffer)) (car articles))) - (forward-line 1)) - (beginning-of-line) - (unless (eobp) - (gnus-agent-copy-nov-line (car articles)) - (setq articles (cdr articles)))) - (when articles - (let (b e) - (set-buffer gnus-agent-overview-buffer) - (setq b (point) - e (point-max)) - (set-buffer nntp-server-buffer) - (insert-buffer-substring gnus-agent-overview-buffer b e))))) - -(defun gnus-agent-load-alist (group &optional dir) - "Load the article-state alist for GROUP." - (setq gnus-agent-article-alist - (gnus-agent-read-file - (if dir - (concat dir ".agentview") - (gnus-agent-article-name ".agentview" group))))) - -(defun gnus-agent-save-alist (group &optional articles state dir) - "Save the article-state alist for GROUP." - (nnheader-temp-write (if dir - (concat dir ".agentview") - (gnus-agent-article-name ".agentview" group)) - (princ (setq gnus-agent-article-alist - (nconc gnus-agent-article-alist - (mapcar (lambda (article) (cons article state)) - articles))) - (current-buffer)) - (insert "\n"))) - -(defun gnus-agent-article-name (article group) - (concat (gnus-agent-directory) (gnus-agent-group-path group) "/" - (if (stringp article) article (string-to-number article)))) - -;;;###autoload -(defun gnus-agent-batch-fetch () - "Start Gnus and fetch session." - (interactive) - (gnus) - (gnus-agent-fetch-session) - (gnus-group-exit)) - -(defun gnus-agent-fetch-session () - "Fetch all articles and headers that are eligible for fetching." - (interactive) - (unless gnus-agent-covered-methods - (error "No servers are covered by the Gnus agent")) - (unless gnus-plugged - (error "Can't fetch articles while Gnus is unplugged")) - (let ((methods gnus-agent-covered-methods) - groups group gnus-command-method) - (save-excursion - (while methods - (setq gnus-command-method (car methods)) - (when (or (gnus-server-opened gnus-command-method) - (gnus-open-server gnus-command-method)) - (setq groups (gnus-groups-from-server (car methods))) - (gnus-agent-with-fetch - (while (setq group (pop groups)) - (when (<= (gnus-group-level group) gnus-agent-handle-level) - (gnus-agent-fetch-group-1 group gnus-command-method))))) - (pop methods)) - (gnus-message 6 "Finished fetching articles into the Gnus agent")))) - -(defun gnus-agent-fetch-group-1 (group method) - "Fetch GROUP." - (let ((gnus-command-method method) - gnus-newsgroup-dependencies gnus-newsgroup-headers - gnus-newsgroup-scored gnus-headers gnus-score - gnus-use-cache articles arts - category predicate info marks score-param) - ;; Fetch headers. - (when (and (or (gnus-active group) (gnus-activate-group group)) - (setq articles (gnus-agent-fetch-headers group))) - ;; Parse them and see which articles we want to fetch. - (setq gnus-newsgroup-dependencies - (make-vector (length articles) 0)) - (setq gnus-newsgroup-headers - (gnus-get-newsgroup-headers-xover articles nil nil group)) - (setq category (gnus-group-category group)) - (setq predicate - (gnus-get-predicate - (or (gnus-group-get-parameter group 'agent-predicate) - (cadr category)))) - (setq score-param - (or (gnus-group-get-parameter group 'agent-score) - (caddr category))) - (when score-param - (gnus-score-headers (list (list score-param)))) - (setq arts nil) - (while (setq gnus-headers (pop gnus-newsgroup-headers)) - (setq gnus-score - (or (cdr (assq (mail-header-number gnus-headers) - gnus-newsgroup-scored)) - gnus-summary-default-score)) - (when (funcall predicate) - (push (mail-header-number gnus-headers) - arts))) - ;; Fetch the articles. - (when arts - (gnus-agent-fetch-articles group arts))) - ;; Perhaps we have some additional articles to fetch. - (setq arts (assq 'download (gnus-info-marks - (setq info (gnus-get-info group))))) - (when (cdr arts) - (gnus-agent-fetch-articles - group (gnus-uncompress-range (cdr arts))) - (setq marks (delq arts (gnus-info-marks info))) - (gnus-info-set-marks info marks)))) - -;;; -;;; Agent Category Mode -;;; - -(defvar gnus-category-mode-hook nil - "Hook run in `gnus-category-mode' buffers.") - -(defvar gnus-category-line-format " %(%20c%): %g\n" - "Format of category lines.") - -(defvar gnus-category-mode-line-format "Gnus: %%b" - "The format specification for the category mode line.") - -(defvar gnus-agent-short-article 100 - "Articles that have fewer lines than this are short.") - -(defvar gnus-agent-long-article 200 - "Articles that have more lines than this are long.") - -(defvar gnus-agent-low-score 0 - "Articles that have a score lower than this have a low score.") - -(defvar gnus-agent-high-score 0 - "Articles that have a score higher than this have a high score.") - - -;;; Internal variables. - -(defvar gnus-category-buffer "*Agent Category*") - -(defvar gnus-category-line-format-alist - `((?c gnus-tmp-name ?s) - (?g gnus-tmp-groups ?d))) - -(defvar gnus-category-mode-line-format-alist - `((?u user-defined ?s))) - -(defvar gnus-category-line-format-spec nil) -(defvar gnus-category-mode-line-format-spec nil) - -(defvar gnus-category-mode-map nil) -(put 'gnus-category-mode 'mode-class 'special) - -(unless gnus-category-mode-map - (setq gnus-category-mode-map (make-sparse-keymap)) - (suppress-keymap gnus-category-mode-map) - - (gnus-define-keys gnus-category-mode-map - "q" gnus-category-exit - "k" gnus-category-kill - "c" gnus-category-copy - "a" gnus-category-add - "p" gnus-category-edit-predicate - "g" gnus-category-edit-groups - "s" gnus-category-edit-score - "l" gnus-category-list - - "\C-c\C-i" gnus-info-find-node - "\C-c\C-b" gnus-bug)) - -(defvar gnus-category-menu-hook nil - "*Hook run after the creation of the menu.") - -(defun gnus-category-make-menu-bar () - (gnus-turn-off-edit-menu 'category) - (unless (boundp 'gnus-category-menu) - (easy-menu-define - gnus-category-menu gnus-category-mode-map "" - '("Categories" - ["Add" gnus-category-add t] - ["Kill" gnus-category-kill t] - ["Copy" gnus-category-copy t] - ["Edit predicate" gnus-category-edit-predicate t] - ["Edit score" gnus-category-edit-score t] - ["Edit groups" gnus-category-edit-groups t] - ["Exit" gnus-category-exit t])) - - (gnus-run-hooks 'gnus-category-menu-hook))) - -(defun gnus-category-mode () - "Major mode for listing and editing agent categories. - -All normal editing commands are switched off. -\\ -For more in-depth information on this mode, read the manual -(`\\[gnus-info-find-node]'). - -The following commands are available: - -\\{gnus-category-mode-map}" - (interactive) - (when (gnus-visual-p 'category-menu 'menu) - (gnus-category-make-menu-bar)) - (kill-all-local-variables) - (gnus-simplify-mode-line) - (setq major-mode 'gnus-category-mode) - (setq mode-name "Category") - (gnus-set-default-directory) - (setq mode-line-process nil) - (use-local-map gnus-category-mode-map) - (buffer-disable-undo (current-buffer)) - (setq truncate-lines t) - (setq buffer-read-only t) - (gnus-run-hooks 'gnus-category-mode-hook)) - -(defalias 'gnus-category-position-point 'gnus-goto-colon) - -(defun gnus-category-insert-line (category) - (let* ((gnus-tmp-name (car category)) - (gnus-tmp-groups (length (cadddr category)))) - (beginning-of-line) - (gnus-add-text-properties - (point) - (prog1 (1+ (point)) - ;; Insert the text. - (eval gnus-category-line-format-spec)) - (list 'gnus-category gnus-tmp-name)))) - -(defun gnus-enter-category-buffer () - "Go to the Category buffer." - (interactive) - (gnus-category-setup-buffer) - (gnus-configure-windows 'category) - (gnus-category-prepare)) - -(defun gnus-category-setup-buffer () - (unless (get-buffer gnus-category-buffer) - (save-excursion - (set-buffer (gnus-get-buffer-create gnus-category-buffer)) - (gnus-category-mode)))) - -(defun gnus-category-prepare () - (gnus-set-format 'category-mode) - (gnus-set-format 'category t) - (let ((alist gnus-category-alist) - (buffer-read-only nil)) - (erase-buffer) - (while alist - (gnus-category-insert-line (pop alist))) - (goto-char (point-min)) - (gnus-category-position-point))) - -(defun gnus-category-name () - (or (get-text-property (gnus-point-at-bol) 'gnus-category) - (error "No category on the current line"))) - -(defun gnus-category-read () - "Read the category alist." - (setq gnus-category-alist - (or (gnus-agent-read-file - (nnheader-concat gnus-agent-directory "lib/categories")) - (list (list 'default 'short nil nil))))) - -(defun gnus-category-write () - "Write the category alist." - (setq gnus-category-predicate-cache nil - gnus-category-group-cache nil) - (nnheader-temp-write (nnheader-concat gnus-agent-directory "lib/categories") - (prin1 gnus-category-alist (current-buffer)))) - -(defun gnus-category-edit-predicate (category) - "Edit the predicate for CATEGORY." - (interactive (list (gnus-category-name))) - (let ((info (assq category gnus-category-alist))) - (gnus-edit-form - (cadr info) (format "Editing the predicate for category %s" category) - `(lambda (predicate) - (setf (cadr (assq ',category gnus-category-alist)) predicate) - (gnus-category-write) - (gnus-category-list))))) - -(defun gnus-category-edit-score (category) - "Edit the score expression for CATEGORY." - (interactive (list (gnus-category-name))) - (let ((info (assq category gnus-category-alist))) - (gnus-edit-form - (caddr info) - (format "Editing the score expression for category %s" category) - `(lambda (groups) - (setf (caddr (assq ',category gnus-category-alist)) groups) - (gnus-category-write) - (gnus-category-list))))) - -(defun gnus-category-edit-groups (category) - "Edit the group list for CATEGORY." - (interactive (list (gnus-category-name))) - (let ((info (assq category gnus-category-alist))) - (gnus-edit-form - (cadddr info) (format "Editing the group list for category %s" category) - `(lambda (groups) - (setf (cadddr (assq ',category gnus-category-alist)) groups) - (gnus-category-write) - (gnus-category-list))))) - -(defun gnus-category-kill (category) - "Kill the current category." - (interactive (list (gnus-category-name))) - (let ((info (assq category gnus-category-alist)) - (buffer-read-only nil)) - (gnus-delete-line) - (gnus-category-write) - (setq gnus-category-alist (delq info gnus-category-alist)))) - -(defun gnus-category-copy (category to) - "Copy the current category." - (interactive (list (gnus-category-name) (intern (read-string "New name: ")))) - (let ((info (assq category gnus-category-alist))) - (push (list to (gnus-copy-sequence (cadr info)) - (gnus-copy-sequence (caddr info)) nil) - gnus-category-alist) - (gnus-category-write) - (gnus-category-list))) - -(defun gnus-category-add (category) - "Create a new category." - (interactive "SCategory name: ") - (when (assq category gnus-category-alist) - (error "Category %s already exists" category)) - (push (list category 'true nil nil) - gnus-category-alist) - (gnus-category-write) - (gnus-category-list)) - -(defun gnus-category-list () - "List all categories." - (interactive) - (gnus-category-prepare)) - -(defun gnus-category-exit () - "Return to the group buffer." - (interactive) - (kill-buffer (current-buffer)) - (gnus-configure-windows 'group t)) - -;; To avoid having 8-bit characters in the source file. -(defvar gnus-category-not (list '! 'not (intern (format "%c" 172)))) - -(defvar gnus-category-predicate-alist - '((spam . gnus-agent-spam-p) - (short . gnus-agent-short-p) - (long . gnus-agent-long-p) - (low . gnus-agent-low-scored-p) - (high . gnus-agent-high-scored-p) - (true . gnus-agent-true) - (false . gnus-agent-false)) - "Mapping from short score predicate symbols to predicate functions.") - -(defun gnus-agent-spam-p () - "Say whether an article is spam or not." - (unless gnus-agent-spam-hashtb - (setq gnus-agent-spam-hashtb (gnus-make-hashtable 1000))) - (if (not (equal (mail-header-references gnus-headers) "")) - nil - (let ((string (gnus-simplify-subject (mail-header-subject gnus-headers)))) - (prog1 - (gnus-gethash string gnus-agent-spam-hashtb) - (gnus-sethash string t gnus-agent-spam-hashtb))))) - -(defun gnus-agent-short-p () - "Say whether an article is short or not." - (< (mail-header-lines gnus-headers) gnus-agent-short-article)) - -(defun gnus-agent-long-p () - "Say whether an article is long or not." - (> (mail-header-lines gnus-headers) gnus-agent-long-article)) - -(defun gnus-agent-low-scored-p () - "Say whether an article has a low score or not." - (< gnus-score gnus-agent-low-score)) - -(defun gnus-agent-high-scored-p () - "Say whether an article has a high score or not." - (> gnus-score gnus-agent-high-score)) - -(defun gnus-category-make-function (cat) - "Make a function from category CAT." - `(lambda () ,(gnus-category-make-function-1 cat))) - -(defun gnus-agent-true () - "Return t." - t) - -(defun gnus-agent-false () - "Return nil." - nil) - -(defun gnus-category-make-function-1 (cat) - "Make a function from category CAT." - (cond - ;; Functions are just returned as is. - ((or (symbolp cat) - (gnus-functionp cat)) - `(,(or (cdr (assq cat gnus-category-predicate-alist)) - cat))) - ;; More complex category. - ((consp cat) - `(,(cond - ((memq (car cat) '(& and)) - 'and) - ((memq (car cat) '(| or)) - 'or) - ((memq (car cat) gnus-category-not) - 'not)) - ,@(mapcar 'gnus-category-make-function-1 (cdr cat)))) - (t - (error "Unknown category type: %s" cat)))) - -(defun gnus-get-predicate (predicate) - "Return the predicate for CATEGORY." - (or (cdr (assoc predicate gnus-category-predicate-cache)) - (cdar (push (cons predicate - (gnus-category-make-function predicate)) - gnus-category-predicate-cache)))) - -(defun gnus-group-category (group) - "Return the category GROUP belongs to." - (unless gnus-category-group-cache - (setq gnus-category-group-cache (gnus-make-hashtable 1000)) - (let ((cs gnus-category-alist) - groups cat) - (while (setq cat (pop cs)) - (setq groups (cadddr cat)) - (while groups - (gnus-sethash (pop groups) cat gnus-category-group-cache))))) - (or (gnus-gethash group gnus-category-group-cache) - (assq 'default gnus-category-alist))) - -(defun gnus-agent-expire () - "Expire all old articles." - (interactive) - (let ((methods gnus-agent-covered-methods) - (day (- (gnus-time-to-day (current-time)) gnus-agent-expire-days)) - gnus-command-method sym group articles - history overview file histories elem art nov-file low info - unreads marked article) - (save-excursion - (setq overview (gnus-get-buffer-create " *expire overview*")) - (while (setq gnus-command-method (pop methods)) - (let ((expiry-hashtb (gnus-make-hashtable 1023))) - (gnus-agent-open-history) - (set-buffer - (setq gnus-agent-current-history - (setq history (gnus-agent-history-buffer)))) - (goto-char (point-min)) - (when (> (buffer-size) 1) - (goto-char (point-min)) - (while (not (eobp)) - (skip-chars-forward "^\t") - (if (> (read (current-buffer)) day) - ;; New article; we don't expire it. - (forward-line 1) - ;; Old article. Schedule it for possible nuking. - (while (not (eolp)) - (setq sym (let ((obarray expiry-hashtb)) - (read (current-buffer)))) - (if (boundp sym) - (set sym (cons (cons (read (current-buffer)) (point)) - (symbol-value sym))) - (set sym (list (cons (read (current-buffer)) (point))))) - (skip-chars-forward " ")) - (forward-line 1))) - ;; We now have all articles that can possibly be expired. - (mapatoms - (lambda (sym) - (setq group (symbol-name sym) - articles (sort (symbol-value sym) 'car-less-than-car) - low (car (gnus-active group)) - info (gnus-get-info group) - unreads (ignore-errors (gnus-list-of-unread-articles group)) - marked (nconc (gnus-uncompress-range - (cdr (assq 'tick (gnus-info-marks info)))) - (gnus-uncompress-range - (cdr (assq 'dormant - (gnus-info-marks info))))) - nov-file (gnus-agent-article-name ".overview" group)) - (gnus-agent-load-alist group) - (gnus-message 5 "Expiring articles in %s" group) - (set-buffer overview) - (erase-buffer) - (when (file-exists-p nov-file) - (nnheader-insert-file-contents nov-file)) - (goto-char (point-min)) - (setq article 0) - (while (setq elem (pop articles)) - (setq article (car elem)) - (when (or (null low) - (< article low) - gnus-agent-expire-all - (and (not (memq article unreads)) - (not (memq article marked)))) - ;; Find and nuke the NOV line. - (while (and (not (eobp)) - (or (not (numberp - (setq art (read (current-buffer))))) - (< art article))) - (if (file-exists-p - (gnus-agent-article-name - (number-to-string art) group)) - (forward-line 1) - ;; Remove old NOV lines that have no articles. - (gnus-delete-line))) - (if (or (eobp) - (/= art article)) - (beginning-of-line) - (gnus-delete-line)) - ;; Nuke the article. - (when (file-exists-p (setq file (gnus-agent-article-name - (number-to-string article) - group))) - (delete-file file)) - ;; Schedule the history line for nuking. - (push (cdr elem) histories))) - (gnus-make-directory (file-name-directory nov-file)) - (let ((coding-system-for-write - gnus-agent-file-coding-system)) - (write-region (point-min) (point-max) nov-file nil 'silent)) - ;; Delete the unwanted entries in the alist. - (setq gnus-agent-article-alist - (sort gnus-agent-article-alist 'car-less-than-car)) - (let* ((alist gnus-agent-article-alist) - (prev (cons nil alist)) - (first prev) - expired) - (while (and alist - (<= (caar alist) article)) - (if (or (not (cdar alist)) - (not (file-exists-p - (gnus-agent-article-name - (number-to-string - (caar alist)) - group)))) - (progn - (push (caar alist) expired) - (setcdr prev (setq alist (cdr alist)))) - (setq prev alist - alist (cdr alist)))) - (setq gnus-agent-article-alist (cdr first)) - ;;; Mark all articles up to the first article - ;;; in `gnus-article-alist' as read. - (when (and info (caar gnus-agent-article-alist)) - (setcar (nthcdr 2 info) - (gnus-range-add - (nth 2 info) - (cons 1 (- (caar gnus-agent-article-alist) 1))))) - ;; Maybe everything has been expired from `gnus-article-alist' - ;; and so the above marking as read could not be conducted, - ;; or there are expired article within the range of the alist. - (when (or (not (caar gnus-agent-article-alist)) - (> (car expired) (caar gnus-agent-article-alist))) - (setcar (nthcdr 2 info) - (gnus-add-to-range - (nth 2 info) - (nreverse expired)))) - (gnus-dribble-enter - (concat "(gnus-group-set-info '" - (gnus-prin1-to-string info) - ")")))) - expiry-hashtb) - (set-buffer history) - (setq histories (nreverse (sort histories '<))) - (while histories - (goto-char (pop histories)) - (gnus-delete-line)) - (gnus-agent-save-history) - (gnus-agent-close-history)) - (gnus-message 4 "Expiry...done")))))) - -;;;###autoload -(defun gnus-agent-batch () - (interactive) - (let ((init-file-user "") - (gnus-always-read-dribble-file t)) - (gnus)) - (gnus-group-send-drafts) - (gnus-agent-fetch-session)) - -(provide 'gnus-agent) - -;;; gnus-agent.el ends here diff --git a/lisp/gnus-art.el b/lisp/gnus-art.el deleted file mode 100644 index e32915e..0000000 --- a/lisp/gnus-art.el +++ /dev/null @@ -1,3311 +0,0 @@ -;;; gnus-art.el --- article mode commands for Semi-gnus -;; Copyright (C) 1996,97,98 Free Software Foundation, Inc. - -;; Author: Lars Magne Ingebrigtsen -;; MORIOKA Tomohiko -;; Keywords: mail, news, MIME - -;; This file is part of GNU Emacs. - -;; GNU Emacs is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 2, or (at your option) -;; any later version. - -;; GNU Emacs is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs; see the file COPYING. If not, write to the -;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. - -;;; Commentary: - -;;; Code: - -(eval-when-compile (require 'cl)) - -(require 'custom) -(require 'gnus) -(require 'gnus-sum) -(require 'gnus-spec) -(require 'gnus-int) -(require 'browse-url) -(require 'alist) -(require 'mime-view) - -(defgroup gnus-article nil - "Article display." - :link '(custom-manual "(gnus)The Article Buffer") - :group 'gnus) - -(defgroup gnus-article-hiding nil - "Hiding article parts." - :link '(custom-manual "(gnus)Article Hiding") - :group 'gnus-article) - -(defgroup gnus-article-highlight nil - "Article highlighting." - :link '(custom-manual "(gnus)Article Highlighting") - :group 'gnus-article - :group 'gnus-visual) - -(defgroup gnus-article-signature nil - "Article signatures." - :link '(custom-manual "(gnus)Article Signature") - :group 'gnus-article) - -(defgroup gnus-article-headers nil - "Article headers." - :link '(custom-manual "(gnus)Hiding Headers") - :group 'gnus-article) - -(defgroup gnus-article-washing nil - "Special commands on articles." - :link '(custom-manual "(gnus)Article Washing") - :group 'gnus-article) - -(defgroup gnus-article-emphasis nil - "Fontisizing articles." - :link '(custom-manual "(gnus)Article Fontisizing") - :group 'gnus-article) - -(defgroup gnus-article-saving nil - "Saving articles." - :link '(custom-manual "(gnus)Saving Articles") - :group 'gnus-article) - -(defgroup gnus-article-mime nil - "Worshiping the MIME wonder." - :link '(custom-manual "(gnus)Using MIME") - :group 'gnus-article) - -(defgroup gnus-article-buttons nil - "Pushable buttons in the article buffer." - :link '(custom-manual "(gnus)Article Buttons") - :group 'gnus-article) - -(defgroup gnus-article-various nil - "Other article options." - :link '(custom-manual "(gnus)Misc Article") - :group 'gnus-article) - -(defcustom gnus-ignored-headers - '("^Path:" "^Expires:" "^Date-Received:" "^References:" "^Xref:" "^Lines:" - "^Relay-Version:" "^Message-ID:" "^Approved:" "^Sender:" "^Received:" - "^X-UIDL:" "^MIME-Version:" "^Return-Path:" "^In-Reply-To:" - "^Content-Type:" "^Content-Transfer-Encoding:" "^X-WebTV-Signature:" - "^X-MimeOLE:" "^X-MSMail-Priority:" "^X-Priority:" "^X-Loop:" - "^X-Authentication-Warning:" "^X-MIME-Autoconverted:" "^X-Face:" - "^X-Attribution:" "^X-Originating-IP:" "^Delivered-To:" - "^NNTP-[-A-Za-z]+:" "^Distribution:" "^X-no-archive:" "^X-Trace:" - "^X-Complaints-To:" "^X-NNTP-Posting-Host:" "^X-Orig.*:" - "^Abuse-Reports-To:" "^Cache-Post-Path:" "^X-Article-Creation-Date:" - "^X-Poster:" "^X-Mail2News-Path:" "^X-Server-Date:" "^X-Cache:" - "^Originator:" "^X-Problems-To:" "^X-Auth-User:" "^X-Post-Time:" - "^X-Admin:" "^X-UID:" "^Resent-[-A-Za-z]+:" "^X-Mailing-List:" - "^Precedence:" "^Original-[-A-Za-z]+:" "^X-filename:" "^X-Orcpt:" - "^Old-Received:" "^X-Pgp-Fingerprint:" "^X-Pgp-Key-Id:" - "^X-Pgp-Public-Key-Url:" "^X-Auth:" "^X-From-Line:" - "^X-Gnus-Article-Number:" "^X-Majordomo:" "^X-Url:" "^X-Sender:" - "^X-Mailing-List:" "^MBOX-Line" "^Priority:" "^X-Pgp" "^X400-[-A-Za-z]+:" - "^Status:") - "*All headers that start with this regexp will be hidden. -This variable can also be a list of regexps of headers to be ignored. -If `gnus-visible-headers' is non-nil, this variable will be ignored." - :type '(choice :custom-show nil - regexp - (repeat regexp)) - :group 'gnus-article-hiding) - -(defcustom gnus-visible-headers - "From:\\|^Newsgroups:\\|^Subject:\\|^Date:\\|^\\(Mail-\\)?Followup-To:\\|^\\(Mail-\\)?Reply-To:\\|^Mail-Copies-To:\\|^Organization:\\|^Summary:\\|^Keywords:\\|^To:\\|^Cc:\\|^Posted-To:\\|^Apparently-To:\\|^Gnus-Warning:\\|^Resent-From:\\|X-Sent:" - "*All headers that do not match this regexp will be hidden. -This variable can also be a list of regexp of headers to remain visible. -If this variable is non-nil, `gnus-ignored-headers' will be ignored." - :type '(repeat :value-to-internal (lambda (widget value) - (custom-split-regexp-maybe value)) - :match (lambda (widget value) - (or (stringp value) - (widget-editable-list-match widget value))) - regexp) - :group 'gnus-article-hiding) - -(defcustom gnus-sorted-header-list - '("^From:" "^Subject:" "^Summary:" "^Keywords:" "^Newsgroups:" - "^Followup-To:" "^To:" "^Cc:" "^Date:" "^Organization:") - "*This variable is a list of regular expressions. -If it is non-nil, headers that match the regular expressions will -be placed first in the article buffer in the sequence specified by -this list." - :type '(repeat regexp) - :group 'gnus-article-hiding) - -(defcustom gnus-boring-article-headers '(empty followup-to reply-to) - "Headers that are only to be displayed if they have interesting data. -Possible values in this list are `empty', `newsgroups', `followup-to', -`reply-to', `date', `long-to', and `many-to'." - :type '(set (const :tag "Headers with no content." empty) - (const :tag "Newsgroups with only one group." newsgroups) - (const :tag "Followup-to identical to newsgroups." followup-to) - (const :tag "Reply-to identical to from." reply-to) - (const :tag "Date less than four days old." date) - (const :tag "Very long To header." long-to) - (const :tag "Multiple To headers." many-to)) - :group 'gnus-article-hiding) - -(defcustom gnus-signature-separator '("^-- $" "^-- *$") - "Regexp matching signature separator. -This can also be a list of regexps. In that case, it will be checked -from head to tail looking for a separator. Searches will be done from -the end of the buffer." - :type '(repeat string) - :group 'gnus-article-signature) - -(defcustom gnus-signature-limit nil - "Provide a limit to what is considered a signature. -If it is a number, no signature may not be longer (in characters) than -that number. If it is a floating point number, no signature may be -longer (in lines) than that number. If it is a function, the function -will be called without any parameters, and if it returns nil, there is -no signature in the buffer. If it is a string, it will be used as a -regexp. If it matches, the text in question is not a signature." - :type '(choice (integer :value 200) - (number :value 4.0) - (function :value fun) - (regexp :value ".*")) - :group 'gnus-article-signature) - -(defcustom gnus-hidden-properties '(invisible t intangible t) - "Property list to use for hiding text." - :type 'sexp - :group 'gnus-article-hiding) - -(defcustom gnus-article-x-face-command - "{ echo '/* Width=48, Height=48 */'; uncompface; } | icontopbm | xv -quit -" - "*String or function to be executed to display an X-Face header. -If it is a string, the command will be executed in a sub-shell -asynchronously. The compressed face will be piped to this command." - :type 'string ;Leave function case to Lisp. - :group 'gnus-article-washing) - -(defcustom gnus-article-x-face-too-ugly nil - "Regexp matching posters whose face shouldn't be shown automatically." - :type '(choice regexp (const nil)) - :group 'gnus-article-washing) - -(defcustom gnus-emphasis-alist - (let ((format - "\\(\\s-\\|^\\|[-\"]\\|\\s(\\|\\s)\\)\\(%s\\(\\w+\\(\\s-+\\w+\\)*[.,]?\\)%s\\)\\(\\s-\\|[-?!.,;:\"]\\|\\s(\\|\\s)\\)") - (types - '(("_" "_" underline) - ("/" "/" italic) - ("\\*" "\\*" bold) - ("_/" "/_" underline-italic) - ("_\\*" "\\*_" underline-bold) - ("\\*/" "/\\*" bold-italic) - ("_\\*/" "/\\*_" underline-bold-italic)))) - `(("\\(\\s-\\|^\\)\\(_\\(\\(\\w\\|_[^_]\\)+\\)_\\)\\(\\s-\\|[?!.,;]\\)" - 2 3 gnus-emphasis-underline) - ,@(mapcar - (lambda (spec) - (list - (format format (car spec) (cadr spec)) - 2 3 (intern (format "gnus-emphasis-%s" (nth 2 spec))))) - types))) - "*Alist that says how to fontify certain phrases. -Each item looks like this: - - (\"_\\\\(\\\\w+\\\\)_\" 0 1 'underline) - -The first element is a regular expression to be matched. The second -is a number that says what regular expression grouping used to find -the entire emphasized word. The third is a number that says what -regexp grouping should be displayed and highlighted. The fourth -is the face used for highlighting." - :type '(repeat (list :value ("" 0 0 default) - regexp - (integer :tag "Match group") - (integer :tag "Emphasize group") - face)) - :group 'gnus-article-emphasis) - -(defface gnus-emphasis-bold '((t (:bold t))) - "Face used for displaying strong emphasized text (*word*)." - :group 'gnus-article-emphasis) - -(defface gnus-emphasis-italic '((t (:italic t))) - "Face used for displaying italic emphasized text (/word/)." - :group 'gnus-article-emphasis) - -(defface gnus-emphasis-underline '((t (:underline t))) - "Face used for displaying underlined emphasized text (_word_)." - :group 'gnus-article-emphasis) - -(defface gnus-emphasis-underline-bold '((t (:bold t :underline t))) - "Face used for displaying underlined bold emphasized text (_*word*_)." - :group 'gnus-article-emphasis) - -(defface gnus-emphasis-underline-italic '((t (:italic t :underline t))) - "Face used for displaying underlined italic emphasized text (_*word*_)." - :group 'gnus-article-emphasis) - -(defface gnus-emphasis-bold-italic '((t (:bold t :italic t))) - "Face used for displaying bold italic emphasized text (/*word*/)." - :group 'gnus-article-emphasis) - -(defface gnus-emphasis-underline-bold-italic - '((t (:bold t :italic t :underline t))) - "Face used for displaying underlined bold italic emphasized text. -Esample: (_/*word*/_)." - :group 'gnus-article-emphasis) - -(defcustom gnus-article-time-format "%a, %b %d %Y %T %Z" - "Format for display of Date headers in article bodies. -See `format-time-string' for the possible values. - -The variable can also be function, which should return a complete Date -header. The function is called with one argument, the time, which can -be fed to `format-time-string'." - :type '(choice string symbol) - :link '(custom-manual "(gnus)Article Date") - :group 'gnus-article-washing) - -(eval-and-compile - (autoload 'hexl-hex-string-to-integer "hexl") - (autoload 'timezone-make-date-arpa-standard "timezone") - (autoload 'mail-extract-address-components "mail-extr")) - -(defcustom gnus-save-all-headers t - "*If non-nil, don't remove any headers before saving." - :group 'gnus-article-saving - :type 'boolean) - -(defcustom gnus-prompt-before-saving 'always - "*This variable says how much prompting is to be done when saving articles. -If it is nil, no prompting will be done, and the articles will be -saved to the default files. If this variable is `always', each and -every article that is saved will be preceded by a prompt, even when -saving large batches of articles. If this variable is neither nil not -`always', there the user will be prompted once for a file name for -each invocation of the saving commands." - :group 'gnus-article-saving - :type '(choice (item always) - (item :tag "never" nil) - (sexp :tag "once" :format "%t\n" :value t))) - -(defcustom gnus-saved-headers gnus-visible-headers - "Headers to keep if `gnus-save-all-headers' is nil. -If `gnus-save-all-headers' is non-nil, this variable will be ignored. -If that variable is nil, however, all headers that match this regexp -will be kept while the rest will be deleted before saving." - :group 'gnus-article-saving - :type 'regexp) - -(defcustom gnus-default-article-saver 'gnus-summary-save-in-rmail - "A function to save articles in your favourite format. -The function must be interactively callable (in other words, it must -be an Emacs command). - -Gnus provides the following functions: - -* gnus-summary-save-in-rmail (Rmail format) -* gnus-summary-save-in-mail (Unix mail format) -* gnus-summary-save-in-folder (MH folder) -* gnus-summary-save-in-file (article format) -* gnus-summary-save-in-vm (use VM's folder format) -* gnus-summary-write-to-file (article format -- overwrite)." - :group 'gnus-article-saving - :type '(radio (function-item gnus-summary-save-in-rmail) - (function-item gnus-summary-save-in-mail) - (function-item gnus-summary-save-in-folder) - (function-item gnus-summary-save-in-file) - (function-item gnus-summary-save-in-vm) - (function-item gnus-summary-write-to-file))) - -(defcustom gnus-rmail-save-name 'gnus-plain-save-name - "A function generating a file name to save articles in Rmail format. -The function is called with NEWSGROUP, HEADERS, and optional LAST-FILE." - :group 'gnus-article-saving - :type 'function) - -(defcustom gnus-mail-save-name 'gnus-plain-save-name - "A function generating a file name to save articles in Unix mail format. -The function is called with NEWSGROUP, HEADERS, and optional LAST-FILE." - :group 'gnus-article-saving - :type 'function) - -(defcustom gnus-folder-save-name 'gnus-folder-save-name - "A function generating a file name to save articles in MH folder. -The function is called with NEWSGROUP, HEADERS, and optional LAST-FOLDER." - :group 'gnus-article-saving - :type 'function) - -(defcustom gnus-file-save-name 'gnus-numeric-save-name - "A function generating a file name to save articles in article format. -The function is called with NEWSGROUP, HEADERS, and optional -LAST-FILE." - :group 'gnus-article-saving - :type 'function) - -(defcustom gnus-split-methods - '((gnus-article-archive-name) - (gnus-article-nndoc-name)) - "*Variable used to suggest where articles are to be saved. -For instance, if you would like to save articles related to Gnus in -the file \"gnus-stuff\", and articles related to VM in \"vm-stuff\", -you could set this variable to something like: - - '((\"^Subject:.*gnus\\|^Newsgroups:.*gnus\" \"gnus-stuff\") - (\"^Subject:.*vm\\|^Xref:.*vm\" \"vm-stuff\")) - -This variable is an alist where the where the key is the match and the -value is a list of possible files to save in if the match is non-nil. - -If the match is a string, it is used as a regexp match on the -article. If the match is a symbol, that symbol will be funcalled -from the buffer of the article to be saved with the newsgroup as the -parameter. If it is a list, it will be evaled in the same buffer. - -If this form or function returns a string, this string will be used as -a possible file name; and if it returns a non-nil list, that list will -be used as possible file names." - :group 'gnus-article-saving - :type '(repeat (choice (list :value (fun) function) - (cons :value ("" "") regexp (repeat string)) - (sexp :value nil)))) - -(defcustom gnus-strict-mime t - "*If nil, MIME-decode even if there is no MIME-Version header." - :group 'gnus-article-mime - :type 'boolean) - -(defcustom gnus-article-display-method-for-mime - 'gnus-article-display-mime-message - "Function to display a MIME message. -The function is called from the article buffer." - :group 'gnus-article-mime - :type 'function) - -(defcustom gnus-article-display-method-for-encoded-word - 'gnus-article-display-message-with-encoded-word - "*Function to display a message with MIME encoded-words. -The function is called from the article buffer." - :group 'gnus-article-mime - :type 'function) - -(defcustom gnus-article-display-method-for-traditional - 'gnus-article-display-traditional-message - "*Function to display a traditional message. -The function is called from the article buffer." - :group 'gnus-article-mime - :type 'function) - -(defcustom gnus-page-delimiter "^\^L" - "*Regexp describing what to use as article page delimiters. -The default value is \"^\^L\", which is a form linefeed at the -beginning of a line." - :type 'regexp - :group 'gnus-article-various) - -(defcustom gnus-article-mode-line-format "Gnus: %%b %S" - "*The format specification for the article mode line. -See `gnus-summary-mode-line-format' for a closer description." - :type 'string - :group 'gnus-article-various) - -(defcustom gnus-article-mode-hook nil - "*A hook for Gnus article mode." - :type 'hook - :group 'gnus-article-various) - -(defcustom gnus-article-menu-hook nil - "*Hook run after the creation of the article mode menu." - :type 'hook - :group 'gnus-article-various) - -(defcustom gnus-article-prepare-hook nil - "*A hook called after an article has been prepared in the article buffer. -If you want to run a special decoding program like nkf, use this hook." - :type 'hook - :group 'gnus-article-various) - -(defcustom gnus-article-hide-pgp-hook nil - "*A hook called after successfully hiding a PGP signature." - :type 'hook - :group 'gnus-article-various) - -(defcustom gnus-article-button-face 'bold - "Face used for highlighting buttons in the article buffer. - -An article button is a piece of text that you can activate by pressing -`RET' or `mouse-2' above it." - :type 'face - :group 'gnus-article-buttons) - -(defcustom gnus-article-mouse-face 'highlight - "Face used for mouse highlighting in the article buffer. - -Article buttons will be displayed in this face when the cursor is -above them." - :type 'face - :group 'gnus-article-buttons) - -(defcustom gnus-signature-face 'gnus-signature-face - "Face used for highlighting a signature in the article buffer. -Obsolete; use the face `gnus-signature-face' for customizations instead." - :type 'face - :group 'gnus-article-highlight - :group 'gnus-article-signature) - -(defface gnus-signature-face - '((((type x)) - (:italic t))) - "Face used for highlighting a signature in the article buffer." - :group 'gnus-article-highlight - :group 'gnus-article-signature) - -(defface gnus-header-from-face - '((((class color) - (background dark)) - (:foreground "spring green")) - (((class color) - (background light)) - (:foreground "red3")) - (t - (:italic t))) - "Face used for displaying from headers." - :group 'gnus-article-headers - :group 'gnus-article-highlight) - -(defface gnus-header-subject-face - '((((class color) - (background dark)) - (:foreground "SeaGreen3")) - (((class color) - (background light)) - (:foreground "red4")) - (t - (:bold t :italic t))) - "Face used for displaying subject headers." - :group 'gnus-article-headers - :group 'gnus-article-highlight) - -(defface gnus-header-newsgroups-face - '((((class color) - (background dark)) - (:foreground "yellow" :italic t)) - (((class color) - (background light)) - (:foreground "MidnightBlue" :italic t)) - (t - (:italic t))) - "Face used for displaying newsgroups headers." - :group 'gnus-article-headers - :group 'gnus-article-highlight) - -(defface gnus-header-name-face - '((((class color) - (background dark)) - (:foreground "SeaGreen")) - (((class color) - (background light)) - (:foreground "maroon")) - (t - (:bold t))) - "Face used for displaying header names." - :group 'gnus-article-headers - :group 'gnus-article-highlight) - -(defface gnus-header-content-face - '((((class color) - (background dark)) - (:foreground "forest green" :italic t)) - (((class color) - (background light)) - (:foreground "indianred4" :italic t)) - (t - (:italic t))) "Face used for displaying header content." - :group 'gnus-article-headers - :group 'gnus-article-highlight) - -(defcustom gnus-header-face-alist - '(("From" nil gnus-header-from-face) - ("Subject" nil gnus-header-subject-face) - ("Newsgroups:.*," nil gnus-header-newsgroups-face) - ("" gnus-header-name-face gnus-header-content-face)) - "*Controls highlighting of article header. - -An alist of the form (HEADER NAME CONTENT). - -HEADER is a regular expression which should match the name of an -header header and NAME and CONTENT are either face names or nil. - -The name of each header field will be displayed using the face -specified by the first element in the list where HEADER match the -header name and NAME is non-nil. Similarly, the content will be -displayed by the first non-nil matching CONTENT face." - :group 'gnus-article-headers - :group 'gnus-article-highlight - :type '(repeat (list (regexp :tag "Header") - (choice :tag "Name" - (item :tag "skip" nil) - (face :value default)) - (choice :tag "Content" - (item :tag "skip" nil) - (face :value default))))) - -;;; Internal variables - -(defvar article-lapsed-timer nil) -(defvar gnus-article-current-summary nil) - -(defvar gnus-article-mode-syntax-table - (let ((table (copy-syntax-table text-mode-syntax-table))) - (modify-syntax-entry ?- "w" table) - (modify-syntax-entry ?> ")" table) - (modify-syntax-entry ?< "(" table) - table) - "Syntax table used in article mode buffers. -Initialized from `text-mode-syntax-table.") - -(defvar gnus-save-article-buffer nil) - -(defvar gnus-article-mode-line-format-alist - (nconc '((?w (gnus-article-wash-status) ?s)) - gnus-summary-mode-line-format-alist)) - -(defvar gnus-number-of-articles-to-be-saved nil) - -(defvar gnus-inhibit-hiding nil) - -(defsubst gnus-article-hide-text (b e props) - "Set text PROPS on the B to E region, extending `intangible' 1 past B." - (add-text-properties b e props) - (when (memq 'intangible props) - (put-text-property - (max (1- b) (point-min)) - b 'intangible (cddr (memq 'intangible props))))) - -(defsubst gnus-article-unhide-text (b e) - "Remove hidden text properties from region between B and E." - (remove-text-properties b e gnus-hidden-properties) - (when (memq 'intangible gnus-hidden-properties) - (put-text-property (max (1- b) (point-min)) - b 'intangible nil))) - -(defun gnus-article-hide-text-type (b e type) - "Hide text of TYPE between B and E." - (gnus-article-hide-text - b e (cons 'article-type (cons type gnus-hidden-properties)))) - -(defun gnus-article-unhide-text-type (b e type) - "Unhide text of TYPE between B and E." - (remove-text-properties - b e (cons 'article-type (cons type gnus-hidden-properties))) - (when (memq 'intangible gnus-hidden-properties) - (put-text-property (max (1- b) (point-min)) - b 'intangible nil))) - -(defun gnus-article-hide-text-of-type (type) - "Hide text of TYPE in the current buffer." - (save-excursion - (let ((b (point-min)) - (e (point-max))) - (while (setq b (text-property-any b e 'article-type type)) - (add-text-properties b (incf b) gnus-hidden-properties))))) - -(defun gnus-article-delete-text-of-type (type) - "Delete text of TYPE in the current buffer." - (save-excursion - (let ((b (point-min))) - (while (setq b (text-property-any b (point-max) 'article-type type)) - (delete-region - b (or (text-property-not-all b (point-max) 'article-type type) - (point-max))))))) - -(defun gnus-article-delete-invisible-text () - "Delete all invisible text in the current buffer." - (save-excursion - (let ((b (point-min))) - (while (setq b (text-property-any b (point-max) 'invisible t)) - (delete-region - b (or (text-property-not-all b (point-max) 'invisible t) - (point-max))))))) - -(defun gnus-article-text-type-exists-p (type) - "Say whether any text of type TYPE exists in the buffer." - (text-property-any (point-min) (point-max) 'article-type type)) - -(defsubst gnus-article-header-rank () - "Give the rank of the string HEADER as given by `gnus-sorted-header-list'." - (let ((list gnus-sorted-header-list) - (i 0)) - (while list - (when (looking-at (car list)) - (setq list nil)) - (setq list (cdr list)) - (incf i)) - i)) - -(defun article-hide-headers (&optional arg delete) - "Toggle whether to hide unwanted headers and possibly sort them as well. -If given a negative prefix, always show; if given a positive prefix, -always hide." - (interactive (gnus-article-hidden-arg)) - (current-buffer) - (if (gnus-article-check-hidden-text 'headers arg) - ;; Show boring headers as well. - (gnus-article-show-hidden-text 'boring-headers) - ;; This function might be inhibited. - (unless gnus-inhibit-hiding - (save-excursion - (save-restriction - (let ((buffer-read-only nil) - (case-fold-search t) - (props (nconc (list 'article-type 'headers) - gnus-hidden-properties)) - (max (1+ (length gnus-sorted-header-list))) - (ignored (when (not gnus-visible-headers) - (cond ((stringp gnus-ignored-headers) - gnus-ignored-headers) - ((listp gnus-ignored-headers) - (mapconcat 'identity gnus-ignored-headers - "\\|"))))) - (visible - (cond ((stringp gnus-visible-headers) - gnus-visible-headers) - ((and gnus-visible-headers - (listp gnus-visible-headers)) - (mapconcat 'identity gnus-visible-headers "\\|")))) - (inhibit-point-motion-hooks t) - beg) - ;; First we narrow to just the headers. - (widen) - (goto-char (point-min)) - ;; Hide any "From " lines at the beginning of (mail) articles. - (while (looking-at "From ") - (forward-line 1)) - (unless (bobp) - (if delete - (delete-region (point-min) (point)) - (gnus-article-hide-text (point-min) (point) props))) - ;; Then treat the rest of the header lines. - (narrow-to-region - (point) - (if (search-forward "\n\n" nil t) ; if there's a body - (progn (forward-line -1) (point)) - (point-max))) - ;; Then we use the two regular expressions - ;; `gnus-ignored-headers' and `gnus-visible-headers' to - ;; select which header lines is to remain visible in the - ;; article buffer. - (goto-char (point-min)) - (while (re-search-forward "^[^ \t]*:" nil t) - (beginning-of-line) - ;; Mark the rank of the header. - (put-text-property - (point) (1+ (point)) 'message-rank - (if (or (and visible (looking-at visible)) - (and ignored - (not (looking-at ignored)))) - (gnus-article-header-rank) - (+ 2 max))) - (forward-line 1)) - (message-sort-headers-1) - (when (setq beg (text-property-any - (point-min) (point-max) 'message-rank (+ 2 max))) - ;; We make the unwanted headers invisible. - (if delete - (delete-region beg (point-max)) - ;; Suggested by Sudish Joseph . - (gnus-article-hide-text-type beg (point-max) 'headers)) - ;; Work around XEmacs lossage. - (put-text-property (point-min) beg 'invisible nil)))))))) - -(defun article-hide-boring-headers (&optional arg) - "Toggle hiding of headers that aren't very interesting. -If given a negative prefix, always show; if given a positive prefix, -always hide." - (interactive (gnus-article-hidden-arg)) - (when (and (not (gnus-article-check-hidden-text 'boring-headers arg)) - (not gnus-show-all-headers)) - (save-excursion - (save-restriction - (let ((buffer-read-only nil) - (list gnus-boring-article-headers) - (inhibit-point-motion-hooks t) - elem) - (nnheader-narrow-to-headers) - (while list - (setq elem (pop list)) - (goto-char (point-min)) - (cond - ;; Hide empty headers. - ((eq elem 'empty) - (while (re-search-forward "^[^:]+:[ \t]*\n[^ \t]" nil t) - (forward-line -1) - (gnus-article-hide-text-type - (progn (beginning-of-line) (point)) - (progn - (end-of-line) - (if (re-search-forward "^[^ \t]" nil t) - (match-beginning 0) - (point-max))) - 'boring-headers))) - ;; Hide boring Newsgroups header. - ((eq elem 'newsgroups) - (when (equal (gnus-fetch-field "newsgroups") - (gnus-group-real-name - (if (boundp 'gnus-newsgroup-name) - gnus-newsgroup-name - ""))) - (gnus-article-hide-header "newsgroups"))) - ((eq elem 'followup-to) - (when (equal (message-fetch-field "followup-to") - (message-fetch-field "newsgroups")) - (gnus-article-hide-header "followup-to"))) - ((eq elem 'reply-to) - (let ((from (message-fetch-field "from")) - (reply-to (message-fetch-field "reply-to"))) - (when (and - from reply-to - (ignore-errors - (equal - (nth 1 (funcall gnus-extract-address-components from)) - (nth 1 (funcall gnus-extract-address-components reply-to))))) - (gnus-article-hide-header "reply-to")))) - ((eq elem 'date) - (let ((date (message-fetch-field "date"))) - (when (and date - (< (gnus-days-between (current-time-string) date) - 4)) - (gnus-article-hide-header "date")))) - ((eq elem 'long-to) - (let ((to (message-fetch-field "to"))) - (when (> (length to) 1024) - (gnus-article-hide-header "to")))) - ((eq elem 'many-to) - (let ((to-count 0)) - (goto-char (point-min)) - (while (re-search-forward "^to:" nil t) - (setq to-count (1+ to-count))) - (when (> to-count 1) - (while (> to-count 0) - (goto-char (point-min)) - (save-restriction - (re-search-forward "^to:" nil nil to-count) - (forward-line -1) - (narrow-to-region (point) (point-max)) - (gnus-article-hide-header "to")) - (setq to-count (1- to-count))))))))))))) - -(defun gnus-article-hide-header (header) - (save-excursion - (goto-char (point-min)) - (when (re-search-forward (concat "^" header ":") nil t) - (gnus-article-hide-text-type - (progn (beginning-of-line) (point)) - (progn - (end-of-line) - (if (re-search-forward "^[^ \t]" nil t) - (match-beginning 0) - (point-max))) - 'boring-headers)))) - -(defun article-treat-dumbquotes () - "Translate M******** sm*rtq**t*s into proper text." - (interactive) - (article-translate-characters "\221\222\223\223" "`'\"\"")) - -(defun article-translate-characters (from to) - "Translate all characters in the body of the article according to FROM and TO. -FROM is a string of characters to translate from; to is a string of -characters to translate to." - (save-excursion - (goto-char (point-min)) - (when (search-forward "\n\n" nil t) - (let ((buffer-read-only nil) - (x (make-string 225 ?x)) - (i -1)) - (while (< (incf i) (length x)) - (aset x i i)) - (setq i 0) - (while (< i (length from)) - (aset x (aref from i) (aref to i)) - (incf i)) - (translate-region (point) (point-max) x))))) - -(defun article-treat-overstrike () - "Translate overstrikes into bold text." - (interactive) - (save-excursion - (goto-char (point-min)) - (when (search-forward "\n\n" nil t) - (let ((buffer-read-only nil)) - (while (search-forward "\b" nil t) - (let ((next (following-char)) - (previous (char-after (- (point) 2)))) - ;; We do the boldification/underlining by hiding the - ;; overstrikes and putting the proper text property - ;; on the letters. - (cond - ((eq next previous) - (gnus-article-hide-text-type (- (point) 2) (point) 'overstrike) - (put-text-property (point) (1+ (point)) 'face 'bold)) - ((eq next ?_) - (gnus-article-hide-text-type - (1- (point)) (1+ (point)) 'overstrike) - (put-text-property - (- (point) 2) (1- (point)) 'face 'underline)) - ((eq previous ?_) - (gnus-article-hide-text-type (- (point) 2) (point) 'overstrike) - (put-text-property - (point) (1+ (point)) 'face 'underline))))))))) - -(defun article-fill () - "Format too long lines." - (interactive) - (save-excursion - (let ((buffer-read-only nil)) - (widen) - (goto-char (point-min)) - (search-forward "\n\n" nil t) - (end-of-line 1) - (let ((paragraph-start "^[>|#:<;* ]*[ \t]*$") - (adaptive-fill-regexp "[ \t]*\\([|#:<;>*]+ *\\)?") - (adaptive-fill-mode t)) - (while (not (eobp)) - (and (>= (current-column) (min fill-column (window-width))) - (/= (preceding-char) ?:) - (fill-paragraph nil)) - (end-of-line 2)))))) - -(defun article-remove-cr () - "Remove carriage returns from an article." - (interactive) - (save-excursion - (let ((buffer-read-only nil)) - (goto-char (point-min)) - (while (search-forward "\r" nil t) - (replace-match "" t t))))) - -(defun article-remove-trailing-blank-lines () - "Remove all trailing blank lines from the article." - (interactive) - (save-excursion - (let ((buffer-read-only nil)) - (goto-char (point-max)) - (delete-region - (point) - (progn - (while (and (not (bobp)) - (looking-at "^[ \t]*$")) - (forward-line -1)) - (forward-line 1) - (point)))))) - -(defun article-display-x-face (&optional force) - "Look for an X-Face header and display it if present." - (interactive (list 'force)) - (save-excursion - ;; Delete the old process, if any. - (when (process-status "article-x-face") - (delete-process "article-x-face")) - (let ((inhibit-point-motion-hooks t) - (case-fold-search t) - from last) - (save-restriction - (nnheader-narrow-to-headers) - (setq from (message-fetch-field "from")) - (goto-char (point-min)) - (while (and gnus-article-x-face-command - (not last) - (or force - ;; Check whether this face is censored. - (not gnus-article-x-face-too-ugly) - (and gnus-article-x-face-too-ugly from - (not (string-match gnus-article-x-face-too-ugly - from)))) - ;; Has to be present. - (re-search-forward "^X-Face: " nil t)) - ;; This used to try to do multiple faces (`while' instead of - ;; `when' above), but (a) sending multiple EOFs to xv doesn't - ;; work (b) it can crash some versions of Emacs (c) are - ;; multiple faces really something to encourage? - (when (stringp gnus-article-x-face-command) - (setq last t)) - ;; We now have the area of the buffer where the X-Face is stored. - (save-excursion - (let ((beg (point)) - (end (1- (re-search-forward "^\\($\\|[^ \t]\\)" nil t)))) - ;; We display the face. - (if (symbolp gnus-article-x-face-command) - ;; The command is a lisp function, so we call it. - (if (gnus-functionp gnus-article-x-face-command) - (funcall gnus-article-x-face-command beg end) - (error "%s is not a function" gnus-article-x-face-command)) - ;; The command is a string, so we interpret the command - ;; as a, well, command, and fork it off. - (let ((process-connection-type nil)) - (process-kill-without-query - (start-process - "article-x-face" nil shell-file-name shell-command-switch - gnus-article-x-face-command)) - (process-send-region "article-x-face" beg end) - (process-send-eof "article-x-face")))))))))) - -(defun gnus-article-decode-rfc1522 () - "Decode MIME encoded-words in header fields." - (let (buffer-read-only) - (let ((charset (save-excursion - (set-buffer gnus-summary-buffer) - default-mime-charset))) - (eword-decode-header charset) - ))) - -(defun article-hide-pgp (&optional arg) - "Toggle hiding of any PGP headers and signatures in the current article. -If given a negative prefix, always show; if given a positive prefix, -always hide." - (interactive (gnus-article-hidden-arg)) - (unless (gnus-article-check-hidden-text 'pgp arg) - (save-excursion - (let ((inhibit-point-motion-hooks t) - buffer-read-only beg end) - (widen) - (goto-char (point-min)) - ;; Hide the "header". - (when (search-forward "\n-----BEGIN PGP SIGNED MESSAGE-----\n" nil t) - (delete-region (1+ (match-beginning 0)) (match-end 0)) - (setq beg (point)) - ;; Hide the actual signature. - (and (search-forward "\n-----BEGIN PGP SIGNATURE-----\n" nil t) - (setq end (1+ (match-beginning 0))) - (delete-region - end - (if (search-forward "\n-----END PGP SIGNATURE-----\n" nil t) - (match-end 0) - ;; Perhaps we shouldn't hide to the end of the buffer - ;; if there is no end to the signature? - (point-max)))) - ;; Hide "- " PGP quotation markers. - (when (and beg end) - (narrow-to-region beg end) - (goto-char (point-min)) - (while (re-search-forward "^- " nil t) - (delete-region - (match-beginning 0) (match-end 0))) - (widen)) - (gnus-run-hooks 'gnus-article-hide-pgp-hook)))))) - -(defun article-hide-pem (&optional arg) - "Toggle hiding of any PEM headers and signatures in the current article. -If given a negative prefix, always show; if given a positive prefix, -always hide." - (interactive (gnus-article-hidden-arg)) - (unless (gnus-article-check-hidden-text 'pem arg) - (save-excursion - (let (buffer-read-only end) - (widen) - (goto-char (point-min)) - ;; hide the horrendously ugly "header". - (and (search-forward "\n-----BEGIN PRIVACY-ENHANCED MESSAGE-----\n" - nil - t) - (setq end (1+ (match-beginning 0))) - (gnus-article-hide-text-type - end - (if (search-forward "\n\n" nil t) - (match-end 0) - (point-max)) - 'pem)) - ;; hide the trailer as well - (and (search-forward "\n-----END PRIVACY-ENHANCED MESSAGE-----\n" - nil - t) - (gnus-article-hide-text-type - (match-beginning 0) (match-end 0) 'pem)))))) - -(defun article-hide-signature (&optional arg) - "Hide the signature in the current article. -If given a negative prefix, always show; if given a positive prefix, -always hide." - (interactive (gnus-article-hidden-arg)) - (unless (gnus-article-check-hidden-text 'signature arg) - (save-excursion - (save-restriction - (let ((buffer-read-only nil)) - (when (gnus-article-narrow-to-signature) - (gnus-article-hide-text-type - (point-min) (point-max) 'signature))))))) - -(defun article-strip-leading-blank-lines () - "Remove all blank lines from the beginning of the article." - (interactive) - (save-excursion - (let ((inhibit-point-motion-hooks t) - buffer-read-only) - (goto-char (point-min)) - (when (search-forward "\n\n" nil t) - (while (and (not (eobp)) - (looking-at "[ \t]*$")) - (gnus-delete-line)))))) - -(defun article-strip-multiple-blank-lines () - "Replace consecutive blank lines with one empty line." - (interactive) - (save-excursion - (let ((inhibit-point-motion-hooks t) - buffer-read-only) - ;; First make all blank lines empty. - (goto-char (point-min)) - (search-forward "\n\n" nil t) - (while (re-search-forward "^[ \t]+$" nil t) - (replace-match "" nil t)) - ;; Then replace multiple empty lines with a single empty line. - (goto-char (point-min)) - (search-forward "\n\n" nil t) - (while (re-search-forward "\n\n\n+" nil t) - (replace-match "\n\n" t t))))) - -(defun article-strip-leading-space () - "Remove all white space from the beginning of the lines in the article." - (interactive) - (save-excursion - (let ((inhibit-point-motion-hooks t) - buffer-read-only) - (goto-char (point-min)) - (search-forward "\n\n" nil t) - (while (re-search-forward "^[ \t]+" nil t) - (replace-match "" t t))))) - -(defun article-strip-blank-lines () - "Strip leading, trailing and multiple blank lines." - (interactive) - (article-strip-leading-blank-lines) - (article-remove-trailing-blank-lines) - (article-strip-multiple-blank-lines)) - -(defun article-strip-all-blank-lines () - "Strip all blank lines." - (interactive) - (save-excursion - (let ((inhibit-point-motion-hooks t) - buffer-read-only) - (goto-char (point-min)) - (search-forward "\n\n" nil t) - (while (re-search-forward "^[ \t]*\n" nil t) - (replace-match "" t t))))) - -(defun gnus-article-narrow-to-signature () - "Narrow to the signature; return t if a signature is found, else nil." - (widen) - (let ((inhibit-point-motion-hooks t)) - (when (gnus-article-search-signature) - (forward-line 1) - ;; Check whether we have some limits to what we consider - ;; to be a signature. - (let ((limits (if (listp gnus-signature-limit) gnus-signature-limit - (list gnus-signature-limit))) - limit limited) - (while (setq limit (pop limits)) - (if (or (and (integerp limit) - (< (- (point-max) (point)) limit)) - (and (floatp limit) - (< (count-lines (point) (point-max)) limit)) - (and (gnus-functionp limit) - (funcall limit)) - (and (stringp limit) - (not (re-search-forward limit nil t)))) - () ; This limit did not succeed. - (setq limited t - limits nil))) - (unless limited - (narrow-to-region (point) (point-max)) - t))))) - -(defun gnus-article-search-signature () - "Search the current buffer for the signature separator. -Put point at the beginning of the signature separator." - (let ((cur (point))) - (goto-char (point-max)) - (if (if (stringp gnus-signature-separator) - (re-search-backward gnus-signature-separator nil t) - (let ((seps gnus-signature-separator)) - (while (and seps - (not (re-search-backward (car seps) nil t))) - (pop seps)) - seps)) - t - (goto-char cur) - nil))) - -(eval-and-compile - (autoload 'w3-display "w3-parse") - (autoload 'w3-do-setup "w3" "" t) - (autoload 'w3-region "w3-display" "" t)) - -(defun gnus-article-treat-html () - "Render HTML." - (interactive) - (let ((cbuf (current-buffer))) - (set-buffer gnus-article-buffer) - (let (buf buffer-read-only b e) - (w3-do-setup) - (goto-char (point-min)) - (narrow-to-region - (if (search-forward "\n\n" nil t) - (setq b (point)) - (point-max)) - (setq e (point-max))) - (nnheader-temp-write nil - (insert-buffer-substring gnus-article-buffer b e) - (require 'url) - (save-window-excursion - (w3-region (point-min) (point-max)) - (setq buf (buffer-substring-no-properties (point-min) (point-max))))) - (when buf - (delete-region (point-min) (point-max)) - (insert buf)) - (widen) - (goto-char (point-min)) - (set-window-start (get-buffer-window (current-buffer)) (point-min)) - (set-buffer cbuf)))) - -(defun gnus-article-hidden-arg () - "Return the current prefix arg as a number, or 0 if no prefix." - (list (if current-prefix-arg - (prefix-numeric-value current-prefix-arg) - 0))) - -(defun gnus-article-check-hidden-text (type arg) - "Return nil if hiding is necessary. -Arg can be nil or a number. Nil and positive means hide, negative -means show, 0 means toggle." - (save-excursion - (save-restriction - (widen) - (let ((hide (gnus-article-hidden-text-p type))) - (cond - ((or (null arg) - (> arg 0)) - nil) - ((< arg 0) - (gnus-article-show-hidden-text type)) - (t - (if (eq hide 'hidden) - (gnus-article-show-hidden-text type) - nil))))))) - -(defun gnus-article-hidden-text-p (type) - "Say whether the current buffer contains hidden text of type TYPE." - (let ((pos (text-property-any (point-min) (point-max) 'article-type type))) - (while (and pos - (not (get-text-property pos 'invisible))) - (setq pos - (text-property-any (1+ pos) (point-max) 'article-type type))) - (if pos - 'hidden - 'shown))) - -(defun gnus-article-show-hidden-text (type &optional hide) - "Show all hidden text of type TYPE. -If HIDE, hide the text instead." - (save-excursion - (let ((buffer-read-only nil) - (inhibit-point-motion-hooks t) - (end (point-min)) - beg) - (while (setq beg (text-property-any end (point-max) 'article-type type)) - (goto-char beg) - (setq end (or - (text-property-not-all beg (point-max) 'article-type type) - (point-max))) - (if hide - (gnus-article-hide-text beg end gnus-hidden-properties) - (gnus-article-unhide-text beg end)) - (goto-char end)) - t))) - -(defconst article-time-units - `((year . ,(* 365.25 24 60 60)) - (week . ,(* 7 24 60 60)) - (day . ,(* 24 60 60)) - (hour . ,(* 60 60)) - (minute . 60) - (second . 1)) - "Mapping from time units to seconds.") - -(defun article-date-ut (&optional type highlight header) - "Convert DATE date to universal time in the current article. -If TYPE is `local', convert to local time; if it is `lapsed', output -how much time has lapsed since DATE." - (interactive (list 'ut t)) - (let* ((header (or header - (mail-header-date gnus-current-headers) - (message-fetch-field "date") - "")) - (date (if (vectorp header) (mail-header-date header) - header)) - (date-regexp "^Date:[ \t]\\|^X-Sent:[ \t]") - (inhibit-point-motion-hooks t) - bface eface newline) - (when (and date (not (string= date ""))) - (save-excursion - (save-restriction - (nnheader-narrow-to-headers) - (let ((buffer-read-only nil)) - ;; Delete any old Date headers. - (if (re-search-forward date-regexp nil t) - (progn - (setq bface (get-text-property (gnus-point-at-bol) 'face) - eface (get-text-property (1- (gnus-point-at-eol)) - 'face)) - (delete-region (progn (beginning-of-line) (point)) - (progn (end-of-line) (point))) - (beginning-of-line)) - (goto-char (point-max)) - (setq newline t)) - (insert (article-make-date-line date type)) - ;; Do highlighting. - (beginning-of-line) - (when (looking-at "\\([^:]+\\): *\\(.*\\)$") - (put-text-property (match-beginning 1) (1+ (match-end 1)) - 'face bface) - (put-text-property (match-beginning 2) (match-end 2) - 'face eface)) - (when newline - (end-of-line) - (insert "\n")))))))) - -(defun article-make-date-line (date type) - "Return a DATE line of TYPE." - (cond - ;; Convert to the local timezone. We have to slap a - ;; `condition-case' round the calls to the timezone - ;; functions since they aren't particularly resistant to - ;; buggy dates. - ((eq type 'local) - (concat "Date: " (condition-case () - (timezone-make-date-arpa-standard date) - (error date)))) - ;; Convert to Universal Time. - ((eq type 'ut) - (concat "Date: " - (condition-case () - (timezone-make-date-arpa-standard date nil "UT") - (error date)))) - ;; Get the original date from the article. - ((eq type 'original) - (concat "Date: " date)) - ;; Let the user define the format. - ((eq type 'user) - (if (gnus-functionp gnus-article-time-format) - (funcall - gnus-article-time-format - (ignore-errors - (gnus-encode-date - (timezone-make-date-arpa-standard - date nil "UT")))) - (concat - "Date: " - (format-time-string gnus-article-time-format - (ignore-errors - (gnus-encode-date - (timezone-make-date-arpa-standard - date nil "UT"))))))) - ;; ISO 8601. - ((eq type 'iso8601) - (concat - "Date: " - (format-time-string "%Y%M%DT%h%m%s" - (ignore-errors - (gnus-encode-date - (timezone-make-date-arpa-standard - date nil "UT")))))) - ;; Do an X-Sent lapsed format. - ((eq type 'lapsed) - ;; If the date is seriously mangled, the timezone functions are - ;; liable to bug out, so we ignore all errors. - (let* ((now (current-time)) - (real-time - (ignore-errors - (gnus-time-minus - (gnus-encode-date - (timezone-make-date-arpa-standard - (current-time-string now) - (current-time-zone now) "UT")) - (gnus-encode-date - (timezone-make-date-arpa-standard - date nil "UT"))))) - (real-sec (and real-time - (+ (* (float (car real-time)) 65536) - (cadr real-time)))) - (sec (and real-time (abs real-sec))) - num prev) - (cond - ((null real-time) - "X-Sent: Unknown") - ((zerop sec) - "X-Sent: Now") - (t - (concat - "X-Sent: " - ;; This is a bit convoluted, but basically we go - ;; through the time units for years, weeks, etc, - ;; and divide things to see whether that results - ;; in positive answers. - (mapconcat - (lambda (unit) - (if (zerop (setq num (ffloor (/ sec (cdr unit))))) - ;; The (remaining) seconds are too few to - ;; be divided into this time unit. - "" - ;; It's big enough, so we output it. - (setq sec (- sec (* num (cdr unit)))) - (prog1 - (concat (if prev ", " "") (int-to-string - (floor num)) - " " (symbol-name (car unit)) - (if (> num 1) "s" "")) - (setq prev t)))) - article-time-units "") - ;; If dates are odd, then it might appear like the - ;; article was sent in the future. - (if (> real-sec 0) - " ago" - " in the future")))))) - (t - (error "Unknown conversion type: %s" type)))) - -(defun article-date-local (&optional highlight) - "Convert the current article date to the local timezone." - (interactive (list t)) - (article-date-ut 'local highlight)) - -(defun article-date-original (&optional highlight) - "Convert the current article date to what it was originally. -This is only useful if you have used some other date conversion -function and want to see what the date was before converting." - (interactive (list t)) - (article-date-ut 'original highlight)) - -(defun article-date-lapsed (&optional highlight) - "Convert the current article date to time lapsed since it was sent." - (interactive (list t)) - (article-date-ut 'lapsed highlight)) - -(defun article-update-date-lapsed () - "Function to be run from a timer to update the lapsed time line." - (let (deactivate-mark) - (save-excursion - (ignore-errors - (when (gnus-buffer-live-p gnus-article-buffer) - (set-buffer gnus-article-buffer) - (goto-char (point-min)) - (when (re-search-forward "^X-Sent:" nil t) - (article-date-lapsed t))))))) - -(defun gnus-start-date-timer (&optional n) - "Start a timer to update the X-Sent header in the article buffers. -The numerical prefix says how frequently (in seconds) the function -is to run." - (interactive "p") - (unless n - (setq n 1)) - (gnus-stop-date-timer) - (setq article-lapsed-timer - (nnheader-run-at-time 1 n 'article-update-date-lapsed))) - -(defun gnus-stop-date-timer () - "Stop the X-Sent timer." - (interactive) - (when article-lapsed-timer - (nnheader-cancel-timer article-lapsed-timer) - (setq article-lapsed-timer nil))) - -(defun article-date-user (&optional highlight) - "Convert the current article date to the user-defined format. -This format is defined by the `gnus-article-time-format' variable." - (interactive (list t)) - (article-date-ut 'user highlight)) - -(defun article-date-iso8601 (&optional highlight) - "Convert the current article date to ISO8601." - (interactive (list t)) - (article-date-ut 'iso8601 highlight)) - -(defun article-show-all () - "Show all hidden text in the article buffer." - (interactive) - (save-excursion - (let ((buffer-read-only nil)) - (gnus-article-unhide-text (point-min) (point-max))))) - -(defun article-emphasize (&optional arg) - "Emphasize text according to `gnus-emphasis-alist'." - (interactive (gnus-article-hidden-arg)) - (unless (gnus-article-check-hidden-text 'emphasis arg) - (save-excursion - (let ((alist gnus-emphasis-alist) - (buffer-read-only nil) - (props (append '(article-type emphasis) - gnus-hidden-properties)) - regexp elem beg invisible visible face) - (goto-char (point-min)) - (search-forward "\n\n" nil t) - (setq beg (point)) - (while (setq elem (pop alist)) - (goto-char beg) - (setq regexp (car elem) - invisible (nth 1 elem) - visible (nth 2 elem) - face (nth 3 elem)) - (while (re-search-forward regexp nil t) - (when (and (match-beginning visible) (match-beginning invisible)) - (gnus-article-hide-text - (match-beginning invisible) (match-end invisible) props) - (gnus-article-unhide-text-type - (match-beginning visible) (match-end visible) 'emphasis) - (gnus-put-text-property-excluding-newlines - (match-beginning visible) (match-end visible) 'face face) - (goto-char (match-end invisible))))))))) - -(defvar gnus-summary-article-menu) -(defvar gnus-summary-post-menu) - -;;; Saving functions. - -(defun gnus-article-save (save-buffer file &optional num) - "Save the currently selected article." - (unless gnus-save-all-headers - ;; Remove headers according to `gnus-saved-headers'. - (let ((gnus-visible-headers - (or gnus-saved-headers gnus-visible-headers)) - (gnus-article-buffer save-buffer)) - (save-excursion - (set-buffer save-buffer) - (article-hide-headers 1 t)))) - (save-window-excursion - (if (not gnus-default-article-saver) - (error "No default saver is defined") - ;; !!! Magic! The saving functions all save - ;; `gnus-original-article-buffer' (or so they think), but we - ;; bind that variable to our save-buffer. - (set-buffer gnus-article-buffer) - (let* ((gnus-save-article-buffer save-buffer) - (filename - (cond - ((not gnus-prompt-before-saving) 'default) - ((eq gnus-prompt-before-saving 'always) nil) - (t file))) - (gnus-number-of-articles-to-be-saved - (when (eq gnus-prompt-before-saving t) - num))) ; Magic - (set-buffer gnus-article-current-summary) - (funcall gnus-default-article-saver filename))))) - -(defun gnus-read-save-file-name (prompt &optional filename - function group headers variable) - (let ((default-name - (funcall function group headers (symbol-value variable))) - result) - (setq - result - (cond - ((eq filename 'default) - default-name) - ((eq filename t) - default-name) - (filename filename) - (t - (let* ((split-name (gnus-get-split-value gnus-split-methods)) - (prompt - (format prompt - (if (and gnus-number-of-articles-to-be-saved - (> gnus-number-of-articles-to-be-saved 1)) - (format "these %d articles" - gnus-number-of-articles-to-be-saved) - "this article"))) - (file - ;; Let the split methods have their say. - (cond - ;; No split name was found. - ((null split-name) - (read-file-name - (concat prompt " (default " - (file-name-nondirectory default-name) ") ") - (file-name-directory default-name) - default-name)) - ;; A single group name is returned. - ((stringp split-name) - (setq default-name - (funcall function split-name headers - (symbol-value variable))) - (read-file-name - (concat prompt " (default " - (file-name-nondirectory default-name) ") ") - (file-name-directory default-name) - default-name)) - ;; A single split name was found - ((= 1 (length split-name)) - (let* ((name (expand-file-name - (car split-name) gnus-article-save-directory)) - (dir (cond ((file-directory-p name) - (file-name-as-directory name)) - ((file-exists-p name) name) - (t gnus-article-save-directory)))) - (read-file-name - (concat prompt " (default " name ") ") - dir name))) - ;; A list of splits was found. - (t - (setq split-name (nreverse split-name)) - (let (result) - (let ((file-name-history - (nconc split-name file-name-history))) - (setq result - (expand-file-name - (read-file-name - (concat prompt " (`M-p' for defaults) ") - gnus-article-save-directory - (car split-name)) - gnus-article-save-directory))) - (car (push result file-name-history))))))) - ;; Create the directory. - (gnus-make-directory (file-name-directory file)) - ;; If we have read a directory, we append the default file name. - (when (file-directory-p file) - (setq file (concat (file-name-as-directory file) - (file-name-nondirectory default-name)))) - ;; Possibly translate some characters. - (nnheader-translate-file-chars file))))) - (gnus-make-directory (file-name-directory result)) - (set variable result))) - -(defun gnus-article-archive-name (group) - "Return the first instance of an \"Archive-name\" in the current buffer." - (let ((case-fold-search t)) - (when (re-search-forward "archive-name: *\\([^ \n\t]+\\)[ \t]*$" nil t) - (nnheader-concat gnus-article-save-directory - (match-string 1))))) - -(defun gnus-article-nndoc-name (group) - "If GROUP is an nndoc group, return the name of the parent group." - (when (eq (car (gnus-find-method-for-group group)) 'nndoc) - (gnus-group-get-parameter group 'save-article-group))) - -(defun gnus-summary-save-in-rmail (&optional filename) - "Append this article to Rmail file. -Optional argument FILENAME specifies file name. -Directory to save to is default to `gnus-article-save-directory'." - (setq filename (gnus-read-save-file-name - "Save %s in rmail file:" filename - gnus-rmail-save-name gnus-newsgroup-name - gnus-current-headers 'gnus-newsgroup-last-rmail)) - (gnus-eval-in-buffer-window gnus-save-article-buffer - (save-excursion - (save-restriction - (widen) - (gnus-output-to-rmail filename)))) - filename) - -(defun gnus-summary-save-in-mail (&optional filename) - "Append this article to Unix mail file. -Optional argument FILENAME specifies file name. -Directory to save to is default to `gnus-article-save-directory'." - (setq filename (gnus-read-save-file-name - "Save %s in Unix mail file:" filename - gnus-mail-save-name gnus-newsgroup-name - gnus-current-headers 'gnus-newsgroup-last-mail)) - (gnus-eval-in-buffer-window gnus-save-article-buffer - (save-excursion - (save-restriction - (widen) - (if (and (file-readable-p filename) - (mail-file-babyl-p filename)) - (gnus-output-to-rmail filename t) - (gnus-output-to-mail filename))))) - filename) - -(defun gnus-summary-save-in-file (&optional filename overwrite) - "Append this article to file. -Optional argument FILENAME specifies file name. -Directory to save to is default to `gnus-article-save-directory'." - (setq filename (gnus-read-save-file-name - "Save %s in file:" filename - gnus-file-save-name gnus-newsgroup-name - gnus-current-headers 'gnus-newsgroup-last-file)) - (gnus-eval-in-buffer-window gnus-save-article-buffer - (save-excursion - (save-restriction - (widen) - (when (and overwrite - (file-exists-p filename)) - (delete-file filename)) - (gnus-output-to-file filename)))) - filename) - -(defun gnus-summary-write-to-file (&optional filename) - "Write this article to a file. -Optional argument FILENAME specifies file name. -The directory to save in defaults to `gnus-article-save-directory'." - (gnus-summary-save-in-file nil t)) - -(defun gnus-summary-save-body-in-file (&optional filename) - "Append this article body to a file. -Optional argument FILENAME specifies file name. -The directory to save in defaults to `gnus-article-save-directory'." - (setq filename (gnus-read-save-file-name - "Save %s body in file:" filename - gnus-file-save-name gnus-newsgroup-name - gnus-current-headers 'gnus-newsgroup-last-file)) - (gnus-eval-in-buffer-window gnus-save-article-buffer - (save-excursion - (save-restriction - (widen) - (goto-char (point-min)) - (when (search-forward "\n\n" nil t) - (narrow-to-region (point) (point-max))) - (gnus-output-to-file filename)))) - filename) - -(defun gnus-summary-save-in-pipe (&optional command) - "Pipe this article to subprocess." - (setq command - (cond ((eq command 'default) - gnus-last-shell-command) - (command command) - (t (read-string - (format - "Shell command on %s: " - (if (and gnus-number-of-articles-to-be-saved - (> gnus-number-of-articles-to-be-saved 1)) - (format "these %d articles" - gnus-number-of-articles-to-be-saved) - "this article")) - gnus-last-shell-command)))) - (when (string-equal command "") - (setq command gnus-last-shell-command)) - (gnus-eval-in-buffer-window gnus-article-buffer - (save-restriction - (widen) - (shell-command-on-region (point-min) (point-max) command nil))) - (setq gnus-last-shell-command command)) - -;;; Article file names when saving. - -(defun gnus-capitalize-newsgroup (newsgroup) - "Capitalize NEWSGROUP name." - (when (not (zerop (length newsgroup))) - (concat (char-to-string (upcase (aref newsgroup 0))) - (substring newsgroup 1)))) - -(defun gnus-Numeric-save-name (newsgroup headers &optional last-file) - "Generate file name from NEWSGROUP, HEADERS, and optional LAST-FILE. -If variable `gnus-use-long-file-name' is non-nil, it is ~/News/News.group/num. -Otherwise, it is like ~/News/news/group/num." - (let ((default - (expand-file-name - (concat (if (gnus-use-long-file-name 'not-save) - (gnus-capitalize-newsgroup newsgroup) - (gnus-newsgroup-directory-form newsgroup)) - "/" (int-to-string (mail-header-number headers))) - gnus-article-save-directory))) - (if (and last-file - (string-equal (file-name-directory default) - (file-name-directory last-file)) - (string-match "^[0-9]+$" (file-name-nondirectory last-file))) - default - (or last-file default)))) - -(defun gnus-numeric-save-name (newsgroup headers &optional last-file) - "Generate file name from NEWSGROUP, HEADERS, and optional LAST-FILE. -If variable `gnus-use-long-file-name' is non-nil, it is -~/News/news.group/num. Otherwise, it is like ~/News/news/group/num." - (let ((default - (expand-file-name - (concat (if (gnus-use-long-file-name 'not-save) - newsgroup - (gnus-newsgroup-directory-form newsgroup)) - "/" (int-to-string (mail-header-number headers))) - gnus-article-save-directory))) - (if (and last-file - (string-equal (file-name-directory default) - (file-name-directory last-file)) - (string-match "^[0-9]+$" (file-name-nondirectory last-file))) - default - (or last-file default)))) - -(defun gnus-Plain-save-name (newsgroup headers &optional last-file) - "Generate file name from NEWSGROUP, HEADERS, and optional LAST-FILE. -If variable `gnus-use-long-file-name' is non-nil, it is -~/News/News.group. Otherwise, it is like ~/News/news/group/news." - (or last-file - (expand-file-name - (if (gnus-use-long-file-name 'not-save) - (gnus-capitalize-newsgroup newsgroup) - (concat (gnus-newsgroup-directory-form newsgroup) "/news")) - gnus-article-save-directory))) - -(defun gnus-plain-save-name (newsgroup headers &optional last-file) - "Generate file name from NEWSGROUP, HEADERS, and optional LAST-FILE. -If variable `gnus-use-long-file-name' is non-nil, it is -~/News/news.group. Otherwise, it is like ~/News/news/group/news." - (or last-file - (expand-file-name - (if (gnus-use-long-file-name 'not-save) - newsgroup - (concat (gnus-newsgroup-directory-form newsgroup) "/news")) - gnus-article-save-directory))) - -(eval-and-compile - (mapcar - (lambda (func) - (let (afunc gfunc) - (if (consp func) - (setq afunc (car func) - gfunc (cdr func)) - (setq afunc func - gfunc (intern (format "gnus-%s" func)))) - (fset gfunc - (if (not (fboundp afunc)) - nil - `(lambda (&optional interactive &rest args) - ,(documentation afunc t) - (interactive (list t)) - (save-excursion - (set-buffer gnus-article-buffer) - (if interactive - (call-interactively ',afunc) - (apply ',afunc args)))))))) - '(article-hide-headers - article-hide-boring-headers - article-treat-overstrike - (article-fill . gnus-article-word-wrap) - article-remove-cr - article-display-x-face - article-hide-pgp - article-hide-pem - article-hide-signature - article-remove-trailing-blank-lines - article-strip-leading-blank-lines - article-strip-multiple-blank-lines - article-strip-leading-space - article-strip-blank-lines - article-strip-all-blank-lines - article-date-local - article-date-iso8601 - article-date-original - article-date-ut - article-date-user - article-date-lapsed - article-emphasize - article-treat-dumbquotes - (article-show-all . gnus-article-show-all-headers)))) - -;;; -;;; Gnus article mode -;;; - -(put 'gnus-article-mode 'mode-class 'special) - -(gnus-define-keys gnus-article-mode-map - " " gnus-article-goto-next-page - "\177" gnus-article-goto-prev-page - [delete] gnus-article-goto-prev-page - "\C-c^" gnus-article-refer-article - "h" gnus-article-show-summary - "s" gnus-article-show-summary - "\C-c\C-m" gnus-article-mail - "?" gnus-article-describe-briefly - gnus-mouse-2 gnus-article-push-button - "\r" gnus-article-press-button - "\t" gnus-article-next-button - "\M-\t" gnus-article-prev-button - "e" gnus-article-edit - "<" beginning-of-buffer - ">" end-of-buffer - "\C-c\C-i" gnus-info-find-node - "\C-c\C-b" gnus-bug - - "\C-d" gnus-article-read-summary-keys - "\M-*" gnus-article-read-summary-keys - "\M-#" gnus-article-read-summary-keys - "\M-^" gnus-article-read-summary-keys - "\M-g" gnus-article-read-summary-keys) - -(substitute-key-definition - 'undefined 'gnus-article-read-summary-keys gnus-article-mode-map) - -(defun gnus-article-make-menu-bar () - (gnus-turn-off-edit-menu 'article) - (unless (boundp 'gnus-article-article-menu) - (easy-menu-define - gnus-article-article-menu gnus-article-mode-map "" - '("Article" - ["Scroll forwards" gnus-article-goto-next-page t] - ["Scroll backwards" gnus-article-goto-prev-page t] - ["Show summary" gnus-article-show-summary t] - ["Fetch Message-ID at point" gnus-article-refer-article t] - ["Mail to address at point" gnus-article-mail t] - ["Send a bug report" gnus-bug t])) - - (easy-menu-define - gnus-article-treatment-menu gnus-article-mode-map "" - '("Treatment" - ["Hide headers" gnus-article-hide-headers t] - ["Hide signature" gnus-article-hide-signature t] - ["Hide citation" gnus-article-hide-citation t] - ["Treat overstrike" gnus-article-treat-overstrike t] - ["Remove carriage return" gnus-article-remove-cr t] - )) - - ;; Note "Commands" menu is defined in gnus-sum.el for consistency - - (when (boundp 'gnus-summary-post-menu) - (define-key gnus-article-mode-map [menu-bar post] - (cons "Post" gnus-summary-post-menu))) - - (gnus-run-hooks 'gnus-article-menu-hook))) - -(defun gnus-article-mode () - "Major mode for displaying an article. - -All normal editing commands are switched off. - -The following commands are available in addition to all summary mode -commands: -\\ -\\[gnus-article-next-page]\t Scroll the article one page forwards -\\[gnus-article-prev-page]\t Scroll the article one page backwards -\\[gnus-article-refer-article]\t Go to the article referred to by an article id near point -\\[gnus-article-show-summary]\t Display the summary buffer -\\[gnus-article-mail]\t Send a reply to the address near point -\\[gnus-article-describe-briefly]\t Describe the current mode briefly -\\[gnus-info-find-node]\t Go to the Gnus info node" - (interactive) - (when (gnus-visual-p 'article-menu 'menu) - (gnus-article-make-menu-bar)) - (gnus-simplify-mode-line) - (setq mode-name "Article") - (setq major-mode 'gnus-article-mode) - (make-local-variable 'minor-mode-alist) - (unless (assq 'gnus-show-mime minor-mode-alist) - (push (list 'gnus-show-mime " MIME") minor-mode-alist)) - (use-local-map gnus-article-mode-map) - (gnus-update-format-specifications nil 'article-mode) - (set (make-local-variable 'page-delimiter) gnus-page-delimiter) - (make-local-variable 'gnus-page-broken) - (make-local-variable 'gnus-button-marker-list) - (make-local-variable 'gnus-article-current-summary) - (gnus-set-default-directory) - (buffer-disable-undo (current-buffer)) - (setq buffer-read-only t) - (set-syntax-table gnus-article-mode-syntax-table) - (gnus-run-hooks 'gnus-article-mode-hook)) - -(defun gnus-article-setup-buffer () - "Initialize the article buffer." - (let* ((name (if gnus-single-article-buffer "*Article*" - (concat "*Article " gnus-newsgroup-name "*"))) - (original - (progn (string-match "\\*Article" name) - (concat " *Original Article" - (substring name (match-end 0)))))) - (setq gnus-article-buffer name) - (setq gnus-original-article-buffer original) - ;; This might be a variable local to the summary buffer. - (unless gnus-single-article-buffer - (save-excursion - (set-buffer gnus-summary-buffer) - (setq gnus-article-buffer name) - (setq gnus-original-article-buffer original) - (gnus-set-global-variables))) - ;; Init original article buffer. - (save-excursion - (set-buffer (gnus-get-buffer-create gnus-original-article-buffer)) - (buffer-disable-undo (current-buffer)) - (setq major-mode 'gnus-original-article-mode) - (make-local-variable 'gnus-original-article)) - (if (get-buffer name) - (save-excursion - (set-buffer name) - (buffer-disable-undo (current-buffer)) - (setq buffer-read-only t) - (unless (eq major-mode 'gnus-article-mode) - (gnus-article-mode)) - (current-buffer)) - (save-excursion - (set-buffer (gnus-get-buffer-create name)) - (gnus-article-mode) - (make-local-variable 'gnus-summary-buffer) - (current-buffer))))) - -;; Set article window start at LINE, where LINE is the number of lines -;; from the head of the article. -(defun gnus-article-set-window-start (&optional line) - (set-window-start - (get-buffer-window gnus-article-buffer t) - (save-excursion - (set-buffer gnus-article-buffer) - (goto-char (point-min)) - (if (not line) - (point-min) - (gnus-message 6 "Moved to bookmark") - (search-forward "\n\n" nil t) - (forward-line line) - (point))))) - -;;; @@ article filters -;;; - -(defun gnus-article-display-mime-message () - "Article display method for MIME message." - ;; called from `gnus-original-article-buffer'. - (let ((default-mime-charset (save-excursion - (set-buffer gnus-summary-buffer) - default-mime-charset))) - (mime-display-message mime-message-structure - gnus-article-buffer nil gnus-article-mode-map)) - ;; `mime-display-message' changes current buffer to `gnus-article-buffer'. - (make-local-variable 'mime-button-mother-dispatcher) - (setq mime-button-mother-dispatcher - (function gnus-article-push-button)) - (run-hooks 'gnus-mime-article-prepare-hook)) - -(defun gnus-article-display-traditional-message () - "Article display method for traditional message." - (set-buffer gnus-article-buffer) - (let (buffer-read-only) - (erase-buffer) - (insert-buffer-substring gnus-original-article-buffer))) - -(defun gnus-article-display-message-with-encoded-word () - "Article display method for message with encoded-words." - (let ((charset (save-excursion - (set-buffer gnus-summary-buffer) - default-mime-charset))) - (gnus-article-display-traditional-message) - (let (buffer-read-only) - (eword-decode-header charset) - (goto-char (point-min)) - (if (search-forward "\n\n" nil t) - (decode-mime-charset-region (match-end 0) (point-max) charset))) - (mime-maybe-hide-echo-buffer)) - (gnus-run-hooks 'gnus-mime-article-prepare-hook)) - -(defun gnus-article-prepare (article &optional all-headers header) - "Prepare ARTICLE in article mode buffer. -ARTICLE should either be an article number or a Message-ID. -If ARTICLE is an id, HEADER should be the article headers. -If ALL-HEADERS is non-nil, no headers are hidden." - (save-excursion - ;; Make sure we start in a summary buffer. - (unless (eq major-mode 'gnus-summary-mode) - (set-buffer gnus-summary-buffer)) - (setq gnus-summary-buffer (current-buffer)) - (let* ((gnus-article (if header (mail-header-number header) article)) - (summary-buffer (current-buffer)) - (gnus-tmp-internal-hook gnus-article-internal-prepare-hook) - (group gnus-newsgroup-name) - result) - (save-excursion - (gnus-article-setup-buffer) - (set-buffer gnus-original-article-buffer) - ;; Deactivate active regions. - (when (and (boundp 'transient-mark-mode) - transient-mark-mode) - (setq mark-active nil)) - (if (not (setq result (let ((buffer-read-only nil)) - (gnus-request-article-this-buffer - article group)))) - ;; There is no such article. - (save-excursion - (when (and (numberp article) - (not (memq article gnus-newsgroup-sparse))) - (setq gnus-article-current - (cons gnus-newsgroup-name article)) - (set-buffer gnus-summary-buffer) - (setq gnus-current-article article) - (if (eq (gnus-article-mark article) gnus-undownloaded-mark) - (progn - (gnus-summary-set-agent-mark article) - (message "Message marked for downloading")) - (gnus-summary-mark-article article gnus-canceled-mark) - (unless (memq article gnus-newsgroup-sparse) - (gnus-error 1 - "No such article (may have expired or been canceled)"))))) - (if (or (eq result 'pseudo) - (eq result 'nneething)) - (progn - (save-excursion - (set-buffer summary-buffer) - (push article gnus-newsgroup-history) - (setq gnus-last-article gnus-current-article - gnus-current-article 0 - gnus-current-headers nil - gnus-article-current nil) - (if (eq result 'nneething) - (gnus-configure-windows 'summary) - (gnus-configure-windows 'article)) - (gnus-set-global-variables)) - (gnus-set-mode-line 'article)) - ;; The result from the `request' was an actual article - - ;; or at least some text that is now displayed in the - ;; article buffer. - (when (and (numberp article) - (not (eq article gnus-current-article))) - ;; Seems like a new article has been selected. - ;; `gnus-current-article' must be an article number. - (save-excursion - (set-buffer summary-buffer) - (push article gnus-newsgroup-history) - (setq gnus-last-article gnus-current-article - gnus-current-article article - gnus-current-headers - (gnus-summary-article-header gnus-current-article) - gnus-article-current - (cons gnus-newsgroup-name gnus-current-article)) - (unless (vectorp gnus-current-headers) - (setq gnus-current-headers nil)) - (gnus-summary-goto-subject gnus-current-article) - (when (gnus-summary-show-thread) - ;; If the summary buffer really was folded, the - ;; previous goto may not actually have gone to - ;; the right article, but the thread root instead. - ;; So we go again. - (gnus-summary-goto-subject gnus-current-article)) - (gnus-run-hooks 'gnus-mark-article-hook) - (gnus-set-mode-line 'summary) - (when (gnus-visual-p 'article-highlight 'highlight) - (gnus-run-hooks 'gnus-visual-mark-article-hook)) - ;; Set the global newsgroup variables here. - ;; Suggested by Jim Sisolak - ;; . - (gnus-set-global-variables) - (setq gnus-have-all-headers - (or all-headers gnus-show-all-headers)))) - (when (or (numberp article) - (stringp article)) - ;; Hooks for getting information from the article. - ;; This hook must be called before being narrowed. - (let ((method - (if gnus-show-mime - (progn - (setq mime-message-structure gnus-current-headers) - (mime-entity-set-buffer-internal - mime-message-structure (current-buffer)) - (if (or (not gnus-strict-mime) - (mime-fetch-field "MIME-Version")) - gnus-article-display-method-for-mime - gnus-article-display-method-for-encoded-word)) - gnus-article-display-method-for-traditional))) - (gnus-run-hooks 'gnus-tmp-internal-hook) - (gnus-run-hooks 'gnus-article-prepare-hook) - ;; Display message. - (funcall method) - ;; Associate this article with the current summary buffer. - (setq gnus-article-current-summary summary-buffer) - ;; Perform the article display hooks. - (gnus-run-hooks 'gnus-article-display-hook)) - ;; Do page break. - (goto-char (point-min)) - (setq gnus-page-broken - (when gnus-break-pages - (gnus-narrow-to-page) - t))) - (gnus-set-mode-line 'article) - (gnus-configure-windows 'article) - (goto-char (point-min)) - (search-forward "\n\n" nil t) - (set-window-point (get-buffer-window (current-buffer)) (point)) - t)))))) - -(defun gnus-article-wash-status () - "Return a string which display status of article washing." - (save-excursion - (set-buffer gnus-article-buffer) - (let ((cite (gnus-article-hidden-text-p 'cite)) - (headers (gnus-article-hidden-text-p 'headers)) - (boring (gnus-article-hidden-text-p 'boring-headers)) - (pgp (gnus-article-hidden-text-p 'pgp)) - (pem (gnus-article-hidden-text-p 'pem)) - (signature (gnus-article-hidden-text-p 'signature)) - (overstrike (gnus-article-hidden-text-p 'overstrike)) - (emphasis (gnus-article-hidden-text-p 'emphasis)) - (mime gnus-show-mime)) - (format "%c%c%c%c%c%c%c" - (if cite ?c ? ) - (if (or headers boring) ?h ? ) - (if (or pgp pem) ?p ? ) - (if signature ?s ? ) - (if overstrike ?o ? ) - (if mime ?m ? ) - (if emphasis ?e ? ))))) - -(fset 'gnus-article-hide-headers-if-wanted 'gnus-article-maybe-hide-headers) - -(defun gnus-article-maybe-hide-headers () - "Hide unwanted headers if `gnus-have-all-headers' is nil. -Provided for backwards compatibility." - (or (save-excursion (set-buffer gnus-summary-buffer) gnus-have-all-headers) - gnus-inhibit-hiding - (gnus-article-hide-headers))) - -;;; Article savers. - -(defun gnus-output-to-file (file-name) - "Append the current article to a file named FILE-NAME." - (let ((artbuf (current-buffer))) - (nnheader-temp-write nil - (insert-buffer-substring artbuf) - ;; Append newline at end of the buffer as separator, and then - ;; save it to file. - (goto-char (point-max)) - (insert "\n") - (append-to-file (point-min) (point-max) file-name) - t))) - -(defun gnus-narrow-to-page (&optional arg) - "Narrow the article buffer to a page. -If given a numerical ARG, move forward ARG pages." - (interactive "P") - (setq arg (if arg (prefix-numeric-value arg) 0)) - (save-excursion - (set-buffer gnus-article-buffer) - (goto-char (point-min)) - (widen) - ;; Remove any old next/prev buttons. - (when (gnus-visual-p 'page-marker) - (let ((buffer-read-only nil)) - (gnus-remove-text-with-property 'gnus-prev) - (gnus-remove-text-with-property 'gnus-next))) - (when - (cond ((< arg 0) - (re-search-backward page-delimiter nil 'move (1+ (abs arg)))) - ((> arg 0) - (re-search-forward page-delimiter nil 'move arg))) - (goto-char (match-end 0))) - (narrow-to-region - (point) - (if (re-search-forward page-delimiter nil 'move) - (match-beginning 0) - (point))) - (when (and (gnus-visual-p 'page-marker) - (not (= (point-min) 1))) - (save-excursion - (goto-char (point-min)) - (gnus-insert-prev-page-button))) - (when (and (gnus-visual-p 'page-marker) - (< (+ (point-max) 2) (buffer-size))) - (save-excursion - (goto-char (point-max)) - (gnus-insert-next-page-button))))) - -;; Article mode commands - -(defun gnus-article-goto-next-page () - "Show the next page of the article." - (interactive) - (when (gnus-article-next-page) - (goto-char (point-min)) - (gnus-article-read-summary-keys nil (gnus-character-to-event ?n)))) - -(defun gnus-article-goto-prev-page () - "Show the next page of the article." - (interactive) - (if (bobp) (gnus-article-read-summary-keys nil (gnus-character-to-event ?p)) - (gnus-article-prev-page nil))) - -(defun gnus-article-next-page (&optional lines) - "Show the next page of the current article. -If end of article, return non-nil. Otherwise return nil. -Argument LINES specifies lines to be scrolled up." - (interactive "p") - (move-to-window-line -1) - (if (save-excursion - (end-of-line) - (and (pos-visible-in-window-p) ;Not continuation line. - (eobp))) - ;; Nothing in this page. - (if (or (not gnus-page-broken) - (save-excursion - (save-restriction - (widen) (forward-line 1) (eobp)))) ;Real end-of-buffer? - t ;Nothing more. - (gnus-narrow-to-page 1) ;Go to next page. - nil) - ;; More in this page. - (let ((scroll-in-place nil)) - (condition-case () - (scroll-up lines) - (end-of-buffer - ;; Long lines may cause an end-of-buffer error. - (goto-char (point-max))))) - (move-to-window-line 0) - nil)) - -(defun gnus-article-prev-page (&optional lines) - "Show previous page of current article. -Argument LINES specifies lines to be scrolled down." - (interactive "p") - (move-to-window-line 0) - (if (and gnus-page-broken - (bobp) - (not (save-restriction (widen) (bobp)))) ;Real beginning-of-buffer? - (progn - (gnus-narrow-to-page -1) ;Go to previous page. - (goto-char (point-max)) - (recenter -1)) - (let ((scroll-in-place nil)) - (prog1 - (condition-case () - (scroll-down lines) - (beginning-of-buffer - (goto-char (point-min)))) - (move-to-window-line 0))))) - -(defun gnus-article-refer-article () - "Read article specified by message-id around point." - (interactive) - (let ((point (point))) - (search-forward ">" nil t) ;Move point to end of "<....>". - (if (re-search-backward "\\(<[^<> \t\n]+>\\)" nil t) - (let ((message-id (match-string 1))) - (goto-char point) - (set-buffer gnus-summary-buffer) - (gnus-summary-refer-article message-id)) - (goto-char (point)) - (error "No references around point")))) - -(defun gnus-article-show-summary () - "Reconfigure windows to show summary buffer." - (interactive) - (if (not (gnus-buffer-live-p gnus-summary-buffer)) - (error "There is no summary buffer for this article buffer") - (gnus-article-set-globals) - (gnus-configure-windows 'article) - (gnus-summary-goto-subject gnus-current-article) - (gnus-summary-position-point))) - -(defun gnus-article-describe-briefly () - "Describe article mode commands briefly." - (interactive) - (gnus-message 6 - (substitute-command-keys "\\\\[gnus-article-goto-next-page]:Next page \\[gnus-article-goto-prev-page]:Prev page \\[gnus-article-show-summary]:Show summary \\[gnus-info-find-node]:Run Info \\[gnus-article-describe-briefly]:This help"))) - -(defun gnus-article-summary-command () - "Execute the last keystroke in the summary buffer." - (interactive) - (let ((obuf (current-buffer)) - (owin (current-window-configuration)) - func) - (switch-to-buffer gnus-article-current-summary 'norecord) - (setq func (lookup-key (current-local-map) (this-command-keys))) - (call-interactively func) - (set-buffer obuf) - (set-window-configuration owin) - (set-window-point (get-buffer-window (current-buffer)) (point)))) - -(defun gnus-article-summary-command-nosave () - "Execute the last keystroke in the summary buffer." - (interactive) - (let (func) - (pop-to-buffer gnus-article-current-summary 'norecord) - (setq func (lookup-key (current-local-map) (this-command-keys))) - (call-interactively func))) - -(defun gnus-article-read-summary-keys (&optional arg key not-restore-window) - "Read a summary buffer key sequence and execute it from the article buffer." - (interactive "P") - (let ((nosaves - '("q" "Q" "c" "r" "R" "\C-c\C-f" "m" "a" "f" "F" - "Zc" "ZC" "ZE" "ZQ" "ZZ" "Zn" "ZR" "ZG" "ZN" "ZP" - "=" "^" "\M-^" "|")) - (nosave-but-article - '("A\r")) - (nosave-in-article - '("\C-d")) - (up-to-top - '("n" "Gn" "p" "Gp")) - keys new-sum-point) - (save-excursion - (set-buffer gnus-article-current-summary) - (let (gnus-pick-mode) - (push (or key last-command-event) unread-command-events) - (setq keys (read-key-sequence nil)))) - (message "") - - (if (or (member keys nosaves) - (member keys nosave-but-article) - (member keys nosave-in-article)) - (let (func) - (save-window-excursion - (pop-to-buffer gnus-article-current-summary 'norecord) - ;; We disable the pick minor mode commands. - (let (gnus-pick-mode) - (setq func (lookup-key (current-local-map) keys)))) - (if (not func) - (ding) - (unless (member keys nosave-in-article) - (set-buffer gnus-article-current-summary)) - (call-interactively func) - (setq new-sum-point (point))) - (when (member keys nosave-but-article) - (pop-to-buffer gnus-article-buffer 'norecord))) - ;; These commands should restore window configuration. - (let ((obuf (current-buffer)) - (owin (current-window-configuration)) - (opoint (point)) - (summary gnus-article-current-summary) - func in-buffer selected) - (if not-restore-window - (pop-to-buffer summary 'norecord) - (switch-to-buffer summary 'norecord)) - (setq in-buffer (current-buffer)) - ;; We disable the pick minor mode commands. - (if (setq func (let (gnus-pick-mode) - (lookup-key (current-local-map) keys))) - (progn - (call-interactively func) - (setq new-sum-point (point))) - (ding)) - (when (eq in-buffer (current-buffer)) - (setq selected (gnus-summary-select-article)) - (set-buffer obuf) - (unless not-restore-window - (set-window-configuration owin)) - (unless (or (not (eq selected 'old)) (member keys up-to-top)) - (set-window-point (get-buffer-window (current-buffer)) - opoint)) - (let ((win (get-buffer-window gnus-article-current-summary))) - (when win - (set-window-point win new-sum-point)))))))) - -(defun gnus-article-hide (&optional arg force) - "Hide all the gruft in the current article. -This means that PGP stuff, signatures, cited text and (some) -headers will be hidden. -If given a prefix, show the hidden text instead." - (interactive (append (gnus-article-hidden-arg) (list 'force))) - (gnus-article-hide-headers arg) - (gnus-article-hide-pgp arg) - (gnus-article-hide-citation-maybe arg force) - (gnus-article-hide-signature arg)) - -(defun gnus-article-maybe-highlight () - "Do some article highlighting if article highlighting is requested." - (when (gnus-visual-p 'article-highlight 'highlight) - (gnus-article-highlight-some))) - -(defun gnus-check-group-server () - ;; Make sure the connection to the server is alive. - (unless (gnus-server-opened - (gnus-find-method-for-group gnus-newsgroup-name)) - (gnus-check-server (gnus-find-method-for-group gnus-newsgroup-name)) - (gnus-request-group gnus-newsgroup-name t))) - -(defun gnus-request-article-this-buffer (article group) - "Get an article and insert it into this buffer." - (let (do-update-line sparse-header) - (prog1 - (save-excursion - (erase-buffer) - (gnus-kill-all-overlays) - (setq group (or group gnus-newsgroup-name)) - - ;; Using `gnus-request-article' directly will insert the article into - ;; `nntp-server-buffer' - so we'll save some time by not having to - ;; copy it from the server buffer into the article buffer. - - ;; We only request an article by message-id when we do not have the - ;; headers for it, so we'll have to get those. - (when (stringp article) - (let ((gnus-override-method gnus-refer-article-method)) - (gnus-read-header article))) - - ;; If the article number is negative, that means that this article - ;; doesn't belong in this newsgroup (possibly), so we find its - ;; message-id and request it by id instead of number. - (when (and (numberp article) - gnus-summary-buffer - (get-buffer gnus-summary-buffer) - (gnus-buffer-exists-p gnus-summary-buffer)) - (save-excursion - (set-buffer gnus-summary-buffer) - (let ((header (gnus-summary-article-header article))) - (when (< article 0) - (cond - ((memq article gnus-newsgroup-sparse) - ;; This is a sparse gap article. - (setq do-update-line article) - (setq article (mail-header-id header)) - (let ((gnus-override-method gnus-refer-article-method)) - (setq sparse-header (gnus-read-header article))) - (setq gnus-newsgroup-sparse - (delq article gnus-newsgroup-sparse))) - ((vectorp header) - ;; It's a real article. - (setq article (mail-header-id header))) - (t - ;; It is an extracted pseudo-article. - (setq article 'pseudo) - (gnus-request-pseudo-article header)))) - - (let ((method (gnus-find-method-for-group - gnus-newsgroup-name))) - (when (and (eq (car method) 'nneething) - (vectorp header)) - (let ((dir (concat - (file-name-as-directory - (or (cadr (assq 'nneething-address method)) - (nth 1 method))) - (mail-header-subject header)))) - (when (file-directory-p dir) - (setq article 'nneething) - (gnus-group-enter-directory dir)))))))) - - (cond - ;; Refuse to select canceled articles. - ((and (numberp article) - gnus-summary-buffer - (get-buffer gnus-summary-buffer) - (gnus-buffer-exists-p gnus-summary-buffer) - (eq (cdr (save-excursion - (set-buffer gnus-summary-buffer) - (assq article gnus-newsgroup-reads))) - gnus-canceled-mark)) - nil) - ;; Check the backlog. - ((and gnus-keep-backlog - (gnus-backlog-request-article group article (current-buffer))) - 'article) - ;; Check asynchronous pre-fetch. - ((gnus-async-request-fetched-article group article (current-buffer)) - (gnus-async-prefetch-next group article gnus-summary-buffer) - (when (and (numberp article) gnus-keep-backlog) - (gnus-backlog-enter-article group article (current-buffer))) - 'article) - ;; Check the cache. - ((and gnus-use-cache - (numberp article) - (gnus-cache-request-article article group)) - 'article) - ;; Get the article and put into the article buffer. - ((or (stringp article) (numberp article)) - (let ((gnus-override-method - (and (stringp article) gnus-refer-article-method)) - (buffer-read-only nil)) - (erase-buffer) - (gnus-kill-all-overlays) - (gnus-check-group-server) - (when (gnus-request-article article group (current-buffer)) - (when (numberp article) - (gnus-async-prefetch-next group article gnus-summary-buffer) - (when gnus-keep-backlog - (gnus-backlog-enter-article - group article (current-buffer)))) - 'article))) - ;; It was a pseudo. - (t article))) - - ;; Associate this article with the current summary buffer. - (setq gnus-article-current-summary gnus-summary-buffer) - - ;; Take the article from the original article buffer - ;; and place it in the buffer it's supposed to be in. - (when (and (get-buffer gnus-article-buffer) - (equal (buffer-name (current-buffer)) - (buffer-name (get-buffer gnus-article-buffer)))) - (save-excursion - (if (get-buffer gnus-original-article-buffer) - (set-buffer gnus-original-article-buffer) - (set-buffer (gnus-get-buffer-create gnus-original-article-buffer)) - (buffer-disable-undo (current-buffer)) - (setq major-mode 'gnus-original-article-mode) - (setq buffer-read-only t)) - (let (buffer-read-only) - (erase-buffer) - (insert-buffer-substring gnus-article-buffer)) - (setq gnus-original-article (cons group article)))) - - ;; Update sparse articles. - (when (and do-update-line - (or (numberp article) - (stringp article))) - (let ((buf (current-buffer))) - (set-buffer gnus-summary-buffer) - (gnus-summary-update-article do-update-line sparse-header) - (gnus-summary-goto-subject do-update-line nil t) - (set-window-point (get-buffer-window (current-buffer) t) - (point)) - (set-buffer buf)))))) - -;;; -;;; Article editing -;;; - -(defcustom gnus-article-edit-mode-hook nil - "Hook run in article edit mode buffers." - :group 'gnus-article-various - :type 'hook) - -(defvar gnus-article-edit-done-function nil) - -(defvar gnus-article-edit-mode-map nil) - -(unless gnus-article-edit-mode-map - (setq gnus-article-edit-mode-map (copy-keymap text-mode-map)) - - (gnus-define-keys gnus-article-edit-mode-map - "\C-c\C-c" gnus-article-edit-done - "\C-c\C-k" gnus-article-edit-exit) - - (gnus-define-keys (gnus-article-edit-wash-map - "\C-c\C-w" gnus-article-edit-mode-map) - "f" gnus-article-edit-full-stops)) - -(defun gnus-article-edit-mode () - "Major mode for editing articles. -This is an extended text-mode. - -\\{gnus-article-edit-mode-map}" - (interactive) - (setq major-mode 'gnus-article-edit-mode) - (setq mode-name "Article Edit") - (use-local-map gnus-article-edit-mode-map) - (make-local-variable 'gnus-article-edit-done-function) - (make-local-variable 'gnus-prev-winconf) - (setq buffer-read-only nil) - (buffer-enable-undo) - (widen) - (gnus-run-hooks 'text-mode-hook 'gnus-article-edit-mode-hook)) - -(defun gnus-article-edit (&optional force) - "Edit the current article. -This will have permanent effect only in mail groups. -If FORCE is non-nil, allow editing of articles even in read-only -groups." - (interactive "P") - (when (and (not force) - (gnus-group-read-only-p)) - (error "The current newsgroup does not support article editing")) - (gnus-article-date-original) - (gnus-article-edit-article - `(lambda (no-highlight) - (gnus-summary-edit-article-done - ,(or (mail-header-references gnus-current-headers) "") - ,(gnus-group-read-only-p) ,gnus-summary-buffer no-highlight)))) - -(defun gnus-article-edit-article (exit-func) - "Start editing the contents of the current article buffer." - (let ((winconf (current-window-configuration))) - (set-buffer gnus-article-buffer) - (gnus-article-edit-mode) - (gnus-article-delete-text-of-type 'annotation) - (gnus-set-text-properties (point-min) (point-max) nil) - (gnus-configure-windows 'edit-article) - (setq gnus-article-edit-done-function exit-func) - (setq gnus-prev-winconf winconf) - (gnus-message 6 "C-c C-c to end edits"))) - -(defun gnus-article-edit-done (&optional arg) - "Update the article edits and exit." - (interactive "P") - (save-excursion - (save-restriction - (widen) - (goto-char (point-min)) - (when (search-forward "\n\n" nil 1) - (let ((lines (count-lines (point) (point-max))) - (length (- (point-max) (point))) - (case-fold-search t) - (body (copy-marker (point)))) - (goto-char (point-min)) - (when (re-search-forward "^content-length:[ \t]\\([0-9]+\\)" body t) - (delete-region (match-beginning 1) (match-end 1)) - (insert (number-to-string length))) - (goto-char (point-min)) - (when (re-search-forward - "^x-content-length:[ \t]\\([0-9]+\\)" body t) - (delete-region (match-beginning 1) (match-end 1)) - (insert (number-to-string length))) - (goto-char (point-min)) - (when (re-search-forward "^lines:[ \t]\\([0-9]+\\)" body t) - (delete-region (match-beginning 1) (match-end 1)) - (insert (number-to-string lines))))))) - (let ((func gnus-article-edit-done-function) - (buf (current-buffer)) - (start (window-start))) - (gnus-article-edit-exit) - (save-excursion - (set-buffer buf) - (let ((buffer-read-only nil)) - (funcall func arg))) - (set-buffer buf) - (set-window-start (get-buffer-window buf) start) - (set-window-point (get-buffer-window buf) (point)))) - -(defun gnus-article-edit-exit () - "Exit the article editing without updating." - (interactive) - ;; We remove all text props from the article buffer. - (let ((buf (format "%s" (buffer-string))) - (curbuf (current-buffer)) - (p (point)) - (window-start (window-start))) - (erase-buffer) - (insert buf) - (let ((winconf gnus-prev-winconf)) - (gnus-article-mode) - ;; The cache and backlog have to be flushed somewhat. - (when gnus-use-cache - (gnus-cache-update-article - (car gnus-article-current) (cdr gnus-article-current))) - (when gnus-keep-backlog - (gnus-backlog-remove-article - (car gnus-article-current) (cdr gnus-article-current))) - ;; Flush original article as well. - (save-excursion - (when (get-buffer gnus-original-article-buffer) - (set-buffer gnus-original-article-buffer) - (setq gnus-original-article nil))) - (set-window-configuration winconf) - ;; Tippy-toe some to make sure that point remains where it was. - (let ((buf (current-buffer))) - (set-buffer curbuf) - (set-window-start (get-buffer-window (current-buffer)) window-start) - (goto-char p) - (set-buffer buf))))) - -(defun gnus-article-edit-full-stops () - "Interactively repair spacing at end of sentences." - (interactive) - (save-excursion - (goto-char (point-min)) - (search-forward-regexp "^$" nil t) - (let ((case-fold-search nil)) - (query-replace-regexp "\\([.!?][])}]* \\)\\([[({A-Z]\\)" "\\1 \\2")))) - -;;; -;;; Article highlights -;;; - -;; Written by Per Abrahamsen . - -;;; Internal Variables: - -(defcustom gnus-button-url-regexp "\\b\\(s?https?\\|ftp\\|file\\|gopher\\|news\\|telnet\\|wais\\|mailto\\):\\(//[-a-zA-Z0-9_.]+:[0-9]*\\)?\\([-a-zA-Z0-9_=!?#$@~`%&*+|\\/:;.,]\\|\\w\\)+\\([-a-zA-Z0-9_=#$@~`%&*+|\\/]\\|\\w\\)" - "Regular expression that matches URLs." - :group 'gnus-article-buttons - :type 'regexp) - -(defcustom gnus-button-alist - `(("<\\(url:[>\n\t ]*?\\)?news:[>\n\t ]*\\([^>\n\t ]*@[^>\n\t ]*\\)>" 0 t - gnus-button-message-id 2) - ("\\bnews:\\([^>\n\t ]*@[^>\n\t ]*\\)" 0 t gnus-button-message-id 1) - ("\\(\\b<\\(url:[>\n\t ]*\\)?news:[>\n\t ]*\\(//\\)?\\([^>\n\t ]*\\)>\\)" - 1 t - gnus-button-fetch-group 4) - ("\\bnews:\\(//\\)?\\([^'\">\n\t ]+\\)" 0 t gnus-button-fetch-group 2) - ("\\bin\\( +article\\| +message\\)? +\\(<\\([^\n @<>]+@[^\n @<>]+\\)>\\)" 2 - t gnus-button-message-id 3) - ("\\( \n\t]+\\)>" 0 t gnus-url-mailto 2) - ("mailto:\\([a-zA-Z.-@_+0-9%]+\\)" 0 t gnus-url-mailto 1) - ("\\bmailto:\\([^ \n\t]+\\)" 0 t gnus-url-mailto 1) - ;; This is how URLs _should_ be embedded in text... - ("]*\\)>" 0 t gnus-button-embedded-url 1) - ;; Raw URLs. - (,gnus-button-url-regexp 0 t gnus-button-url 0)) - "*Alist of regexps matching buttons in article bodies. - -Each entry has the form (REGEXP BUTTON FORM CALLBACK PAR...), where -REGEXP: is the string matching text around the button, -BUTTON: is the number of the regexp grouping actually matching the button, -FORM: is a lisp expression which must eval to true for the button to -be added, -CALLBACK: is the function to call when the user push this button, and each -PAR: is a number of a regexp grouping whose text will be passed to CALLBACK. - -CALLBACK can also be a variable, in that case the value of that -variable it the real callback function." - :group 'gnus-article-buttons - :type '(repeat (list regexp - (integer :tag "Button") - (sexp :tag "Form") - (function :tag "Callback") - (repeat :tag "Par" - :inline t - (integer :tag "Regexp group"))))) - -(defcustom gnus-header-button-alist - `(("^\\(References\\|Message-I[Dd]\\):" "<[^>]+>" - 0 t gnus-button-message-id 0) - ("^\\(From\\|Reply-To\\):" ": *\\(.+\\)$" 1 t gnus-button-reply 1) - ("^\\(Cc\\|To\\):" "[^ \t\n<>,()\"]+@[^ \t\n<>,()\"]+" - 0 t gnus-button-mailto 0) - ("^X-[Uu][Rr][Ll]:" ,gnus-button-url-regexp 0 t gnus-button-url 0) - ("^Subject:" ,gnus-button-url-regexp 0 t gnus-button-url 0) - ("^[^:]+:" ,gnus-button-url-regexp 0 t gnus-button-url 0) - ("^[^:]+:" "\\(<\\(url: \\)?news:\\([^>\n ]*\\)>\\)" 1 t - gnus-button-message-id 3)) - "*Alist of headers and regexps to match buttons in article heads. - -This alist is very similar to `gnus-button-alist', except that each -alist has an additional HEADER element first in each entry: - -\(HEADER REGEXP BUTTON FORM CALLBACK PAR) - -HEADER is a regexp to match a header. For a fuller explanation, see -`gnus-button-alist'." - :group 'gnus-article-buttons - :group 'gnus-article-headers - :type '(repeat (list (regexp :tag "Header") - regexp - (integer :tag "Button") - (sexp :tag "Form") - (function :tag "Callback") - (repeat :tag "Par" - :inline t - (integer :tag "Regexp group"))))) - -(defvar gnus-button-regexp nil) -(defvar gnus-button-marker-list nil) -;; Regexp matching any of the regexps from `gnus-button-alist'. - -(defvar gnus-button-last nil) -;; The value of `gnus-button-alist' when `gnus-button-regexp' was build. - -;;; Commands: - -(defun gnus-article-push-button (event) - "Check text under the mouse pointer for a callback function. -If the text under the mouse pointer has a `gnus-callback' property, -call it with the value of the `gnus-data' text property." - (interactive "e") - (set-buffer (window-buffer (posn-window (event-start event)))) - (let* ((pos (posn-point (event-start event))) - (data (get-text-property pos 'gnus-data)) - (fun (get-text-property pos 'gnus-callback))) - (goto-char pos) - (when fun - (funcall fun data)))) - -(defun gnus-article-press-button () - "Check text at point for a callback function. -If the text at point has a `gnus-callback' property, -call it with the value of the `gnus-data' text property." - (interactive) - (let* ((data (get-text-property (point) 'gnus-data)) - (fun (get-text-property (point) 'gnus-callback))) - (when fun - (funcall fun data)))) - -(defun gnus-article-prev-button (n) - "Move point to N buttons backward. -If N is negative, move forward instead." - (interactive "p") - (gnus-article-next-button (- n))) - -(defun gnus-article-next-button (n) - "Move point to N buttons forward. -If N is negative, move backward instead." - (interactive "p") - (let ((function (if (< n 0) 'previous-single-property-change - 'next-single-property-change)) - (inhibit-point-motion-hooks t) - (backward (< n 0)) - (limit (if (< n 0) (point-min) (point-max)))) - (setq n (abs n)) - (while (and (not (= limit (point))) - (> n 0)) - ;; Skip past the current button. - (when (get-text-property (point) 'gnus-callback) - (goto-char (funcall function (point) 'gnus-callback nil limit))) - ;; Go to the next (or previous) button. - (gnus-goto-char (funcall function (point) 'gnus-callback nil limit)) - ;; Put point at the start of the button. - (when (and backward (not (get-text-property (point) 'gnus-callback))) - (goto-char (funcall function (point) 'gnus-callback nil limit))) - ;; Skip past intangible buttons. - (when (get-text-property (point) 'intangible) - (incf n)) - (decf n)) - (unless (zerop n) - (gnus-message 5 "No more buttons")) - n)) - -(defun gnus-article-highlight (&optional force) - "Highlight current article. -This function calls `gnus-article-highlight-headers', -`gnus-article-highlight-citation', -`gnus-article-highlight-signature', and `gnus-article-add-buttons' to -do the highlighting. See the documentation for those functions." - (interactive (list 'force)) - (gnus-article-highlight-headers) - (gnus-article-highlight-citation force) - (gnus-article-highlight-signature) - (gnus-article-add-buttons force) - (gnus-article-add-buttons-to-head)) - -(defun gnus-article-highlight-some (&optional force) - "Highlight current article. -This function calls `gnus-article-highlight-headers', -`gnus-article-highlight-signature', and `gnus-article-add-buttons' to -do the highlighting. See the documentation for those functions." - (interactive (list 'force)) - (gnus-article-highlight-headers) - (gnus-article-highlight-signature) - (gnus-article-add-buttons)) - -(defun gnus-article-highlight-headers () - "Highlight article headers as specified by `gnus-header-face-alist'." - (interactive) - (save-excursion - (set-buffer gnus-article-buffer) - (save-restriction - (let ((alist gnus-header-face-alist) - (buffer-read-only nil) - (case-fold-search t) - (inhibit-point-motion-hooks t) - entry regexp header-face field-face from hpoints fpoints) - (message-narrow-to-head) - (while (setq entry (pop alist)) - (goto-char (point-min)) - (setq regexp (concat "^\\(" - (if (string-equal "" (nth 0 entry)) - "[^\t ]" - (nth 0 entry)) - "\\)") - header-face (nth 1 entry) - field-face (nth 2 entry)) - (while (and (re-search-forward regexp nil t) - (not (eobp))) - (beginning-of-line) - (setq from (point)) - (unless (search-forward ":" nil t) - (forward-char 1)) - (when (and header-face - (not (memq (point) hpoints))) - (push (point) hpoints) - (gnus-put-text-property from (point) 'face header-face)) - (when (and field-face - (not (memq (setq from (point)) fpoints))) - (push from fpoints) - (if (re-search-forward "^[^ \t]" nil t) - (forward-char -2) - (goto-char (point-max))) - (gnus-put-text-property from (point) 'face field-face)))))))) - -(defun gnus-article-highlight-signature () - "Highlight the signature in an article. -It does this by highlighting everything after -`gnus-signature-separator' using `gnus-signature-face'." - (interactive) - (save-excursion - (set-buffer gnus-article-buffer) - (let ((buffer-read-only nil) - (inhibit-point-motion-hooks t)) - (save-restriction - (when (and gnus-signature-face - (gnus-article-narrow-to-signature)) - (gnus-overlay-put (gnus-make-overlay (point-min) (point-max)) - 'face gnus-signature-face) - (widen) - (gnus-article-search-signature) - (let ((start (match-beginning 0)) - (end (set-marker (make-marker) (1+ (match-end 0))))) - (gnus-article-add-button start (1- end) 'gnus-signature-toggle - end))))))) - -(defun gnus-button-in-region-p (b e prop) - "Say whether PROP exists in the region." - (text-property-not-all b e prop nil)) - -(defun gnus-article-add-buttons (&optional force) - "Find external references in the article and make buttons of them. -\"External references\" are things like Message-IDs and URLs, as -specified by `gnus-button-alist'." - (interactive (list 'force)) - (save-excursion - (set-buffer gnus-article-buffer) - (let ((buffer-read-only nil) - (inhibit-point-motion-hooks t) - (case-fold-search t) - (alist gnus-button-alist) - beg entry regexp) - ;; Remove all old markers. - (let (marker entry) - (while (setq marker (pop gnus-button-marker-list)) - (goto-char marker) - (when (setq entry (gnus-button-entry)) - (put-text-property (match-beginning (nth 1 entry)) - (match-end (nth 1 entry)) - 'gnus-callback nil)) - (set-marker marker nil))) - ;; We skip the headers. - (goto-char (point-min)) - (unless (search-forward "\n\n" nil t) - (goto-char (point-max))) - (setq beg (point)) - (while (setq entry (pop alist)) - (setq regexp (car entry)) - (goto-char beg) - (while (re-search-forward regexp nil t) - (let* ((start (and entry (match-beginning (nth 1 entry)))) - (end (and entry (match-end (nth 1 entry)))) - (from (match-beginning 0))) - (when (and (or (eq t (nth 2 entry)) - (eval (nth 2 entry))) - (not (gnus-button-in-region-p - start end 'gnus-callback))) - ;; That optional form returned non-nil, so we add the - ;; button. - (gnus-article-add-button - start end 'gnus-button-push - (car (push (set-marker (make-marker) from) - gnus-button-marker-list)))))))))) - -;; Add buttons to the head of an article. -(defun gnus-article-add-buttons-to-head () - "Add buttons to the head of the article." - (interactive) - (save-excursion - (set-buffer gnus-article-buffer) - (let ((buffer-read-only nil) - (inhibit-point-motion-hooks t) - (case-fold-search t) - (alist gnus-header-button-alist) - entry beg end) - (nnheader-narrow-to-headers) - (while alist - ;; Each alist entry. - (setq entry (car alist) - alist (cdr alist)) - (goto-char (point-min)) - (while (re-search-forward (car entry) nil t) - ;; Each header matching the entry. - (setq beg (match-beginning 0)) - (setq end (or (and (re-search-forward "^[^ \t]" nil t) - (match-beginning 0)) - (point-max))) - (goto-char beg) - (while (re-search-forward (nth 1 entry) end t) - ;; Each match within a header. - (let* ((entry (cdr entry)) - (start (match-beginning (nth 1 entry))) - (end (match-end (nth 1 entry))) - (form (nth 2 entry))) - (goto-char (match-end 0)) - (when (eval form) - (gnus-article-add-button - start end (nth 3 entry) - (buffer-substring (match-beginning (nth 4 entry)) - (match-end (nth 4 entry))))))) - (goto-char end)))) - (widen))) - -;;; External functions: - -(defun gnus-article-add-button (from to fun &optional data) - "Create a button between FROM and TO with callback FUN and data DATA." - (when gnus-article-button-face - (gnus-overlay-put (gnus-make-overlay from to) - 'face gnus-article-button-face)) - (gnus-add-text-properties - from to - (nconc (and gnus-article-mouse-face - (list gnus-mouse-face-prop gnus-article-mouse-face)) - (list 'gnus-callback fun) - (and data (list 'gnus-data data))))) - -;;; Internal functions: - -(defun gnus-article-set-globals () - (save-excursion - (set-buffer gnus-summary-buffer) - (gnus-set-global-variables))) - -(defun gnus-signature-toggle (end) - (save-excursion - (set-buffer gnus-article-buffer) - (let ((buffer-read-only nil) - (inhibit-point-motion-hooks t)) - (if (get-text-property end 'invisible) - (gnus-article-unhide-text end (point-max)) - (gnus-article-hide-text end (point-max) gnus-hidden-properties))))) - -(defun gnus-button-entry () - ;; Return the first entry in `gnus-button-alist' matching this place. - (let ((alist gnus-button-alist) - (entry nil)) - (while alist - (setq entry (pop alist)) - (if (looking-at (car entry)) - (setq alist nil) - (setq entry nil))) - entry)) - -(defun gnus-button-push (marker) - ;; Push button starting at MARKER. - (save-excursion - (set-buffer gnus-article-buffer) - (goto-char marker) - (let* ((entry (gnus-button-entry)) - (inhibit-point-motion-hooks t) - (fun (nth 3 entry)) - (args (mapcar (lambda (group) - (let ((string (match-string group))) - (gnus-set-text-properties - 0 (length string) nil string) - string)) - (nthcdr 4 entry)))) - (cond - ((fboundp fun) - (apply fun args)) - ((and (boundp fun) - (fboundp (symbol-value fun))) - (apply (symbol-value fun) args)) - (t - (gnus-message 1 "You must define `%S' to use this button" - (cons fun args))))))) - -(defun gnus-button-message-id (message-id) - "Fetch MESSAGE-ID." - (save-excursion - (set-buffer gnus-summary-buffer) - (gnus-summary-refer-article message-id))) - -(defun gnus-button-fetch-group (address) - "Fetch GROUP specified by ADDRESS." - (if (not (string-match "[:/]" address)) - ;; This is just a simple group url. - (gnus-group-read-ephemeral-group address gnus-select-method) - (if (not (string-match "^\\([^:/]+\\)\\(:\\([^/]+\\)/\\)?\\(.*\\)$" - address)) - (error "Can't parse %s" address) - (gnus-group-read-ephemeral-group - (match-string 4 address) - `(nntp ,(match-string 1 address) - (nntp-address ,(match-string 1 address)) - (nntp-port-number ,(if (match-end 3) - (match-string 3 address) - "nntp"))))))) - -(defun gnus-url-parse-query-string (query &optional downcase) - (let (retval pairs cur key val) - (setq pairs (gnus-split-string query "&")) - (while pairs - (setq cur (car pairs) - pairs (cdr pairs)) - (if (not (string-match "=" cur)) - nil ; Grace - (setq key (gnus-url-unhex-string (substring cur 0 (match-beginning 0))) - val (gnus-url-unhex-string (substring cur (match-end 0) nil))) - (if downcase - (setq key (downcase key))) - (setq cur (assoc key retval)) - (if cur - (setcdr cur (cons val (cdr cur))) - (setq retval (cons (list key val) retval))))) - retval)) - -(defun gnus-url-unhex (x) - (if (> x ?9) - (if (>= x ?a) - (+ 10 (- x ?a)) - (+ 10 (- x ?A))) - (- x ?0))) - -(defun gnus-url-unhex-string (str &optional allow-newlines) - "Remove %XXX embedded spaces, etc in a url. -If optional second argument ALLOW-NEWLINES is non-nil, then allow the -decoding of carriage returns and line feeds in the string, which is normally -forbidden in URL encoding." - (setq str (or str "")) - (let ((tmp "") - (case-fold-search t)) - (while (string-match "%[0-9a-f][0-9a-f]" str) - (let* ((start (match-beginning 0)) - (ch1 (gnus-url-unhex (elt str (+ start 1)))) - (code (+ (* 16 ch1) - (gnus-url-unhex (elt str (+ start 2)))))) - (setq tmp (concat - tmp (substring str 0 start) - (cond - (allow-newlines - (char-to-string code)) - ((or (= code ?\n) (= code ?\r)) - " ") - (t (char-to-string code)))) - str (substring str (match-end 0))))) - (setq tmp (concat tmp str)) - tmp)) - -(defun gnus-url-mailto (url) - ;; Send mail to someone - (when (string-match "mailto:/*\\(.*\\)" url) - (setq url (substring url (match-beginning 1) nil))) - (let (to args subject func) - (if (string-match (regexp-quote "?") url) - (setq to (gnus-url-unhex-string (substring url 0 (match-beginning 0))) - args (gnus-url-parse-query-string - (substring url (match-end 0) nil) t)) - (setq to (gnus-url-unhex-string url))) - (setq args (cons (list "to" to) args) - subject (cdr-safe (assoc "subject" args))) - (gnus-setup-message 'reply - (message-mail) - (while args - (setq func (intern-soft (concat "message-goto-" (downcase (caar args))))) - (if (fboundp func) - (funcall func) - (message-position-on-field (caar args))) - (insert (mapconcat 'identity (cdar args) ", ")) - (setq args (cdr args))) - (if subject - (message-goto-body) - (message-goto-subject))))) - -(defun gnus-button-mailto (address) - ;; Mail to ADDRESS. - (set-buffer (gnus-copy-article-buffer)) - (gnus-setup-message 'reply - (message-reply address))) - -(defun gnus-button-reply (address) - ;; Reply to ADDRESS. - (gnus-setup-message 'reply - (message-reply address))) - -(defun gnus-button-url (address) - "Browse ADDRESS." - ;; In Emacs 20, `browse-url-browser-function' may be an alist. - (if (listp browse-url-browser-function) - (browse-url address) - (funcall browse-url-browser-function address))) - -(defun gnus-button-embedded-url (address) - "Browse ADDRESS." - ;; In Emacs 20, `browse-url-browser-function' may be an alist. - (if (listp browse-url-browser-function) - (browse-url (gnus-strip-whitespace address)) - (funcall browse-url-browser-function (gnus-strip-whitespace address)))) - -;;; Next/prev buttons in the article buffer. - -(defvar gnus-next-page-line-format "%{%(Next page...%)%}\n") -(defvar gnus-prev-page-line-format "%{%(Previous page...%)%}\n") - -(defvar gnus-prev-page-map nil) -(unless gnus-prev-page-map - (setq gnus-prev-page-map (make-sparse-keymap)) - (define-key gnus-prev-page-map gnus-mouse-2 'gnus-button-prev-page) - (define-key gnus-prev-page-map "\r" 'gnus-button-prev-page)) - -(defun gnus-insert-prev-page-button () - (let ((buffer-read-only nil)) - (gnus-eval-format - gnus-prev-page-line-format nil - `(gnus-prev t local-map ,gnus-prev-page-map - gnus-callback gnus-article-button-prev-page - gnus-type annotation)))) - -(defvar gnus-next-page-map nil) -(unless gnus-next-page-map - (setq gnus-next-page-map (make-keymap)) - (suppress-keymap gnus-prev-page-map) - (define-key gnus-next-page-map gnus-mouse-2 'gnus-button-next-page) - (define-key gnus-next-page-map "\r" 'gnus-button-next-page)) - -(defun gnus-button-next-page () - "Go to the next page." - (interactive) - (let ((win (selected-window))) - (select-window (get-buffer-window gnus-article-buffer t)) - (gnus-article-next-page) - (select-window win))) - -(defun gnus-button-prev-page () - "Go to the prev page." - (interactive) - (let ((win (selected-window))) - (select-window (get-buffer-window gnus-article-buffer t)) - (gnus-article-prev-page) - (select-window win))) - -(defun gnus-insert-next-page-button () - (let ((buffer-read-only nil)) - (gnus-eval-format gnus-next-page-line-format nil - `(gnus-next - t local-map ,gnus-next-page-map - gnus-callback gnus-article-button-next-page - gnus-type annotation)))) - -(defun gnus-article-button-next-page (arg) - "Go to the next page." - (interactive "P") - (let ((win (selected-window))) - (select-window (get-buffer-window gnus-article-buffer t)) - (gnus-article-next-page) - (select-window win))) - -(defun gnus-article-button-prev-page (arg) - "Go to the prev page." - (interactive "P") - (let ((win (selected-window))) - (select-window (get-buffer-window gnus-article-buffer t)) - (gnus-article-prev-page) - (select-window win))) - - -;;; @ for mime-view -;;; - -(defun gnus-article-header-presentation-method (entity situation) - (mime-insert-decoded-header entity) - ) - -(set-alist 'mime-header-presentation-method-alist - 'gnus-original-article-mode - #'gnus-article-header-presentation-method) - -(defun gnus-mime-preview-quitting-method () - (if gnus-show-mime - (gnus-article-show-summary) - (mime-preview-kill-buffer) - (delete-other-windows) - (gnus-article-show-summary) - (gnus-summary-select-article nil t) - )) - -(set-alist 'mime-preview-quitting-method-alist - 'gnus-original-article-mode #'gnus-mime-preview-quitting-method) - -(defun gnus-following-method (buf) - (set-buffer buf) - (message-followup) - (message-yank-original) - (kill-buffer buf) - (goto-char (point-min)) - ) - -(set-alist 'mime-preview-following-method-alist - 'gnus-original-article-mode #'gnus-following-method) - - -;;; @ end -;;; - -(gnus-ems-redefine) - -(provide 'gnus-art) - -(run-hooks 'gnus-art-load-hook) - -;;; gnus-art.el ends here diff --git a/lisp/gnus-async.el b/lisp/gnus-async.el deleted file mode 100644 index 8da43cc..0000000 --- a/lisp/gnus-async.el +++ /dev/null @@ -1,325 +0,0 @@ -;;; gnus-async.el --- asynchronous support for Gnus -;; Copyright (C) 1996,97,98 Free Software Foundation, Inc. - -;; Author: Lars Magne Ingebrigtsen -;; Keywords: news - -;; This file is part of GNU Emacs. - -;; GNU Emacs is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 2, or (at your option) -;; any later version. - -;; GNU Emacs is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs; see the file COPYING. If not, write to the -;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. - -;;; Commentary: - -;;; Code: - -(eval-when-compile (require 'cl)) - -(require 'gnus) -(require 'gnus-sum) -(require 'nntp) - -(defgroup gnus-asynchronous nil - "Support for asynchronous operations." - :group 'gnus) - -(defcustom gnus-asynchronous t - "*If nil, inhibit all Gnus asynchronicity. -If non-nil, let the other asynch variables be heeded." - :group 'gnus-asynchronous - :type 'boolean) - -(defcustom gnus-use-article-prefetch 30 - "*If non-nil, prefetch articles in groups that allow this. -If a number, prefetch only that many articles forward; -if t, prefetch as many articles as possible." - :group 'gnus-asynchronous - :type '(choice (const :tag "off" nil) - (const :tag "all" t) - (integer :tag "some" 0))) - -(defcustom gnus-prefetched-article-deletion-strategy '(read exit) - "List of symbols that say when to remove articles from the prefetch buffer. -Possible values in this list are `read', which means that -articles are removed as they are read, and `exit', which means -that all articles belonging to a group are removed on exit -from that group." - :group 'gnus-asynchronous - :type '(set (const read) (const exit))) - -(defcustom gnus-use-header-prefetch nil - "*If non-nil, prefetch the headers to the next group." - :group 'gnus-asynchronous - :type 'boolean) - -(defcustom gnus-async-prefetch-article-p 'gnus-async-unread-p - "Function called to say whether an article should be prefetched or not. -The function is called with one parameter -- the article data. -It should return non-nil if the article is to be prefetched." - :group 'gnus-asynchronous - :type 'function) - -;;; Internal variables. - -(defvar gnus-async-prefetch-article-buffer " *Async Prefetch Article*") -(defvar gnus-async-article-alist nil) -(defvar gnus-async-article-semaphore '(nil)) -(defvar gnus-async-fetch-list nil) -(defvar gnus-asynch-obarray nil) - -(defvar gnus-async-prefetch-headers-buffer " *Async Prefetch Headers*") -(defvar gnus-async-header-prefetched nil) - -;;; Utility functions. - -(defun gnus-group-asynchronous-p (group) - "Say whether GROUP is fetched from a server that supports asynchronicity." - (gnus-asynchronous-p (gnus-find-method-for-group group))) - -;;; Somewhat bogus semaphores. - -(defun gnus-async-get-semaphore (semaphore) - "Wait until SEMAPHORE is released." - (while (/= (length (nconc (symbol-value semaphore) (list nil))) 2) - (sleep-for 1))) - -(defun gnus-async-release-semaphore (semaphore) - "Release SEMAPHORE." - (setcdr (symbol-value semaphore) nil)) - -(defmacro gnus-async-with-semaphore (&rest forms) - `(unwind-protect - (progn - (gnus-async-get-semaphore 'gnus-async-article-semaphore) - ,@forms) - (gnus-async-release-semaphore 'gnus-async-article-semaphore))) - -(put 'gnus-asynch-with-semaphore 'lisp-indent-function 0) -(put 'gnus-asynch-with-semaphore 'edebug-form-spec '(body)) - -;;; -;;; Article prefetch -;;; - -(gnus-add-shutdown 'gnus-async-close 'gnus) -(defun gnus-async-close () - (gnus-kill-buffer gnus-async-prefetch-article-buffer) - (gnus-kill-buffer gnus-async-prefetch-headers-buffer) - (setq gnus-async-article-alist nil - gnus-async-header-prefetched nil)) - -(defun gnus-async-set-buffer () - (nnheader-set-temp-buffer gnus-async-prefetch-article-buffer t) - (unless gnus-asynch-obarray - (set (make-local-variable 'gnus-asynch-obarray) - (gnus-make-hashtable 1023)))) - -(defun gnus-async-halt-prefetch () - "Stop prefetching." - (setq gnus-async-fetch-list nil)) - -(defun gnus-async-prefetch-next (group article summary) - "Possibly prefetch several articles starting with the article after ARTICLE." - (when (and (gnus-buffer-live-p summary) - gnus-asynchronous - (gnus-group-asynchronous-p group)) - (save-excursion - (set-buffer gnus-summary-buffer) - (let ((next (caadr (gnus-data-find-list article)))) - (when next - (if (not (fboundp 'run-with-idle-timer)) - ;; This is either an older Emacs or XEmacs, so we - ;; do this, which leads to slightly slower article - ;; buffer display. - (gnus-async-prefetch-article group next summary) - (run-with-idle-timer - 0.1 nil 'gnus-async-prefetch-article group next summary))))))) - -(defun gnus-async-prefetch-article (group article summary &optional next) - "Possibly prefetch several articles starting with ARTICLE." - (if (not (gnus-buffer-live-p summary)) - (gnus-async-with-semaphore - (setq gnus-async-fetch-list nil)) - (when (and gnus-asynchronous - (gnus-alive-p)) - (when next - (gnus-async-with-semaphore - (pop gnus-async-fetch-list))) - (let ((do-fetch next) - (do-message t)) ;(eq major-mode 'gnus-summary-mode))) - (when (and (gnus-group-asynchronous-p group) - (gnus-buffer-live-p summary) - (or (not next) - gnus-async-fetch-list)) - (gnus-async-with-semaphore - (unless next - (setq do-fetch (not gnus-async-fetch-list)) - ;; Nix out any outstanding requests. - (setq gnus-async-fetch-list nil) - ;; Fill in the new list. - (let ((n gnus-use-article-prefetch) - (data (gnus-data-find-list article)) - d) - (while (and (setq d (pop data)) - (if (numberp n) - (natnump (decf n)) - n)) - (unless (or (gnus-async-prefetched-article-entry - group (setq article (gnus-data-number d))) - (not (natnump article)) - (not (funcall gnus-async-prefetch-article-p d))) - ;; Not already fetched -- so we add it to the list. - (push article gnus-async-fetch-list))) - (setq gnus-async-fetch-list - (nreverse gnus-async-fetch-list)))) - - (when do-fetch - (setq article (car gnus-async-fetch-list)))) - - (when (and do-fetch article) - ;; We want to fetch some more articles. - (save-excursion - (set-buffer summary) - (let (mark) - (gnus-async-set-buffer) - (goto-char (point-max)) - (setq mark (point-marker)) - (let ((nnheader-callback-function - (gnus-make-async-article-function - group article mark summary next)) - (nntp-server-buffer - (get-buffer gnus-async-prefetch-article-buffer))) - (when do-message - (gnus-message 9 "Prefetching article %d in group %s" - article group)) - (gnus-request-article article group)))))))))) - -(defun gnus-make-async-article-function (group article mark summary next) - "Return a callback function." - `(lambda (arg) - (save-excursion - (when arg - (gnus-async-set-buffer) - (gnus-async-with-semaphore - (push (list ',(intern (format "%s-%d" group article) - gnus-asynch-obarray) - ,mark (set-marker (make-marker) (point-max)) - ,group ,article) - gnus-async-article-alist))) - (if (not (gnus-buffer-live-p ,summary)) - (gnus-async-with-semaphore - (setq gnus-async-fetch-list nil)) - (gnus-async-prefetch-article ,group ,next ,summary t))))) - -(defun gnus-async-unread-p (data) - "Return non-nil if DATA represents an unread article." - (gnus-data-unread-p data)) - -(defun gnus-async-request-fetched-article (group article buffer) - "See whether we have ARTICLE from GROUP and put it in BUFFER." - (when (numberp article) - (let ((entry (gnus-async-prefetched-article-entry group article))) - (when entry - (save-excursion - (gnus-async-set-buffer) - (copy-to-buffer buffer (cadr entry) (caddr entry)) - ;; Remove the read article from the prefetch buffer. - (when (memq 'read gnus-prefetched-article-deletion-strategy) - (gnus-async-delete-prefected-entry entry)) - t))))) - -(defun gnus-async-delete-prefected-entry (entry) - "Delete ENTRY from buffer and alist." - (ignore-errors - (delete-region (cadr entry) (caddr entry)) - (set-marker (cadr entry) nil) - (set-marker (caddr entry) nil)) - (gnus-async-with-semaphore - (setq gnus-async-article-alist - (delq entry gnus-async-article-alist)))) - -(defun gnus-async-prefetch-remove-group (group) - "Remove all articles belonging to GROUP from the prefetch buffer." - (when (and (gnus-group-asynchronous-p group) - (memq 'exit gnus-prefetched-article-deletion-strategy)) - (let ((alist gnus-async-article-alist)) - (save-excursion - (gnus-async-set-buffer) - (while alist - (when (equal group (nth 3 (car alist))) - (gnus-async-delete-prefected-entry (car alist))) - (pop alist)))))) - -(defun gnus-async-prefetched-article-entry (group article) - "Return the entry for ARTICLE in GROUP iff it has been prefetched." - (let ((entry (save-excursion - (gnus-async-set-buffer) - (assq (intern (format "%s-%d" group article) - gnus-asynch-obarray) - gnus-async-article-alist)))) - ;; Perhaps something has emptied the buffer? - (if (and entry - (= (cadr entry) (caddr entry))) - (progn - (ignore-errors - (set-marker (cadr entry) nil) - (set-marker (caddr entry) nil)) - (setq gnus-async-article-alist - (delq entry gnus-async-article-alist)) - nil) - entry))) - -;;; -;;; Header prefetch -;;; - -(defun gnus-async-prefetch-headers (group) - "Prefetch the headers for group GROUP." - (save-excursion - (let (unread) - (when (and gnus-use-header-prefetch - gnus-asynchronous - (gnus-group-asynchronous-p group) - (listp gnus-async-header-prefetched) - (setq unread (gnus-list-of-unread-articles group))) - ;; Mark that a fetch is in progress. - (setq gnus-async-header-prefetched t) - (nnheader-set-temp-buffer gnus-async-prefetch-headers-buffer t) - (erase-buffer) - (let ((nntp-server-buffer (current-buffer)) - (nnheader-callback-function - `(lambda (arg) - (setq gnus-async-header-prefetched - ,(cons group unread))))) - (gnus-retrieve-headers unread group gnus-fetch-old-headers)))))) - -(defun gnus-async-retrieve-fetched-headers (articles group) - "See whether we have prefetched headers." - (when (and gnus-use-header-prefetch - (gnus-group-asynchronous-p group) - (listp gnus-async-header-prefetched) - (equal group (car gnus-async-header-prefetched)) - (equal articles (cdr gnus-async-header-prefetched))) - (save-excursion - (nnheader-set-temp-buffer gnus-async-prefetch-headers-buffer t) - (nntp-decode-text) - (copy-to-buffer nntp-server-buffer (point-min) (point-max)) - (erase-buffer) - (setq gnus-async-header-prefetched nil) - t))) - -(provide 'gnus-async) - -;;; gnus-async.el ends here diff --git a/lisp/gnus-audio.el b/lisp/gnus-audio.el deleted file mode 100644 index f3bb686..0000000 --- a/lisp/gnus-audio.el +++ /dev/null @@ -1,131 +0,0 @@ -;;; gnus-audio.el --- Sound effects for Gnus -;; Copyright (C) 1996 Free Software Foundation - -;; Author: Steven L. Baur - -;; This file is part of GNU Emacs. - -;; GNU Emacs is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 2, or (at your option) -;; any later version. - -;; GNU Emacs is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs; see the file COPYING. If not, write to the -;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. - -;;; Commentary: -;; This file provides access to sound effects in Gnus. -;; Prerelease: This file is partially stripped to support earcons.el -;; You can safely ignore most of it until Red Gnus. **Evil Laugh** -;;; Code: - -(when (null (boundp 'running-xemacs)) - (defvar running-xemacs (string-match "XEmacs\\|Lucid" emacs-version))) - -(require 'nnheader) -(eval-when-compile (require 'cl)) - -(defvar gnus-audio-inline-sound - (and (fboundp 'device-sound-enabled-p) - (device-sound-enabled-p)) - "When t, we will not spawn a subprocess to play sounds.") - -(defvar gnus-audio-directory (nnheader-find-etc-directory "sounds") - "The directory containing the Sound Files.") - -(defvar gnus-audio-au-player "/usr/bin/showaudio" - "Executable program for playing sun AU format sound files.") - -(defvar gnus-audio-wav-player "/usr/local/bin/play" - "Executable program for playing WAV files.") - -;;; The following isn't implemented yet. Wait for Millennium Gnus. -;(defvar gnus-audio-effects-enabled t -; "When t, Gnus will use sound effects.") -;(defvar gnus-audio-enable-hooks nil -; "Functions run when enabling sound effects.") -;(defvar gnus-audio-disable-hooks nil -; "Functions run when disabling sound effects.") -;(defvar gnus-audio-theme-song nil -; "Theme song for Gnus.") -;(defvar gnus-audio-enter-group nil -; "Sound effect played when selecting a group.") -;(defvar gnus-audio-exit-group nil -; "Sound effect played when exiting a group.") -;(defvar gnus-audio-score-group nil -; "Sound effect played when scoring a group.") -;(defvar gnus-audio-busy-sound nil -; "Sound effect played when going into a ... sequence.") - - -;;;###autoload - ;(defun gnus-audio-enable-sound () -; "Enable Sound Effects for Gnus." -; (interactive) -; (setq gnus-audio-effects-enabled t) -; (gnus-run-hooks gnus-audio-enable-hooks)) - -;;;###autoload - ;(defun gnus-audio-disable-sound () -; "Disable Sound Effects for Gnus." -; (interactive) -; (setq gnus-audio-effects-enabled nil) -; (gnus-run-hooks gnus-audio-disable-hooks)) - -;;;###autoload -(defun gnus-audio-play (file) - "Play a sound through the speaker." - (interactive) - (let ((sound-file (if (file-exists-p file) - file - (concat gnus-audio-directory file)))) - (when (file-exists-p sound-file) - (if gnus-audio-inline-sound - (play-sound-file sound-file) - (cond ((string-match "\\.wav$" sound-file) - (call-process gnus-audio-wav-player - sound-file - 0 - nil - sound-file)) - ((string-match "\\.au$" sound-file) - (call-process gnus-audio-au-player - sound-file - 0 - nil - sound-file))))))) - - -;;; The following isn't implemented yet, wait for Red Gnus - ;(defun gnus-audio-startrek-sounds () -; "Enable sounds from Star Trek the original series." -; (interactive) -; (setq gnus-audio-busy-sound "working.au") -; (setq gnus-audio-enter-group "bulkhead_door.au") -; (setq gnus-audio-exit-group "bulkhead_door.au") -; (setq gnus-audio-score-group "ST_laser.au") -; (setq gnus-audio-theme-song "startrek.au") -; (add-hook 'gnus-select-group-hook 'gnus-audio-startrek-select-group) -; (add-hook 'gnus-exit-group-hook 'gnus-audio-startrek-exit-group)) -;;;*** - -(defvar gnus-startup-jingle "Tuxedomoon.Jingle4.au" - "Name of the Gnus startup jingle file.") - -(defun gnus-play-jingle () - "Play the Gnus startup jingle, unless that's inhibited." - (interactive) - (gnus-audio-play gnus-startup-jingle)) - -(provide 'gnus-audio) - -(run-hooks 'gnus-audio-load-hook) - -;;; gnus-audio.el ends here diff --git a/lisp/gnus-bcklg.el b/lisp/gnus-bcklg.el deleted file mode 100644 index d370673..0000000 --- a/lisp/gnus-bcklg.el +++ /dev/null @@ -1,154 +0,0 @@ -;;; gnus-bcklg.el --- backlog functions for Gnus -;; Copyright (C) 1996,97,98 Free Software Foundation, Inc. - -;; Author: Lars Magne Ingebrigtsen -;; Keywords: news - -;; This file is part of GNU Emacs. - -;; GNU Emacs is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 2, or (at your option) -;; any later version. - -;; GNU Emacs is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs; see the file COPYING. If not, write to the -;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. - -;;; Commentary: - -;;; Code: - -(eval-when-compile (require 'cl)) - -(require 'gnus) - -;;; -;;; Buffering of read articles. -;;; - -(defvar gnus-backlog-buffer " *Gnus Backlog*") -(defvar gnus-backlog-articles nil) -(defvar gnus-backlog-hashtb nil) - -(defun gnus-backlog-buffer () - "Return the backlog buffer." - (or (get-buffer gnus-backlog-buffer) - (save-excursion - (set-buffer (gnus-get-buffer-create gnus-backlog-buffer)) - (buffer-disable-undo (current-buffer)) - (setq buffer-read-only t) - (get-buffer gnus-backlog-buffer)))) - -(defun gnus-backlog-setup () - "Initialize backlog variables." - (unless gnus-backlog-hashtb - (setq gnus-backlog-hashtb (gnus-make-hashtable 1024)))) - -(gnus-add-shutdown 'gnus-backlog-shutdown 'gnus) - -(defun gnus-backlog-shutdown () - "Clear all backlog variables and buffers." - (when (get-buffer gnus-backlog-buffer) - (kill-buffer gnus-backlog-buffer)) - (setq gnus-backlog-hashtb nil - gnus-backlog-articles nil)) - -(defun gnus-backlog-enter-article (group number buffer) - (gnus-backlog-setup) - (let ((ident (intern (concat group ":" (int-to-string number)) - gnus-backlog-hashtb)) - b) - (if (memq ident gnus-backlog-articles) - () ; It's already kept. - ;; Remove the oldest article, if necessary. - (and (numberp gnus-keep-backlog) - (>= (length gnus-backlog-articles) gnus-keep-backlog) - (gnus-backlog-remove-oldest-article)) - (push ident gnus-backlog-articles) - ;; Insert the new article. - (save-excursion - (set-buffer (gnus-backlog-buffer)) - (let (buffer-read-only) - (goto-char (point-max)) - (unless (bolp) - (insert "\n")) - (setq b (point)) - (insert-buffer-substring buffer) - ;; Tag the beginning of the article with the ident. - (gnus-put-text-property b (1+ b) 'gnus-backlog ident)))))) - -(defun gnus-backlog-remove-oldest-article () - (save-excursion - (set-buffer (gnus-backlog-buffer)) - (goto-char (point-min)) - (if (zerop (buffer-size)) - () ; The buffer is empty. - (let ((ident (get-text-property (point) 'gnus-backlog)) - buffer-read-only) - ;; Remove the ident from the list of articles. - (when ident - (setq gnus-backlog-articles (delq ident gnus-backlog-articles))) - ;; Delete the article itself. - (delete-region - (point) (next-single-property-change - (1+ (point)) 'gnus-backlog nil (point-max))))))) - -(defun gnus-backlog-remove-article (group number) - "Remove article NUMBER in GROUP from the backlog." - (when (numberp number) - (gnus-backlog-setup) - (let ((ident (intern (concat group ":" (int-to-string number)) - gnus-backlog-hashtb)) - beg end) - (when (memq ident gnus-backlog-articles) - ;; It was in the backlog. - (save-excursion - (set-buffer (gnus-backlog-buffer)) - (let (buffer-read-only) - (when (setq beg (text-property-any - (point-min) (point-max) 'gnus-backlog - ident)) - ;; Find the end (i. e., the beginning of the next article). - (setq end - (next-single-property-change - (1+ beg) 'gnus-backlog (current-buffer) (point-max))) - (delete-region beg end) - ;; Return success. - t)) - (setq gnus-backlog-articles (delq ident gnus-backlog-articles))))))) - -(defun gnus-backlog-request-article (group number buffer) - (when (numberp number) - (gnus-backlog-setup) - (let ((ident (intern (concat group ":" (int-to-string number)) - gnus-backlog-hashtb)) - beg end) - (when (memq ident gnus-backlog-articles) - ;; It was in the backlog. - (save-excursion - (set-buffer (gnus-backlog-buffer)) - (if (not (setq beg (text-property-any - (point-min) (point-max) 'gnus-backlog - ident))) - ;; It wasn't in the backlog after all. - (ignore - (setq gnus-backlog-articles (delq ident gnus-backlog-articles))) - ;; Find the end (i. e., the beginning of the next article). - (setq end - (next-single-property-change - (1+ beg) 'gnus-backlog (current-buffer) (point-max))))) - (let ((buffer-read-only nil)) - (erase-buffer) - (insert-buffer-substring gnus-backlog-buffer beg end) - t))))) - -(provide 'gnus-bcklg) - -;;; gnus-bcklg.el ends here diff --git a/lisp/gnus-cache.el b/lisp/gnus-cache.el deleted file mode 100644 index 470fb21..0000000 --- a/lisp/gnus-cache.el +++ /dev/null @@ -1,682 +0,0 @@ -;;; gnus-cache.el --- cache interface for Gnus -;; Copyright (C) 1995,96,97,98 Free Software Foundation, Inc. - -;; Author: Lars Magne Ingebrigtsen -;; Keywords: news - -;; This file is part of GNU Emacs. - -;; GNU Emacs is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 2, or (at your option) -;; any later version. - -;; GNU Emacs is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs; see the file COPYING. If not, write to the -;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. - -;;; Commentary: - -;;; Code: - -(eval-when-compile (require 'cl)) - -(require 'gnus) -(require 'gnus-int) -(require 'gnus-range) -(require 'gnus-start) -(eval-when-compile - (require 'gnus-sum)) - -(defcustom gnus-cache-active-file - (concat (file-name-as-directory gnus-cache-directory) "active") - "*The cache active file." - :group 'gnus-cache - :type 'file) - -(defcustom gnus-cache-enter-articles '(ticked dormant) - "Classes of articles to enter into the cache." - :group 'gnus-cache - :type '(set (const ticked) (const dormant) (const unread) (const read))) - -(defcustom gnus-cache-remove-articles '(read) - "Classes of articles to remove from the cache." - :group 'gnus-cache - :type '(set (const ticked) (const dormant) (const unread) (const read))) - -(defcustom gnus-cacheable-groups nil - "*Groups that match this regexp will be cached. - -If you only want to cache your nntp groups, you could set this -variable to \"^nntp\". - -If a group matches both gnus-cacheable-groups and gnus-uncacheable-groups -it's not cached." - :group 'gnus-cache - :type '(choice (const :tag "off" nil) - regexp)) - -(defcustom gnus-uncacheable-groups nil - "*Groups that match this regexp will not be cached. - -If you want to avoid caching your nnml groups, you could set this -variable to \"^nnml\". - -If a group matches both gnus-cacheable-groups and gnus-uncacheable-groups -it's not cached." - :group 'gnus-cache - :type '(choice (const :tag "off" nil) - regexp)) - -(defvar gnus-cache-overview-coding-system 'raw-text - "Coding system used on Gnus cache files.") - - - -;;; Internal variables. - -(defvar gnus-cache-removable-articles nil) -(defvar gnus-cache-buffer nil) -(defvar gnus-cache-active-hashtb nil) -(defvar gnus-cache-active-altered nil) - -(eval-and-compile - (autoload 'nnml-generate-nov-databases-1 "nnml") - (autoload 'nnvirtual-find-group-art "nnvirtual")) - - - -;;; Functions called from Gnus. - -(defun gnus-cache-open () - "Initialize the cache." - (when (or (file-exists-p gnus-cache-directory) - (and gnus-use-cache - (not (eq gnus-use-cache 'passive)))) - (gnus-cache-read-active))) - -;; Complexities of byte-compiling make this kludge necessary. Eeek. -(ignore-errors - (gnus-add-shutdown 'gnus-cache-close 'gnus)) - -(defun gnus-cache-close () - "Shut down the cache." - (gnus-cache-write-active) - (gnus-cache-save-buffers) - (setq gnus-cache-active-hashtb nil)) - -(defun gnus-cache-save-buffers () - ;; save the overview buffer if it exists and has been modified - ;; delete empty cache subdirectories - (when gnus-cache-buffer - (let ((buffer (cdr gnus-cache-buffer)) - (overview-file (gnus-cache-file-name - (car gnus-cache-buffer) ".overview"))) - ;; write the overview only if it was modified - (when (buffer-modified-p buffer) - (save-excursion - (set-buffer buffer) - (if (> (buffer-size) 0) - ;; Non-empty overview, write it to a file. - (let ((coding-system-for-write - gnus-cache-overview-coding-system)) - (gnus-write-buffer overview-file)) - ;; Empty overview file, remove it - (when (file-exists-p overview-file) - (delete-file overview-file)) - ;; If possible, remove group's cache subdirectory. - (condition-case nil - ;; FIXME: we can detect the error type and warn the user - ;; of any inconsistencies (articles w/o nov entries?). - ;; for now, just be conservative...delete only if safe -- sj - (delete-directory (file-name-directory overview-file)) - (error nil))))) - ;; Kill the buffer -- it's either unmodified or saved. - (gnus-kill-buffer buffer) - (setq gnus-cache-buffer nil)))) - -(defun gnus-cache-possibly-enter-article - (group article headers ticked dormant unread &optional force) - (when (and (or force (not (eq gnus-use-cache 'passive))) - (numberp article) - (> article 0) - (vectorp headers)) ; This might be a dummy article. - ;; If this is a virtual group, we find the real group. - (when (gnus-virtual-group-p group) - (let ((result (nnvirtual-find-group-art - (gnus-group-real-name group) article))) - (setq group (car result) - headers (copy-sequence headers)) - (mail-header-set-number headers (cdr result)))) - (let ((number (mail-header-number headers)) - file) - (when (and number - (> number 0) ; Reffed article. - (or force - (and (or (not gnus-cacheable-groups) - (string-match gnus-cacheable-groups group)) - (or (not gnus-uncacheable-groups) - (not (string-match - gnus-uncacheable-groups group))) - (gnus-cache-member-of-class - gnus-cache-enter-articles ticked dormant unread))) - (not (file-exists-p (setq file (gnus-cache-file-name - group number))))) - ;; Possibly create the cache directory. - (gnus-make-directory (file-name-directory file)) - ;; Save the article in the cache. - (if (file-exists-p file) - t ; The article already is saved. - (save-excursion - (set-buffer nntp-server-buffer) - (let ((gnus-use-cache nil)) - (gnus-request-article-this-buffer number group)) - (when (> (buffer-size) 0) - (gnus-write-buffer file) - (gnus-cache-change-buffer group) - (set-buffer (cdr gnus-cache-buffer)) - (goto-char (point-max)) - (forward-line -1) - (while (condition-case () - (when (not (bobp)) - (> (read (current-buffer)) number)) - (error - ;; The line was malformed, so we just remove it!! - (gnus-delete-line) - t)) - (forward-line -1)) - (if (bobp) - (if (not (eobp)) - (progn - (beginning-of-line) - (when (< (read (current-buffer)) number) - (forward-line 1))) - (beginning-of-line)) - (forward-line 1)) - (beginning-of-line) - ;; [number subject from date id references chars lines xref] - (insert (format "%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t\n" - (mail-header-number headers) - (mail-header-subject headers) - (mail-header-from headers) - (mail-header-date headers) - (mail-header-id headers) - (or (mail-header-references headers) "") - (or (mail-header-chars headers) "") - (or (mail-header-lines headers) "") - (or (mail-header-xref headers) ""))) - ;; Update the active info. - (set-buffer gnus-summary-buffer) - (gnus-cache-update-active group number) - (push article gnus-newsgroup-cached) - (gnus-summary-update-secondary-mark article)) - t)))))) - -(defun gnus-cache-enter-remove-article (article) - "Mark ARTICLE for later possible removal." - (when article - (push article gnus-cache-removable-articles))) - -(defun gnus-cache-possibly-remove-articles () - "Possibly remove some of the removable articles." - (if (not (gnus-virtual-group-p gnus-newsgroup-name)) - (gnus-cache-possibly-remove-articles-1) - (let ((arts gnus-cache-removable-articles) - ga) - (while arts - (when (setq ga (nnvirtual-find-group-art - (gnus-group-real-name gnus-newsgroup-name) (pop arts))) - (let ((gnus-cache-removable-articles (list (cdr ga))) - (gnus-newsgroup-name (car ga))) - (gnus-cache-possibly-remove-articles-1))))) - (setq gnus-cache-removable-articles nil))) - -(defun gnus-cache-possibly-remove-articles-1 () - "Possibly remove some of the removable articles." - (unless (eq gnus-use-cache 'passive) - (let ((articles gnus-cache-removable-articles) - (cache-articles gnus-newsgroup-cached) - article) - (gnus-cache-change-buffer gnus-newsgroup-name) - (while articles - (when (memq (setq article (pop articles)) cache-articles) - ;; The article was in the cache, so we see whether we are - ;; supposed to remove it from the cache. - (gnus-cache-possibly-remove-article - article (memq article gnus-newsgroup-marked) - (memq article gnus-newsgroup-dormant) - (or (memq article gnus-newsgroup-unreads) - (memq article gnus-newsgroup-unselected)))))) - ;; The overview file might have been modified, save it - ;; safe because we're only called at group exit anyway. - (gnus-cache-save-buffers))) - -(defun gnus-cache-request-article (article group) - "Retrieve ARTICLE in GROUP from the cache." - (let ((file (gnus-cache-file-name group article)) - (buffer-read-only nil)) - (when (file-exists-p file) - (erase-buffer) - (gnus-kill-all-overlays) - (nnheader-insert-file-contents file) - t))) - -(defun gnus-cache-possibly-alter-active (group active) - "Alter the ACTIVE info for GROUP to reflect the articles in the cache." - (when gnus-cache-active-hashtb - (let ((cache-active (gnus-gethash group gnus-cache-active-hashtb))) - (when cache-active - (when (< (car cache-active) (car active)) - (setcar active (car cache-active))) - (when (> (cdr cache-active) (cdr active)) - (setcdr active (cdr cache-active))))))) - -(defun gnus-cache-retrieve-headers (articles group &optional fetch-old) - "Retrieve the headers for ARTICLES in GROUP." - (let ((cached - (setq gnus-newsgroup-cached (gnus-cache-articles-in-group group)))) - (if (not cached) - ;; No cached articles here, so we just retrieve them - ;; the normal way. - (let ((gnus-use-cache nil)) - (gnus-retrieve-headers articles group fetch-old)) - (let ((uncached-articles (gnus-sorted-intersection - (gnus-sorted-complement articles cached) - articles)) - (cache-file (gnus-cache-file-name group ".overview")) - type) - ;; We first retrieve all the headers that we don't have in - ;; the cache. - (let ((gnus-use-cache nil)) - (when uncached-articles - (setq type (and articles - (gnus-retrieve-headers - uncached-articles group fetch-old))))) - (gnus-cache-save-buffers) - ;; Then we insert the cached headers. - (save-excursion - (cond - ((not (file-exists-p cache-file)) - ;; There are no cached headers. - type) - ((null type) - ;; There were no uncached headers (or retrieval was - ;; unsuccessful), so we use the cached headers exclusively. - (set-buffer nntp-server-buffer) - (erase-buffer) - (nnheader-insert-file-contents cache-file) - 'nov) - ((eq type 'nov) - ;; We have both cached and uncached NOV headers, so we - ;; braid them. - (gnus-cache-braid-nov group cached) - type) - (t - ;; We braid HEADs. - (gnus-cache-braid-heads group (gnus-sorted-intersection - cached articles)) - type))))))) - -(defun gnus-cache-enter-article (&optional n) - "Enter the next N articles into the cache. -If not given a prefix, use the process marked articles instead. -Returns the list of articles entered." - (interactive "P") - (let ((articles (gnus-summary-work-articles n)) - article out) - (while (setq article (pop articles)) - (gnus-summary-remove-process-mark article) - (if (natnump article) - (when (gnus-cache-possibly-enter-article - gnus-newsgroup-name article - (gnus-summary-article-header article) - nil nil nil t) - (push article out)) - (gnus-message 2 "Can't cache article %d" article)) - (gnus-summary-update-secondary-mark article)) - (gnus-summary-next-subject 1) - (gnus-summary-position-point) - (nreverse out))) - -(defun gnus-cache-remove-article (n) - "Remove the next N articles from the cache. -If not given a prefix, use the process marked articles instead. -Returns the list of articles removed." - (interactive "P") - (gnus-cache-change-buffer gnus-newsgroup-name) - (let ((articles (gnus-summary-work-articles n)) - article out) - (while articles - (setq article (pop articles)) - (gnus-summary-remove-process-mark article) - (when (gnus-cache-possibly-remove-article article nil nil nil t) - (push article out)) - (gnus-summary-update-secondary-mark article)) - (gnus-summary-next-subject 1) - (gnus-summary-position-point) - (nreverse out))) - -(defun gnus-cached-article-p (article) - "Say whether ARTICLE is cached in the current group." - (memq article gnus-newsgroup-cached)) - -(defun gnus-summary-insert-cached-articles () - "Insert all the articles cached for this group into the current buffer." - (interactive) - (let ((cached (sort (copy-sequence gnus-newsgroup-cached) '<)) - (gnus-verbose (max 6 gnus-verbose))) - (unless cached - (gnus-message 3 "No cached articles for this group")) - (while cached - (gnus-summary-goto-subject (pop cached) t)))) - -(defalias 'gnus-summary-limit-include-cached - 'gnus-summary-insert-cached-articles) - -;;; Internal functions. - -(defun gnus-cache-change-buffer (group) - (and gnus-cache-buffer - ;; See if the current group's overview cache has been loaded. - (or (string= group (car gnus-cache-buffer)) - ;; Another overview cache is current, save it. - (gnus-cache-save-buffers))) - ;; if gnus-cache buffer is nil, create it - (unless gnus-cache-buffer - ;; Create cache buffer - (save-excursion - (setq gnus-cache-buffer - (cons group - (set-buffer (gnus-get-buffer-create - " *gnus-cache-overview*")))) - (buffer-disable-undo (current-buffer)) - ;; Insert the contents of this group's cache overview. - (erase-buffer) - (let ((file (gnus-cache-file-name group ".overview"))) - (when (file-exists-p file) - (nnheader-insert-file-contents file))) - ;; We have a fresh (empty/just loaded) buffer, - ;; mark it as unmodified to save a redundant write later. - (set-buffer-modified-p nil)))) - -;; Return whether an article is a member of a class. -(defun gnus-cache-member-of-class (class ticked dormant unread) - (or (and ticked (memq 'ticked class)) - (and dormant (memq 'dormant class)) - (and unread (memq 'unread class)) - (and (not unread) (not ticked) (not dormant) (memq 'read class)))) - -(defun gnus-cache-file-name (group article) - (concat (file-name-as-directory gnus-cache-directory) - (file-name-as-directory - (nnheader-translate-file-chars - (if (gnus-use-long-file-name 'not-cache) - group - (let ((group (nnheader-replace-chars-in-string group ?/ ?_))) - ;; Translate the first colon into a slash. - (when (string-match ":" group) - (aset group (match-beginning 0) ?/)) - (nnheader-replace-chars-in-string group ?. ?/))) - t)) - (if (stringp article) article (int-to-string article)))) - -(defun gnus-cache-update-article (group article) - "If ARTICLE is in the cache, remove it and re-enter it." - (gnus-cache-change-buffer group) - (when (gnus-cache-possibly-remove-article article nil nil nil t) - (let ((gnus-use-cache nil)) - (gnus-cache-possibly-enter-article - gnus-newsgroup-name article (gnus-summary-article-header article) - nil nil nil t)))) - -(defun gnus-cache-possibly-remove-article (article ticked dormant unread - &optional force) - "Possibly remove ARTICLE from the cache." - (let ((group gnus-newsgroup-name) - (number article) - file) - ;; If this is a virtual group, we find the real group. - (when (gnus-virtual-group-p group) - (let ((result (nnvirtual-find-group-art - (gnus-group-real-name group) article))) - (setq group (car result) - number (cdr result)))) - (setq file (gnus-cache-file-name group number)) - (when (and (file-exists-p file) - (or force - (gnus-cache-member-of-class - gnus-cache-remove-articles ticked dormant unread))) - (save-excursion - (delete-file file) - (set-buffer (cdr gnus-cache-buffer)) - (goto-char (point-min)) - (when (or (looking-at (concat (int-to-string number) "\t")) - (search-forward (concat "\n" (int-to-string number) "\t") - (point-max) t)) - (delete-region (progn (beginning-of-line) (point)) - (progn (forward-line 1) (point))))) - (setq gnus-newsgroup-cached - (delq article gnus-newsgroup-cached)) - (gnus-summary-update-secondary-mark article) - t))) - -(defun gnus-cache-articles-in-group (group) - "Return a sorted list of cached articles in GROUP." - (let ((dir (file-name-directory (gnus-cache-file-name group 1))) - articles) - (when (file-exists-p dir) - (setq articles - (sort (mapcar (lambda (name) (string-to-int name)) - (directory-files dir nil "^[0-9]+$" t)) - '<)) - ;; Update the cache active file, just to synch more. - (when articles - (gnus-cache-update-active group (car articles) t) - (gnus-cache-update-active group (car (last articles)))) - articles))) - -(defun gnus-cache-braid-nov (group cached &optional file) - (let ((cache-buf (gnus-get-buffer-create " *gnus-cache*")) - beg end) - (gnus-cache-save-buffers) - (save-excursion - (set-buffer cache-buf) - (buffer-disable-undo (current-buffer)) - (erase-buffer) - (nnheader-insert-file-contents (or file (gnus-cache-file-name group ".overview"))) - (goto-char (point-min)) - (insert "\n") - (goto-char (point-min))) - (set-buffer nntp-server-buffer) - (goto-char (point-min)) - (while cached - (while (and (not (eobp)) - (< (read (current-buffer)) (car cached))) - (forward-line 1)) - (beginning-of-line) - (save-excursion - (set-buffer cache-buf) - (if (search-forward (concat "\n" (int-to-string (car cached)) "\t") - nil t) - (setq beg (progn (beginning-of-line) (point)) - end (progn (end-of-line) (point))) - (setq beg nil))) - (when beg - (insert-buffer-substring cache-buf beg end) - (insert "\n")) - (setq cached (cdr cached))) - (kill-buffer cache-buf))) - -(defun gnus-cache-braid-heads (group cached) - (let ((cache-buf (gnus-get-buffer-create " *gnus-cache*"))) - (save-excursion - (set-buffer cache-buf) - (buffer-disable-undo (current-buffer)) - (erase-buffer)) - (set-buffer nntp-server-buffer) - (goto-char (point-min)) - (while cached - (while (and (not (eobp)) - (looking-at "2.. +\\([0-9]+\\) ") - (< (progn (goto-char (match-beginning 1)) - (read (current-buffer))) - (car cached))) - (search-forward "\n.\n" nil 'move)) - (beginning-of-line) - (save-excursion - (set-buffer cache-buf) - (erase-buffer) - (nnheader-insert-file-contents (gnus-cache-file-name group (car cached))) - (goto-char (point-min)) - (insert "220 ") - (princ (car cached) (current-buffer)) - (insert " Article retrieved.\n") - (search-forward "\n\n" nil 'move) - (delete-region (point) (point-max)) - (forward-char -1) - (insert ".")) - (insert-buffer-substring cache-buf) - (setq cached (cdr cached))) - (kill-buffer cache-buf))) - -;;;###autoload -(defun gnus-jog-cache () - "Go through all groups and put the articles into the cache. - -Usage: -$ emacs -batch -l ~/.emacs -l gnus -f gnus-jog-cache" - (interactive) - (let ((gnus-mark-article-hook nil) - (gnus-expert-user t) - (nnmail-spool-file nil) - (gnus-use-dribble-file nil) - (gnus-novice-user nil) - (gnus-large-newsgroup nil)) - ;; Start Gnus. - (gnus) - ;; Go through all groups... - (gnus-group-mark-buffer) - (gnus-group-iterate nil - (lambda (group) - (let (gnus-auto-select-next) - (gnus-summary-read-group group nil t) - ;; ... and enter the articles into the cache. - (when (eq major-mode 'gnus-summary-mode) - (gnus-uu-mark-buffer) - (gnus-cache-enter-article) - (kill-buffer (current-buffer)))))))) - -(defun gnus-cache-read-active (&optional force) - "Read the cache active file." - (gnus-make-directory gnus-cache-directory) - (if (or (not (file-exists-p gnus-cache-active-file)) - (not (zerop (nth 7 (file-attributes gnus-cache-active-file)))) - force) - ;; There is no active file, so we generate one. - (gnus-cache-generate-active) - ;; We simply read the active file. - (save-excursion - (gnus-set-work-buffer) - (nnheader-insert-file-contents gnus-cache-active-file) - (gnus-active-to-gnus-format - nil (setq gnus-cache-active-hashtb - (gnus-make-hashtable - (count-lines (point-min) (point-max))))) - (setq gnus-cache-active-altered nil)))) - -(defun gnus-cache-write-active (&optional force) - "Write the active hashtb to the active file." - (when (or force - (and gnus-cache-active-hashtb - gnus-cache-active-altered)) - (nnheader-temp-write gnus-cache-active-file - (mapatoms - (lambda (sym) - (when (and sym (boundp sym)) - (insert (format "%s %d %d y\n" - (symbol-name sym) (cdr (symbol-value sym)) - (car (symbol-value sym)))))) - gnus-cache-active-hashtb)) - ;; Mark the active hashtb as unaltered. - (setq gnus-cache-active-altered nil))) - -(defun gnus-cache-update-active (group number &optional low) - "Update the upper bound of the active info of GROUP to NUMBER. -If LOW, update the lower bound instead." - (let ((active (gnus-gethash group gnus-cache-active-hashtb))) - (if (null active) - ;; We just create a new active entry for this group. - (gnus-sethash group (cons number number) gnus-cache-active-hashtb) - ;; Update the lower or upper bound. - (if low - (setcar active number) - (setcdr active number))) - ;; Mark the active hashtb as altered. - (setq gnus-cache-active-altered t))) - -;;;###autoload -(defun gnus-cache-generate-active (&optional directory) - "Generate the cache active file." - (interactive) - (let* ((top (null directory)) - (directory (expand-file-name (or directory gnus-cache-directory))) - (files (directory-files directory 'full)) - (group - (if top - "" - (string-match - (concat "^" (regexp-quote - (file-name-as-directory - (expand-file-name gnus-cache-directory)))) - (directory-file-name directory)) - (nnheader-replace-chars-in-string - (substring (directory-file-name directory) (match-end 0)) - ?/ ?.))) - nums alphs) - (when top - (gnus-message 5 "Generating the cache active file...") - (setq gnus-cache-active-hashtb (gnus-make-hashtable 123))) - ;; Separate articles from all other files and directories. - (while files - (if (string-match "^[0-9]+$" (file-name-nondirectory (car files))) - (push (string-to-int (file-name-nondirectory (pop files))) nums) - (push (pop files) alphs))) - ;; If we have nums, then this is probably a valid group. - (when (setq nums (sort nums '<)) - (gnus-sethash group (cons (car nums) (gnus-last-element nums)) - gnus-cache-active-hashtb)) - ;; Go through all the other files. - (while alphs - (when (and (file-directory-p (car alphs)) - (not (string-match "^\\.\\.?$" - (file-name-nondirectory (car alphs))))) - ;; We descend directories. - (gnus-cache-generate-active (car alphs))) - (setq alphs (cdr alphs))) - ;; Write the new active file. - (when top - (gnus-cache-write-active t) - (gnus-message 5 "Generating the cache active file...done")))) - -;;;###autoload -(defun gnus-cache-generate-nov-databases (dir) - "Generate NOV files recursively starting in DIR." - (interactive (list gnus-cache-directory)) - (gnus-cache-close) - (let ((nnml-generate-active-function 'identity)) - (nnml-generate-nov-databases-1 dir))) - -(defun gnus-cache-move-cache (dir) - "Move the cache tree to somewhere else." - (interactive "FMove the cache tree to: ") - (rename-file gnus-cache-directory dir)) - -(provide 'gnus-cache) - -;;; gnus-cache.el ends here diff --git a/lisp/gnus-cite.el b/lisp/gnus-cite.el deleted file mode 100644 index 8866867..0000000 --- a/lisp/gnus-cite.el +++ /dev/null @@ -1,959 +0,0 @@ -;;; gnus-cite.el --- parse citations in articles for Gnus -;; Copyright (C) 1995,96,97,98 Free Software Foundation, Inc. - -;; Author: Per Abhiddenware; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 2, or (at your option) -;; any later version. - -;; GNU Emacs is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs; see the file COPYING. If not, write to the -;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. - -;;; Commentary: - -;;; Code: - -(eval-when-compile (require 'cl)) - -(require 'gnus) -(require 'gnus-art) -(require 'gnus-range) - -;;; Customization: - -(defgroup gnus-cite nil - "Citation." - :prefix "gnus-cite-" - :link '(custom-manual "(gnus)Article Highlighting") - :group 'gnus-article) - -(defcustom gnus-cite-reply-regexp - "^\\(Subject: Re\\|In-Reply-To\\|References\\):" - "*If headers match this regexp it is reasonable to believe that -article has citations." - :group 'gnus-cite - :type 'string) - -(defcustom gnus-cite-always-check nil - "Check article always for citations. Set it t to check all articles." - :group 'gnus-cite - :type '(choice (const :tag "no" nil) - (const :tag "yes" t))) - -(defcustom gnus-cited-opened-text-button-line-format "%(%{[-]%}%)\n" - "Format of opened cited text buttons." - :group 'gnus-cite - :type 'string) - -(defcustom gnus-cited-closed-text-button-line-format "%(%{[+]%}%)\n" - "Format of closed cited text buttons." - :group 'gnus-cite - :type 'string) - -(defcustom gnus-cited-lines-visible nil - "The number of lines of hidden cited text to remain visible." - :group 'gnus-cite - :type '(choice (const :tag "none" nil) - integer)) - -(defcustom gnus-cite-parse-max-size 25000 - "Maximum article size (in bytes) where parsing citations is allowed. -Set it to nil to parse all articles." - :group 'gnus-cite - :type '(choice (const :tag "all" nil) - integer)) - -(defcustom gnus-cite-prefix-regexp - "^[]>|:}+ ]*[]>|:}+]\\(.*>\\)?\\|^.*>" - "*Regexp matching the longest possible citation prefix on a line." - :group 'gnus-cite - :type 'regexp) - -(defcustom gnus-cite-max-prefix 20 - "Maximum possible length for a citation prefix." - :group 'gnus-cite - :type 'integer) - -(defcustom gnus-supercite-regexp - (concat "^\\(" gnus-cite-prefix-regexp "\\)? *" - ">>>>> +\"\\([^\"\n]+\\)\" +==") - "*Regexp matching normal Supercite attribution lines. -The first grouping must match prefixes added by other packages." - :group 'gnus-cite - :type 'regexp) - -(defcustom gnus-supercite-secondary-regexp "^.*\"\\([^\"\n]+\\)\" +==" - "Regexp matching mangled Supercite attribution lines. -The first regexp group should match the Supercite attribution." - :group 'gnus-cite - :type 'regexp) - -(defcustom gnus-cite-minimum-match-count 2 - "Minimum number of identical prefixes before we believe it's a citation." - :group 'gnus-cite - :type 'integer) - -(defcustom gnus-cite-attribution-prefix - "In article\\|in <\\|On \\(Mon\\|Tue\\|Wed\\|Thu\\|Fri\\|Sat\\|Sun\\)," - "*Regexp matching the beginning of an attribution line." - :group 'gnus-cite - :type 'regexp) - -(defcustom gnus-cite-attribution-suffix - "\\(\\(wrote\\|writes\\|said\\|says\\|>\\)\\(:\\|\\.\\.\\.\\)\\)[ \t]*$" - "*Regexp matching the end of an attribution line. -The text matching the first grouping will be used as a button." - :group 'gnus-cite - :type 'regexp) - -(defface gnus-cite-attribution-face '((t - (:italic t))) - "Face used for attribution lines.") - -(defcustom gnus-cite-attribution-face 'gnus-cite-attribution-face - "Face used for attribution lines. -It is merged with the face for the cited text belonging to the attribution." - :group 'gnus-cite - :type 'face) - -(defface gnus-cite-face-1 '((((class color) - (background dark)) - (:foreground "light blue")) - (((class color) - (background light)) - (:foreground "MidnightBlue")) - (t - (:italic t))) - "Citation face.") - -(defface gnus-cite-face-2 '((((class color) - (background dark)) - (:foreground "light cyan")) - (((class color) - (background light)) - (:foreground "firebrick")) - (t - (:italic t))) - "Citation face.") - -(defface gnus-cite-face-3 '((((class color) - (background dark)) - (:foreground "light yellow")) - (((class color) - (background light)) - (:foreground "dark green")) - (t - (:italic t))) - "Citation face.") - -(defface gnus-cite-face-4 '((((class color) - (background dark)) - (:foreground "light pink")) - (((class color) - (background light)) - (:foreground "OrangeRed")) - (t - (:italic t))) - "Citation face.") - -(defface gnus-cite-face-5 '((((class color) - (background dark)) - (:foreground "pale green")) - (((class color) - (background light)) - (:foreground "dark khaki")) - (t - (:italic t))) - "Citation face.") - -(defface gnus-cite-face-6 '((((class color) - (background dark)) - (:foreground "beige")) - (((class color) - (background light)) - (:foreground "dark violet")) - (t - (:italic t))) - "Citation face.") - -(defface gnus-cite-face-7 '((((class color) - (background dark)) - (:foreground "orange")) - (((class color) - (background light)) - (:foreground "SteelBlue4")) - (t - (:italic t))) - "Citation face.") - -(defface gnus-cite-face-8 '((((class color) - (background dark)) - (:foreground "magenta")) - (((class color) - (background light)) - (:foreground "magenta")) - (t - (:italic t))) - "Citation face.") - -(defface gnus-cite-face-9 '((((class color) - (background dark)) - (:foreground "violet")) - (((class color) - (background light)) - (:foreground "violet")) - (t - (:italic t))) - "Citation face.") - -(defface gnus-cite-face-10 '((((class color) - (background dark)) - (:foreground "medium purple")) - (((class color) - (background light)) - (:foreground "medium purple")) - (t - (:italic t))) - "Citation face.") - -(defface gnus-cite-face-11 '((((class color) - (background dark)) - (:foreground "turquoise")) - (((class color) - (background light)) - (:foreground "turquoise")) - (t - (:italic t))) - "Citation face.") - -(defcustom gnus-cite-face-list - '(gnus-cite-face-1 gnus-cite-face-2 gnus-cite-face-3 gnus-cite-face-4 - gnus-cite-face-5 gnus-cite-face-6 gnus-cite-face-7 gnus-cite-face-8 - gnus-cite-face-9 gnus-cite-face-10 gnus-cite-face-11) - "*List of faces used for highlighting citations. - -When there are citations from multiple articles in the same message, -Gnus will try to give each citation from each article its own face. -This should make it easier to see who wrote what." - :group 'gnus-cite - :type '(repeat face)) - -(defcustom gnus-cite-hide-percentage 50 - "Only hide excess citation if above this percentage of the body." - :group 'gnus-cite - :type 'number) - -(defcustom gnus-cite-hide-absolute 10 - "Only hide excess citation if above this number of lines in the body." - :group 'gnus-cite - :type 'integer) - -;;; Internal Variables: - -(defvar gnus-cite-article nil) -(defvar gnus-cite-overlay-list nil) - -(defvar gnus-cite-prefix-alist nil) -;; Alist of citation prefixes. -;; The cdr is a list of lines with that prefix. - -(defvar gnus-cite-attribution-alist nil) -;; Alist of attribution lines. -;; The car is a line number. -;; The cdr is the prefix for the citation started by that line. - -(defvar gnus-cite-loose-prefix-alist nil) -;; Alist of citation prefixes that have no matching attribution. -;; The cdr is a list of lines with that prefix. - -(defvar gnus-cite-loose-attribution-alist nil) -;; Alist of attribution lines that have no matching citation. -;; Each member has the form (WROTE IN PREFIX TAG), where -;; WROTE: is the attribution line number -;; IN: is the line number of the previous line if part of the same attribution, -;; PREFIX: Is the citation prefix of the attribution line(s), and -;; TAG: Is a Supercite tag, if any. - -(defvar gnus-cited-opened-text-button-line-format-alist - `((?b (marker-position beg) ?d) - (?e (marker-position end) ?d) - (?n (count-lines beg end) ?d) - (?l (- end beg) ?d))) -(defvar gnus-cited-opened-text-button-line-format-spec nil) -(defvar gnus-cited-closed-text-button-line-format-alist - gnus-cited-opened-text-button-line-format-alist) -(defvar gnus-cited-closed-text-button-line-format-spec nil) - - -;;; Commands: - -(defun gnus-article-highlight-citation (&optional force) - "Highlight cited text. -Each citation in the article will be highlighted with a different face. -The faces are taken from `gnus-cite-face-list'. -Attribution lines are highlighted with the same face as the -corresponding citation merged with `gnus-cite-attribution-face'. - -Text is considered cited if at least `gnus-cite-minimum-match-count' -lines matches `gnus-cite-prefix-regexp' with the same prefix. - -Lines matching `gnus-cite-attribution-suffix' and perhaps -`gnus-cite-attribution-prefix' are considered attribution lines." - (interactive (list 'force)) - (save-excursion - (set-buffer gnus-article-buffer) - (gnus-cite-parse-maybe force) - (let ((buffer-read-only nil) - (alist gnus-cite-prefix-alist) - (faces gnus-cite-face-list) - (inhibit-point-motion-hooks t) - face entry prefix skip numbers number face-alist) - ;; Loop through citation prefixes. - (while alist - (setq entry (car alist) - alist (cdr alist) - prefix (car entry) - numbers (cdr entry) - face (car faces) - faces (or (cdr faces) gnus-cite-face-list) - face-alist (cons (cons prefix face) face-alist)) - (while numbers - (setq number (car numbers) - numbers (cdr numbers)) - (and (not (assq number gnus-cite-attribution-alist)) - (not (assq number gnus-cite-loose-attribution-alist)) - (gnus-cite-add-face number prefix face)))) - ;; Loop through attribution lines. - (setq alist gnus-cite-attribution-alist) - (while alist - (setq entry (car alist) - alist (cdr alist) - number (car entry) - prefix (cdr entry) - skip (gnus-cite-find-prefix number) - face (cdr (assoc prefix face-alist))) - ;; Add attribution button. - (goto-line number) - (when (re-search-forward gnus-cite-attribution-suffix - (save-excursion (end-of-line 1) (point)) - t) - (gnus-article-add-button (match-beginning 1) (match-end 1) - 'gnus-cite-toggle prefix)) - ;; Highlight attribution line. - (gnus-cite-add-face number skip face) - (gnus-cite-add-face number skip gnus-cite-attribution-face)) - ;; Loop through attribution lines. - (setq alist gnus-cite-loose-attribution-alist) - (while alist - (setq entry (car alist) - alist (cdr alist) - number (car entry) - skip (gnus-cite-find-prefix number)) - (gnus-cite-add-face number skip gnus-cite-attribution-face))))) - -(defun gnus-dissect-cited-text () - "Dissect the article buffer looking for cited text." - (save-excursion - (set-buffer gnus-article-buffer) - (gnus-cite-parse-maybe) - (let ((alist gnus-cite-prefix-alist) - prefix numbers number marks m) - ;; Loop through citation prefixes. - (while alist - (setq numbers (pop alist) - prefix (pop numbers)) - (while numbers - (setq number (pop numbers)) - (goto-char (point-min)) - (forward-line number) - (push (cons (point-marker) "") marks) - (while (and numbers - (= (1- number) (car numbers))) - (setq number (pop numbers))) - (goto-char (point-min)) - (forward-line (1- number)) - (push (cons (point-marker) prefix) marks))) - ;; Skip to the beginning of the body. - (goto-char (point-min)) - (search-forward "\n\n" nil t) - (push (cons (point-marker) "") marks) - ;; Find the end of the body. - (goto-char (point-max)) - (gnus-article-search-signature) - (push (cons (point-marker) "") marks) - ;; Sort the marks. - (setq marks (sort marks 'car-less-than-car)) - (let ((omarks marks)) - (setq marks nil) - (while (cdr omarks) - (if (= (caar omarks) (caadr omarks)) - (progn - (unless (equal (cdar omarks) "") - (push (car omarks) marks)) - (unless (equal (cdadr omarks) "") - (push (cadr omarks) marks)) - (unless (and (equal (cdar omarks) "") - (equal (cdadr omarks) "") - (not (cddr omarks))) - (setq omarks (cdr omarks)))) - (push (car omarks) marks)) - (setq omarks (cdr omarks))) - (when (car omarks) - (push (car omarks) marks)) - (setq marks (setq m (nreverse marks))) - (while (cddr m) - (if (and (equal (cdadr m) "") - (equal (cdar m) (cdaddr m)) - (goto-char (caadr m)) - (forward-line 1) - (= (point) (caaddr m))) - (setcdr m (cdddr m)) - (setq m (cdr m)))) - marks)))) - -(defun gnus-article-fill-cited-article (&optional force width) - "Do word wrapping in the current article. -If WIDTH (the numerical prefix), use that text width when filling." - (interactive (list t current-prefix-arg)) - (save-excursion - (set-buffer gnus-article-buffer) - (let ((buffer-read-only nil) - (inhibit-point-motion-hooks t) - (marks (gnus-dissect-cited-text)) - (adaptive-fill-mode nil) - (filladapt-mode nil) - (fill-column (if width (prefix-numeric-value width) fill-column))) - (save-restriction - (while (cdr marks) - (widen) - (narrow-to-region (caar marks) (caadr marks)) - (let ((adaptive-fill-regexp - (concat "^" (regexp-quote (cdar marks)) " *")) - (fill-prefix (cdar marks))) - (fill-region (point-min) (point-max))) - (set-marker (caar marks) nil) - (setq marks (cdr marks))) - (when marks - (set-marker (caar marks) nil)) - ;; All this information is now incorrect. - (setq gnus-cite-prefix-alist nil - gnus-cite-attribution-alist nil - gnus-cite-loose-prefix-alist nil - gnus-cite-loose-attribution-alist nil - gnus-cite-article nil))))) - -(defun gnus-article-hide-citation (&optional arg force) - "Toggle hiding of all cited text except attribution lines. -See the documentation for `gnus-article-highlight-citation'. -If given a negative prefix, always show; if given a positive prefix, -always hide." - (interactive (append (gnus-article-hidden-arg) (list 'force))) - (gnus-set-format 'cited-opened-text-button t) - (gnus-set-format 'cited-closed-text-button t) - (save-excursion - (set-buffer gnus-article-buffer) - (cond - ((gnus-article-check-hidden-text 'cite arg) - t) - ((gnus-article-text-type-exists-p 'cite) - (let ((buffer-read-only nil)) - (gnus-article-hide-text-of-type 'cite))) - (t - (let ((buffer-read-only nil) - (marks (gnus-dissect-cited-text)) - (inhibit-point-motion-hooks t) - (props (nconc (list 'article-type 'cite) - gnus-hidden-properties)) - beg end start) - (while marks - (setq beg nil - end nil) - (while (and marks (string= (cdar marks) "")) - (setq marks (cdr marks))) - (when marks - (setq beg (caar marks))) - (while (and marks (not (string= (cdar marks) ""))) - (setq marks (cdr marks))) - (when marks - (setq end (caar marks))) - ;; Skip past lines we want to leave visible. - (when (and beg end gnus-cited-lines-visible) - (goto-char beg) - (forward-line gnus-cited-lines-visible) - (if (>= (point) end) - (setq beg nil) - (setq beg (point-marker)))) - (when (and beg end) - ;; We use markers for the end-points to facilitate later - ;; wrapping and mangling of text. - (setq beg (set-marker (make-marker) beg) - end (set-marker (make-marker) end)) - (gnus-add-text-properties beg end props) - (goto-char beg) - (unless (save-excursion (search-backward "\n\n" nil t)) - (insert "\n")) - (put-text-property - (setq start (point-marker)) - (progn - (gnus-article-add-button - (point) - (progn (eval gnus-cited-closed-text-button-line-format-spec) - (point)) - `gnus-article-toggle-cited-text - (list (cons beg end) start)) - (point)) - 'article-type 'annotation) - (set-marker beg (point))))))))) - -(defun gnus-article-toggle-cited-text (args) - "Toggle hiding the text in REGION." - (let* ((region (car args)) - (start (cadr args)) - (hidden - (text-property-any - (car region) (1- (cdr region)) - (car gnus-hidden-properties) (cadr gnus-hidden-properties))) - (inhibit-point-motion-hooks t) - buffer-read-only) - (funcall - (if hidden - 'remove-text-properties 'gnus-add-text-properties) - (car region) (cdr region) gnus-hidden-properties) - (save-excursion - (goto-char start) - (gnus-delete-line) - (put-text-property - (point) - (progn - (gnus-article-add-button - (point) - (progn (eval - (if hidden - gnus-cited-opened-text-button-line-format-spec - gnus-cited-closed-text-button-line-format-spec)) - (point)) - `gnus-article-toggle-cited-text - args) - (point)) - 'article-type 'annotation)))) - -(defun gnus-article-hide-citation-maybe (&optional arg force) - "Toggle hiding of cited text that has an attribution line. -If given a negative prefix, always show; if given a positive prefix, -always hide. -This will do nothing unless at least `gnus-cite-hide-percentage' -percent and at least `gnus-cite-hide-absolute' lines of the body is -cited text with attributions. When called interactively, these two -variables are ignored. -See also the documentation for `gnus-article-highlight-citation'." - (interactive (append (gnus-article-hidden-arg) '(force))) - (unless (gnus-article-check-hidden-text 'cite arg) - (save-excursion - (set-buffer gnus-article-buffer) - (gnus-cite-parse-maybe force) - (goto-char (point-min)) - (search-forward "\n\n" nil t) - (let ((start (point)) - (atts gnus-cite-attribution-alist) - (buffer-read-only nil) - (inhibit-point-motion-hooks t) - (hidden 0) - total) - (goto-char (point-max)) - (gnus-article-search-signature) - (setq total (count-lines start (point))) - (while atts - (setq hidden (+ hidden (length (cdr (assoc (cdar atts) - gnus-cite-prefix-alist)))) - atts (cdr atts))) - (when (or force - (and (> (* 100 hidden) (* gnus-cite-hide-percentage total)) - (> hidden gnus-cite-hide-absolute))) - (setq atts gnus-cite-attribution-alist) - (while atts - (setq total (cdr (assoc (cdar atts) gnus-cite-prefix-alist)) - atts (cdr atts)) - (while total - (setq hidden (car total) - total (cdr total)) - (goto-line hidden) - (unless (assq hidden gnus-cite-attribution-alist) - (gnus-add-text-properties - (point) (progn (forward-line 1) (point)) - (nconc (list 'article-type 'cite) - gnus-hidden-properties)))))))))) - -(defun gnus-article-hide-citation-in-followups () - "Hide cited text in non-root articles." - (interactive) - (save-excursion - (set-buffer gnus-article-buffer) - (let ((article (cdr gnus-article-current))) - (unless (save-excursion - (set-buffer gnus-summary-buffer) - (gnus-article-displayed-root-p article)) - (gnus-article-hide-citation))))) - -;;; Internal functions: - -(defun gnus-cite-parse-maybe (&optional force) - ;; Parse if the buffer has changes since last time. - (if (and (not force) - (equal gnus-cite-article gnus-article-current)) - () - (gnus-cite-localize) - ;;Reset parser information. - (setq gnus-cite-prefix-alist nil - gnus-cite-attribution-alist nil - gnus-cite-loose-prefix-alist nil - gnus-cite-loose-attribution-alist nil) - (while gnus-cite-overlay-list - (gnus-delete-overlay (pop gnus-cite-overlay-list))) - ;; Parse if not too large. - (if (and (not force) - gnus-cite-parse-max-size - (> (buffer-size) gnus-cite-parse-max-size)) - () - (setq gnus-cite-article (cons (car gnus-article-current) - (cdr gnus-article-current))) - (gnus-cite-parse-wrapper)))) - -(defun gnus-cite-parse-wrapper () - ;; Wrap chopped gnus-cite-parse - (goto-char (point-min)) - (unless (search-forward "\n\n" nil t) - (goto-char (point-max))) - (save-excursion - (gnus-cite-parse-attributions)) - ;; Try to avoid check citation if there is no reason to believe - ;; that article has citations - (if (or gnus-cite-always-check - (save-excursion - (re-search-backward gnus-cite-reply-regexp nil t)) - gnus-cite-loose-attribution-alist) - (progn (save-excursion - (gnus-cite-parse)) - (save-excursion - (gnus-cite-connect-attributions))))) - -(defun gnus-cite-parse () - ;; Parse and connect citation prefixes and attribution lines. - - ;; Parse current buffer searching for citation prefixes. - (let ((line (1+ (count-lines (point-min) (point)))) - (case-fold-search t) - (max (save-excursion - (goto-char (point-max)) - (gnus-article-search-signature) - (point))) - alist entry start begin end numbers prefix) - ;; Get all potential prefixes in `alist'. - (while (< (point) max) - ;; Each line. - (setq begin (point) - end (progn (beginning-of-line 2) (point)) - start end) - (goto-char begin) - ;; Ignore standard Supercite attribution prefix. - (when (looking-at gnus-supercite-regexp) - (if (match-end 1) - (setq end (1+ (match-end 1))) - (setq end (1+ begin)))) - ;; Ignore very long prefixes. - (when (> end (+ (point) gnus-cite-max-prefix)) - (setq end (+ (point) gnus-cite-max-prefix))) - (while (re-search-forward gnus-cite-prefix-regexp (1- end) t) - ;; Each prefix. - (setq end (match-end 0) - prefix (buffer-substring begin end)) - (gnus-set-text-properties 0 (length prefix) nil prefix) - (setq entry (assoc prefix alist)) - (if entry - (setcdr entry (cons line (cdr entry))) - (push (list prefix line) alist)) - (goto-char begin)) - (goto-char start) - (setq line (1+ line))) - ;; We got all the potential prefixes. Now create - ;; `gnus-cite-prefix-alist' containing the oldest prefix for each - ;; line that appears at least gnus-cite-minimum-match-count - ;; times. First sort them by length. Longer is older. - (setq alist (sort alist (lambda (a b) - (> (length (car a)) (length (car b)))))) - (while alist - (setq entry (car alist) - prefix (car entry) - numbers (cdr entry) - alist (cdr alist)) - (cond ((null numbers) - ;; No lines with this prefix that wasn't also part of - ;; a longer prefix. - ) - ((< (length numbers) gnus-cite-minimum-match-count) - ;; Too few lines with this prefix. We keep it a bit - ;; longer in case it is an exact match for an attribution - ;; line, but we don't remove the line from other - ;; prefixes. - (push entry gnus-cite-prefix-alist)) - (t - (push entry - gnus-cite-prefix-alist) - ;; Remove articles from other prefixes. - (let ((loop alist) - current) - (while loop - (setq current (car loop) - loop (cdr loop)) - (setcdr current - (gnus-set-difference (cdr current) numbers))))))))) - -(defun gnus-cite-parse-attributions () - (let (al-alist) - ;; Parse attributions - (while (re-search-forward gnus-cite-attribution-suffix (point-max) t) - (let* ((start (match-beginning 0)) - (end (match-end 0)) - (wrote (count-lines (point-min) end)) - (prefix (gnus-cite-find-prefix wrote)) - ;; Check previous line for an attribution leader. - (tag (progn - (beginning-of-line 1) - (when (looking-at gnus-supercite-secondary-regexp) - (buffer-substring (match-beginning 1) - (match-end 1))))) - (in (progn - (goto-char start) - (and (re-search-backward gnus-cite-attribution-prefix - (save-excursion - (beginning-of-line 0) - (point)) - t) - (not (re-search-forward gnus-cite-attribution-suffix - start t)) - (count-lines (point-min) (1+ (point))))))) - (when (eq wrote in) - (setq in nil)) - (goto-char end) - ;; don't add duplicates - (let ((al (buffer-substring (save-excursion (beginning-of-line 0) - (1+ (point))) - end))) - (if (not (assoc al al-alist)) - (progn - (push (list wrote in prefix tag) - gnus-cite-loose-attribution-alist) - (push (cons al t) al-alist)))))))) - -(defun gnus-cite-connect-attributions () - ;; Connect attributions to citations - - ;; No citations have been connected to attribution lines yet. - (setq gnus-cite-loose-prefix-alist (append gnus-cite-prefix-alist nil)) - - ;; Parse current buffer searching for attribution lines. - ;; Find exact supercite citations. - (gnus-cite-match-attributions 'small nil - (lambda (prefix tag) - (when tag - (concat "\\`" - (regexp-quote prefix) "[ \t]*" - (regexp-quote tag) ">")))) - ;; Find loose supercite citations after attributions. - (gnus-cite-match-attributions 'small t - (lambda (prefix tag) - (when tag - (concat "\\<" - (regexp-quote tag) - "\\>")))) - ;; Find loose supercite citations anywhere. - (gnus-cite-match-attributions 'small nil - (lambda (prefix tag) - (when tag - (concat "\\<" - (regexp-quote tag) - "\\>")))) - ;; Find nested citations after attributions. - (gnus-cite-match-attributions 'small-if-unique t - (lambda (prefix tag) - (concat "\\`" (regexp-quote prefix) ".+"))) - ;; Find nested citations anywhere. - (gnus-cite-match-attributions 'small nil - (lambda (prefix tag) - (concat "\\`" (regexp-quote prefix) ".+"))) - ;; Remove loose prefixes with too few lines. - (let ((alist gnus-cite-loose-prefix-alist) - entry) - (while alist - (setq entry (car alist) - alist (cdr alist)) - (when (< (length (cdr entry)) gnus-cite-minimum-match-count) - (setq gnus-cite-prefix-alist - (delq entry gnus-cite-prefix-alist) - gnus-cite-loose-prefix-alist - (delq entry gnus-cite-loose-prefix-alist))))) - ;; Find flat attributions. - (gnus-cite-match-attributions 'first t nil) - ;; Find any attributions (are we getting desperate yet?). - (gnus-cite-match-attributions 'first nil nil)) - -(defun gnus-cite-match-attributions (sort after fun) - ;; Match all loose attributions and citations (SORT AFTER FUN) . - ;; - ;; If SORT is `small', the citation with the shortest prefix will be - ;; used, if it is `first' the first prefix will be used, if it is - ;; `small-if-unique' the shortest prefix will be used if the - ;; attribution line does not share its own prefix with other - ;; loose attribution lines, otherwise the first prefix will be used. - ;; - ;; If AFTER is non-nil, only citations after the attribution line - ;; will be considered. - ;; - ;; If FUN is non-nil, it will be called with the arguments (WROTE - ;; PREFIX TAG) and expected to return a regular expression. Only - ;; citations whose prefix matches the regular expression will be - ;; considered. - ;; - ;; WROTE is the attribution line number. - ;; PREFIX is the attribution line prefix. - ;; TAG is the Supercite tag on the attribution line. - (let ((atts gnus-cite-loose-attribution-alist) - (case-fold-search t) - att wrote in prefix tag regexp limit smallest best size) - (while atts - (setq att (car atts) - atts (cdr atts) - wrote (nth 0 att) - in (nth 1 att) - prefix (nth 2 att) - tag (nth 3 att) - regexp (if fun (funcall fun prefix tag) "") - size (cond ((eq sort 'small) t) - ((eq sort 'first) nil) - (t (< (length (gnus-cite-find-loose prefix)) 2))) - limit (if after wrote -1) - smallest 1000000 - best nil) - (let ((cites gnus-cite-loose-prefix-alist) - cite candidate numbers first compare) - (while cites - (setq cite (car cites) - cites (cdr cites) - candidate (car cite) - numbers (cdr cite) - first (apply 'min numbers) - compare (if size (length candidate) first)) - (and (> first limit) - regexp - (string-match regexp candidate) - (< compare smallest) - (setq best cite - smallest compare)))) - (if (null best) - () - (setq gnus-cite-loose-attribution-alist - (delq att gnus-cite-loose-attribution-alist)) - (push (cons wrote (car best)) gnus-cite-attribution-alist) - (when in - (push (cons in (car best)) gnus-cite-attribution-alist)) - (when (memq best gnus-cite-loose-prefix-alist) - (let ((loop gnus-cite-prefix-alist) - (numbers (cdr best)) - current) - (setq gnus-cite-loose-prefix-alist - (delq best gnus-cite-loose-prefix-alist)) - (while loop - (setq current (car loop) - loop (cdr loop)) - (if (eq current best) - () - (setcdr current (gnus-set-difference (cdr current) numbers)) - (when (null (cdr current)) - (setq gnus-cite-loose-prefix-alist - (delq current gnus-cite-loose-prefix-alist) - atts (delq current atts))))))))))) - -(defun gnus-cite-find-loose (prefix) - ;; Return a list of loose attribution lines prefixed by PREFIX. - (let* ((atts gnus-cite-loose-attribution-alist) - att line lines) - (while atts - (setq att (car atts) - line (car att) - atts (cdr atts)) - (when (string-equal (gnus-cite-find-prefix line) prefix) - (push line lines))) - lines)) - -(defun gnus-cite-add-face (number prefix face) - ;; At line NUMBER, ignore PREFIX and add FACE to the rest of the line. - (when face - (let ((inhibit-point-motion-hooks t) - from to overlay) - (goto-line number) - (unless (eobp) ; Sometimes things become confused. - (forward-char (length prefix)) - (skip-chars-forward " \t") - (setq from (point)) - (end-of-line 1) - (skip-chars-backward " \t") - (setq to (point)) - (when (< from to) - (push (setq overlay (gnus-make-overlay from to)) - gnus-cite-overlay-list) - (gnus-overlay-put overlay 'face face)))))) - -(defun gnus-cite-toggle (prefix) - (save-excursion - (set-buffer gnus-article-buffer) - (gnus-cite-parse-maybe) - (let ((buffer-read-only nil) - (numbers (cdr (assoc prefix gnus-cite-prefix-alist))) - (inhibit-point-motion-hooks t) - number) - (while numbers - (setq number (car numbers) - numbers (cdr numbers)) - (goto-line number) - (cond ((get-text-property (point) 'invisible) - (remove-text-properties (point) (progn (forward-line 1) (point)) - gnus-hidden-properties)) - ((assq number gnus-cite-attribution-alist)) - (t - (gnus-add-text-properties - (point) (progn (forward-line 1) (point)) - (nconc (list 'article-type 'cite) - gnus-hidden-properties)))))))) - -(defun gnus-cite-find-prefix (line) - ;; Return citation prefix for LINE. - (let ((alist gnus-cite-prefix-alist) - (prefix "") - entry) - (while alist - (setq entry (car alist) - alist (cdr alist)) - (when (memq line (cdr entry)) - (setq prefix (car entry)))) - prefix)) - -(defun gnus-cite-localize () - "Make the citation variables local to the article buffer." - (let ((vars '(gnus-cite-article - gnus-cite-overlay-list gnus-cite-prefix-alist - gnus-cite-attribution-alist gnus-cite-loose-prefix-alist - gnus-cite-loose-attribution-alist))) - (while vars - (make-local-variable (pop vars))))) - -(gnus-ems-redefine) - -(provide 'gnus-cite) - -;;; gnus-cite.el ends here diff --git a/lisp/gnus-cus.el b/lisp/gnus-cus.el deleted file mode 100644 index 025273b..0000000 --- a/lisp/gnus-cus.el +++ /dev/null @@ -1,652 +0,0 @@ -;;; gnus-cus.el --- customization commands for Gnus -;; -;; Copyright (C) 1996 Free Software Foundation, Inc. - -;; Author: Per Abrahamsen -;; Keywords: news - -;; This file is part of GNU Emacs. - -;; GNU Emacs is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 2, or (at your option) -;; any later version. - -;; GNU Emacs is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs; see the file COPYING. If not, write to the -;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. - -;;; Commentary: - -;;; Code: - -(require 'wid-edit) -(require 'gnus-score) - -;;; Widgets: - -;; There should be special validation for this. -(define-widget 'gnus-email-address 'string - "An email address") - -(defun gnus-custom-mode () - "Major mode for editing Gnus customization buffers. - -The following commands are available: - -\\[widget-forward] Move to next button or editable field. -\\[widget-backward] Move to previous button or editable field. -\\[widget-button-click] Activate button under the mouse pointer. -\\[widget-button-press] Activate button under point. - -Entry to this mode calls the value of `gnus-custom-mode-hook' -if that value is non-nil." - (kill-all-local-variables) - (setq major-mode 'gnus-custom-mode - mode-name "Gnus Customize") - (use-local-map widget-keymap) - (gnus-run-hooks 'gnus-custom-mode-hook)) - -;;; Group Customization: - -(defconst gnus-group-parameters - '((to-address (gnus-email-address :tag "To Address") "\ -This will be used when doing followups and posts. - -This is primarily useful in mail groups that represent closed -mailing lists--mailing lists where it's expected that everybody that -writes to the mailing list is subscribed to it. Since using this -parameter ensures that the mail only goes to the mailing list itself, -it means that members won't receive two copies of your followups. - -Using `to-address' will actually work whether the group is foreign or -not. Let's say there's a group on the server that is called -`fa.4ad-l'. This is a real newsgroup, but the server has gotten the -articles from a mail-to-news gateway. Posting directly to this group -is therefore impossible--you have to send mail to the mailing list -address instead.") - - (to-list (gnus-email-address :tag "To List") "\ -This address will be used when doing a `a' in the group. - -It is totally ignored when doing a followup--except that if it is -present in a news group, you'll get mail group semantics when doing -`f'.") - - (broken-reply-to (const :tag "Broken Reply To" t) "\ -Ignore `Reply-To' headers in this group. - -That can be useful if you're reading a mailing list group where the -listserv has inserted `Reply-To' headers that point back to the -listserv itself. This is broken behavior. So there!") - - (to-group (string :tag "To Group") "\ -All posts will be send to the specified group.") - - (gcc-self (choice :tag "GCC" - :value t - (const t) - (const none) - (string :format "%v" :hide-front-space t)) "\ -Specify default value for GCC header. - -If this symbol is present in the group parameter list and set to `t', -new composed messages will be `Gcc''d to the current group. If it is -present and set to `none', no `Gcc:' header will be generated, if it -is present and a string, this string will be inserted literally as a -`gcc' header (this symbol takes precedence over any default `Gcc' -rules as described later).") - - (auto-expire (const :tag "Automatic Expire" t) "\ -All articles that are read will be marked as expirable.") - - (total-expire (const :tag "Total Expire" t) "\ -All read articles will be put through the expiry process - -This happens even if they are not marked as expirable. -Use with caution.") - - (expiry-wait (choice :tag "Expire Wait" - :value never - (const never) - (const immediate) - (number :hide-front-space t - :format "%v")) "\ -When to expire. - -Overrides any `nnmail-expiry-wait' and `nnmail-expiry-wait-function' -when expiring expirable messages. The value can either be a number of -days (not necessarily an integer) or the symbols `never' or -`immediate'.") - - (score-file (file :tag "Score File") "\ -Make the specified file into the current score file. -This means that all score commands you issue will end up in this file.") - - (adapt-file (file :tag "Adapt File") "\ -Make the specified file into the current adaptive file. -All adaptive score entries will be put into this file.") - - (admin-address (gnus-email-address :tag "Admin Address") "\ -Administration address for a mailing list. - -When unsubscribing to a mailing list you should never send the -unsubscription notice to the mailing list itself. Instead, you'd -send messages to the administrative address. This parameter allows -you to put the admin address somewhere convenient.") - - (display (choice :tag "Display" - :value default - (const all) - (const default)) "\ -Which articles to display on entering the group. - -`all' - Display all articles, both read and unread. - -`default' - Display the default visible articles, which normally includes - unread and ticked articles.") - - (comment (string :tag "Comment") "\ -An arbitrary comment on the group.") - - (visible (const :tag "Permanently visible" t) "\ -Always display this group, even when there are no unread articles -in it..")) - "Alist of valid group parameters. - -Each entry has the form (NAME TYPE DOC), where NAME is the parameter -itself (a symbol), TYPE is the parameters type (a sexp widget), and -DOC is a documentation string for the parameter.") - -(defvar gnus-custom-params) -(defvar gnus-custom-method) -(defvar gnus-custom-group) - -(defun gnus-group-customize (group) - "Edit the group on the current line." - (interactive (list (gnus-group-group-name))) - (let (info - (types (mapcar (lambda (entry) - `(cons :format "%v%h\n" - :doc ,(nth 2 entry) - (const :format "" ,(nth 0 entry)) - ,(nth 1 entry))) - gnus-group-parameters))) - (unless group - (error "No group on current line")) - (unless (setq info (gnus-get-info group)) - (error "Killed group; can't be edited")) - ;; Ready. - (kill-buffer (gnus-get-buffer-create "*Gnus Customize*")) - (switch-to-buffer (gnus-get-buffer-create "*Gnus Customize*")) - (gnus-custom-mode) - (make-local-variable 'gnus-custom-group) - (setq gnus-custom-group group) - (widget-insert "Customize the ") - (widget-create 'info-link - :help-echo "Push me to learn more." - :tag "group parameters" - "(gnus)Group Parameters") - (widget-insert " for <") - (widget-insert group) - (widget-insert "> and press ") - (widget-create 'push-button - :tag "done" - :help-echo "Push me when done customizing." - :action 'gnus-group-customize-done) - (widget-insert ".\n\n") - (make-local-variable 'gnus-custom-params) - (setq gnus-custom-params - (widget-create 'group - :value (gnus-info-params info) - `(set :inline t - :greedy t - :tag "Parameters" - :format "%t:\n%h%v" - :doc "\ -These special paramerters are recognized by Gnus. -Check the [ ] for the parameters you want to apply to this group, then -edit the value to suit your taste." - ,@types) - '(repeat :inline t - :tag "Variables" - :format "%t:\n%h%v%i\n\n" - :doc "\ -Set variables local to the group you are entering. - -If you want to turn threading off in `news.answers', you could put -`(gnus-show-threads nil)' in the group parameters of that group. -`gnus-show-threads' will be made into a local variable in the summary -buffer you enter, and the form `nil' will be `eval'ed there. - -This can also be used as a group-specific hook function, if you'd -like. If you want to hear a beep when you enter a group, you could -put something like `(dummy-variable (ding))' in the parameters of that -group. `dummy-variable' will be set to the result of the `(ding)' -form, but who cares?" - (group :value (nil nil) - (symbol :tag "Variable") - (sexp :tag - "Value"))) - - '(repeat :inline t - :tag "Unknown entries" - sexp))) - (widget-insert "\n\nYou can also edit the ") - (widget-create 'info-link - :tag "select method" - :help-echo "Push me to learn more about select methods." - "(gnus)Select Methods") - (widget-insert " for the group.\n") - (setq gnus-custom-method - (widget-create 'sexp - :tag "Method" - :value (gnus-info-method info))) - (use-local-map widget-keymap) - (widget-setup))) - -(defun gnus-group-customize-done (&rest ignore) - "Apply changes and bury the buffer." - (interactive) - (gnus-group-edit-group-done 'params gnus-custom-group - (widget-value gnus-custom-params)) - (gnus-group-edit-group-done 'method gnus-custom-group - (widget-value gnus-custom-method)) - (bury-buffer)) - -;;; Score Customization: - -(defconst gnus-score-parameters - '((mark (number :tag "Mark") "\ -The value of this entry should be a number. -Any articles with a score lower than this number will be marked as read.") - - (expunge (number :tag "Expunge") "\ -The value of this entry should be a number. -Any articles with a score lower than this number will be removed from -the summary buffer.") - - (mark-and-expunge (number :tag "Mark-and-expunge") "\ -The value of this entry should be a number. -Any articles with a score lower than this number will be marked as -read and removed from the summary buffer.") - - (thread-mark-and-expunge (number :tag "Thread-mark-and-expunge") "\ -The value of this entry should be a number. -All articles that belong to a thread that has a total score below this -number will be marked as read and removed from the summary buffer. -`gnus-thread-score-function' says how to compute the total score -for a thread.") - - (files (repeat :inline t :tag "Files" file) "\ -The value of this entry should be any number of file names. -These files are assumed to be score files as well, and will be loaded -the same way this one was.") - - (exclude-files (repeat :inline t :tag "Exclude-files" file) "\ -The clue of this entry should be any number of files. -These files will not be loaded, even though they would normally be so, -for some reason or other.") - - (eval (sexp :tag "Eval" :value nil) "\ -The value of this entry will be `eval'el. -This element will be ignored when handling global score files.") - - (read-only (boolean :tag "Read-only" :value t) "\ -Read-only score files will not be updated or saved. -Global score files should feature this atom.") - - (orphan (number :tag "Orphan") "\ -The value of this entry should be a number. -Articles that do not have parents will get this number added to their -scores. Imagine you follow some high-volume newsgroup, like -`comp.lang.c'. Most likely you will only follow a few of the threads, -also want to see any new threads. - -You can do this with the following two score file entries: - - (orphan -500) - (mark-and-expunge -100) - -When you enter the group the first time, you will only see the new -threads. You then raise the score of the threads that you find -interesting (with `I T' or `I S'), and ignore (`C y') the rest. -Next time you enter the group, you will see new articles in the -interesting threads, plus any new threads. - -I.e.---the orphan score atom is for high-volume groups where there -exist a few interesting threads which can't be found automatically -by ordinary scoring rules.") - - (adapt (choice :tag "Adapt" - (const t) - (const ignore) - (sexp :format "%v" - :hide-front-space t)) "\ -This entry controls the adaptive scoring. -If it is `t', the default adaptive scoring rules will be used. If it -is `ignore', no adaptive scoring will be performed on this group. If -it is a list, this list will be used as the adaptive scoring rules. -If it isn't present, or is something other than `t' or `ignore', the -default adaptive scoring rules will be used. If you want to use -adaptive scoring on most groups, you'd set `gnus-use-adaptive-scoring' -to `t', and insert an `(adapt ignore)' in the groups where you do not -want adaptive scoring. If you only want adaptive scoring in a few -groups, you'd set `gnus-use-adaptive-scoring' to `nil', and insert -`(adapt t)' in the score files of the groups where you want it.") - - (adapt-file (file :tag "Adapt-file") "\ -All adaptive score entries will go to the file named by this entry. -It will also be applied when entering the group. This atom might -be handy if you want to adapt on several groups at once, using the -same adaptive file for a number of groups.") - - (local (repeat :tag "Local" - (group :value (nil nil) - (symbol :tag "Variable") - (sexp :tag "Value"))) "\ -The value of this entry should be a list of `(VAR VALUE)' pairs. -Each VAR will be made buffer-local to the current summary buffer, -and set to the value specified. This is a convenient, if somewhat -strange, way of setting variables in some groups if you don't like -hooks much.") - (touched (sexp :format "Touched\n") "Internal variable.")) - "Alist of valid symbolic score parameters. - -Each entry has the form (NAME TYPE DOC), where NAME is the parameter -itself (a symbol), TYPE is the parameters type (a sexp widget), and DOC is a -documentation string for the parameter.") - -(define-widget 'gnus-score-string 'group - "Edit score entries for string-valued headers." - :convert-widget 'gnus-score-string-convert) - -(defun gnus-score-string-convert (widget) - ;; Set args appropriately. - (let* ((tag (widget-get widget :tag)) - (item `(const :format "" :value ,(downcase tag))) - (match '(string :tag "Match")) - (score '(choice :tag "Score" - (const :tag "default" nil) - (integer :format "%v" - :hide-front-space t))) - (expire '(choice :tag "Expire" - (const :tag "off" nil) - (integer :format "%v" - :hide-front-space t))) - (type '(choice :tag "Type" - :value s - ;; I should really create a forgiving :match - ;; function for each type below, that only - ;; looked at the first letter. - (const :tag "Regexp" r) - (const :tag "Regexp (fixed case)" R) - (const :tag "Substring" s) - (const :tag "Substring (fixed case)" S) - (const :tag "Exact" e) - (const :tag "Exact (fixed case)" E) - (const :tag "Word" w) - (const :tag "Word (fixed case)" W) - (const :tag "default" nil))) - (group `(group ,match ,score ,expire ,type)) - (doc (concat (or (widget-get widget :doc) - (concat "Change score based on the " tag - " header.\n")) - " -You can have an arbitrary number of score entries for this header, -each score entry has four elements: - -1. The \"match element\". This should be the string to look for in the - header. - -2. The \"score element\". This number should be an integer in the - neginf to posinf interval. This number is added to the score - of the article if the match is successful. If this element is - not present, the `gnus-score-interactive-default-score' number - will be used instead. This is 1000 by default. - -3. The \"date element\". This date says when the last time this score - entry matched, which provides a mechanism for expiring the - score entries. It this element is not present, the score - entry is permanent. The date is represented by the number of - days since December 31, 1 ce. - -4. The \"type element\". This element specifies what function should - be used to see whether this score entry matches the article. - - There are the regexp, as well as substring types, and exact match, - and word match types. If this element is not present, Gnus will - assume that substring matching should be used. There is case - sensitive variants of all match types."))) - (widget-put widget :args `(,item - (repeat :inline t - :indent 0 - :tag ,tag - :doc ,doc - :format "%t:\n%h%v%i\n\n" - (choice :format "%v" - :value ("" nil nil s) - ,group - sexp))))) - widget) - -(define-widget 'gnus-score-integer 'group - "Edit score entries for integer-valued headers." - :convert-widget 'gnus-score-integer-convert) - -(defun gnus-score-integer-convert (widget) - ;; Set args appropriately. - (let* ((tag (widget-get widget :tag)) - (item `(const :format "" :value ,(downcase tag))) - (match '(integer :tag "Match")) - (score '(choice :tag "Score" - (const :tag "default" nil) - (integer :format "%v" - :hide-front-space t))) - (expire '(choice :tag "Expire" - (const :tag "off" nil) - (integer :format "%v" - :hide-front-space t))) - (type '(choice :tag "Type" - :value < - (const <) - (const >) - (const =) - (const >=) - (const <=))) - (group `(group ,match ,score ,expire ,type)) - (doc (concat (or (widget-get widget :doc) - (concat "Change score based on the " tag - " header."))))) - (widget-put widget :args `(,item - (repeat :inline t - :indent 0 - :tag ,tag - :doc ,doc - :format "%t:\n%h%v%i\n\n" - ,group)))) - widget) - -(define-widget 'gnus-score-date 'group - "Edit score entries for date-valued headers." - :convert-widget 'gnus-score-date-convert) - -(defun gnus-score-date-convert (widget) - ;; Set args appropriately. - (let* ((tag (widget-get widget :tag)) - (item `(const :format "" :value ,(downcase tag))) - (match '(string :tag "Match")) - (score '(choice :tag "Score" - (const :tag "default" nil) - (integer :format "%v" - :hide-front-space t))) - (expire '(choice :tag "Expire" - (const :tag "off" nil) - (integer :format "%v" - :hide-front-space t))) - (type '(choice :tag "Type" - :value regexp - (const regexp) - (const before) - (const at) - (const after))) - (group `(group ,match ,score ,expire ,type)) - (doc (concat (or (widget-get widget :doc) - (concat "Change score based on the " tag - " header.")) - " -For the Date header we have three kinda silly match types: `before', -`at' and `after'. I can't really imagine this ever being useful, but, -like, it would feel kinda silly not to provide this function. Just in -case. You never know. Better safe than sorry. Once burnt, twice -shy. Don't judge a book by its cover. Never not have sex on a first -date. (I have been told that at least one person, and I quote, -\"found this function indispensable\", however.) - -A more useful match type is `regexp'. With it, you can match the date -string using a regular expression. The date is normalized to ISO8601 -compact format first---`YYYYMMDDTHHMMSS'. If you want to match all -articles that have been posted on April 1st in every year, you could -use `....0401.........' as a match string, for instance. (Note that -the date is kept in its original time zone, so this will match -articles that were posted when it was April 1st where the article was -posted from. Time zones are such wholesome fun for the whole family, -eh?"))) - (widget-put widget :args `(,item - (repeat :inline t - :indent 0 - :tag ,tag - :doc ,doc - :format "%t:\n%h%v%i\n\n" - ,group)))) - widget) - -(defvar gnus-custom-scores) -(defvar gnus-custom-score-alist) - -(defun gnus-score-customize (file) - "Customize score file FILE." - (interactive (list gnus-current-score-file)) - (let ((scores (gnus-score-load file)) - (types (mapcar (lambda (entry) - `(group :format "%v%h\n" - :doc ,(nth 2 entry) - (const :format "" ,(nth 0 entry)) - ,(nth 1 entry))) - gnus-score-parameters))) - ;; Ready. - (kill-buffer (gnus-get-buffer-create "*Gnus Customize*")) - (switch-to-buffer (gnus-get-buffer-create "*Gnus Customize*")) - (gnus-custom-mode) - (make-local-variable 'gnus-custom-score-alist) - (setq gnus-custom-score-alist scores) - (widget-insert "Customize the ") - (widget-create 'info-link - :help-echo "Push me to learn more." - :tag "score entries" - "(gnus)Score File Format") - (widget-insert " for\n\t") - (widget-insert file) - (widget-insert "\nand press ") - (widget-create 'push-button - :tag "done" - :help-echo "Push me when done customizing." - :action 'gnus-score-customize-done) - (widget-insert ".\n -Check the [ ] for the entries you want to apply to this score file, then -edit the value to suit your taste. Don't forget to mark the checkbox, -if you do all your changes will be lost. ") - (widget-create 'push-button - :action (lambda (&rest ignore) - (require 'gnus-audio) - (gnus-audio-play "Evil_Laugh.au")) - "Bhahahah!") - (widget-insert "\n\n") - (make-local-variable 'gnus-custom-scores) - (setq gnus-custom-scores - (widget-create 'group - :value scores - `(checklist :inline t - :greedy t - (gnus-score-string :tag "From") - (gnus-score-string :tag "Subject") - (gnus-score-string :tag "References") - (gnus-score-string :tag "Xref") - (gnus-score-string :tag "Message-ID") - (gnus-score-integer :tag "Lines") - (gnus-score-integer :tag "Chars") - (gnus-score-date :tag "Date") - (gnus-score-string :tag "Head" - :doc "\ -Match all headers in the article. - -Using one of `Head', `Body', `All' will slow down scoring considerable. -") - (gnus-score-string :tag "Body" - :doc "\ -Match the body sans header of the article. - -Using one of `Head', `Body', `All' will slow down scoring considerable. -") - (gnus-score-string :tag "All" - :doc "\ -Match the entire article, including both headers and body. - -Using one of `Head', `Body', `All' will slow down scoring -considerable. -") - (gnus-score-string :tag - "Followup" - :doc "\ -Score all followups to the specified authors. - -This entry is somewhat special, in that it will match the `From:' -header, and affect the score of not only the matching articles, but -also all followups to the matching articles. This allows you -e.g. increase the score of followups to your own articles, or decrease -the score of followups to the articles of some known trouble-maker. -") - (gnus-score-string :tag "Thread" - :doc "\ -Add a score entry on all articles that are part of a thread. - -This match key works along the same lines as the `Followup' match key. -If you say that you want to score on a (sub-)thread that is started by -an article with a `Message-ID' X, then you add a `thread' match. This -will add a new `thread' match for each article that has X in its -`References' header. (These new `thread' matches will use the -`Message-ID's of these matching articles.) This will ensure that you -can raise/lower the score of an entire thread, even though some -articles in the thread may not have complete `References' headers. -Note that using this may lead to undeterministic scores of the -articles in the thread. -") - ,@types) - '(repeat :inline t - :tag "Unknown entries" - sexp))) - (use-local-map widget-keymap) - (widget-setup))) - -(defun gnus-score-customize-done (&rest ignore) - "Reset the score alist with the present value." - (let ((alist gnus-custom-score-alist) - (value (widget-value gnus-custom-scores))) - (setcar alist (car value)) - (setcdr alist (cdr value)) - (gnus-score-set 'touched '(t) alist)) - (bury-buffer)) - -;;; The End: - -(provide 'gnus-cus) - -;;; gnus-cus.el ends here diff --git a/lisp/gnus-demon.el b/lisp/gnus-demon.el deleted file mode 100644 index 0015a90..0000000 --- a/lisp/gnus-demon.el +++ /dev/null @@ -1,326 +0,0 @@ -;;; gnus-demon.el --- daemonic Gnus behaviour -;; Copyright (C) 1995,96,97,98 Free Software Foundation, Inc. - -;; Author: Lars Magne Ingebrigtsen -;; Keywords: news - -;; This file is part of GNU Emacs. - -;; GNU Emacs is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 2, or (at your option) -;; any later version. - -;; GNU Emacs is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs; see the file COPYING. If not, write to the -;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. - -;;; Commentary: - -;;; Code: - -(eval-when-compile (require 'cl)) - -(require 'gnus) -(require 'gnus-int) -(require 'nnheader) -(require 'nntp) -(require 'nnmail) -(require 'gnus-util) -(eval-and-compile - (if (string-match "XEmacs" (emacs-version)) - (require 'itimer) - (require 'timer))) - -(defgroup gnus-demon nil - "Demonic behaviour." - :group 'gnus) - -(defcustom gnus-demon-handlers nil - "Alist of daemonic handlers to be run at intervals. -Each handler is a list on the form - -\(FUNCTION TIME IDLE) - -FUNCTION is the function to be called. -TIME is the number of `gnus-demon-timestep's between each call. -If nil, never call. If t, call each `gnus-demon-timestep'. -If IDLE is t, only call if Emacs has been idle for a while. If IDLE -is a number, only call when Emacs has been idle more than this number -of `gnus-demon-timestep's. If IDLE is nil, don't care about -idleness. If IDLE is a number and TIME is nil, then call once each -time Emacs has been idle for IDLE `gnus-demon-timestep's." - :group 'gnus-demon - :type '(repeat (list function - (choice :tag "Time" - (const :tag "never" nil) - (const :tag "one" t) - (integer :tag "steps" 1)) - (choice :tag "Idle" - (const :tag "don't care" nil) - (const :tag "for a while" t) - (integer :tag "steps" 1))))) - -(defcustom gnus-demon-timestep 60 - "*Number of seconds in each demon timestep." - :group 'gnus-demon - :type 'integer) - -;;; Internal variables. - -(defvar gnus-demon-timer nil) -(defvar gnus-demon-idle-has-been-called nil) -(defvar gnus-demon-idle-time 0) -(defvar gnus-demon-handler-state nil) -(defvar gnus-demon-last-keys nil) -(defvar gnus-inhibit-demon nil - "*If non-nil, no daemonic function will be run.") - -(eval-and-compile - (autoload 'timezone-parse-date "timezone") - (autoload 'timezone-make-arpa-date "timezone")) - -;;; Functions. - -(defun gnus-demon-add-handler (function time idle) - "Add the handler FUNCTION to be run at TIME and IDLE." - ;; First remove any old handlers that use this function. - (gnus-demon-remove-handler function) - ;; Then add the new one. - (push (list function time idle) gnus-demon-handlers) - (gnus-demon-init)) - -(defun gnus-demon-remove-handler (function &optional no-init) - "Remove the handler FUNCTION from the list of handlers." - (gnus-pull function gnus-demon-handlers) - (unless no-init - (gnus-demon-init))) - -(defun gnus-demon-init () - "Initialize the Gnus daemon." - (interactive) - (gnus-demon-cancel) - (when gnus-demon-handlers - ;; Set up the timer. - (setq gnus-demon-timer - (nnheader-run-at-time - gnus-demon-timestep gnus-demon-timestep 'gnus-demon)) - ;; Reset control variables. - (setq gnus-demon-handler-state - (mapcar - (lambda (handler) - (list (car handler) (gnus-demon-time-to-step (nth 1 handler)) - (nth 2 handler))) - gnus-demon-handlers)) - (setq gnus-demon-idle-time 0) - (setq gnus-demon-idle-has-been-called nil) - (setq gnus-use-demon t))) - -(gnus-add-shutdown 'gnus-demon-cancel 'gnus) - -(defun gnus-demon-cancel () - "Cancel any Gnus daemons." - (interactive) - (when gnus-demon-timer - (nnheader-cancel-timer gnus-demon-timer)) - (setq gnus-demon-timer nil - gnus-use-demon nil - gnus-demon-idle-has-been-called nil) - (condition-case () - (nnheader-cancel-function-timers 'gnus-demon) - (error t))) - -(defun gnus-demon-is-idle-p () - "Whether Emacs is idle or not." - ;; We do this simply by comparing the 100 most recent keystrokes - ;; with the ones we had last time. If they are the same, one might - ;; guess that Emacs is indeed idle. This only makes sense if one - ;; calls this function seldom -- like once a minute, which is what - ;; we do here. - (let ((keys (recent-keys))) - (or (equal keys gnus-demon-last-keys) - (progn - (setq gnus-demon-last-keys keys) - nil)))) - -(defun gnus-demon-time-to-step (time) - "Find out how many seconds to TIME, which is on the form \"17:43\"." - (if (not (stringp time)) - time - (let* ((now (current-time)) - ;; obtain NOW as discrete components -- make a vector for speed - (nowParts (apply 'vector (decode-time now))) - ;; obtain THEN as discrete components - (thenParts (timezone-parse-time time)) - (thenHour (string-to-int (elt thenParts 0))) - (thenMin (string-to-int (elt thenParts 1))) - ;; convert time as elements into number of seconds since EPOCH. - (then (encode-time 0 - thenMin - thenHour - ;; If THEN is earlier than NOW, make it - ;; same time tomorrow. Doc for encode-time - ;; says that this is OK. - (+ (elt nowParts 3) - (if (or (< thenHour (elt nowParts 2)) - (and (= thenHour (elt nowParts 2)) - (<= thenMin (elt nowParts 1)))) - 1 0)) - (elt nowParts 4) - (elt nowParts 5) - (elt nowParts 6) - (elt nowParts 7) - (elt nowParts 8))) - ;; calculate number of seconds between NOW and THEN - (diff (+ (* 65536 (- (car then) (car now))) - (- (cadr then) (cadr now))))) - ;; return number of timesteps in the number of seconds - (round (/ diff gnus-demon-timestep))))) - -(defun gnus-demon () - "The Gnus daemon that takes care of running all Gnus handlers." - ;; Increase or reset the time Emacs has been idle. - (if (gnus-demon-is-idle-p) - (incf gnus-demon-idle-time) - (setq gnus-demon-idle-time 0) - (setq gnus-demon-idle-has-been-called nil)) - ;; Disable all daemonic stuff if we're in the minibuffer - (when (and (not (window-minibuffer-p (selected-window))) - (not gnus-inhibit-demon)) - ;; Then we go through all the handler and call those that are - ;; sufficiently ripe. - (let ((handlers gnus-demon-handler-state) - (gnus-inhibit-demon t) - handler time idle) - (while handlers - (setq handler (pop handlers)) - (cond - ((numberp (setq time (nth 1 handler))) - ;; These handlers use a regular timeout mechanism. We decrease - ;; the timer if it hasn't reached zero yet. - (unless (zerop time) - (setcar (nthcdr 1 handler) (decf time))) - (and (zerop time) ; If the timer now is zero... - ;; Test for appropriate idleness - (progn - (setq idle (nth 2 handler)) - (cond - ((null idle) t) ; Don't care about idle. - ((numberp idle) ; Numerical idle... - (< idle gnus-demon-idle-time)) ; Idle timed out. - (t (< 0 gnus-demon-idle-time)))) ; Or just need to be idle. - ;; So we call the handler. - (progn - (ignore-errors (funcall (car handler))) - ;; And reset the timer. - (setcar (nthcdr 1 handler) - (gnus-demon-time-to-step - (nth 1 (assq (car handler) gnus-demon-handlers))))))) - ;; These are only supposed to be called when Emacs is idle. - ((null (setq idle (nth 2 handler))) - ;; We do nothing. - ) - ((and (not (numberp idle)) - (gnus-demon-is-idle-p)) - ;; We want to call this handler each and every time that - ;; Emacs is idle. - (ignore-errors (funcall (car handler)))) - (t - ;; We want to call this handler only if Emacs has been idle - ;; for a specified number of timesteps. - (and (not (memq (car handler) gnus-demon-idle-has-been-called)) - (< idle gnus-demon-idle-time) - (gnus-demon-is-idle-p) - (progn - (ignore-errors (funcall (car handler))) - ;; Make sure the handler won't be called once more in - ;; this idle-cycle. - (push (car handler) gnus-demon-idle-has-been-called))))))))) - -(defun gnus-demon-add-nocem () - "Add daemonic NoCeM handling to Gnus." - (gnus-demon-add-handler 'gnus-demon-scan-nocem 60 30)) - -(defun gnus-demon-scan-nocem () - "Scan NoCeM groups for NoCeM messages." - (save-window-excursion - (gnus-nocem-scan-groups))) - -(defun gnus-demon-add-disconnection () - "Add daemonic server disconnection to Gnus." - (gnus-demon-add-handler 'gnus-demon-close-connections nil 30)) - -(defun gnus-demon-close-connections () - (save-window-excursion - (gnus-close-backends))) - -(defun gnus-demon-add-nntp-close-connection () - "Add daemonic nntp server disconnection to Gnus. -If no commands have gone out via nntp during the last five -minutes, the connection is closed." - (gnus-demon-add-handler 'gnus-demon-close-connections 5 nil)) - -(defun gnus-demon-nntp-close-connection () - (save-window-excursion - (when (nnmail-time-less '(0 300) - (nnmail-time-since nntp-last-command-time)) - (nntp-close-server)))) - -(defun gnus-demon-add-scanmail () - "Add daemonic scanning of mail from the mail backends." - (gnus-demon-add-handler 'gnus-demon-scan-mail 120 60)) - -(defun gnus-demon-scan-mail () - (save-window-excursion - (let ((servers gnus-opened-servers) - server) - (gnus-clear-inboxes-moved) - (while (setq server (car (pop servers))) - (and (gnus-check-backend-function 'request-scan (car server)) - (or (gnus-server-opened server) - (gnus-open-server server)) - (gnus-request-scan nil server)))))) - -(defun gnus-demon-add-rescan () - "Add daemonic scanning of new articles from all backends." - (gnus-demon-add-handler 'gnus-demon-scan-news 120 60)) - -(defun gnus-demon-scan-news () - (let ((win (current-window-configuration))) - (unwind-protect - (save-window-excursion - (save-excursion - (when (gnus-alive-p) - (save-excursion - (set-buffer gnus-group-buffer) - (gnus-group-get-new-news))))) - (set-window-configuration win)))) - -(defun gnus-demon-add-scan-timestamps () - "Add daemonic updating of timestamps in empty newgroups." - (gnus-demon-add-handler 'gnus-demon-scan-timestamps nil 30)) - -(defun gnus-demon-scan-timestamps () - "Set the timestamp on all newsgroups with no unread and no ticked articles." - (when (gnus-alive-p) - (let ((cur-time (current-time)) - (newsrc (cdr gnus-newsrc-alist)) - info group unread has-ticked) - (while (setq info (pop newsrc)) - (setq group (gnus-info-group info) - unread (gnus-group-unread group) - has-ticked (cdr (assq 'tick (gnus-info-marks info)))) - (when (and (numberp unread) - (= unread 0) - (not has-ticked)) - (gnus-group-set-parameter group 'timestamp cur-time)))))) - -(provide 'gnus-demon) - -;;; gnus-demon.el ends here diff --git a/lisp/gnus-draft.el b/lisp/gnus-draft.el deleted file mode 100644 index 7a3ca8a..0000000 --- a/lisp/gnus-draft.el +++ /dev/null @@ -1,209 +0,0 @@ -;;; gnus-draft.el --- draft message support for Semi-gnus -;; Copyright (C) 1997,98 Free Software Foundation, Inc. - -;; Author: Lars Magne Ingebrigtsen -;; MORIOKA Tomohiko -;; Keywords: mail, news, MIME, offline - -;; This file is part of GNU Emacs. - -;; GNU Emacs is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 2, or (at your option) -;; any later version. - -;; GNU Emacs is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs; see the file COPYING. If not, write to the -;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. - -;;; Commentary: - -;;; Code: - -(require 'gnus) -(require 'gnus-sum) -(require 'message) -(require 'gnus-msg) -(require 'nndraft) -(require 'gnus-agent) -(eval-when-compile (require 'cl)) - -;;; Draft minor mode - -(defvar gnus-draft-mode nil - "Minor mode for providing a draft summary buffers.") - -(defvar gnus-draft-mode-map nil) - -(unless gnus-draft-mode-map - (setq gnus-draft-mode-map (make-sparse-keymap)) - - (gnus-define-keys gnus-draft-mode-map - "Dt" gnus-draft-toggle-sending - "De" gnus-draft-edit-message - "Ds" gnus-draft-send-message - "DS" gnus-draft-send-all-messages)) - -(defun gnus-draft-make-menu-bar () - (unless (boundp 'gnus-draft-menu) - (easy-menu-define - gnus-draft-menu gnus-draft-mode-map "" - '("Drafts" - ["Toggle whether to send" gnus-draft-toggle-sending t] - ["Edit" gnus-draft-edit-message t] - ["Send selected message(s)" gnus-draft-send-message t] - ["Send all messages" gnus-draft-send-all-messages t] - ["Delete draft" gnus-summary-delete-article t])))) - -(defun gnus-draft-mode (&optional arg) - "Minor mode for providing a draft summary buffers. - -\\{gnus-draft-mode-map}" - (interactive "P") - (when (eq major-mode 'gnus-summary-mode) - (when (set (make-local-variable 'gnus-draft-mode) - (if (null arg) (not gnus-draft-mode) - (> (prefix-numeric-value arg) 0))) - ;; Set up the menu. - (when (gnus-visual-p 'draft-menu 'menu) - (gnus-draft-make-menu-bar)) - (gnus-add-minor-mode 'gnus-draft-mode " Draft" gnus-draft-mode-map) - (gnus-run-hooks 'gnus-draft-mode-hook)))) - -;;; Commands - -(defun gnus-draft-toggle-sending (article) - "Toggle whether to send an article or not." - (interactive (list (gnus-summary-article-number))) - (if (gnus-draft-article-sendable-p article) - (progn - (push article gnus-newsgroup-unsendable) - (gnus-summary-mark-article article gnus-unsendable-mark)) - (setq gnus-newsgroup-unsendable - (delq article gnus-newsgroup-unsendable)) - (gnus-summary-mark-article article gnus-unread-mark)) - (gnus-summary-position-point)) - -(defun gnus-draft-edit-message () - "Enter a mail/post buffer to edit and send the draft." - (interactive) - (let ((article (gnus-summary-article-number))) - (gnus-summary-mark-as-read article gnus-canceled-mark) - (gnus-draft-setup article gnus-newsgroup-name) - (set-buffer-modified-p t) - (save-buffer) - (push - `((lambda () - (when (gnus-buffer-exists-p ,gnus-summary-buffer) - (save-excursion - (set-buffer ,gnus-summary-buffer) - (gnus-cache-possibly-remove-article ,article nil nil nil t))))) - message-send-actions))) - -(defun gnus-draft-send-message (&optional n) - "Send the current draft." - (interactive "P") - (let ((articles (gnus-summary-work-articles n)) - article) - (while (setq article (pop articles)) - (gnus-summary-remove-process-mark article) - (unless (memq article gnus-newsgroup-unsendable) - (gnus-draft-send article gnus-newsgroup-name) - (gnus-summary-mark-article article gnus-canceled-mark))))) - -(defun gnus-draft-send (article &optional group) - "Send message ARTICLE." - (gnus-draft-setup article (or group "nndraft:queue")) - (let ((message-syntax-checks 'dont-check-for-anything-just-trust-me) - message-send-hook type method) - ;; We read the meta-information that says how and where - ;; this message is to be sent. - (save-restriction - (message-narrow-to-head) - (when (re-search-forward - (concat "^" (regexp-quote gnus-agent-meta-information-header) ":") - nil t) - (setq type (ignore-errors (read (current-buffer))) - method (ignore-errors (read (current-buffer)))) - (message-remove-header gnus-agent-meta-information-header))) - ;; Then we send it. If we have no meta-information, we just send - ;; it and let Message figure out how. - (when (if type - (let ((message-this-is-news (eq type 'news)) - (message-this-is-mail (eq type 'mail)) - (gnus-post-method method) - (message-post-method method)) - (message-send-and-exit)) - (message-send-and-exit)) - (let ((gnus-verbose-backends nil)) - (gnus-request-expire-articles - (list article) (or group "nndraft:queue") t))))) - -(defun gnus-draft-send-all-messages () - "Send all the sendable drafts." - (interactive) - (gnus-uu-mark-buffer) - (gnus-draft-send-message)) - -(defun gnus-group-send-drafts () - "Send all sendable articles from the queue group." - (interactive) - (gnus-activate-group "nndraft:queue") - (save-excursion - (let ((articles (nndraft-articles)) - (unsendable (gnus-uncompress-range - (cdr (assq 'unsend - (gnus-info-marks - (gnus-get-info "nndraft:queue")))))) - article) - (while (setq article (pop articles)) - (unless (memq article unsendable) - (gnus-draft-send article)))))) - -;;; Utility functions - -(defcustom gnus-draft-decoding-function - (function - (lambda () - (mime-edit-decode-buffer nil) - (eword-decode-header) - )) - "*Function called to decode the message from network representation." - :group 'gnus-agent - :type 'function) - -;;;!!!If this is byte-compiled, it fails miserably. -;;;!!!This is because `gnus-setup-message' uses uninterned symbols. -;;;!!!This has been fixed in recent versions of Emacs and XEmacs, -;;;!!!but for the time being, we'll just run this tiny function uncompiled. - -(progn -(defun gnus-draft-setup (narticle group) - (gnus-setup-message 'forward - (let ((article narticle)) - (message-mail) - (erase-buffer) - (if (not (gnus-request-restore-buffer article group)) - (error "Couldn't restore the article") - ;; Insert the separator. - (funcall gnus-draft-decoding-function) - (goto-char (point-min)) - (search-forward "\n\n") - (forward-char -1) - (insert mail-header-separator) - (forward-line 1) - (message-set-auto-save-file-name)))))) - -(defun gnus-draft-article-sendable-p (article) - "Say whether ARTICLE is sendable." - (not (memq article gnus-newsgroup-unsendable))) - -(provide 'gnus-draft) - -;;; gnus-draft.el ends here diff --git a/lisp/gnus-dup.el b/lisp/gnus-dup.el deleted file mode 100644 index 6958f02..0000000 --- a/lisp/gnus-dup.el +++ /dev/null @@ -1,160 +0,0 @@ -;;; gnus-dup.el --- suppression of duplicate articles in Gnus -;; Copyright (C) 1996,97,98 Free Software Foundation, Inc. - -;; Author: Lars Magne Ingebrigtsen -;; Keywords: news - -;; This file is part of GNU Emacs. - -;; GNU Emacs is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 2, or (at your option) -;; any later version. - -;; GNU Emacs is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs; see the file COPYING. If not, write to the -;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. - -;;; Commentary: - -;; This package tries to mark articles as read the second time the -;; user reads a copy. This is useful if the server doesn't support -;; Xref properly, or if the user reads the same group from several -;; servers. - -;;; Code: - -(eval-when-compile (require 'cl)) - -(require 'gnus) -(require 'gnus-art) - -(defgroup gnus-duplicate nil - "Suppression of duplicate articles." - :group 'gnus) - -(defcustom gnus-save-duplicate-list nil - "*If non-nil, save the duplicate list when shutting down Gnus. -If nil, duplicate suppression will only work on duplicates -seen in the same session." - :group 'gnus-duplicate - :type 'boolean) - -(defcustom gnus-duplicate-list-length 10000 - "*The number of Message-IDs to keep in the duplicate suppression list." - :group 'gnus-duplicate - :type 'integer) - -(defcustom gnus-duplicate-file (nnheader-concat gnus-directory "suppression") - "*The name of the file to store the duplicate suppression list." - :group 'gnus-duplicate - :type 'file) - -;;; Internal variables - -(defvar gnus-dup-list nil) -(defvar gnus-dup-hashtb nil) - -(defvar gnus-dup-list-dirty nil) - -;;; -;;; Starting and stopping -;;; - -(gnus-add-shutdown 'gnus-dup-close 'gnus) - -(defun gnus-dup-close () - "Possibly save the duplicate suppression list and shut down the subsystem." - (gnus-dup-save) - (setq gnus-dup-list nil - gnus-dup-hashtb nil - gnus-dup-list-dirty nil)) - -(defun gnus-dup-open () - "Possibly read the duplicate suppression list and start the subsystem." - (if gnus-save-duplicate-list - (gnus-dup-read) - (setq gnus-dup-list nil)) - (setq gnus-dup-hashtb (gnus-make-hashtable gnus-duplicate-list-length)) - ;; Enter all Message-IDs into the hash table. - (let ((list gnus-dup-list) - (obarray gnus-dup-hashtb)) - (while list - (intern (pop list))))) - -(defun gnus-dup-read () - "Read the duplicate suppression list." - (setq gnus-dup-list nil) - (when (file-exists-p gnus-duplicate-file) - (load gnus-duplicate-file t t t))) - -(defun gnus-dup-save () - "Save the duplicate suppression list." - (when (and gnus-save-duplicate-list - gnus-dup-list-dirty) - (nnheader-temp-write gnus-duplicate-file - (gnus-prin1 `(setq gnus-dup-list ',gnus-dup-list)))) - (setq gnus-dup-list-dirty nil)) - -;;; -;;; Interface functions -;;; - -(defun gnus-dup-enter-articles () - "Enter articles from the current group for future duplicate suppression." - (unless gnus-dup-list - (gnus-dup-open)) - (setq gnus-dup-list-dirty t) ; mark list for saving - (let ((data gnus-newsgroup-data) - datum msgid) - ;; Enter the Message-IDs of all read articles into the list - ;; and hash table. - (while (setq datum (pop data)) - (when (and (not (gnus-data-pseudo-p datum)) - (> (gnus-data-number datum) 0) - (not (memq (gnus-data-number datum) gnus-newsgroup-unreads)) - (not (= (gnus-data-mark datum) gnus-canceled-mark)) - (setq msgid (mail-header-id (gnus-data-header datum))) - (not (nnheader-fake-message-id-p msgid)) - (not (intern-soft msgid gnus-dup-hashtb))) - (push msgid gnus-dup-list) - (intern msgid gnus-dup-hashtb)))) - ;; Chop off excess Message-IDs from the list. - (let ((end (nthcdr gnus-duplicate-list-length gnus-dup-list))) - (when end - (setcdr end nil)))) - -(defun gnus-dup-suppress-articles () - "Mark duplicate articles as read." - (unless gnus-dup-list - (gnus-dup-open)) - (gnus-message 6 "Suppressing duplicates...") - (let ((headers gnus-newsgroup-headers) - number header) - (while (setq header (pop headers)) - (when (and (intern-soft (mail-header-id header) gnus-dup-hashtb) - (gnus-summary-article-unread-p (mail-header-number header))) - (setq gnus-newsgroup-unreads - (delq (setq number (mail-header-number header)) - gnus-newsgroup-unreads)) - (push (cons number gnus-duplicate-mark) - gnus-newsgroup-reads)))) - (gnus-message 6 "Suppressing duplicates...done")) - -(defun gnus-dup-unsuppress-article (article) - "Stop suppression of ARTICLE." - (let ((id (mail-header-id (gnus-data-header (gnus-data-find article))))) - (when id - (setq gnus-dup-list-dirty t) - (setq gnus-dup-list (delete id gnus-dup-list)) - (unintern id gnus-dup-hashtb)))) - -(provide 'gnus-dup) - -;;; gnus-dup.el ends here diff --git a/lisp/gnus-eform.el b/lisp/gnus-eform.el deleted file mode 100644 index 6a93242..0000000 --- a/lisp/gnus-eform.el +++ /dev/null @@ -1,129 +0,0 @@ -;;; gnus-eform.el --- a mode for editing forms for Gnus -;; Copyright (C) 1996,97,98 Free Software Foundation, Inc. - -;; Author: Lars Magne Ingebrigtsen -;; Keywords: news - -;; This file is part of GNU Emacs. - -;; GNU Emacs is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 2, or (at your option) -;; any later version. - -;; GNU Emacs is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs; see the file COPYING. If not, write to the -;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. - -;;; Commentary: - -;;; Code: - -(require 'gnus) -(require 'gnus-win) - -;;; -;;; Editing forms -;;; - -(defgroup gnus-edit-form nil - "A mode for editing forms." - :group 'gnus) - -(defcustom gnus-edit-form-mode-hook nil - "Hook run in `gnus-edit-form-mode' buffers." - :group 'gnus-edit-form - :type 'hook) - -(defcustom gnus-edit-form-menu-hook nil - "Hook run when creating menus in `gnus-edit-form-mode' buffers." - :group 'gnus-edit-form - :type 'hook) - -;;; Internal variables - -(defvar gnus-edit-form-buffer "*Gnus edit form*") -(defvar gnus-edit-form-done-function nil) - -(defvar gnus-edit-form-mode-map nil) -(unless gnus-edit-form-mode-map - (setq gnus-edit-form-mode-map (copy-keymap emacs-lisp-mode-map)) - (gnus-define-keys gnus-edit-form-mode-map - "\C-c\C-c" gnus-edit-form-done - "\C-c\C-k" gnus-edit-form-exit)) - -(defun gnus-edit-form-make-menu-bar () - (unless (boundp 'gnus-edit-form-menu) - (easy-menu-define - gnus-edit-form-menu gnus-edit-form-mode-map "" - '("Edit Form" - ["Exit and save changes" gnus-edit-form-done t] - ["Exit" gnus-edit-form-exit t])) - (gnus-run-hooks 'gnus-edit-form-menu-hook))) - -(defun gnus-edit-form-mode () - "Major mode for editing forms. -It is a slightly enhanced emacs-lisp-mode. - -\\{gnus-edit-form-mode-map}" - (interactive) - (when (gnus-visual-p 'group-menu 'menu) - (gnus-edit-form-make-menu-bar)) - (kill-all-local-variables) - (setq major-mode 'gnus-edit-form-mode) - (setq mode-name "Edit Form") - (use-local-map gnus-edit-form-mode-map) - (make-local-variable 'gnus-edit-form-done-function) - (make-local-variable 'gnus-prev-winconf) - (gnus-run-hooks 'gnus-edit-form-mode-hook)) - -(defun gnus-edit-form (form documentation exit-func) - "Edit FORM in a new buffer. -Call EXIT-FUNC on exit. Display DOCUMENTATION in the beginning -of the buffer." - (let ((winconf (current-window-configuration))) - (set-buffer (gnus-get-buffer-create gnus-edit-form-buffer)) - (gnus-configure-windows 'edit-form) - (gnus-edit-form-mode) - (setq gnus-prev-winconf winconf) - (setq gnus-edit-form-done-function exit-func) - (erase-buffer) - (insert documentation) - (unless (bolp) - (insert "\n")) - (goto-char (point-min)) - (while (not (eobp)) - (insert ";;; ") - (forward-line 1)) - (insert ";; Type `C-c C-c' after you've finished editing.\n") - (insert "\n") - (let ((p (point))) - (pp form (current-buffer)) - (insert "\n") - (goto-char p)))) - -(defun gnus-edit-form-done () - "Update changes and kill the current buffer." - (interactive) - (goto-char (point-min)) - (let ((form (read (current-buffer))) - (func gnus-edit-form-done-function)) - (gnus-edit-form-exit) - (funcall func form))) - -(defun gnus-edit-form-exit () - "Kill the current buffer." - (interactive) - (let ((winconf gnus-prev-winconf)) - (kill-buffer (current-buffer)) - (set-window-configuration winconf))) - -(provide 'gnus-eform) - -;;; gnus-eform.el ends here diff --git a/lisp/gnus-ems.el b/lisp/gnus-ems.el deleted file mode 100644 index f798e12..0000000 --- a/lisp/gnus-ems.el +++ /dev/null @@ -1,351 +0,0 @@ -;;; gnus-ems.el --- functions for making Semi-gnus work under different Emacsen -;; Copyright (C) 1995,96,97,98 Free Software Foundation, Inc. - -;; Author: Lars Magne Ingebrigtsen -;; Tatsuya Ichikawa -;; Keywords: news - -;; This file is part of GNU Emacs. - -;; GNU Emacs is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 2, or (at your option) -;; any later version. - -;; GNU Emacs is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs; see the file COPYING. If not, write to the -;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. - -;;; Commentary: - -;;; Code: - -(eval-when-compile (require 'cl)) - -;;; Function aliases later to be redefined for XEmacs usage. - -(defvar gnus-xemacs (string-match "XEmacs\\|Lucid" emacs-version) - "Non-nil if running under XEmacs.") - -(defvar gnus-mouse-2 [mouse-2]) -(defvar gnus-down-mouse-2 [down-mouse-2]) -(defvar gnus-mode-line-modified - (if (or gnus-xemacs - (< emacs-major-version 20)) - '("--**-" . "-----") - '("**" "--"))) - -(eval-and-compile - (autoload 'gnus-xmas-define "gnus-xmas") - (autoload 'gnus-xmas-redefine "gnus-xmas") - (autoload 'appt-select-lowest-window "appt")) - -(or (fboundp 'mail-file-babyl-p) - (fset 'mail-file-babyl-p 'rmail-file-p)) - -;;; Mule functions. - -(defun gnus-mule-cite-add-face (number prefix face) - ;; At line NUMBER, ignore PREFIX and add FACE to the rest of the line. - (when face - (let ((inhibit-point-motion-hooks t) - from to) - (goto-line number) - (unless (eobp) ; Sometimes things become confused (broken). - (forward-char (chars-in-string prefix)) - (skip-chars-forward " \t") - (setq from (point)) - (end-of-line 1) - (skip-chars-backward " \t") - (setq to (point)) - (when (< from to) - (push (setq overlay (gnus-make-overlay from to)) - gnus-cite-overlay-list) - (gnus-overlay-put (gnus-make-overlay from to) 'face face)))))) - -(defvar gnus-mule-bitmap-image-file nil) -(defun gnus-mule-group-startup-message (&optional x y) - "Insert startup message in current buffer." - ;; Insert the message. - (erase-buffer) - (insert - (if (featurep 'bitmap) - (format " %s - -" - "" (if (and (stringp gnus-mule-bitmap-image-file) - (file-exists-p gnus-mule-bitmap-image-file)) - (insert-file gnus-mule-bitmap-image-file))) - (format " %s - _ ___ _ _ - _ ___ __ ___ __ _ ___ - __ _ ___ __ ___ - _ ___ _ - _ _ __ _ - ___ __ _ - __ _ - _ _ _ - _ _ _ - _ _ _ - __ ___ - _ _ _ _ - _ _ - _ _ - _ _ - _ - __ - -" - ""))) - ;; And then hack it. - (gnus-indent-rigidly (point-min) (point-max) - (/ (max (- (window-width) (or x 46)) 0) 2)) - (goto-char (point-min)) - (forward-line 1) - (let* ((pheight (count-lines (point-min) (point-max))) - (wheight (window-height)) - (rest (- wheight pheight))) - (insert (make-string (max 0 (* 2 (/ rest 3))) ?\n))) - ;; Fontify some. - (put-text-property (point-min) (point-max) 'face 'gnus-splash-face) - (goto-char (point-min)) - (setq mode-line-buffer-identification (concat " " gnus-version)) - (setq gnus-simple-splash t) - (set-buffer-modified-p t)) - -(defun gnus-encode-coding-string (string system) - string) - -(defun gnus-decode-coding-string (string system) - string) - -(eval-and-compile - (if (string-match "XEmacs\\|Lucid" emacs-version) - nil - - (defvar gnus-mouse-face-prop 'mouse-face - "Property used for highlighting mouse regions.")) - - (cond - ((string-match "XEmacs\\|Lucid" emacs-version) - (gnus-xmas-define)) - - ((or (not (boundp 'emacs-minor-version)) - (and (< emacs-major-version 20) - (< emacs-minor-version 30))) - ;; Remove the `intangible' prop. - (let ((props (and (boundp 'gnus-hidden-properties) - gnus-hidden-properties))) - (while (and props (not (eq (car (cdr props)) 'intangible))) - (setq props (cdr props))) - (when props - (setcdr props (cdr (cdr (cdr props)))))) - (unless (fboundp 'buffer-substring-no-properties) - (defun buffer-substring-no-properties (beg end) - (format "%s" (buffer-substring beg end))))) - - ((boundp 'MULE) - (provide 'gnusutil)))) - -(eval-and-compile - (cond - ((not window-system) - (defun gnus-dummy-func (&rest args)) - (let ((funcs '(mouse-set-point set-face-foreground - set-face-background x-popup-menu))) - (while funcs - (unless (fboundp (car funcs)) - (fset (car funcs) 'gnus-dummy-func)) - (setq funcs (cdr funcs)))))) - (unless (fboundp 'file-regular-p) - (defun file-regular-p (file) - (and (not (file-directory-p file)) - (not (file-symlink-p file)) - (file-exists-p file)))) - (unless (fboundp 'face-list) - (defun face-list (&rest args)))) - -(eval-and-compile - (let ((case-fold-search t)) - (cond - ((string-match "windows-nt\\|os/2\\|emx" (symbol-name system-type)) - (setq nnheader-file-name-translation-alist - (append nnheader-file-name-translation-alist - '((?: . ?_) - (?+ . ?-)))))))) - -(defvar gnus-tmp-unread) -(defvar gnus-tmp-replied) -(defvar gnus-tmp-score-char) -(defvar gnus-tmp-indentation) -(defvar gnus-tmp-opening-bracket) -(defvar gnus-tmp-lines) -(defvar gnus-tmp-name) -(defvar gnus-tmp-closing-bracket) -(defvar gnus-tmp-subject-or-nil) - -(defun gnus-ems-redefine () - (cond - ((string-match "XEmacs\\|Lucid" emacs-version) - (gnus-xmas-redefine)) - - ((featurep 'mule) - ;; Mule and new Emacs definitions - - ;; [Note] Now there are three kinds of mule implementations, - ;; original MULE, XEmacs/mule and beta version of Emacs including - ;; some mule features. Unfortunately these API are different. In - ;; particular, Emacs (including original MULE) and XEmacs are - ;; quite different. - ;; Predicates to check are following: - ;; (boundp 'MULE) is t only if MULE (original; anything older than - ;; Mule 2.3) is running. - ;; (featurep 'mule) is t when every mule variants are running. - - ;; These implementations may be able to share between original - ;; MULE and beta version of new Emacs. In addition, it is able to - ;; detect XEmacs/mule by (featurep 'mule) and to check variable - ;; `emacs-version'. In this case, implementation for XEmacs/mule - ;; may be able to share between XEmacs and XEmacs/mule. - - (defvar gnus-summary-display-table nil - "Display table used in summary mode buffers.") - (fset 'gnus-summary-set-display-table (lambda ())) - (fset 'gnus-encode-coding-string 'encode-coding-string) - (fset 'gnus-decode-coding-string 'decode-coding-string) - - (if (fboundp 'truncate-string-to-width) - (fset 'gnus-truncate-string 'truncate-string-to-width) - (fset 'gnus-truncate-string 'truncate-string)) - - (defun gnus-tilde-max-form (el max-width) - "Return a form that limits EL to MAX-WIDTH." - (let ((max (abs max-width))) - (if (symbolp el) - `(if (> (string-width ,el) ,max) - ,(if (< max-width 0) - `(gnus-truncate-string - ,el (string-width ,el) - (- (string-width ,el) ,max)) - `(gnus-truncate-string ,el ,max)) - ,el) - `(let ((val (eval ,el))) - (if (> (string-width val) ,max) - ,(if (< max-width 0) - `(gnus-truncate-string - val (string-width val) - (- (string-width val) ,max)) - `(gnus-truncate-string val ,max)) - val))))) - - (defun gnus-tilde-cut-form (el cut-width) - "Return a form that cuts CUT-WIDTH off of EL." - (let ((cut (abs cut-width))) - (if (symbolp el) - `(if (> (string-width ,el) ,cut) - ,(if (< cut-width 0) - `(gnus-truncate-string - ,el (- (string-width ,el) ,cut)) - `(gnus-truncate-string - ,el (- (string-width ,el) ,cut) ,cut)) - ,el) - `(let ((val (eval ,el))) - (if (> (string-width val) ,cut) - ,(if (< cut-width 0) - `(gnus-truncate-string - val (- (string-width val) ,cut)) - `(gnus-truncate-string - val (- (string-width val) ,cut) ,cut)) - val))))) - - (when window-system - (require 'path-util) - (if (module-installed-p 'bitmap) - (fset 'gnus-group-startup-message 'gnus-mule-group-startup-message) - )) - - (when (boundp 'gnus-check-before-posting) - (setq gnus-check-before-posting - (delq 'long-lines - (delq 'control-chars gnus-check-before-posting)))) - - (when (fboundp 'chars-in-string) - (fset 'gnus-cite-add-face 'gnus-mule-cite-add-face)) - - ))) - -(defun gnus-region-active-p () - "Say whether the region is active." - (and (boundp 'transient-mark-mode) - transient-mark-mode - (boundp 'mark-active) - mark-active)) - -(defun gnus-add-minor-mode (mode name map) - (if (fboundp 'add-minor-mode) - (add-minor-mode mode name map) - (set (make-local-variable mode) t) - (unless (assq mode minor-mode-alist) - (push `(,mode ,name) minor-mode-alist)) - (unless (assq mode minor-mode-map-alist) - (push (cons mode map) - minor-mode-map-alist)))) - -(defun gnus-x-splash () - "Show a splash screen using a pixmap in the current buffer." - (let ((dir (nnheader-find-etc-directory "gnus")) - pixmap file height beg i) - (save-excursion - (switch-to-buffer (gnus-get-buffer-create gnus-group-buffer)) - (let ((buffer-read-only nil)) - (erase-buffer) - (when (and dir - (file-exists-p (setq file (concat dir "x-splash")))) - (nnheader-temp-write nil - (insert-file-contents file) - (goto-char (point-min)) - (ignore-errors - (setq pixmap (read (current-buffer)))))) - (when pixmap - (erase-buffer) - (unless (facep 'gnus-splash) - (make-face 'gnus-splash)) - (setq height (/ (car pixmap) (frame-char-height)) - width (/ (cadr pixmap) (frame-char-width))) - (set-face-foreground 'gnus-splash "ForestGreen") - (set-face-stipple 'gnus-splash pixmap) - (insert-char ?\n (* (/ (window-height) 2 height) height)) - (setq i height) - (while (> i 0) - (insert-char ? (* (+ (/ (window-width) 2 width) 1) width)) - (setq beg (point)) - (insert-char ? width) - (set-text-properties beg (point) '(face gnus-splash)) - (insert "\n") - (decf i)) - (goto-char (point-min)) - (sit-for 0)))))) - -(if (fboundp 'split-string) - (fset 'gnus-split-string 'split-string) - (defun gnus-split-string (string pattern) - "Return a list of substrings of STRING which are separated by PATTERN." - (let (parts (start 0)) - (while (string-match pattern string start) - (setq parts (cons (substring string start (match-beginning 0)) parts) - start (match-end 0))) - (nreverse (cons (substring string start) parts))))) - -(provide 'gnus-ems) - -;; Local Variables: -;; byte-compile-warnings: '(redefine callargs) -;; End: - -;;; gnus-ems.el ends here diff --git a/lisp/gnus-gl.el b/lisp/gnus-gl.el deleted file mode 100644 index 93ef915..0000000 --- a/lisp/gnus-gl.el +++ /dev/null @@ -1,857 +0,0 @@ -;;; gnus-gl.el --- an interface to GroupLens for Gnus -;; Copyright (C) 1995,96,97,98 Free Software Foundation, Inc. - -;; Author: Brad Miller -;; Keywords: news, score - -;; This file is part of GNU Emacs. - -;; GNU Emacs is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 2, or (at your option) -;; any later version. - -;; GNU Emacs is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs; see the file COPYING. If not, write to the -;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. - -;;; Commentary: - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; GroupLens software and documentation is copyright (c) 1995 by Paul -;; Resnick (Massachusetts Institute of Technology); Brad Miller, John -;; Riedl, Jon Herlocker, and Joseph Konstan (University of Minnesota), -;; and David Maltz (Carnegie-Mellon University). -;; -;; Permission to use, copy, modify, and distribute this documentation -;; for non-commercial and commercial purposes without fee is hereby -;; granted provided that this copyright notice and permission notice -;; appears in all copies and that the names of the individuals and -;; institutions holding this copyright are not used in advertising or -;; publicity pertaining to this software without specific, written -;; prior permission. The copyright holders make no representations -;; about the suitability of this software and documentation for any -;; purpose. It is provided ``as is'' without express or implied -;; warranty. -;; -;; The copyright holders request that they be notified of -;; modifications of this code. Please send electronic mail to -;; grouplens@cs.umn.edu for more information or to announce derived -;; works. -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; Author: Brad Miller -;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; -;; User Documentation: -;; To use GroupLens you must load this file. -;; You must also register a pseudonym with the Better Bit Bureau. -;; http://www.cs.umn.edu/Research/GroupLens -;; -;; ---------------- For your .emacs or .gnus file ---------------- -;; -;; As of version 2.5, grouplens now works as a minor mode of -;; gnus-summary-mode. To get make that work you just need a couple of -;; hooks. -;; (setq gnus-use-grouplens t) -;; (setq grouplens-pseudonym "") -;; (setq grouplens-bbb-host "grouplens.cs.umn.edu") -;; -;; (setq gnus-summary-default-score 0) -;; -;; USING GROUPLENS -;; How do I Rate an article?? -;; Before you type n to go to the next article, hit a number from 1-5 -;; Type r in the summary buffer and you will be prompted. -;; Note that when you're in grouplens-minor-mode 'r' masks the -;; usual reply binding for 'r' -;; -;; What if, Gasp, I find a bug??? -;; Please type M-x gnus-gl-submit-bug-report. This will set up a -;; mail buffer with the state of variables and buffers that will help -;; me debug the problem. A short description up front would help too! -;; -;; How do I display the prediction for an article: -;; If you set the gnus-summary-line-format as shown above, the score -;; (prediction) will be shown automatically. -;; -;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; Programmer Notes -;; 10/9/95 -;; gnus-scores-articles contains the articles -;; When scoring is done, the call tree looks something like: -;; gnus-possibly-score-headers -;; ==> gnus-score-headers -;; ==> gnus-score-load-file -;; ==> get-all-mids (from the eval form) -;; -;; it would be nice to have one that gets called after all the other -;; headers have been scored. -;; we may want a variable gnus-grouplens-scale-factor -;; and gnus-grouplens-offset this would probably be either -3 or 0 -;; to make the scores centered around zero or not. -;; Notes 10/12/95 -;; According to Lars, Norse god of gnus, the simple way to insert a -;; call to an external function is to have a function added to the -;; variable gnus-score-find-files-function This new function -;; gnus-grouplens-score-alist will return a core alist that -;; has (("message-id" ("" score) ("" score)) -;; This seems like it would be pretty inefficient, though workable. -;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; TODO -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; -;; 3. Add some more ways to rate messages -;; 4. Better error handling for token timeouts. -;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; bugs -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; - -;;; Code: - -(eval-when-compile (require 'cl)) - -(require 'gnus-score) -(require 'gnus) - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;;; User variables -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -(defvar gnus-summary-grouplens-line-format - "%U\%R\%z%l%I\%(%[%4L: %-20,20n%]%) %s\n" - "*The line format spec in summary GroupLens mode buffers.") - -(defvar grouplens-pseudonym "" - "User's pseudonym. -This pseudonym is obtained during the registration process") - -(defvar grouplens-bbb-host "grouplens.cs.umn.edu" - "Host where the bbbd is running" ) - -(defvar grouplens-bbb-port 9000 - "Port where the bbbd is listening" ) - -(defvar grouplens-newsgroups - '("comp.groupware" "comp.human-factors" "comp.lang.c++" - "comp.lang.java" "comp.os.linux.admin" "comp.os.linux.advocacy" - "comp.os.linux.announce" "comp.os.linux.answers" - "comp.os.linux.development" "comp.os.linux.development.apps" - "comp.os.linux.development.system" "comp.os.linux.hardware" - "comp.os.linux.help" "comp.os.linux.m68k" "comp.os.linux.misc" - "comp.os.linux.networking" "comp.os.linux.setup" "comp.os.linux.x" - "mn.general" "rec.arts.movies" "rec.arts.movies.current-films" - "rec.food.recipes" "rec.humor") - "*Groups that are part of the GroupLens experiment.") - -(defvar grouplens-prediction-display 'prediction-spot - "valid values are: - prediction-spot -- an * corresponding to the prediction between 1 and 5, - confidence-interval -- a numeric confidence interval - prediction-bar -- |##### | the longer the bar, the better the article, - confidence-bar -- | ----- } the prediction is in the middle of the bar, - confidence-spot -- ) * | the spot gets bigger with more confidence, - prediction-num -- plain-old numeric value, - confidence-plus-minus -- prediction +/i confidence") - -(defvar grouplens-score-offset 0 - "Offset the prediction by this value. -Setting this variable to -2 would have the following effect on -GroupLens scores: - - 1 --> -2 - 2 --> -1 - 3 --> 0 - 4 --> 1 - 5 --> 2 - -The reason is that a user might want to do this is to combine -GroupLens predictions with scores calculated by other score methods.") - -(defvar grouplens-score-scale-factor 1 - "This variable allows the user to magnify the effect of GroupLens scores. -The scale factor is applied after the offset.") - -(defvar gnus-grouplens-override-scoring 'override - "Tell GroupLens to override the normal Gnus scoring mechanism. -GroupLens scores can be combined with gnus scores in one of three ways. -'override -- just use grouplens predictions for grouplens groups -'combine -- combine grouplens scores with gnus scores -'separate -- treat grouplens scores completely separate from gnus") - - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;;; Program global variables -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -(defvar grouplens-bbb-token nil - "Current session token number") - -(defvar grouplens-bbb-process nil - "Process Id of current bbbd network stream process") - -(defvar grouplens-bbb-buffer nil - "Buffer associated with the BBBD process") - -(defvar grouplens-rating-alist nil - "Current set of message-id rating pairs") - -(defvar grouplens-current-hashtable nil - "A hashtable to hold predictions from the BBB") - -(defvar grouplens-current-group nil) - -;;(defvar bbb-alist nil) - -(defvar bbb-timeout-secs 10 - "Number of seconds to wait for some response from the BBB. -If this times out we give up and assume that something has died..." ) - -(defvar grouplens-previous-article nil - "Message-ID of the last article read.") - -(defvar bbb-read-point) -(defvar bbb-response-point) - -(defun bbb-renew-hash-table () - (setq grouplens-current-hashtable (make-vector 100 0))) - -(bbb-renew-hash-table) - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;;; Utility Functions -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -(defun bbb-connect-to-bbbd (host port) - (unless grouplens-bbb-buffer - (setq grouplens-bbb-buffer - (gnus-get-buffer-create (format " *BBBD trace: %s*" host))) - (save-excursion - (set-buffer grouplens-bbb-buffer) - (make-local-variable 'bbb-read-point) - (make-local-variable 'bbb-response-point) - (setq bbb-read-point (point-min)))) - - ;; if an old process is still running for some reason, kill it - (when grouplens-bbb-process - (ignore-errors - (when (eq 'open (process-status grouplens-bbb-process)) - (set-process-buffer grouplens-bbb-process nil) - (delete-process grouplens-bbb-process)))) - - ;; clear the trace buffer of old output - (save-excursion - (set-buffer grouplens-bbb-buffer) - (erase-buffer)) - - ;; open the connection to the server - (catch 'done - (condition-case error - (setq grouplens-bbb-process - (open-network-stream "BBBD" grouplens-bbb-buffer host port)) - (error (gnus-message 3 "Error: Failed to connect to BBB") - nil)) - (and (null grouplens-bbb-process) - (throw 'done nil)) - (save-excursion - (set-buffer grouplens-bbb-buffer) - (setq bbb-read-point (point-min)) - (or (bbb-read-response grouplens-bbb-process) - (throw 'done nil)))) - - ;; return the process - grouplens-bbb-process) - -(defun bbb-send-command (process command) - (goto-char (point-max)) - (insert command) - (insert "\r\n") - (setq bbb-read-point (point)) - (setq bbb-response-point (point)) - (set-marker (process-mark process) (point)) ; process output also comes here - (process-send-string process command) - (process-send-string process "\r\n") - (process-send-eof process)) - -(defun bbb-read-response (process) - "This function eats the initial response of OK or ERROR from the BBB." - (let ((case-fold-search nil) - match-end) - (goto-char bbb-read-point) - (while (and (not (search-forward "\r\n" nil t)) - (accept-process-output process bbb-timeout-secs)) - (goto-char bbb-read-point)) - (setq match-end (point)) - (goto-char bbb-read-point) - (setq bbb-read-point match-end) - (looking-at "OK"))) - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;;; Login Functions -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -(defun bbb-login () - "return the token number if login is successful, otherwise return nil." - (interactive) - (setq grouplens-bbb-token nil) - (if (not (equal grouplens-pseudonym "")) - (let ((bbb-process - (bbb-connect-to-bbbd grouplens-bbb-host grouplens-bbb-port))) - (if bbb-process - (save-excursion - (set-buffer (process-buffer bbb-process)) - (bbb-send-command bbb-process - (concat "login " grouplens-pseudonym)) - (if (bbb-read-response bbb-process) - (setq grouplens-bbb-token (bbb-extract-token-number)) - (gnus-message 3 "Error: GroupLens login failed"))))) - (gnus-message 3 "Error: you must set a pseudonym")) - grouplens-bbb-token) - -(defun bbb-extract-token-number () - (let ((token-pos (search-forward "token=" nil t))) - (when (looking-at "[0-9]+") - (buffer-substring token-pos (match-end 0))))) - -(gnus-add-shutdown 'bbb-logout 'gnus) - -(defun bbb-logout () - "logout of bbb session." - (when grouplens-bbb-token - (let ((bbb-process - (bbb-connect-to-bbbd grouplens-bbb-host grouplens-bbb-port))) - (when bbb-process - (save-excursion - (set-buffer (process-buffer bbb-process)) - (bbb-send-command bbb-process (concat "logout " grouplens-bbb-token)) - (bbb-read-response bbb-process)))))) - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;;; Get Predictions -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -(defun bbb-build-mid-scores-alist (groupname) - "this function can be called as part of the function to return the list of score files to use. -See the gnus variable gnus-score-find-score-files-function. - -*Note:* If you want to use grouplens scores along with calculated scores, -you should see the offset and scale variables. At this point, I don't -recommend using both scores and grouplens predictions together." - (setq grouplens-current-group groupname) - (when (member groupname grouplens-newsgroups) - (setq grouplens-previous-article nil) - ;; scores-alist should be a list of lists: - ;; ((("message-id" ("" score1 nil s) (" score2 nil s)))) - ;;`((("message-id" . ,predict-list))) ; Yes, this is the return value - (list - (list - (list (append (list "message-id") - (bbb-get-predictions (bbb-get-all-mids) groupname))))))) - -(defun bbb-get-predictions (midlist groupname) - "Ask the bbb for predictions, and build up the score alist." - (gnus-message 5 "Fetching Predictions...") - (if grouplens-bbb-token - (let ((bbb-process (bbb-connect-to-bbbd grouplens-bbb-host - grouplens-bbb-port))) - (when bbb-process - (save-excursion - (set-buffer (process-buffer bbb-process)) - (bbb-send-command bbb-process - (bbb-build-predict-command midlist groupname - grouplens-bbb-token)) - (if (bbb-read-response bbb-process) - (bbb-get-prediction-response bbb-process) - (gnus-message 1 "Invalid Token, login and try again") - (ding))))) - (gnus-message 3 "Error: You are not logged in to a BBB") - (ding))) - -(defun bbb-get-all-mids () - (mapcar (function (lambda (x) (mail-header-id x))) gnus-newsgroup-headers)) - -(defun bbb-build-predict-command (mlist grpname token) - (concat "getpredictions " token " " grpname "\r\n" - (mapconcat 'identity mlist "\r\n") "\r\n.\r\n")) - -(defun bbb-get-prediction-response (process) - (let ((case-fold-search nil)) - (goto-char bbb-read-point) - (while (and (not (search-forward ".\r\n" nil t)) - (accept-process-output process bbb-timeout-secs)) - (goto-char bbb-read-point)) - (goto-char (+ bbb-response-point 4));; we ought to be right before OK - (bbb-build-response-alist))) - -;; build-response-alist assumes that the cursor has been positioned at -;; the first line of the list of mid/rating pairs. -(defun bbb-build-response-alist () - (let (resp mid pred) - (while - (cond - ((looking-at "\\(<.*>\\) :nopred=") - ;;(push `(,(bbb-get-mid) ,gnus-summary-default-score nil s) resp) - (forward-line 1) - t) - ((looking-at "\\(<.*>\\) :pred=\\([0-9]\.[0-9][0-9]\\) :conflow=\\([0-9]\.[0-9][0-9]\\) :confhigh=\\([0-9]\.[0-9][0-9]\\)") - (setq mid (bbb-get-mid) - pred (bbb-get-pred)) - (push `(,mid ,pred nil s) resp) - (gnus-sethash mid (list pred (bbb-get-confl) (bbb-get-confh)) - grouplens-current-hashtable) - (forward-line 1) - t) - ((looking-at "\\(<.*>\\) :pred=\\([0-9]\.[0-9][0-9]\\)") - (setq mid (bbb-get-mid) - pred (bbb-get-pred)) - (push `(,mid ,pred nil s) resp) - (gnus-sethash mid (list pred 0 0) grouplens-current-hashtable) - (forward-line 1) - t) - (t nil))) - resp)) - -;; these "get" functions assume that there is an active match lying -;; around. Where the first parenthesized expression is the -;; message-id, and the second is the prediction, the third and fourth -;; are the confidence interval -;; -;; Since gnus assumes that scores are integer values?? we round the -;; prediction. -(defun bbb-get-mid () - (buffer-substring (match-beginning 1) (match-end 1))) - -(defun bbb-get-pred () - (let ((tpred (string-to-number (buffer-substring (match-beginning 2) - (match-end 2))))) - (if (> tpred 0) - (round (* grouplens-score-scale-factor - (+ grouplens-score-offset tpred))) - 1))) - -(defun bbb-get-confl () - (string-to-number (buffer-substring (match-beginning 4) (match-end 4)))) - -(defun bbb-get-confh () - (string-to-number (buffer-substring (match-beginning 4) (match-end 4)))) - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;;; Prediction Display -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -(defconst grplens-rating-range 4.0) -(defconst grplens-maxrating 5) -(defconst grplens-minrating 1) -(defconst grplens-predstringsize 12) - -(defvar gnus-tmp-score) -(defun bbb-grouplens-score (header) - (if (eq gnus-grouplens-override-scoring 'separate) - (bbb-grouplens-other-score header) - (let* ((rate-string (make-string 12 ?\ )) - (mid (mail-header-id header)) - (hashent (gnus-gethash mid grouplens-current-hashtable)) - (iscore gnus-tmp-score) - (low (car (cdr hashent))) - (high (car (cdr (cdr hashent))))) - (aset rate-string 0 ?|) - (aset rate-string 11 ?|) - (unless (member grouplens-current-group grouplens-newsgroups) - (unless (equal grouplens-prediction-display 'prediction-num) - (cond ((< iscore 0) - (setq iscore 1)) - ((> iscore 5) - (setq iscore 5)))) - (setq low 0) - (setq high 0)) - (if (and (bbb-valid-score iscore) - (not (null mid))) - (cond - ;; prediction-spot - ((equal grouplens-prediction-display 'prediction-spot) - (setq rate-string (bbb-fmt-prediction-spot rate-string iscore))) - ;; confidence-interval - ((equal grouplens-prediction-display 'confidence-interval) - (setq rate-string (bbb-fmt-confidence-interval iscore low high))) - ;; prediction-bar - ((equal grouplens-prediction-display 'prediction-bar) - (setq rate-string (bbb-fmt-prediction-bar rate-string iscore))) - ;; confidence-bar - ((equal grouplens-prediction-display 'confidence-bar) - (setq rate-string (format "| %4.2f |" iscore))) - ;; confidence-spot - ((equal grouplens-prediction-display 'confidence-spot) - (setq rate-string (format "| %4.2f |" iscore))) - ;; prediction-num - ((equal grouplens-prediction-display 'prediction-num) - (setq rate-string (bbb-fmt-prediction-num iscore))) - ;; confidence-plus-minus - ((equal grouplens-prediction-display 'confidence-plus-minus) - (setq rate-string (bbb-fmt-confidence-plus-minus iscore low high)) - ) - (t (gnus-message 3 "Invalid prediction display type"))) - (aset rate-string 5 ?N) (aset rate-string 6 ?A)) - rate-string))) - -;; Gnus user format function that doesn't depend on -;; bbb-build-mid-scores-alist being used as the score function, but is -;; instead called from gnus-select-group-hook. -- LAB -(defun bbb-grouplens-other-score (header) - (if (not (member grouplens-current-group grouplens-newsgroups)) - ;; Return an empty string - "" - (let* ((rate-string (make-string 12 ?\ )) - (mid (mail-header-id header)) - (hashent (gnus-gethash mid grouplens-current-hashtable)) - (pred (or (nth 0 hashent) 0)) - (low (nth 1 hashent)) - (high (nth 2 hashent))) - ;; Init rate-string - (aset rate-string 0 ?|) - (aset rate-string 11 ?|) - (unless (equal grouplens-prediction-display 'prediction-num) - (cond ((< pred 0) - (setq pred 1)) - ((> pred 5) - (setq pred 5)))) - ;; If no entry in BBB hash mark rate string as NA and return - (cond - ((null hashent) - (aset rate-string 5 ?N) - (aset rate-string 6 ?A) - rate-string) - - ((equal grouplens-prediction-display 'prediction-spot) - (bbb-fmt-prediction-spot rate-string pred)) - - ((equal grouplens-prediction-display 'confidence-interval) - (bbb-fmt-confidence-interval pred low high)) - - ((equal grouplens-prediction-display 'prediction-bar) - (bbb-fmt-prediction-bar rate-string pred)) - - ((equal grouplens-prediction-display 'confidence-bar) - (format "| %4.2f |" pred)) - - ((equal grouplens-prediction-display 'confidence-spot) - (format "| %4.2f |" pred)) - - ((equal grouplens-prediction-display 'prediction-num) - (bbb-fmt-prediction-num pred)) - - ((equal grouplens-prediction-display 'confidence-plus-minus) - (bbb-fmt-confidence-plus-minus pred low high)) - - (t - (gnus-message 3 "Invalid prediction display type") - (aset rate-string 0 ?|) - (aset rate-string 11 ?|) - rate-string))))) - -(defun bbb-valid-score (score) - (or (equal grouplens-prediction-display 'prediction-num) - (and (>= score grplens-minrating) - (<= score grplens-maxrating)))) - -(defun bbb-requires-confidence (format-type) - (or (equal format-type 'confidence-plus-minus) - (equal format-type 'confidence-spot) - (equal format-type 'confidence-interval))) - -(defun bbb-have-confidence (clow chigh) - (not (or (null clow) - (null chigh)))) - -(defun bbb-fmt-prediction-spot (rate-string score) - (aset rate-string - (round (* (/ (- score grplens-minrating) grplens-rating-range) - (+ (- grplens-predstringsize 4) 1.49))) - ?*) - rate-string) - -(defun bbb-fmt-confidence-interval (score low high) - (if (bbb-have-confidence low high) - (format "|%4.2f-%4.2f |" low high) - (bbb-fmt-prediction-num score))) - -(defun bbb-fmt-confidence-plus-minus (score low high) - (if (bbb-have-confidence low high) - (format "|%3.1f+/-%4.2f|" score (/ (- high low) 2.0)) - (bbb-fmt-prediction-num score))) - -(defun bbb-fmt-prediction-bar (rate-string score) - (let* ((i 1) - (step (/ grplens-rating-range (- grplens-predstringsize 4))) - (half-step (/ step 2)) - (loc (- grplens-minrating half-step))) - (while (< i (- grplens-predstringsize 2)) - (if (> score loc) - (aset rate-string i ?#) - (aset rate-string i ?\ )) - (setq i (+ i 1)) - (setq loc (+ loc step))) - ) - rate-string) - -(defun bbb-fmt-prediction-num (score) - (format "| %4.2f |" score)) - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;;; Put Ratings -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -(defun bbb-put-ratings () - (if (and grouplens-bbb-token - grouplens-rating-alist - (member gnus-newsgroup-name grouplens-newsgroups)) - (let ((bbb-process (bbb-connect-to-bbbd grouplens-bbb-host - grouplens-bbb-port)) - (rate-command (bbb-build-rate-command grouplens-rating-alist))) - (if bbb-process - (save-excursion - (set-buffer (process-buffer bbb-process)) - (gnus-message 5 "Sending Ratings...") - (bbb-send-command bbb-process rate-command) - (if (bbb-read-response bbb-process) - (setq grouplens-rating-alist nil) - (gnus-message 1 - "Token timed out: call bbb-login and quit again") - (ding)) - (gnus-message 5 "Sending Ratings...Done")) - (gnus-message 3 "No BBB connection"))) - (setq grouplens-rating-alist nil))) - -(defun bbb-build-rate-command (rate-alist) - (concat "putratings " grouplens-bbb-token " " grouplens-current-group " \r\n" - (mapconcat '(lambda (this) ; form (mid . (score . time)) - (concat (car this) - " :rating=" (cadr this) ".00" - " :time=" (cddr this))) - rate-alist "\r\n") - "\r\n.\r\n")) - -;; Interactive rating functions. -(defun bbb-summary-rate-article (rating &optional midin) - (interactive "nRating: ") - (when (member gnus-newsgroup-name grouplens-newsgroups) - (let ((mid (or midin (bbb-get-current-id)))) - (if (and rating - (>= rating grplens-minrating) - (<= rating grplens-maxrating) - mid) - (let ((oldrating (assoc mid grouplens-rating-alist))) - (if oldrating - (setcdr oldrating (cons rating 0)) - (push `(,mid . (,rating . 0)) grouplens-rating-alist)) - (gnus-summary-mark-article nil (int-to-string rating))) - (gnus-message 3 "Invalid rating"))))) - -(defun grouplens-next-unread-article (rating) - "Select unread article after current one." - (interactive "P") - (when rating - (bbb-summary-rate-article rating)) - (gnus-summary-next-unread-article)) - -(defun grouplens-best-unread-article (rating) - "Select unread article after current one." - (interactive "P") - (when rating - (bbb-summary-rate-article rating)) - (gnus-summary-best-unread-article)) - -(defun grouplens-summary-catchup-and-exit (rating) - "Mark all articles not marked as unread in this newsgroup as read, then exit. -If prefix argument ALL is non-nil, all articles are marked as read." - (interactive "P") - (when rating - (bbb-summary-rate-article rating)) - (if (numberp rating) - (gnus-summary-catchup-and-exit) - (gnus-summary-catchup-and-exit rating))) - -(defun grouplens-score-thread (score) - "Raise the score of the articles in the current thread with SCORE." - (interactive "nRating: ") - (let (e) - (save-excursion - (let ((articles (gnus-summary-articles-in-thread)) - article) - (while (setq article (pop articles)) - (gnus-summary-goto-subject article) - (bbb-summary-rate-article score - (mail-header-id - (gnus-summary-article-header article))))) - (setq e (point))) - (let ((gnus-summary-check-current t)) - (or (zerop (gnus-summary-next-subject 1 t)) - (goto-char e)))) - (gnus-summary-recenter) - (gnus-summary-position-point) - (gnus-set-mode-line 'summary)) - -(defun bbb-exit-group () - (bbb-put-ratings) - (bbb-renew-hash-table)) - -(defun bbb-get-current-id () - (if gnus-current-headers - (mail-header-id gnus-current-headers) - (gnus-message 3 "You must select an article before you rate it"))) - -(defun bbb-grouplens-group-p (group) - "Say whether GROUP is a GroupLens group." - (if (member group grouplens-newsgroups) " (GroupLens Enhanced)" "")) - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; TIME SPENT READING -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -(defvar grouplens-current-starting-time nil) - -(defun grouplens-start-timer () - (setq grouplens-current-starting-time (current-time))) - -(defun grouplens-elapsed-time () - (let ((et (bbb-time-float (current-time)))) - (- et (bbb-time-float grouplens-current-starting-time)))) - -(defun bbb-time-float (timeval) - (+ (* (car timeval) 65536) - (cadr timeval))) - -(defun grouplens-do-time () - (when (member gnus-newsgroup-name grouplens-newsgroups) - (when grouplens-previous-article - (let ((elapsed-time (grouplens-elapsed-time)) - (oldrating (assoc grouplens-previous-article - grouplens-rating-alist))) - (if (not oldrating) - (push `(,grouplens-previous-article . (0 . ,elapsed-time)) - grouplens-rating-alist) - (setcdr oldrating (cons (cadr oldrating) elapsed-time))))) - (grouplens-start-timer) - (setq grouplens-previous-article (bbb-get-current-id)))) - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; BUG REPORTING -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -(defconst gnus-gl-version "gnus-gl.el 2.50") -(defconst gnus-gl-maintainer-address "grouplens-bug@cs.umn.edu") -(defun gnus-gl-submit-bug-report () - "Submit via mail a bug report on gnus-gl." - (interactive) - (require 'reporter) - (reporter-submit-bug-report gnus-gl-maintainer-address - (concat "gnus-gl.el " gnus-gl-version) - (list 'grouplens-pseudonym - 'grouplens-bbb-host - 'grouplens-bbb-port - 'grouplens-newsgroups - 'grouplens-bbb-token - 'grouplens-bbb-process - 'grouplens-current-group - 'grouplens-previous-article) - nil - 'gnus-gl-get-trace)) - -(defun gnus-gl-get-trace () - "Insert the contents of the BBBD trace buffer." - (when grouplens-bbb-buffer - (insert-buffer grouplens-bbb-buffer))) - -;; -;; GroupLens minor mode -;; - -(defvar gnus-grouplens-mode nil - "Minor mode for providing a GroupLens interface in Gnus summary buffers.") - -(defvar gnus-grouplens-mode-map nil) - -(unless gnus-grouplens-mode-map - (setq gnus-grouplens-mode-map (make-keymap)) - (gnus-define-keys - gnus-grouplens-mode-map - "n" grouplens-next-unread-article - "r" bbb-summary-rate-article - "k" grouplens-score-thread - "c" grouplens-summary-catchup-and-exit - "," grouplens-best-unread-article)) - -(defun gnus-grouplens-make-menu-bar () - (unless (boundp 'gnus-grouplens-menu) - (easy-menu-define - gnus-grouplens-menu gnus-grouplens-mode-map "" - '("GroupLens" - ["Login" bbb-login t] - ["Rate" bbb-summary-rate-article t] - ["Next article" grouplens-next-unread-article t] - ["Best article" grouplens-best-unread-article t] - ["Raise thread" grouplens-score-thread t] - ["Report bugs" gnus-gl-submit-bug-report t])))) - -(defun gnus-grouplens-mode (&optional arg) - "Minor mode for providing a GroupLens interface in Gnus summary buffers." - (interactive "P") - (when (and (eq major-mode 'gnus-summary-mode) - (member gnus-newsgroup-name grouplens-newsgroups)) - (make-local-variable 'gnus-grouplens-mode) - (setq gnus-grouplens-mode - (if (null arg) (not gnus-grouplens-mode) - (> (prefix-numeric-value arg) 0))) - (when gnus-grouplens-mode - (make-local-hook 'gnus-select-article-hook) - (add-hook 'gnus-select-article-hook 'grouplens-do-time nil 'local) - (make-local-hook 'gnus-exit-group-hook) - (add-hook 'gnus-exit-group-hook 'bbb-exit-group nil 'local) - (make-local-variable 'gnus-score-find-score-files-function) - - (cond - ((eq gnus-grouplens-override-scoring 'combine) - ;; either add bbb-buld-mid-scores-alist to a list - ;; or make a list - (if (listp gnus-score-find-score-files-function) - (setq gnus-score-find-score-files-function - (append 'bbb-build-mid-scores-alist - gnus-score-find-score-files-function)) - (setq gnus-score-find-score-files-function - (list gnus-score-find-score-files-function - 'bbb-build-mid-scores-alist)))) - ;; leave the gnus-score-find-score-files variable alone - ((eq gnus-grouplens-override-scoring 'separate) - (add-hook 'gnus-select-group-hook - (lambda () - (bbb-get-predictions (bbb-get-all-mids) - gnus-newsgroup-name)))) - ;; default is to override - (t - (setq gnus-score-find-score-files-function - 'bbb-build-mid-scores-alist))) - - ;; Change how summary lines look - (make-local-variable 'gnus-summary-line-format) - (make-local-variable 'gnus-summary-line-format-spec) - (setq gnus-summary-line-format gnus-summary-grouplens-line-format) - (setq gnus-summary-line-format-spec nil) - (gnus-update-format-specifications nil 'summary) - (gnus-update-summary-mark-positions) - - ;; Set up the menu. - (when (and menu-bar-mode - (gnus-visual-p 'grouplens-menu 'menu)) - (gnus-grouplens-make-menu-bar)) - (gnus-add-minor-mode - 'gnus-grouplens-mode " GroupLens" gnus-grouplens-mode-map) - (gnus-run-hooks 'gnus-grouplens-mode-hook)))) - -(provide 'gnus-gl) - -;;; gnus-gl.el ends here diff --git a/lisp/gnus-group.el b/lisp/gnus-group.el deleted file mode 100644 index 612be02..0000000 --- a/lisp/gnus-group.el +++ /dev/null @@ -1,3389 +0,0 @@ -;;; gnus-group.el --- group mode commands for Gnus -;; Copyright (C) 1996,97,98 Free Software Foundation, Inc. - -;; Author: Lars Magne Ingebrigtsen -;; Keywords: news - -;; This file is part of GNU Emacs. - -;; GNU Emacs is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 2, or (at your option) -;; any later version. - -;; GNU Emacs is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs; see the file COPYING. If not, write to the -;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. - -;;; Commentary: - -;;; Code: - -(eval-when-compile (require 'cl)) - -(require 'gnus) -(require 'gnus-start) -(require 'nnmail) -(require 'gnus-spec) -(require 'gnus-int) -(require 'gnus-range) -(require 'gnus-win) -(require 'gnus-undo) - -(defcustom gnus-group-archive-directory - "*ftp@ftp.hpc.uh.edu:/pub/emacs/ding-list/" - "*The address of the (ding) archives." - :group 'gnus-group-foreign - :type 'directory) - -(defcustom gnus-group-recent-archive-directory - "*ftp@ftp.hpc.uh.edu:/pub/emacs/ding-list-recent/" - "*The address of the most recent (ding) articles." - :group 'gnus-group-foreign - :type 'directory) - -(defcustom gnus-no-groups-message "No news is no news" - "*Message displayed by Gnus when no groups are available." - :group 'gnus-start - :type 'string) - -(defcustom gnus-keep-same-level nil - "*Non-nil means that the next newsgroup after the current will be on the same level. -When you type, for instance, `n' after reading the last article in the -current newsgroup, you will go to the next newsgroup. If this variable -is nil, the next newsgroup will be the next from the group -buffer. -If this variable is non-nil, Gnus will either put you in the -next newsgroup with the same level, or, if no such newsgroup is -available, the next newsgroup with the lowest possible level higher -than the current level. -If this variable is `best', Gnus will make the next newsgroup the one -with the best level." - :group 'gnus-group-levels - :type '(choice (const nil) - (const best) - (sexp :tag "other" t))) - -(defcustom gnus-group-goto-unread t - "*If non-nil, movement commands will go to the next unread and subscribed group." - :link '(custom-manual "(gnus)Group Maneuvering") - :group 'gnus-group-various - :type 'boolean) - -(defcustom gnus-goto-next-group-when-activating t - "*If non-nil, the \\\\[gnus-group-get-new-news-this-group] command will advance point to the next group." - :link '(custom-manual "(gnus)Scanning New Messages") - :group 'gnus-group-various - :type 'boolean) - -(defcustom gnus-permanently-visible-groups nil - "*Regexp to match groups that should always be listed in the group buffer. -This means that they will still be listed even when there are no -unread articles in the groups. - -If nil, no groups are permanently visible." - :group 'gnus-group-listing - :type 'regexp) - -(defcustom gnus-list-groups-with-ticked-articles t - "*If non-nil, list groups that have only ticked articles. -If nil, only list groups that have unread articles." - :group 'gnus-group-listing - :type 'boolean) - -(defcustom gnus-group-default-list-level gnus-level-subscribed - "*Default listing level. -Ignored if `gnus-group-use-permanent-levels' is non-nil." - :group 'gnus-group-listing - :type 'integer) - -(defcustom gnus-group-list-inactive-groups t - "*If non-nil, inactive groups will be listed." - :group 'gnus-group-listing - :group 'gnus-group-levels - :type 'boolean) - -(defcustom gnus-group-sort-function 'gnus-group-sort-by-alphabet - "*Function used for sorting the group buffer. -This function will be called with group info entries as the arguments -for the groups to be sorted. Pre-made functions include -`gnus-group-sort-by-alphabet', `gnus-group-sort-by-real-name', -`gnus-group-sort-by-unread', `gnus-group-sort-by-level', -`gnus-group-sort-by-score', `gnus-group-sort-by-method', and -`gnus-group-sort-by-rank'. - -This variable can also be a list of sorting functions. In that case, -the most significant sort function should be the last function in the -list." - :group 'gnus-group-listing - :link '(custom-manual "(gnus)Sorting Groups") - :type '(radio (function-item gnus-group-sort-by-alphabet) - (function-item gnus-group-sort-by-real-name) - (function-item gnus-group-sort-by-unread) - (function-item gnus-group-sort-by-level) - (function-item gnus-group-sort-by-score) - (function-item gnus-group-sort-by-method) - (function-item gnus-group-sort-by-rank) - (function :tag "other" nil))) - -(defcustom gnus-group-line-format "%M\%S\%p\%P\%5y: %(%g%)%l\n" - "*Format of group lines. -It works along the same lines as a normal formatting string, -with some simple extensions. - -%M Only marked articles (character, \"*\" or \" \") -%S Whether the group is subscribed (character, \"U\", \"K\", \"Z\" or \" \") -%L Level of subscribedness (integer) -%N Number of unread articles (integer) -%I Number of dormant articles (integer) -%i Number of ticked and dormant (integer) -%T Number of ticked articles (integer) -%R Number of read articles (integer) -%t Estimated total number of articles (integer) -%y Number of unread, unticked articles (integer) -%G Group name (string) -%g Qualified group name (string) -%D Group description (string) -%s Select method (string) -%o Moderated group (char, \"m\") -%p Process mark (char) -%O Moderated group (string, \"(m)\" or \"\") -%P Topic indentation (string) -%m Whether there is new(ish) mail in the group (char, \"%\") -%l Whether there are GroupLens predictions for this group (string) -%n Select from where (string) -%z A string that look like `<%s:%n>' if a foreign select method is used -%d The date the group was last entered. -%u User defined specifier. The next character in the format string should - be a letter. Gnus will call the function gnus-user-format-function-X, - where X is the letter following %u. The function will be passed the - current header as argument. The function should return a string, which - will be inserted into the buffer just like information from any other - group specifier. - -Text between %( and %) will be highlighted with `gnus-mouse-face' when -the mouse point move inside the area. There can only be one such area. - -Note that this format specification is not always respected. For -reasons of efficiency, when listing killed groups, this specification -is ignored altogether. If the spec is changed considerably, your -output may end up looking strange when listing both alive and killed -groups. - -If you use %o or %O, reading the active file will be slower and quite -a bit of extra memory will be used. %D will also worsen performance. -Also note that if you change the format specification to include any -of these specs, you must probably re-start Gnus to see them go into -effect." - :group 'gnus-group-visual - :type 'string) - -(defcustom gnus-group-mode-line-format "Gnus: %%b {%M\%:%S}" - "*The format specification for the group mode line. -It works along the same lines as a normal formatting string, -with some simple extensions: - -%S The native news server. -%M The native select method. -%: \":\" if %S isn't \"\"." - :group 'gnus-group-visual - :type 'string) - -(defcustom gnus-group-mode-hook nil - "Hook for Gnus group mode." - :group 'gnus-group-various - :options '(gnus-topic-mode) - :type 'hook) - -(defcustom gnus-group-menu-hook nil - "Hook run after the creation of the group mode menu." - :group 'gnus-group-various - :type 'hook) - -(defcustom gnus-group-catchup-group-hook nil - "Hook run when catching up a group from the group buffer." - :group 'gnus-group-various - :link '(custom-manual "(gnus)Group Data") - :type 'hook) - -(defcustom gnus-group-update-group-hook nil - "Hook called when updating group lines." - :group 'gnus-group-visual - :type 'hook) - -(defcustom gnus-group-prepare-function 'gnus-group-prepare-flat - "*A function that is called to generate the group buffer. -The function is called with three arguments: The first is a number; -all group with a level less or equal to that number should be listed, -if the second is non-nil, empty groups should also be displayed. If -the third is non-nil, it is a number. No groups with a level lower -than this number should be displayed. - -The only current function implemented is `gnus-group-prepare-flat'." - :group 'gnus-group-listing - :type 'function) - -(defcustom gnus-group-prepare-hook nil - "Hook called after the group buffer has been generated. -If you want to modify the group buffer, you can use this hook." - :group 'gnus-group-listing - :type 'hook) - -(defcustom gnus-suspend-gnus-hook nil - "Hook called when suspending (not exiting) Gnus." - :group 'gnus-exit - :type 'hook) - -(defcustom gnus-exit-gnus-hook nil - "Hook called when exiting Gnus." - :group 'gnus-exit - :type 'hook) - -(defcustom gnus-after-exiting-gnus-hook nil - "Hook called after exiting Gnus." - :group 'gnus-exit - :type 'hook) - -(defcustom gnus-group-update-hook '(gnus-group-highlight-line) - "Hook called when a group line is changed. -The hook will not be called if `gnus-visual' is nil. - -The default function `gnus-group-highlight-line' will -highlight the line according to the `gnus-group-highlight' -variable." - :group 'gnus-group-visual - :type 'hook) - -(defcustom gnus-useful-groups - '(("(ding) mailing list mirrored at sunsite.auc.dk" - "emacs.ding" - (nntp "sunsite.auc.dk" - (nntp-address "sunsite.auc.dk"))) - ("gnus-bug archive" - "gnus-bug" - (nndir "/ftp@ftp.ifi.uio.no:/pub/emacs/gnus/gnus-bug/")) - ("Gnus help group" - "gnus-help" - (nndoc "gnus-help" - (nndoc-article-type mbox) - (eval `(nndoc-address - ,(let ((file (nnheader-find-etc-directory - "gnus-tut.txt" t))) - (unless file - (error "Couldn't find doc group")) - file)))))) - "*Alist of useful group-server pairs." - :group 'gnus-group-listing - :type '(repeat (list (string :tag "Description") - (string :tag "Name") - (sexp :tag "Method")))) - -(defcustom gnus-group-highlight - '(;; News. - ((and (= unread 0) (not mailp) (eq level 1)) . - gnus-group-news-1-empty-face) - ((and (not mailp) (eq level 1)) . - gnus-group-news-1-face) - ((and (= unread 0) (not mailp) (eq level 2)) . - gnus-group-news-2-empty-face) - ((and (not mailp) (eq level 2)) . - gnus-group-news-2-face) - ((and (= unread 0) (not mailp) (eq level 3)) . - gnus-group-news-3-empty-face) - ((and (not mailp) (eq level 3)) . - gnus-group-news-3-face) - ((and (= unread 0) (not mailp)) . - gnus-group-news-low-empty-face) - ((and (not mailp)) . - gnus-group-news-low-face) - ;; Mail. - ((and (= unread 0) (eq level 1)) . - gnus-group-mail-1-empty-face) - ((eq level 1) . - gnus-group-mail-1-face) - ((and (= unread 0) (eq level 2)) . - gnus-group-mail-2-empty-face) - ((eq level 2) . - gnus-group-mail-2-face) - ((and (= unread 0) (eq level 3)) . - gnus-group-mail-3-empty-face) - ((eq level 3) . - gnus-group-mail-3-face) - ((= unread 0) . - gnus-group-mail-low-empty-face) - (t . - gnus-group-mail-low-face)) - "*Controls the highlighting of group buffer lines. - -Below is a list of `Form'/`Face' pairs. When deciding how a a -particular group line should be displayed, each form is -evaluated. The content of the face field after the first true form is -used. You can change how those group lines are displayed by -editing the face field. - -It is also possible to change and add form fields, but currently that -requires an understanding of Lisp expressions. Hopefully this will -change in a future release. For now, you can use the following -variables in the Lisp expression: - -group: The name of the group. -unread: The number of unread articles in the group. -method: The select method used. -mailp: Whether it's a mail group or not. -level: The level of the group. -score: The score of the group. -ticked: The number of ticked articles." - :group 'gnus-group-visual - :type '(repeat (cons (sexp :tag "Form") face))) - -(defcustom gnus-new-mail-mark ?% - "Mark used for groups with new mail." - :group 'gnus-group-visual - :type 'character) - -;;; Internal variables - -(defvar gnus-group-sort-alist-function 'gnus-group-sort-flat - "Function for sorting the group buffer.") - -(defvar gnus-group-sort-selected-function 'gnus-group-sort-selected-flat - "Function for sorting the selected groups in the group buffer.") - -(defvar gnus-group-indentation-function nil) -(defvar gnus-goto-missing-group-function nil) -(defvar gnus-group-update-group-function nil) -(defvar gnus-group-goto-next-group-function nil - "Function to override finding the next group after listing groups.") - -(defvar gnus-group-edit-buffer nil) - -(defvar gnus-group-line-format-alist - `((?M gnus-tmp-marked-mark ?c) - (?S gnus-tmp-subscribed ?c) - (?L gnus-tmp-level ?d) - (?N (cond ((eq number t) "*" ) - ((numberp number) - (int-to-string - (+ number - (gnus-range-length (cdr (assq 'dormant gnus-tmp-marked))) - (gnus-range-length (cdr (assq 'tick gnus-tmp-marked)))))) - (t number)) ?s) - (?R gnus-tmp-number-of-read ?s) - (?t gnus-tmp-number-total ?d) - (?y gnus-tmp-number-of-unread ?s) - (?I (gnus-range-length (cdr (assq 'dormant gnus-tmp-marked))) ?d) - (?T (gnus-range-length (cdr (assq 'tick gnus-tmp-marked))) ?d) - (?i (+ (gnus-range-length (cdr (assq 'dormant gnus-tmp-marked))) - (gnus-range-length (cdr (assq 'tick gnus-tmp-marked)))) ?d) - (?g gnus-tmp-group ?s) - (?G gnus-tmp-qualified-group ?s) - (?c (gnus-short-group-name gnus-tmp-group) ?s) - (?D gnus-tmp-newsgroup-description ?s) - (?o gnus-tmp-moderated ?c) - (?O gnus-tmp-moderated-string ?s) - (?p gnus-tmp-process-marked ?c) - (?s gnus-tmp-news-server ?s) - (?n gnus-tmp-news-method ?s) - (?P gnus-group-indentation ?s) - (?l gnus-tmp-grouplens ?s) - (?z gnus-tmp-news-method-string ?s) - (?m (gnus-group-new-mail gnus-tmp-group) ?c) - (?d (gnus-group-timestamp-string gnus-tmp-group) ?s) - (?u gnus-tmp-user-defined ?s))) - -(defvar gnus-group-mode-line-format-alist - `((?S gnus-tmp-news-server ?s) - (?M gnus-tmp-news-method ?s) - (?u gnus-tmp-user-defined ?s) - (?: gnus-tmp-colon ?s))) - -(defvar gnus-topic-topology nil - "The complete topic hierarchy.") - -(defvar gnus-topic-alist nil - "The complete topic-group alist.") - -(defvar gnus-group-marked nil) - -(defvar gnus-group-list-mode nil) - -;;; -;;; Gnus group mode -;;; - -(put 'gnus-group-mode 'mode-class 'special) - -(when t - (gnus-define-keys gnus-group-mode-map - " " gnus-group-read-group - "=" gnus-group-select-group - "\r" gnus-group-select-group - "\M-\r" gnus-group-quick-select-group - [(meta control return)] gnus-group-select-group-ephemerally - "j" gnus-group-jump-to-group - "n" gnus-group-next-unread-group - "p" gnus-group-prev-unread-group - "\177" gnus-group-prev-unread-group - [delete] gnus-group-prev-unread-group - [backspace] gnus-group-prev-unread-group - "N" gnus-group-next-group - "P" gnus-group-prev-group - "\M-n" gnus-group-next-unread-group-same-level - "\M-p" gnus-group-prev-unread-group-same-level - "," gnus-group-best-unread-group - "." gnus-group-first-unread-group - "u" gnus-group-unsubscribe-current-group - "U" gnus-group-unsubscribe-group - "c" gnus-group-catchup-current - "C" gnus-group-catchup-current-all - "\M-c" gnus-group-clear-data - "l" gnus-group-list-groups - "L" gnus-group-list-all-groups - "m" gnus-group-mail - "g" gnus-group-get-new-news - "\M-g" gnus-group-get-new-news-this-group - "R" gnus-group-restart - "r" gnus-group-read-init-file - "B" gnus-group-browse-foreign-server - "b" gnus-group-check-bogus-groups - "F" gnus-group-find-new-groups - "\C-c\C-d" gnus-group-describe-group - "\M-d" gnus-group-describe-all-groups - "\C-c\C-a" gnus-group-apropos - "\C-c\M-\C-a" gnus-group-description-apropos - "a" gnus-group-post-news - "\ek" gnus-group-edit-local-kill - "\eK" gnus-group-edit-global-kill - "\C-k" gnus-group-kill-group - "\C-y" gnus-group-yank-group - "\C-w" gnus-group-kill-region - "\C-x\C-t" gnus-group-transpose-groups - "\C-c\C-l" gnus-group-list-killed - "\C-c\C-x" gnus-group-expire-articles - "\C-c\M-\C-x" gnus-group-expire-all-groups - "V" gnus-version - "s" gnus-group-save-newsrc - "z" gnus-group-suspend - "q" gnus-group-exit - "Q" gnus-group-quit - "?" gnus-group-describe-briefly - "\C-c\C-i" gnus-info-find-node - "\M-e" gnus-group-edit-group-method - "^" gnus-group-enter-server-mode - gnus-mouse-2 gnus-mouse-pick-group - "<" beginning-of-buffer - ">" end-of-buffer - "\C-c\C-b" gnus-bug - "\C-c\C-s" gnus-group-sort-groups - "t" gnus-topic-mode - "\C-c\M-g" gnus-activate-all-groups - "\M-&" gnus-group-universal-argument - "#" gnus-group-mark-group - "\M-#" gnus-group-unmark-group) - - (gnus-define-keys (gnus-group-mark-map "M" gnus-group-mode-map) - "m" gnus-group-mark-group - "u" gnus-group-unmark-group - "w" gnus-group-mark-region - "b" gnus-group-mark-buffer - "r" gnus-group-mark-regexp - "U" gnus-group-unmark-all-groups) - - (gnus-define-keys (gnus-group-group-map "G" gnus-group-mode-map) - "d" gnus-group-make-directory-group - "h" gnus-group-make-help-group - "u" gnus-group-make-useful-group - "a" gnus-group-make-archive-group - "k" gnus-group-make-kiboze-group - "m" gnus-group-make-group - "E" gnus-group-edit-group - "e" gnus-group-edit-group-method - "p" gnus-group-edit-group-parameters - "v" gnus-group-add-to-virtual - "V" gnus-group-make-empty-virtual - "D" gnus-group-enter-directory - "f" gnus-group-make-doc-group - "w" gnus-group-make-web-group - "r" gnus-group-rename-group - "c" gnus-group-customize - "\177" gnus-group-delete-group - [delete] gnus-group-delete-group) - - (gnus-define-keys (gnus-group-soup-map "s" gnus-group-group-map) - "b" gnus-group-brew-soup - "w" gnus-soup-save-areas - "s" gnus-soup-send-replies - "p" gnus-soup-pack-packet - "r" nnsoup-pack-replies) - - (gnus-define-keys (gnus-group-sort-map "S" gnus-group-group-map) - "s" gnus-group-sort-groups - "a" gnus-group-sort-groups-by-alphabet - "u" gnus-group-sort-groups-by-unread - "l" gnus-group-sort-groups-by-level - "v" gnus-group-sort-groups-by-score - "r" gnus-group-sort-groups-by-rank - "m" gnus-group-sort-groups-by-method) - - (gnus-define-keys (gnus-group-sort-selected-map "P" gnus-group-group-map) - "s" gnus-group-sort-selected-groups - "a" gnus-group-sort-selected-groups-by-alphabet - "u" gnus-group-sort-selected-groups-by-unread - "l" gnus-group-sort-selected-groups-by-level - "v" gnus-group-sort-selected-groups-by-score - "r" gnus-group-sort-selected-groups-by-rank - "m" gnus-group-sort-selected-groups-by-method) - - (gnus-define-keys (gnus-group-list-map "A" gnus-group-mode-map) - "k" gnus-group-list-killed - "z" gnus-group-list-zombies - "s" gnus-group-list-groups - "u" gnus-group-list-all-groups - "A" gnus-group-list-active - "a" gnus-group-apropos - "d" gnus-group-description-apropos - "m" gnus-group-list-matching - "M" gnus-group-list-all-matching - "l" gnus-group-list-level) - - (gnus-define-keys (gnus-group-score-map "W" gnus-group-mode-map) - "f" gnus-score-flush-cache) - - (gnus-define-keys (gnus-group-help-map "H" gnus-group-mode-map) - "d" gnus-group-describe-group - "f" gnus-group-fetch-faq - "v" gnus-version) - - (gnus-define-keys (gnus-group-sub-map "S" gnus-group-mode-map) - "l" gnus-group-set-current-level - "t" gnus-group-unsubscribe-current-group - "s" gnus-group-unsubscribe-group - "k" gnus-group-kill-group - "y" gnus-group-yank-group - "w" gnus-group-kill-region - "\C-k" gnus-group-kill-level - "z" gnus-group-kill-all-zombies)) - -(defun gnus-group-make-menu-bar () - (gnus-turn-off-edit-menu 'group) - (unless (boundp 'gnus-group-reading-menu) - - (easy-menu-define - gnus-group-reading-menu gnus-group-mode-map "" - '("Group" - ["Read" gnus-group-read-group (gnus-group-group-name)] - ["Select" gnus-group-select-group (gnus-group-group-name)] - ["See old articles" (gnus-group-select-group 'all) - :keys "C-u SPC" :active (gnus-group-group-name)] - ["Catch up" gnus-group-catchup-current (gnus-group-group-name)] - ["Catch up all articles" gnus-group-catchup-current-all - (gnus-group-group-name)] - ["Check for new articles" gnus-group-get-new-news-this-group - (gnus-group-group-name)] - ["Toggle subscription" gnus-group-unsubscribe-current-group - (gnus-group-group-name)] - ["Kill" gnus-group-kill-group (gnus-group-group-name)] - ["Yank" gnus-group-yank-group gnus-list-of-killed-groups] - ["Describe" gnus-group-describe-group (gnus-group-group-name)] - ["Fetch FAQ" gnus-group-fetch-faq (gnus-group-group-name)] - ;; Actually one should check, if any of the marked groups gives t for - ;; (gnus-check-backend-function 'request-expire-articles ...) - ["Expire articles" gnus-group-expire-articles - (or (and (gnus-group-group-name) - (gnus-check-backend-function - 'request-expire-articles - (gnus-group-group-name))) gnus-group-marked)] - ["Set group level" gnus-group-set-current-level - (gnus-group-group-name)] - ["Select quick" gnus-group-quick-select-group (gnus-group-group-name)] - ["Customize" gnus-group-customize (gnus-group-group-name)] - ("Edit" - ["Parameters" gnus-group-edit-group-parameters - (gnus-group-group-name)] - ["Select method" gnus-group-edit-group-method - (gnus-group-group-name)] - ["Info" gnus-group-edit-group (gnus-group-group-name)] - ["Local kill file" gnus-group-edit-local-kill (gnus-group-group-name)] - ["Global kill file" gnus-group-edit-global-kill t]))) - - (easy-menu-define - gnus-group-group-menu gnus-group-mode-map "" - '("Groups" - ("Listing" - ["List unread subscribed groups" gnus-group-list-groups t] - ["List (un)subscribed groups" gnus-group-list-all-groups t] - ["List killed groups" gnus-group-list-killed gnus-killed-list] - ["List zombie groups" gnus-group-list-zombies gnus-zombie-list] - ["List level..." gnus-group-list-level t] - ["Describe all groups" gnus-group-describe-all-groups t] - ["Group apropos..." gnus-group-apropos t] - ["Group and description apropos..." gnus-group-description-apropos t] - ["List groups matching..." gnus-group-list-matching t] - ["List all groups matching..." gnus-group-list-all-matching t] - ["List active file" gnus-group-list-active t]) - ("Sort" - ["Default sort" gnus-group-sort-groups t] - ["Sort by method" gnus-group-sort-groups-by-method t] - ["Sort by rank" gnus-group-sort-groups-by-rank t] - ["Sort by score" gnus-group-sort-groups-by-score t] - ["Sort by level" gnus-group-sort-groups-by-level t] - ["Sort by unread" gnus-group-sort-groups-by-unread t] - ["Sort by name" gnus-group-sort-groups-by-alphabet t]) - ("Sort process/prefixed" - ["Default sort" gnus-group-sort-selected-groups - (or (not (boundp 'gnus-topic-mode)) (not gnus-topic-mode))] - ["Sort by method" gnus-group-sort-selected-groups-by-method - (or (not (boundp 'gnus-topic-mode)) (not gnus-topic-mode))] - ["Sort by rank" gnus-group-sort-selected-groups-by-rank - (or (not (boundp 'gnus-topic-mode)) (not gnus-topic-mode))] - ["Sort by score" gnus-group-sort-selected-groups-by-score - (or (not (boundp 'gnus-topic-mode)) (not gnus-topic-mode))] - ["Sort by level" gnus-group-sort-selected-groups-by-level - (or (not (boundp 'gnus-topic-mode)) (not gnus-topic-mode))] - ["Sort by unread" gnus-group-sort-selected-groups-by-unread - (or (not (boundp 'gnus-topic-mode)) (not gnus-topic-mode))] - ["Sort by name" gnus-group-sort-selected-groups-by-alphabet - (or (not (boundp 'gnus-topic-mode)) (not gnus-topic-mode))]) - ("Mark" - ["Mark group" gnus-group-mark-group - (and (gnus-group-group-name) - (not (memq (gnus-group-group-name) gnus-group-marked)))] - ["Unmark group" gnus-group-unmark-group - (and (gnus-group-group-name) - (memq (gnus-group-group-name) gnus-group-marked))] - ["Unmark all" gnus-group-unmark-all-groups gnus-group-marked] - ["Mark regexp..." gnus-group-mark-regexp t] - ["Mark region" gnus-group-mark-region t] - ["Mark buffer" gnus-group-mark-buffer t] - ["Execute command" gnus-group-universal-argument - (or gnus-group-marked (gnus-group-group-name))]) - ("Subscribe" - ["Subscribe to a group" gnus-group-unsubscribe-group t] - ["Kill all newsgroups in region" gnus-group-kill-region t] - ["Kill all zombie groups" gnus-group-kill-all-zombies - gnus-zombie-list] - ["Kill all groups on level..." gnus-group-kill-level t]) - ("Foreign groups" - ["Make a foreign group" gnus-group-make-group t] - ["Add a directory group" gnus-group-make-directory-group t] - ["Add the help group" gnus-group-make-help-group t] - ["Add the archive group" gnus-group-make-archive-group t] - ["Make a doc group" gnus-group-make-doc-group t] - ["Make a web group" gnus-group-make-web-group t] - ["Make a kiboze group" gnus-group-make-kiboze-group t] - ["Make a virtual group" gnus-group-make-empty-virtual t] - ["Add a group to a virtual" gnus-group-add-to-virtual t] - ["Rename group" gnus-group-rename-group - (gnus-check-backend-function - 'request-rename-group (gnus-group-group-name))] - ["Delete group" gnus-group-delete-group - (gnus-check-backend-function - 'request-delete-group (gnus-group-group-name))]) - ("Move" - ["Next" gnus-group-next-group t] - ["Previous" gnus-group-prev-group t] - ["Next unread" gnus-group-next-unread-group t] - ["Previous unread" gnus-group-prev-unread-group t] - ["Next unread same level" gnus-group-next-unread-group-same-level t] - ["Previous unread same level" - gnus-group-prev-unread-group-same-level t] - ["Jump to group" gnus-group-jump-to-group t] - ["First unread group" gnus-group-first-unread-group t] - ["Best unread group" gnus-group-best-unread-group t]) - ["Delete bogus groups" gnus-group-check-bogus-groups t] - ["Find new newsgroups" gnus-group-find-new-groups t] - ["Transpose" gnus-group-transpose-groups - (gnus-group-group-name)] - ["Read a directory as a group..." gnus-group-enter-directory t])) - - (easy-menu-define - gnus-group-misc-menu gnus-group-mode-map "" - '("Misc" - ("SOUP" - ["Pack replies" nnsoup-pack-replies (fboundp 'nnsoup-request-group)] - ["Send replies" gnus-soup-send-replies - (fboundp 'gnus-soup-pack-packet)] - ["Pack packet" gnus-soup-pack-packet (fboundp 'gnus-soup-pack-packet)] - ["Save areas" gnus-soup-save-areas (fboundp 'gnus-soup-pack-packet)] - ["Brew SOUP" gnus-group-brew-soup (fboundp 'gnus-soup-pack-packet)]) - ["Send a bug report" gnus-bug t] - ["Send a mail" gnus-group-mail t] - ["Post an article..." gnus-group-post-news t] - ["Check for new news" gnus-group-get-new-news t] - ["Activate all groups" gnus-activate-all-groups t] - ["Restart Gnus" gnus-group-restart t] - ["Read init file" gnus-group-read-init-file t] - ["Browse foreign server" gnus-group-browse-foreign-server t] - ["Enter server buffer" gnus-group-enter-server-mode t] - ["Expire all expirable articles" gnus-group-expire-all-groups t] - ["Generate any kiboze groups" nnkiboze-generate-groups t] - ["Gnus version" gnus-version t] - ["Save .newsrc files" gnus-group-save-newsrc t] - ["Suspend Gnus" gnus-group-suspend t] - ["Clear dribble buffer" gnus-group-clear-dribble t] - ["Read manual" gnus-info-find-node t] - ["Flush score cache" gnus-score-flush-cache t] - ["Toggle topics" gnus-topic-mode t] - ["Send a bug report" gnus-bug t] - ["Exit from Gnus" gnus-group-exit t] - ["Exit without saving" gnus-group-quit t])) - - (gnus-run-hooks 'gnus-group-menu-hook))) - -(defun gnus-group-mode () - "Major mode for reading news. - -All normal editing commands are switched off. -\\ -The group buffer lists (some of) the groups available. For instance, -`\\[gnus-group-list-groups]' will list all subscribed groups with unread articles, while `\\[gnus-group-list-zombies]' -lists all zombie groups. - -Groups that are displayed can be entered with `\\[gnus-group-read-group]'. To subscribe -to a group not displayed, type `\\[gnus-group-unsubscribe-group]'. - -For more in-depth information on this mode, read the manual (`\\[gnus-info-find-node]'). - -The following commands are available: - -\\{gnus-group-mode-map}" - (interactive) - (when (gnus-visual-p 'group-menu 'menu) - (gnus-group-make-menu-bar)) - (kill-all-local-variables) - (gnus-simplify-mode-line) - (setq major-mode 'gnus-group-mode) - (setq mode-name "Group") - (gnus-group-set-mode-line) - (setq mode-line-process nil) - (use-local-map gnus-group-mode-map) - (buffer-disable-undo (current-buffer)) - (setq truncate-lines t) - (setq buffer-read-only t) - (gnus-set-default-directory) - (gnus-update-format-specifications nil 'group 'group-mode) - (gnus-update-group-mark-positions) - (make-local-hook 'post-command-hook) - (add-hook 'post-command-hook 'gnus-clear-inboxes-moved nil t) - (when gnus-use-undo - (gnus-undo-mode 1)) - (when gnus-slave - (gnus-slave-mode)) - (gnus-run-hooks 'gnus-group-mode-hook)) - -(defun gnus-update-group-mark-positions () - (save-excursion - (let ((gnus-process-mark ?\200) - (gnus-group-marked '("dummy.group")) - (gnus-active-hashtb (make-vector 10 0)) - (topic "")) - (gnus-set-active "dummy.group" '(0 . 0)) - (gnus-set-work-buffer) - (gnus-group-insert-group-line "dummy.group" 0 nil 0 nil) - (goto-char (point-min)) - (setq gnus-group-mark-positions - (list (cons 'process (and (search-forward "\200" nil t) - (- (point) 2)))))))) - -(defun gnus-clear-inboxes-moved () - (setq nnmail-moved-inboxes nil)) - -(defun gnus-mouse-pick-group (e) - "Enter the group under the mouse pointer." - (interactive "e") - (mouse-set-point e) - (gnus-group-read-group nil)) - -;; Look at LEVEL and find out what the level is really supposed to be. -;; If LEVEL is non-nil, LEVEL will be returned, if not, what happens -;; will depend on whether `gnus-group-use-permanent-levels' is used. -(defun gnus-group-default-level (&optional level number-or-nil) - (cond - (gnus-group-use-permanent-levels - (or (setq gnus-group-use-permanent-levels - (or level (if (numberp gnus-group-use-permanent-levels) - gnus-group-use-permanent-levels - (or gnus-group-default-list-level - gnus-level-subscribed)))) - gnus-group-default-list-level gnus-level-subscribed)) - (number-or-nil - level) - (t - (or level gnus-group-default-list-level gnus-level-subscribed)))) - -(defun gnus-group-setup-buffer () - (set-buffer (gnus-get-buffer-create gnus-group-buffer)) - (unless (eq major-mode 'gnus-group-mode) - (gnus-group-mode) - (when gnus-carpal - (gnus-carpal-setup-buffer 'group)))) - -(defun gnus-group-list-groups (&optional level unread lowest) - "List newsgroups with level LEVEL or lower that have unread articles. -Default is all subscribed groups. -If argument UNREAD is non-nil, groups with no unread articles are also -listed. - -Also see the `gnus-group-use-permanent-levels' variable." - (interactive - (list (if current-prefix-arg - (prefix-numeric-value current-prefix-arg) - (or - (gnus-group-default-level nil t) - gnus-group-default-list-level - gnus-level-subscribed)))) - ;; Just do this here, for no particular good reason. - (gnus-clear-inboxes-moved) - (unless level - (setq level (car gnus-group-list-mode) - unread (cdr gnus-group-list-mode))) - (setq level (gnus-group-default-level level)) - (gnus-group-setup-buffer) - (gnus-update-format-specifications nil 'group 'group-mode) - (let ((case-fold-search nil) - (props (text-properties-at (gnus-point-at-bol))) - (empty (= (point-min) (point-max))) - (group (gnus-group-group-name)) - number) - (set-buffer gnus-group-buffer) - (setq number (funcall gnus-group-prepare-function level unread lowest)) - (when (or (and (numberp number) - (zerop number)) - (zerop (buffer-size))) - ;; No groups in the buffer. - (gnus-message 5 gnus-no-groups-message)) - ;; We have some groups displayed. - (goto-char (point-max)) - (when (or (not gnus-group-goto-next-group-function) - (not (funcall gnus-group-goto-next-group-function - group props))) - (cond - (empty - (goto-char (point-min))) - ((not group) - ;; Go to the first group with unread articles. - (gnus-group-search-forward t)) - (t - ;; Find the right group to put point on. If the current group - ;; has disappeared in the new listing, try to find the next - ;; one. If no next one can be found, just leave point at the - ;; first newsgroup in the buffer. - (when (not (gnus-goto-char - (text-property-any - (point-min) (point-max) - 'gnus-group (gnus-intern-safe - group gnus-active-hashtb)))) - (let ((newsrc (cdddr (gnus-gethash group gnus-newsrc-hashtb)))) - (while (and newsrc - (not (gnus-goto-char - (text-property-any - (point-min) (point-max) 'gnus-group - (gnus-intern-safe - (caar newsrc) gnus-active-hashtb))))) - (setq newsrc (cdr newsrc))) - (unless newsrc - (goto-char (point-max)) - (forward-line -1))))))) - ;; Adjust cursor point. - (gnus-group-position-point))) - -(defun gnus-group-list-level (level &optional all) - "List groups on LEVEL. -If ALL (the prefix), also list groups that have no unread articles." - (interactive "nList groups on level: \nP") - (gnus-group-list-groups level all level)) - -(defun gnus-group-prepare-flat (level &optional all lowest regexp) - "List all newsgroups with unread articles of level LEVEL or lower. -If ALL is non-nil, list groups that have no unread articles. -If LOWEST is non-nil, list all newsgroups of level LOWEST or higher. -If REGEXP, only list groups matching REGEXP." - (set-buffer gnus-group-buffer) - (let ((buffer-read-only nil) - (newsrc (cdr gnus-newsrc-alist)) - (lowest (or lowest 1)) - info clevel unread group params) - (erase-buffer) - (when (< lowest gnus-level-zombie) - ;; List living groups. - (while newsrc - (setq info (car newsrc) - group (gnus-info-group info) - params (gnus-info-params info) - newsrc (cdr newsrc) - unread (car (gnus-gethash group gnus-newsrc-hashtb))) - (and unread ; This group might be bogus - (or (not regexp) - (string-match regexp group)) - (<= (setq clevel (gnus-info-level info)) level) - (>= clevel lowest) - (or all ; We list all groups? - (if (eq unread t) ; Unactivated? - gnus-group-list-inactive-groups ; We list unactivated - (> unread 0)) ; We list groups with unread articles - (and gnus-list-groups-with-ticked-articles - (cdr (assq 'tick (gnus-info-marks info)))) - ; And groups with tickeds - ;; Check for permanent visibility. - (and gnus-permanently-visible-groups - (string-match gnus-permanently-visible-groups - group)) - (memq 'visible params) - (cdr (assq 'visible params))) - (gnus-group-insert-group-line - group (gnus-info-level info) - (gnus-info-marks info) unread (gnus-info-method info))))) - - ;; List dead groups. - (and (>= level gnus-level-zombie) (<= lowest gnus-level-zombie) - (gnus-group-prepare-flat-list-dead - (setq gnus-zombie-list (sort gnus-zombie-list 'string<)) - gnus-level-zombie ?Z - regexp)) - (and (>= level gnus-level-killed) (<= lowest gnus-level-killed) - (gnus-group-prepare-flat-list-dead - (setq gnus-killed-list (sort gnus-killed-list 'string<)) - gnus-level-killed ?K regexp)) - - (gnus-group-set-mode-line) - (setq gnus-group-list-mode (cons level all)) - (gnus-run-hooks 'gnus-group-prepare-hook) - t)) - -(defun gnus-group-prepare-flat-list-dead (groups level mark regexp) - ;; List zombies and killed lists somewhat faster, which was - ;; suggested by Jack Vinson . It does - ;; this by ignoring the group format specification altogether. - (let (group) - (if regexp - ;; This loop is used when listing groups that match some - ;; regexp. - (while groups - (setq group (pop groups)) - (when (string-match regexp group) - (gnus-add-text-properties - (point) (prog1 (1+ (point)) - (insert " " mark " *: " group "\n")) - (list 'gnus-group (gnus-intern-safe group gnus-active-hashtb) - 'gnus-unread t - 'gnus-level level)))) - ;; This loop is used when listing all groups. - (while groups - (gnus-add-text-properties - (point) (prog1 (1+ (point)) - (insert " " mark " *: " - (setq group (pop groups)) "\n")) - (list 'gnus-group (gnus-intern-safe group gnus-active-hashtb) - 'gnus-unread t - 'gnus-level level)))))) - -(defun gnus-group-update-group-line () - "Update the current line in the group buffer." - (let* ((buffer-read-only nil) - (group (gnus-group-group-name)) - (entry (and group (gnus-gethash group gnus-newsrc-hashtb))) - gnus-group-indentation) - (when group - (and entry - (not (gnus-ephemeral-group-p group)) - (gnus-dribble-enter - (concat "(gnus-group-set-info '" - (gnus-prin1-to-string (nth 2 entry)) - ")"))) - (setq gnus-group-indentation (gnus-group-group-indentation)) - (gnus-delete-line) - (gnus-group-insert-group-line-info group) - (forward-line -1) - (gnus-group-position-point)))) - -(defun gnus-group-insert-group-line-info (group) - "Insert GROUP on the current line." - (let ((entry (gnus-gethash group gnus-newsrc-hashtb)) - (gnus-group-indentation (gnus-group-group-indentation)) - active info) - (if entry - (progn - ;; (Un)subscribed group. - (setq info (nth 2 entry)) - (gnus-group-insert-group-line - group (gnus-info-level info) (gnus-info-marks info) - (or (car entry) t) (gnus-info-method info))) - ;; This group is dead. - (gnus-group-insert-group-line - group - (if (member group gnus-zombie-list) gnus-level-zombie gnus-level-killed) - nil - (if (setq active (gnus-active group)) - (if (zerop (cdr active)) - 0 - (- (1+ (cdr active)) (car active))) - nil) - nil)))) - -(defun gnus-group-insert-group-line (gnus-tmp-group gnus-tmp-level - gnus-tmp-marked number - gnus-tmp-method) - "Insert a group line in the group buffer." - (let* ((gnus-tmp-active (gnus-active gnus-tmp-group)) - (gnus-tmp-number-total - (if gnus-tmp-active - (1+ (- (cdr gnus-tmp-active) (car gnus-tmp-active))) - 0)) - (gnus-tmp-number-of-unread - (if (numberp number) (int-to-string (max 0 number)) - "*")) - (gnus-tmp-number-of-read - (if (numberp number) - (int-to-string (max 0 (- gnus-tmp-number-total number))) - "*")) - (gnus-tmp-subscribed - (cond ((<= gnus-tmp-level gnus-level-subscribed) ? ) - ((<= gnus-tmp-level gnus-level-unsubscribed) ?U) - ((= gnus-tmp-level gnus-level-zombie) ?Z) - (t ?K))) - (gnus-tmp-qualified-group (gnus-group-real-name gnus-tmp-group)) - (gnus-tmp-newsgroup-description - (if gnus-description-hashtb - (or (gnus-gethash gnus-tmp-group gnus-description-hashtb) "") - "")) - (gnus-tmp-moderated - (if (and gnus-moderated-hashtb - (gnus-gethash gnus-tmp-group gnus-moderated-hashtb)) - ?m ? )) - (gnus-tmp-moderated-string - (if (eq gnus-tmp-moderated ?m) "(m)" "")) - (gnus-tmp-method - (gnus-server-get-method gnus-tmp-group gnus-tmp-method)) ; - (gnus-tmp-news-server (or (cadr gnus-tmp-method) "")) - (gnus-tmp-news-method (or (car gnus-tmp-method) "")) - (gnus-tmp-news-method-string - (if gnus-tmp-method - (format "(%s:%s)" (car gnus-tmp-method) - (cadr gnus-tmp-method)) "")) - (gnus-tmp-marked-mark - (if (and (numberp number) - (zerop number) - (cdr (assq 'tick gnus-tmp-marked))) - ?* ? )) - (gnus-tmp-process-marked - (if (member gnus-tmp-group gnus-group-marked) - gnus-process-mark ? )) - (gnus-tmp-grouplens - (or (and gnus-use-grouplens - (bbb-grouplens-group-p gnus-tmp-group)) - "")) - (buffer-read-only nil) - header gnus-tmp-header) ; passed as parameter to user-funcs. - (beginning-of-line) - (gnus-add-text-properties - (point) - (prog1 (1+ (point)) - ;; Insert the text. - (eval gnus-group-line-format-spec)) - `(gnus-group ,(gnus-intern-safe gnus-tmp-group gnus-active-hashtb) - gnus-unread ,(if (numberp number) - (string-to-int gnus-tmp-number-of-unread) - t) - gnus-marked ,gnus-tmp-marked-mark - gnus-indentation ,gnus-group-indentation - gnus-level ,gnus-tmp-level)) - (when (inline (gnus-visual-p 'group-highlight 'highlight)) - (forward-line -1) - (gnus-run-hooks 'gnus-group-update-hook) - (forward-line)) - ;; Allow XEmacs to remove front-sticky text properties. - (gnus-group-remove-excess-properties))) - -(defun gnus-group-highlight-line () - "Highlight the current line according to `gnus-group-highlight'." - (let* ((list gnus-group-highlight) - (p (point)) - (end (progn (end-of-line) (point))) - ;; now find out where the line starts and leave point there. - (beg (progn (beginning-of-line) (point))) - (group (gnus-group-group-name)) - (entry (gnus-group-entry group)) - (unread (if (numberp (car entry)) (car entry) 0)) - (active (gnus-active group)) - (total (if active (1+ (- (cdr active) (car active))) 0)) - (info (nth 2 entry)) - (method (gnus-server-get-method group (gnus-info-method info))) - (marked (gnus-info-marks info)) - (mailp (memq 'mail (assoc (symbol-name - (car (or method gnus-select-method))) - gnus-valid-select-methods))) - (level (or (gnus-info-level info) gnus-level-killed)) - (score (or (gnus-info-score info) 0)) - (ticked (gnus-range-length (cdr (assq 'tick marked)))) - (group-age (gnus-group-timestamp-delta group)) - (inhibit-read-only t)) - ;; Eval the cars of the lists until we find a match. - (while (and list - (not (eval (caar list)))) - (setq list (cdr list))) - (let ((face (cdar list))) - (unless (eq face (get-text-property beg 'face)) - (gnus-put-text-property-excluding-characters-with-faces - beg end 'face - (setq face (if (boundp face) (symbol-value face) face))) - (gnus-extent-start-open beg))) - (goto-char p))) - -(defun gnus-group-update-group (group &optional visible-only) - "Update all lines where GROUP appear. -If VISIBLE-ONLY is non-nil, the group won't be displayed if it isn't -already." - ;; Can't use `save-excursion' here, so we do it manually. - (let ((buf (current-buffer)) - mark) - (set-buffer gnus-group-buffer) - (setq mark (point-marker)) - ;; The buffer may be narrowed. - (save-restriction - (widen) - (let ((ident (gnus-intern-safe group gnus-active-hashtb)) - (loc (point-min)) - found buffer-read-only) - ;; Enter the current status into the dribble buffer. - (let ((entry (gnus-gethash group gnus-newsrc-hashtb))) - (when (and entry - (not (gnus-ephemeral-group-p group))) - (gnus-dribble-enter - (concat "(gnus-group-set-info '" - (gnus-prin1-to-string (nth 2 entry)) - ")")))) - ;; Find all group instances. If topics are in use, each group - ;; may be listed in more than once. - (while (setq loc (text-property-any - loc (point-max) 'gnus-group ident)) - (setq found t) - (goto-char loc) - (let ((gnus-group-indentation (gnus-group-group-indentation))) - (gnus-delete-line) - (gnus-group-insert-group-line-info group) - (save-excursion - (forward-line -1) - (gnus-run-hooks 'gnus-group-update-group-hook))) - (setq loc (1+ loc))) - (unless (or found visible-only) - ;; No such line in the buffer, find out where it's supposed to - ;; go, and insert it there (or at the end of the buffer). - (if gnus-goto-missing-group-function - (funcall gnus-goto-missing-group-function group) - (let ((entry (cddr (gnus-gethash group gnus-newsrc-hashtb)))) - (while (and entry (car entry) - (not - (gnus-goto-char - (text-property-any - (point-min) (point-max) - 'gnus-group (gnus-intern-safe - (caar entry) gnus-active-hashtb))))) - (setq entry (cdr entry))) - (or entry (goto-char (point-max))))) - ;; Finally insert the line. - (let ((gnus-group-indentation (gnus-group-group-indentation))) - (gnus-group-insert-group-line-info group) - (save-excursion - (forward-line -1) - (gnus-run-hooks 'gnus-group-update-group-hook)))) - (when gnus-group-update-group-function - (funcall gnus-group-update-group-function group)) - (gnus-group-set-mode-line))) - (goto-char mark) - (set-marker mark nil) - (set-buffer buf))) - -(defun gnus-group-set-mode-line () - "Update the mode line in the group buffer." - (when (memq 'group gnus-updated-mode-lines) - ;; Yes, we want to keep this mode line updated. - (save-excursion - (set-buffer gnus-group-buffer) - (let* ((gformat (or gnus-group-mode-line-format-spec - (gnus-set-format 'group-mode))) - (gnus-tmp-news-server (cadr gnus-select-method)) - (gnus-tmp-news-method (car gnus-select-method)) - (gnus-tmp-colon (if (equal gnus-tmp-news-server "") "" ":")) - (max-len 60) - gnus-tmp-header ;Dummy binding for user-defined formats - ;; Get the resulting string. - (modified - (and gnus-dribble-buffer - (buffer-name gnus-dribble-buffer) - (buffer-modified-p gnus-dribble-buffer) - (save-excursion - (set-buffer gnus-dribble-buffer) - (not (zerop (buffer-size)))))) - (mode-string (eval gformat))) - ;; Say whether the dribble buffer has been modified. - (setq mode-line-modified - (if modified (car gnus-mode-line-modified) - (cdr gnus-mode-line-modified))) - ;; If the line is too long, we chop it off. - (when (> (length mode-string) max-len) - (setq mode-string (substring mode-string 0 (- max-len 4)))) - (prog1 - (setq mode-line-buffer-identification - (gnus-mode-line-buffer-identification - (list mode-string))) - (set-buffer-modified-p modified)))))) - -(defun gnus-group-group-name () - "Get the name of the newsgroup on the current line." - (let ((group (get-text-property (gnus-point-at-bol) 'gnus-group))) - (when group - (symbol-name group)))) - -(defun gnus-group-group-level () - "Get the level of the newsgroup on the current line." - (get-text-property (gnus-point-at-bol) 'gnus-level)) - -(defun gnus-group-group-indentation () - "Get the indentation of the newsgroup on the current line." - (or (get-text-property (gnus-point-at-bol) 'gnus-indentation) - (and gnus-group-indentation-function - (funcall gnus-group-indentation-function)) - "")) - -(defun gnus-group-group-unread () - "Get the number of unread articles of the newsgroup on the current line." - (get-text-property (gnus-point-at-bol) 'gnus-unread)) - -(defun gnus-group-new-mail (group) - (if (nnmail-new-mail-p (gnus-group-real-name group)) - gnus-new-mail-mark - ? )) - -(defun gnus-group-level (group) - "Return the estimated level of GROUP." - (or (gnus-info-level (gnus-get-info group)) - (and (member group gnus-zombie-list) gnus-level-zombie) - gnus-level-killed)) - -(defun gnus-group-search-forward (&optional backward all level first-too) - "Find the next newsgroup with unread articles. -If BACKWARD is non-nil, find the previous newsgroup instead. -If ALL is non-nil, just find any newsgroup. -If LEVEL is non-nil, find group with level LEVEL, or higher if no such -group exists. -If FIRST-TOO, the current line is also eligible as a target." - (let ((way (if backward -1 1)) - (low gnus-level-killed) - (beg (point)) - pos found lev) - (if (and backward (progn (beginning-of-line)) (bobp)) - nil - (unless first-too - (forward-line way)) - (while (and - (not (eobp)) - (not (setq - found - (and - (get-text-property (point) 'gnus-group) - (or all - (and - (let ((unread - (get-text-property (point) 'gnus-unread))) - (and (numberp unread) (> unread 0))) - (setq lev (get-text-property (point) - 'gnus-level)) - (<= lev gnus-level-subscribed))) - (or (not level) - (and (setq lev (get-text-property (point) - 'gnus-level)) - (or (= lev level) - (and (< lev low) - (< level lev) - (progn - (setq low lev) - (setq pos (point)) - nil)))))))) - (zerop (forward-line way))))) - (if found - (progn (gnus-group-position-point) t) - (goto-char (or pos beg)) - (and pos t)))) - -;;; Gnus group mode commands - -;; Group marking. - -(defun gnus-group-mark-group (n &optional unmark no-advance) - "Mark the current group." - (interactive "p") - (let ((buffer-read-only nil) - group) - (while (and (> n 0) - (not (eobp))) - (when (setq group (gnus-group-group-name)) - ;; Go to the mark position. - (beginning-of-line) - (forward-char (or (cdr (assq 'process gnus-group-mark-positions)) 2)) - (subst-char-in-region - (point) (1+ (point)) (following-char) - (if unmark - (progn - (setq gnus-group-marked (delete group gnus-group-marked)) - ? ) - (setq gnus-group-marked - (cons group (delete group gnus-group-marked))) - gnus-process-mark))) - (unless no-advance - (gnus-group-next-group 1)) - (decf n)) - (gnus-summary-position-point) - n)) - -(defun gnus-group-unmark-group (n) - "Remove the mark from the current group." - (interactive "p") - (gnus-group-mark-group n 'unmark) - (gnus-group-position-point)) - -(defun gnus-group-unmark-all-groups () - "Unmark all groups." - (interactive) - (let ((groups gnus-group-marked)) - (save-excursion - (while groups - (gnus-group-remove-mark (pop groups))))) - (gnus-group-position-point)) - -(defun gnus-group-mark-region (unmark beg end) - "Mark all groups between point and mark. -If UNMARK, remove the mark instead." - (interactive "P\nr") - (let ((num (count-lines beg end))) - (save-excursion - (goto-char beg) - (- num (gnus-group-mark-group num unmark))))) - -(defun gnus-group-mark-buffer (&optional unmark) - "Mark all groups in the buffer. -If UNMARK, remove the mark instead." - (interactive "P") - (gnus-group-mark-region unmark (point-min) (point-max))) - -(defun gnus-group-mark-regexp (regexp) - "Mark all groups that match some regexp." - (interactive "sMark (regexp): ") - (let ((alist (cdr gnus-newsrc-alist)) - group) - (while alist - (when (string-match regexp (setq group (gnus-info-group (pop alist)))) - (gnus-group-set-mark group)))) - (gnus-group-position-point)) - -(defun gnus-group-remove-mark (group) - "Remove the process mark from GROUP and move point there. -Return nil if the group isn't displayed." - (if (gnus-group-goto-group group) - (save-excursion - (gnus-group-mark-group 1 'unmark t) - t) - (setq gnus-group-marked - (delete group gnus-group-marked)) - nil)) - -(defun gnus-group-set-mark (group) - "Set the process mark on GROUP." - (if (gnus-group-goto-group group) - (save-excursion - (gnus-group-mark-group 1 nil t)) - (setq gnus-group-marked (cons group (delete group gnus-group-marked))))) - -(defun gnus-group-universal-argument (arg &optional groups func) - "Perform any command on all groups according to the process/prefix convention." - (interactive "P") - (if (eq (setq func (or func - (key-binding - (read-key-sequence - (substitute-command-keys - "\\\\[gnus-group-universal-argument]"))))) - 'undefined) - (gnus-error 1 "Undefined key") - (gnus-group-iterate arg - (lambda (group) - (command-execute func)))) - (gnus-group-position-point)) - -(defun gnus-group-process-prefix (n) - "Return a list of groups to work on. -Take into consideration N (the prefix) and the list of marked groups." - (cond - (n - (setq n (prefix-numeric-value n)) - ;; There is a prefix, so we return a list of the N next - ;; groups. - (let ((way (if (< n 0) -1 1)) - (n (abs n)) - group groups) - (save-excursion - (while (> n 0) - (if (setq group (gnus-group-group-name)) - (push group groups)) - (setq n (1- n)) - (gnus-group-next-group way))) - (nreverse groups))) - ((gnus-region-active-p) - ;; Work on the region between point and mark. - (let ((max (max (point) (mark))) - groups) - (save-excursion - (goto-char (min (point) (mark))) - (while - (and - (push (gnus-group-group-name) groups) - (zerop (gnus-group-next-group 1)) - (< (point) max))) - (nreverse groups)))) - (gnus-group-marked - ;; No prefix, but a list of marked articles. - (reverse gnus-group-marked)) - (t - ;; Neither marked articles or a prefix, so we return the - ;; current group. - (let ((group (gnus-group-group-name))) - (and group (list group)))))) - -;;; !!!Surely gnus-group-iterate should be a macro instead? I can't -;;; imagine why I went through these contortions... -(eval-and-compile - (let ((function (make-symbol "gnus-group-iterate-function")) - (window (make-symbol "gnus-group-iterate-window")) - (groups (make-symbol "gnus-group-iterate-groups")) - (group (make-symbol "gnus-group-iterate-group"))) - (eval - `(defun gnus-group-iterate (arg ,function) - "Iterate FUNCTION over all process/prefixed groups. -FUNCTION will be called with the group name as the paremeter -and with point over the group in question." - (let ((,groups (gnus-group-process-prefix arg)) - (,window (selected-window)) - ,group) - (while (setq ,group (pop ,groups)) - (select-window ,window) - (gnus-group-remove-mark ,group) - (save-selected-window - (save-excursion - (funcall ,function ,group))))))))) - -(put 'gnus-group-iterate 'lisp-indent-function 1) - -;; Selecting groups. - -(defun gnus-group-read-group (&optional all no-article group select-articles) - "Read news in this newsgroup. -If the prefix argument ALL is non-nil, already read articles become -readable. IF ALL is a number, fetch this number of articles. If the -optional argument NO-ARTICLE is non-nil, no article will be -auto-selected upon group entry. If GROUP is non-nil, fetch that -group." - (interactive "P") - (let ((no-display (eq all 0)) - (group (or group (gnus-group-group-name))) - number active marked entry) - (when (eq all 0) - (setq all nil)) - (unless group - (error "No group on current line")) - (setq marked (gnus-info-marks - (nth 2 (setq entry (gnus-gethash - group gnus-newsrc-hashtb))))) - ;; This group might be a dead group. In that case we have to get - ;; the number of unread articles from `gnus-active-hashtb'. - (setq number - (cond ((numberp all) all) - (entry (car entry)) - ((setq active (gnus-active group)) - (- (1+ (cdr active)) (car active))))) - (gnus-summary-read-group - group (or all (and (numberp number) - (zerop (+ number (gnus-range-length - (cdr (assq 'tick marked))) - (gnus-range-length - (cdr (assq 'dormant marked))))))) - no-article nil no-display nil select-articles))) - -(defun gnus-group-select-group (&optional all) - "Select this newsgroup. -No article is selected automatically. -If ALL is non-nil, already read articles become readable. -If ALL is a number, fetch this number of articles." - (interactive "P") - (gnus-group-read-group all t)) - -(defun gnus-group-quick-select-group (&optional all) - "Select the current group \"quickly\". -This means that no highlighting or scoring will be performed. -If ALL (the prefix argument) is 0, don't even generate the summary -buffer. - -This might be useful if you want to toggle threading -before entering the group." - (interactive "P") - (require 'gnus-score) - (let (gnus-visual - gnus-score-find-score-files-function - gnus-home-score-file - gnus-apply-kill-hook - gnus-summary-expunge-below) - (gnus-group-read-group all t))) - -(defun gnus-group-visible-select-group (&optional all) - "Select the current group without hiding any articles." - (interactive "P") - (let ((gnus-inhibit-limiting t)) - (gnus-group-read-group all t))) - -(defun gnus-group-select-group-ephemerally () - "Select the current group without doing any processing whatsoever. -You will actually be entered into a group that's a copy of -the current group; no changes you make while in this group will -be permanent." - (interactive) - (require 'gnus-score) - (let* (gnus-visual - gnus-score-find-score-files-function gnus-apply-kill-hook - gnus-summary-expunge-below gnus-show-threads gnus-suppress-duplicates - gnus-summary-mode-hook gnus-select-group-hook - (group (gnus-group-group-name)) - (method (gnus-find-method-for-group group))) - (gnus-group-read-ephemeral-group - (gnus-group-prefixed-name group method) method))) - -;;;###autoload -(defun gnus-fetch-group (group) - "Start Gnus if necessary and enter GROUP. -Returns whether the fetching was successful or not." - (interactive "sGroup name: ") - (unless (get-buffer gnus-group-buffer) - (gnus-no-server)) - (gnus-group-read-group nil nil group)) - -;;;###autoload -(defun gnus-fetch-group-other-frame (group) - "Pop up a frame and enter GROUP." - (interactive "P") - (let ((window (get-buffer-window gnus-group-buffer))) - (cond (window - (select-frame (window-frame window))) - ((= (length (frame-list)) 1) - (select-frame (make-frame))) - (t - (other-frame 1)))) - (gnus-fetch-group group)) - -(defvar gnus-ephemeral-group-server 0) - -;; Enter a group that is not in the group buffer. Non-nil is returned -;; if selection was successful. -(defun gnus-group-read-ephemeral-group (group method &optional activate - quit-config request-only - select-articles) - "Read GROUP from METHOD as an ephemeral group. -If ACTIVATE, request the group first. -If QUIT-CONFIG, use that window configuration when exiting from the -ephemeral group. -If REQUEST-ONLY, don't actually read the group; just request it. -If SELECT-ARTICLES, only select those articles. - -Return the name of the group is selection was successful." - ;; Transform the select method into a unique server. - (when (stringp method) - (setq method (gnus-server-to-method method))) - (setq method - `(,(car method) ,(concat (cadr method) "-ephemeral") - (,(intern (format "%s-address" (car method))) ,(cadr method)) - ,@(cddr method))) - (let ((group (if (gnus-group-foreign-p group) group - (gnus-group-prefixed-name group method)))) - (gnus-sethash - group - `(-1 nil (,group - ,gnus-level-default-subscribed nil nil ,method - ((quit-config . - ,(if quit-config quit-config - (cons gnus-summary-buffer - gnus-current-window-configuration)))))) - gnus-newsrc-hashtb) - (push method gnus-ephemeral-servers) - (set-buffer gnus-group-buffer) - (unless (gnus-check-server method) - (error "Unable to contact server: %s" (gnus-status-message method))) - (when activate - (gnus-activate-group group 'scan) - (unless (gnus-request-group group) - (error "Couldn't request group: %s" - (nnheader-get-report (car method))))) - (if request-only - group - (condition-case () - (when (gnus-group-read-group t t group select-articles) - group) - ;;(error nil) - (quit nil))))) - -(defun gnus-group-jump-to-group (group) - "Jump to newsgroup GROUP." - (interactive - (list (completing-read - "Group: " gnus-active-hashtb nil - (gnus-read-active-file-p) - nil - 'gnus-group-history))) - - (when (equal group "") - (error "Empty group name")) - - (unless (gnus-ephemeral-group-p group) - ;; Either go to the line in the group buffer... - (unless (gnus-group-goto-group group) - ;; ... or insert the line. - (gnus-group-update-group group) - (gnus-group-goto-group group))) - ;; Adjust cursor point. - (gnus-group-position-point)) - -(defun gnus-group-goto-group (group &optional far) - "Goto to newsgroup GROUP. -If FAR, it is likely that the group is not on the current line." - (when group - (if far - (gnus-goto-char - (text-property-any - (point-min) (point-max) - 'gnus-group (gnus-intern-safe group gnus-active-hashtb))) - (beginning-of-line) - (cond - ;; It's quite likely that we are on the right line, so - ;; we check the current line first. - ((eq (get-text-property (point) 'gnus-group) - (gnus-intern-safe group gnus-active-hashtb)) - (point)) - ;; Previous and next line are also likely, so we check them as well. - ((save-excursion - (forward-line -1) - (eq (get-text-property (point) 'gnus-group) - (gnus-intern-safe group gnus-active-hashtb))) - (forward-line -1) - (point)) - ((save-excursion - (forward-line 1) - (eq (get-text-property (point) 'gnus-group) - (gnus-intern-safe group gnus-active-hashtb))) - (forward-line 1) - (point)) - (t - ;; Search through the entire buffer. - (gnus-goto-char - (text-property-any - (point-min) (point-max) - 'gnus-group (gnus-intern-safe group gnus-active-hashtb)))))))) - -(defun gnus-group-next-group (n &optional silent) - "Go to next N'th newsgroup. -If N is negative, search backward instead. -Returns the difference between N and the number of skips actually -done." - (interactive "p") - (gnus-group-next-unread-group n t nil silent)) - -(defun gnus-group-next-unread-group (n &optional all level silent) - "Go to next N'th unread newsgroup. -If N is negative, search backward instead. -If ALL is non-nil, choose any newsgroup, unread or not. -If LEVEL is non-nil, choose the next group with level LEVEL, or, if no -such group can be found, the next group with a level higher than -LEVEL. -Returns the difference between N and the number of skips actually -made." - (interactive "p") - (let ((backward (< n 0)) - (n (abs n))) - (while (and (> n 0) - (gnus-group-search-forward - backward (or (not gnus-group-goto-unread) all) level)) - (setq n (1- n))) - (when (and (/= 0 n) - (not silent)) - (gnus-message 7 "No more%s newsgroups%s" (if all "" " unread") - (if level " on this level or higher" ""))) - n)) - -(defun gnus-group-prev-group (n) - "Go to previous N'th newsgroup. -Returns the difference between N and the number of skips actually -done." - (interactive "p") - (gnus-group-next-unread-group (- n) t)) - -(defun gnus-group-prev-unread-group (n) - "Go to previous N'th unread newsgroup. -Returns the difference between N and the number of skips actually -done." - (interactive "p") - (gnus-group-next-unread-group (- n))) - -(defun gnus-group-next-unread-group-same-level (n) - "Go to next N'th unread newsgroup on the same level. -If N is negative, search backward instead. -Returns the difference between N and the number of skips actually -done." - (interactive "p") - (gnus-group-next-unread-group n t (gnus-group-group-level)) - (gnus-group-position-point)) - -(defun gnus-group-prev-unread-group-same-level (n) - "Go to next N'th unread newsgroup on the same level. -Returns the difference between N and the number of skips actually -done." - (interactive "p") - (gnus-group-next-unread-group (- n) t (gnus-group-group-level)) - (gnus-group-position-point)) - -(defun gnus-group-best-unread-group (&optional exclude-group) - "Go to the group with the highest level. -If EXCLUDE-GROUP, do not go to that group." - (interactive) - (goto-char (point-min)) - (let ((best 100000) - unread best-point) - (while (not (eobp)) - (setq unread (get-text-property (point) 'gnus-unread)) - (when (and (numberp unread) (> unread 0)) - (when (and (get-text-property (point) 'gnus-level) - (< (get-text-property (point) 'gnus-level) best) - (or (not exclude-group) - (not (equal exclude-group (gnus-group-group-name))))) - (setq best (get-text-property (point) 'gnus-level)) - (setq best-point (point)))) - (forward-line 1)) - (when best-point - (goto-char best-point)) - (gnus-summary-position-point) - (and best-point (gnus-group-group-name)))) - -(defun gnus-group-first-unread-group () - "Go to the first group with unread articles." - (interactive) - (prog1 - (let ((opoint (point)) - unread) - (goto-char (point-min)) - (if (or (eq (setq unread (gnus-group-group-unread)) t) ; Not active. - (and (numberp unread) ; Not a topic. - (not (zerop unread))) ; Has unread articles. - (zerop (gnus-group-next-unread-group 1))) ; Next unread group. - (point) ; Success. - (goto-char opoint) - nil)) ; Not success. - (gnus-group-position-point))) - -(defun gnus-group-enter-server-mode () - "Jump to the server buffer." - (interactive) - (gnus-enter-server-buffer)) - -(defun gnus-group-make-group (name &optional method address args) - "Add a new newsgroup. -The user will be prompted for a NAME, for a select METHOD, and an -ADDRESS." - (interactive - (list - (gnus-read-group "Group name: ") - (gnus-read-method "From method: "))) - - (when (stringp method) - (setq method (gnus-server-to-method method))) - (let* ((meth (when (and method - (not (gnus-server-equal method gnus-select-method))) - (if address (list (intern method) address) - method))) - (nname (if method (gnus-group-prefixed-name name meth) name)) - backend info) - (when (gnus-gethash nname gnus-newsrc-hashtb) - (error "Group %s already exists" nname)) - ;; Subscribe to the new group. - (gnus-group-change-level - (setq info (list t nname gnus-level-default-subscribed nil nil meth)) - gnus-level-default-subscribed gnus-level-killed - (and (gnus-group-group-name) - (gnus-gethash (gnus-group-group-name) - gnus-newsrc-hashtb)) - t) - ;; Make it active. - (gnus-set-active nname (cons 1 0)) - (unless (gnus-ephemeral-group-p name) - (gnus-dribble-enter - (concat "(gnus-group-set-info '" - (gnus-prin1-to-string (cdr info)) ")"))) - ;; Insert the line. - (gnus-group-insert-group-line-info nname) - (forward-line -1) - (gnus-group-position-point) - - ;; Load the backend and try to make the backend create - ;; the group as well. - (when (assoc (symbol-name (setq backend (car (gnus-server-get-method - nil meth)))) - gnus-valid-select-methods) - (require backend)) - (gnus-check-server meth) - (when (gnus-check-backend-function 'request-create-group nname) - (gnus-request-create-group nname nil args)) - t)) - -(defun gnus-group-delete-group (group &optional force) - "Delete the current group. Only meaningful with mail groups. -If FORCE (the prefix) is non-nil, all the articles in the group will -be deleted. This is \"deleted\" as in \"removed forever from the face -of the Earth\". There is no undo. The user will be prompted before -doing the deletion." - (interactive - (list (gnus-group-group-name) - current-prefix-arg)) - (unless group - (error "No group to rename")) - (unless (gnus-check-backend-function 'request-delete-group group) - (error "This backend does not support group deletion")) - (prog1 - (if (not (gnus-yes-or-no-p - (format - "Do you really want to delete %s%s? " - group (if force " and all its contents" "")))) - () ; Whew! - (gnus-message 6 "Deleting group %s..." group) - (if (not (gnus-request-delete-group group force)) - (gnus-error 3 "Couldn't delete group %s" group) - (gnus-message 6 "Deleting group %s...done" group) - (gnus-group-goto-group group) - (gnus-group-kill-group 1 t) - (gnus-sethash group nil gnus-active-hashtb) - t)) - (gnus-group-position-point))) - -(defun gnus-group-rename-group (group new-name) - "Rename group from GROUP to NEW-NAME. -When used interactively, GROUP is the group under point -and NEW-NAME will be prompted for." - (interactive - (list - (gnus-group-group-name) - (progn - (unless (gnus-check-backend-function - 'request-rename-group (gnus-group-group-name)) - (error "This backend does not support renaming groups")) - (gnus-read-group "Rename group to: " - (gnus-group-real-name (gnus-group-group-name)))))) - - (unless (gnus-check-backend-function 'request-rename-group group) - (error "This backend does not support renaming groups")) - (unless group - (error "No group to rename")) - (when (equal (gnus-group-real-name group) new-name) - (error "Can't rename to the same name")) - - ;; We find the proper prefixed name. - (setq new-name - (if (gnus-group-native-p group) - ;; Native group. - new-name - ;; Foreign group. - (gnus-group-prefixed-name - (gnus-group-real-name new-name) - (gnus-info-method (gnus-get-info group))))) - - (gnus-message 6 "Renaming group %s to %s..." group new-name) - (prog1 - (if (not (gnus-request-rename-group group new-name)) - (gnus-error 3 "Couldn't rename group %s to %s" group new-name) - ;; We rename the group internally by killing it... - (gnus-group-goto-group group) - (gnus-group-kill-group) - ;; ... changing its name ... - (setcar (cdar gnus-list-of-killed-groups) new-name) - ;; ... and then yanking it. Magic! - (gnus-group-yank-group) - (gnus-set-active new-name (gnus-active group)) - (gnus-message 6 "Renaming group %s to %s...done" group new-name) - new-name) - (setq gnus-killed-list (delete group gnus-killed-list)) - (gnus-set-active group nil) - (gnus-dribble-touch) - (gnus-group-position-point))) - -(defun gnus-group-edit-group (group &optional part) - "Edit the group on the current line." - (interactive (list (gnus-group-group-name))) - (let ((part (or part 'info)) - info) - (unless group - (error "No group on current line")) - (unless (setq info (gnus-get-info group)) - (error "Killed group; can't be edited")) - (ignore-errors - (gnus-close-group group)) - (gnus-edit-form - ;; Find the proper form to edit. - (cond ((eq part 'method) - (or (gnus-info-method info) "native")) - ((eq part 'params) - (gnus-info-params info)) - (t info)) - ;; The proper documentation. - (format - "Editing the %s for `%s'." - (cond - ((eq part 'method) "select method") - ((eq part 'params) "group parameters") - (t "group info")) - group) - `(lambda (form) - (gnus-group-edit-group-done ',part ,group form))))) - -(defun gnus-group-edit-group-method (group) - "Edit the select method of GROUP." - (interactive (list (gnus-group-group-name))) - (gnus-group-edit-group group 'method)) - -(defun gnus-group-edit-group-parameters (group) - "Edit the group parameters of GROUP." - (interactive (list (gnus-group-group-name))) - (gnus-group-edit-group group 'params)) - -(defun gnus-group-edit-group-done (part group form) - "Update variables." - (let* ((method (cond ((eq part 'info) (nth 4 form)) - ((eq part 'method) form) - (t nil))) - (info (cond ((eq part 'info) form) - ((eq part 'method) (gnus-get-info group)) - (t nil))) - (new-group (if info - (if (or (not method) - (gnus-server-equal - gnus-select-method method)) - (gnus-group-real-name (car info)) - (gnus-group-prefixed-name - (gnus-group-real-name (car info)) method)) - nil))) - (when (and new-group - (not (equal new-group group))) - (when (gnus-group-goto-group group) - (gnus-group-kill-group 1)) - (gnus-activate-group new-group)) - ;; Set the info. - (if (not (and info new-group)) - (gnus-group-set-info form (or new-group group) part) - (setq info (gnus-copy-sequence info)) - (setcar info new-group) - (unless (gnus-server-equal method "native") - (unless (nthcdr 3 info) - (nconc info (list nil nil))) - (unless (nthcdr 4 info) - (nconc info (list nil))) - (gnus-info-set-method info method)) - (gnus-group-set-info info)) - (gnus-group-update-group (or new-group group)) - (gnus-group-position-point))) - -(defun gnus-group-make-useful-group (group method) - "Create one of the groups described in `gnus-useful-groups'." - (interactive - (let ((entry (assoc (completing-read "Create group: " gnus-useful-groups - nil t) - gnus-useful-groups))) - (list (cadr entry) (caddr entry)))) - (setq method (gnus-copy-sequence method)) - (let (entry) - (while (setq entry (memq (assq 'eval method) method)) - (setcar entry (eval (cadar entry))))) - (gnus-group-make-group group method)) - -(defun gnus-group-make-help-group () - "Create the Gnus documentation group." - (interactive) - (let ((name (gnus-group-prefixed-name "gnus-help" '(nndoc "gnus-help"))) - (file (nnheader-find-etc-directory "gnus-tut.txt" t))) - (when (gnus-gethash name gnus-newsrc-hashtb) - (error "Documentation group already exists")) - (if (not file) - (gnus-message 1 "Couldn't find doc group") - (gnus-group-make-group - (gnus-group-real-name name) - (list 'nndoc "gnus-help" - (list 'nndoc-address file) - (list 'nndoc-article-type 'mbox))))) - (gnus-group-position-point)) - -(defun gnus-group-make-doc-group (file type) - "Create a group that uses a single file as the source." - (interactive - (list (read-file-name "File name: ") - (and current-prefix-arg 'ask))) - (when (eq type 'ask) - (let ((err "") - char found) - (while (not found) - (message - "%sFile type (mbox, babyl, digest, forward, mmdf, guess) [mbdfag]: " - err) - (setq found (cond ((= (setq char (read-char)) ?m) 'mbox) - ((= char ?b) 'babyl) - ((= char ?d) 'digest) - ((= char ?f) 'forward) - ((= char ?a) 'mmfd) - (t (setq err (format "%c unknown. " char)) - nil)))) - (setq type found))) - (let* ((file (expand-file-name file)) - (name (gnus-generate-new-group-name - (gnus-group-prefixed-name - (file-name-nondirectory file) '(nndoc ""))))) - (gnus-group-make-group - (gnus-group-real-name name) - (list 'nndoc file - (list 'nndoc-address file) - (list 'nndoc-article-type (or type 'guess)))))) - -(defvar nnweb-type-definition) -(defvar gnus-group-web-type-history nil) -(defvar gnus-group-web-search-history nil) -(defun gnus-group-make-web-group (&optional solid) - "Create an ephemeral nnweb group. -If SOLID (the prefix), create a solid group." - (interactive "P") - (require 'nnweb) - (let* ((group - (if solid (gnus-read-group "Group name: ") - (message-unique-id))) - (default-type (or (car gnus-group-web-type-history) - (symbol-name (caar nnweb-type-definition)))) - (type - (gnus-string-or - (completing-read - (format "Search engine type (default %s): " default-type) - (mapcar (lambda (elem) (list (symbol-name (car elem)))) - nnweb-type-definition) - nil t nil 'gnus-group-web-type-history) - default-type)) - (search - (read-string - "Search string: " - (cons (or (car gnus-group-web-search-history) "") 0) - 'gnus-group-web-search-history)) - (method - `(nnweb ,group (nnweb-search ,search) - (nnweb-type ,(intern type)) - (nnweb-ephemeral-p t)))) - (if solid - (gnus-group-make-group group "nnweb" "" `(,(intern type) ,search)) - (gnus-group-read-ephemeral-group - group method t - (cons (current-buffer) - (if (eq major-mode 'gnus-summary-mode) 'summary 'group)))))) - -(defun gnus-group-make-archive-group (&optional all) - "Create the (ding) Gnus archive group of the most recent articles. -Given a prefix, create a full group." - (interactive "P") - (let ((group (gnus-group-prefixed-name - (if all "ding.archives" "ding.recent") '(nndir "")))) - (when (gnus-gethash group gnus-newsrc-hashtb) - (error "Archive group already exists")) - (gnus-group-make-group - (gnus-group-real-name group) - (list 'nndir (if all "hpc" "edu") - (list 'nndir-directory - (if all gnus-group-archive-directory - gnus-group-recent-archive-directory)))) - (gnus-group-add-parameter group (cons 'to-address "ding@gnus.org")))) - -(defun gnus-group-make-directory-group (dir) - "Create an nndir group. -The user will be prompted for a directory. The contents of this -directory will be used as a newsgroup. The directory should contain -mail messages or news articles in files that have numeric names." - (interactive - (list (read-file-name "Create group from directory: "))) - (unless (file-exists-p dir) - (error "No such directory")) - (unless (file-directory-p dir) - (error "Not a directory")) - (let ((ext "") - (i 0) - group) - (while (or (not group) (gnus-gethash group gnus-newsrc-hashtb)) - (setq group - (gnus-group-prefixed-name - (concat (file-name-as-directory (directory-file-name dir)) - ext) - '(nndir ""))) - (setq ext (format "<%d>" (setq i (1+ i))))) - (gnus-group-make-group - (gnus-group-real-name group) - (list 'nndir (gnus-group-real-name group) (list 'nndir-directory dir))))) - -(defun gnus-group-make-kiboze-group (group address scores) - "Create an nnkiboze group. -The user will be prompted for a name, a regexp to match groups, and -score file entries for articles to include in the group." - (interactive - (list - (read-string "nnkiboze group name: ") - (read-string "Source groups (regexp): ") - (let ((headers (mapcar (lambda (group) (list group)) - '("subject" "from" "number" "date" "message-id" - "references" "chars" "lines" "xref" - "followup" "all" "body" "head"))) - scores header regexp regexps) - (while (not (equal "" (setq header (completing-read - "Match on header: " headers nil t)))) - (setq regexps nil) - (while (not (equal "" (setq regexp (read-string - (format "Match on %s (string): " - header))))) - (push (list regexp nil nil 'r) regexps)) - (push (cons header regexps) scores)) - scores))) - (gnus-group-make-group group "nnkiboze" address) - (nnheader-temp-write (gnus-score-file-name (concat "nnkiboze:" group)) - (let (emacs-lisp-mode-hook) - (pp scores (current-buffer))))) - -(defun gnus-group-add-to-virtual (n vgroup) - "Add the current group to a virtual group." - (interactive - (list current-prefix-arg - (completing-read "Add to virtual group: " gnus-newsrc-hashtb nil t - "nnvirtual:"))) - (unless (eq (car (gnus-find-method-for-group vgroup)) 'nnvirtual) - (error "%s is not an nnvirtual group" vgroup)) - (gnus-close-group vgroup) - (let* ((groups (gnus-group-process-prefix n)) - (method (gnus-info-method (gnus-get-info vgroup)))) - (setcar (cdr method) - (concat - (nth 1 method) "\\|" - (mapconcat - (lambda (s) - (gnus-group-remove-mark s) - (concat "\\(^" (regexp-quote s) "$\\)")) - groups "\\|")))) - (gnus-group-position-point)) - -(defun gnus-group-make-empty-virtual (group) - "Create a new, fresh, empty virtual group." - (interactive "sCreate new, empty virtual group: ") - (let* ((method (list 'nnvirtual "^$")) - (pgroup (gnus-group-prefixed-name group method))) - ;; Check whether it exists already. - (when (gnus-gethash pgroup gnus-newsrc-hashtb) - (error "Group %s already exists" pgroup)) - ;; Subscribe the new group after the group on the current line. - (gnus-subscribe-group pgroup (gnus-group-group-name) method) - (gnus-group-update-group pgroup) - (forward-line -1) - (gnus-group-position-point))) - -(defun gnus-group-enter-directory (dir) - "Enter an ephemeral nneething group." - (interactive "DDirectory to read: ") - (let* ((method (list 'nneething dir '(nneething-read-only t))) - (leaf (gnus-group-prefixed-name - (file-name-nondirectory (directory-file-name dir)) - method)) - (name (gnus-generate-new-group-name leaf))) - (unless (gnus-group-read-ephemeral-group - name method t - (cons (current-buffer) - (if (eq major-mode 'gnus-summary-mode) - 'summary 'group))) - (error "Couldn't enter %s" dir)))) - -;; Group sorting commands -;; Suggested by Joe Hildebrand . - -(defun gnus-group-sort-groups (func &optional reverse) - "Sort the group buffer according to FUNC. -When used interactively, the sorting function used will be -determined by the `gnus-group-sort-function' variable. -If REVERSE (the prefix), reverse the sorting order." - (interactive (list gnus-group-sort-function current-prefix-arg)) - (funcall gnus-group-sort-alist-function - (gnus-make-sort-function func) reverse) - (gnus-group-list-groups) - (gnus-dribble-touch)) - -(defun gnus-group-sort-flat (func reverse) - ;; We peel off the dummy group from the alist. - (when func - (when (equal (gnus-info-group (car gnus-newsrc-alist)) "dummy.group") - (pop gnus-newsrc-alist)) - ;; Do the sorting. - (setq gnus-newsrc-alist - (sort gnus-newsrc-alist func)) - (when reverse - (setq gnus-newsrc-alist (nreverse gnus-newsrc-alist))) - ;; Regenerate the hash table. - (gnus-make-hashtable-from-newsrc-alist))) - -(defun gnus-group-sort-groups-by-alphabet (&optional reverse) - "Sort the group buffer alphabetically by group name. -If REVERSE, sort in reverse order." - (interactive "P") - (gnus-group-sort-groups 'gnus-group-sort-by-alphabet reverse)) - -(defun gnus-group-sort-groups-by-unread (&optional reverse) - "Sort the group buffer by number of unread articles. -If REVERSE, sort in reverse order." - (interactive "P") - (gnus-group-sort-groups 'gnus-group-sort-by-unread reverse)) - -(defun gnus-group-sort-groups-by-level (&optional reverse) - "Sort the group buffer by group level. -If REVERSE, sort in reverse order." - (interactive "P") - (gnus-group-sort-groups 'gnus-group-sort-by-level reverse)) - -(defun gnus-group-sort-groups-by-score (&optional reverse) - "Sort the group buffer by group score. -If REVERSE, sort in reverse order." - (interactive "P") - (gnus-group-sort-groups 'gnus-group-sort-by-score reverse)) - -(defun gnus-group-sort-groups-by-rank (&optional reverse) - "Sort the group buffer by group rank. -If REVERSE, sort in reverse order." - (interactive "P") - (gnus-group-sort-groups 'gnus-group-sort-by-rank reverse)) - -(defun gnus-group-sort-groups-by-method (&optional reverse) - "Sort the group buffer alphabetically by backend name. -If REVERSE, sort in reverse order." - (interactive "P") - (gnus-group-sort-groups 'gnus-group-sort-by-method reverse)) - -;;; Selected group sorting. - -(defun gnus-group-sort-selected-groups (n func &optional reverse) - "Sort the process/prefixed groups." - (interactive (list current-prefix-arg gnus-group-sort-function)) - (let ((groups (gnus-group-process-prefix n))) - (funcall gnus-group-sort-selected-function - groups (gnus-make-sort-function func) reverse) - (gnus-group-list-groups))) - -(defun gnus-group-sort-selected-flat (groups func reverse) - (let (entries infos) - ;; First find all the group entries for these groups. - (while groups - (push (nthcdr 2 (gnus-gethash (pop groups) gnus-newsrc-hashtb)) - entries)) - ;; Then sort the infos. - (setq infos - (sort - (mapcar - (lambda (entry) (car entry)) - (setq entries (nreverse entries))) - func)) - (when reverse - (setq infos (nreverse infos))) - ;; Go through all the infos and replace the old entries - ;; with the new infos. - (while infos - (setcar entries (pop infos)) - (pop entries)) - ;; Update the hashtable. - (gnus-make-hashtable-from-newsrc-alist))) - -(defun gnus-group-sort-selected-groups-by-alphabet (&optional reverse) - "Sort the group buffer alphabetically by group name. -If REVERSE, sort in reverse order." - (interactive "P") - (gnus-group-sort-selected-groups 'gnus-group-sort-by-alphabet reverse)) - -(defun gnus-group-sort-selected-groups-by-unread (&optional reverse) - "Sort the group buffer by number of unread articles. -If REVERSE, sort in reverse order." - (interactive "P") - (gnus-group-sort-selected-groups 'gnus-group-sort-by-unread reverse)) - -(defun gnus-group-sort-selected-groups-by-level (&optional reverse) - "Sort the group buffer by group level. -If REVERSE, sort in reverse order." - (interactive "P") - (gnus-group-sort-selected-groups 'gnus-group-sort-by-level reverse)) - -(defun gnus-group-sort-selected-groups-by-score (&optional reverse) - "Sort the group buffer by group score. -If REVERSE, sort in reverse order." - (interactive "P") - (gnus-group-sort-selected-groups 'gnus-group-sort-by-score reverse)) - -(defun gnus-group-sort-selected-groups-by-rank (&optional reverse) - "Sort the group buffer by group rank. -If REVERSE, sort in reverse order." - (interactive "P") - (gnus-group-sort-selected-groups 'gnus-group-sort-by-rank reverse)) - -(defun gnus-group-sort-selected-groups-by-method (&optional reverse) - "Sort the group buffer alphabetically by backend name. -If REVERSE, sort in reverse order." - (interactive "P") - (gnus-group-sort-selected-groups 'gnus-group-sort-by-method reverse)) - -;;; Sorting predicates. - -(defun gnus-group-sort-by-alphabet (info1 info2) - "Sort alphabetically." - (string< (gnus-info-group info1) (gnus-info-group info2))) - -(defun gnus-group-sort-by-real-name (info1 info2) - "Sort alphabetically on real (unprefixed) names." - (string< (gnus-group-real-name (gnus-info-group info1)) - (gnus-group-real-name (gnus-info-group info2)))) - -(defun gnus-group-sort-by-unread (info1 info2) - "Sort by number of unread articles." - (let ((n1 (car (gnus-gethash (gnus-info-group info1) gnus-newsrc-hashtb))) - (n2 (car (gnus-gethash (gnus-info-group info2) gnus-newsrc-hashtb)))) - (< (or (and (numberp n1) n1) 0) - (or (and (numberp n2) n2) 0)))) - -(defun gnus-group-sort-by-level (info1 info2) - "Sort by level." - (< (gnus-info-level info1) (gnus-info-level info2))) - -(defun gnus-group-sort-by-method (info1 info2) - "Sort alphabetically by backend name." - (string< (symbol-name (car (gnus-find-method-for-group - (gnus-info-group info1) info1))) - (symbol-name (car (gnus-find-method-for-group - (gnus-info-group info2) info2))))) - -(defun gnus-group-sort-by-score (info1 info2) - "Sort by group score." - (< (gnus-info-score info1) (gnus-info-score info2))) - -(defun gnus-group-sort-by-rank (info1 info2) - "Sort by level and score." - (let ((level1 (gnus-info-level info1)) - (level2 (gnus-info-level info2))) - (or (< level1 level2) - (and (= level1 level2) - (> (gnus-info-score info1) (gnus-info-score info2)))))) - -;;; Clearing data - -(defun gnus-group-clear-data (&optional arg) - "Clear all marks and read ranges from the current group." - (interactive "P") - (gnus-group-iterate arg - (lambda (group) - (let (info) - (gnus-info-clear-data (setq info (gnus-get-info group))) - (gnus-get-unread-articles-in-group info (gnus-active group) t) - (when (gnus-group-goto-group group) - (gnus-group-update-group-line)))))) - -(defun gnus-group-clear-data-on-native-groups () - "Clear all marks and read ranges from all native groups." - (interactive) - (when (gnus-yes-or-no-p "Really clear all data from almost all groups? ") - (let ((alist (cdr gnus-newsrc-alist)) - info) - (while (setq info (pop alist)) - (when (gnus-group-native-p (gnus-info-group info)) - (gnus-info-clear-data info))) - (gnus-get-unread-articles) - (gnus-dribble-touch) - (when (gnus-y-or-n-p - "Move the cache away to avoid problems in the future? ") - (call-interactively 'gnus-cache-move-cache))))) - -(defun gnus-info-clear-data (info) - "Clear all marks and read ranges from INFO." - (let ((group (gnus-info-group info))) - (gnus-undo-register - `(progn - (gnus-info-set-marks ',info ',(gnus-info-marks info) t) - (gnus-info-set-read ',info ',(gnus-info-read info)) - (when (gnus-group-goto-group ,group) - (gnus-group-update-group-line)))) - (gnus-info-set-read info nil) - (when (gnus-info-marks info) - (gnus-info-set-marks info nil)))) - -;; Group catching up. - -(defun gnus-group-catchup-current (&optional n all) - "Mark all articles not marked as unread in current newsgroup as read. -If prefix argument N is numeric, the next N newsgroups will be -caught up. If ALL is non-nil, marked articles will also be marked as -read. Cross references (Xref: header) of articles are ignored. -The number of newsgroups that this function was unable to catch -up is returned." - (interactive "P") - (let ((groups (gnus-group-process-prefix n)) - (ret 0)) - (unless groups (error "No groups selected")) - (if (not - (or (not gnus-interactive-catchup) ;Without confirmation? - gnus-expert-user - (gnus-y-or-n-p - (format - (if all - "Do you really want to mark all articles in %s as read? " - "Mark all unread articles in %s as read? ") - (if (= (length groups) 1) - (car groups) - (format "these %d groups" (length groups))))))) - n - (while groups - ;; Virtual groups have to be given special treatment. - (let ((method (gnus-find-method-for-group (car groups)))) - (when (eq 'nnvirtual (car method)) - (nnvirtual-catchup-group - (gnus-group-real-name (car groups)) (nth 1 method) all))) - (gnus-group-remove-mark (car groups)) - (if (>= (gnus-group-group-level) gnus-level-zombie) - (gnus-message 2 "Dead groups can't be caught up") - (if (prog1 - (gnus-group-goto-group (car groups)) - (gnus-group-catchup (car groups) all)) - (gnus-group-update-group-line) - (setq ret (1+ ret)))) - (setq groups (cdr groups))) - (gnus-group-next-unread-group 1) - ret))) - -(defun gnus-group-catchup-current-all (&optional n) - "Mark all articles in current newsgroup as read. -Cross references (Xref: header) of articles are ignored." - (interactive "P") - (gnus-group-catchup-current n 'all)) - -(defun gnus-group-catchup (group &optional all) - "Mark all articles in GROUP as read. -If ALL is non-nil, all articles are marked as read. -The return value is the number of articles that were marked as read, -or nil if no action could be taken." - (let* ((entry (gnus-gethash group gnus-newsrc-hashtb)) - (num (car entry))) - ;; Do the updating only if the newsgroup isn't killed. - (if (not (numberp (car entry))) - (gnus-message 1 "Can't catch up %s; non-active group" group) - ;; Do auto-expirable marks if that's required. - (when (gnus-group-auto-expirable-p group) - (gnus-add-marked-articles - group 'expire (gnus-list-of-unread-articles group)) - (when all - (let ((marks (nth 3 (nth 2 entry)))) - (gnus-add-marked-articles - group 'expire (gnus-uncompress-range (cdr (assq 'tick marks)))) - (gnus-add-marked-articles - group 'expire (gnus-uncompress-range (cdr (assq 'tick marks))))))) - (when entry - (gnus-update-read-articles group nil) - ;; Also nix out the lists of marks and dormants. - (when all - (gnus-add-marked-articles group 'tick nil nil 'force) - (gnus-add-marked-articles group 'dormant nil nil 'force)) - (let ((gnus-newsgroup-name group)) - (gnus-run-hooks 'gnus-group-catchup-group-hook)) - num)))) - -(defun gnus-group-expire-articles (&optional n) - "Expire all expirable articles in the current newsgroup." - (interactive "P") - (let ((groups (gnus-group-process-prefix n)) - group) - (unless groups - (error "No groups to expire")) - (while (setq group (pop groups)) - (gnus-group-remove-mark group) - (when (gnus-check-backend-function 'request-expire-articles group) - (gnus-message 6 "Expiring articles in %s..." group) - (let* ((info (gnus-get-info group)) - (expirable (if (gnus-group-total-expirable-p group) - (cons nil (gnus-list-of-read-articles group)) - (assq 'expire (gnus-info-marks info)))) - (expiry-wait (gnus-group-find-parameter group 'expiry-wait))) - (when expirable - (setcdr - expirable - (gnus-compress-sequence - (if expiry-wait - ;; We set the expiry variables to the group - ;; parameter. - (let ((nnmail-expiry-wait-function nil) - (nnmail-expiry-wait expiry-wait)) - (gnus-request-expire-articles - (gnus-uncompress-sequence (cdr expirable)) group)) - ;; Just expire using the normal expiry values. - (gnus-request-expire-articles - (gnus-uncompress-sequence (cdr expirable)) group)))) - (gnus-close-group group)) - (gnus-message 6 "Expiring articles in %s...done" group))) - (gnus-dribble-touch) - (gnus-group-position-point)))) - -(defun gnus-group-expire-all-groups () - "Expire all expirable articles in all newsgroups." - (interactive) - (save-excursion - (gnus-message 5 "Expiring...") - (let ((gnus-group-marked (mapcar (lambda (info) (gnus-info-group info)) - (cdr gnus-newsrc-alist)))) - (gnus-group-expire-articles nil))) - (gnus-group-position-point) - (gnus-message 5 "Expiring...done")) - -(defun gnus-group-set-current-level (n level) - "Set the level of the next N groups to LEVEL." - (interactive - (list - current-prefix-arg - (string-to-int - (let ((s (read-string - (format "Level (default %s): " - (or (gnus-group-group-level) - gnus-level-default-subscribed))))) - (if (string-match "^\\s-*$" s) - (int-to-string (or (gnus-group-group-level) - gnus-level-default-subscribed)) - s))))) - (unless (and (>= level 1) (<= level gnus-level-killed)) - (error "Illegal level: %d" level)) - (let ((groups (gnus-group-process-prefix n)) - group) - (while (setq group (pop groups)) - (gnus-group-remove-mark group) - (gnus-message 6 "Changed level of %s from %d to %d" - group (or (gnus-group-group-level) gnus-level-killed) - level) - (gnus-group-change-level - group level (or (gnus-group-group-level) gnus-level-killed)) - (gnus-group-update-group-line))) - (gnus-group-position-point)) - -(defun gnus-group-unsubscribe (&optional n) - "Unsubscribe the current group." - (interactive "P") - (gnus-group-unsubscribe-current-group n 'unsubscribe)) - -(defun gnus-group-subscribe (&optional n) - "Subscribe the current group." - (interactive "P") - (gnus-group-unsubscribe-current-group n 'subscribe)) - -(defun gnus-group-unsubscribe-current-group (&optional n do-sub) - "Toggle subscription of the current group. -If given numerical prefix, toggle the N next groups." - (interactive "P") - (let ((groups (gnus-group-process-prefix n)) - group) - (while groups - (setq group (car groups) - groups (cdr groups)) - (gnus-group-remove-mark group) - (gnus-group-unsubscribe-group - group - (cond - ((eq do-sub 'unsubscribe) - gnus-level-default-unsubscribed) - ((eq do-sub 'subscribe) - gnus-level-default-subscribed) - ((<= (gnus-group-group-level) gnus-level-subscribed) - gnus-level-default-unsubscribed) - (t - gnus-level-default-subscribed)) - t) - (gnus-group-update-group-line)) - (gnus-group-next-group 1))) - -(defun gnus-group-unsubscribe-group (group &optional level silent) - "Toggle subscription to GROUP. -Killed newsgroups are subscribed. If SILENT, don't try to update the -group line." - (interactive - (list (completing-read - "Group: " gnus-active-hashtb nil - (gnus-read-active-file-p) - nil - 'gnus-group-history))) - (let ((newsrc (gnus-gethash group gnus-newsrc-hashtb))) - (cond - ((string-match "^[ \t]*$" group) - (error "Empty group name")) - (newsrc - ;; Toggle subscription flag. - (gnus-group-change-level - newsrc (if level level (if (<= (gnus-info-level (nth 2 newsrc)) - gnus-level-subscribed) - (1+ gnus-level-subscribed) - gnus-level-default-subscribed))) - (unless silent - (gnus-group-update-group group))) - ((and (stringp group) - (or (not (gnus-read-active-file-p)) - (gnus-active group))) - ;; Add new newsgroup. - (gnus-group-change-level - group - (if level level gnus-level-default-subscribed) - (or (and (member group gnus-zombie-list) - gnus-level-zombie) - gnus-level-killed) - (when (gnus-group-group-name) - (gnus-gethash (gnus-group-group-name) gnus-newsrc-hashtb))) - (unless silent - (gnus-group-update-group group))) - (t (error "No such newsgroup: %s" group))) - (gnus-group-position-point))) - -(defun gnus-group-transpose-groups (n) - "Move the current newsgroup up N places. -If given a negative prefix, move down instead. The difference between -N and the number of steps taken is returned." - (interactive "p") - (unless (gnus-group-group-name) - (error "No group on current line")) - (gnus-group-kill-group 1) - (prog1 - (forward-line (- n)) - (gnus-group-yank-group) - (gnus-group-position-point))) - -(defun gnus-group-kill-all-zombies () - "Kill all zombie newsgroups." - (interactive) - (setq gnus-killed-list (nconc gnus-zombie-list gnus-killed-list)) - (setq gnus-zombie-list nil) - (gnus-dribble-touch) - (gnus-group-list-groups)) - -(defun gnus-group-kill-region (begin end) - "Kill newsgroups in current region (excluding current point). -The killed newsgroups can be yanked by using \\[gnus-group-yank-group]." - (interactive "r") - (let ((lines - ;; Count lines. - (save-excursion - (count-lines - (progn - (goto-char begin) - (beginning-of-line) - (point)) - (progn - (goto-char end) - (beginning-of-line) - (point)))))) - (goto-char begin) - (beginning-of-line) ;Important when LINES < 1 - (gnus-group-kill-group lines))) - -(defun gnus-group-kill-group (&optional n discard) - "Kill the next N groups. -The killed newsgroups can be yanked by using \\[gnus-group-yank-group]. -However, only groups that were alive can be yanked; already killed -groups or zombie groups can't be yanked. -The return value is the name of the group that was killed, or a list -of groups killed." - (interactive "P") - (let ((buffer-read-only nil) - (groups (gnus-group-process-prefix n)) - group entry level out) - (if (< (length groups) 10) - ;; This is faster when there are few groups. - (while groups - (push (setq group (pop groups)) out) - (gnus-group-remove-mark group) - (setq level (gnus-group-group-level)) - (gnus-delete-line) - (when (and (not discard) - (setq entry (gnus-gethash group gnus-newsrc-hashtb))) - (gnus-undo-register - `(progn - (gnus-group-goto-group ,(gnus-group-group-name)) - (gnus-group-yank-group))) - (push (cons (car entry) (nth 2 entry)) - gnus-list-of-killed-groups)) - (gnus-group-change-level - (if entry entry group) gnus-level-killed (if entry nil level))) - ;; If there are lots and lots of groups to be killed, we use - ;; this thing instead. - (let (entry) - (setq groups (nreverse groups)) - (while groups - (gnus-group-remove-mark (setq group (pop groups))) - (gnus-delete-line) - (push group gnus-killed-list) - (setq gnus-newsrc-alist - (delq (assoc group gnus-newsrc-alist) - gnus-newsrc-alist)) - (when gnus-group-change-level-function - (funcall gnus-group-change-level-function - group gnus-level-killed 3)) - (cond - ((setq entry (gnus-gethash group gnus-newsrc-hashtb)) - (push (cons (car entry) (nth 2 entry)) - gnus-list-of-killed-groups) - (setcdr (cdr entry) (cdddr entry))) - ((member group gnus-zombie-list) - (setq gnus-zombie-list (delete group gnus-zombie-list)))) - ;; There may be more than one instance displayed. - (while (gnus-group-goto-group group) - (gnus-delete-line))) - (gnus-make-hashtable-from-newsrc-alist))) - - (gnus-group-position-point) - (if (< (length out) 2) (car out) (nreverse out)))) - -(defun gnus-group-yank-group (&optional arg) - "Yank the last newsgroups killed with \\[gnus-group-kill-group], inserting it before the current newsgroup. -The numeric ARG specifies how many newsgroups are to be yanked. The -name of the newsgroup yanked is returned, or (if several groups are -yanked) a list of yanked groups is returned." - (interactive "p") - (setq arg (or arg 1)) - (let (info group prev out) - (while (>= (decf arg) 0) - (when (not (setq info (pop gnus-list-of-killed-groups))) - (error "No more newsgroups to yank")) - (push (setq group (nth 1 info)) out) - ;; Find which newsgroup to insert this one before - search - ;; backward until something suitable is found. If there are no - ;; other newsgroups in this buffer, just make this newsgroup the - ;; first newsgroup. - (setq prev (gnus-group-group-name)) - (gnus-group-change-level - info (gnus-info-level (cdr info)) gnus-level-killed - (and prev (gnus-gethash prev gnus-newsrc-hashtb)) - t) - (gnus-group-insert-group-line-info group) - (gnus-undo-register - `(when (gnus-group-goto-group ,group) - (gnus-group-kill-group 1)))) - (forward-line -1) - (gnus-group-position-point) - (if (< (length out) 2) (car out) (nreverse out)))) - -(defun gnus-group-kill-level (level) - "Kill all groups that is on a certain LEVEL." - (interactive "nKill all groups on level: ") - (cond - ((= level gnus-level-zombie) - (setq gnus-killed-list - (nconc gnus-zombie-list gnus-killed-list)) - (setq gnus-zombie-list nil)) - ((and (< level gnus-level-zombie) - (> level 0) - (or gnus-expert-user - (gnus-yes-or-no-p - (format - "Do you really want to kill all groups on level %d? " - level)))) - (let* ((prev gnus-newsrc-alist) - (alist (cdr prev))) - (while alist - (if (= (gnus-info-level (car alist)) level) - (progn - (push (gnus-info-group (car alist)) gnus-killed-list) - (setcdr prev (cdr alist))) - (setq prev alist)) - (setq alist (cdr alist))) - (gnus-make-hashtable-from-newsrc-alist) - (gnus-group-list-groups))) - (t - (error "Can't kill; illegal level: %d" level)))) - -(defun gnus-group-list-all-groups (&optional arg) - "List all newsgroups with level ARG or lower. -Default is gnus-level-unsubscribed, which lists all subscribed and most -unsubscribed groups." - (interactive "P") - (gnus-group-list-groups (or arg gnus-level-unsubscribed) t)) - -;; Redefine this to list ALL killed groups if prefix arg used. -;; Rewritten by engstrom@src.honeywell.com (Eric Engstrom). -(defun gnus-group-list-killed (&optional arg) - "List all killed newsgroups in the group buffer. -If ARG is non-nil, list ALL killed groups known to Gnus. This may -entail asking the server for the groups." - (interactive "P") - ;; Find all possible killed newsgroups if arg. - (when arg - (gnus-get-killed-groups)) - (if (not gnus-killed-list) - (gnus-message 6 "No killed groups") - (let (gnus-group-list-mode) - (funcall gnus-group-prepare-function - gnus-level-killed t gnus-level-killed)) - (goto-char (point-min))) - (gnus-group-position-point)) - -(defun gnus-group-list-zombies () - "List all zombie newsgroups in the group buffer." - (interactive) - (if (not gnus-zombie-list) - (gnus-message 6 "No zombie groups") - (let (gnus-group-list-mode) - (funcall gnus-group-prepare-function - gnus-level-zombie t gnus-level-zombie)) - (goto-char (point-min))) - (gnus-group-position-point)) - -(defun gnus-group-list-active () - "List all groups that are available from the server(s)." - (interactive) - ;; First we make sure that we have really read the active file. - (unless (gnus-read-active-file-p) - (let ((gnus-read-active-file t)) - (gnus-read-active-file))) - ;; Find all groups and sort them. - (let ((groups - (sort - (let (list) - (mapatoms - (lambda (sym) - (and (boundp sym) - (symbol-value sym) - (push (symbol-name sym) list))) - gnus-active-hashtb) - list) - 'string<)) - (buffer-read-only nil) - group) - (erase-buffer) - (while groups - (gnus-add-text-properties - (point) (prog1 (1+ (point)) - (insert " *: " - (setq group (pop groups)) "\n")) - (list 'gnus-group (gnus-intern-safe group gnus-active-hashtb) - 'gnus-unread t - 'gnus-level (inline (gnus-group-level group))))) - (goto-char (point-min)))) - -(defun gnus-activate-all-groups (level) - "Activate absolutely all groups." - (interactive (list gnus-level-unsubscribed)) - (let ((gnus-activate-level level) - (gnus-activate-foreign-newsgroups level)) - (gnus-group-get-new-news))) - -(defun gnus-group-get-new-news (&optional arg) - "Get newly arrived articles. -If ARG is a number, it specifies which levels you are interested in -re-scanning. If ARG is non-nil and not a number, this will force -\"hard\" re-reading of the active files from all servers." - (interactive "P") - (let ((gnus-inhibit-demon t)) - (gnus-run-hooks 'gnus-get-new-news-hook) - - ;; Read any slave files. - (unless gnus-slave - (gnus-master-read-slave-newsrc)) - - ;; We might read in new NoCeM messages here. - (when (and gnus-use-nocem - (null arg)) - (gnus-nocem-scan-groups)) - ;; If ARG is not a number, then we read the active file. - (when (and arg (not (numberp arg))) - (let ((gnus-read-active-file t)) - (gnus-read-active-file)) - (setq arg nil) - - ;; If the user wants it, we scan for new groups. - (when (eq gnus-check-new-newsgroups 'always) - (gnus-find-new-newsgroups))) - - (setq arg (gnus-group-default-level arg t)) - (if (and gnus-read-active-file (not arg)) - (progn - (gnus-read-active-file) - (gnus-get-unread-articles arg)) - (let ((gnus-read-active-file (if arg nil gnus-read-active-file))) - (gnus-get-unread-articles arg))) - (gnus-run-hooks 'gnus-after-getting-new-news-hook) - (gnus-group-list-groups (and (numberp arg) - (max (car gnus-group-list-mode) arg))))) - -(defun gnus-group-get-new-news-this-group (&optional n dont-scan) - "Check for newly arrived news in the current group (and the N-1 next groups). -The difference between N and the number of newsgroup checked is returned. -If N is negative, this group and the N-1 previous groups will be checked." - (interactive "P") - (let* ((groups (gnus-group-process-prefix n)) - (ret (if (numberp n) (- n (length groups)) 0)) - (beg (unless n - (point))) - group method) - (while (setq group (pop groups)) - (gnus-group-remove-mark group) - ;; Bypass any previous denials from the server. - (gnus-remove-denial (setq method (gnus-find-method-for-group group))) - (if (gnus-activate-group group (if dont-scan nil 'scan)) - (progn - (gnus-get-unread-articles-in-group - (gnus-get-info group) (gnus-active group) t) - (unless (gnus-virtual-group-p group) - (gnus-close-group group)) - (gnus-agent-save-group-info - method (gnus-group-real-name group) (gnus-active group)) - (gnus-group-update-group group)) - (if (eq (gnus-server-status (gnus-find-method-for-group group)) - 'denied) - (gnus-error 3 "Server denied access") - (gnus-error 3 "%s error: %s" group (gnus-status-message group))))) - (when beg - (goto-char beg)) - (when gnus-goto-next-group-when-activating - (gnus-group-next-unread-group 1 t)) - (gnus-summary-position-point) - ret)) - -(defun gnus-group-fetch-faq (group &optional faq-dir) - "Fetch the FAQ for the current group. -If given a prefix argument, prompt for the FAQ dir -to use." - (interactive - (list - (gnus-group-group-name) - (when current-prefix-arg - (completing-read - "Faq dir: " (and (listp gnus-group-faq-directory) - (mapcar (lambda (file) (list file)) - gnus-group-faq-directory)))))) - (unless group - (error "No group name given")) - (let ((dirs (or faq-dir gnus-group-faq-directory)) - dir found file) - (unless (listp dirs) - (setq dirs (list dirs))) - (while (and (not found) - (setq dir (pop dirs))) - (let ((name (gnus-group-real-name group))) - (setq file (concat (file-name-as-directory dir) name))) - (if (not (file-exists-p file)) - (gnus-message 1 "No such file: %s" file) - (let ((enable-local-variables nil)) - (find-file file) - (setq found t)))))) - -(defun gnus-group-describe-group (force &optional group) - "Display a description of the current newsgroup." - (interactive (list current-prefix-arg (gnus-group-group-name))) - (let* ((method (gnus-find-method-for-group group)) - (mname (gnus-group-prefixed-name "" method)) - desc) - (when (and force - gnus-description-hashtb) - (gnus-sethash mname nil gnus-description-hashtb)) - (unless group - (error "No group name given")) - (when (or (and gnus-description-hashtb - ;; We check whether this group's method has been - ;; queried for a description file. - (gnus-gethash mname gnus-description-hashtb)) - (setq desc (gnus-group-get-description group)) - (gnus-read-descriptions-file method)) - (gnus-message 1 - (or desc (gnus-gethash group gnus-description-hashtb) - "No description available"))))) - -;; Suggested by Per Abrahamsen . -(defun gnus-group-describe-all-groups (&optional force) - "Pop up a buffer with descriptions of all newsgroups." - (interactive "P") - (when force - (setq gnus-description-hashtb nil)) - (when (not (or gnus-description-hashtb - (gnus-read-all-descriptions-files))) - (error "Couldn't request descriptions file")) - (let ((buffer-read-only nil) - b) - (erase-buffer) - (mapatoms - (lambda (group) - (setq b (point)) - (insert (format " *: %-20s %s\n" (symbol-name group) - (symbol-value group))) - (gnus-add-text-properties - b (1+ b) (list 'gnus-group group - 'gnus-unread t 'gnus-marked nil - 'gnus-level (1+ gnus-level-subscribed)))) - gnus-description-hashtb) - (goto-char (point-min)) - (gnus-group-position-point))) - -;; Suggested by Daniel Quinlan . -(defun gnus-group-apropos (regexp &optional search-description) - "List all newsgroups that have names that match a regexp." - (interactive "sGnus apropos (regexp): ") - (let ((prev "") - (obuf (current-buffer)) - groups des) - ;; Go through all newsgroups that are known to Gnus. - (mapatoms - (lambda (group) - (and (symbol-name group) - (string-match regexp (symbol-name group)) - (symbol-value group) - (push (symbol-name group) groups))) - gnus-active-hashtb) - ;; Also go through all descriptions that are known to Gnus. - (when search-description - (mapatoms - (lambda (group) - (and (string-match regexp (symbol-value group)) - (gnus-active (symbol-name group)) - (push (symbol-name group) groups))) - gnus-description-hashtb)) - (if (not groups) - (gnus-message 3 "No groups matched \"%s\"." regexp) - ;; Print out all the groups. - (save-excursion - (pop-to-buffer "*Gnus Help*") - (buffer-disable-undo (current-buffer)) - (erase-buffer) - (setq groups (sort groups 'string<)) - (while groups - ;; Groups may be entered twice into the list of groups. - (when (not (string= (car groups) prev)) - (insert (setq prev (car groups)) "\n") - (when (and gnus-description-hashtb - (setq des (gnus-gethash (car groups) - gnus-description-hashtb))) - (insert " " des "\n"))) - (setq groups (cdr groups))) - (goto-char (point-min)))) - (pop-to-buffer obuf))) - -(defun gnus-group-description-apropos (regexp) - "List all newsgroups that have names or descriptions that match a regexp." - (interactive "sGnus description apropos (regexp): ") - (when (not (or gnus-description-hashtb - (gnus-read-all-descriptions-files))) - (error "Couldn't request descriptions file")) - (gnus-group-apropos regexp t)) - -;; Suggested by Per Abrahamsen . -(defun gnus-group-list-matching (level regexp &optional all lowest) - "List all groups with unread articles that match REGEXP. -If the prefix LEVEL is non-nil, it should be a number that says which -level to cut off listing groups. -If ALL, also list groups with no unread articles. -If LOWEST, don't list groups with level lower than LOWEST. - -This command may read the active file." - (interactive "P\nsList newsgroups matching: ") - ;; First make sure active file has been read. - (when (and level - (> (prefix-numeric-value level) gnus-level-killed)) - (gnus-get-killed-groups)) - (gnus-group-prepare-flat - (or level gnus-level-subscribed) all (or lowest 1) regexp) - (goto-char (point-min)) - (gnus-group-position-point)) - -(defun gnus-group-list-all-matching (level regexp &optional lowest) - "List all groups that match REGEXP. -If the prefix LEVEL is non-nil, it should be a number that says which -level to cut off listing groups. -If LOWEST, don't list groups with level lower than LOWEST." - (interactive "P\nsList newsgroups matching: ") - (when level - (setq level (prefix-numeric-value level))) - (gnus-group-list-matching (or level gnus-level-killed) regexp t lowest)) - -;; Suggested by Jack Vinson . -(defun gnus-group-save-newsrc (&optional force) - "Save the Gnus startup files. -If FORCE, force saving whether it is necessary or not." - (interactive "P") - (gnus-save-newsrc-file force)) - -(defun gnus-group-restart (&optional arg) - "Force Gnus to read the .newsrc file." - (interactive "P") - (when (gnus-yes-or-no-p - (format "Are you sure you want to restart Gnus? ")) - (gnus-save-newsrc-file) - (gnus-clear-system) - (gnus))) - -(defun gnus-group-read-init-file () - "Read the Gnus elisp init file." - (interactive) - (gnus-read-init-file) - (gnus-message 5 "Read %s" gnus-init-file)) - -(defun gnus-group-check-bogus-groups (&optional silent) - "Check bogus newsgroups. -If given a prefix, don't ask for confirmation before removing a bogus -group." - (interactive "P") - (gnus-check-bogus-newsgroups (and (not silent) (not gnus-expert-user))) - (gnus-group-list-groups)) - -(defun gnus-group-find-new-groups (&optional arg) - "Search for new groups and add them. -Each new group will be treated with `gnus-subscribe-newsgroup-method.' -With 1 C-u, use the `ask-server' method to query the server for new -groups. -With 2 C-u's, use most complete method possible to query the server -for new groups, and subscribe the new groups as zombies." - (interactive "p") - (gnus-find-new-newsgroups (or arg 1)) - (gnus-group-list-groups)) - -(defun gnus-group-edit-global-kill (&optional article group) - "Edit the global kill file. -If GROUP, edit that local kill file instead." - (interactive "P") - (setq gnus-current-kill-article article) - (gnus-kill-file-edit-file group) - (gnus-message - 6 - (substitute-command-keys - (format "Editing a %s kill file (Type \\[gnus-kill-file-exit] to exit)" - (if group "local" "global"))))) - -(defun gnus-group-edit-local-kill (article group) - "Edit a local kill file." - (interactive (list nil (gnus-group-group-name))) - (gnus-group-edit-global-kill article group)) - -(defun gnus-group-force-update () - "Update `.newsrc' file." - (interactive) - (gnus-save-newsrc-file)) - -(defun gnus-group-suspend () - "Suspend the current Gnus session. -In fact, cleanup buffers except for group mode buffer. -The hook gnus-suspend-gnus-hook is called before actually suspending." - (interactive) - (gnus-run-hooks 'gnus-suspend-gnus-hook) - ;; Kill Gnus buffers except for group mode buffer. - (let ((group-buf (get-buffer gnus-group-buffer))) - (mapcar (lambda (buf) - (unless (member buf (list group-buf gnus-dribble-buffer)) - (kill-buffer buf))) - (gnus-buffers)) - (gnus-kill-gnus-frames) - (when group-buf - (bury-buffer group-buf) - (delete-windows-on group-buf t)))) - -(defun gnus-group-clear-dribble () - "Clear all information from the dribble buffer." - (interactive) - (gnus-dribble-clear) - (gnus-message 7 "Cleared dribble buffer")) - -(defun gnus-group-exit () - "Quit reading news after updating .newsrc.eld and .newsrc. -The hook `gnus-exit-gnus-hook' is called before actually exiting." - (interactive) - (when - (or noninteractive ;For gnus-batch-kill - (not gnus-interactive-exit) ;Without confirmation - gnus-expert-user - (gnus-y-or-n-p "Are you sure you want to quit reading news? ")) - (gnus-run-hooks 'gnus-exit-gnus-hook) - ;; Offer to save data from non-quitted summary buffers. - (gnus-offer-save-summaries) - ;; Save the newsrc file(s). - (gnus-save-newsrc-file) - ;; Kill-em-all. - (gnus-close-backends) - ;; Reset everything. - (gnus-clear-system) - ;; Allow the user to do things after cleaning up. - (gnus-run-hooks 'gnus-after-exiting-gnus-hook))) - -(defun gnus-group-quit () - "Quit reading news without updating .newsrc.eld or .newsrc. -The hook `gnus-exit-gnus-hook' is called before actually exiting." - (interactive) - (when (or noninteractive ;For gnus-batch-kill - (zerop (buffer-size)) - (not (gnus-server-opened gnus-select-method)) - gnus-expert-user - (not gnus-current-startup-file) - (gnus-yes-or-no-p - (format "Quit reading news without saving %s? " - (file-name-nondirectory gnus-current-startup-file)))) - (gnus-run-hooks 'gnus-exit-gnus-hook) - (gnus-configure-windows 'group t) - (gnus-dribble-save) - (gnus-close-backends) - (gnus-clear-system) - (gnus-kill-buffer gnus-group-buffer) - ;; Allow the user to do things after cleaning up. - (gnus-run-hooks 'gnus-after-exiting-gnus-hook))) - -(defun gnus-group-describe-briefly () - "Give a one line description of the group mode commands." - (interactive) - (gnus-message 7 (substitute-command-keys "\\\\[gnus-group-read-group]:Select \\[gnus-group-next-unread-group]:Forward \\[gnus-group-prev-unread-group]:Backward \\[gnus-group-exit]:Exit \\[gnus-info-find-node]:Run Info \\[gnus-group-describe-briefly]:This help"))) - -(defun gnus-group-browse-foreign-server (method) - "Browse a foreign news server. -If called interactively, this function will ask for a select method - (nntp, nnspool, etc.) and a server address (eg. nntp.some.where). -If not, METHOD should be a list where the first element is the method -and the second element is the address." - (interactive - (list (let ((how (completing-read - "Which backend: " - (append gnus-valid-select-methods gnus-server-alist) - nil t (cons "nntp" 0) 'gnus-method-history))) - ;; We either got a backend name or a virtual server name. - ;; If the first, we also need an address. - (if (assoc how gnus-valid-select-methods) - (list (intern how) - ;; Suggested by mapjph@bath.ac.uk. - (completing-read - "Address: " - (mapcar (lambda (server) (list server)) - gnus-secondary-servers))) - ;; We got a server name. - how)))) - (gnus-browse-foreign-server method)) - -(defun gnus-group-set-info (info &optional method-only-group part) - (let* ((entry (gnus-gethash - (or method-only-group (gnus-info-group info)) - gnus-newsrc-hashtb)) - (part-info info) - (info (if method-only-group (nth 2 entry) info)) - method) - (when method-only-group - (unless entry - (error "Trying to change non-existent group %s" method-only-group)) - ;; We have received parts of the actual group info - either the - ;; select method or the group parameters. We first check - ;; whether we have to extend the info, and if so, do that. - (let ((len (length info)) - (total (if (eq part 'method) 5 6))) - (when (< len total) - (setcdr (nthcdr (1- len) info) - (make-list (- total len) nil))) - ;; Then we enter the new info. - (setcar (nthcdr (1- total) info) part-info))) - (unless entry - ;; This is a new group, so we just create it. - (save-excursion - (set-buffer gnus-group-buffer) - (setq method (gnus-info-method info)) - (when (gnus-server-equal method "native") - (setq method nil)) - (save-excursion - (set-buffer gnus-group-buffer) - (if method - ;; It's a foreign group... - (gnus-group-make-group - (gnus-group-real-name (gnus-info-group info)) - (if (stringp method) method - (prin1-to-string (car method))) - (and (consp method) - (nth 1 (gnus-info-method info)))) - ;; It's a native group. - (gnus-group-make-group (gnus-info-group info)))) - (gnus-message 6 "Note: New group created") - (setq entry - (gnus-gethash (gnus-group-prefixed-name - (gnus-group-real-name (gnus-info-group info)) - (or (gnus-info-method info) gnus-select-method)) - gnus-newsrc-hashtb)))) - ;; Whether it was a new group or not, we now have the entry, so we - ;; can do the update. - (if entry - (progn - (setcar (nthcdr 2 entry) info) - (when (and (not (eq (car entry) t)) - (gnus-active (gnus-info-group info))) - (setcar entry (length (gnus-list-of-unread-articles (car info)))))) - (error "No such group: %s" (gnus-info-group info))))) - -(defun gnus-group-set-method-info (group select-method) - (gnus-group-set-info select-method group 'method)) - -(defun gnus-group-set-params-info (group params) - (gnus-group-set-info params group 'params)) - -(defun gnus-add-marked-articles (group type articles &optional info force) - ;; Add ARTICLES of TYPE to the info of GROUP. - ;; If INFO is non-nil, use that info. If FORCE is non-nil, don't - ;; add, but replace marked articles of TYPE with ARTICLES. - (let ((info (or info (gnus-get-info group))) - marked m) - (or (not info) - (and (not (setq marked (nthcdr 3 info))) - (or (null articles) - (setcdr (nthcdr 2 info) - (list (list (cons type (gnus-compress-sequence - articles t))))))) - (and (not (setq m (assq type (car marked)))) - (or (null articles) - (setcar marked - (cons (cons type (gnus-compress-sequence articles t) ) - (car marked))))) - (if force - (if (null articles) - (setcar (nthcdr 3 info) - (gnus-delete-alist type (car marked))) - (setcdr m (gnus-compress-sequence articles t))) - (setcdr m (gnus-compress-sequence - (sort (nconc (gnus-uncompress-range (cdr m)) - (copy-sequence articles)) '<) t)))))) - -;;; -;;; Group timestamps -;;; - -(defun gnus-group-set-timestamp () - "Change the timestamp of the current group to the current time. -This function can be used in hooks like `gnus-select-group-hook' -or `gnus-group-catchup-group-hook'." - (when gnus-newsgroup-name - (let ((time (current-time))) - (setcdr (cdr time) nil) - (gnus-group-set-parameter gnus-newsgroup-name 'timestamp time)))) - -(defsubst gnus-group-timestamp (group) - "Return the timestamp for GROUP." - (gnus-group-get-parameter group 'timestamp t)) - -(defun gnus-group-timestamp-delta (group) - "Return the offset in seconds from the timestamp for GROUP to the current time, as a floating point number." - (let* ((time (or (gnus-group-timestamp group) - (list 0 0))) - (delta (gnus-time-minus (current-time) time))) - (+ (* (nth 0 delta) 65536.0) - (nth 1 delta)))) - -(defun gnus-group-timestamp-string (group) - "Return a string of the timestamp for GROUP." - (let ((time (gnus-group-timestamp group))) - (if (not time) - "" - (gnus-time-iso8601 time)))) - -(provide 'gnus-group) - -;;; gnus-group.el ends here diff --git a/lisp/gnus-i18n.el b/lisp/gnus-i18n.el deleted file mode 100644 index 78eeb03..0000000 --- a/lisp/gnus-i18n.el +++ /dev/null @@ -1,95 +0,0 @@ -;;; gnus-i18n.el --- Internationalization for Gnus - -;; Copyright (C) 1996,1997 Free Software Foundation, Inc. - -;; Author: MORIOKA Tomohiko -;; Created: 1997/11/27 -;; Keywords: internationalization, news, mail - -;; This file is not part of GNU Emacs yet. - -;; This program is free software; you can redistribute it and/or -;; modify it under the terms of the GNU General Public License as -;; published by the Free Software Foundation; either version 2, or (at -;; your option) any later version. - -;; This program is distributed in the hope that it will be useful, but -;; WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -;; General Public License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs; see the file COPYING. If not, write to the -;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. - -;;; Code: - -;;; @ newsgroup default charset -;;; - -(defvar gnus-newsgroup-default-charset-alist - '(("^\\(fj\\|tnn\\|japan\\)\\." . iso-2022-jp-2) - ("^han\\." . euc-kr) - ("^relcom\\." . koi8-r) - ("^alt\\.chinese\\.text\\.big5" . cn-big5) - ("^hk\\(star\\)?\\." . cn-big5) - ("^tw\\." . cn-big5) - ("^alt\\.chinese" . hz-gb-2312) - ) - "Alist of newsgroup patterns vs. corresponding default MIME charset. -Each element looks like (REGEXP . SYMBOL). REGEXP is pattern for -newsgroup name. SYMBOL is MIME charset or coding-system.") - -(defun gnus-set-newsgroup-default-charset (newsgroup charset) - "Set CHARSET for the NEWSGROUP as default MIME charset." - (let* ((ng-regexp (concat "^" (regexp-quote newsgroup) "\\($\\|\\.\\)")) - (pair (assoc ng-regexp gnus-newsgroup-default-charset-alist)) - ) - (if pair - (setcdr pair charset) - (setq gnus-newsgroup-default-charset-alist - (cons (cons ng-regexp charset) - gnus-newsgroup-default-charset-alist)) - ))) - - -;;; @ localization -;;; - -(defun gnus-set-summary-default-charset () - "Set up `default-mime-charset' of summary buffer. -It is specified by variable `gnus-newsgroup-default-charset-alist' -\(cf. function `gnus-set-newsgroup-default-charset')." - (if (buffer-live-p gnus-summary-buffer) - (let ((charset - (catch 'found - (let ((group - (save-excursion - (set-buffer gnus-summary-buffer) - gnus-newsgroup-name)) - (alist gnus-newsgroup-default-charset-alist)) - (while alist - (let ((pair (car alist))) - (if (string-match (car pair) group) - (throw 'found (cdr pair)) - )) - (setq alist (cdr alist))) - )))) - (if charset - (progn - (save-excursion - (set-buffer gnus-summary-buffer) - (make-local-variable 'default-mime-charset) - (setq default-mime-charset charset)) - (make-local-variable 'default-mime-charset) - (setq default-mime-charset charset)) - (kill-local-variable 'default-mime-charset))))) - - -;;; @ end -;;; - -(provide 'gnus-i18n) - -;;; gnus-i18n.el ends here diff --git a/lisp/gnus-int.el b/lisp/gnus-int.el deleted file mode 100644 index 8143d0d..0000000 --- a/lisp/gnus-int.el +++ /dev/null @@ -1,507 +0,0 @@ -;;; gnus-int.el --- backend interface functions for Gnus -;; Copyright (C) 1996,97,98 Free Software Foundation, Inc. - -;; Author: Lars Magne Ingebrigtsen -;; Keywords: news - -;; This file is part of GNU Emacs. - -;; GNU Emacs is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 2, or (at your option) -;; any later version. - -;; GNU Emacs is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs; see the file COPYING. If not, write to the -;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. - -;;; Commentary: - -;;; Code: - -(eval-when-compile (require 'cl)) - -(require 'gnus) - -(defcustom gnus-open-server-hook nil - "Hook called just before opening connection to the news server." - :group 'gnus-start - :type 'hook) - -;;; -;;; Server Communication -;;; - -(defun gnus-start-news-server (&optional confirm) - "Open a method for getting news. -If CONFIRM is non-nil, the user will be asked for an NNTP server." - (let (how) - (if gnus-current-select-method - ;; Stream is already opened. - nil - ;; Open NNTP server. - (unless gnus-nntp-service - (setq gnus-nntp-server nil)) - (when confirm - ;; Read server name with completion. - (setq gnus-nntp-server - (completing-read "NNTP server: " - (mapcar (lambda (server) (list server)) - (cons (list gnus-nntp-server) - gnus-secondary-servers)) - nil nil gnus-nntp-server))) - - (when (and gnus-nntp-server - (stringp gnus-nntp-server) - (not (string= gnus-nntp-server ""))) - (setq gnus-select-method - (cond ((or (string= gnus-nntp-server "") - (string= gnus-nntp-server "::")) - (list 'nnspool (system-name))) - ((string-match "^:" gnus-nntp-server) - (list 'nnmh gnus-nntp-server - (list 'nnmh-directory - (file-name-as-directory - (expand-file-name - (concat "~/" (substring - gnus-nntp-server 1))))) - (list 'nnmh-get-new-mail nil))) - (t - (list 'nntp gnus-nntp-server))))) - - (setq how (car gnus-select-method)) - (cond - ((eq how 'nnspool) - (require 'nnspool) - (gnus-message 5 "Looking up local news spool...")) - ((eq how 'nnmh) - (require 'nnmh) - (gnus-message 5 "Looking up mh spool...")) - (t - (require 'nntp))) - (setq gnus-current-select-method gnus-select-method) - (gnus-run-hooks 'gnus-open-server-hook) - (or - ;; gnus-open-server-hook might have opened it - (gnus-server-opened gnus-select-method) - (gnus-open-server gnus-select-method) - (gnus-y-or-n-p - (format - "%s (%s) open error: '%s'. Continue? " - (car gnus-select-method) (cadr gnus-select-method) - (gnus-status-message gnus-select-method))) - (gnus-error 1 "Couldn't open server on %s" - (nth 1 gnus-select-method)))))) - -(defun gnus-check-group (group) - "Try to make sure that the server where GROUP exists is alive." - (let ((method (gnus-find-method-for-group group))) - (or (gnus-server-opened method) - (gnus-open-server method)))) - -(defun gnus-check-server (&optional method silent) - "Check whether the connection to METHOD is down. -If METHOD is nil, use `gnus-select-method'. -If it is down, start it up (again)." - (let ((method (or method gnus-select-method))) - ;; Transform virtual server names into select methods. - (when (stringp method) - (setq method (gnus-server-to-method method))) - (if (gnus-server-opened method) - ;; The stream is already opened. - t - ;; Open the server. - (unless silent - (gnus-message 5 "Opening %s server%s..." (car method) - (if (equal (nth 1 method) "") "" - (format " on %s" (nth 1 method))))) - (gnus-run-hooks 'gnus-open-server-hook) - (prog1 - (gnus-open-server method) - (unless silent - (message "")))))) - -(defun gnus-get-function (method function &optional noerror) - "Return a function symbol based on METHOD and FUNCTION." - ;; Translate server names into methods. - (unless method - (error "Attempted use of a nil select method")) - (when (stringp method) - (setq method (gnus-server-to-method method))) - ;; Check cache of constructed names. - (let* ((method-sym (if gnus-agent - (gnus-agent-get-function method) - (car method))) - (method-fns (get method-sym 'gnus-method-functions)) - (func (let ((method-fnlist-elt (assq function method-fns))) - (unless method-fnlist-elt - (setq method-fnlist-elt - (cons function - (intern (format "%s-%s" method-sym function)))) - (put method-sym 'gnus-method-functions - (cons method-fnlist-elt method-fns))) - (cdr method-fnlist-elt)))) - ;; Maybe complain if there is no function. - (unless (fboundp func) - (unless (car method) - (error "Trying to require a method that doesn't exist")) - (require (car method)) - (when (not (fboundp func)) - (if noerror - (setq func nil) - (error "No such function: %s" func)))) - func)) - - -;;; -;;; Interface functions to the backends. -;;; - -(defun gnus-open-server (gnus-command-method) - "Open a connection to GNUS-COMMAND-METHOD." - (when (stringp gnus-command-method) - (setq gnus-command-method (gnus-server-to-method gnus-command-method))) - (let ((elem (assoc gnus-command-method gnus-opened-servers))) - ;; If this method was previously denied, we just return nil. - (if (eq (nth 1 elem) 'denied) - (progn - (gnus-message 1 "Denied server") - nil) - ;; Open the server. - (let ((result - (funcall (gnus-get-function gnus-command-method 'open-server) - (nth 1 gnus-command-method) - (nthcdr 2 gnus-command-method)))) - ;; If this hasn't been opened before, we add it to the list. - (unless elem - (setq elem (list gnus-command-method nil) - gnus-opened-servers (cons elem gnus-opened-servers))) - ;; Set the status of this server. - (setcar (cdr elem) (if result 'ok 'denied)) - ;; Return the result from the "open" call. - result)))) - -(defun gnus-close-server (gnus-command-method) - "Close the connection to GNUS-COMMAND-METHOD." - (when (stringp gnus-command-method) - (setq gnus-command-method (gnus-server-to-method gnus-command-method))) - (funcall (gnus-get-function gnus-command-method 'close-server) - (nth 1 gnus-command-method))) - -(defun gnus-request-list (gnus-command-method) - "Request the active file from GNUS-COMMAND-METHOD." - (when (stringp gnus-command-method) - (setq gnus-command-method (gnus-server-to-method gnus-command-method))) - (funcall (gnus-get-function gnus-command-method 'request-list) - (nth 1 gnus-command-method))) - -(defun gnus-request-list-newsgroups (gnus-command-method) - "Request the newsgroups file from GNUS-COMMAND-METHOD." - (when (stringp gnus-command-method) - (setq gnus-command-method (gnus-server-to-method gnus-command-method))) - (funcall (gnus-get-function gnus-command-method 'request-list-newsgroups) - (nth 1 gnus-command-method))) - -(defun gnus-request-newgroups (date gnus-command-method) - "Request all new groups since DATE from GNUS-COMMAND-METHOD." - (when (stringp gnus-command-method) - (setq gnus-command-method (gnus-server-to-method gnus-command-method))) - (let ((func (gnus-get-function gnus-command-method 'request-newgroups t))) - (when func - (funcall func date (nth 1 gnus-command-method))))) - -(defun gnus-server-opened (gnus-command-method) - "Check whether a connection to GNUS-COMMAND-METHOD has been opened." - (when (stringp gnus-command-method) - (setq gnus-command-method (gnus-server-to-method gnus-command-method))) - (funcall (inline (gnus-get-function gnus-command-method 'server-opened)) - (nth 1 gnus-command-method))) - -(defun gnus-status-message (gnus-command-method) - "Return the status message from GNUS-COMMAND-METHOD. -If GNUS-COMMAND-METHOD is a string, it is interpreted as a group name. The method -this group uses will be queried." - (let ((gnus-command-method - (if (stringp gnus-command-method) - (gnus-find-method-for-group gnus-command-method) - gnus-command-method))) - (funcall (gnus-get-function gnus-command-method 'status-message) - (nth 1 gnus-command-method)))) - -(defun gnus-request-regenerate (gnus-command-method) - "Request a data generation from GNUS-COMMAND-METHOD." - (when (stringp gnus-command-method) - (setq gnus-command-method (gnus-server-to-method gnus-command-method))) - (funcall (gnus-get-function gnus-command-method 'request-regenerate) - (nth 1 gnus-command-method))) - -(defun gnus-request-group (group &optional dont-check gnus-command-method) - "Request GROUP. If DONT-CHECK, no information is required." - (let ((gnus-command-method - (or gnus-command-method (inline (gnus-find-method-for-group group))))) - (when (stringp gnus-command-method) - (setq gnus-command-method - (inline (gnus-server-to-method gnus-command-method)))) - (funcall (inline (gnus-get-function gnus-command-method 'request-group)) - (gnus-group-real-name group) (nth 1 gnus-command-method) - dont-check))) - -(defun gnus-list-active-group (group) - "Request active information on GROUP." - (let ((gnus-command-method (gnus-find-method-for-group group)) - (func 'list-active-group)) - (when (gnus-check-backend-function func group) - (funcall (gnus-get-function gnus-command-method func) - (gnus-group-real-name group) (nth 1 gnus-command-method))))) - -(defun gnus-request-group-description (group) - "Request a description of GROUP." - (let ((gnus-command-method (gnus-find-method-for-group group)) - (func 'request-group-description)) - (when (gnus-check-backend-function func group) - (funcall (gnus-get-function gnus-command-method func) - (gnus-group-real-name group) (nth 1 gnus-command-method))))) - -(defun gnus-close-group (group) - "Request the GROUP be closed." - (let ((gnus-command-method (inline (gnus-find-method-for-group group)))) - (funcall (gnus-get-function gnus-command-method 'close-group) - (gnus-group-real-name group) (nth 1 gnus-command-method)))) - -(defun gnus-retrieve-headers (articles group &optional fetch-old) - "Request headers for ARTICLES in GROUP. -If FETCH-OLD, retrieve all headers (or some subset thereof) in the group." - (let ((gnus-command-method (gnus-find-method-for-group group))) - (if (and gnus-use-cache (numberp (car articles))) - (gnus-cache-retrieve-headers articles group fetch-old) - (funcall (gnus-get-function gnus-command-method 'retrieve-headers) - articles (gnus-group-real-name group) - (nth 1 gnus-command-method) fetch-old)))) - -(defun gnus-retrieve-articles (articles group) - "Request ARTICLES in GROUP." - (let ((gnus-command-method (gnus-find-method-for-group group))) - (funcall (gnus-get-function gnus-command-method 'retrieve-articles) - articles (gnus-group-real-name group) - (nth 1 gnus-command-method)))) - -(defun gnus-retrieve-groups (groups gnus-command-method) - "Request active information on GROUPS from GNUS-COMMAND-METHOD." - (when (stringp gnus-command-method) - (setq gnus-command-method (gnus-server-to-method gnus-command-method))) - (funcall (gnus-get-function gnus-command-method 'retrieve-groups) - groups (nth 1 gnus-command-method))) - -(defun gnus-request-type (group &optional article) - "Return the type (`post' or `mail') of GROUP (and ARTICLE)." - (let ((gnus-command-method (gnus-find-method-for-group group))) - (if (not (gnus-check-backend-function - 'request-type (car gnus-command-method))) - 'unknown - (funcall (gnus-get-function gnus-command-method 'request-type) - (gnus-group-real-name group) article)))) - -(defun gnus-request-update-mark (group article mark) - "Allow the backend to change the mark the user tries to put on an article." - (let ((gnus-command-method (gnus-find-method-for-group group))) - (if (not (gnus-check-backend-function - 'request-update-mark (car gnus-command-method))) - mark - (funcall (gnus-get-function gnus-command-method 'request-update-mark) - (gnus-group-real-name group) article mark)))) - -(defun gnus-request-article (article group &optional buffer) - "Request the ARTICLE in GROUP. -ARTICLE can either be an article number or an article Message-ID. -If BUFFER, insert the article in that group." - (let ((gnus-command-method (gnus-find-method-for-group group))) - (funcall (gnus-get-function gnus-command-method 'request-article) - article (gnus-group-real-name group) - (nth 1 gnus-command-method) buffer))) - -(defun gnus-request-head (article group) - "Request the head of ARTICLE in GROUP." - (let* ((gnus-command-method (gnus-find-method-for-group group)) - (head (gnus-get-function gnus-command-method 'request-head t)) - res clean-up) - (cond - ;; Check the cache. - ((and gnus-use-cache - (numberp article) - (gnus-cache-request-article article group)) - (setq res (cons group article) - clean-up t)) - ;; Use `head' function. - ((fboundp head) - (setq res (funcall head article (gnus-group-real-name group) - (nth 1 gnus-command-method)))) - ;; Use `article' function. - (t - (setq res (gnus-request-article article group) - clean-up t))) - (when clean-up - (save-excursion - (set-buffer nntp-server-buffer) - (goto-char (point-min)) - (when (search-forward "\n\n" nil t) - (delete-region (1- (point)) (point-max))) - (nnheader-fold-continuation-lines))) - res)) - -(defun gnus-request-body (article group) - "Request the body of ARTICLE in GROUP." - (let* ((gnus-command-method (gnus-find-method-for-group group)) - (head (gnus-get-function gnus-command-method 'request-body t)) - res clean-up) - (cond - ;; Check the cache. - ((and gnus-use-cache - (numberp article) - (gnus-cache-request-article article group)) - (setq res (cons group article) - clean-up t)) - ;; Use `head' function. - ((fboundp head) - (setq res (funcall head article (gnus-group-real-name group) - (nth 1 gnus-command-method)))) - ;; Use `article' function. - (t - (setq res (gnus-request-article article group) - clean-up t))) - (when clean-up - (save-excursion - (set-buffer nntp-server-buffer) - (goto-char (point-min)) - (when (search-forward "\n\n" nil t) - (delete-region (point-min) (1- (point)))))) - res)) - -(defun gnus-request-post (gnus-command-method) - "Post the current buffer using GNUS-COMMAND-METHOD." - (when (stringp gnus-command-method) - (setq gnus-command-method (gnus-server-to-method gnus-command-method))) - (funcall (gnus-get-function gnus-command-method 'request-post) - (nth 1 gnus-command-method))) - -(defun gnus-request-scan (group gnus-command-method) - "Request a SCAN being performed in GROUP from GNUS-COMMAND-METHOD. -If GROUP is nil, all groups on GNUS-COMMAND-METHOD are scanned." - (when gnus-plugged - (let ((gnus-command-method - (if group (gnus-find-method-for-group group) gnus-command-method)) - (gnus-inhibit-demon t)) - (funcall (gnus-get-function gnus-command-method 'request-scan) - (and group (gnus-group-real-name group)) - (nth 1 gnus-command-method))))) - -(defsubst gnus-request-update-info (info gnus-command-method) - "Request that GNUS-COMMAND-METHOD update INFO." - (when (stringp gnus-command-method) - (setq gnus-command-method (gnus-server-to-method gnus-command-method))) - (when (gnus-check-backend-function - 'request-update-info (car gnus-command-method)) - (funcall (gnus-get-function gnus-command-method 'request-update-info) - (gnus-group-real-name (gnus-info-group info)) - info (nth 1 gnus-command-method)))) - -(defun gnus-request-expire-articles (articles group &optional force) - (let ((gnus-command-method (gnus-find-method-for-group group))) - (funcall (gnus-get-function gnus-command-method 'request-expire-articles) - articles (gnus-group-real-name group) (nth 1 gnus-command-method) - force))) - -(defun gnus-request-move-article - (article group server accept-function &optional last) - (let ((gnus-command-method (gnus-find-method-for-group group))) - (funcall (gnus-get-function gnus-command-method 'request-move-article) - article (gnus-group-real-name group) - (nth 1 gnus-command-method) accept-function last))) - -(defun gnus-request-accept-article (group &optional gnus-command-method last) - ;; Make sure there's a newline at the end of the article. - (when (stringp gnus-command-method) - (setq gnus-command-method (gnus-server-to-method gnus-command-method))) - (when (and (not gnus-command-method) - (stringp group)) - (setq gnus-command-method (gnus-group-name-to-method group))) - (goto-char (point-max)) - (unless (bolp) - (insert "\n")) - (let ((func (car (or gnus-command-method - (gnus-find-method-for-group group))))) - (funcall (intern (format "%s-request-accept-article" func)) - (if (stringp group) (gnus-group-real-name group) group) - (cadr gnus-command-method) - last))) - -(defun gnus-request-replace-article (article group buffer) - (let ((func (car (gnus-group-name-to-method group)))) - (funcall (intern (format "%s-request-replace-article" func)) - article (gnus-group-real-name group) buffer))) - -(defun gnus-request-associate-buffer (group) - (let ((gnus-command-method (gnus-find-method-for-group group))) - (funcall (gnus-get-function gnus-command-method 'request-associate-buffer) - (gnus-group-real-name group)))) - -(defun gnus-request-restore-buffer (article group) - "Request a new buffer restored to the state of ARTICLE." - (let ((gnus-command-method (gnus-find-method-for-group group))) - (funcall (gnus-get-function gnus-command-method 'request-restore-buffer) - article (gnus-group-real-name group) - (nth 1 gnus-command-method)))) - -(defun gnus-request-create-group (group &optional gnus-command-method args) - (when (stringp gnus-command-method) - (setq gnus-command-method (gnus-server-to-method gnus-command-method))) - (let ((gnus-command-method - (or gnus-command-method (gnus-find-method-for-group group)))) - (funcall (gnus-get-function gnus-command-method 'request-create-group) - (gnus-group-real-name group) (nth 1 gnus-command-method) args))) - -(defun gnus-request-delete-group (group &optional force) - (let ((gnus-command-method (gnus-find-method-for-group group))) - (funcall (gnus-get-function gnus-command-method 'request-delete-group) - (gnus-group-real-name group) force (nth 1 gnus-command-method)))) - -(defun gnus-request-rename-group (group new-name) - (let ((gnus-command-method (gnus-find-method-for-group group))) - (funcall (gnus-get-function gnus-command-method 'request-rename-group) - (gnus-group-real-name group) - (gnus-group-real-name new-name) (nth 1 gnus-command-method)))) - -(defun gnus-close-backends () - ;; Send a close request to all backends that support such a request. - (let ((methods gnus-valid-select-methods) - (gnus-inhibit-demon t) - func gnus-command-method) - (while (setq gnus-command-method (pop methods)) - (when (fboundp (setq func (intern - (concat (car gnus-command-method) - "-request-close")))) - (funcall func))))) - -(defun gnus-asynchronous-p (gnus-command-method) - (let ((func (gnus-get-function gnus-command-method 'asynchronous-p t))) - (when (fboundp func) - (funcall func)))) - -(defun gnus-remove-denial (gnus-command-method) - (when (stringp gnus-command-method) - (setq gnus-command-method (gnus-server-to-method gnus-command-method))) - (let* ((elem (assoc gnus-command-method gnus-opened-servers)) - (status (cadr elem))) - ;; If this hasn't been opened before, we add it to the list. - (when (eq status 'denied) - ;; Set the status of this server. - (setcar (cdr elem) 'closed)))) - -(provide 'gnus-int) - -;;; gnus-int.el ends here diff --git a/lisp/gnus-kill.el b/lisp/gnus-kill.el deleted file mode 100644 index abcc401..0000000 --- a/lisp/gnus-kill.el +++ /dev/null @@ -1,714 +0,0 @@ -;;; gnus-kill.el --- kill commands for Gnus -;; Copyright (C) 1995,96,97,98 Free Software Foundation, Inc. - -;; Author: Masanobu UMEDA -;; Lars Magne Ingebrigtsen -;; Keywords: news - -;; This file is part of GNU Emacs. - -;; GNU Emacs is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 2, or (at your option) -;; any later version. - -;; GNU Emacs is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs; see the file COPYING. If not, write to the -;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. - -;;; Commentary: - -;;; Code: - -(eval-when-compile (require 'cl)) - -(require 'gnus) -(require 'gnus-art) -(require 'gnus-range) - -(defcustom gnus-kill-file-mode-hook nil - "Hook for Gnus kill file mode." - :group 'gnus-score-kill - :type 'hook) - -(defcustom gnus-kill-expiry-days 7 - "*Number of days before expiring unused kill file entries." - :group 'gnus-score-kill - :group 'gnus-score-expire - :type 'integer) - -(defcustom gnus-kill-save-kill-file nil - "*If non-nil, will save kill files after processing them." - :group 'gnus-score-kill - :type 'boolean) - -(defcustom gnus-winconf-kill-file nil - "What does this do, Lars?" - :group 'gnus-score-kill - :type 'sexp) - -(defcustom gnus-kill-killed t - "*If non-nil, Gnus will apply kill files to already killed articles. -If it is nil, Gnus will never apply kill files to articles that have -already been through the scoring process, which might very well save lots -of time." - :group 'gnus-score-kill - :type 'boolean) - - - -(defmacro gnus-raise (field expression level) - `(gnus-kill ,field ,expression - (function (gnus-summary-raise-score ,level)) t)) - -(defmacro gnus-lower (field expression level) - `(gnus-kill ,field ,expression - (function (gnus-summary-raise-score (- ,level))) t)) - -;;; -;;; Gnus Kill File Mode -;;; - -(defvar gnus-kill-file-mode-map nil) - -(unless gnus-kill-file-mode-map - (gnus-define-keymap (setq gnus-kill-file-mode-map - (copy-keymap emacs-lisp-mode-map)) - "\C-c\C-k\C-s" gnus-kill-file-kill-by-subject - "\C-c\C-k\C-a" gnus-kill-file-kill-by-author - "\C-c\C-k\C-t" gnus-kill-file-kill-by-thread - "\C-c\C-k\C-x" gnus-kill-file-kill-by-xref - "\C-c\C-a" gnus-kill-file-apply-buffer - "\C-c\C-e" gnus-kill-file-apply-last-sexp - "\C-c\C-c" gnus-kill-file-exit)) - -(defun gnus-kill-file-mode () - "Major mode for editing kill files. - -If you are using this mode - you probably shouldn't. Kill files -perform badly and paint with a pretty broad brush. Score files, on -the other hand, are vastly faster (40x speedup) and give you more -control over what to do. - -In addition to Emacs-Lisp Mode, the following commands are available: - -\\{gnus-kill-file-mode-map} - - A kill file contains Lisp expressions to be applied to a selected -newsgroup. The purpose is to mark articles as read on the basis of -some set of regexps. A global kill file is applied to every newsgroup, -and a local kill file is applied to a specified newsgroup. Since a -global kill file is applied to every newsgroup, for better performance -use a local one. - - A kill file can contain any kind of Emacs Lisp expressions expected -to be evaluated in the Summary buffer. Writing Lisp programs for this -purpose is not so easy because the internal working of Gnus must be -well-known. For this reason, Gnus provides a general function which -does this easily for non-Lisp programmers. - - The `gnus-kill' function executes commands available in Summary Mode -by their key sequences. `gnus-kill' should be called with FIELD, -REGEXP and optional COMMAND and ALL. FIELD is a string representing -the header field or an empty string. If FIELD is an empty string, the -entire article body is searched for. REGEXP is a string which is -compared with FIELD value. COMMAND is a string representing a valid -key sequence in Summary mode or Lisp expression. COMMAND defaults to -'(gnus-summary-mark-as-read nil \"X\"). Make sure that COMMAND is -executed in the Summary buffer. If the second optional argument ALL -is non-nil, the COMMAND is applied to articles which are already -marked as read or unread. Articles which are marked are skipped over -by default. - - For example, if you want to mark articles of which subjects contain -the string `AI' as read, a possible kill file may look like: - - (gnus-kill \"Subject\" \"AI\") - - If you want to mark articles with `D' instead of `X', you can use -the following expression: - - (gnus-kill \"Subject\" \"AI\" \"d\") - -In this example it is assumed that the command -`gnus-summary-mark-as-read-forward' is assigned to `d' in Summary Mode. - - It is possible to delete unnecessary headers which are marked with -`X' in a kill file as follows: - - (gnus-expunge \"X\") - - If the Summary buffer is empty after applying kill files, Gnus will -exit the selected newsgroup normally. If headers which are marked -with `D' are deleted in a kill file, it is impossible to read articles -which are marked as read in the previous Gnus sessions. Marks other -than `D' should be used for articles which should really be deleted. - -Entry to this mode calls emacs-lisp-mode-hook and -gnus-kill-file-mode-hook with no arguments, if that value is non-nil." - (interactive) - (kill-all-local-variables) - (use-local-map gnus-kill-file-mode-map) - (set-syntax-table emacs-lisp-mode-syntax-table) - (setq major-mode 'gnus-kill-file-mode) - (setq mode-name "Kill") - (lisp-mode-variables nil) - (gnus-run-hooks 'emacs-lisp-mode-hook 'gnus-kill-file-mode-hook)) - -(defun gnus-kill-file-edit-file (newsgroup) - "Begin editing a kill file for NEWSGROUP. -If NEWSGROUP is nil, the global kill file is selected." - (interactive "sNewsgroup: ") - (let ((file (gnus-newsgroup-kill-file newsgroup))) - (gnus-make-directory (file-name-directory file)) - ;; Save current window configuration if this is first invocation. - (or (and (get-file-buffer file) - (get-buffer-window (get-file-buffer file))) - (setq gnus-winconf-kill-file (current-window-configuration))) - ;; Hack windows. - (let ((buffer (find-file-noselect file))) - (cond ((get-buffer-window buffer) - (pop-to-buffer buffer)) - ((eq major-mode 'gnus-group-mode) - (gnus-configure-windows 'group) ;Take all windows. - (pop-to-buffer buffer)) - ((eq major-mode 'gnus-summary-mode) - (gnus-configure-windows 'article) - (pop-to-buffer gnus-article-buffer) - (bury-buffer gnus-article-buffer) - (switch-to-buffer buffer)) - (t ;No good rules. - (find-file-other-window file)))) - (gnus-kill-file-mode))) - -;; Fix by Sudish Joseph . -(defun gnus-kill-set-kill-buffer () - (let* ((file (gnus-newsgroup-kill-file gnus-newsgroup-name)) - (buffer (find-file-noselect file))) - (set-buffer buffer) - (gnus-kill-file-mode) - (bury-buffer buffer))) - -(defun gnus-kill-file-enter-kill (field regexp &optional dont-move) - ;; Enter kill file entry. - ;; FIELD: String containing the name of the header field to kill. - ;; REGEXP: The string to kill. - (save-excursion - (let (string) - (unless (eq major-mode 'gnus-kill-file-mode) - (gnus-kill-set-kill-buffer)) - (unless dont-move - (goto-char (point-max))) - (insert (setq string (format "(gnus-kill %S %S)\n" field regexp))) - (gnus-kill-file-apply-string string)))) - -(defun gnus-kill-file-kill-by-subject () - "Kill by subject." - (interactive) - (gnus-kill-file-enter-kill - "Subject" - (if (vectorp gnus-current-headers) - (regexp-quote - (gnus-simplify-subject (mail-header-subject gnus-current-headers))) - "") - t)) - -(defun gnus-kill-file-kill-by-author () - "Kill by author." - (interactive) - (gnus-kill-file-enter-kill - "From" - (if (vectorp gnus-current-headers) - (regexp-quote (mail-header-from gnus-current-headers)) - "") t)) - -(defun gnus-kill-file-kill-by-thread () - "Kill by author." - (interactive) - (gnus-kill-file-enter-kill - "References" - (if (vectorp gnus-current-headers) - (regexp-quote (mail-header-id gnus-current-headers)) - ""))) - -(defun gnus-kill-file-kill-by-xref () - "Kill by Xref." - (interactive) - (let ((xref (and (vectorp gnus-current-headers) - (mail-header-xref gnus-current-headers))) - (start 0) - group) - (if xref - (while (string-match " \\([^ \t]+\\):" xref start) - (setq start (match-end 0)) - (when (not (string= - (setq group - (substring xref (match-beginning 1) (match-end 1))) - gnus-newsgroup-name)) - (gnus-kill-file-enter-kill - "Xref" (concat " " (regexp-quote group) ":") t))) - (gnus-kill-file-enter-kill "Xref" "" t)))) - -(defun gnus-kill-file-raise-followups-to-author (level) - "Raise score for all followups to the current author." - (interactive "p") - (let ((name (mail-header-from gnus-current-headers)) - string) - (save-excursion - (gnus-kill-set-kill-buffer) - (goto-char (point-min)) - (setq name (read-string (concat "Add " level - " to followup articles to: ") - (regexp-quote name))) - (setq - string - (format - "(gnus-kill %S %S '(gnus-summary-temporarily-raise-by-thread %S))\n" - "From" name level)) - (insert string) - (gnus-kill-file-apply-string string)) - (gnus-message - 6 "Added temporary score file entry for followups to %s." name))) - -(defun gnus-kill-file-apply-buffer () - "Apply current buffer to current newsgroup." - (interactive) - (if (and gnus-current-kill-article - (get-buffer gnus-summary-buffer)) - ;; Assume newsgroup is selected. - (gnus-kill-file-apply-string (buffer-string)) - (ding) (gnus-message 2 "No newsgroup is selected."))) - -(defun gnus-kill-file-apply-string (string) - "Apply STRING to current newsgroup." - (interactive) - (let ((string (concat "(progn \n" string "\n)"))) - (save-excursion - (save-window-excursion - (pop-to-buffer gnus-summary-buffer) - (eval (car (read-from-string string))))))) - -(defun gnus-kill-file-apply-last-sexp () - "Apply sexp before point in current buffer to current newsgroup." - (interactive) - (if (and gnus-current-kill-article - (get-buffer gnus-summary-buffer)) - ;; Assume newsgroup is selected. - (let ((string - (buffer-substring - (save-excursion (forward-sexp -1) (point)) (point)))) - (save-excursion - (save-window-excursion - (pop-to-buffer gnus-summary-buffer) - (eval (car (read-from-string string)))))) - (ding) (gnus-message 2 "No newsgroup is selected."))) - -(defun gnus-kill-file-exit () - "Save a kill file, then return to the previous buffer." - (interactive) - (save-buffer) - (let ((killbuf (current-buffer))) - ;; We don't want to return to article buffer. - (when (get-buffer gnus-article-buffer) - (bury-buffer gnus-article-buffer)) - ;; Delete the KILL file windows. - (delete-windows-on killbuf) - ;; Restore last window configuration if available. - (when gnus-winconf-kill-file - (set-window-configuration gnus-winconf-kill-file)) - (setq gnus-winconf-kill-file nil) - ;; Kill the KILL file buffer. Suggested by tale@pawl.rpi.edu. - (kill-buffer killbuf))) - -;; For kill files - -(defun gnus-Newsgroup-kill-file (newsgroup) - "Return the name of a kill file for NEWSGROUP. -If NEWSGROUP is nil, return the global kill file instead." - (cond ((or (null newsgroup) - (string-equal newsgroup "")) - ;; The global kill file is placed at top of the directory. - (expand-file-name gnus-kill-file-name gnus-kill-files-directory)) - (gnus-use-long-file-name - ;; Append ".KILL" to capitalized newsgroup name. - (expand-file-name (concat (gnus-capitalize-newsgroup newsgroup) - "." gnus-kill-file-name) - gnus-kill-files-directory)) - (t - ;; Place "KILL" under the hierarchical directory. - (expand-file-name (concat (gnus-newsgroup-directory-form newsgroup) - "/" gnus-kill-file-name) - gnus-kill-files-directory)))) - -(defun gnus-expunge (marks) - "Remove lines marked with MARKS." - (save-excursion - (set-buffer gnus-summary-buffer) - (gnus-summary-limit-to-marks marks 'reverse))) - -(defun gnus-apply-kill-file-unless-scored () - "Apply .KILL file, unless a .SCORE file for the same newsgroup exists." - (cond ((file-exists-p (gnus-score-file-name gnus-newsgroup-name)) - ;; Ignores global KILL. - (when (file-exists-p (gnus-newsgroup-kill-file gnus-newsgroup-name)) - (gnus-message 3 "Note: Ignoring %s.KILL; preferring .SCORE" - gnus-newsgroup-name)) - 0) - ((or (file-exists-p (gnus-newsgroup-kill-file nil)) - (file-exists-p (gnus-newsgroup-kill-file gnus-newsgroup-name))) - (gnus-apply-kill-file-internal)) - (t - 0))) - -(defun gnus-apply-kill-file-internal () - "Apply a kill file to the current newsgroup. -Returns the number of articles marked as read." - (let* ((kill-files (list (gnus-newsgroup-kill-file nil) - (gnus-newsgroup-kill-file gnus-newsgroup-name))) - (unreads (length gnus-newsgroup-unreads)) - (gnus-summary-inhibit-highlight t) - beg) - (setq gnus-newsgroup-kill-headers nil) - ;; If there are any previously scored articles, we remove these - ;; from the `gnus-newsgroup-headers' list that the score functions - ;; will see. This is probably pretty wasteful when it comes to - ;; conses, but is, I think, faster than having to assq in every - ;; single score function. - (let ((files kill-files)) - (while files - (if (file-exists-p (car files)) - (let ((headers gnus-newsgroup-headers)) - (if gnus-kill-killed - (setq gnus-newsgroup-kill-headers - (mapcar (lambda (header) (mail-header-number header)) - headers)) - (while headers - (unless (gnus-member-of-range - (mail-header-number (car headers)) - gnus-newsgroup-killed) - (push (mail-header-number (car headers)) - gnus-newsgroup-kill-headers)) - (setq headers (cdr headers)))) - (setq files nil)) - (setq files (cdr files))))) - (if (not gnus-newsgroup-kill-headers) - () - (save-window-excursion - (save-excursion - (while kill-files - (if (not (file-exists-p (car kill-files))) - () - (gnus-message 6 "Processing kill file %s..." (car kill-files)) - (find-file (car kill-files)) - (goto-char (point-min)) - - (if (consp (ignore-errors (read (current-buffer)))) - (gnus-kill-parse-gnus-kill-file) - (gnus-kill-parse-rn-kill-file)) - - (gnus-message - 6 "Processing kill file %s...done" (car kill-files))) - (setq kill-files (cdr kill-files))))) - - (gnus-set-mode-line 'summary) - - (if beg - (let ((nunreads (- unreads (length gnus-newsgroup-unreads)))) - (or (eq nunreads 0) - (gnus-message 6 "Marked %d articles as read" nunreads)) - nunreads) - 0)))) - -;; Parse a Gnus killfile. -(defun gnus-score-insert-help (string alist idx) - (save-excursion - (pop-to-buffer "*Score Help*") - (buffer-disable-undo (current-buffer)) - (erase-buffer) - (insert string ":\n\n") - (while alist - (insert (format " %c: %s\n" (caar alist) (nth idx (car alist)))) - (setq alist (cdr alist))))) - -(defun gnus-kill-parse-gnus-kill-file () - (goto-char (point-min)) - (gnus-kill-file-mode) - (let (beg form) - (while (progn - (setq beg (point)) - (setq form (ignore-errors (read (current-buffer))))) - (unless (listp form) - (error "Illegal kill entry (possibly rn kill file?): %s" form)) - (if (or (eq (car form) 'gnus-kill) - (eq (car form) 'gnus-raise) - (eq (car form) 'gnus-lower)) - (progn - (delete-region beg (point)) - (insert (or (eval form) ""))) - (save-excursion - (set-buffer gnus-summary-buffer) - (ignore-errors (eval form))))) - (and (buffer-modified-p) - gnus-kill-save-kill-file - (save-buffer)) - (set-buffer-modified-p nil))) - -;; Parse an rn killfile. -(defun gnus-kill-parse-rn-kill-file () - (goto-char (point-min)) - (gnus-kill-file-mode) - (let ((mod-to-header - '((?a . "") - (?h . "") - (?f . "from") - (?: . "subject"))) - ;;(com-to-com - ;; '((?m . " ") - ;; (?j . "X"))) - pattern modifier commands) - (while (not (eobp)) - (if (not (looking-at "[ \t]*/\\([^/]*\\)/\\([ahfcH]\\)?:\\([a-z=:]*\\)")) - () - (setq pattern (buffer-substring (match-beginning 1) (match-end 1))) - (setq modifier (if (match-beginning 2) (char-after (match-beginning 2)) - ?s)) - (setq commands (buffer-substring (match-beginning 3) (match-end 3))) - - ;; The "f:+" command marks everything *but* the matches as read, - ;; so we simply first match everything as read, and then unmark - ;; PATTERN later. - (when (string-match "\\+" commands) - (gnus-kill "from" ".") - (setq commands "m")) - - (gnus-kill - (or (cdr (assq modifier mod-to-header)) "subject") - pattern - (if (string-match "m" commands) - '(gnus-summary-mark-as-unread nil " ") - '(gnus-summary-mark-as-read nil "X")) - nil t)) - (forward-line 1)))) - -;; Kill changes and new format by suggested by JWZ and Sudish Joseph -;; . -(defun gnus-kill (field regexp &optional exe-command all silent) - "If FIELD of an article matches REGEXP, execute COMMAND. -Optional 1st argument COMMAND is default to - (gnus-summary-mark-as-read nil \"X\"). -If optional 2nd argument ALL is non-nil, articles marked are also applied to. -If FIELD is an empty string (or nil), entire article body is searched for. -COMMAND must be a lisp expression or a string representing a key sequence." - ;; We don't want to change current point nor window configuration. - (let ((old-buffer (current-buffer))) - (save-excursion - (save-window-excursion - ;; Selected window must be summary buffer to execute keyboard - ;; macros correctly. See command_loop_1. - (switch-to-buffer gnus-summary-buffer 'norecord) - (goto-char (point-min)) ;From the beginning. - (let ((kill-list regexp) - (date (current-time-string)) - (command (or exe-command '(gnus-summary-mark-as-read - nil gnus-kill-file-mark))) - kill kdate prev) - (if (listp kill-list) - ;; It is a list. - (if (not (consp (cdr kill-list))) - ;; It's on the form (regexp . date). - (if (zerop (gnus-execute field (car kill-list) - command nil (not all))) - (when (> (gnus-days-between date (cdr kill-list)) - gnus-kill-expiry-days) - (setq regexp nil)) - (setcdr kill-list date)) - (while (setq kill (car kill-list)) - (if (consp kill) - ;; It's a temporary kill. - (progn - (setq kdate (cdr kill)) - (if (zerop (gnus-execute - field (car kill) command nil (not all))) - (when (> (gnus-days-between date kdate) - gnus-kill-expiry-days) - ;; Time limit has been exceeded, so we - ;; remove the match. - (if prev - (setcdr prev (cdr kill-list)) - (setq regexp (cdr regexp)))) - ;; Successful kill. Set the date to today. - (setcdr kill date))) - ;; It's a permanent kill. - (gnus-execute field kill command nil (not all))) - (setq prev kill-list) - (setq kill-list (cdr kill-list)))) - (gnus-execute field kill-list command nil (not all)))))) - (switch-to-buffer old-buffer) - (when (and (eq major-mode 'gnus-kill-file-mode) regexp (not silent)) - (gnus-pp-gnus-kill - (nconc (list 'gnus-kill field - (if (consp regexp) (list 'quote regexp) regexp)) - (when (or exe-command all) - (list (list 'quote exe-command))) - (if all (list t) nil)))))) - -(defun gnus-pp-gnus-kill (object) - (if (or (not (consp (nth 2 object))) - (not (consp (cdr (nth 2 object)))) - (and (eq 'quote (car (nth 2 object))) - (not (consp (cdadr (nth 2 object)))))) - (concat "\n" (gnus-prin1-to-string object)) - (save-excursion - (set-buffer (gnus-get-buffer-create "*Gnus PP*")) - (buffer-disable-undo (current-buffer)) - (erase-buffer) - (insert (format "\n(%S %S\n '(" (nth 0 object) (nth 1 object))) - (let ((klist (cadr (nth 2 object))) - (first t)) - (while klist - (insert (if first (progn (setq first nil) "") "\n ") - (gnus-prin1-to-string (car klist))) - (setq klist (cdr klist)))) - (insert ")") - (and (nth 3 object) - (insert "\n " - (if (and (consp (nth 3 object)) - (not (eq 'quote (car (nth 3 object))))) - "'" "") - (gnus-prin1-to-string (nth 3 object)))) - (when (nth 4 object) - (insert "\n t")) - (insert ")") - (prog1 - (buffer-substring (point-min) (point-max)) - (kill-buffer (current-buffer)))))) - -(defun gnus-execute-1 (function regexp form header) - (save-excursion - (let (did-kill) - (if (null header) - nil ;Nothing to do. - (if function - ;; Compare with header field. - (let (value) - (and header - (progn - (setq value (funcall function header)) - ;; Number (Lines:) or symbol must be converted to string. - (unless (stringp value) - (setq value (gnus-prin1-to-string value))) - (setq did-kill (string-match regexp value))) - (cond ((stringp form) ;Keyboard macro. - (execute-kbd-macro form)) - ((gnus-functionp form) - (funcall form)) - (t - (eval form))))) - ;; Search article body. - (let ((gnus-current-article nil) ;Save article pointer. - (gnus-last-article nil) - (gnus-break-pages nil) ;No need to break pages. - (gnus-mark-article-hook nil)) ;Inhibit marking as read. - (gnus-message - 6 "Searching for article: %d..." (mail-header-number header)) - (gnus-article-setup-buffer) - (gnus-article-prepare (mail-header-number header) t) - (when (save-excursion - (set-buffer gnus-article-buffer) - (goto-char (point-min)) - (setq did-kill (re-search-forward regexp nil t))) - (cond ((stringp form) ;Keyboard macro. - (execute-kbd-macro form)) - ((gnus-functionp form) - (funcall form)) - (t - (eval form))))))) - did-kill))) - -(defun gnus-execute (field regexp form &optional backward unread) - "If FIELD of article header matches REGEXP, execute lisp FORM (or a string). -If FIELD is an empty string (or nil), entire article body is searched for. -If optional 1st argument BACKWARD is non-nil, do backward instead. -If optional 2nd argument UNREAD is non-nil, articles which are -marked as read or ticked are ignored." - (save-excursion - (let ((killed-no 0) - function article header) - (cond - ;; Search body. - ((or (null field) - (string-equal field "")) - (setq function nil)) - ;; Get access function of header field. - ((fboundp - (setq function - (intern-soft - (concat "mail-header-" (downcase field))))) - (setq function `(lambda (h) (,function h)))) - ;; Signal error. - (t - (error "Unknown header field: \"%s\"" field))) - ;; Starting from the current article. - (while (or - ;; First article. - (and (not article) - (setq article (gnus-summary-article-number))) - ;; Find later articles. - (setq article - (gnus-summary-search-forward unread nil backward))) - (and (or (null gnus-newsgroup-kill-headers) - (memq article gnus-newsgroup-kill-headers)) - (vectorp (setq header (gnus-summary-article-header article))) - (gnus-execute-1 function regexp form header) - (setq killed-no (1+ killed-no)))) - ;; Return the number of killed articles. - killed-no))) - -;;;###autoload -(defalias 'gnus-batch-kill 'gnus-batch-score) -;;;###autoload -(defun gnus-batch-score () - "Run batched scoring. -Usage: emacs -batch -l ~/.emacs -l gnus -f gnus-batch-score" - (interactive) - (let* ((gnus-newsrc-options-n - (gnus-newsrc-parse-options - (concat "options -n " - (mapconcat 'identity command-line-args-left " ")))) - (gnus-expert-user t) - (nnmail-spool-file nil) - (gnus-use-dribble-file nil) - (gnus-batch-mode t) - info group newsrc entry - ;; Disable verbose message. - gnus-novice-user gnus-large-newsgroup - gnus-options-subscribe gnus-auto-subscribed-groups - gnus-options-not-subscribe) - ;; Eat all arguments. - (setq command-line-args-left nil) - (gnus-slave) - ;; Apply kills to specified newsgroups in command line arguments. - (setq newsrc (cdr gnus-newsrc-alist)) - (while (setq info (pop newsrc)) - (setq group (gnus-info-group info) - entry (gnus-gethash group gnus-newsrc-hashtb)) - (when (and (<= (gnus-info-level info) gnus-level-subscribed) - (and (car entry) - (or (eq (car entry) t) - (not (zerop (car entry)))))) - (gnus-summary-read-group group nil t nil t) - (when (eq (current-buffer) (get-buffer gnus-summary-buffer)) - (gnus-summary-exit)))) - ;; Exit Emacs. - (switch-to-buffer gnus-group-buffer) - (gnus-group-save-newsrc))) - -(provide 'gnus-kill) - -;;; gnus-kill.el ends here diff --git a/lisp/gnus-load.el b/lisp/gnus-load.el deleted file mode 100644 index 978f272..0000000 --- a/lisp/gnus-load.el +++ /dev/null @@ -1,103 +0,0 @@ -;;; gnus-load.el --- automatically extracted custom dependencies -;; -;;; Code: - -(put 'nnmail 'custom-loads '("nnmail")) -(put 'gnus-article-emphasis 'custom-loads '("gnus-art")) -(put 'gnus-article-headers 'custom-loads '("gnus-sum" "gnus-art")) -(put 'nnmail-procmail 'custom-loads '("nnmail")) -(put 'gnus-score-kill 'custom-loads '("gnus-kill")) -(put 'gnus-visual 'custom-loads '("smiley" "gnus" "gnus-picon" "gnus-art" "earcon")) -(put 'gnus-score-expire 'custom-loads '("gnus-score" "gnus-kill")) -(put 'gnus-summary-maneuvering 'custom-loads '("gnus-sum")) -(put 'gnus-start 'custom-loads '("gnus" "gnus-util" "gnus-start" "gnus-int" "gnus-group")) -(put 'gnus-extract-view 'custom-loads '("gnus-uu" "gnus-sum")) -(put 'gnus-various 'custom-loads '("gnus-sum")) -(put 'gnus-article-washing 'custom-loads '("gnus-art")) -(put 'gnus-score-files 'custom-loads '("gnus-score")) -(put 'message-news 'custom-loads '("message")) -(put 'gnus-thread 'custom-loads '("gnus-sum")) -(put 'languages 'custom-loads '("cus-edit")) -(put 'development 'custom-loads '("cus-edit")) -(put 'gnus-treading 'custom-loads '("gnus-sum")) -(put 'nnmail-various 'custom-loads '("nnmail")) -(put 'extensions 'custom-loads '("wid-edit")) -(put 'message-various 'custom-loads '("message")) -(put 'gnus-summary-exit 'custom-loads '("gnus-sum")) -(put 'news 'custom-loads '("message" "gnus")) -(put 'gnus 'custom-loads '("nnmail" "gnus" "gnus-win" "gnus-uu" "gnus-eform" "gnus-dup" "gnus-demon" "gnus-cache" "gnus-async" "gnus-art")) -(put 'gnus-summary-visual 'custom-loads '("gnus-sum")) -(put 'gnus-group-listing 'custom-loads '("gnus-group")) -(put 'gnus-score 'custom-loads '("gnus" "gnus-nocem")) -(put 'gnus-group-select 'custom-loads '("gnus-sum")) -(put 'message-buffers 'custom-loads '("message")) -(put 'gnus-threading 'custom-loads '("gnus-sum")) -(put 'gnus-score-decay 'custom-loads '("gnus-score")) -(put 'help 'custom-loads '("cus-edit")) -(put 'gnus-nocem 'custom-loads '("gnus-nocem")) -(put 'gnus-cite 'custom-loads '("gnus-cite")) -(put 'gnus-demon 'custom-loads '("gnus-demon")) -(put 'gnus-message 'custom-loads '("message")) -(put 'gnus-score-default 'custom-loads '("gnus-sum" "gnus-score")) -(put 'nnmail-duplicate 'custom-loads '("nnmail")) -(put 'message-interface 'custom-loads '("message")) -(put 'nnmail-files 'custom-loads '("nnmail")) -(put 'gnus-edit-form 'custom-loads '("gnus-eform")) -(put 'emacs 'custom-loads '("cus-edit")) -(put 'gnus-summary-mail 'custom-loads '("gnus-sum")) -(put 'gnus-topic 'custom-loads '("gnus-topic")) -(put 'wp 'custom-loads '("cus-edit")) -(put 'gnus-summary-choose 'custom-loads '("gnus-sum")) -(put 'widget-browse 'custom-loads '("wid-browse")) -(put 'external 'custom-loads '("cus-edit")) -(put 'message-headers 'custom-loads '("message")) -(put 'message-forwarding 'custom-loads '("message")) -(put 'message-faces 'custom-loads '("message")) -(put 'environment 'custom-loads '("cus-edit")) -(put 'gnus-article-mime 'custom-loads '("gnus-sum" "gnus-art")) -(put 'gnus-duplicate 'custom-loads '("gnus-dup")) -(put 'nnmail-retrieve 'custom-loads '("nnmail")) -(put 'widgets 'custom-loads '("wid-edit" "wid-browse")) -(put 'earcon 'custom-loads '("earcon")) -(put 'hypermedia 'custom-loads '("wid-edit")) -(put 'gnus-group-levels 'custom-loads '("gnus-group")) -(put 'gnus-summary-format 'custom-loads '("gnus-sum")) -(put 'gnus-files 'custom-loads '("nnmail" "gnus")) -(put 'gnus-windows 'custom-loads '("gnus-win")) -(put 'gnus-article-buttons 'custom-loads '("gnus-art")) -(put 'gnus-summary 'custom-loads '("gnus" "gnus-sum")) -(put 'gnus-article-hiding 'custom-loads '("gnus-sum" "gnus-art")) -(put 'gnus-group 'custom-loads '("gnus" "gnus-topic")) -(put 'gnus-article-various 'custom-loads '("gnus-sum" "gnus-art")) -(put 'gnus-summary-marks 'custom-loads '("gnus-sum")) -(put 'gnus-article-saving 'custom-loads '("gnus-art")) -(put 'nnmail-expire 'custom-loads '("nnmail")) -(put 'message-mail 'custom-loads '("message")) -(put 'faces 'custom-loads '("wid-edit" "cus-edit" "message" "gnus")) -(put 'gnus-summary-various 'custom-loads '("gnus-sum")) -(put 'applications 'custom-loads '("cus-edit")) -(put 'gnus-extract-archive 'custom-loads '("gnus-uu")) -(put 'message 'custom-loads '("message")) -(put 'message-sending 'custom-loads '("message")) -(put 'editing 'custom-loads '("cus-edit")) -(put 'gnus-score-adapt 'custom-loads '("gnus-score")) -(put 'message-insertion 'custom-loads '("message")) -(put 'gnus-extract-post 'custom-loads '("gnus-uu")) -(put 'mail 'custom-loads '("message" "gnus")) -(put 'gnus-summary-sort 'custom-loads '("gnus-sum")) -(put 'customize 'custom-loads '("wid-edit" "custom" "cus-face" "cus-edit")) -(put 'nnmail-split 'custom-loads '("nnmail")) -(put 'gnus-asynchronous 'custom-loads '("gnus-async")) -(put 'gnus-article-highlight 'custom-loads '("gnus-art")) -(put 'gnus-extract 'custom-loads '("gnus-uu")) -(put 'gnus-article 'custom-loads '("gnus-cite" "gnus-art")) -(put 'gnus-group-foreign 'custom-loads '("gnus-group")) -(put 'programming 'custom-loads '("cus-edit")) -(put 'nnmail-prepare 'custom-loads '("nnmail")) -(put 'picons 'custom-loads '("gnus-picon")) -(put 'gnus-article-signature 'custom-loads '("gnus-art")) -(put 'gnus-group-various 'custom-loads '("gnus-group")) - -(provide 'gnus-load) - -;;; gnus-load.el ends here diff --git a/lisp/gnus-logic.el b/lisp/gnus-logic.el deleted file mode 100644 index c276a0b..0000000 --- a/lisp/gnus-logic.el +++ /dev/null @@ -1,229 +0,0 @@ -;;; gnus-logic.el --- advanced scoring code for Gnus -;; Copyright (C) 1996,97,98 Free Software Foundation, Inc. - -;; Author: Lars Magne Ingebrigtsen -;; Keywords: news - -;; This file is part of GNU Emacs. - -;; GNU Emacs is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 2, or (at your option) -;; any later version. - -;; GNU Emacs is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs; see the file COPYING. If not, write to the -;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. - -;;; Commentary: - -;;; Code: - -(eval-when-compile (require 'cl)) - -(require 'gnus) -(require 'gnus-score) -(require 'gnus-util) - -;;; Internal variables. - -(defvar gnus-advanced-headers nil) - -;; To avoid having 8-bit characters in the source file. -(defvar gnus-advanced-not (intern (format "%c" 172))) - -(defconst gnus-advanced-index - ;; Name to index alist. - '(("number" 0 gnus-advanced-integer) - ("subject" 1 gnus-advanced-string) - ("from" 2 gnus-advanced-string) - ("date" 3 gnus-advanced-date) - ("message-id" 4 gnus-advanced-string) - ("references" 5 gnus-advanced-string) - ("chars" 6 gnus-advanced-integer) - ("lines" 7 gnus-advanced-integer) - ("xref" 8 gnus-advanced-string) - ("head" nil gnus-advanced-body) - ("body" nil gnus-advanced-body) - ("all" nil gnus-advanced-body))) - -(eval-and-compile - (autoload 'parse-time-string "parse-time")) - -(defun gnus-score-advanced (rule &optional trace) - "Apply advanced scoring RULE to all the articles in the current group." - (let ((headers gnus-newsgroup-headers) - gnus-advanced-headers score) - (while (setq gnus-advanced-headers (pop headers)) - (when (gnus-advanced-score-rule (car rule)) - ;; This rule was successful, so we add the score to - ;; this article. - (if (setq score (assq (mail-header-number gnus-advanced-headers) - gnus-newsgroup-scored)) - (setcdr score - (+ (cdr score) - (or (nth 1 rule) - gnus-score-interactive-default-score))) - (push (cons (mail-header-number gnus-advanced-headers) - (or (nth 1 rule) - gnus-score-interactive-default-score)) - gnus-newsgroup-scored) - (when trace - (push (cons "A file" rule) - gnus-score-trace))))))) - -(defun gnus-advanced-score-rule (rule) - "Apply RULE to `gnus-advanced-headers'." - (let ((type (car rule))) - (cond - ;; "And" rule. - ((or (eq type '&) (eq type 'and)) - (pop rule) - (if (not rule) - t ; Empty rule is true. - (while (and rule - (gnus-advanced-score-rule (car rule))) - (pop rule)) - ;; If all the rules were true, then `rule' should be nil. - (not rule))) - ;; "Or" rule. - ((or (eq type '|) (eq type 'or)) - (pop rule) - (if (not rule) - nil - (while (and rule - (not (gnus-advanced-score-rule (car rule)))) - (pop rule)) - ;; If one of the rules returned true, then `rule' should be non-nil. - rule)) - ;; "Not" rule. - ((or (eq type '!) (eq type 'not) (eq type gnus-advanced-not)) - (not (gnus-advanced-score-rule (nth 1 rule)))) - ;; This is a `1-'-type redirection rule. - ((and (symbolp type) - (string-match "^[0-9]+-$\\|^\\^+$" (symbol-name type))) - (let ((gnus-advanced-headers - (gnus-parent-headers - gnus-advanced-headers - (if (string-match "^\\([0-9]+\\)-$" (symbol-name type)) - ;; 1- type redirection. - (string-to-number - (substring (symbol-name type) - (match-beginning 0) (match-end 0))) - ;; ^^^ type redirection. - (length (symbol-name type)))))) - (when gnus-advanced-headers - (gnus-advanced-score-rule (nth 1 rule))))) - ;; Plain scoring rule. - ((stringp type) - (gnus-advanced-score-article rule)) - ;; Bug-out time! - (t - (error "Unknown advanced score type: %s" rule))))) - -(defun gnus-advanced-score-article (rule) - ;; `rule' is a semi-normal score rule, so we find out - ;; what function that's supposed to do the actual - ;; processing. - (let* ((header (car rule)) - (func (assoc (downcase header) gnus-advanced-index))) - (if (not func) - (error "No such header: %s" rule) - ;; Call the score function. - (funcall (caddr func) (or (cadr func) header) - (cadr rule) (caddr rule))))) - -(defun gnus-advanced-string (index match type) - "See whether string MATCH of TYPE matches `gnus-advanced-headers' in INDEX." - (let* ((type (or type 's)) - (case-fold-search (not (eq (downcase (symbol-name type)) - (symbol-name type)))) - (header (aref gnus-advanced-headers index))) - (cond - ((memq type '(r R regexp Regexp)) - (string-match match header)) - ((memq type '(s S string String)) - (string-match (regexp-quote match) header)) - ((memq type '(e E exact Exact)) - (string= match header)) - ((memq type '(f F fuzzy Fuzzy)) - (string-match (regexp-quote (gnus-simplify-subject-fuzzy match)) - header)) - (t - (error "No such string match type: %s" type))))) - -(defun gnus-advanced-integer (index match type) - (if (not (memq type '(< > <= >= =))) - (error "No such integer score type: %s" type) - (funcall type match (or (aref gnus-advanced-headers index) 0)))) - -(defun gnus-advanced-date (index match type) - (let ((date (apply 'encode-time (parse-time-string - (aref gnus-advanced-headers index)))) - (match (apply 'encode-time (parse-time-string match)))) - (cond - ((eq type 'at) - (equal date match)) - ((eq type 'before) - (gnus-time-less match date)) - ((eq type 'after) - (gnus-time-less date match)) - (t - (error "No such date score type: %s" type))))) - -(defun gnus-advanced-body (header match type) - (when (string= header "all") - (setq header "article")) - (save-excursion - (set-buffer nntp-server-buffer) - (let* ((request-func (cond ((string= "head" header) - 'gnus-request-head) - ((string= "body" header) - 'gnus-request-body) - (t 'gnus-request-article))) - ofunc article) - ;; Not all backends support partial fetching. In that case, - ;; we just fetch the entire article. - (unless (gnus-check-backend-function - (intern (concat "request-" header)) - gnus-newsgroup-name) - (setq ofunc request-func) - (setq request-func 'gnus-request-article)) - (setq article (mail-header-number gnus-advanced-headers)) - (gnus-message 7 "Scoring article %s..." article) - (when (funcall request-func article gnus-newsgroup-name) - (goto-char (point-min)) - ;; If just parts of the article is to be searched and the - ;; backend didn't support partial fetching, we just narrow - ;; to the relevant parts. - (when ofunc - (if (eq ofunc 'gnus-request-head) - (narrow-to-region - (point) - (or (search-forward "\n\n" nil t) (point-max))) - (narrow-to-region - (or (search-forward "\n\n" nil t) (point)) - (point-max)))) - (let* ((case-fold-search (not (eq (downcase (symbol-name type)) - (symbol-name type)))) - (search-func - (cond ((memq type '(r R regexp Regexp)) - 're-search-forward) - ((memq type '(s S string String)) - 'search-forward) - (t - (error "Illegal match type: %s" type))))) - (goto-char (point-min)) - (prog1 - (funcall search-func match nil t) - (widen))))))) - -(provide 'gnus-logic) - -;;; gnus-logic.el ends here. diff --git a/lisp/gnus-mh.el b/lisp/gnus-mh.el deleted file mode 100644 index fa01f5a..0000000 --- a/lisp/gnus-mh.el +++ /dev/null @@ -1,105 +0,0 @@ -;;; gnus-mh.el --- mh-e interface for Gnus -;; Copyright (C) 1994,95,96,97,98 Free Software Foundation, Inc. - -;; Author: Masanobu UMEDA -;; Lars Magne Ingebrigtsen -;; Keywords: news - -;; This file is part of GNU Emacs. - -;; GNU Emacs is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 2, or (at your option) -;; any later version. - -;; GNU Emacs is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs; see the file COPYING. If not, write to the -;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. - -;;; Commentary: - -;;; Send mail using mh-e. - -;; The following mh-e interface is all cooperative works of -;; tanaka@flab.fujitsu.CO.JP (TANAKA Hiroshi), kawabe@sra.CO.JP -;; (Yoshikatsu Kawabe), and shingu@casund.cpr.canon.co.jp (Toshiaki -;; SHINGU). - -;;; Code: - -(require 'gnus) -(require 'mh-e) -(require 'mh-comp) -(require 'gnus-msg) -(require 'gnus-sum) - -(defun gnus-summary-save-article-folder (&optional arg) - "Append the current article to an mh folder. -If N is a positive number, save the N next articles. -If N is a negative number, save the N previous articles. -If N is nil and any articles have been marked with the process mark, -save those articles instead." - (interactive "P") - (let ((gnus-default-article-saver 'gnus-summary-save-in-folder)) - (gnus-summary-save-article arg))) - -(defun gnus-summary-save-in-folder (&optional folder) - "Save this article to MH folder (using `rcvstore' in MH library). -Optional argument FOLDER specifies folder name." - ;; Thanks to yuki@flab.Fujitsu.JUNET and ohm@kaba.junet. - (mh-find-path) - (let ((folder - (cond ((and (eq folder 'default) - gnus-newsgroup-last-folder) - gnus-newsgroup-last-folder) - (folder folder) - (t (mh-prompt-for-folder - "Save article in" - (funcall gnus-folder-save-name gnus-newsgroup-name - gnus-current-headers gnus-newsgroup-last-folder) - t)))) - (errbuf (gnus-get-buffer-create " *Gnus rcvstore*")) - ;; Find the rcvstore program. - (exec-path (if mh-lib (cons mh-lib exec-path) exec-path))) - (gnus-eval-in-buffer-window gnus-original-article-buffer - (save-restriction - (widen) - (unwind-protect - (call-process-region - (point-min) (point-max) "rcvstore" nil errbuf nil folder) - (set-buffer errbuf) - (if (zerop (buffer-size)) - (message "Article saved in folder: %s" folder) - (message "%s" (buffer-string))) - (kill-buffer errbuf)))) - (setq gnus-newsgroup-last-folder folder))) - -(defun gnus-Folder-save-name (newsgroup headers &optional last-folder) - "Generate folder name from NEWSGROUP, HEADERS, and optional LAST-FOLDER. -If variable `gnus-use-long-file-name' is nil, it is +News.group. -Otherwise, it is like +news/group." - (or last-folder - (concat "+" - (if gnus-use-long-file-name - (gnus-capitalize-newsgroup newsgroup) - (gnus-newsgroup-directory-form newsgroup))))) - -(defun gnus-folder-save-name (newsgroup headers &optional last-folder) - "Generate folder name from NEWSGROUP, HEADERS, and optional LAST-FOLDER. -If variable `gnus-use-long-file-name' is nil, it is +news.group. -Otherwise, it is like +news/group." - (or last-folder - (concat "+" - (if gnus-use-long-file-name - newsgroup - (gnus-newsgroup-directory-form newsgroup))))) - -(provide 'gnus-mh) - -;;; gnus-mh.el ends here diff --git a/lisp/gnus-move.el b/lisp/gnus-move.el deleted file mode 100644 index f676783..0000000 --- a/lisp/gnus-move.el +++ /dev/null @@ -1,181 +0,0 @@ -;;; gnus-move.el --- commands for moving Gnus from one server to another -;; Copyright (C) 1996,97,98 Free Software Foundation, Inc. - -;; Author: Lars Magne Ingebrigtsen -;; Keywords: news - -;; This file is part of GNU Emacs. - -;; GNU Emacs is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 2, or (at your option) -;; any later version. - -;; GNU Emacs is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs; see the file COPYING. If not, write to the -;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. - -;;; Commentary: - -;;; Code: - -(eval-when-compile (require 'cl)) - -(require 'gnus) -(require 'gnus-start) -(require 'gnus-int) -(require 'gnus-range) - -;;; -;;; Moving by comparing Message-ID's. -;;; - -;;;###autoload -(defun gnus-change-server (from-server to-server) - "Move from FROM-SERVER to TO-SERVER. -Update the .newsrc.eld file to reflect the change of nntp server." - (interactive - (list gnus-select-method (gnus-read-method "Move to method: "))) - - ;; First start Gnus. - (let ((gnus-activate-level 0) - (nnmail-spool-file nil)) - (gnus)) - - (save-excursion - ;; Go through all groups and translate. - (let ((newsrc gnus-newsrc-alist) - (nntp-nov-gap nil) - info) - (while (setq info (pop newsrc)) - (when (gnus-group-native-p (gnus-info-group info)) - (gnus-move-group-to-server info from-server to-server)))))) - -(defun gnus-move-group-to-server (info from-server to-server) - "Move group INFO from FROM-SERVER to TO-SERVER." - (let ((group (gnus-info-group info)) - to-active hashtb type mark marks - to-article to-reads to-marks article - act-articles) - (gnus-message 7 "Translating %s..." group) - (when (gnus-request-group group nil to-server) - (setq to-active (gnus-parse-active) - hashtb (gnus-make-hashtable 1024) - act-articles (gnus-uncompress-range to-active)) - ;; Fetch the headers from the `to-server'. - (when (and to-active - act-articles - (setq type (gnus-retrieve-headers - act-articles - group to-server))) - ;; Convert HEAD headers. I don't care. - (when (eq type 'headers) - (nnvirtual-convert-headers)) - ;; Create a mapping from Message-ID to article number. - (set-buffer nntp-server-buffer) - (goto-char (point-min)) - (while (looking-at - "^[0-9]+\t[^\t]*\t[^\t]*\t[^\t]*\t\\([^\t]*\\)\t") - (gnus-sethash - (buffer-substring (match-beginning 1) (match-end 1)) - (read (current-buffer)) - hashtb) - (forward-line 1)) - ;; Then we read the headers from the `from-server'. - (when (and (gnus-request-group group nil from-server) - (gnus-active group) - (setq type (gnus-retrieve-headers - (gnus-uncompress-range - (gnus-active group)) - group from-server))) - ;; Make it easier to map marks. - (let ((mark-lists (gnus-info-marks info)) - ms type m) - (while mark-lists - (setq type (caar mark-lists) - ms (gnus-uncompress-range (cdr (pop mark-lists)))) - (while ms - (if (setq m (assq (car ms) marks)) - (setcdr m (cons type (cdr m))) - (push (list (car ms) type) marks)) - (pop ms)))) - ;; Convert. - (when (eq type 'headers) - (nnvirtual-convert-headers)) - ;; Go through the headers and map away. - (set-buffer nntp-server-buffer) - (goto-char (point-min)) - (while (looking-at - "^[0-9]+\t[^\t]*\t[^\t]*\t[^\t]*\t\\([^\t]*\\)\t") - (when (setq to-article - (gnus-gethash - (buffer-substring (match-beginning 1) (match-end 1)) - hashtb)) - ;; Add this article to the list of read articles. - (push to-article to-reads) - ;; See if there are any marks and then add them. - (when (setq mark (assq (read (current-buffer)) marks)) - (setq marks (delq mark marks)) - (setcar mark to-article) - (push mark to-marks)) - (forward-line 1))) - ;; Now we know what the read articles are and what the - ;; article marks are. We transform the information - ;; into the Gnus info format. - (setq to-reads - (gnus-range-add - (gnus-compress-sequence - (and (setq to-reads (delq nil to-reads)) - (sort to-reads '<)) - t) - (cons 1 (1- (car to-active))))) - (gnus-info-set-read info to-reads) - ;; Do the marks. I'm sure y'all understand what's - ;; going on down below, so I won't bother with any - ;; further comments. - (let ((mlists gnus-article-mark-lists) - lists ms a) - (while mlists - (push (list (cdr (pop mlists))) lists)) - (while (setq ms (pop marks)) - (setq article (pop ms)) - (while ms - (setcdr (setq a (assq (pop ms) lists)) - (cons article (cdr a))))) - (setq a lists) - (while a - (setcdr (car a) (gnus-compress-sequence - (and (cdar a) (sort (cdar a) '<)))) - (pop a)) - (gnus-info-set-marks info lists t))))) - (gnus-message 7 "Translating %s...done" group))) - -(defun gnus-group-move-group-to-server (info from-server to-server) - "Move the group on the current line from FROM-SERVER to TO-SERVER." - (interactive - (let ((info (gnus-get-info (gnus-group-group-name)))) - (list info (gnus-find-method-for-group (gnus-info-group info)) - (gnus-read-method (format "Move group %s to method: " - (gnus-info-group info)))))) - (save-excursion - (gnus-move-group-to-server info from-server to-server) - ;; We have to update the group info to point use the right server. - (gnus-info-set-method info to-server t) - ;; We also have to change the name of the group and stuff. - (let* ((group (gnus-info-group info)) - (new-name (gnus-group-prefixed-name - (gnus-group-real-name group) to-server))) - (gnus-info-set-group info new-name) - (gnus-sethash new-name (gnus-gethash group gnus-newsrc-hashtb) - gnus-newsrc-hashtb) - (gnus-sethash group nil gnus-newsrc-hashtb)))) - -(provide 'gnus-move) - -;;; gnus-move.el ends here diff --git a/lisp/gnus-msg.el b/lisp/gnus-msg.el deleted file mode 100644 index b1e5714..0000000 --- a/lisp/gnus-msg.el +++ /dev/null @@ -1,1150 +0,0 @@ -;;; gnus-msg.el --- mail and post interface for Semi-gnus -;; Copyright (C) 1995,96,97,98 Free Software Foundation, Inc. - -;; Author: Masanobu UMEDA -;; Lars Magne Ingebrigtsen -;; MORIOKA Tomohiko -;; Shuhei KOBAYASHI -;; Keywords: mail, news, MIME - -;; This file is part of GNU Emacs. - -;; GNU Emacs is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 2, or (at your option) -;; any later version. - -;; GNU Emacs is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs; see the file COPYING. If not, write to the -;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. - -;;; Commentary: - -;;; Code: - -(eval-when-compile (require 'cl)) - -(require 'gnus) -(require 'gnus-ems) -(require 'message) -(require 'gnus-art) - -(defcustom gnus-post-method nil - "*Preferred method for posting USENET news. - -If this variable is `current', Gnus will use the \"current\" select -method when posting. If it is nil (which is the default), Gnus will -use the native posting method of the server. - -This method will not be used in mail groups and the like, only in -\"real\" newsgroups. - -If not nil nor `native', the value must be a valid method as discussed -in the documentation of `gnus-select-method'. It can also be a list of -methods. If that is the case, the user will be queried for what select -method to use when posting." - :group 'gnus-group-foreign - :type `(choice (const nil) - (const current) - (const native) - (sexp :tag "Methods" ,gnus-select-method))) - -(defvar gnus-outgoing-message-group nil - "*All outgoing messages will be put in this group. -If you want to store all your outgoing mail and articles in the group -\"nnml:archive\", you set this variable to that value. This variable -can also be a list of group names. - -If you want to have greater control over what group to put each -message in, you can set this variable to a function that checks the -current newsgroup name and then returns a suitable group name (or list -of names).") - -(defvar gnus-mailing-list-groups nil - "*Regexp matching groups that are really mailing lists. -This is useful when you're reading a mailing list that has been -gatewayed to a newsgroup, and you want to followup to an article in -the group.") - -(defvar gnus-add-to-list nil - "*If non-nil, add a `to-list' parameter automatically.") - -(defvar gnus-crosspost-complaint - "Hi, - -You posted the article below with the following Newsgroups header: - -Newsgroups: %s - -The %s group, at least, was an inappropriate recipient -of this message. Please trim your Newsgroups header to exclude this -group before posting in the future. - -Thank you. - -" - "Format string to be inserted when complaining about crossposts. -The first %s will be replaced by the Newsgroups header; -the second with the current group name.") - -(defvar gnus-message-setup-hook nil - "Hook run after setting up a message buffer.") - -(defvar gnus-bug-create-help-buffer t - "*Should we create the *Gnus Help Bug* buffer?") - -(defvar gnus-posting-styles nil - "*Alist of styles to use when posting.") - -(defvar gnus-posting-style-alist - '((organization . message-user-organization) - (signature . message-signature) - (signature-file . message-signature-file) - (address . user-mail-address) - (name . user-full-name)) - "*Mapping from style parameters to variables.") - -;;; Internal variables. - -(defvar gnus-inhibit-posting-styles nil - "Inhibit the use of posting styles.") - -(defvar gnus-message-buffer "*Mail Gnus*") -(defvar gnus-article-copy nil) -(defvar gnus-last-posting-server nil) -(defvar gnus-message-group-art nil) - -(defconst gnus-bug-message - (format "Sending a bug report to the Gnus Towers. -======================================== - -This gnus is the %s%s. -If you think the bug is a Semi-gnus bug, send a bug report to Semi-gnus -Developers. (the addresses below are mailing list addresses) - -======================================== - -The buffer below is a mail buffer. When you press `C-c C-c', it will -be sent to the Gnus Bug Exterminators. - -At the bottom of the buffer you'll see lots of variable settings. -Please do not delete those. They will tell the Bug People what your -environment is, so that it will be easier to locate the bugs. - -If you have found a bug that makes Emacs go \"beep\", set -debug-on-error to t (`M-x set-variable RET debug-on-error RET t RET') -and include the backtrace in your bug report. - -Please describe the bug in annoying, painstaking detail. - -Thank you for your help in stamping out bugs. -" - gnus-product-name - (if (string= gnus-product-name "Semi-gnus") - "" - ", a modified version of Semi-gnus"))) - -(eval-and-compile - (autoload 'gnus-uu-post-news "gnus-uu" nil t) - (autoload 'news-setup "rnewspost") - (autoload 'news-reply-mode "rnewspost") - (autoload 'rmail-dont-reply-to "mail-utils") - (autoload 'rmail-output "rmailout")) - - -;;; -;;; Gnus Posting Functions -;;; - -(gnus-define-keys (gnus-summary-send-map "S" gnus-summary-mode-map) - "p" gnus-summary-post-news - "f" gnus-summary-followup - "F" gnus-summary-followup-with-original - "c" gnus-summary-cancel-article - "s" gnus-summary-supersede-article - "r" gnus-summary-reply - "R" gnus-summary-reply-with-original - "w" gnus-summary-wide-reply - "W" gnus-summary-wide-reply-with-original - "n" gnus-summary-followup-to-mail - "N" gnus-summary-followup-to-mail-with-original - "m" gnus-summary-mail-other-window - "u" gnus-uu-post-news - "\M-c" gnus-summary-mail-crosspost-complaint - "om" gnus-summary-mail-forward - "op" gnus-summary-post-forward - "Om" gnus-summary-mail-digest - "Op" gnus-summary-post-digest) - -(gnus-define-keys (gnus-send-bounce-map "D" gnus-summary-send-map) - "b" gnus-summary-resend-bounced-mail - ;; "c" gnus-summary-send-draft - "r" gnus-summary-resend-message) - -;;; Internal functions. - -(defvar gnus-article-reply nil) -(defmacro gnus-setup-message (config &rest forms) - (let ((winconf (make-symbol "gnus-setup-message-winconf")) - (buffer (make-symbol "gnus-setup-message-buffer")) - (article (make-symbol "gnus-setup-message-article")) - (group (make-symbol "gnus-setup-message-group"))) - `(let ((,winconf (current-window-configuration)) - (,buffer (buffer-name (current-buffer))) - (,article (and gnus-article-reply (gnus-summary-article-number))) - (,group gnus-newsgroup-name) - (message-header-setup-hook - (copy-sequence message-header-setup-hook)) - (message-mode-hook (copy-sequence message-mode-hook))) - (add-hook 'message-header-setup-hook 'gnus-inews-insert-gcc) - (add-hook 'message-header-setup-hook 'gnus-inews-insert-archive-gcc) - (add-hook 'message-mode-hook 'gnus-configure-posting-styles) - (unwind-protect - (progn - ,@forms) - (gnus-inews-add-send-actions ,winconf ,buffer ,article) - (setq gnus-message-buffer (current-buffer)) - (set (make-local-variable 'gnus-message-group-art) - (cons ,group ,article)) - (make-local-variable 'gnus-newsgroup-name) - (gnus-run-hooks 'gnus-message-setup-hook)) - (gnus-add-buffer) - (gnus-configure-windows ,config t) - (set-buffer-modified-p nil)))) - -(defun gnus-inews-add-send-actions (winconf buffer article) - (make-local-hook 'message-sent-hook) - (add-hook 'message-sent-hook 'gnus-inews-do-gcc nil t) - (setq message-post-method - `(lambda (arg) - (gnus-post-method arg ,gnus-newsgroup-name))) - (setq message-user-agent (gnus-extended-version)) - (message-add-action - `(set-window-configuration ,winconf) 'exit 'postpone 'kill) - (message-add-action - `(when (gnus-buffer-exists-p ,buffer) - (save-excursion - (set-buffer ,buffer) - ,(when article - `(gnus-summary-mark-article-as-replied ,article)))) - 'send)) - -(put 'gnus-setup-message 'lisp-indent-function 1) -(put 'gnus-setup-message 'edebug-form-spec '(form body)) - -;;; Post news commands of Gnus group mode and summary mode - -(defun gnus-group-mail () - "Start composing a mail." - (interactive) - (gnus-setup-message 'message - (message-mail))) - -(defun gnus-group-post-news (&optional arg) - "Start composing a news message. -If ARG, post to the group under point. -If ARG is 1, prompt for a group name." - (interactive "P") - ;; Bind this variable here to make message mode hooks work ok. - (let ((gnus-newsgroup-name - (if arg - (if (= 1 (prefix-numeric-value arg)) - (completing-read "Newsgroup: " gnus-active-hashtb nil - (gnus-read-active-file-p)) - (gnus-group-group-name)) - ""))) - (gnus-post-news 'post gnus-newsgroup-name))) - -(defun gnus-summary-post-news () - "Start composing a news message." - (interactive) - (gnus-post-news 'post gnus-newsgroup-name)) - -(defun gnus-summary-followup (yank &optional force-news) - "Compose a followup to an article. -If prefix argument YANK is non-nil, original article is yanked automatically." - (interactive - (list (and current-prefix-arg - (gnus-summary-work-articles 1)))) - (when yank - (gnus-summary-goto-subject (car yank))) - (save-window-excursion - (gnus-summary-select-article)) - (let ((headers (gnus-summary-article-header (gnus-summary-article-number))) - (gnus-newsgroup-name gnus-newsgroup-name)) - ;; Send a followup. - (gnus-post-news nil gnus-newsgroup-name - headers gnus-article-buffer - yank nil force-news))) - -(defun gnus-summary-followup-with-original (n &optional force-news) - "Compose a followup to an article and include the original article." - (interactive "P") - (gnus-summary-followup (gnus-summary-work-articles n) force-news)) - -(defun gnus-summary-followup-to-mail (&optional arg) - "Followup to the current mail message via news." - (interactive - (list (and current-prefix-arg - (gnus-summary-work-articles 1)))) - (gnus-summary-followup arg t)) - -(defun gnus-summary-followup-to-mail-with-original (&optional arg) - "Followup to the current mail message via news." - (interactive "P") - (gnus-summary-followup (gnus-summary-work-articles arg) t)) - -(defun gnus-inews-yank-articles (articles) - (let (beg article) - (message-goto-body) - (while (setq article (pop articles)) - (save-window-excursion - (set-buffer gnus-summary-buffer) - (gnus-summary-select-article nil nil nil article) - (gnus-summary-remove-process-mark article)) - (gnus-copy-article-buffer) - (let ((message-reply-buffer gnus-article-copy) - (message-reply-headers gnus-current-headers)) - (message-yank-original) - (setq beg (or beg (mark t)))) - (when articles - (insert "\n"))) - (push-mark) - (goto-char beg))) - -(defun gnus-summary-cancel-article (&optional n symp) - "Cancel an article you posted. -Uses the process-prefix convention. If given the symbolic -prefix `a', cancel using the standard posting method; if not -post using the current select method." - (interactive (gnus-interactive "P\ny")) - (let ((articles (gnus-summary-work-articles n)) - (message-post-method - `(lambda (arg) - (gnus-post-method (not (eq symp 'a)) ,gnus-newsgroup-name))) - article) - (while (setq article (pop articles)) - (when (gnus-summary-select-article t nil nil article) - (when (gnus-eval-in-buffer-window gnus-article-buffer - (save-excursion - (set-buffer gnus-original-article-buffer) - (message-cancel-news))) - (gnus-summary-mark-as-read article gnus-canceled-mark) - (gnus-cache-remove-article 1)) - (gnus-article-hide-headers-if-wanted)) - (gnus-summary-remove-process-mark article)))) - -(defun gnus-summary-supersede-article () - "Compose an article that will supersede a previous article. -This is done simply by taking the old article and adding a Supersedes -header line with the old Message-ID." - (interactive) - (let ((article (gnus-summary-article-number))) - (gnus-setup-message 'reply-yank - (gnus-summary-select-article t) - (set-buffer gnus-original-article-buffer) - (message-supersede) - (push - `((lambda () - (when (gnus-buffer-exists-p ,gnus-summary-buffer) - (save-excursion - (set-buffer ,gnus-summary-buffer) - (gnus-cache-possibly-remove-article ,article nil nil nil t) - (gnus-summary-mark-as-read ,article gnus-canceled-mark))))) - message-send-actions)))) - - - -(defun gnus-copy-article-buffer (&optional article-buffer) - ;; make a copy of the article buffer with all text properties removed - ;; this copy is in the buffer gnus-article-copy. - ;; if ARTICLE-BUFFER is nil, gnus-article-buffer is used - ;; this buffer should be passed to all mail/news reply/post routines. - (setq gnus-article-copy (gnus-get-buffer-create " *gnus article copy*")) - (buffer-disable-undo gnus-article-copy) - (let ((article-buffer (or article-buffer gnus-article-buffer)) - end beg) - (if (not (and (get-buffer article-buffer) - (gnus-buffer-exists-p article-buffer))) - (error "Can't find any article buffer") - (save-excursion - (set-buffer article-buffer) - (save-restriction - ;; Copy over the (displayed) article buffer, delete - ;; hidden text and remove text properties. - (widen) - (copy-to-buffer gnus-article-copy (point-min) (point-max)) - (set-buffer gnus-article-copy) - (gnus-article-delete-text-of-type 'annotation) - (gnus-remove-text-with-property 'gnus-prev) - (gnus-remove-text-with-property 'gnus-next) - (insert - (prog1 - (format "%s" (buffer-string)) - (erase-buffer))) - ;; Find the original headers. - (set-buffer gnus-original-article-buffer) - (goto-char (point-min)) - (while (looking-at message-unix-mail-delimiter) - (forward-line 1)) - (setq beg (point)) - (setq end (or (search-forward "\n\n" nil t) (point))) - ;; Delete the headers from the displayed articles. - (set-buffer gnus-article-copy) - (delete-region (goto-char (point-min)) - (or (search-forward "\n\n" nil t) (point))) - ;; Insert the original article headers. - (insert-buffer-substring gnus-original-article-buffer beg end) - (gnus-article-decode-rfc1522))) - gnus-article-copy))) - -(defun gnus-post-news (post &optional group header article-buffer yank subject - force-news) - (when article-buffer - (gnus-copy-article-buffer)) - (let ((gnus-article-reply article-buffer) - (add-to-list gnus-add-to-list)) - (gnus-setup-message (cond (yank 'reply-yank) - (article-buffer 'reply) - (t 'message)) - (let* ((group (or group gnus-newsgroup-name)) - (pgroup group) - to-address to-group mailing-list to-list - newsgroup-p) - (when group - (setq to-address (gnus-group-find-parameter group 'to-address) - to-group (gnus-group-find-parameter group 'to-group) - to-list (gnus-group-find-parameter group 'to-list) - newsgroup-p (gnus-group-find-parameter group 'newsgroup) - mailing-list (when gnus-mailing-list-groups - (string-match gnus-mailing-list-groups group)) - group (gnus-group-real-name group))) - (if (or (and to-group - (gnus-news-group-p to-group)) - newsgroup-p - force-news - (and (gnus-news-group-p - (or pgroup gnus-newsgroup-name) - (if header (mail-header-number header) - gnus-current-article)) - (not mailing-list) - (not to-list) - (not to-address))) - ;; This is news. - (if post - (message-news (or to-group group)) - (set-buffer gnus-article-copy) - (gnus-msg-treat-broken-reply-to) - (message-followup (if (or newsgroup-p force-news) nil to-group))) - ;; The is mail. - (if post - (progn - (message-mail (or to-address to-list)) - ;; Arrange for mail groups that have no `to-address' to - ;; get that when the user sends off the mail. - (when (and (not to-list) - (not to-address) - add-to-list) - (push (list 'gnus-inews-add-to-address pgroup) - message-send-actions))) - (set-buffer gnus-article-copy) - (gnus-msg-treat-broken-reply-to) - (message-wide-reply to-address))) - (when yank - (gnus-inews-yank-articles yank)))))) - -(defun gnus-msg-treat-broken-reply-to () - "Remove the Reply-to header iff broken-reply-to." - (when (gnus-group-find-parameter - gnus-newsgroup-name 'broken-reply-to) - (save-restriction - (message-narrow-to-head) - (message-remove-header "reply-to")))) - -(defun gnus-post-method (arg group &optional silent) - "Return the posting method based on GROUP and ARG. -If SILENT, don't prompt the user." - (let ((group-method (gnus-find-method-for-group group))) - (cond - ;; If the group-method is nil (which shouldn't happen) we use - ;; the default method. - ((null group-method) - (or (and (null (eq gnus-post-method 'active)) gnus-post-method) - gnus-select-method message-post-method)) - ;; We want the inverse of the default - ((and arg (not (eq arg 0))) - (if (eq gnus-post-method 'active) - gnus-select-method - group-method)) - ;; We query the user for a post method. - ((or arg - (and gnus-post-method - (not (eq gnus-post-method 'current)) - (listp (car gnus-post-method)))) - (let* ((methods - ;; Collect all methods we know about. - (append - (when (and gnus-post-method - (not (eq gnus-post-method 'current))) - (if (listp (car gnus-post-method)) - gnus-post-method - (list gnus-post-method))) - gnus-secondary-select-methods - (mapcar 'cdr gnus-server-alist) - (list gnus-select-method) - (list group-method))) - method-alist post-methods method) - ;; Weed out all mail methods. - (while methods - (setq method (gnus-server-get-method "" (pop methods))) - (when (or (gnus-method-option-p method 'post) - (gnus-method-option-p method 'post-mail)) - (push method post-methods))) - ;; Create a name-method alist. - (setq method-alist - (mapcar - (lambda (m) - (list (concat (cadr m) " (" (symbol-name (car m)) ")") m)) - post-methods)) - ;; Query the user. - (cadr - (assoc - (setq gnus-last-posting-server - (if (and silent - gnus-last-posting-server) - ;; Just use the last value. - gnus-last-posting-server - (completing-read - "Posting method: " method-alist nil t - (cons (or gnus-last-posting-server "") 0)))) - method-alist)))) - ;; Override normal method. - ((and (eq gnus-post-method 'current) - (not (eq (car group-method) 'nndraft)) - (not arg)) - group-method) - ((and gnus-post-method - (not (eq gnus-post-method 'current))) - gnus-post-method) - ;; Use the normal select method. - (t gnus-select-method)))) - - - -;; Dummy to avoid byte-compile warning. -(defvar nnspool-rejected-article-hook) -(defvar xemacs-codename) - -;;; Since the User-Agent is ``vanity'' headers. -(defun gnus-extended-version () - "Stringified gnus version." - (interactive) - (concat gnus-product-name "/" gnus-version-number)) - - -;;; -;;; Gnus Mail Functions -;;; - -;;; Mail reply commands of Gnus summary mode - -(defun gnus-summary-reply (&optional yank wide) - "Start composing a reply mail to the current message. -If prefix argument YANK is non-nil, the original article is yanked -automatically." - (interactive - (list (and current-prefix-arg - (gnus-summary-work-articles 1)))) - ;; Stripping headers should be specified with mail-yank-ignored-headers. - (when yank - (gnus-summary-goto-subject (car yank))) - (let ((gnus-article-reply t)) - (gnus-setup-message (if yank 'reply-yank 'reply) - (gnus-summary-select-article) - (set-buffer (gnus-copy-article-buffer)) - (gnus-msg-treat-broken-reply-to) - (message-reply nil wide) - (when yank - (gnus-inews-yank-articles yank))))) - -(defun gnus-summary-reply-with-original (n &optional wide) - "Start composing a reply mail to the current message. -The original article will be yanked." - (interactive "P") - (gnus-summary-reply (gnus-summary-work-articles n) wide)) - -(defun gnus-summary-wide-reply (&optional yank) - "Start composing a wide reply mail to the current message. -If prefix argument YANK is non-nil, the original article is yanked -automatically." - (interactive - (list (and current-prefix-arg - (gnus-summary-work-articles 1)))) - (gnus-summary-reply yank t)) - -(defun gnus-summary-wide-reply-with-original (n) - "Start composing a wide reply mail to the current message. -The original article will be yanked." - (interactive "P") - (gnus-summary-reply-with-original n t)) - -(defun gnus-summary-mail-forward (&optional full-headers post) - "Forward the current message to another user. -If FULL-HEADERS (the prefix), include full headers when forwarding." - (interactive "P") - (gnus-setup-message 'forward - (gnus-summary-select-article) - (let ((charset default-mime-charset)) - (set-buffer gnus-original-article-buffer) - (make-local-variable 'default-mime-charset) - (setq default-mime-charset charset) - ) - (let ((message-included-forward-headers - (if full-headers "" message-included-forward-headers))) - (message-forward post)))) - -(defun gnus-summary-post-forward (&optional full-headers) - "Forward the current article to a newsgroup. -If FULL-HEADERS (the prefix), include full headers when forwarding." - (interactive "P") - (gnus-summary-mail-forward full-headers t)) - -;;; XXX: generate Subject and ``Topics''? -(defun gnus-summary-mail-digest (&optional n post) - "Digests and forwards all articles in this series." - (interactive "P") - (let ((subject "Digested Articles") - (articles (gnus-summary-work-articles n)) - article) - (gnus-setup-message 'forward - (gnus-summary-select-article) - (if post (message-news nil subject) (message-mail nil subject)) - (message-goto-body) - (while (setq article (pop articles)) - (save-window-excursion - (set-buffer gnus-summary-buffer) - (gnus-summary-select-article nil nil nil article) - (gnus-summary-remove-process-mark article)) - (insert (mime-make-tag "message" "rfc822") "\n") - (insert-buffer-substring gnus-original-article-buffer)) - (push-mark) - (message-goto-body) - (mime-edit-enclose-digest-region (point)(mark t))))) - -(defun gnus-summary-post-digest (&optional n) - "Digest and forwards all articles in this series to a newsgroup." - (interactive "P") - (gnus-summary-mail-digest n t)) - -(defun gnus-summary-resend-message (address n) - "Resend the current article to ADDRESS." - (interactive "sResend message(s) to: \nP") - (let ((articles (gnus-summary-work-articles n)) - article) - (while (setq article (pop articles)) - (gnus-summary-select-article nil nil nil article) - (save-excursion - (set-buffer gnus-original-article-buffer) - (message-resend address))))) - -(defvar gnus-nastygram-message - "The following article was inappropriately posted to %s.\n\n" - "Format string to insert in nastygrams. -The current group name will be inserted at \"%s\".") - -(defun gnus-summary-mail-nastygram (n) - "Send a nastygram to the author of the current article." - (interactive "P") - (when (or gnus-expert-user - (gnus-y-or-n-p - "Really send a nastygram to the author of the current article? ")) - (let ((group gnus-newsgroup-name)) - (gnus-summary-reply-with-original n) - (set-buffer gnus-message-buffer) - (message-goto-body) - (insert (format gnus-nastygram-message group)) - (message-send-and-exit)))) - -(defun gnus-summary-mail-crosspost-complaint (n) - "Send a complaint about crossposting to the current article(s)." - (interactive "P") - (let ((articles (gnus-summary-work-articles n)) - article) - (while (setq article (pop articles)) - (set-buffer gnus-summary-buffer) - (gnus-summary-goto-subject article) - (let ((group (gnus-group-real-name gnus-newsgroup-name)) - newsgroups followup-to) - (gnus-summary-select-article) - (set-buffer gnus-original-article-buffer) - (if (and (<= (length (message-tokenize-header - (setq newsgroups (mail-fetch-field "newsgroups")) - ", ")) - 1) - (or (not (setq followup-to (mail-fetch-field "followup-to"))) - (not (member group (message-tokenize-header - followup-to ", "))))) - (if followup-to - (gnus-message 1 "Followup-to restricted") - (gnus-message 1 "Not a crossposted article")) - (set-buffer gnus-summary-buffer) - (gnus-summary-reply-with-original 1) - (set-buffer gnus-message-buffer) - (message-goto-body) - (insert (format gnus-crosspost-complaint newsgroups group)) - (message-goto-subject) - (re-search-forward " *$") - (replace-match " (crosspost notification)" t t) - (gnus-deactivate-mark) - (when (gnus-y-or-n-p "Send this complaint? ") - (message-send-and-exit))))))) - -(defun gnus-summary-mail-other-window () - "Compose mail in other window." - (interactive) - (gnus-setup-message 'message - (message-mail))) - -(defun gnus-mail-parse-comma-list () - (let (accumulated - beg) - (skip-chars-forward " ") - (while (not (eobp)) - (setq beg (point)) - (skip-chars-forward "^,") - (while (zerop - (save-excursion - (save-restriction - (let ((i 0)) - (narrow-to-region beg (point)) - (goto-char beg) - (logand (progn - (while (search-forward "\"" nil t) - (incf i)) - (if (zerop i) 2 i)) - 2))))) - (skip-chars-forward ",") - (skip-chars-forward "^,")) - (skip-chars-backward " ") - (push (buffer-substring beg (point)) - accumulated) - (skip-chars-forward "^,") - (skip-chars-forward ", ")) - accumulated)) - -(defun gnus-inews-add-to-address (group) - (let ((to-address (mail-fetch-field "to"))) - (when (and to-address - (gnus-alive-p)) - ;; This mail group doesn't have a `to-list', so we add one - ;; here. Magic! - (when (gnus-y-or-n-p - (format "Do you want to add this as `to-list': %s " to-address)) - (gnus-group-add-parameter group (cons 'to-list to-address)))))) - -(defun gnus-put-message () - "Put the current message in some group and return to Gnus." - (interactive) - (let ((reply gnus-article-reply) - (winconf gnus-prev-winconf) - (group gnus-newsgroup-name)) - - (or (and group (not (gnus-group-read-only-p group))) - (setq group (read-string "Put in group: " nil - (gnus-writable-groups)))) - (when (gnus-gethash group gnus-newsrc-hashtb) - (error "No such group: %s" group)) - - (save-excursion - (save-restriction - (widen) - (message-narrow-to-headers) - (let (gnus-deletable-headers) - (if (message-news-p) - (message-generate-headers message-required-news-headers) - (message-generate-headers message-required-mail-headers))) - (goto-char (point-max)) - (insert "Gcc: " group "\n") - (widen))) - - (gnus-inews-do-gcc) - - (when (get-buffer gnus-group-buffer) - (when (gnus-buffer-exists-p (car-safe reply)) - (set-buffer (car reply)) - (and (cdr reply) - (gnus-summary-mark-article-as-replied - (cdr reply)))) - (when winconf - (set-window-configuration winconf))))) - -(defun gnus-article-mail (yank) - "Send a reply to the address near point. -If YANK is non-nil, include the original article." - (interactive "P") - (let ((address - (buffer-substring - (save-excursion (re-search-backward "[ \t\n]" nil t) (1+ (point))) - (save-excursion (re-search-forward "[ \t\n]" nil t) (1- (point)))))) - (when address - (message-reply address) - (when yank - (gnus-inews-yank-articles (list (cdr gnus-article-current))))))) - -(defvar nntp-server-type) -(defun gnus-bug () - "Send a bug report to the Gnus maintainers." - (interactive) - (unless (gnus-alive-p) - (error "Gnus has been shut down")) - (gnus-setup-message 'bug - (delete-other-windows) - (when gnus-bug-create-help-buffer - (switch-to-buffer "*Gnus Help Bug*") - (erase-buffer) - (insert gnus-bug-message) - (goto-char (point-min))) - (message-pop-to-buffer "*Gnus Bug*") - (message-setup - `((To . ,gnus-maintainer) (Cc . ,semi-gnus-developers) (Subject . ""))) - (when gnus-bug-create-help-buffer - (push `(gnus-bug-kill-buffer) message-send-actions)) - (goto-char (point-min)) - (re-search-forward (concat "^" (regexp-quote mail-header-separator) "$")) - (forward-line 1) - (insert (gnus-version) "\n" - (emacs-version) "\n") - (when (and (boundp 'nntp-server-type) - (stringp nntp-server-type)) - (insert nntp-server-type)) - (insert "\n\n\n\n\n") - (gnus-debug) - (goto-char (point-min)) - (search-forward "Subject: " nil t) - (message ""))) - -(defun gnus-bug-kill-buffer () - (when (get-buffer "*Gnus Help Bug*") - (kill-buffer "*Gnus Help Bug*"))) - -(defun gnus-debug () - "Attempts to go through the Gnus source file and report what variables have been changed. -The source file has to be in the Emacs load path." - (interactive) - (let ((files '("gnus.el" "gnus-sum.el" "gnus-group.el" - "gnus-art.el" "gnus-start.el" "gnus-async.el" - "gnus-msg.el" "gnus-score.el" "gnus-win.el" "gnus-topic.el" - "nnmail.el" "message.el")) - (point (point)) - file expr olist sym) - (gnus-message 4 "Please wait while we snoop your variables...") - (sit-for 0) - ;; Go through all the files looking for non-default values for variables. - (save-excursion - (set-buffer (gnus-get-buffer-create " *gnus bug info*")) - (buffer-disable-undo (current-buffer)) - (while files - (erase-buffer) - (when (and (setq file (locate-library (pop files))) - (file-exists-p file)) - (insert-file-contents file) - (goto-char (point-min)) - (if (not (re-search-forward "^;;* *Internal variables" nil t)) - (gnus-message 4 "Malformed sources in file %s" file) - (narrow-to-region (point-min) (point)) - (goto-char (point-min)) - (while (setq expr (ignore-errors (read (current-buffer)))) - (ignore-errors - (and (or (eq (car expr) 'defvar) - (eq (car expr) 'defcustom)) - (stringp (nth 3 expr)) - (or (not (boundp (nth 1 expr))) - (not (equal (eval (nth 2 expr)) - (symbol-value (nth 1 expr))))) - (push (nth 1 expr) olist))))))) - (kill-buffer (current-buffer))) - (when (setq olist (nreverse olist)) - (insert "------------------ Environment follows ------------------\n\n")) - (while olist - (if (boundp (car olist)) - (condition-case () - (pp `(setq ,(car olist) - ,(if (or (consp (setq sym (symbol-value (car olist)))) - (and (symbolp sym) - (not (or (eq sym nil) - (eq sym t))))) - (list 'quote (symbol-value (car olist))) - (symbol-value (car olist)))) - (current-buffer)) - (error - (format "(setq %s 'whatever)\n" (car olist)))) - (insert ";; (makeunbound '" (symbol-name (car olist)) ")\n")) - (setq olist (cdr olist))) - (insert "\n\n") - ;; Remove any control chars - they seem to cause trouble for some - ;; mailers. (Byte-compiled output from the stuff above.) - (goto-char point) - (while (re-search-forward "[\000-\010\013-\037\200-\237]" nil t) - (replace-match (format "\\%03o" (string-to-char (match-string 0))) - t t)))) - -;;; Treatment of rejected articles. -;;; Bounced mail. - -(defun gnus-summary-resend-bounced-mail (&optional fetch) - "Re-mail the current message. -This only makes sense if the current message is a bounce message than -contains some mail you have written which has been bounced back to -you. -If FETCH, try to fetch the article that this is a reply to, if indeed -this is a reply." - (interactive "P") - (gnus-summary-select-article t) - (set-buffer gnus-original-article-buffer) - (gnus-setup-message 'compose-bounce - (let* ((references (mail-fetch-field "references")) - (parent (and references (gnus-parent-id references)))) - (message-bounce) - ;; If there are references, we fetch the article we answered to. - (and fetch parent - (gnus-summary-refer-article parent) - (gnus-summary-show-all-headers))))) - -;;; Gcc handling. - -;; Do Gcc handling, which copied the message over to some group. -(defun gnus-inews-do-gcc (&optional gcc) - (interactive) - (when (gnus-alive-p) - (save-excursion - (save-restriction - (message-narrow-to-headers) - (let ((gcc (or gcc (mail-fetch-field "gcc" nil t))) - (coding-system-for-write 'raw-text) - groups group method) - (when gcc - (message-remove-header "gcc") - (widen) - (setq groups (message-tokenize-header gcc " ,")) - ;; Copy the article over to some group(s). - (while (setq group (pop groups)) - (gnus-check-server - (setq method - (cond ((and (null (gnus-get-info group)) - (eq (car gnus-message-archive-method) - (car - (gnus-server-to-method - (gnus-group-method group))))) - ;; If the group doesn't exist, we assume - ;; it's an archive group... - gnus-message-archive-method) - ;; Use the method. - ((gnus-info-method (gnus-get-info group)) - (gnus-info-method (gnus-get-info group))) - ;; Find the method. - (t (gnus-group-method group))))) - (gnus-check-server method) - (unless (gnus-request-group group t method) - (gnus-request-create-group group method)) - (save-excursion - (nnheader-set-temp-buffer " *acc*") - (insert-buffer-substring message-encoding-buffer) - (gnus-run-hooks 'gnus-before-do-gcc-hook) - (goto-char (point-min)) - (when (re-search-forward - (concat "^" (regexp-quote mail-header-separator) "$") - nil t) - (replace-match "" t t )) - (unless (gnus-request-accept-article group method t) - (gnus-message 1 "Couldn't store article in group %s: %s" - group (gnus-status-message method)) - (sit-for 2)) - (kill-buffer (current-buffer)))))))))) - -(defun gnus-inews-insert-gcc () - "Insert Gcc headers based on `gnus-outgoing-message-group'." - (save-excursion - (save-restriction - (message-narrow-to-headers) - (let* ((group gnus-outgoing-message-group) - (gcc (cond - ((gnus-functionp group) - (funcall group)) - ((or (stringp group) (list group)) - group)))) - (when gcc - (insert "Gcc: " - (if (stringp gcc) gcc - (mapconcat 'identity gcc " ")) - "\n")))))) - -(defun gnus-inews-insert-archive-gcc (&optional group) - "Insert the Gcc to say where the article is to be archived." - (let* ((var gnus-message-archive-group) - (group (or group gnus-newsgroup-name "")) - (gcc-self-val - (and gnus-newsgroup-name - (gnus-group-find-parameter - gnus-newsgroup-name 'gcc-self))) - result - (groups - (cond - ((null gnus-message-archive-method) - ;; Ignore. - nil) - ((stringp var) - ;; Just a single group. - (list var)) - ((null var) - ;; We don't want this. - nil) - ((and (listp var) (stringp (car var))) - ;; A list of groups. - var) - ((gnus-functionp var) - ;; A function. - (funcall var group)) - (t - ;; An alist of regexps/functions/forms. - (while (and var - (not - (setq result - (cond - ((stringp (caar var)) - ;; Regexp. - (when (string-match (caar var) group) - (cdar var))) - ((gnus-functionp (car var)) - ;; Function. - (funcall (car var) group)) - (t - (eval (car var))))))) - (setq var (cdr var))) - result))) - name) - (when (or groups gcc-self-val) - (when (stringp groups) - (setq groups (list groups))) - (save-excursion - (save-restriction - (message-narrow-to-headers) - (goto-char (point-max)) - (insert "Gcc: ") - (if gcc-self-val - ;; Use the `gcc-self' param value instead. - (progn - (insert - (if (stringp gcc-self-val) - gcc-self-val - group)) - (if (not (eq gcc-self-val 'none)) - (insert "\n") - (progn - (beginning-of-line) - (kill-line)))) - ;; Use the list of groups. - (while (setq name (pop groups)) - (insert (if (string-match ":" name) - name - (gnus-group-prefixed-name - name gnus-message-archive-method))) - (when groups - (insert " "))) - (insert "\n"))))))) - -;;; Posting styles. - -(defvar gnus-message-style-insertions nil) - -(defun gnus-configure-posting-styles () - "Configure posting styles according to `gnus-posting-styles'." - (unless gnus-inhibit-posting-styles - (let ((styles gnus-posting-styles) - (gnus-newsgroup-name (or gnus-newsgroup-name "")) - style match variable attribute value value-value) - (make-local-variable 'gnus-message-style-insertions) - ;; Go through all styles and look for matches. - (while styles - (setq style (pop styles) - match (pop style)) - (when (cond ((stringp match) - ;; Regexp string match on the group name. - (string-match match gnus-newsgroup-name)) - ((or (symbolp match) - (gnus-functionp match)) - (cond ((gnus-functionp match) - ;; Function to be called. - (funcall match)) - ((boundp match) - ;; Variable to be checked. - (symbol-value match)))) - ((listp match) - ;; This is a form to be evaled. - (eval match))) - ;; We have a match, so we set the variables. - (while style - (setq attribute (pop style) - value (cadr attribute) - variable nil) - ;; We find the variable that is to be modified. - (if (and (not (stringp (car attribute))) - (not (eq 'body (car attribute))) - (not (setq variable - (cdr (assq (car attribute) - gnus-posting-style-alist))))) - (message "Couldn't find attribute %s" (car attribute)) - ;; We get the value. - (setq value-value - (cond ((stringp value) - value) - ((or (symbolp value) - (gnus-functionp value)) - (cond ((gnus-functionp value) - (funcall value)) - ((boundp value) - (symbol-value value)))) - ((listp value) - (eval value)))) - (if variable - ;; This is an ordinary variable. - (set (make-local-variable variable) value-value) - ;; This is either a body or a header to be inserted in the - ;; message. - (when value-value - (let ((attr (car attribute))) - (make-local-variable 'message-setup-hook) - (if (eq 'body attr) - (add-hook 'message-setup-hook - `(lambda () - (save-excursion - (message-goto-body) - (insert ,value-value)))) - (add-hook 'message-setup-hook - 'gnus-message-insert-stylings) - (push (cons (if (stringp attr) attr - (symbol-name attr)) - value-value) - gnus-message-style-insertions)))))))))))) - -(defun gnus-message-insert-stylings () - (let (val) - (save-excursion - (message-goto-eoh) - (while (setq val (pop gnus-message-style-insertions)) - (when (cdr val) - (insert (car val) ": " (cdr val) "\n")) - (gnus-pull (car val) gnus-message-style-insertions))))) - -;;; Allow redefinition of functions. - -(gnus-ems-redefine) - -(provide 'gnus-msg) - -;;; gnus-msg.el ends here diff --git a/lisp/gnus-nocem.el b/lisp/gnus-nocem.el deleted file mode 100644 index d678531..0000000 --- a/lisp/gnus-nocem.el +++ /dev/null @@ -1,352 +0,0 @@ -;;; gnus-nocem.el --- NoCeM pseudo-cancellation treatment -;; Copyright (C) 1995,96,97,98 Free Software Foundation, Inc. - -;; Author: Lars Magne Ingebrigtsen -;; Keywords: news - -;; This file is part of GNU Emacs. - -;; GNU Emacs is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 2, or (at your option) -;; any later version. - -;; GNU Emacs is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs; see the file COPYING. If not, write to the -;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. - -;;; Commentary: - -;;; Code: - -(eval-when-compile (require 'cl)) - -(require 'gnus) -(require 'nnmail) -(require 'gnus-art) -(require 'gnus-sum) -(require 'gnus-range) - -(defgroup gnus-nocem nil - "NoCeM pseudo-cancellation treatment" - :group 'gnus-score) - -(defcustom gnus-nocem-groups - '("news.lists.filters" "news.admin.net-abuse.bulletins" - "alt.nocem.misc" "news.admin.net-abuse.announce") - "*List of groups that will be searched for NoCeM messages." - :group 'gnus-nocem - :type '(repeat (string :tag "Group"))) - -(defcustom gnus-nocem-issuers - '("AutoMoose-1" "Automoose-1" ; CancelMoose[tm] - "rbraver@ohww.norman.ok.us" ; Robert Braver - "clewis@ferret.ocunix.on.ca" ; Chris Lewis - "jem@xpat.com" ; Despammer from Korea - "snowhare@xmission.com" ; Benjamin "Snowhare" Franz - "red@redpoll.mrfs.oh.us (Richard E. Depew)" ; ARMM! ARMM! - ) - "*List of NoCeM issuers to pay attention to. - -This can also be a list of `(ISSUER CONDITIONS)' elements." - :group 'gnus-nocem - :type '(repeat (choice string sexp))) - -(defcustom gnus-nocem-directory - (nnheader-concat gnus-article-save-directory "NoCeM/") - "*Directory where NoCeM files will be stored." - :group 'gnus-nocem - :type 'directory) - -(defcustom gnus-nocem-expiry-wait 15 - "*Number of days to keep NoCeM headers in the cache." - :group 'gnus-nocem - :type 'integer) - -(defcustom gnus-nocem-verifyer 'mc-verify - "*Function called to verify that the NoCeM message is valid. -One likely value is `mc-verify'. If the function in this variable -isn't bound, the message will be used unconditionally." - :group 'gnus-nocem - :type '(radio (function-item mc-verify) - (function :tag "other"))) - -(defcustom gnus-nocem-liberal-fetch nil - "*If t try to fetch all messages which have @@NCM in the subject. -Otherwise don't fetch messages which have references or whose message-id -matches an previously scanned and verified nocem message." - :group 'gnus-nocem - :type 'boolean) - -;;; Internal variables - -(defvar gnus-nocem-active nil) -(defvar gnus-nocem-alist nil) -(defvar gnus-nocem-touched-alist nil) -(defvar gnus-nocem-hashtb nil) -(defvar gnus-nocem-seen-message-ids nil) - -;;; Functions - -(defun gnus-nocem-active-file () - (concat (file-name-as-directory gnus-nocem-directory) "active")) - -(defun gnus-nocem-cache-file () - (concat (file-name-as-directory gnus-nocem-directory) "cache")) - -;; -;; faster lookups for group names: -;; - -(defvar gnus-nocem-real-group-hashtb nil - "Real-name mappings of subscribed groups.") - -(defun gnus-fill-real-hashtb () - "Fill up a hash table with the real-name mappings from the user's active file." - (setq gnus-nocem-real-group-hashtb (gnus-make-hashtable - (length gnus-newsrc-alist))) - (mapcar (lambda (group) - (setq group (gnus-group-real-name (car group))) - (gnus-sethash group t gnus-nocem-real-group-hashtb)) - gnus-newsrc-alist)) - -(defun gnus-nocem-scan-groups () - "Scan all NoCeM groups for new NoCeM messages." - (interactive) - (let ((groups gnus-nocem-groups) - (gnus-inhibit-demon t) - group active gactive articles) - (gnus-make-directory gnus-nocem-directory) - ;; Load any previous NoCeM headers. - (gnus-nocem-load-cache) - ;; Get the group name mappings: - (gnus-fill-real-hashtb) - ;; Read the active file if it hasn't been read yet. - (and (file-exists-p (gnus-nocem-active-file)) - (not gnus-nocem-active) - (ignore-errors - (load (gnus-nocem-active-file) t t t))) - ;; Go through all groups and see whether new articles have - ;; arrived. - (while (setq group (pop groups)) - (if (not (setq gactive (gnus-activate-group group))) - () ; This group doesn't exist. - (setq active (nth 1 (assoc group gnus-nocem-active))) - (when (and (not (< (cdr gactive) (car gactive))) ; Empty group. - (or (not active) - (< (cdr active) (cdr gactive)))) - ;; Ok, there are new articles in this group, se we fetch the - ;; headers. - (save-excursion - (let ((dependencies (make-vector 10 nil)) - headers header) - (nnheader-temp-write nil - (setq headers - (if (eq 'nov - (gnus-retrieve-headers - (setq articles - (gnus-uncompress-range - (cons - (if active (1+ (cdr active)) - (car gactive)) - (cdr gactive)))) - group)) - (gnus-get-newsgroup-headers-xover - articles nil dependencies) - (gnus-get-newsgroup-headers dependencies))) - (while (setq header (pop headers)) - ;; We take a closer look on all articles that have - ;; "@@NCM" in the subject. Unless we already read - ;; this cross posted message. Nocem messages - ;; are not allowed to have references, so we can - ;; ignore scanning followups. - (and (string-match "@@NCM" (mail-header-subject header)) - (or gnus-nocem-liberal-fetch - (and (or (string= "" (mail-header-references - header)) - (null (mail-header-references header))) - (not (member (mail-header-message-id header) - gnus-nocem-seen-message-ids)))) - (gnus-nocem-check-article group header))))))) - (setq gnus-nocem-active - (cons (list group gactive) - (delq (assoc group gnus-nocem-active) - gnus-nocem-active))))) - ;; Save the results, if any. - (gnus-nocem-save-cache) - (gnus-nocem-save-active))) - -(defun gnus-nocem-check-article (group header) - "Check whether the current article is an NCM article and that we want it." - ;; Get the article. - (gnus-message 7 "Checking article %d in %s for NoCeM..." - (mail-header-number header) group) - (let ((date (mail-header-date header)) - issuer b e type) - (when (or (not date) - (nnmail-time-less - (nnmail-time-since (nnmail-date-to-time date)) - (nnmail-days-to-time gnus-nocem-expiry-wait))) - (gnus-request-article-this-buffer (mail-header-number header) group) - (goto-char (point-min)) - (when (re-search-forward "-----BEGIN PGP MESSAGE-----" nil t) - (delete-region (point-min) (match-beginning 0))) - (when (re-search-forward "-----END PGP MESSAGE-----\n?" nil t) - (delete-region (match-end 0) (point-max))) - (goto-char (point-min)) - ;; The article has to have proper NoCeM headers. - (when (and (setq b (search-forward "\n@@BEGIN NCM HEADERS\n" nil t)) - (setq e (search-forward "\n@@BEGIN NCM BODY\n" nil t))) - ;; We get the name of the issuer. - (narrow-to-region b e) - (setq issuer (mail-fetch-field "issuer") - type (mail-fetch-field "issuer")) - (widen) - (if (not (gnus-nocem-message-wanted-p issuer type)) - (message "invalid NoCeM issuer: %s" issuer) - (and (gnus-nocem-verify-issuer issuer) ; She is who she says she is. - (gnus-nocem-enter-article) ; We gobble the message. - (push (mail-header-message-id header) ; But don't come back for - gnus-nocem-seen-message-ids))))))) ; second helpings. - -(defun gnus-nocem-message-wanted-p (issuer type) - (let ((issuers gnus-nocem-issuers) - wanted conditions condition) - (cond - ;; Do the quick check first. - ((member issuer issuers) - t) - ((setq conditions (cdr (assoc issuer issuers))) - ;; Check whether we want this type. - (while (setq condition (pop conditions)) - (cond - ((stringp condition) - (setq wanted (string-match condition type))) - ((and (consp condition) - (eq (car condition) 'not) - (stringp (cadr condition))) - (setq wanted (not (string-match (cadr condition) type)))) - (t - (error "Invalid NoCeM condition: %S" condition)))) - wanted)))) - -(defun gnus-nocem-verify-issuer (person) - "Verify using PGP that the canceler is who she says she is." - (if (fboundp gnus-nocem-verifyer) - (ignore-errors - (funcall gnus-nocem-verifyer)) - ;; If we don't have Mailcrypt, then we use the message anyway. - t)) - -(defun gnus-nocem-enter-article () - "Enter the current article into the NoCeM cache." - (goto-char (point-min)) - (let ((b (search-forward "\n@@BEGIN NCM BODY\n" nil t)) - (e (search-forward "\n@@END NCM BODY\n" nil t)) - (buf (current-buffer)) - ncm id group) - (when (and b e) - (narrow-to-region b (1+ (match-beginning 0))) - (goto-char (point-min)) - (while (search-forward "\t" nil t) - (cond - ((not (ignore-errors - (setq group (let ((obarray gnus-active-hashtb)) (read buf))))) - ;; An error. - ) - ((not (symbolp group)) - ;; Ignore invalid entries. - ) - ((not (boundp group)) - ;; Make sure all entries in the hashtb are bound. - (set group nil)) - (t - (when (gnus-gethash (gnus-group-real-name (symbol-name group)) - gnus-nocem-real-group-hashtb) - ;; Valid group. - (beginning-of-line) - (while (= (following-char) ?\t) - (forward-line -1)) - (setq id (buffer-substring (point) (1- (search-forward "\t")))) - (unless (gnus-gethash id gnus-nocem-hashtb) - ;; only store if not already present - (gnus-sethash id t gnus-nocem-hashtb) - (push id ncm)) - (forward-line 1) - (while (= (following-char) ?\t) - (forward-line 1)))))) - (when ncm - (setq gnus-nocem-touched-alist t) - (push (cons (let ((time (current-time))) (setcdr (cdr time) nil) time) - ncm) - gnus-nocem-alist)) - t))) - -(defun gnus-nocem-load-cache () - "Load the NoCeM cache." - (interactive) - (unless gnus-nocem-alist - ;; The buffer doesn't exist, so we create it and load the NoCeM - ;; cache. - (when (file-exists-p (gnus-nocem-cache-file)) - (load (gnus-nocem-cache-file) t t t) - (gnus-nocem-alist-to-hashtb)))) - -(defun gnus-nocem-save-cache () - "Save the NoCeM cache." - (when (and gnus-nocem-alist - gnus-nocem-touched-alist) - (nnheader-temp-write (gnus-nocem-cache-file) - (gnus-prin1 `(setq gnus-nocem-alist ',gnus-nocem-alist))) - (setq gnus-nocem-touched-alist nil))) - -(defun gnus-nocem-save-active () - "Save the NoCeM active file." - (nnheader-temp-write (gnus-nocem-active-file) - (gnus-prin1 `(setq gnus-nocem-active ',gnus-nocem-active)))) - -(defun gnus-nocem-alist-to-hashtb () - "Create a hashtable from the Message-IDs we have." - (let* ((alist gnus-nocem-alist) - (pprev (cons nil alist)) - (prev pprev) - (expiry (nnmail-days-to-time gnus-nocem-expiry-wait)) - entry) - (setq gnus-nocem-hashtb (gnus-make-hashtable (* (length alist) 51))) - (while (setq entry (car alist)) - (if (not (nnmail-time-less (nnmail-time-since (car entry)) expiry)) - ;; This entry has expired, so we remove it. - (setcdr prev (cdr alist)) - (setq prev alist) - ;; This is ok, so we enter it into the hashtable. - (setq entry (cdr entry)) - (while entry - (gnus-sethash (car entry) t gnus-nocem-hashtb) - (setq entry (cdr entry)))) - (setq alist (cdr alist))))) - -(gnus-add-shutdown 'gnus-nocem-close 'gnus) - -(defun gnus-nocem-close () - "Clear internal NoCeM variables." - (setq gnus-nocem-alist nil - gnus-nocem-hashtb nil - gnus-nocem-active nil - gnus-nocem-touched-alist nil - gnus-nocem-seen-message-ids nil - gnus-nocem-real-group-hashtb nil)) - -(defun gnus-nocem-unwanted-article-p (id) - "Say whether article ID in the current group is wanted." - (and gnus-nocem-hashtb - (gnus-gethash id gnus-nocem-hashtb))) - -(provide 'gnus-nocem) - -;;; gnus-nocem.el ends here diff --git a/lisp/gnus-picon.el b/lisp/gnus-picon.el deleted file mode 100644 index a3b5418..0000000 --- a/lisp/gnus-picon.el +++ /dev/null @@ -1,739 +0,0 @@ -;;; gnus-picon.el --- displaying pretty icons in Gnus -;; Copyright (C) 1996,97,98 Free Software Foundation, Inc. - -;; Author: Wes Hardaker -;; Keywords: news xpm annotation glyph faces - -;; This file is part of GNU Emacs. - -;; GNU Emacs is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 2, or (at your option) -;; any later version. - -;; GNU Emacs is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs; see the file COPYING. If not, write to the -;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. - -;;; Commentary: - -;;; Code: - -(require 'gnus) -(require 'xpm) -(require 'annotations) -(require 'custom) -(require 'gnus-art) -(require 'gnus-win) - -;;; User variables: - -(defgroup picons nil - "Show pictures of people, domains, and newsgroups (XEmacs). -For this to work, you must add gnus-group-display-picons to the -gnus-summary-display-hook or to the gnus-article-display-hook -depending on what gnus-picons-display-where is set to. You must -also add gnus-article-display-picons to gnus-article-display-hook." - :group 'gnus-visual) - -(defcustom gnus-picons-display-where 'picons - "Where to display the group and article icons. -Legal values are `article' and `picons'." - :type '(choice symbol string) - :group 'picons) - -(defcustom gnus-picons-has-modeline-p t - "*Whether the picons window should have a modeline. -This is only useful if `gnus-picons-display-where' is `picons'." - :type 'boolean - :group 'picons) - -(defcustom gnus-picons-database "/usr/local/faces" - "*Defines the location of the faces database. -For information on obtaining this database of pretty pictures, please -see http://www.cs.indiana.edu/picons/ftp/index.html" - :type 'directory - :group 'picons) - -(defcustom gnus-picons-news-directories '("news") - "*List of directories to search for newsgroups faces." - :type '(repeat string) - :group 'picons) -(define-obsolete-variable-alias 'gnus-picons-news-directory - 'gnus-picons-news-directories) - -(defcustom gnus-picons-user-directories '("local" "users" "usenix" "misc") - "*List of directories to search for user faces." - :type '(repeat string) - :group 'picons) - -(defcustom gnus-picons-domain-directories '("domains") - "*List of directories to search for domain faces. -Some people may want to add \"unknown\" to this list." - :type '(repeat string) - :group 'picons) - -(defcustom gnus-picons-refresh-before-display nil - "*If non-nil, display the article buffer before computing the picons." - :type 'boolean - :group 'picons) - -(defcustom gnus-picons-group-excluded-groups nil - "*If this regexp matches the group name, group picons will be disabled." - :type 'regexp - :group 'picons) - -(defcustom gnus-picons-x-face-file-name - (format "/tmp/picon-xface.%s.xbm" (user-login-name)) - "*The name of the file in which to store the converted X-face header." - :type 'string - :group 'picons) - -(defcustom gnus-picons-convert-x-face (format "{ echo '/* Width=48, Height=48 */'; uncompface; } | icontopbm | pbmtoxbm > %s" gnus-picons-x-face-file-name) - "*Command to convert the x-face header into a xbm file." - :type 'string - :group 'picons) - -(defcustom gnus-picons-display-as-address t - "*If t display textual email addresses along with pictures." - :type 'boolean - :group 'picons) - -(defcustom gnus-picons-file-suffixes - (when (featurep 'x) - (let ((types (list "xbm"))) - (when (featurep 'gif) - (push "gif" types)) - (when (featurep 'xpm) - (push "xpm" types)) - types)) - "*List of suffixes on picon file names to try." - :type '(repeat string) - :group 'picons) - -(defcustom gnus-picons-display-article-move-p t - "*Whether to move point to first empty line when displaying picons. -This has only an effect if `gnus-picons-display-where' has value `article'." - :type 'boolean - :group 'picons) - -(defcustom gnus-picons-clear-cache-on-shutdown t - "*Whether to clear the picons cache when exiting gnus. -Gnus caches every picons it finds while it is running. This saves -some time in the search process but eats some memory. If this -variable is set to nil, Gnus will never clear the cache itself; you -will have to manually call `gnus-picons-clear-cache' to clear it. -Otherwise the cache will be cleared every time you exit Gnus." - :type 'boolean - :group 'picons) - -(defcustom gnus-picons-piconsearch-url nil - "*The url to query for picons. Setting this to nil will disable it. -The only publicly available address currently known is -http://www.cs.indiana.edu:800/piconsearch. If you know of any other, -please tell me so that we can list it." - :type '(choice (const :tag "Disable" :value nil) - (const :tag "www.cs.indiana.edu" - :value "http://www.cs.indiana.edu:800/piconsearch") - (string)) - :group 'picons) - -(defface gnus-picons-xbm-face '((t (:foreground "black" :background "white"))) - "Face to show X face" - :group 'picons) - -;;; Internal variables: - -(defvar gnus-picons-processes-alist nil - "Picons processes currently running and their environment.") -(defvar gnus-picons-glyph-alist nil - "Picons glyphs cache. -List of pairs (KEY . GLYPH) where KEY is either a filename or an URL.") -(defvar gnus-picons-url-alist nil - "Picons file names cache. -List of pairs (KEY . NAME) where KEY is (USER HOST DBS) and NAME is an URL.") - -(defvar gnus-picons-jobs-alist nil - "List of jobs that still need be done. -This is a list of (SYM-ANN TAG ARGS...) where SYM-ANN three annotations list, -TAG is one of `picon' or `search' indicating that the job should query a -picon or do a search for picons file names, and ARGS is some additionnal -arguments necessary for the job.") - -(defvar gnus-picons-job-already-running nil - "Lock to ensure only one stream of http requests is running.") - -;;; Functions: - -(defun gnus-picons-remove-all () - "Removes all picons from the Gnus display(s)." - (interactive) - (map-extents (function (lambda (ext unused) (delete-annotation ext) nil)) - nil nil nil nil nil 'gnus-picon) - (setq gnus-picons-jobs-alist '()) - ;; notify running job that it may have been preempted - (if (and (listp gnus-picons-job-already-running) - gnus-picons-job-already-running) - (setq gnus-picons-job-already-running t))) - -(defun gnus-get-buffer-name (variable) - "Returns the buffer name associated with the contents of a variable." - (let ((buf (gnus-get-buffer-create (gnus-window-to-buffer-helper - (cdr - (assq variable gnus-window-to-buffer)))))) - (and buf - (buffer-name buf)))) - -(defun gnus-picons-buffer-name () - (cond ((or (stringp gnus-picons-display-where) - (bufferp gnus-picons-display-where)) - gnus-picons-display-where) - ((eq gnus-picons-display-where 'picons) - (if gnus-single-article-buffer - "*Picons*" - (concat "*Picons " gnus-newsgroup-name "*"))) - (t - (gnus-get-buffer-name gnus-picons-display-where)))) - -(defun gnus-picons-kill-buffer () - (let ((buf (get-buffer (gnus-picons-buffer-name)))) - (if (buffer-live-p buf) - (kill-buffer buf)))) - -(defun gnus-picons-setup-buffer () - (let ((name (gnus-picons-buffer-name))) - (save-excursion - (if (get-buffer name) - (set-buffer name) - (set-buffer (gnus-get-buffer-create name)) - (buffer-disable-undo) - (setq buffer-read-only t) - (add-hook 'gnus-summary-prepare-exit-hook 'gnus-picons-kill-buffer)) - (current-buffer)))) - -(defun gnus-picons-set-buffer () - (set-buffer (gnus-picons-setup-buffer)) - (goto-char (point-min)) - (if (and (eq gnus-picons-display-where 'article) - gnus-picons-display-article-move-p) - (if (search-forward "\n\n" nil t) - (forward-line -1) - (goto-char (point-max))) - (setq buffer-read-only t) - (unless gnus-picons-has-modeline-p - (set-specifier has-modeline-p - (list (list (current-buffer) - (cons nil gnus-picons-has-modeline-p))))))) - -(defun gnus-picons-prepare-for-annotations () - "Prepare picons buffer for putting annotations." - ;; let drawing catch up - (when gnus-picons-refresh-before-display - (sit-for 0)) - (gnus-picons-set-buffer) - (gnus-picons-remove-all)) - -(defun gnus-picons-make-annotation (&rest args) - (let ((annot (apply 'make-annotation args))) - (set-extent-property annot 'gnus-picon t) - (set-extent-property annot 'duplicable t) - annot)) - -(defun gnus-picons-article-display-x-face () - "Display the x-face header bitmap in the 'gnus-picons-display-where buffer." - (let ((gnus-article-x-face-command 'gnus-picons-display-x-face)) - (gnus-article-display-x-face))) - -(defun gnus-picons-x-face-sentinel (process event) - (when (memq process gnus-picons-processes-alist) - (setq gnus-picons-processes-alist - (delq process gnus-picons-processes-alist)) - (gnus-picons-set-buffer) - (gnus-picons-make-annotation (make-glyph gnus-picons-x-face-file-name) - nil 'text) - (when (file-exists-p gnus-picons-x-face-file-name) - (delete-file gnus-picons-x-face-file-name)))) - -(defun gnus-picons-display-x-face (beg end) - "Function to display the x-face header in the picons window. -To use: (setq gnus-article-x-face-command 'gnus-picons-display-x-face)" - (interactive) - (if (featurep 'xface) - ;; Use builtin support - (save-excursion - ;; Don't remove this binding, it is really needed: when - ;; `gnus-picons-set-buffer' changes buffer (like when it is - ;; set to display picons outside of the article buffer), BEG - ;; and END still refer the buffer current now ! - (let ((buf (current-buffer))) - (gnus-picons-set-buffer) - (gnus-picons-make-annotation - (vector 'xface - :data (concat "X-Face: " (buffer-substring beg end buf))) - nil 'text nil nil nil t))) - ;; convert the x-face header to a .xbm file - (let* ((process-connection-type nil) - (process (start-process-shell-command "gnus-x-face" nil - gnus-picons-convert-x-face))) - (push process gnus-picons-processes-alist) - (process-kill-without-query process) - (set-process-sentinel process 'gnus-picons-x-face-sentinel) - (process-send-region process beg end) - (process-send-eof process)))) - -(defun gnus-article-display-picons () - "Display faces for an author and her domain in gnus-picons-display-where." - (interactive) - (let (from at-idx) - (when (and (featurep 'xpm) - (or (not (fboundp 'device-type)) (equal (device-type) 'x)) - (setq from (mail-fetch-field "from")) - (setq from (downcase (or (cadr (mail-extract-address-components - from)) - ""))) - (or (setq at-idx (string-match "@" from)) - (setq at-idx (length from)))) - (save-excursion - (let ((username (downcase (substring from 0 at-idx))) - (addrs (if (eq at-idx (length from)) - (if gnus-local-domain - (message-tokenize-header gnus-local-domain ".")) - (message-tokenize-header (substring from (1+ at-idx)) - ".")))) - (gnus-picons-prepare-for-annotations) - (gnus-group-display-picons) - (if (null gnus-picons-piconsearch-url) - (progn - (gnus-picons-display-pairs (gnus-picons-lookup-pairs - addrs - gnus-picons-domain-directories) - gnus-picons-display-as-address - "." t) - (if (and gnus-picons-display-as-address addrs) - (gnus-picons-make-annotation - [string :data "@"] nil 'text nil nil nil t)) - (gnus-picons-display-picon-or-name - (gnus-picons-lookup-user username addrs) - username t)) - (push (list 'gnus-article-annotations 'search username addrs - gnus-picons-domain-directories t) - gnus-picons-jobs-alist) - (gnus-picons-next-job))))))) - -(defun gnus-group-display-picons () - "Display icons for the group in the `gnus-picons-display-where' buffer." - (interactive) - (when (and (featurep 'xpm) - (or (not (fboundp 'device-type)) (equal (device-type) 'x)) - (or (null gnus-picons-group-excluded-groups) - (not (string-match gnus-picons-group-excluded-groups - gnus-newsgroup-name)))) - (save-excursion - (gnus-picons-prepare-for-annotations) - (if (null gnus-picons-piconsearch-url) - (gnus-picons-display-pairs - (gnus-picons-lookup-pairs - (reverse (message-tokenize-header - (gnus-group-real-name gnus-newsgroup-name) - ".")) - gnus-picons-news-directories) - t ".") - (push (list 'gnus-group-annotations 'search nil - (message-tokenize-header - (gnus-group-real-name gnus-newsgroup-name) ".") - (if (listp gnus-picons-news-directories) - gnus-picons-news-directories - (list gnus-picons-news-directories)) - nil) - gnus-picons-jobs-alist) - (gnus-picons-next-job)) - - (add-hook 'gnus-summary-exit-hook 'gnus-picons-remove-all)))) - -(defun gnus-picons-lookup-internal (addrs dir) - (setq dir (expand-file-name dir gnus-picons-database)) - (gnus-picons-try-face (dolist (part (reverse addrs) dir) - (setq dir (expand-file-name part dir))))) - -(defun gnus-picons-lookup (addrs dirs) - "Lookup the picon for ADDRS in databases DIRS. -Returns the picon filename or NIL if none found." - (let (result) - (while (and dirs (null result)) - (setq result (gnus-picons-lookup-internal addrs (pop dirs)))) - result)) - -(defun gnus-picons-lookup-user-internal (user domains) - (let ((dirs gnus-picons-user-directories) - domains-tmp dir picon) - (while (and dirs (null picon)) - (setq domains-tmp domains - dir (pop dirs)) - (while (and domains-tmp - (null (setq picon (gnus-picons-lookup-internal - (cons user domains-tmp) dir)))) - (pop domains-tmp)) - ;; Also make a try in MISC subdir - (unless picon - (setq picon (gnus-picons-lookup-internal (list user "MISC") dir)))) - picon)) - -(defun gnus-picons-lookup-user (user domains) - "Lookup the picon for USER at DOMAINS. -USER is a string containing a name. -DOMAINS is a list of strings from the fully qualified domain name." - (or (gnus-picons-lookup-user-internal user domains) - (gnus-picons-lookup-user-internal "unknown" domains))) - -(defun gnus-picons-lookup-pairs (domains directories) - "Lookup picons for DOMAINS and all its parents in DIRECTORIES. -Returns a list of PAIRS whose CAR is the picon filename or NIL if -none, and whose CDR is the corresponding element of DOMAINS." - (let (picons) - (setq directories (if (listp directories) - directories - (list directories))) - (while domains - (push (list (gnus-picons-lookup (cons "unknown" domains) directories) - (pop domains)) - picons)) - picons)) - -(defun gnus-picons-display-picon-or-name (picon name &optional right-p) - (cond (picon (gnus-picons-display-glyph picon name right-p)) - (gnus-picons-display-as-address (list (gnus-picons-make-annotation - (vector 'string :data name) - nil 'text - nil nil nil right-p))))) - -(defun gnus-picons-display-pairs (pairs &optional bar-p dot-p right-p) - "Display picons in list PAIRS." - (let ((domain-p (and gnus-picons-display-as-address dot-p)) - pair picons) - (when (and bar-p domain-p right-p) - (setq picons (gnus-picons-display-glyph - (let ((gnus-picons-file-suffixes '("xbm"))) - (gnus-picons-try-face - gnus-xmas-glyph-directory "bar.")) - nil right-p))) - (while (setq pair (pop pairs)) - (setq picons (nconc picons - (gnus-picons-display-picon-or-name - (car pair) (cadr pair) right-p) - (if (and domain-p pairs) - (list (gnus-picons-make-annotation - (vector 'string :data dot-p) - nil 'text nil nil nil right-p)))))) - picons)) - -(defun gnus-picons-try-face (dir &optional filebase) - (let* ((dir (file-name-as-directory dir)) - (filebase (or filebase "face.")) - (key (concat dir filebase)) - (glyph (cdr (assoc key gnus-picons-glyph-alist))) - (suffixes gnus-picons-file-suffixes) - f suf) - (while (setq suf (pop suffixes)) - (when (file-exists-p (setq f (expand-file-name - (concat filebase suf) - dir))) - (setq suffixes nil - glyph (make-glyph f)) - (when (equal suf "xbm") - (set-glyph-face glyph 'gnus-picons-xbm-face)) - (push (cons key glyph) gnus-picons-glyph-alist))) - glyph)) - -(defun gnus-picons-display-glyph (glyph &optional part rightp) - (let ((new (gnus-picons-make-annotation - glyph (point) 'text nil nil nil rightp))) - (when (and part gnus-picons-display-as-address) - (set-annotation-data - new (cons new (make-glyph (vector 'string :data part)))) - (set-annotation-action new 'gnus-picons-action-toggle)) - (nconc - (list new) - (if (and (eq major-mode 'gnus-article-mode) - (not gnus-picons-display-as-address) - (not part)) - (list (gnus-picons-make-annotation [string :data " "] (point) - 'text nil nil nil rightp)))))) - -(defun gnus-picons-action-toggle (data) - "Toggle annotation." - (interactive "e") - (let* ((annot (car data)) - (glyph (annotation-glyph annot))) - (set-annotation-glyph annot (cdr data)) - (set-annotation-data annot (cons annot glyph)))) - -(defun gnus-picons-clear-cache () - "Clear the picons cache." - (interactive) - (setq gnus-picons-glyph-alist nil - gnus-picons-url-alist nil)) - -(gnus-add-shutdown 'gnus-picons-close 'gnus) - -(defun gnus-picons-close () - "Shut down the picons." - (if gnus-picons-clear-cache-on-shutdown - (gnus-picons-clear-cache))) - -;;; Query a remote DB. This requires some stuff from w3 ! - -(require 'url) -(require 'w3-forms) - -(defun gnus-picons-url-retrieve (url fn arg) - (let ((old-asynch (default-value 'url-be-asynchronous)) - (url-working-buffer (generate-new-buffer " *picons*")) - (url-package-name "Gnus") - (url-package-version gnus-version-number) - url-request-method) - (setq-default url-be-asynchronous t) - (save-excursion - (set-buffer url-working-buffer) - (setq url-be-asynchronous t - url-current-callback-data arg - url-current-callback-func fn) - (url-retrieve url t)) - (setq-default url-be-asynchronous old-asynch))) - -(defun gnus-picons-make-glyph (type) - "Make a TYPE glyph using current buffer as data. Handles xbm nicely." - (cond ((null type) nil) - ((eq type 'xbm) (let ((fname (make-temp-name "/tmp/picon"))) - (write-region (point-min) (point-max) fname - nil 'quiet) - (prog1 (make-glyph (vector 'xbm :file fname)) - (delete-file fname)))) - (t (make-glyph (vector type :data (buffer-string)))))) - -;;; Parsing of piconsearch result page. - -;; Assumes: -;; 1 - each value field has the form: "key = value" -;; 2 - a "

" separates the keywords from the results -;; 3 - every results begins by the path within the database at the beginning -;; of the line in raw text. -;; 3b - and the href following it is the preferred image type. - -;; if 1 or 2 is not met, it will probably cause an error. The other -;; will go undetected - -(defun gnus-picons-parse-value (name) - (goto-char (point-min)) - (re-search-forward (concat "" - (regexp-quote name) - " *= * *\\([^ <][^<]*\\) *")) - (buffer-substring (match-beginning 1) (match-end 1))) - -(defun gnus-picons-parse-filenames () - ;; returns an alist of ((USER ADDRS DB) . URL) - (let* ((case-fold-search t) - (user (gnus-picons-parse-value "user")) - (host (gnus-picons-parse-value "host")) - (dbs (message-tokenize-header (gnus-picons-parse-value "db") " ")) - (start-re - (concat - ;; dbs - "^\\(" (mapconcat 'identity dbs "\\|") "\\)/" - ;; host - "\\(\\(" (replace-in-string host "\\." "/\\|" t) "/\\|MISC/\\)*\\)" - ;; user - "\\(" (regexp-quote user) "\\|unknown\\)/" - "face\\.")) - cur-db cur-host cur-user types res) - ;; now point will be somewhere in the header. Find beginning of - ;; entries - (re-search-forward "

[ \t\n]*") - (while (re-search-forward start-re nil t) - (setq cur-db (buffer-substring (match-beginning 1) (match-end 1)) - cur-host (buffer-substring (match-beginning 2) (match-end 2)) - cur-user (buffer-substring (match-beginning 4) (match-end 4)) - cur-host (nreverse (message-tokenize-header cur-host "/"))) - ;; XXX - KLUDGE: there is a blank picon in news/MISC/unknown - (unless (and (string-equal cur-db "news") - (string-equal cur-user "unknown") - (equal cur-host '("MISC"))) - ;; ok now we have found an entry (USER HOST DB), find the - ;; corresponding picon URL - (save-restriction - ;; restrict region to this entry - (narrow-to-region (point) (search-forward "
")) - (goto-char (point-min)) - (setq types gnus-picons-file-suffixes) - (while (and types - (not (re-search-forward - (concat " -;; Keywords: news - -;; This file is part of GNU Emacs. - -;; GNU Emacs is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 2, or (at your option) -;; any later version. - -;; GNU Emacs is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs; see the file COPYING. If not, write to the -;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. - -;;; Commentary: - -;;; Code: - -(eval-when-compile (require 'cl)) - -;;; List and range functions - -(defun gnus-last-element (list) - "Return last element of LIST." - (while (cdr list) - (setq list (cdr list))) - (car list)) - -(defun gnus-copy-sequence (list) - "Do a complete, total copy of a list." - (let (out) - (while (consp list) - (if (consp (car list)) - (push (gnus-copy-sequence (pop list)) out) - (push (pop list) out))) - (if list - (nconc (nreverse out) list) - (nreverse out)))) - -(defun gnus-set-difference (list1 list2) - "Return a list of elements of LIST1 that do not appear in LIST2." - (let ((list1 (copy-sequence list1))) - (while list2 - (setq list1 (delq (car list2) list1)) - (setq list2 (cdr list2))) - list1)) - -(defun gnus-sorted-complement (list1 list2) - "Return a list of elements that are in LIST1 or LIST2 but not both. -Both lists have to be sorted over <." - (let (out) - (if (or (null list1) (null list2)) - (or list1 list2) - (while (and list1 list2) - (cond ((= (car list1) (car list2)) - (setq list1 (cdr list1) - list2 (cdr list2))) - ((< (car list1) (car list2)) - (setq out (cons (car list1) out)) - (setq list1 (cdr list1))) - (t - (setq out (cons (car list2) out)) - (setq list2 (cdr list2))))) - (nconc (nreverse out) (or list1 list2))))) - -(defun gnus-intersection (list1 list2) - (let ((result nil)) - (while list2 - (when (memq (car list2) list1) - (setq result (cons (car list2) result))) - (setq list2 (cdr list2))) - result)) - -(defun gnus-sorted-intersection (list1 list2) - ;; LIST1 and LIST2 have to be sorted over <. - (let (out) - (while (and list1 list2) - (cond ((= (car list1) (car list2)) - (setq out (cons (car list1) out) - list1 (cdr list1) - list2 (cdr list2))) - ((< (car list1) (car list2)) - (setq list1 (cdr list1))) - (t - (setq list2 (cdr list2))))) - (nreverse out))) - -(defun gnus-set-sorted-intersection (list1 list2) - ;; LIST1 and LIST2 have to be sorted over <. - ;; This function modifies LIST1. - (let* ((top (cons nil list1)) - (prev top)) - (while (and list1 list2) - (cond ((= (car list1) (car list2)) - (setq prev list1 - list1 (cdr list1) - list2 (cdr list2))) - ((< (car list1) (car list2)) - (setcdr prev (cdr list1)) - (setq list1 (cdr list1))) - (t - (setq list2 (cdr list2))))) - (setcdr prev nil) - (cdr top))) - -(defun gnus-compress-sequence (numbers &optional always-list) - "Convert list of numbers to a list of ranges or a single range. -If ALWAYS-LIST is non-nil, this function will always release a list of -ranges." - (let* ((first (car numbers)) - (last (car numbers)) - result) - (if (null numbers) - nil - (if (not (listp (cdr numbers))) - numbers - (while numbers - (cond ((= last (car numbers)) nil) ;Omit duplicated number - ((= (1+ last) (car numbers)) ;Still in sequence - (setq last (car numbers))) - (t ;End of one sequence - (setq result - (cons (if (= first last) first - (cons first last)) - result)) - (setq first (car numbers)) - (setq last (car numbers)))) - (setq numbers (cdr numbers))) - (if (and (not always-list) (null result)) - (if (= first last) (list first) (cons first last)) - (nreverse (cons (if (= first last) first (cons first last)) - result))))))) - -(defalias 'gnus-uncompress-sequence 'gnus-uncompress-range) -(defun gnus-uncompress-range (ranges) - "Expand a list of ranges into a list of numbers. -RANGES is either a single range on the form `(num . num)' or a list of -these ranges." - (let (first last result) - (cond - ((null ranges) - nil) - ((not (listp (cdr ranges))) - (setq first (car ranges)) - (setq last (cdr ranges)) - (while (<= first last) - (setq result (cons first result)) - (setq first (1+ first))) - (nreverse result)) - (t - (while ranges - (if (atom (car ranges)) - (when (numberp (car ranges)) - (setq result (cons (car ranges) result))) - (setq first (caar ranges)) - (setq last (cdar ranges)) - (while (<= first last) - (setq result (cons first result)) - (setq first (1+ first)))) - (setq ranges (cdr ranges))) - (nreverse result))))) - -(defun gnus-add-to-range (ranges list) - "Return a list of ranges that has all articles from both RANGES and LIST. -Note: LIST has to be sorted over `<'." - (if (not ranges) - (gnus-compress-sequence list t) - (setq list (copy-sequence list)) - (unless (listp (cdr ranges)) - (setq ranges (list ranges))) - (let ((out ranges) - ilist lowest highest temp) - (while (and ranges list) - (setq ilist list) - (setq lowest (or (and (atom (car ranges)) (car ranges)) - (caar ranges))) - (while (and list (cdr list) (< (cadr list) lowest)) - (setq list (cdr list))) - (when (< (car ilist) lowest) - (setq temp list) - (setq list (cdr list)) - (setcdr temp nil) - (setq out (nconc (gnus-compress-sequence ilist t) out))) - (setq highest (or (and (atom (car ranges)) (car ranges)) - (cdar ranges))) - (while (and list (<= (car list) highest)) - (setq list (cdr list))) - (setq ranges (cdr ranges))) - (when list - (setq out (nconc (gnus-compress-sequence list t) out))) - (setq out (sort out (lambda (r1 r2) - (< (or (and (atom r1) r1) (car r1)) - (or (and (atom r2) r2) (car r2)))))) - (setq ranges out) - (while ranges - (if (atom (car ranges)) - (when (cdr ranges) - (if (atom (cadr ranges)) - (when (= (1+ (car ranges)) (cadr ranges)) - (setcar ranges (cons (car ranges) - (cadr ranges))) - (setcdr ranges (cddr ranges))) - (when (= (1+ (car ranges)) (caadr ranges)) - (setcar (cadr ranges) (car ranges)) - (setcar ranges (cadr ranges)) - (setcdr ranges (cddr ranges))))) - (when (cdr ranges) - (if (atom (cadr ranges)) - (when (= (1+ (cdar ranges)) (cadr ranges)) - (setcdr (car ranges) (cadr ranges)) - (setcdr ranges (cddr ranges))) - (when (= (1+ (cdar ranges)) (caadr ranges)) - (setcdr (car ranges) (cdadr ranges)) - (setcdr ranges (cddr ranges)))))) - (setq ranges (cdr ranges))) - out))) - -(defun gnus-remove-from-range (ranges list) - "Return a list of ranges that has all articles from LIST removed from RANGES. -Note: LIST has to be sorted over `<'." - ;; !!! This function shouldn't look like this, but I've got a headache. - (gnus-compress-sequence - (gnus-sorted-complement - (gnus-uncompress-range ranges) list))) - -(defun gnus-member-of-range (number ranges) - (if (not (listp (cdr ranges))) - (and (>= number (car ranges)) - (<= number (cdr ranges))) - (let ((not-stop t)) - (while (and ranges - (if (numberp (car ranges)) - (>= number (car ranges)) - (>= number (caar ranges))) - not-stop) - (when (if (numberp (car ranges)) - (= number (car ranges)) - (and (>= number (caar ranges)) - (<= number (cdar ranges)))) - (setq not-stop nil)) - (setq ranges (cdr ranges))) - (not not-stop)))) - -(defun gnus-range-length (range) - "Return the length RANGE would have if uncompressed." - (length (gnus-uncompress-range range))) - -(defun gnus-sublist-p (list sublist) - "Test whether all elements in SUBLIST are members of LIST." - (let ((sublistp t)) - (while sublist - (unless (memq (pop sublist) list) - (setq sublistp nil - sublist nil))) - sublistp)) - -(defun gnus-range-add (range1 range2) - "Add RANGE2 to RANGE1 destructively." - (cond - ;; If either are nil, then the job is quite easy. - ((or (null range1) (null range2)) - (or range1 range2)) - (t - ;; I don't like thinking. - (gnus-compress-sequence - (sort - (nconc - (gnus-uncompress-range range1) - (gnus-uncompress-range range2)) - '<))))) - -(provide 'gnus-range) - -;;; gnus-range.el ends here diff --git a/lisp/gnus-salt.el b/lisp/gnus-salt.el deleted file mode 100644 index e98762e..0000000 --- a/lisp/gnus-salt.el +++ /dev/null @@ -1,1028 +0,0 @@ -;;; gnus-salt.el --- alternate summary mode interfaces for Gnus -;; Copyright (C) 1996,97,98 Free Software Foundation, Inc. - -;; Author: Lars Magne Ingebrigtsen -;; Keywords: news - -;; This file is part of GNU Emacs. - -;; GNU Emacs is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 2, or (at your option) -;; any later version. - -;; GNU Emacs is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs; see the file COPYING. If not, write to the -;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. - -;;; Commentary: - -;;; Code: - -(eval-when-compile (require 'cl)) - -(require 'gnus) -(require 'gnus-sum) - -;;; -;;; gnus-pick-mode -;;; - -(defvar gnus-pick-mode nil - "Minor mode for providing a pick-and-read interface in Gnus summary buffers.") - -(defcustom gnus-pick-display-summary nil - "*Display summary while reading." - :type 'boolean - :group 'gnus-summary-pick) - -(defcustom gnus-pick-mode-hook nil - "Hook run in summary pick mode buffers." - :type 'hook - :group 'gnus-summary-pick) - -(defcustom gnus-mark-unpicked-articles-as-read nil - "*If non-nil, mark all unpicked articles as read." - :type 'boolean - :group 'gnus-summary-pick) - -(defcustom gnus-pick-elegant-flow t - "If non-nil, gnus-pick-start-reading will run gnus-summary-next-group when no articles have been picked." - :type 'boolean - :group 'gnus-summary-pick) - -(defcustom gnus-summary-pick-line-format - "%-5P %U\%R\%z\%I\%(%[%4L: %-20,20n%]%) %s\n" - "*The format specification of the lines in pick buffers. -It accepts the same format specs that `gnus-summary-line-format' does." - :type 'string - :group 'gnus-summary-pick) - -;;; Internal variables. - -(defvar gnus-pick-mode-map nil) - -(unless gnus-pick-mode-map - (setq gnus-pick-mode-map (make-sparse-keymap)) - - (gnus-define-keys gnus-pick-mode-map - " " gnus-pick-next-page - "u" gnus-pick-unmark-article-or-thread - "." gnus-pick-article-or-thread - gnus-down-mouse-2 gnus-pick-mouse-pick-region - "\r" gnus-pick-start-reading - )) - -(defun gnus-pick-make-menu-bar () - (unless (boundp 'gnus-pick-menu) - (easy-menu-define - gnus-pick-menu gnus-pick-mode-map "" - '("Pick" - ("Pick" - ["Article" gnus-summary-mark-as-processable t] - ["Thread" gnus-uu-mark-thread t] - ["Region" gnus-uu-mark-region t] - ["Regexp" gnus-uu-mark-by-regexp t] - ["Buffer" gnus-uu-mark-buffer t]) - ("Unpick" - ["Article" gnus-summary-unmark-as-processable t] - ["Thread" gnus-uu-unmark-thread t] - ["Region" gnus-uu-unmark-region t] - ["Regexp" gnus-uu-unmark-by-regexp t] - ["Buffer" gnus-summary-unmark-all-processable t]) - ["Start reading" gnus-pick-start-reading t] - ["Switch pick mode off" gnus-pick-mode gnus-pick-mode])))) - -(defun gnus-pick-mode (&optional arg) - "Minor mode for providing a pick-and-read interface in Gnus summary buffers. - -\\{gnus-pick-mode-map}" - (interactive "P") - (when (eq major-mode 'gnus-summary-mode) - (if (not (set (make-local-variable 'gnus-pick-mode) - (if (null arg) (not gnus-pick-mode) - (> (prefix-numeric-value arg) 0)))) - (remove-hook 'gnus-message-setup-hook 'gnus-pick-setup-message) - ;; Make sure that we don't select any articles upon group entry. - (set (make-local-variable 'gnus-auto-select-first) nil) - ;; Change line format. - (setq gnus-summary-line-format gnus-summary-pick-line-format) - (setq gnus-summary-line-format-spec nil) - (gnus-update-format-specifications nil 'summary) - (gnus-update-summary-mark-positions) - (add-hook 'gnus-message-setup-hook 'gnus-pick-setup-message) - (set (make-local-variable 'gnus-summary-goto-unread) 'never) - ;; Set up the menu. - (when (gnus-visual-p 'pick-menu 'menu) - (gnus-pick-make-menu-bar)) - (gnus-add-minor-mode 'gnus-pick-mode " Pick" gnus-pick-mode-map) - (gnus-run-hooks 'gnus-pick-mode-hook)))) - -(defun gnus-pick-setup-message () - "Make Message do the right thing on exit." - (when (and (gnus-buffer-live-p gnus-summary-buffer) - (save-excursion - (set-buffer gnus-summary-buffer) - gnus-pick-mode)) - (message-add-action - '(gnus-configure-windows 'pick t) 'send 'exit 'postpone 'kill))) - -(defvar gnus-pick-line-number 1) -(defun gnus-pick-line-number () - "Return the current line number." - (if (bobp) - (setq gnus-pick-line-number 1) - (incf gnus-pick-line-number))) - -(defun gnus-pick-start-reading (&optional catch-up) - "Start reading the picked articles. -If given a prefix, mark all unpicked articles as read." - (interactive "P") - (if gnus-newsgroup-processable - (progn - (gnus-summary-limit-to-articles nil) - (when (or catch-up gnus-mark-unpicked-articles-as-read) - (gnus-summary-limit-mark-excluded-as-read)) - (gnus-summary-first-article) - (gnus-configure-windows - (if gnus-pick-display-summary 'article 'pick) t)) - (if gnus-pick-elegant-flow - (progn - (when (or catch-up gnus-mark-unpicked-articles-as-read) - (gnus-summary-catchup nil t)) - (if (gnus-group-quit-config gnus-newsgroup-name) - (gnus-summary-exit) - (gnus-summary-next-group))) - (error "No articles have been picked")))) - -(defun gnus-pick-goto-article (arg) - "Go to the article number indicated by ARG. If ARG is an invalid -article number, then stay on current line." - (let (pos) - (save-excursion - (goto-char (point-min)) - (when (zerop (forward-line (1- (prefix-numeric-value arg)))) - (setq pos (point)))) - (if (not pos) - (gnus-error 2 "No such line: %s" arg) - (goto-char pos)))) - -(defun gnus-pick-article (&optional arg) - "Pick the article on the current line. -If ARG, pick the article on that line instead." - (interactive "P") - (when arg - (gnus-pick-goto-article arg)) - (gnus-summary-mark-as-processable 1)) - -(defun gnus-pick-article-or-thread (&optional arg) - "If gnus-thread-hide-subtree is t, then pick the thread on the current line. -Otherwise pick the article on the current line. -If ARG, pick the article/thread on that line instead." - (interactive "P") - (when arg - (gnus-pick-goto-article arg)) - (if gnus-thread-hide-subtree - (gnus-uu-mark-thread) - (gnus-summary-mark-as-processable 1))) - -(defun gnus-pick-unmark-article-or-thread (&optional arg) - "If gnus-thread-hide-subtree is t, then unmark the thread on current line. -Otherwise unmark the article on current line. -If ARG, unmark thread/article on that line instead." - (interactive "P") - (when arg - (gnus-pick-goto-article arg)) - (if gnus-thread-hide-subtree - (gnus-uu-unmark-thread) - (gnus-summary-unmark-as-processable 1))) - -(defun gnus-pick-mouse-pick (e) - (interactive "e") - (mouse-set-point e) - (save-excursion - (gnus-summary-mark-as-processable 1))) - -(defun gnus-pick-mouse-pick-region (start-event) - "Pick articles that the mouse is dragged over. -This must be bound to a button-down mouse event." - (interactive "e") - (mouse-minibuffer-check start-event) - (let* ((echo-keystrokes 0) - (start-posn (event-start start-event)) - (start-point (posn-point start-posn)) - (start-line (1+ (count-lines 1 start-point))) - (start-window (posn-window start-posn)) - (bounds (gnus-window-edges start-window)) - (top (nth 1 bounds)) - (bottom (if (window-minibuffer-p start-window) - (nth 3 bounds) - ;; Don't count the mode line. - (1- (nth 3 bounds)))) - (click-count (1- (event-click-count start-event)))) - (setq mouse-selection-click-count click-count) - (setq mouse-selection-click-count-buffer (current-buffer)) - (mouse-set-point start-event) - ;; In case the down click is in the middle of some intangible text, - ;; use the end of that text, and put it in START-POINT. - (when (< (point) start-point) - (goto-char start-point)) - (gnus-pick-article) - (setq start-point (point)) - ;; end-of-range is used only in the single-click case. - ;; It is the place where the drag has reached so far - ;; (but not outside the window where the drag started). - (let (event end end-point (end-of-range (point))) - (track-mouse - (while (progn - (setq event (cdr (gnus-read-event-char))) - (or (mouse-movement-p event) - (eq (car-safe event) 'switch-frame))) - (if (eq (car-safe event) 'switch-frame) - nil - (setq end (event-end event) - end-point (posn-point end)) - - (cond - ;; Are we moving within the original window? - ((and (eq (posn-window end) start-window) - (integer-or-marker-p end-point)) - ;; Go to START-POINT first, so that when we move to END-POINT, - ;; if it's in the middle of intangible text, - ;; point jumps in the direction away from START-POINT. - (goto-char start-point) - (goto-char end-point) - (gnus-pick-article) - ;; In case the user moved his mouse really fast, pick - ;; articles on the line between this one and the last one. - (let* ((this-line (1+ (count-lines 1 end-point))) - (min-line (min this-line start-line)) - (max-line (max this-line start-line))) - (while (< min-line max-line) - (goto-line min-line) - (gnus-pick-article) - (setq min-line (1+ min-line))) - (setq start-line this-line)) - (when (zerop (% click-count 3)) - (setq end-of-range (point)))) - (t - (let ((mouse-row (cdr (cdr (mouse-position))))) - (cond - ((null mouse-row)) - ((< mouse-row top) - (mouse-scroll-subr start-window (- mouse-row top))) - ((>= mouse-row bottom) - (mouse-scroll-subr start-window - (1+ (- mouse-row bottom))))))))))) - (when (consp event) - (let ((fun (key-binding (vector (car event))))) - ;; Run the binding of the terminating up-event, if possible. - ;; In the case of a multiple click, it gives the wrong results, - ;; because it would fail to set up a region. - (when nil - ;; (and (= (mod mouse-selection-click-count 3) 0) (fboundp fun)) - ;; In this case, we can just let the up-event execute normally. - (let ((end (event-end event))) - ;; Set the position in the event before we replay it, - ;; because otherwise it may have a position in the wrong - ;; buffer. - (setcar (cdr end) end-of-range) - ;; Delete the overlay before calling the function, - ;; because delete-overlay increases buffer-modified-tick. - (push event unread-command-events)))))))) - -(defun gnus-pick-next-page () - "Go to the next page. If at the end of the buffer, start reading articles." - (interactive) - (let ((scroll-in-place nil)) - (condition-case nil - (scroll-up) - (end-of-buffer (gnus-pick-start-reading))))) - -;;; -;;; gnus-binary-mode -;;; - -(defvar gnus-binary-mode nil - "Minor mode for providing a binary group interface in Gnus summary buffers.") - -(defvar gnus-binary-mode-hook nil - "Hook run in summary binary mode buffers.") - -(defvar gnus-binary-mode-map nil) - -(unless gnus-binary-mode-map - (setq gnus-binary-mode-map (make-sparse-keymap)) - - (gnus-define-keys - gnus-binary-mode-map - "g" gnus-binary-show-article)) - -(defun gnus-binary-make-menu-bar () - (unless (boundp 'gnus-binary-menu) - (easy-menu-define - gnus-binary-menu gnus-binary-mode-map "" - '("Pick" - ["Switch binary mode off" gnus-binary-mode t])))) - -(defun gnus-binary-mode (&optional arg) - "Minor mode for providing a binary group interface in Gnus summary buffers." - (interactive "P") - (when (eq major-mode 'gnus-summary-mode) - (make-local-variable 'gnus-binary-mode) - (setq gnus-binary-mode - (if (null arg) (not gnus-binary-mode) - (> (prefix-numeric-value arg) 0))) - (when gnus-binary-mode - ;; Make sure that we don't select any articles upon group entry. - (make-local-variable 'gnus-auto-select-first) - (setq gnus-auto-select-first nil) - (make-local-variable 'gnus-summary-display-article-function) - (setq gnus-summary-display-article-function 'gnus-binary-display-article) - ;; Set up the menu. - (when (gnus-visual-p 'binary-menu 'menu) - (gnus-binary-make-menu-bar)) - (gnus-add-minor-mode 'gnus-binary-mode " Binary" gnus-binary-mode-map) - (gnus-run-hooks 'gnus-binary-mode-hook)))) - -(defun gnus-binary-display-article (article &optional all-header) - "Run ARTICLE through the binary decode functions." - (when (gnus-summary-goto-subject article) - (let ((gnus-view-pseudos 'automatic)) - (gnus-uu-decode-uu)))) - -(defun gnus-binary-show-article (&optional arg) - "Bypass the binary functions and show the article." - (interactive "P") - (let (gnus-summary-display-article-function) - (gnus-summary-show-article arg))) - -;;; -;;; gnus-tree-mode -;;; - -(defcustom gnus-tree-line-format "%(%[%3,3n%]%)" - "Format of tree elements." - :type 'string - :group 'gnus-summary-tree) - -(defcustom gnus-tree-minimize-window t - "If non-nil, minimize the tree buffer window. -If a number, never let the tree buffer grow taller than that number of -lines." - :type '(choice boolean - integer) - :group 'gnus-summary-tree) - -(defcustom gnus-selected-tree-face 'modeline - "*Face used for highlighting selected articles in the thread tree." - :type 'face - :group 'gnus-summary-tree) - -(defvar gnus-tree-brackets '((?\[ . ?\]) (?\( . ?\)) - (?\{ . ?\}) (?< . ?>)) - "Brackets used in tree nodes.") - -(defvar gnus-tree-parent-child-edges '(?- ?\\ ?|) - "Characters used to connect parents with children.") - -(defcustom gnus-tree-mode-line-format "Gnus: %%b %S %Z" - "*The format specification for the tree mode line." - :type 'string - :group 'gnus-summary-tree) - -(defcustom gnus-generate-tree-function 'gnus-generate-vertical-tree - "*Function for generating a thread tree. -Two predefined functions are available: -`gnus-generate-horizontal-tree' and `gnus-generate-vertical-tree'." - :type '(radio (function-item gnus-generate-vertical-tree) - (function-item gnus-generate-horizontal-tree) - (function :tag "Other" nil)) - :group 'gnus-summary-tree) - -(defcustom gnus-tree-mode-hook nil - "*Hook run in tree mode buffers." - :type 'hook - :group 'gnus-summary-tree) - -;;; Internal variables. - -(defvar gnus-tree-line-format-alist - `((?n gnus-tmp-name ?s) - (?f gnus-tmp-from ?s) - (?N gnus-tmp-number ?d) - (?\[ gnus-tmp-open-bracket ?c) - (?\] gnus-tmp-close-bracket ?c) - (?s gnus-tmp-subject ?s))) - -(defvar gnus-tree-mode-line-format-alist gnus-summary-mode-line-format-alist) - -(defvar gnus-tree-mode-line-format-spec nil) -(defvar gnus-tree-line-format-spec nil) - -(defvar gnus-tree-node-length nil) -(defvar gnus-selected-tree-overlay nil) - -(defvar gnus-tree-displayed-thread nil) - -(defvar gnus-tree-mode-map nil) -(put 'gnus-tree-mode 'mode-class 'special) - -(unless gnus-tree-mode-map - (setq gnus-tree-mode-map (make-keymap)) - (suppress-keymap gnus-tree-mode-map) - (gnus-define-keys - gnus-tree-mode-map - "\r" gnus-tree-select-article - gnus-mouse-2 gnus-tree-pick-article - "\C-?" gnus-tree-read-summary-keys - "h" gnus-tree-show-summary - - "\C-c\C-i" gnus-info-find-node) - - (substitute-key-definition - 'undefined 'gnus-tree-read-summary-keys gnus-tree-mode-map)) - -(defun gnus-tree-make-menu-bar () - (unless (boundp 'gnus-tree-menu) - (easy-menu-define - gnus-tree-menu gnus-tree-mode-map "" - '("Tree" - ["Select article" gnus-tree-select-article t])))) - -(defun gnus-tree-mode () - "Major mode for displaying thread trees." - (interactive) - (gnus-set-format 'tree-mode) - (gnus-set-format 'tree t) - (when (gnus-visual-p 'tree-menu 'menu) - (gnus-tree-make-menu-bar)) - (kill-all-local-variables) - (gnus-simplify-mode-line) - (setq mode-name "Tree") - (setq major-mode 'gnus-tree-mode) - (use-local-map gnus-tree-mode-map) - (buffer-disable-undo (current-buffer)) - (setq buffer-read-only t) - (setq truncate-lines t) - (save-excursion - (gnus-set-work-buffer) - (gnus-tree-node-insert (make-mail-header "") nil) - (setq gnus-tree-node-length (1- (point)))) - (gnus-run-hooks 'gnus-tree-mode-hook)) - -(defun gnus-tree-read-summary-keys (&optional arg) - "Read a summary buffer key sequence and execute it." - (interactive "P") - (let ((buf (current-buffer)) - win) - (set-buffer gnus-article-buffer) - (gnus-article-read-summary-keys arg nil t) - (when (setq win (get-buffer-window buf)) - (select-window win) - (when gnus-selected-tree-overlay - (goto-char (or (gnus-overlay-end gnus-selected-tree-overlay) 1))) - (gnus-tree-minimize)))) - -(defun gnus-tree-show-summary () - "Reconfigure windows to show summary buffer." - (interactive) - (if (not (gnus-buffer-live-p gnus-summary-buffer)) - (error "There is no summary buffer for this tree buffer") - (gnus-configure-windows 'article) - (gnus-summary-goto-subject gnus-current-article))) - -(defun gnus-tree-select-article (article) - "Select the article under point, if any." - (interactive (list (gnus-tree-article-number))) - (let ((buf (current-buffer))) - (when article - (save-excursion - (set-buffer gnus-summary-buffer) - (gnus-summary-goto-article article)) - (select-window (get-buffer-window buf))))) - -(defun gnus-tree-pick-article (e) - "Select the article under the mouse pointer." - (interactive "e") - (mouse-set-point e) - (gnus-tree-select-article (gnus-tree-article-number))) - -(defun gnus-tree-article-number () - (get-text-property (point) 'gnus-number)) - -(defun gnus-tree-article-region (article) - "Return a cons with BEG and END of the article region." - (let ((pos (text-property-any (point-min) (point-max) 'gnus-number article))) - (when pos - (cons pos (next-single-property-change pos 'gnus-number))))) - -(defun gnus-tree-goto-article (article) - (let ((pos (text-property-any (point-min) (point-max) 'gnus-number article))) - (when pos - (goto-char pos)))) - -(defun gnus-tree-recenter () - "Center point in the tree window." - (let ((selected (selected-window)) - (tree-window (get-buffer-window gnus-tree-buffer t))) - (when tree-window - (select-window tree-window) - (when gnus-selected-tree-overlay - (goto-char (or (gnus-overlay-end gnus-selected-tree-overlay) 1))) - (let* ((top (cond ((< (window-height) 4) 0) - ((< (window-height) 7) 1) - (t 2))) - (height (1- (window-height))) - (bottom (save-excursion (goto-char (point-max)) - (forward-line (- height)) - (point)))) - ;; Set the window start to either `bottom', which is the biggest - ;; possible valid number, or the second line from the top, - ;; whichever is the least. - (set-window-start - tree-window (min bottom (save-excursion - (forward-line (- top)) (point))))) - (select-window selected)))) - -(defun gnus-get-tree-buffer () - "Return the tree buffer properly initialized." - (save-excursion - (set-buffer (gnus-get-buffer-create gnus-tree-buffer)) - (unless (eq major-mode 'gnus-tree-mode) - (gnus-tree-mode)) - (current-buffer))) - -(defun gnus-tree-minimize () - (when (and gnus-tree-minimize-window - (not (one-window-p))) - (let ((windows 0) - tot-win-height) - (walk-windows (lambda (window) (incf windows))) - (setq tot-win-height - (- (frame-height) - (* window-min-height (1- windows)) - 2)) - (let* ((window-min-height 2) - (height (count-lines (point-min) (point-max))) - (min (max (1- window-min-height) height)) - (tot (if (numberp gnus-tree-minimize-window) - (min gnus-tree-minimize-window min) - min)) - (win (get-buffer-window (current-buffer))) - (wh (and win (1- (window-height win))))) - (setq tot (min tot tot-win-height)) - (when (and win - (not (eq tot wh))) - (let ((selected (selected-window))) - (when (ignore-errors (select-window win)) - (enlarge-window (- tot wh)) - (select-window selected)))))))) - -;;; Generating the tree. - -(defun gnus-tree-node-insert (header sparse &optional adopted) - (let* ((dummy (stringp header)) - (header (if (vectorp header) header - (progn - (setq header (make-mail-header "*****")) - (mail-header-set-number header 0) - (mail-header-set-lines header 0) - (mail-header-set-chars header 0) - header))) - (gnus-tmp-from (mail-header-from header)) - (gnus-tmp-subject (mail-header-subject header)) - (gnus-tmp-number (mail-header-number header)) - (gnus-tmp-name - (cond - ((string-match "(.+)" gnus-tmp-from) - (substring gnus-tmp-from - (1+ (match-beginning 0)) (1- (match-end 0)))) - ((string-match "<[^>]+> *$" gnus-tmp-from) - (let ((beg (match-beginning 0))) - (or (and (string-match "^\"[^\"]*\"" gnus-tmp-from) - (substring gnus-tmp-from (1+ (match-beginning 0)) - (1- (match-end 0)))) - (substring gnus-tmp-from 0 beg)))) - ((memq gnus-tmp-number sparse) - "***") - (t gnus-tmp-from))) - (gnus-tmp-open-bracket - (cond ((memq gnus-tmp-number sparse) - (caadr gnus-tree-brackets)) - (dummy (caaddr gnus-tree-brackets)) - (adopted (car (nth 3 gnus-tree-brackets))) - (t (caar gnus-tree-brackets)))) - (gnus-tmp-close-bracket - (cond ((memq gnus-tmp-number sparse) - (cdadr gnus-tree-brackets)) - (adopted (cdr (nth 3 gnus-tree-brackets))) - (dummy - (cdaddr gnus-tree-brackets)) - (t (cdar gnus-tree-brackets)))) - (buffer-read-only nil) - beg end) - (gnus-add-text-properties - (setq beg (point)) - (setq end (progn (eval gnus-tree-line-format-spec) (point))) - (list 'gnus-number gnus-tmp-number)) - (when (or t (gnus-visual-p 'tree-highlight 'highlight)) - (gnus-tree-highlight-node gnus-tmp-number beg end)))) - -(defun gnus-tree-highlight-node (article beg end) - "Highlight current line according to `gnus-summary-highlight'." - (let ((list gnus-summary-highlight) - face) - (save-excursion - (set-buffer gnus-summary-buffer) - (let* ((score (or (cdr (assq article gnus-newsgroup-scored)) - gnus-summary-default-score 0)) - (default gnus-summary-default-score) - (mark (or (gnus-summary-article-mark article) gnus-unread-mark))) - ;; Eval the cars of the lists until we find a match. - (while (and list - (not (eval (caar list)))) - (setq list (cdr list))))) - (unless (eq (setq face (cdar list)) (get-text-property beg 'face)) - (gnus-put-text-property-excluding-characters-with-faces - beg end 'face - (if (boundp face) (symbol-value face) face))))) - -(defun gnus-tree-indent (level) - (insert (make-string (1- (* (1+ gnus-tree-node-length) level)) ? ))) - -(defvar gnus-tmp-limit) -(defvar gnus-tmp-sparse) -(defvar gnus-tmp-indent) - -(defun gnus-generate-tree (thread) - "Generate a thread tree for THREAD." - (save-excursion - (set-buffer (gnus-get-tree-buffer)) - (let ((buffer-read-only nil) - (gnus-tmp-indent 0)) - (erase-buffer) - (funcall gnus-generate-tree-function thread 0) - (gnus-set-mode-line 'tree) - (goto-char (point-min)) - (gnus-tree-minimize) - (gnus-tree-recenter) - (let ((selected (selected-window))) - (when (get-buffer-window (set-buffer gnus-tree-buffer) t) - (select-window (get-buffer-window (set-buffer gnus-tree-buffer) t)) - (gnus-horizontal-recenter) - (select-window selected)))))) - -(defun gnus-generate-horizontal-tree (thread level &optional dummyp adopted) - "Generate a horizontal tree." - (let* ((dummy (stringp (car thread))) - (do (or dummy - (and (car thread) - (memq (mail-header-number (car thread)) - gnus-tmp-limit)))) - col beg) - (if (not do) - ;; We don't want this article. - (setq thread (cdr thread)) - (if (not (bolp)) - ;; Not the first article on the line, so we insert a "-". - (insert (car gnus-tree-parent-child-edges)) - ;; If the level isn't zero, then we insert some indentation. - (unless (zerop level) - (gnus-tree-indent level) - (insert (cadr gnus-tree-parent-child-edges)) - (setq col (- (setq beg (point)) (gnus-point-at-bol) 1)) - ;; Draw "|" lines upwards. - (while (progn - (forward-line -1) - (forward-char col) - (= (following-char) ? )) - (delete-char 1) - (insert (caddr gnus-tree-parent-child-edges))) - (goto-char beg))) - (setq dummyp nil) - ;; Insert the article node. - (gnus-tree-node-insert (pop thread) gnus-tmp-sparse adopted)) - (if (null thread) - ;; End of the thread, so we go to the next line. - (unless (bolp) - (insert "\n")) - ;; Recurse downwards in all children of this article. - (while thread - (gnus-generate-horizontal-tree - (pop thread) (if do (1+ level) level) - (or dummyp dummy) dummy))))) - -(defsubst gnus-tree-indent-vertical () - (let ((len (- (* (1+ gnus-tree-node-length) gnus-tmp-indent) - (- (point) (gnus-point-at-bol))))) - (when (> len 0) - (insert (make-string len ? ))))) - -(defsubst gnus-tree-forward-line (n) - (while (>= (decf n) 0) - (unless (zerop (forward-line 1)) - (end-of-line) - (insert "\n"))) - (end-of-line)) - -(defun gnus-generate-vertical-tree (thread level &optional dummyp adopted) - "Generate a vertical tree." - (let* ((dummy (stringp (car thread))) - (do (or dummy - (and (car thread) - (memq (mail-header-number (car thread)) - gnus-tmp-limit)))) - beg) - (if (not do) - ;; We don't want this article. - (setq thread (cdr thread)) - (if (not (save-excursion (beginning-of-line) (bobp))) - ;; Not the first article on the line, so we insert a "-". - (progn - (gnus-tree-indent-vertical) - (insert (make-string (/ gnus-tree-node-length 2) ? )) - (insert (caddr gnus-tree-parent-child-edges)) - (gnus-tree-forward-line 1)) - ;; If the level isn't zero, then we insert some indentation. - (unless (zerop gnus-tmp-indent) - (gnus-tree-forward-line (1- (* 2 level))) - (gnus-tree-indent-vertical) - (delete-char -1) - (insert (cadr gnus-tree-parent-child-edges)) - (setq beg (point)) - (forward-char -1) - ;; Draw "-" lines leftwards. - (while (and (> (point) 1) - (= (char-after (1- (point))) ? )) - (delete-char -1) - (insert (car gnus-tree-parent-child-edges)) - (forward-char -1)) - (goto-char beg) - (gnus-tree-forward-line 1))) - (setq dummyp nil) - ;; Insert the article node. - (gnus-tree-indent-vertical) - (gnus-tree-node-insert (pop thread) gnus-tmp-sparse adopted) - (gnus-tree-forward-line 1)) - (if (null thread) - ;; End of the thread, so we go to the next line. - (progn - (goto-char (point-min)) - (end-of-line) - (incf gnus-tmp-indent)) - ;; Recurse downwards in all children of this article. - (while thread - (gnus-generate-vertical-tree - (pop thread) (if do (1+ level) level) - (or dummyp dummy) dummy))))) - -;;; Interface functions. - -(defun gnus-possibly-generate-tree (article &optional force) - "Generate the thread tree for ARTICLE if it isn't displayed already." - (when (save-excursion - (set-buffer gnus-summary-buffer) - (and gnus-use-trees - gnus-show-threads - (vectorp (gnus-summary-article-header article)))) - (save-excursion - (let ((top (save-excursion - (set-buffer gnus-summary-buffer) - (gnus-cut-thread - (gnus-remove-thread - (mail-header-id - (gnus-summary-article-header article)) - t)))) - (gnus-tmp-limit gnus-newsgroup-limit) - (gnus-tmp-sparse gnus-newsgroup-sparse)) - (when (or force - (not (eq top gnus-tree-displayed-thread))) - (gnus-generate-tree top) - (setq gnus-tree-displayed-thread top)))))) - -(defun gnus-tree-open (group) - (gnus-get-tree-buffer)) - -(defun gnus-tree-close (group) - (gnus-kill-buffer gnus-tree-buffer)) - -(defun gnus-highlight-selected-tree (article) - "Highlight the selected article in the tree." - (let ((buf (current-buffer)) - region) - (set-buffer gnus-tree-buffer) - (when (setq region (gnus-tree-article-region article)) - (when (or (not gnus-selected-tree-overlay) - (gnus-extent-detached-p gnus-selected-tree-overlay)) - ;; Create a new overlay. - (gnus-overlay-put - (setq gnus-selected-tree-overlay (gnus-make-overlay 1 2)) - 'face gnus-selected-tree-face)) - ;; Move the overlay to the article. - (gnus-move-overlay - gnus-selected-tree-overlay (goto-char (car region)) (cdr region)) - (gnus-tree-minimize) - (gnus-tree-recenter) - (let ((selected (selected-window))) - (when (get-buffer-window (set-buffer gnus-tree-buffer) t) - (select-window (get-buffer-window (set-buffer gnus-tree-buffer) t)) - (gnus-horizontal-recenter) - (select-window selected)))) - ;; If we remove this save-excursion, it updates the wrong mode lines?!? - (save-excursion - (set-buffer gnus-tree-buffer) - (gnus-set-mode-line 'tree)) - (set-buffer buf))) - -(defun gnus-tree-highlight-article (article face) - (save-excursion - (set-buffer (gnus-get-tree-buffer)) - (let (region) - (when (setq region (gnus-tree-article-region article)) - (gnus-put-text-property (car region) (cdr region) 'face face) - (set-window-point - (get-buffer-window (current-buffer) t) (cdr region)))))) - -;;; -;;; gnus-carpal -;;; - -(defvar gnus-carpal-group-buffer-buttons - '(("next" . gnus-group-next-unread-group) - ("prev" . gnus-group-prev-unread-group) - ("read" . gnus-group-read-group) - ("select" . gnus-group-select-group) - ("catch-up" . gnus-group-catchup-current) - ("new-news" . gnus-group-get-new-news-this-group) - ("toggle-sub" . gnus-group-unsubscribe-current-group) - ("subscribe" . gnus-group-unsubscribe-group) - ("kill" . gnus-group-kill-group) - ("yank" . gnus-group-yank-group) - ("describe" . gnus-group-describe-group) - "list" - ("subscribed" . gnus-group-list-groups) - ("all" . gnus-group-list-all-groups) - ("killed" . gnus-group-list-killed) - ("zombies" . gnus-group-list-zombies) - ("matching" . gnus-group-list-matching) - ("post" . gnus-group-post-news) - ("mail" . gnus-group-mail) - ("rescan" . gnus-group-get-new-news) - ("browse-foreign" . gnus-group-browse-foreign) - ("exit" . gnus-group-exit))) - -(defvar gnus-carpal-summary-buffer-buttons - '("mark" - ("read" . gnus-summary-mark-as-read-forward) - ("tick" . gnus-summary-tick-article-forward) - ("clear" . gnus-summary-clear-mark-forward) - ("expirable" . gnus-summary-mark-as-expirable) - "move" - ("scroll" . gnus-summary-next-page) - ("next-unread" . gnus-summary-next-unread-article) - ("prev-unread" . gnus-summary-prev-unread-article) - ("first" . gnus-summary-first-unread-article) - ("best" . gnus-summary-best-unread-article) - "article" - ("headers" . gnus-summary-toggle-header) - ("uudecode" . gnus-uu-decode-uu) - ("enter-digest" . gnus-summary-enter-digest-group) - ("fetch-parent" . gnus-summary-refer-parent-article) - "mail" - ("move" . gnus-summary-move-article) - ("copy" . gnus-summary-copy-article) - ("respool" . gnus-summary-respool-article) - "threads" - ("lower" . gnus-summary-lower-thread) - ("kill" . gnus-summary-kill-thread) - "post" - ("post" . gnus-summary-post-news) - ("mail" . gnus-summary-mail) - ("followup" . gnus-summary-followup-with-original) - ("reply" . gnus-summary-reply-with-original) - ("cancel" . gnus-summary-cancel-article) - "misc" - ("exit" . gnus-summary-exit) - ("fed-up" . gnus-summary-catchup-and-goto-next-group))) - -(defvar gnus-carpal-server-buffer-buttons - '(("add" . gnus-server-add-server) - ("browse" . gnus-server-browse-server) - ("list" . gnus-server-list-servers) - ("kill" . gnus-server-kill-server) - ("yank" . gnus-server-yank-server) - ("copy" . gnus-server-copy-server) - ("exit" . gnus-server-exit))) - -(defvar gnus-carpal-browse-buffer-buttons - '(("subscribe" . gnus-browse-unsubscribe-current-group) - ("exit" . gnus-browse-exit))) - -(defvar gnus-carpal-group-buffer "*Carpal Group*") -(defvar gnus-carpal-summary-buffer "*Carpal Summary*") -(defvar gnus-carpal-server-buffer "*Carpal Server*") -(defvar gnus-carpal-browse-buffer "*Carpal Browse*") - -(defvar gnus-carpal-attached-buffer nil) - -(defvar gnus-carpal-mode-hook nil - "*Hook run in carpal mode buffers.") - -(defvar gnus-carpal-button-face 'bold - "*Face used on carpal buttons.") - -(defvar gnus-carpal-header-face 'bold-italic - "*Face used on carpal buffer headers.") - -(defvar gnus-carpal-mode-map nil) -(put 'gnus-carpal-mode 'mode-class 'special) - -(if gnus-carpal-mode-map - nil - (setq gnus-carpal-mode-map (make-keymap)) - (suppress-keymap gnus-carpal-mode-map) - (define-key gnus-carpal-mode-map " " 'gnus-carpal-select) - (define-key gnus-carpal-mode-map "\r" 'gnus-carpal-select) - (define-key gnus-carpal-mode-map gnus-mouse-2 'gnus-carpal-mouse-select)) - -(defun gnus-carpal-mode () - "Major mode for clicking buttons. - -All normal editing commands are switched off. -\\ -The following commands are available: - -\\{gnus-carpal-mode-map}" - (interactive) - (kill-all-local-variables) - (setq mode-line-modified (cdr gnus-mode-line-modified)) - (setq major-mode 'gnus-carpal-mode) - (setq mode-name "Gnus Carpal") - (setq mode-line-process nil) - (use-local-map gnus-carpal-mode-map) - (buffer-disable-undo (current-buffer)) - (setq buffer-read-only t) - (make-local-variable 'gnus-carpal-attached-buffer) - (gnus-run-hooks 'gnus-carpal-mode-hook)) - -(defun gnus-carpal-setup-buffer (type) - (let ((buffer (symbol-value (intern (format "gnus-carpal-%s-buffer" type))))) - (if (get-buffer buffer) - () - (save-excursion - (set-buffer (gnus-get-buffer-create buffer)) - (gnus-carpal-mode) - (setq gnus-carpal-attached-buffer - (intern (format "gnus-%s-buffer" type))) - (let ((buttons (symbol-value - (intern (format "gnus-carpal-%s-buffer-buttons" - type)))) - (buffer-read-only nil) - button) - (while buttons - (setq button (car buttons) - buttons (cdr buttons)) - (if (stringp button) - (gnus-set-text-properties - (point) - (prog2 (insert button) (point) (insert " ")) - (list 'face gnus-carpal-header-face)) - (gnus-set-text-properties - (point) - (prog2 (insert (car button)) (point) (insert " ")) - (list 'gnus-callback (cdr button) - 'face gnus-carpal-button-face - gnus-mouse-face-prop 'highlight)))) - (let ((fill-column (- (window-width) 2))) - (fill-region (point-min) (point-max))) - (set-window-point (get-buffer-window (current-buffer)) - (point-min))))))) - -(defun gnus-carpal-select () - "Select the button under point." - (interactive) - (let ((func (get-text-property (point) 'gnus-callback))) - (if (null func) - () - (pop-to-buffer (symbol-value gnus-carpal-attached-buffer)) - (call-interactively func)))) - -(defun gnus-carpal-mouse-select (event) - "Select the button under the mouse pointer." - (interactive "e") - (mouse-set-point event) - (gnus-carpal-select)) - -;;; Allow redefinition of functions. -(gnus-ems-redefine) - -(provide 'gnus-salt) - -;;; gnus-salt.el ends here diff --git a/lisp/gnus-score.el b/lisp/gnus-score.el deleted file mode 100644 index 76cc2a3..0000000 --- a/lisp/gnus-score.el +++ /dev/null @@ -1,2918 +0,0 @@ -;;; gnus-score.el --- scoring code for Gnus -;; Copyright (C) 1995,96,97,98 Free Software Foundation, Inc. - -;; Author: Per Abrahamsen -;; Lars Magne Ingebrigtsen -;; Keywords: news - -;; This file is part of GNU Emacs. - -;; GNU Emacs is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 2, or (at your option) -;; any later version. - -;; GNU Emacs is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs; see the file COPYING. If not, write to the -;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. - -;;; Commentary: - -;;; Code: - -(eval-when-compile (require 'cl)) - -(require 'gnus) -(require 'gnus-sum) -(require 'gnus-range) -(require 'message) -(require 'score-mode) - -(defcustom gnus-global-score-files nil - "List of global score files and directories. -Set this variable if you want to use people's score files. One entry -for each score file or each score file directory. Gnus will decide -by itself what score files are applicable to which group. - -Say you want to use the single score file -\"/ftp.gnus.org@ftp:/pub/larsi/ding/score/soc.motss.SCORE\" and all -score files in the \"/ftp.some-where:/pub/score\" directory. - - (setq gnus-global-score-files - '(\"/ftp.gnus.org:/pub/larsi/ding/score/soc.motss.SCORE\" - \"/ftp.some-where:/pub/score\"))" - :group 'gnus-score-files - :type '(repeat file)) - -(defcustom gnus-score-file-single-match-alist nil - "Alist mapping regexps to lists of score files. -Each element of this alist should be of the form - (\"REGEXP\" [ \"SCORE-FILE-1\" ] [ \"SCORE-FILE-2\" ] ... ) - -If the name of a group is matched by REGEXP, the corresponding scorefiles -will be used for that group. -The first match found is used, subsequent matching entries are ignored (to -use multiple matches, see gnus-score-file-multiple-match-alist). - -These score files are loaded in addition to any files returned by -gnus-score-find-score-files-function (which see)." - :group 'gnus-score-files - :type '(repeat (cons regexp (repeat file)))) - -(defcustom gnus-score-file-multiple-match-alist nil - "Alist mapping regexps to lists of score files. -Each element of this alist should be of the form - (\"REGEXP\" [ \"SCORE-FILE-1\" ] [ \"SCORE-FILE-2\" ] ... ) - -If the name of a group is matched by REGEXP, the corresponding scorefiles -will be used for that group. -If multiple REGEXPs match a group, the score files corresponding to each -match will be used (for only one match to be used, see -gnus-score-file-single-match-alist). - -These score files are loaded in addition to any files returned by -gnus-score-find-score-files-function (which see)." - :group 'gnus-score-files - :type '(repeat (cons regexp (repeat file)))) - -(defcustom gnus-score-file-suffix "SCORE" - "Suffix of the score files." - :group 'gnus-score-files - :type 'string) - -(defcustom gnus-adaptive-file-suffix "ADAPT" - "Suffix of the adaptive score files." - :group 'gnus-score-files - :group 'gnus-score-adapt - :type 'string) - -(defcustom gnus-score-find-score-files-function 'gnus-score-find-bnews - "Function used to find score files. -The function will be called with the group name as the argument, and -should return a list of score files to apply to that group. The score -files do not actually have to exist. - -Predefined values are: - -gnus-score-find-single: Only apply the group's own score file. -gnus-score-find-hierarchical: Also apply score files from parent groups. -gnus-score-find-bnews: Apply score files whose names matches. - -See the documentation to these functions for more information. - -This variable can also be a list of functions to be called. Each -function should either return a list of score files, or a list of -score alists. - -If functions other than these pre-defined functions are used, -the `a' symbolic prefix to the score commands will always use -\"all.SCORE\"." - :group 'gnus-score-files - :type '(radio (function-item gnus-score-find-single) - (function-item gnus-score-find-hierarchical) - (function-item gnus-score-find-bnews) - (function :tag "Other"))) - -(defcustom gnus-score-interactive-default-score 1000 - "*Scoring commands will raise/lower the score with this number as the default." - :group 'gnus-score-default - :type 'integer) - -(defcustom gnus-score-expiry-days 7 - "*Number of days before unused score file entries are expired. -If this variable is nil, no score file entries will be expired." - :group 'gnus-score-expire - :type '(choice (const :tag "never" nil) - number)) - -(defcustom gnus-update-score-entry-dates t - "*In non-nil, update matching score entry dates. -If this variable is nil, then score entries that provide matches -will be expired along with non-matching score entries." - :group 'gnus-score-expire - :type 'boolean) - -(defcustom gnus-orphan-score nil - "*All orphans get this score added. Set in the score file." - :group 'gnus-score-default - :type '(choice (const nil) - integer)) - -(defcustom gnus-decay-scores nil - "*If non-nil, decay non-permanent scores." - :group 'gnus-score-decay - :type 'boolean) - -(defcustom gnus-decay-score-function 'gnus-decay-score - "*Function called to decay a score. -It is called with one parameter -- the score to be decayed." - :group 'gnus-score-decay - :type '(radio (function-item gnus-decay-score) - (function :tag "Other"))) - -(defcustom gnus-score-decay-constant 3 - "*Decay all \"small\" scores with this amount." - :group 'gnus-score-decay - :type 'integer) - -(defcustom gnus-score-decay-scale .05 - "*Decay all \"big\" scores with this factor." - :group 'gnus-score-decay - :type 'number) - -(defcustom gnus-home-score-file nil - "Variable to control where interactive score entries are to go. -It can be: - - * A string - This file file will be used as the home score file. - - * A function - The result of this function will be used as the home score file. - The function will be passed the name of the group as its - parameter. - - * A list - The elements in this list can be: - - * `(regexp file-name ...)' - If the `regexp' matches the group name, the first `file-name' will - will be used as the home score file. (Multiple filenames are - allowed so that one may use gnus-score-file-single-match-alist to - set this variable.) - - * A function. - If the function returns non-nil, the result will be used - as the home score file. The function will be passed the - name of the group as its parameter. - - * A string. Use the string as the home score file. - - The list will be traversed from the beginning towards the end looking - for matches." - :group 'gnus-score-files - :type '(choice string - (repeat (choice string - (cons regexp (repeat file)) - (function :value fun))) - (function :value fun))) - -(defcustom gnus-home-adapt-file nil - "Variable to control where new adaptive score entries are to go. -This variable allows the same syntax as `gnus-home-score-file'." - :group 'gnus-score-adapt - :group 'gnus-score-files - :type '(choice string - (repeat (choice string - (cons regexp (repeat file)) - (function :value fun))) - (function :value fun))) - -(defcustom gnus-default-adaptive-score-alist - '((gnus-kill-file-mark) - (gnus-unread-mark) - (gnus-read-mark (from 3) (subject 30)) - (gnus-catchup-mark (subject -10)) - (gnus-killed-mark (from -1) (subject -20)) - (gnus-del-mark (from -2) (subject -15))) -"*Alist of marks and scores." -:group 'gnus-score-adapt -:type '(repeat (cons (symbol :tag "Mark") - (repeat (list (choice :tag "Header" - (const from) - (const subject) - (symbol :tag "other")) - (integer :tag "Score")))))) - -(defcustom gnus-ignored-adaptive-words nil - "List of words to be ignored when doing adaptive word scoring." - :group 'gnus-score-adapt - :type '(repeat string)) - -(defcustom gnus-default-ignored-adaptive-words - '("a" "i" "the" "to" "of" "and" "in" "is" "it" "for" "that" "if" "you" - "this" "be" "on" "with" "not" "have" "are" "or" "as" "from" "can" - "but" "by" "at" "an" "will" "no" "all" "was" "do" "there" "my" "one" - "so" "we" "they" "what" "would" "any" "which" "about" "get" "your" - "use" "some" "me" "then" "name" "like" "out" "when" "up" "time" - "other" "more" "only" "just" "end" "also" "know" "how" "new" "should" - "been" "than" "them" "he" "who" "make" "may" "people" "these" "now" - "their" "here" "into" "first" "could" "way" "had" "see" "work" "well" - "were" "two" "very" "where" "while" "us" "because" "good" "same" - "even" "much" "most" "many" "such" "long" "his" "over" "last" "since" - "right" "before" "our" "without" "too" "those" "why" "must" "part" - "being" "current" "back" "still" "go" "point" "value" "each" "did" - "both" "true" "off" "say" "another" "state" "might" "under" "start" - "try" "re") - "*Default list of words to be ignored when doing adaptive word scoring." - :group 'gnus-score-adapt - :type '(repeat string)) - -(defcustom gnus-default-adaptive-word-score-alist - `((,gnus-read-mark . 30) - (,gnus-catchup-mark . -10) - (,gnus-killed-mark . -20) - (,gnus-del-mark . -15)) -"*Alist of marks and scores." -:group 'gnus-score-adapt -:type '(repeat (cons (character :tag "Mark") - (integer :tag "Score")))) - -(defcustom gnus-adaptive-word-minimum nil - "If a number, this is the minimum score value that can be assigned to a word." - :group 'gnus-score-adapt - :type '(choice (const nil) integer)) - -(defcustom gnus-adaptive-word-no-group-words nil - "If t, don't adaptively score words included in the group name." - :group 'gnus-score-adapt - :type 'boolean) - -(defcustom gnus-score-mimic-keymap nil - "*Have the score entry functions pretend that they are a keymap." - :group 'gnus-score-default - :type 'boolean) - -(defcustom gnus-score-exact-adapt-limit 10 - "*Number that says how long a match has to be before using substring matching. -When doing adaptive scoring, one normally uses fuzzy or substring -matching. However, if the header one matches is short, the possibility -for false positives is great, so if the length of the match is less -than this variable, exact matching will be used. - -If this variable is nil, exact matching will always be used." - :group 'gnus-score-adapt - :type '(choice (const nil) integer)) - -(defcustom gnus-score-uncacheable-files "ADAPT$" - "All score files that match this regexp will not be cached." - :group 'gnus-score-adapt - :group 'gnus-score-files - :type 'regexp) - -(defcustom gnus-score-default-header nil - "Default header when entering new scores. - -Should be one of the following symbols. - - a: from - s: subject - b: body - h: head - i: message-id - t: references - x: xref - l: lines - d: date - f: followup - -If nil, the user will be asked for a header." - :group 'gnus-score-default - :type '(choice (const :tag "from" a) - (const :tag "subject" s) - (const :tag "body" b) - (const :tag "head" h) - (const :tag "message-id" i) - (const :tag "references" t) - (const :tag "xref" x) - (const :tag "lines" l) - (const :tag "date" d) - (const :tag "followup" f) - (const :tag "ask" nil))) - -(defcustom gnus-score-default-type nil - "Default match type when entering new scores. - -Should be one of the following symbols. - - s: substring - e: exact string - f: fuzzy string - r: regexp string - b: before date - a: after date - n: this date - <: less than number - >: greater than number - =: equal to number - -If nil, the user will be asked for a match type." - :group 'gnus-score-default - :type '(choice (const :tag "substring" s) - (const :tag "exact string" e) - (const :tag "fuzzy string" f) - (const :tag "regexp string" r) - (const :tag "before date" b) - (const :tag "after date" a) - (const :tag "this date" n) - (const :tag "less than number" <) - (const :tag "greater than number" >) - (const :tag "equal than number" =) - (const :tag "ask" nil))) - -(defcustom gnus-score-default-fold nil - "Use case folding for new score file entries iff not nil." - :group 'gnus-score-default - :type 'boolean) - -(defcustom gnus-score-default-duration nil - "Default duration of effect when entering new scores. - -Should be one of the following symbols. - - t: temporary - p: permanent - i: immediate - -If nil, the user will be asked for a duration." - :group 'gnus-score-default - :type '(choice (const :tag "temporary" t) - (const :tag "permanent" p) - (const :tag "immediate" i) - (const :tag "ask" nil))) - -(defcustom gnus-score-after-write-file-function nil - "Function called with the name of the score file just written to disk." - :group 'gnus-score-files - :type 'function) - -(defcustom gnus-score-thread-simplify nil - "If non-nil, subjects will simplified as in threading." - :group 'gnus-score-various - :type 'boolean) - - - -;; Internal variables. - -(defvar gnus-adaptive-word-syntax-table - (let ((table (copy-syntax-table (standard-syntax-table))) - (numbers '(?0 ?1 ?2 ?3 ?4 ?5 ?6 ?7 ?8 ?9))) - (while numbers - (modify-syntax-entry (pop numbers) " " table)) - (modify-syntax-entry ?' "w" table) - table) - "Syntax table used when doing adaptive word scoring.") - -(defvar gnus-scores-exclude-files nil) -(defvar gnus-internal-global-score-files nil) -(defvar gnus-score-file-list nil) - -(defvar gnus-short-name-score-file-cache nil) - -(defvar gnus-score-help-winconf nil) -(defvar gnus-adaptive-score-alist gnus-default-adaptive-score-alist) -(defvar gnus-adaptive-word-score-alist gnus-default-adaptive-word-score-alist) -(defvar gnus-score-trace nil) -(defvar gnus-score-edit-buffer nil) - -(defvar gnus-score-alist nil - "Alist containing score information. -The keys can be symbols or strings. The following symbols are defined. - -touched: If this alist has been modified. -mark: Automatically mark articles below this. -expunge: Automatically expunge articles below this. -files: List of other score files to load when loading this one. -eval: Sexp to be evaluated when the score file is loaded. - -String entries have the form (HEADER (MATCH TYPE SCORE DATE) ...) -where HEADER is the header being scored, MATCH is the string we are -looking for, TYPE is a flag indicating whether it should use regexp or -substring matching, SCORE is the score to add and DATE is the date -of the last successful match.") - -(defvar gnus-score-cache nil) -(defvar gnus-scores-articles nil) -(defvar gnus-score-index nil) - - -(defconst gnus-header-index - ;; Name to index alist. - '(("number" 1 gnus-score-integer) - ("subject" 8 gnus-score-string) - ("from" 9 gnus-score-string) - ("date" 10 gnus-score-date) - ("message-id" 11 gnus-score-string) - ("references" 12 gnus-score-string) - ("chars" 13 gnus-score-integer) - ("lines" 14 gnus-score-integer) - ("xref" 15 gnus-score-string) - ("head" -1 gnus-score-body) - ("body" -1 gnus-score-body) - ("all" -1 gnus-score-body) - ("followup" 9 gnus-score-followup) - ("thread" 12 gnus-score-thread))) - -;;; Summary mode score maps. - -(gnus-define-keys (gnus-summary-score-map "V" gnus-summary-mode-map) - "s" gnus-summary-set-score - "S" gnus-summary-current-score - "c" gnus-score-change-score-file - "C" gnus-score-customize - "m" gnus-score-set-mark-below - "x" gnus-score-set-expunge-below - "R" gnus-summary-rescore - "e" gnus-score-edit-current-scores - "f" gnus-score-edit-file - "F" gnus-score-flush-cache - "t" gnus-score-find-trace - "w" gnus-score-find-favourite-words) - -;; Summary score file commands - -;; Much modification of the kill (ahem, score) code and lots of the -;; functions are written by Per Abrahamsen . - -(defun gnus-summary-lower-score (&optional score symp) - "Make a score entry based on the current article. -The user will be prompted for header to score on, match type, -permanence, and the string to be used. The numerical prefix will be -used as score." - (interactive (gnus-interactive "P\ny")) - (gnus-summary-increase-score (- (gnus-score-default score)) symp)) - -(defun gnus-score-kill-help-buffer () - (when (get-buffer "*Score Help*") - (kill-buffer "*Score Help*") - (when gnus-score-help-winconf - (set-window-configuration gnus-score-help-winconf)))) - -(defun gnus-summary-increase-score (&optional score symp) - "Make a score entry based on the current article. -The user will be prompted for header to score on, match type, -permanence, and the string to be used. The numerical prefix will be -used as score." - (interactive (gnus-interactive "P\ny")) - (let* ((nscore (gnus-score-default score)) - (prefix (if (< nscore 0) ?L ?I)) - (increase (> nscore 0)) - (char-to-header - '((?a "from" nil nil string) - (?s "subject" nil nil string) - (?b "body" "" nil body-string) - (?h "head" "" nil body-string) - (?i "message-id" nil t string) - (?r "references" "message-id" nil string) - (?x "xref" nil nil string) - (?l "lines" nil nil number) - (?d "date" nil nil date) - (?f "followup" nil nil string) - (?t "thread" "message-id" nil string))) - (char-to-type - '((?s s "substring" string) - (?e e "exact string" string) - (?f f "fuzzy string" string) - (?r r "regexp string" string) - (?z s "substring" body-string) - (?p r "regexp string" body-string) - (?b before "before date" date) - (?a after "after date" date) - (?n at "this date" date) - (?< < "less than number" number) - (?> > "greater than number" number) - (?= = "equal to number" number))) - (current-score-file gnus-current-score-file) - (char-to-perm - (list (list ?t (current-time-string) "temporary") - '(?p perm "permanent") '(?i now "immediate"))) - (mimic gnus-score-mimic-keymap) - (hchar (and gnus-score-default-header - (aref (symbol-name gnus-score-default-header) 0))) - (tchar (and gnus-score-default-type - (aref (symbol-name gnus-score-default-type) 0))) - (pchar (and gnus-score-default-duration - (aref (symbol-name gnus-score-default-duration) 0))) - entry temporary type match) - - (unwind-protect - (progn - - ;; First we read the header to score. - (while (not hchar) - (if mimic - (progn - (sit-for 1) - (message "%c-" prefix)) - (message "%s header (%s?): " (if increase "Increase" "Lower") - (mapconcat (lambda (s) (char-to-string (car s))) - char-to-header ""))) - (setq hchar (read-char)) - (when (or (= hchar ??) (= hchar ?\C-h)) - (setq hchar nil) - (gnus-score-insert-help "Match on header" char-to-header 1))) - - (gnus-score-kill-help-buffer) - (unless (setq entry (assq (downcase hchar) char-to-header)) - (if mimic (error "%c %c" prefix hchar) - (error "Illegal header type"))) - - (when (/= (downcase hchar) hchar) - ;; This was a majuscule, so we end reading and set the defaults. - (if mimic (message "%c %c" prefix hchar) (message "")) - (setq tchar (or tchar ?s) - pchar (or pchar ?t))) - - (let ((legal-types - (delq nil - (mapcar (lambda (s) - (if (eq (nth 4 entry) - (nth 3 s)) - s nil)) - char-to-type)))) - ;; We continue reading - the type. - (while (not tchar) - (if mimic - (progn - (sit-for 1) (message "%c %c-" prefix hchar)) - (message "%s header '%s' with match type (%s?): " - (if increase "Increase" "Lower") - (nth 1 entry) - (mapconcat (lambda (s) (char-to-string (car s))) - legal-types ""))) - (setq tchar (read-char)) - (when (or (= tchar ??) (= tchar ?\C-h)) - (setq tchar nil) - (gnus-score-insert-help "Match type" legal-types 2))) - - (gnus-score-kill-help-buffer) - (unless (setq type (nth 1 (assq (downcase tchar) legal-types))) - (if mimic (error "%c %c" prefix hchar) - (error "Illegal match type")))) - - (when (/= (downcase tchar) tchar) - ;; It was a majuscule, so we end reading and use the default. - (if mimic (message "%c %c %c" prefix hchar tchar) - (message "")) - (setq pchar (or pchar ?t))) - - ;; We continue reading. - (while (not pchar) - (if mimic - (progn - (sit-for 1) (message "%c %c %c-" prefix hchar tchar)) - (message "%s permanence (%s?): " (if increase "Increase" "Lower") - (mapconcat (lambda (s) (char-to-string (car s))) - char-to-perm ""))) - (setq pchar (read-char)) - (when (or (= pchar ??) (= pchar ?\C-h)) - (setq pchar nil) - (gnus-score-insert-help "Match permanence" char-to-perm 2))) - - (gnus-score-kill-help-buffer) - (if mimic (message "%c %c %c" prefix hchar tchar pchar) - (message "")) - (unless (setq temporary (cadr (assq pchar char-to-perm))) - ;; Deal with der(r)ided superannuated paradigms. - (when (and (eq (1+ prefix) 77) - (eq (+ hchar 12) 109) - (eq tchar 114) - (eq (- pchar 4) 111)) - (error "You rang?")) - (if mimic - (error "%c %c %c %c" prefix hchar tchar pchar) - (error "Illegal match duration")))) - ;; Always kill the score help buffer. - (gnus-score-kill-help-buffer)) - - ;; We have all the data, so we enter this score. - (setq match (if (string= (nth 2 entry) "") "" - (gnus-summary-header (or (nth 2 entry) (nth 1 entry))))) - - ;; Modify the match, perhaps. - (cond - ((equal (nth 1 entry) "xref") - (when (string-match "^Xref: *" match) - (setq match (substring match (match-end 0)))) - (when (string-match "^[^:]* +" match) - (setq match (substring match (match-end 0)))))) - - (when (memq type '(r R regexp Regexp)) - (setq match (regexp-quote match))) - - ;; Change score file to the "all.SCORE" file. - (when (eq symp 'a) - (save-excursion - (set-buffer gnus-summary-buffer) - (gnus-score-load-file - ;; This is a kludge; yes... - (cond - ((eq gnus-score-find-score-files-function - 'gnus-score-find-hierarchical) - (gnus-score-file-name "")) - ((eq gnus-score-find-score-files-function 'gnus-score-find-single) - current-score-file) - (t - (gnus-score-file-name "all")))))) - - (gnus-summary-score-entry - (nth 1 entry) ; Header - match ; Match - type ; Type - (if (eq score 's) nil score) ; Score - (if (eq temporary 'perm) ; Temp - nil - temporary) - (not (nth 3 entry))) ; Prompt - - (when (eq symp 'a) - ;; We change the score file back to the previous one. - (save-excursion - (set-buffer gnus-summary-buffer) - (gnus-score-load-file current-score-file))))) - -(defun gnus-score-insert-help (string alist idx) - (setq gnus-score-help-winconf (current-window-configuration)) - (save-excursion - (set-buffer (gnus-get-buffer-create "*Score Help*")) - (buffer-disable-undo (current-buffer)) - (delete-windows-on (current-buffer)) - (erase-buffer) - (insert string ":\n\n") - (let ((max -1) - (list alist) - (i 0) - n width pad format) - ;; find the longest string to display - (while list - (setq n (length (nth idx (car list)))) - (unless (> max n) - (setq max n)) - (setq list (cdr list))) - (setq max (+ max 4)) ; %c, `:', SPACE, a SPACE at end - (setq n (/ (1- (window-width)) max)) ; items per line - (setq width (/ (1- (window-width)) n)) ; width of each item - ;; insert `n' items, each in a field of width `width' - (while alist - (if (< i n) - () - (setq i 0) - (delete-char -1) ; the `\n' takes a char - (insert "\n")) - (setq pad (- width 3)) - (setq format (concat "%c: %-" (int-to-string pad) "s")) - (insert (format format (caar alist) (nth idx (car alist)))) - (setq alist (cdr alist)) - (setq i (1+ i)))) - ;; display ourselves in a small window at the bottom - (gnus-appt-select-lowest-window) - (split-window) - (pop-to-buffer "*Score Help*") - (let ((window-min-height 1)) - (shrink-window-if-larger-than-buffer)) - (select-window (get-buffer-window gnus-summary-buffer)))) - -(defun gnus-summary-header (header &optional no-err) - ;; Return HEADER for current articles, or error. - (let ((article (gnus-summary-article-number)) - headers) - (if article - (if (and (setq headers (gnus-summary-article-header article)) - (vectorp headers)) - (aref headers (nth 1 (assoc header gnus-header-index))) - (if no-err - nil - (error "Pseudo-articles can't be scored"))) - (if no-err - (error "No article on current line") - nil)))) - -(defun gnus-newsgroup-score-alist () - (or - (let ((param-file (gnus-group-find-parameter - gnus-newsgroup-name 'score-file))) - (when param-file - (gnus-score-load param-file))) - (gnus-score-load - (gnus-score-file-name gnus-newsgroup-name))) - gnus-score-alist) - -(defsubst gnus-score-get (symbol &optional alist) - ;; Get SYMBOL's definition in ALIST. - (cdr (assoc symbol - (or alist - gnus-score-alist - (gnus-newsgroup-score-alist))))) - -(defun gnus-summary-score-entry (header match type score date - &optional prompt silent) - "Enter score file entry. -HEADER is the header being scored. -MATCH is the string we are looking for. -TYPE is the match type: substring, regexp, exact, fuzzy. -SCORE is the score to add. -DATE is the expire date, or nil for no expire, or 'now for immediate expire. -If optional argument `PROMPT' is non-nil, allow user to edit match. -If optional argument `SILENT' is nil, show effect of score entry." - ;; Regexp is the default type. - (when (eq type t) - (setq type 'r)) - ;; Simplify matches... - (cond ((or (eq type 'r) (eq type 's) (eq type nil)) - (setq match (if match (gnus-simplify-subject-re match) ""))) - ((eq type 'f) - (setq match (gnus-simplify-subject-fuzzy match)))) - (let ((score (gnus-score-default score)) - (header (format "%s" (downcase header))) - new) - (when prompt - (setq match (read-string - (format "Match %s on %s, %s: " - (cond ((eq date 'now) - "now") - ((stringp date) - "temp") - (t "permanent")) - header - (if (< score 0) "lower" "raise")) - (if (numberp match) - (int-to-string match) - match)))) - - ;; Get rid of string props. - (setq match (format "%s" match)) - - ;; If this is an integer comparison, we transform from string to int. - (when (eq (nth 2 (assoc header gnus-header-index)) 'gnus-score-integer) - (setq match (string-to-int match))) - - (unless (eq date 'now) - ;; Add the score entry to the score file. - (when (= score gnus-score-interactive-default-score) - (setq score nil)) - (let ((old (gnus-score-get header)) - elem) - (setq new - (cond - (type - (list match score - (and date (if (numberp date) date - (gnus-day-number date))) - type)) - (date (list match score (gnus-day-number date))) - (score (list match score)) - (t (list match)))) - ;; We see whether we can collapse some score entries. - ;; This isn't quite correct, because there may be more elements - ;; later on with the same key that have matching elems... Hm. - (if (and old - (setq elem (assoc match old)) - (eq (nth 3 elem) (nth 3 new)) - (or (and (numberp (nth 2 elem)) (numberp (nth 2 new))) - (and (not (nth 2 elem)) (not (nth 2 new))))) - ;; Yup, we just add this new score to the old elem. - (setcar (cdr elem) (+ (or (nth 1 elem) - gnus-score-interactive-default-score) - (or (nth 1 new) - gnus-score-interactive-default-score))) - ;; Nope, we have to add a new elem. - (gnus-score-set header (if old (cons new old) (list new)) nil t)) - (gnus-score-set 'touched '(t)))) - - ;; Score the current buffer. - (unless silent - (if (and (>= (nth 1 (assoc header gnus-header-index)) 0) - (eq (nth 2 (assoc header gnus-header-index)) - 'gnus-score-string)) - (gnus-summary-score-effect header match type score) - (gnus-summary-rescore))) - - ;; Return the new scoring rule. - new)) - -(defun gnus-summary-score-effect (header match type score) - "Simulate the effect of a score file entry. -HEADER is the header being scored. -MATCH is the string we are looking for. -TYPE is the score type. -SCORE is the score to add." - (interactive (list (completing-read "Header: " - gnus-header-index - (lambda (x) (fboundp (nth 2 x))) - t) - (read-string "Match: ") - (y-or-n-p "Use regexp match? ") - (prefix-numeric-value current-prefix-arg))) - (save-excursion - (unless (and (stringp match) (> (length match) 0)) - (error "No match")) - (goto-char (point-min)) - (let ((regexp (cond ((eq type 'f) - (gnus-simplify-subject-fuzzy match)) - ((eq type 'r) - match) - ((eq type 'e) - (concat "\\`" (regexp-quote match) "\\'")) - (t - (regexp-quote match))))) - (while (not (eobp)) - (let ((content (gnus-summary-header header 'noerr)) - (case-fold-search t)) - (and content - (when (if (eq type 'f) - (string-equal (gnus-simplify-subject-fuzzy content) - regexp) - (string-match regexp content)) - (gnus-summary-raise-score score)))) - (beginning-of-line 2)))) - (gnus-set-mode-line 'summary)) - -(defun gnus-summary-score-crossposting (score date) - ;; Enter score file entry for current crossposting. - ;; SCORE is the score to add. - ;; DATE is the expire date. - (let ((xref (gnus-summary-header "xref")) - (start 0) - group) - (unless xref - (error "This article is not crossposted")) - (while (string-match " \\([^ \t]+\\):" xref start) - (setq start (match-end 0)) - (when (not (string= - (setq group - (substring xref (match-beginning 1) (match-end 1))) - gnus-newsgroup-name)) - (gnus-summary-score-entry - "xref" (concat " " group ":") nil score date t))))) - - -;;; -;;; Gnus Score Files -;;; - -;; All score code written by Per Abrahamsen . - -;; Added by Per Abrahamsen . -(defun gnus-score-set-mark-below (score) - "Automatically mark articles with score below SCORE as read." - (interactive - (list (or (and current-prefix-arg (prefix-numeric-value current-prefix-arg)) - (string-to-int (read-string "Mark below: "))))) - (setq score (or score gnus-summary-default-score 0)) - (gnus-score-set 'mark (list score)) - (gnus-score-set 'touched '(t)) - (setq gnus-summary-mark-below score) - (gnus-score-update-lines)) - -(defun gnus-score-update-lines () - "Update all lines in the summary buffer." - (save-excursion - (goto-char (point-min)) - (while (not (eobp)) - (gnus-summary-update-line) - (forward-line 1)))) - -(defun gnus-score-update-all-lines () - "Update all lines in the summary buffer, even the hidden ones." - (save-excursion - (goto-char (point-min)) - (let (hidden) - (while (not (eobp)) - (when (gnus-summary-show-thread) - (push (point) hidden)) - (gnus-summary-update-line) - (forward-line 1)) - ;; Re-hide the hidden threads. - (while hidden - (goto-char (pop hidden)) - (gnus-summary-hide-thread))))) - -(defun gnus-score-set-expunge-below (score) - "Automatically expunge articles with score below SCORE." - (interactive - (list (or (and current-prefix-arg (prefix-numeric-value current-prefix-arg)) - (string-to-int (read-string "Set expunge below: "))))) - (setq score (or score gnus-summary-default-score 0)) - (gnus-score-set 'expunge (list score)) - (gnus-score-set 'touched '(t))) - -(defun gnus-score-followup-article (&optional score) - "Add SCORE to all followups to the article in the current buffer." - (interactive "P") - (setq score (gnus-score-default score)) - (when (gnus-buffer-live-p gnus-summary-buffer) - (save-excursion - (save-restriction - (message-narrow-to-headers) - (let ((id (mail-fetch-field "message-id"))) - (when id - (set-buffer gnus-summary-buffer) - (gnus-summary-score-entry - "references" (concat id "[ \t]*$") 'r - score (current-time-string) nil t))))))) - -(defun gnus-score-followup-thread (&optional score) - "Add SCORE to all later articles in the thread the current buffer is part of." - (interactive "P") - (setq score (gnus-score-default score)) - (when (gnus-buffer-live-p gnus-summary-buffer) - (save-excursion - (save-restriction - (goto-char (point-min)) - (let ((id (mail-fetch-field "message-id"))) - (when id - (set-buffer gnus-summary-buffer) - (gnus-summary-score-entry - "references" id 's - score (current-time-string)))))))) - -(defun gnus-score-set (symbol value &optional alist warn) - ;; Set SYMBOL to VALUE in ALIST. - (let* ((alist - (or alist - gnus-score-alist - (gnus-newsgroup-score-alist))) - (entry (assoc symbol alist))) - (cond ((gnus-score-get 'read-only alist) - ;; This is a read-only score file, so we do nothing. - (when warn - (gnus-message 4 "Note: read-only score file; entry discarded"))) - (entry - (setcdr entry value)) - ((null alist) - (error "Empty alist")) - (t - (setcdr alist - (cons (cons symbol value) (cdr alist))))))) - -(defun gnus-summary-raise-score (n) - "Raise the score of the current article by N." - (interactive "p") - (gnus-summary-set-score (+ (gnus-summary-article-score) - (or n gnus-score-interactive-default-score )))) - -(defun gnus-summary-set-score (n) - "Set the score of the current article to N." - (interactive "p") - (save-excursion - (gnus-summary-show-thread) - (let ((buffer-read-only nil)) - ;; Set score. - (gnus-summary-update-mark - (if (= n (or gnus-summary-default-score 0)) ? - (if (< n (or gnus-summary-default-score 0)) - gnus-score-below-mark gnus-score-over-mark)) - 'score)) - (let* ((article (gnus-summary-article-number)) - (score (assq article gnus-newsgroup-scored))) - (if score (setcdr score n) - (push (cons article n) gnus-newsgroup-scored))) - (gnus-summary-update-line))) - -(defun gnus-summary-current-score () - "Return the score of the current article." - (interactive) - (gnus-message 1 "%s" (gnus-summary-article-score))) - -(defun gnus-score-change-score-file (file) - "Change current score alist." - (interactive - (list (read-file-name "Change to score file: " gnus-kill-files-directory))) - (gnus-score-load-file file) - (gnus-set-mode-line 'summary)) - -(defvar gnus-score-edit-exit-function) -(defun gnus-score-edit-current-scores (file) - "Edit the current score alist." - (interactive (list gnus-current-score-file)) - (if (not gnus-current-score-file) - (error "No current score file") - (let ((winconf (current-window-configuration))) - (when (buffer-name gnus-summary-buffer) - (gnus-score-save)) - (gnus-make-directory (file-name-directory file)) - (setq gnus-score-edit-buffer (find-file-noselect file)) - (gnus-configure-windows 'edit-score) - (gnus-score-mode) - (setq gnus-score-edit-exit-function 'gnus-score-edit-done) - (make-local-variable 'gnus-prev-winconf) - (setq gnus-prev-winconf winconf)) - (gnus-message - 4 (substitute-command-keys - "\\\\[gnus-score-edit-exit] to save edits")))) - -(defun gnus-score-edit-file (file) - "Edit a score file." - (interactive - (list (read-file-name "Edit score file: " gnus-kill-files-directory))) - (gnus-make-directory (file-name-directory file)) - (when (buffer-name gnus-summary-buffer) - (gnus-score-save)) - (let ((winconf (current-window-configuration))) - (setq gnus-score-edit-buffer (find-file-noselect file)) - (gnus-configure-windows 'edit-score) - (gnus-score-mode) - (setq gnus-score-edit-exit-function 'gnus-score-edit-done) - (make-local-variable 'gnus-prev-winconf) - (setq gnus-prev-winconf winconf)) - (gnus-message - 4 (substitute-command-keys - "\\\\[gnus-score-edit-exit] to save edits"))) - -(defun gnus-score-load-file (file) - ;; Load score file FILE. Returns a list a retrieved score-alists. - (let* ((file (expand-file-name - (or (and (string-match - (concat "^" (regexp-quote - (expand-file-name - gnus-kill-files-directory))) - (expand-file-name file)) - file) - (concat (file-name-as-directory gnus-kill-files-directory) - file)))) - (cached (assoc file gnus-score-cache)) - (global (member file gnus-internal-global-score-files)) - lists alist) - (if cached - ;; The score file was already loaded. - (setq alist (cdr cached)) - ;; We load the score file. - (setq gnus-score-alist nil) - (setq alist (gnus-score-load-score-alist file)) - ;; We add '(touched) to the alist to signify that it hasn't been - ;; touched (yet). - (unless (assq 'touched alist) - (push (list 'touched nil) alist)) - ;; If it is a global score file, we make it read-only. - (and global - (not (assq 'read-only alist)) - (push (list 'read-only t) alist)) - (push (cons file alist) gnus-score-cache)) - (let ((a alist) - found) - (while a - ;; Downcase all header names. - (cond - ((stringp (caar a)) - (setcar (car a) (downcase (caar a))) - (setq found t)) - ;; Advanced scoring. - ((consp (caar a)) - (setq found t))) - (pop a)) - ;; If there are actual scores in the alist, we add it to the - ;; return value of this function. - (when found - (setq lists (list alist)))) - ;; Treat the other possible atoms in the score alist. - (let ((mark (car (gnus-score-get 'mark alist))) - (expunge (car (gnus-score-get 'expunge alist))) - (mark-and-expunge (car (gnus-score-get 'mark-and-expunge alist))) - (files (gnus-score-get 'files alist)) - (exclude-files (gnus-score-get 'exclude-files alist)) - (orphan (car (gnus-score-get 'orphan alist))) - (adapt (gnus-score-get 'adapt alist)) - (thread-mark-and-expunge - (car (gnus-score-get 'thread-mark-and-expunge alist))) - (adapt-file (car (gnus-score-get 'adapt-file alist))) - (local (gnus-score-get 'local alist)) - (decay (car (gnus-score-get 'decay alist))) - (eval (car (gnus-score-get 'eval alist)))) - ;; Perform possible decays. - (when (and gnus-decay-scores - (or cached (file-exists-p file)) - (or (not decay) - (gnus-decay-scores alist decay))) - (gnus-score-set 'touched '(t) alist) - (gnus-score-set 'decay (list (gnus-time-to-day (current-time))) alist)) - ;; We do not respect eval and files atoms from global score - ;; files. - (when (and files (not global)) - (setq lists (apply 'append lists - (mapcar (lambda (file) - (gnus-score-load-file file)) - (if adapt-file (cons adapt-file files) - files))))) - (when (and eval (not global)) - (eval eval)) - ;; We then expand any exclude-file directives. - (setq gnus-scores-exclude-files - (nconc - (apply - 'nconc - (mapcar - (lambda (sfile) - (list - (expand-file-name sfile (file-name-directory file)) - (expand-file-name sfile gnus-kill-files-directory))) - exclude-files)) - gnus-scores-exclude-files)) - (when local - (save-excursion - (set-buffer gnus-summary-buffer) - (while local - (and (consp (car local)) - (symbolp (caar local)) - (progn - (make-local-variable (caar local)) - (set (caar local) (nth 1 (car local))))) - (setq local (cdr local))))) - (when orphan - (setq gnus-orphan-score orphan)) - (setq gnus-adaptive-score-alist - (cond ((equal adapt '(t)) - (setq gnus-newsgroup-adaptive t) - gnus-default-adaptive-score-alist) - ((equal adapt '(ignore)) - (setq gnus-newsgroup-adaptive nil)) - ((consp adapt) - (setq gnus-newsgroup-adaptive t) - adapt) - (t - ;;(setq gnus-newsgroup-adaptive gnus-use-adaptive-scoring) - gnus-default-adaptive-score-alist))) - (setq gnus-thread-expunge-below - (or thread-mark-and-expunge gnus-thread-expunge-below)) - (setq gnus-summary-mark-below - (or mark mark-and-expunge gnus-summary-mark-below)) - (setq gnus-summary-expunge-below - (or expunge mark-and-expunge gnus-summary-expunge-below)) - (setq gnus-newsgroup-adaptive-score-file - (or adapt-file gnus-newsgroup-adaptive-score-file))) - (setq gnus-current-score-file file) - (setq gnus-score-alist alist) - lists)) - -(defun gnus-score-load (file) - ;; Load score FILE. - (let ((cache (assoc file gnus-score-cache))) - (if cache - (setq gnus-score-alist (cdr cache)) - (setq gnus-score-alist nil) - (gnus-score-load-score-alist file) - (unless gnus-score-alist - (setq gnus-score-alist (copy-alist '((touched nil))))) - (push (cons file gnus-score-alist) gnus-score-cache)))) - -(defun gnus-score-remove-from-cache (file) - (setq gnus-score-cache - (delq (assoc file gnus-score-cache) gnus-score-cache))) - -(defun gnus-score-load-score-alist (file) - "Read score FILE." - (let (alist) - (if (not (file-readable-p file)) - ;; Couldn't read file. - (setq gnus-score-alist nil) - ;; Read file. - (save-excursion - (gnus-set-work-buffer) - (insert-file-contents file) - (goto-char (point-min)) - ;; Only do the loading if the score file isn't empty. - (when (save-excursion (re-search-forward "[()0-9a-zA-Z]" nil t)) - (setq alist - (condition-case () - (read (current-buffer)) - (error - (gnus-error 3.2 "Problem with score file %s" file)))))) - (cond - ((and alist - (atom alist)) - ;; Bogus score file. - (error "Invalid syntax with score file %s" file)) - ((eq (car alist) 'setq) - ;; This is an old-style score file. - (setq gnus-score-alist (gnus-score-transform-old-to-new alist))) - (t - (setq gnus-score-alist alist))) - ;; Check the syntax of the score file. - (setq gnus-score-alist - (gnus-score-check-syntax gnus-score-alist file))))) - -(defun gnus-score-check-syntax (alist file) - "Check the syntax of the score ALIST." - (cond - ((null alist) - nil) - ((not (consp alist)) - (gnus-message 1 "Score file is not a list: %s" file) - (ding) - nil) - (t - (let ((a alist) - sr err s type) - (while (and a (not err)) - (setq - err - (cond - ((not (listp (car a))) - (format "Illegal score element %s in %s" (car a) file)) - ((stringp (caar a)) - (cond - ((not (listp (setq sr (cdar a)))) - (format "Illegal header match %s in %s" (nth 1 (car a)) file)) - (t - (setq type (caar a)) - (while (and sr (not err)) - (setq s (pop sr)) - (setq - err - (cond - ((if (member (downcase type) '("lines" "chars")) - (not (numberp (car s))) - (not (stringp (car s)))) - (format "Illegal match %s in %s" (car s) file)) - ((and (cadr s) (not (integerp (cadr s)))) - (format "Non-integer score %s in %s" (cadr s) file)) - ((and (caddr s) (not (integerp (caddr s)))) - (format "Non-integer date %s in %s" (caddr s) file)) - ((and (cadddr s) (not (symbolp (cadddr s)))) - (format "Non-symbol match type %s in %s" (cadddr s) file))))) - err))))) - (setq a (cdr a))) - (if err - (progn - (ding) - (gnus-message 3 err) - (sit-for 2) - nil) - alist))))) - -(defun gnus-score-transform-old-to-new (alist) - (let* ((alist (nth 2 alist)) - out entry) - (when (eq (car alist) 'quote) - (setq alist (nth 1 alist))) - (while alist - (setq entry (car alist)) - (if (stringp (car entry)) - (let ((scor (cdr entry))) - (push entry out) - (while scor - (setcar scor - (list (caar scor) (nth 2 (car scor)) - (and (nth 3 (car scor)) - (gnus-day-number (nth 3 (car scor)))) - (if (nth 1 (car scor)) 'r 's))) - (setq scor (cdr scor)))) - (push (if (not (listp (cdr entry))) - (list (car entry) (cdr entry)) - entry) - out)) - (setq alist (cdr alist))) - (cons (list 'touched t) (nreverse out)))) - -(defun gnus-score-save () - ;; Save all score information. - (let ((cache gnus-score-cache) - entry score file) - (save-excursion - (setq gnus-score-alist nil) - (nnheader-set-temp-buffer " *Gnus Scores*") - (while cache - (current-buffer) - (setq entry (pop cache) - file (car entry) - score (cdr entry)) - (if (or (not (equal (gnus-score-get 'touched score) '(t))) - (gnus-score-get 'read-only score) - (and (file-exists-p file) - (not (file-writable-p file)))) - () - (setq score (setcdr entry (gnus-delete-alist 'touched score))) - (erase-buffer) - (let (emacs-lisp-mode-hook) - (if (string-match - (concat (regexp-quote gnus-adaptive-file-suffix) "$") - file) - ;; This is an adaptive score file, so we do not run - ;; it through `pp'. These files can get huge, and - ;; are not meant to be edited by human hands. - (gnus-prin1 score) - ;; This is a normal score file, so we print it very - ;; prettily. - (let ((lisp-mode-syntax-table score-mode-syntax-table)) - (pp score (current-buffer))))) - (gnus-make-directory (file-name-directory file)) - ;; If the score file is empty, we delete it. - (if (zerop (buffer-size)) - (delete-file file) - ;; There are scores, so we write the file. - (when (file-writable-p file) - (gnus-write-buffer file) - (when gnus-score-after-write-file-function - (funcall gnus-score-after-write-file-function file))))) - (and gnus-score-uncacheable-files - (string-match gnus-score-uncacheable-files file) - (gnus-score-remove-from-cache file))) - (kill-buffer (current-buffer))))) - -(defun gnus-score-load-files (score-files) - "Load all score files in SCORE-FILES." - ;; Load the score files. - (let (scores) - (while score-files - (if (stringp (car score-files)) - ;; It is a string, which means that it's a score file name, - ;; so we load the score file and add the score alist to - ;; the list of alists. - (setq scores (nconc (gnus-score-load-file (car score-files)) scores)) - ;; It is an alist, so we just add it to the list directly. - (setq scores (nconc (car score-files) scores))) - (setq score-files (cdr score-files))) - ;; Prune the score files that are to be excluded, if any. - (when gnus-scores-exclude-files - (let ((s scores) - c) - (while s - (and (setq c (rassq (car s) gnus-score-cache)) - (member (car c) gnus-scores-exclude-files) - (setq scores (delq (car s) scores))) - (setq s (cdr s))))) - scores)) - -(defun gnus-score-headers (score-files &optional trace) - ;; Score `gnus-newsgroup-headers'. - (let (scores news) - ;; PLM: probably this is not the best place to clear orphan-score - (setq gnus-orphan-score nil - gnus-scores-articles nil - gnus-scores-exclude-files nil - scores (gnus-score-load-files score-files)) - (setq news scores) - ;; Do the scoring. - (while news - (setq scores news - news nil) - (when (and gnus-summary-default-score - scores) - (let* ((entries gnus-header-index) - (now (gnus-day-number (current-time-string))) - (expire (and gnus-score-expiry-days - (- now gnus-score-expiry-days))) - (headers gnus-newsgroup-headers) - (current-score-file gnus-current-score-file) - entry header new) - (gnus-message 5 "Scoring...") - ;; Create articles, an alist of the form `(HEADER . SCORE)'. - (while (setq header (pop headers)) - ;; WARNING: The assq makes the function O(N*S) while it could - ;; be written as O(N+S), where N is (length gnus-newsgroup-headers) - ;; and S is (length gnus-newsgroup-scored). - (unless (assq (mail-header-number header) gnus-newsgroup-scored) - (setq gnus-scores-articles ;Total of 2 * N cons-cells used. - (cons (cons header (or gnus-summary-default-score 0)) - gnus-scores-articles)))) - - (save-excursion - (set-buffer (gnus-get-buffer-create "*Headers*")) - (buffer-disable-undo (current-buffer)) - (when (gnus-buffer-live-p gnus-summary-buffer) - (message-clone-locals gnus-summary-buffer)) - - ;; Set the global variant of this variable. - (setq gnus-current-score-file current-score-file) - ;; score orphans - (when gnus-orphan-score - (setq gnus-score-index - (nth 1 (assoc "references" gnus-header-index))) - (gnus-score-orphans gnus-orphan-score)) - ;; Run each header through the score process. - (while entries - (setq entry (pop entries) - header (nth 0 entry) - gnus-score-index (nth 1 (assoc header gnus-header-index))) - (when (< 0 (apply 'max (mapcar - (lambda (score) - (length (gnus-score-get header score))) - scores))) - ;; Call the scoring function for this type of "header". - (when (setq new (funcall (nth 2 entry) scores header - now expire trace)) - (push new news)))) - ;; Remove the buffer. - (kill-buffer (current-buffer))) - - ;; Add articles to `gnus-newsgroup-scored'. - (while gnus-scores-articles - (when (or (/= gnus-summary-default-score - (cdar gnus-scores-articles)) - gnus-save-score) - (push (cons (mail-header-number (caar gnus-scores-articles)) - (cdar gnus-scores-articles)) - gnus-newsgroup-scored)) - (setq gnus-scores-articles (cdr gnus-scores-articles))) - - (let (score) - (while (setq score (pop scores)) - (while score - (when (listp (caar score)) - (gnus-score-advanced (car score) trace)) - (pop score)))) - - (gnus-message 5 "Scoring...done")))))) - - -(defun gnus-get-new-thread-ids (articles) - (let ((index (nth 1 (assoc "message-id" gnus-header-index))) - (refind gnus-score-index) - id-list art this tref) - (while articles - (setq art (car articles) - this (aref (car art) index) - tref (aref (car art) refind) - articles (cdr articles)) - (when (string-equal tref "") ;no references line - (push this id-list))) - id-list)) - -;; Orphan functions written by plm@atcmp.nl (Peter Mutsaers). -(defun gnus-score-orphans (score) - (let ((new-thread-ids (gnus-get-new-thread-ids gnus-scores-articles)) - alike articles art arts this last this-id) - - (setq gnus-scores-articles (sort gnus-scores-articles 'gnus-score-string<) - articles gnus-scores-articles) - - ;;more or less the same as in gnus-score-string - (erase-buffer) - (while articles - (setq art (car articles) - this (aref (car art) gnus-score-index) - articles (cdr articles)) - ;;completely skip if this is empty (not a child, so not an orphan) - (when (not (string= this "")) - (if (equal last this) - ;; O(N*H) cons-cells used here, where H is the number of - ;; headers. - (push art alike) - (when last - ;; Insert the line, with a text property on the - ;; terminating newline referring to the articles with - ;; this line. - (insert last ?\n) - (put-text-property (1- (point)) (point) 'articles alike)) - (setq alike (list art) - last this)))) - (when last ; Bwadr, duplicate code. - (insert last ?\n) - (put-text-property (1- (point)) (point) 'articles alike)) - - ;; PLM: now delete those lines that contain an entry from new-thread-ids - (while new-thread-ids - (setq this-id (car new-thread-ids) - new-thread-ids (cdr new-thread-ids)) - (goto-char (point-min)) - (while (search-forward this-id nil t) - ;; found a match. remove this line - (beginning-of-line) - (kill-line 1))) - - ;; now for each line: update its articles with score by moving to - ;; every end-of-line in the buffer and read the articles property - (goto-char (point-min)) - (while (eq 0 (progn - (end-of-line) - (setq arts (get-text-property (point) 'articles)) - (while arts - (setq art (car arts) - arts (cdr arts)) - (setcdr art (+ score (cdr art)))) - (forward-line)))))) - - -(defun gnus-score-integer (scores header now expire &optional trace) - (let ((gnus-score-index (nth 1 (assoc header gnus-header-index))) - entries alist) - - ;; Find matches. - (while scores - (setq alist (car scores) - scores (cdr scores) - entries (assoc header alist)) - (while (cdr entries) ;First entry is the header index. - (let* ((rest (cdr entries)) - (kill (car rest)) - (match (nth 0 kill)) - (type (or (nth 3 kill) '>)) - (score (or (nth 1 kill) gnus-score-interactive-default-score)) - (date (nth 2 kill)) - (found nil) - (match-func (if (or (eq type '>) (eq type '<) (eq type '<=) - (eq type '>=) (eq type '=)) - type - (error "Illegal match type: %s" type))) - (articles gnus-scores-articles)) - ;; Instead of doing all the clever stuff that - ;; `gnus-score-string' does to minimize searches and stuff, - ;; I will assume that people generally will put so few - ;; matches on numbers that any cleverness will take more - ;; time than one would gain. - (while articles - (when (funcall match-func - (or (aref (caar articles) gnus-score-index) 0) - match) - (when trace - (push (cons (car-safe (rassq alist gnus-score-cache)) kill) - gnus-score-trace)) - (setq found t) - (setcdr (car articles) (+ score (cdar articles)))) - (setq articles (cdr articles))) - ;; Update expire date - (cond ((null date)) ;Permanent entry. - ((and found gnus-update-score-entry-dates) ;Match, update date. - (gnus-score-set 'touched '(t) alist) - (setcar (nthcdr 2 kill) now)) - ((and expire (< date expire)) ;Old entry, remove. - (gnus-score-set 'touched '(t) alist) - (setcdr entries (cdr rest)) - (setq rest entries))) - (setq entries rest))))) - nil) - -(defun gnus-score-date (scores header now expire &optional trace) - (let ((gnus-score-index (nth 1 (assoc header gnus-header-index))) - entries alist match match-func article) - - ;; Find matches. - (while scores - (setq alist (car scores) - scores (cdr scores) - entries (assoc header alist)) - (while (cdr entries) ;First entry is the header index. - (let* ((rest (cdr entries)) - (kill (car rest)) - (type (or (nth 3 kill) 'before)) - (score (or (nth 1 kill) gnus-score-interactive-default-score)) - (date (nth 2 kill)) - (found nil) - (articles gnus-scores-articles) - l) - (cond - ((eq type 'after) - (setq match-func 'string< - match (gnus-date-iso8601 (nth 0 kill)))) - ((eq type 'before) - (setq match-func 'gnus-string> - match (gnus-date-iso8601 (nth 0 kill)))) - ((eq type 'at) - (setq match-func 'string= - match (gnus-date-iso8601 (nth 0 kill)))) - ((eq type 'regexp) - (setq match-func 'string-match - match (nth 0 kill))) - (t (error "Illegal match type: %s" type))) - ;; Instead of doing all the clever stuff that - ;; `gnus-score-string' does to minimize searches and stuff, - ;; I will assume that people generally will put so few - ;; matches on numbers that any cleverness will take more - ;; time than one would gain. - (while (setq article (pop articles)) - (when (and - (setq l (aref (car article) gnus-score-index)) - (funcall match-func match (gnus-date-iso8601 l))) - (when trace - (push (cons (car-safe (rassq alist gnus-score-cache)) kill) - gnus-score-trace)) - (setq found t) - (setcdr article (+ score (cdr article))))) - ;; Update expire date - (cond ((null date)) ;Permanent entry. - ((and found gnus-update-score-entry-dates) ;Match, update date. - (gnus-score-set 'touched '(t) alist) - (setcar (nthcdr 2 kill) now)) - ((and expire (< date expire)) ;Old entry, remove. - (gnus-score-set 'touched '(t) alist) - (setcdr entries (cdr rest)) - (setq rest entries))) - (setq entries rest))))) - nil) - -(defun gnus-score-body (scores header now expire &optional trace) - (save-excursion - (setq gnus-scores-articles - (sort gnus-scores-articles - (lambda (a1 a2) - (< (mail-header-number (car a1)) - (mail-header-number (car a2)))))) - (set-buffer nntp-server-buffer) - (save-restriction - (let* ((buffer-read-only nil) - (articles gnus-scores-articles) - (all-scores scores) - (request-func (cond ((string= "head" header) - 'gnus-request-head) - ((string= "body" header) - 'gnus-request-body) - (t 'gnus-request-article))) - entries alist ofunc article last) - (when articles - (setq last (mail-header-number (caar (last articles)))) - ;; Not all backends support partial fetching. In that case, - ;; we just fetch the entire article. - (unless (gnus-check-backend-function - (and (string-match "^gnus-" (symbol-name request-func)) - (intern (substring (symbol-name request-func) - (match-end 0)))) - gnus-newsgroup-name) - (setq ofunc request-func) - (setq request-func 'gnus-request-article)) - (while articles - (setq article (mail-header-number (caar articles))) - (gnus-message 7 "Scoring article %s of %s..." article last) - (when (funcall request-func article gnus-newsgroup-name) - (widen) - (goto-char (point-min)) - ;; If just parts of the article is to be searched, but the - ;; backend didn't support partial fetching, we just narrow - ;; to the relevant parts. - (when ofunc - (if (eq ofunc 'gnus-request-head) - (narrow-to-region - (point) - (or (search-forward "\n\n" nil t) (point-max))) - (narrow-to-region - (or (search-forward "\n\n" nil t) (point)) - (point-max)))) - (setq scores all-scores) - ;; Find matches. - (while scores - (setq alist (pop scores) - entries (assoc header alist)) - (while (cdr entries) ;First entry is the header index. - (let* ((rest (cdr entries)) - (kill (car rest)) - (match (nth 0 kill)) - (type (or (nth 3 kill) 's)) - (score (or (nth 1 kill) - gnus-score-interactive-default-score)) - (date (nth 2 kill)) - (found nil) - (case-fold-search - (not (or (eq type 'R) (eq type 'S) - (eq type 'Regexp) (eq type 'String)))) - (search-func - (cond ((or (eq type 'r) (eq type 'R) - (eq type 'regexp) (eq type 'Regexp)) - 're-search-forward) - ((or (eq type 's) (eq type 'S) - (eq type 'string) (eq type 'String)) - 'search-forward) - (t - (error "Illegal match type: %s" type))))) - (goto-char (point-min)) - (when (funcall search-func match nil t) - ;; Found a match, update scores. - (setcdr (car articles) (+ score (cdar articles))) - (setq found t) - (when trace - (push - (cons (car-safe (rassq alist gnus-score-cache)) kill) - gnus-score-trace))) - ;; Update expire date - (unless trace - (cond - ((null date)) ;Permanent entry. - ((and found gnus-update-score-entry-dates) - ;; Match, update date. - (gnus-score-set 'touched '(t) alist) - (setcar (nthcdr 2 kill) now)) - ((and expire (< date expire)) ;Old entry, remove. - (gnus-score-set 'touched '(t) alist) - (setcdr entries (cdr rest)) - (setq rest entries)))) - (setq entries rest))))) - (setq articles (cdr articles))))))) - nil) - -(defun gnus-score-thread (scores header now expire &optional trace) - (gnus-score-followup scores header now expire trace t)) - -(defun gnus-score-followup (scores header now expire &optional trace thread) - ;; Insert the unique article headers in the buffer. - (let ((gnus-score-index (nth 1 (assoc header gnus-header-index))) - (current-score-file gnus-current-score-file) - (all-scores scores) - ;; gnus-score-index is used as a free variable. - alike last this art entries alist articles - new news) - - ;; Change score file to the adaptive score file. All entries that - ;; this function makes will be put into this file. - (save-excursion - (set-buffer gnus-summary-buffer) - (gnus-score-load-file - (or gnus-newsgroup-adaptive-score-file - (gnus-score-file-name - gnus-newsgroup-name gnus-adaptive-file-suffix)))) - - (setq gnus-scores-articles (sort gnus-scores-articles 'gnus-score-string<) - articles gnus-scores-articles) - - (erase-buffer) - (while articles - (setq art (car articles) - this (aref (car art) gnus-score-index) - articles (cdr articles)) - (if (equal last this) - (push art alike) - (when last - (insert last ?\n) - (put-text-property (1- (point)) (point) 'articles alike)) - (setq alike (list art) - last this))) - (when last ; Bwadr, duplicate code. - (insert last ?\n) - (put-text-property (1- (point)) (point) 'articles alike)) - - ;; Find matches. - (while scores - (setq alist (car scores) - scores (cdr scores) - entries (assoc header alist)) - (while (cdr entries) ;First entry is the header index. - (let* ((rest (cdr entries)) - (kill (car rest)) - (match (nth 0 kill)) - (type (or (nth 3 kill) 's)) - (score (or (nth 1 kill) gnus-score-interactive-default-score)) - (date (nth 2 kill)) - (found nil) - (mt (aref (symbol-name type) 0)) - (case-fold-search - (not (or (= mt ?R) (= mt ?S) (= mt ?E) (= mt ?F)))) - (dmt (downcase mt)) - (search-func - (cond ((= dmt ?r) 're-search-forward) - ((or (= dmt ?e) (= dmt ?s) (= dmt ?f)) 'search-forward) - (t (error "Illegal match type: %s" type)))) - arts art) - (goto-char (point-min)) - (if (= dmt ?e) - (while (funcall search-func match nil t) - (and (= (progn (beginning-of-line) (point)) - (match-beginning 0)) - (= (progn (end-of-line) (point)) - (match-end 0)) - (progn - (setq found (setq arts (get-text-property - (point) 'articles))) - ;; Found a match, update scores. - (while arts - (setq art (car arts) - arts (cdr arts)) - (gnus-score-add-followups - (car art) score all-scores thread)))) - (end-of-line)) - (while (funcall search-func match nil t) - (end-of-line) - (setq found (setq arts (get-text-property (point) 'articles))) - ;; Found a match, update scores. - (while (setq art (pop arts)) - (when (setq new (gnus-score-add-followups - (car art) score all-scores thread)) - (push new news))))) - ;; Update expire date - (cond ((null date)) ;Permanent entry. - ((and found gnus-update-score-entry-dates) ;Match, update date. - (gnus-score-set 'touched '(t) alist) - (setcar (nthcdr 2 kill) now)) - ((and expire (< date expire)) ;Old entry, remove. - (gnus-score-set 'touched '(t) alist) - (setcdr entries (cdr rest)) - (setq rest entries))) - (setq entries rest)))) - ;; We change the score file back to the previous one. - (save-excursion - (set-buffer gnus-summary-buffer) - (gnus-score-load-file current-score-file)) - (list (cons "references" news)))) - -(defun gnus-score-add-followups (header score scores &optional thread) - "Add a score entry to the adapt file." - (save-excursion - (set-buffer gnus-summary-buffer) - (let* ((id (mail-header-id header)) - (scores (car scores)) - entry dont) - ;; Don't enter a score if there already is one. - (while (setq entry (pop scores)) - (and (equal "references" (car entry)) - (or (null (nth 3 (cadr entry))) - (eq 's (nth 3 (cadr entry)))) - (assoc id entry) - (setq dont t))) - (unless dont - (gnus-summary-score-entry - (if thread "thread" "references") - id 's score (current-time-string) nil t))))) - -(defun gnus-score-string (score-list header now expire &optional trace) - ;; Score ARTICLES according to HEADER in SCORE-LIST. - ;; Update matching entries to NOW and remove unmatched entries older - ;; than EXPIRE. - - ;; Insert the unique article headers in the buffer. - (let ((gnus-score-index (nth 1 (assoc header gnus-header-index))) - ;; gnus-score-index is used as a free variable. - (simplify (and gnus-score-thread-simplify - (string= "subject" header))) - alike last this art entries alist articles - fuzzies arts words kill) - - ;; Sorting the articles costs os O(N*log N) but will allow us to - ;; only match with each unique header. Thus the actual matching - ;; will be O(M*U) where M is the number of strings to match with, - ;; and U is the number of unique headers. It is assumed (but - ;; untested) this will be a net win because of the large constant - ;; factor involved with string matching. - (setq gnus-scores-articles (sort gnus-scores-articles 'gnus-score-string<) - articles gnus-scores-articles) - - (erase-buffer) - (while (setq art (pop articles)) - (setq this (aref (car art) gnus-score-index)) - (if simplify - (setq this (gnus-map-function gnus-simplify-subject-functions this))) - (if (equal last this) - ;; O(N*H) cons-cells used here, where H is the number of - ;; headers. - (push art alike) - (when last - ;; Insert the line, with a text property on the - ;; terminating newline referring to the articles with - ;; this line. - (insert last ?\n) - (put-text-property (1- (point)) (point) 'articles alike)) - (setq alike (list art) - last this))) - (when last ; Bwadr, duplicate code. - (insert last ?\n) - (put-text-property (1- (point)) (point) 'articles alike)) - - ;; Go through all the score alists and pick out the entries - ;; for this header. - (while score-list - (setq alist (pop score-list) - ;; There's only one instance of this header for - ;; each score alist. - entries (assoc header alist)) - (while (cdr entries) ;First entry is the header index. - (let* ((kill (cadr entries)) - (type (or (nth 3 kill) 's)) - (score (or (nth 1 kill) gnus-score-interactive-default-score)) - (date (nth 2 kill)) - (found nil) - (mt (aref (symbol-name type) 0)) - (case-fold-search (not (memq mt '(?R ?S ?E ?F)))) - (dmt (downcase mt)) - ; Assume user already simplified regexp and fuzzies - (match (if (and simplify (not (memq dmt '(?f ?r)))) - (gnus-map-function - gnus-simplify-subject-functions - (nth 0 kill)) - (nth 0 kill))) - (search-func - (cond ((= dmt ?r) 're-search-forward) - ((or (= dmt ?e) (= dmt ?s) (= dmt ?f)) 'search-forward) - ((= dmt ?w) nil) - (t (error "Illegal match type: %s" type))))) - (cond - ;; Fuzzy matches. We save these for later. - ((= dmt ?f) - (push (cons entries alist) fuzzies) - (setq entries (cdr entries))) - ;; Word matches. Save these for even later. - ((= dmt ?w) - (push (cons entries alist) words) - (setq entries (cdr entries))) - ;; Exact matches. - ((= dmt ?e) - ;; Do exact matching. - (goto-char (point-min)) - (while (and (not (eobp)) - (funcall search-func match nil t)) - ;; Is it really exact? - (and (eolp) - (= (gnus-point-at-bol) (match-beginning 0)) - ;; Yup. - (progn - (setq found (setq arts (get-text-property - (point) 'articles))) - ;; Found a match, update scores. - (if trace - (while (setq art (pop arts)) - (setcdr art (+ score (cdr art))) - (push - (cons - (car-safe (rassq alist gnus-score-cache)) - kill) - gnus-score-trace)) - (while (setq art (pop arts)) - (setcdr art (+ score (cdr art))))))) - (forward-line 1)) - ;; Update expiry date - (if trace - (setq entries (cdr entries)) - (cond - ;; Permanent entry. - ((null date) - (setq entries (cdr entries))) - ;; We have a match, so we update the date. - ((and found gnus-update-score-entry-dates) - (gnus-score-set 'touched '(t) alist) - (setcar (nthcdr 2 kill) now) - (setq entries (cdr entries))) - ;; This entry has expired, so we remove it. - ((and expire (< date expire)) - (gnus-score-set 'touched '(t) alist) - (setcdr entries (cddr entries))) - ;; No match; go to next entry. - (t - (setq entries (cdr entries)))))) - ;; Regexp and substring matching. - (t - (goto-char (point-min)) - (when (string= match "") - (setq match "\n")) - (while (and (not (eobp)) - (funcall search-func match nil t)) - (goto-char (match-beginning 0)) - (end-of-line) - (setq found (setq arts (get-text-property (point) 'articles))) - ;; Found a match, update scores. - (if trace - (while (setq art (pop arts)) - (setcdr art (+ score (cdr art))) - (push (cons (car-safe (rassq alist gnus-score-cache)) kill) - gnus-score-trace)) - (while (setq art (pop arts)) - (setcdr art (+ score (cdr art))))) - (forward-line 1)) - ;; Update expiry date - (if trace - (setq entries (cdr entries)) - (cond - ;; Permanent entry. - ((null date) - (setq entries (cdr entries))) - ;; We have a match, so we update the date. - ((and found gnus-update-score-entry-dates) - (gnus-score-set 'touched '(t) alist) - (setcar (nthcdr 2 kill) now) - (setq entries (cdr entries))) - ;; This entry has expired, so we remove it. - ((and expire (< date expire)) - (gnus-score-set 'touched '(t) alist) - (setcdr entries (cddr entries))) - ;; No match; go to next entry. - (t - (setq entries (cdr entries)))))))))) - - ;; Find fuzzy matches. - (when fuzzies - ;; Simplify the entire buffer for easy matching. - (gnus-simplify-buffer-fuzzy) - (while (setq kill (cadaar fuzzies)) - (let* ((match (nth 0 kill)) - (type (nth 3 kill)) - (score (or (nth 1 kill) gnus-score-interactive-default-score)) - (date (nth 2 kill)) - (mt (aref (symbol-name type) 0)) - (case-fold-search (not (= mt ?F))) - found) - (goto-char (point-min)) - (while (and (not (eobp)) - (search-forward match nil t)) - (when (and (= (gnus-point-at-bol) (match-beginning 0)) - (eolp)) - (setq found (setq arts (get-text-property (point) 'articles))) - (if trace - (while (setq art (pop arts)) - (setcdr art (+ score (cdr art))) - (push (cons - (car-safe (rassq (cdar fuzzies) gnus-score-cache)) - kill) - gnus-score-trace)) - ;; Found a match, update scores. - (while (setq art (pop arts)) - (setcdr art (+ score (cdr art)))))) - (forward-line 1)) - ;; Update expiry date - (if (not trace) - (cond - ;; Permanent. - ((null date) - ) - ;; Match, update date. - ((and found gnus-update-score-entry-dates) - (gnus-score-set 'touched '(t) (cdar fuzzies)) - (setcar (nthcdr 2 kill) now)) - ;; Old entry, remove. - ((and expire (< date expire)) - (gnus-score-set 'touched '(t) (cdar fuzzies)) - (setcdr (caar fuzzies) (cddaar fuzzies))))) - (setq fuzzies (cdr fuzzies))))) - - (when words - ;; Enter all words into the hashtb. - (let ((hashtb (gnus-make-hashtable - (* 10 (count-lines (point-min) (point-max)))))) - (gnus-enter-score-words-into-hashtb hashtb) - (while (setq kill (cadaar words)) - (let* ((score (or (nth 1 kill) gnus-score-interactive-default-score)) - (date (nth 2 kill)) - found) - (when (setq arts (intern-soft (nth 0 kill) hashtb)) - (setq arts (symbol-value arts)) - (setq found t) - (if trace - (while (setq art (pop arts)) - (setcdr art (+ score (cdr art))) - (push (cons - (car-safe (rassq (cdar words) gnus-score-cache)) - kill) - gnus-score-trace)) - ;; Found a match, update scores. - (while (setq art (pop arts)) - (setcdr art (+ score (cdr art)))))) - ;; Update expiry date - (if (not trace) - (cond - ;; Permanent. - ((null date) - ) - ;; Match, update date. - ((and found gnus-update-score-entry-dates) - (gnus-score-set 'touched '(t) (cdar words)) - (setcar (nthcdr 2 kill) now)) - ;; Old entry, remove. - ((and expire (< date expire)) - (gnus-score-set 'touched '(t) (cdar words)) - (setcdr (caar words) (cddaar words))))) - (setq words (cdr words)))))) - nil)) - -(defun gnus-enter-score-words-into-hashtb (hashtb) - ;; Find all the words in the buffer and enter them into - ;; the hashtable. - (let ((syntab (syntax-table)) - word val) - (goto-char (point-min)) - (unwind-protect - (progn - (set-syntax-table gnus-adaptive-word-syntax-table) - (while (re-search-forward "\\b\\w+\\b" nil t) - (setq val - (gnus-gethash - (setq word (downcase (buffer-substring - (match-beginning 0) (match-end 0)))) - hashtb)) - (gnus-sethash - word - (append (get-text-property (gnus-point-at-eol) 'articles) val) - hashtb))) - (set-syntax-table syntab)) - ;; Make all the ignorable words ignored. - (let ((ignored (append gnus-ignored-adaptive-words - (if gnus-adaptive-word-no-group-words - (message-tokenize-header - (gnus-group-real-name gnus-newsgroup-name) - ".")) - gnus-default-ignored-adaptive-words))) - (while ignored - (gnus-sethash (pop ignored) nil hashtb))))) - -(defun gnus-score-string< (a1 a2) - ;; Compare headers in articles A2 and A2. - ;; The header index used is the free variable `gnus-score-index'. - (string-lessp (aref (car a1) gnus-score-index) - (aref (car a2) gnus-score-index))) - -(defun gnus-current-score-file-nondirectory (&optional score-file) - (let ((score-file (or score-file gnus-current-score-file))) - (if score-file - (gnus-short-group-name (file-name-nondirectory score-file)) - "none"))) - -(defun gnus-score-adaptive () - "Create adaptive score rules for this newsgroup." - (when gnus-newsgroup-adaptive - ;; We change the score file to the adaptive score file. - (save-excursion - (set-buffer gnus-summary-buffer) - (gnus-score-load-file - (or gnus-newsgroup-adaptive-score-file - (gnus-home-score-file gnus-newsgroup-name t) - (gnus-score-file-name - gnus-newsgroup-name gnus-adaptive-file-suffix)))) - ;; Perform ordinary line scoring. - (when (or (not (listp gnus-newsgroup-adaptive)) - (memq 'line gnus-newsgroup-adaptive)) - (save-excursion - (let* ((malist (gnus-copy-sequence gnus-adaptive-score-alist)) - (alist malist) - (date (current-time-string)) - (data gnus-newsgroup-data) - elem headers match func) - ;; First we transform the adaptive rule alist into something - ;; that's faster to process. - (while malist - (setq elem (car malist)) - (when (symbolp (car elem)) - (setcar elem (symbol-value (car elem)))) - (setq elem (cdr elem)) - (while elem - (when (fboundp - (setq func - (intern - (concat "mail-header-" - (if (eq (caar elem) 'followup) - "message-id" - (downcase (symbol-name (caar elem)))))))) - (setcdr (car elem) - (cons (if (eq (caar elem) 'followup) - "references" - (symbol-name (caar elem))) - (cdar elem))) - (setcar (car elem) - `(lambda (h) - (,func h)))) - (setq elem (cdr elem))) - (setq malist (cdr malist))) - ;; Then we score away. - (while data - (setq elem (cdr (assq (gnus-data-mark (car data)) alist))) - (if (or (not elem) - (gnus-data-pseudo-p (car data))) - () - (when (setq headers (gnus-data-header (car data))) - (while elem - (setq match (funcall (caar elem) headers)) - (gnus-summary-score-entry - (nth 1 (car elem)) match - (cond - ((numberp match) - '=) - ((equal (nth 1 (car elem)) "date") - 'a) - (t - ;; Whether we use substring or exact matches is - ;; controlled here. - (if (or (not gnus-score-exact-adapt-limit) - (< (length match) gnus-score-exact-adapt-limit)) - 'e - (if (equal (nth 1 (car elem)) "subject") - 'f 's)))) - (nth 2 (car elem)) date nil t) - (setq elem (cdr elem))))) - (setq data (cdr data)))))) - - ;; Perform adaptive word scoring. - (when (and (listp gnus-newsgroup-adaptive) - (memq 'word gnus-newsgroup-adaptive)) - (nnheader-temp-write nil - (let* ((hashtb (gnus-make-hashtable 1000)) - (date (gnus-day-number (current-time-string))) - (data gnus-newsgroup-data) - (syntab (syntax-table)) - word d score val) - (unwind-protect - (progn - (set-syntax-table gnus-adaptive-word-syntax-table) - ;; Go through all articles. - (while (setq d (pop data)) - (when (and - (not (gnus-data-pseudo-p d)) - (setq score - (cdr (assq - (gnus-data-mark d) - gnus-adaptive-word-score-alist)))) - ;; This article has a mark that should lead to - ;; adaptive word rules, so we insert the subject - ;; and find all words in that string. - (insert (mail-header-subject (gnus-data-header d))) - (downcase-region (point-min) (point-max)) - (goto-char (point-min)) - (while (re-search-forward "\\b\\w+\\b" nil t) - ;; Put the word and score into the hashtb. - (setq val (gnus-gethash (setq word (match-string 0)) - hashtb)) - (setq val (+ score (or val 0))) - (if (and gnus-adaptive-word-minimum - (< val gnus-adaptive-word-minimum)) - (setq val gnus-adaptive-word-minimum)) - (gnus-sethash word val hashtb)) - (erase-buffer)))) - (set-syntax-table syntab)) - ;; Make all the ignorable words ignored. - (let ((ignored (append gnus-ignored-adaptive-words - (if gnus-adaptive-word-no-group-words - (message-tokenize-header - (gnus-group-real-name - gnus-newsgroup-name) - ".")) - gnus-default-ignored-adaptive-words))) - (while ignored - (gnus-sethash (pop ignored) nil hashtb))) - ;; Now we have all the words and scores, so we - ;; add these rules to the ADAPT file. - (set-buffer gnus-summary-buffer) - (mapatoms - (lambda (word) - (when (symbol-value word) - (gnus-summary-score-entry - "subject" (symbol-name word) 'w (symbol-value word) - date nil t))) - hashtb)))))) - -(defun gnus-score-edit-done () - (let ((bufnam (buffer-file-name (current-buffer))) - (winconf gnus-prev-winconf)) - (when winconf - (set-window-configuration winconf)) - (gnus-score-remove-from-cache bufnam) - (gnus-score-load-file bufnam))) - -(defun gnus-score-find-trace () - "Find all score rules that applies to the current article." - (interactive) - (let ((old-scored gnus-newsgroup-scored)) - (let ((gnus-newsgroup-headers - (list (gnus-summary-article-header))) - (gnus-newsgroup-scored nil) - trace) - (save-excursion - (nnheader-set-temp-buffer "*Score Trace*")) - (setq gnus-score-trace nil) - (gnus-possibly-score-headers 'trace) - (if (not (setq trace gnus-score-trace)) - (gnus-error - 1 "No score rules apply to the current article (default score %d)." - gnus-summary-default-score) - (set-buffer "*Score Trace*") - (while trace - (insert (format "%S -> %s\n" (cdar trace) - (if (caar trace) - (file-name-nondirectory (caar trace)) - "(non-file rule)"))) - (setq trace (cdr trace))) - (goto-char (point-min)) - (gnus-configure-windows 'score-trace))) - (set-buffer gnus-summary-buffer) - (setq gnus-newsgroup-scored old-scored))) - -(defun gnus-score-find-favourite-words () - "List words used in scoring." - (interactive) - (let ((alists (gnus-score-load-files (gnus-all-score-files))) - alist rule rules kill) - ;; Go through all the score alists for this group - ;; and find all `w' rules. - (while (setq alist (pop alists)) - (while (setq rule (pop alist)) - (when (and (stringp (car rule)) - (equal "subject" (downcase (pop rule)))) - (while (setq kill (pop rule)) - (when (memq (nth 3 kill) '(w W word Word)) - (push (cons (or (nth 1 kill) - gnus-score-interactive-default-score) - (car kill)) - rules)))))) - (setq rules (sort rules (lambda (r1 r2) - (string-lessp (cdr r1) (cdr r2))))) - ;; Add up words that have appeared several times. - (let ((r rules)) - (while (cdr r) - (if (equal (cdar r) (cdadr r)) - (progn - (setcar (car r) (+ (caar r) (caadr r))) - (setcdr r (cddr r))) - (pop r)))) - ;; Insert the words. - (nnheader-set-temp-buffer "*Score Words*") - (if (not (setq rules (sort rules (lambda (r1 r2) (> (car r1) (car r2)))))) - (gnus-error 3 "No word score rules") - (while rules - (insert (format "%-5d: %s\n" (caar rules) (cdar rules))) - (pop rules)) - (goto-char (point-min)) - (gnus-configure-windows 'score-words)))) - -(defun gnus-summary-rescore () - "Redo the entire scoring process in the current summary." - (interactive) - (gnus-score-save) - (setq gnus-score-cache nil) - (setq gnus-newsgroup-scored nil) - (gnus-possibly-score-headers) - (gnus-score-update-all-lines)) - -(defun gnus-score-flush-cache () - "Flush the cache of score files." - (interactive) - (gnus-score-save) - (setq gnus-score-cache nil - gnus-score-alist nil - gnus-short-name-score-file-cache nil) - (gnus-message 6 "The score cache is now flushed")) - -(gnus-add-shutdown 'gnus-score-close 'gnus) - -(defvar gnus-score-file-alist-cache nil) - -(defun gnus-score-close () - "Clear all internal score variables." - (setq gnus-score-cache nil - gnus-internal-global-score-files nil - gnus-score-file-list nil - gnus-score-file-alist-cache nil)) - -;; Summary score marking commands. - -(defun gnus-summary-raise-same-subject-and-select (score) - "Raise articles which has the same subject with SCORE and select the next." - (interactive "p") - (let ((subject (gnus-summary-article-subject))) - (gnus-summary-raise-score score) - (while (gnus-summary-find-subject subject) - (gnus-summary-raise-score score)) - (gnus-summary-next-article t))) - -(defun gnus-summary-raise-same-subject (score) - "Raise articles which has the same subject with SCORE." - (interactive "p") - (let ((subject (gnus-summary-article-subject))) - (gnus-summary-raise-score score) - (while (gnus-summary-find-subject subject) - (gnus-summary-raise-score score)) - (gnus-summary-next-subject 1 t))) - -(defun gnus-score-default (level) - (if level (prefix-numeric-value level) - gnus-score-interactive-default-score)) - -(defun gnus-summary-raise-thread (&optional score) - "Raise the score of the articles in the current thread with SCORE." - (interactive "P") - (setq score (gnus-score-default score)) - (let (e) - (save-excursion - (let ((articles (gnus-summary-articles-in-thread))) - (while articles - (gnus-summary-goto-subject (car articles)) - (gnus-summary-raise-score score) - (setq articles (cdr articles)))) - (setq e (point))) - (let ((gnus-summary-check-current t)) - (unless (zerop (gnus-summary-next-subject 1 t)) - (goto-char e)))) - (gnus-summary-recenter) - (gnus-summary-position-point) - (gnus-set-mode-line 'summary)) - -(defun gnus-summary-lower-same-subject-and-select (score) - "Raise articles which has the same subject with SCORE and select the next." - (interactive "p") - (gnus-summary-raise-same-subject-and-select (- score))) - -(defun gnus-summary-lower-same-subject (score) - "Raise articles which has the same subject with SCORE." - (interactive "p") - (gnus-summary-raise-same-subject (- score))) - -(defun gnus-summary-lower-thread (&optional score) - "Lower score of articles in the current thread with SCORE." - (interactive "P") - (gnus-summary-raise-thread (- (1- (gnus-score-default score))))) - -;;; Finding score files. - -(defun gnus-score-score-files (group) - "Return a list of all possible score files." - ;; Search and set any global score files. - (when gnus-global-score-files - (unless gnus-internal-global-score-files - (gnus-score-search-global-directories gnus-global-score-files))) - ;; Fix the kill-file dir variable. - (setq gnus-kill-files-directory - (file-name-as-directory gnus-kill-files-directory)) - ;; If we can't read it, there are no score files. - (if (not (file-exists-p (expand-file-name gnus-kill-files-directory))) - (setq gnus-score-file-list nil) - (if (not (gnus-use-long-file-name 'not-score)) - ;; We do not use long file names, so we have to do some - ;; directory traversing. - (setq gnus-score-file-list - (cons nil - (or gnus-short-name-score-file-cache - (prog2 - (gnus-message 6 "Finding all score files...") - (setq gnus-short-name-score-file-cache - (gnus-score-score-files-1 - gnus-kill-files-directory)) - (gnus-message 6 "Finding all score files...done"))))) - ;; We want long file names. - (when (or (not gnus-score-file-list) - (not (car gnus-score-file-list)) - (gnus-file-newer-than gnus-kill-files-directory - (car gnus-score-file-list))) - (setq gnus-score-file-list - (cons (nth 5 (file-attributes gnus-kill-files-directory)) - (nreverse - (directory-files - gnus-kill-files-directory t - (gnus-score-file-regexp))))))) - (cdr gnus-score-file-list))) - -(defun gnus-score-score-files-1 (dir) - "Return all possible score files under DIR." - (let ((files (list (expand-file-name dir))) - (regexp (gnus-score-file-regexp)) - (case-fold-search nil) - seen out file) - (while (setq file (pop files)) - (cond - ;; Ignore "." and "..". - ((member (file-name-nondirectory file) '("." "..")) - nil) - ;; Add subtrees of directory to also be searched. - ((and (file-directory-p file) - (not (member (file-truename file) seen))) - (push (file-truename file) seen) - (setq files (nconc (directory-files file t nil t) files))) - ;; Add files to the list of score files. - ((string-match regexp file) - (push file out)))) - (or out - ;; Return a dummy value. - (list "~/News/this.file.does.not.exist.SCORE")))) - -(defun gnus-score-file-regexp () - "Return a regexp that match all score files." - (concat "\\(" (regexp-quote gnus-score-file-suffix ) - "\\|" (regexp-quote gnus-adaptive-file-suffix) "\\)\\'")) - -(defun gnus-score-find-bnews (group) - "Return a list of score files for GROUP. -The score files are those files in the ~/News/ directory which matches -GROUP using BNews sys file syntax." - (let* ((sfiles (append (gnus-score-score-files group) - gnus-internal-global-score-files)) - (kill-dir (file-name-as-directory - (expand-file-name gnus-kill-files-directory))) - (klen (length kill-dir)) - (score-regexp (gnus-score-file-regexp)) - (trans (cdr (assq ?: nnheader-file-name-translation-alist))) - ofiles not-match regexp) - (save-excursion - (set-buffer (gnus-get-buffer-create "*gnus score files*")) - (buffer-disable-undo (current-buffer)) - ;; Go through all score file names and create regexp with them - ;; as the source. - (while sfiles - (erase-buffer) - (insert (car sfiles)) - (goto-char (point-min)) - ;; First remove the suffix itself. - (when (re-search-forward (concat "." score-regexp) nil t) - (replace-match "" t t) - (goto-char (point-min)) - (if (looking-at (regexp-quote kill-dir)) - ;; If the file name was just "SCORE", `klen' is one character - ;; too much. - (delete-char (min (1- (point-max)) klen)) - (goto-char (point-max)) - (search-backward "/") - (delete-region (1+ (point)) (point-min))) - ;; If short file names were used, we have to translate slashes. - (goto-char (point-min)) - (let ((regexp (concat - "[/:" (if trans (char-to-string trans) "") "]"))) - (while (re-search-forward regexp nil t) - (replace-match "." t t))) - ;; Kludge to get rid of "nntp+" problems. - (goto-char (point-min)) - (when (looking-at "nn[a-z]+\\+") - (search-forward "+") - (forward-char -1) - (insert "\\") - (forward-char 1)) - ;; Kludge to deal with "++". - (while (search-forward "+" nil t) - (replace-match "\\+" t t)) - ;; Translate "all" to ".*". - (goto-char (point-min)) - (while (search-forward "all" nil t) - (replace-match ".*" t t)) - (goto-char (point-min)) - ;; Deal with "not."s. - (if (looking-at "not.") - (progn - (setq not-match t) - (setq regexp (concat "^" (buffer-substring 5 (point-max)) "$"))) - (setq regexp (concat "^" (buffer-substring 1 (point-max)) "$")) - (setq not-match nil)) - ;; Finally - if this resulting regexp matches the group name, - ;; we add this score file to the list of score files - ;; applicable to this group. - (when (or (and not-match - (not (string-match regexp group))) - (and (not not-match) - (string-match regexp group))) - (push (car sfiles) ofiles))) - (setq sfiles (cdr sfiles))) - (kill-buffer (current-buffer)) - ;; Slight kludge here - the last score file returned should be - ;; the local score file, whether it exists or not. This is so - ;; that any score commands the user enters will go to the right - ;; file, and not end up in some global score file. - (let ((localscore (gnus-score-file-name group))) - (setq ofiles (cons localscore (delete localscore ofiles)))) - (gnus-sort-score-files (nreverse ofiles))))) - -(defun gnus-score-find-single (group) - "Return list containing the score file for GROUP." - (list (or gnus-newsgroup-adaptive-score-file - (gnus-score-file-name group gnus-adaptive-file-suffix)) - (gnus-score-file-name group))) - -(defun gnus-score-find-hierarchical (group) - "Return list of score files for GROUP. -This includes the score file for the group and all its parents." - (let* ((prefix (gnus-group-real-prefix group)) - (all (list nil)) - (group (gnus-group-real-name group)) - (start 0)) - (while (string-match "\\." group (1+ start)) - (setq start (match-beginning 0)) - (push (substring group 0 start) all)) - (push group all) - (setq all - (nconc - (mapcar (lambda (group) - (gnus-score-file-name group gnus-adaptive-file-suffix)) - (setq all (nreverse all))) - (mapcar 'gnus-score-file-name all))) - (if (equal prefix "") - all - (mapcar - (lambda (file) - (nnheader-translate-file-chars - (concat (file-name-directory file) prefix - (file-name-nondirectory file)))) - all)))) - -(defun gnus-score-file-rank (file) - "Return a number that says how specific score FILE is. -Destroys the current buffer." - (if (member file gnus-internal-global-score-files) - 0 - (when (string-match - (concat "^" (regexp-quote - (expand-file-name - (file-name-as-directory gnus-kill-files-directory)))) - file) - (setq file (substring file (match-end 0)))) - (insert file) - (goto-char (point-min)) - (let ((beg (point)) - elems) - (while (re-search-forward "[./]" nil t) - (push (buffer-substring beg (1- (point))) - elems)) - (erase-buffer) - (setq elems (delete "all" elems)) - (length elems)))) - -(defun gnus-sort-score-files (files) - "Sort FILES so that the most general files come first." - (nnheader-temp-write nil - (let ((alist - (mapcar - (lambda (file) - (cons (inline (gnus-score-file-rank file)) file)) - files))) - (mapcar - (lambda (f) (cdr f)) - (sort alist 'car-less-than-car))))) - -(defun gnus-score-find-alist (group) - "Return list of score files for GROUP. -The list is determined from the variable gnus-score-file-alist." - (let ((alist gnus-score-file-multiple-match-alist) - score-files) - ;; if this group has been seen before, return the cached entry - (if (setq score-files (assoc group gnus-score-file-alist-cache)) - (cdr score-files) ;ensures caching groups with no matches - ;; handle the multiple match alist - (while alist - (when (string-match (caar alist) group) - (setq score-files - (nconc score-files (copy-sequence (cdar alist))))) - (setq alist (cdr alist))) - (setq alist gnus-score-file-single-match-alist) - ;; handle the single match alist - (while alist - (when (string-match (caar alist) group) - ;; progn used just in case ("regexp") has no files - ;; and score-files is still nil. -sj - ;; this can be construed as a "stop searching here" feature :> - ;; and used to simplify regexps in the single-alist - (setq score-files - (nconc score-files (copy-sequence (cdar alist)))) - (setq alist nil)) - (setq alist (cdr alist))) - ;; cache the score files - (push (cons group score-files) gnus-score-file-alist-cache) - score-files))) - -(defun gnus-all-score-files (&optional group) - "Return a list of all score files for the current group." - (let ((funcs gnus-score-find-score-files-function) - (group (or group gnus-newsgroup-name)) - score-files) - (when group - ;; Make sure funcs is a list. - (and funcs - (not (listp funcs)) - (setq funcs (list funcs))) - ;; Get the initial score files for this group. - (when funcs - (setq score-files (nreverse (gnus-score-find-alist group)))) - ;; Add any home adapt files. - (let ((home (gnus-home-score-file group t))) - (when home - (push home score-files) - (setq gnus-newsgroup-adaptive-score-file home))) - ;; Check whether there is a `adapt-file' group parameter. - (let ((param-file (gnus-group-find-parameter group 'adapt-file))) - (when param-file - (push param-file score-files) - (setq gnus-newsgroup-adaptive-score-file param-file))) - ;; Go through all the functions for finding score files (or actual - ;; scores) and add them to a list. - (while funcs - (when (gnus-functionp (car funcs)) - (setq score-files - (nconc score-files (nreverse (funcall (car funcs) group))))) - (setq funcs (cdr funcs))) - ;; Add any home score files. - (let ((home (gnus-home-score-file group))) - (when home - (push home score-files))) - ;; Check whether there is a `score-file' group parameter. - (let ((param-file (gnus-group-find-parameter group 'score-file))) - (when param-file - (push param-file score-files))) - ;; Expand all files names. - (let ((files score-files)) - (while files - (when (stringp (car files)) - (setcar files (expand-file-name - (car files) gnus-kill-files-directory))) - (pop files))) - (setq score-files (nreverse score-files)) - ;; Remove any duplicate score files. - (while (and score-files - (member (car score-files) (cdr score-files))) - (pop score-files)) - (let ((files score-files)) - (while (cdr files) - (if (member (cadr files) (cddr files)) - (setcdr files (cddr files)) - (pop files)))) - ;; Do the scoring if there are any score files for this group. - score-files))) - -(defun gnus-possibly-score-headers (&optional trace) - "Do scoring if scoring is required." - (let ((score-files (gnus-all-score-files))) - (when score-files - (gnus-score-headers score-files trace)))) - -(defun gnus-score-file-name (newsgroup &optional suffix) - "Return the name of a score file for NEWSGROUP." - (let ((suffix (or suffix gnus-score-file-suffix))) - (nnheader-translate-file-chars - (cond - ((or (null newsgroup) - (string-equal newsgroup "")) - ;; The global score file is placed at top of the directory. - (expand-file-name suffix gnus-kill-files-directory)) - ((gnus-use-long-file-name 'not-score) - ;; Append ".SCORE" to newsgroup name. - (expand-file-name (concat (gnus-newsgroup-savable-name newsgroup) - "." suffix) - gnus-kill-files-directory)) - (t - ;; Place "SCORE" under the hierarchical directory. - (expand-file-name (concat (gnus-newsgroup-directory-form newsgroup) - "/" suffix) - gnus-kill-files-directory)))))) - -(defun gnus-score-search-global-directories (files) - "Scan all global score directories for score files." - ;; Set the variable `gnus-internal-global-score-files' to all - ;; available global score files. - (interactive (list gnus-global-score-files)) - (let (out) - (while files - ;; #### /$ Unix-specific? - (if (string-match "/$" (car files)) - (setq out (nconc (directory-files - (car files) t - (concat (gnus-score-file-regexp) "$")))) - (push (car files) out)) - (setq files (cdr files))) - (setq gnus-internal-global-score-files out))) - -(defun gnus-score-default-fold-toggle () - "Toggle folding for new score file entries." - (interactive) - (setq gnus-score-default-fold (not gnus-score-default-fold)) - (if gnus-score-default-fold - (gnus-message 1 "New score file entries will be case insensitive.") - (gnus-message 1 "New score file entries will be case sensitive."))) - -;;; Home score file. - -(defun gnus-home-score-file (group &optional adapt) - "Return the home score file for GROUP. -If ADAPT, return the home adaptive file instead." - (let ((list (if adapt gnus-home-adapt-file gnus-home-score-file)) - elem found) - ;; Make sure we have a list. - (unless (listp list) - (setq list (list list))) - ;; Go through the list and look for matches. - (while (and (not found) - (setq elem (pop list))) - (setq found - (cond - ;; Simple string. - ((stringp elem) - elem) - ;; Function. - ((gnus-functionp elem) - (funcall elem group)) - ;; Regexp-file cons - ((consp elem) - (when (string-match (gnus-globalify-regexp (car elem)) group) - (replace-match (cadr elem) t nil group )))))) - (when found - (nnheader-concat gnus-kill-files-directory found)))) - -(defun gnus-hierarchial-home-score-file (group) - "Return the score file of the top-level hierarchy of GROUP." - (if (string-match "^[^.]+\\." group) - (concat (match-string 0 group) gnus-score-file-suffix) - ;; Group name without any dots. - (concat group (if (gnus-use-long-file-name 'not-score) "." "/") - gnus-score-file-suffix))) - -(defun gnus-hierarchial-home-adapt-file (group) - "Return the adapt file of the top-level hierarchy of GROUP." - (if (string-match "^[^.]+\\." group) - (concat (match-string 0 group) gnus-adaptive-file-suffix) - ;; Group name without any dots. - (concat group (if (gnus-use-long-file-name 'not-score) "." "/") - gnus-adaptive-file-suffix))) - -(defun gnus-current-home-score-file (group) - "Return the \"current\" regular score file." - (car (nreverse (gnus-score-find-alist group)))) - -;;; -;;; Score decays -;;; - -(defun gnus-decay-score (score) - "Decay SCORE according to `gnus-score-decay-constant' and `gnus-score-decay-scale'." - (floor - (- score - (* (if (< score 0) -1 1) - (min (abs score) - (max gnus-score-decay-constant - (* (abs score) - gnus-score-decay-scale))))))) - -(defun gnus-decay-scores (alist day) - "Decay non-permanent scores in ALIST." - (let ((times (- (gnus-time-to-day (current-time)) day)) - kill entry updated score n) - (unless (zerop times) ;Done decays today already? - (while (setq entry (pop alist)) - (when (stringp (car entry)) - (setq entry (cdr entry)) - (while (setq kill (pop entry)) - (when (nth 2 kill) - (setq updated t) - (setq score (or (nth 1 kill) - gnus-score-interactive-default-score) - n times) - (while (natnump (decf n)) - (setq score (funcall gnus-decay-score-function score))) - (setcdr kill (cons score - (cdr (cdr kill))))))))) - ;; Return whether this score file needs to be saved. By Je-haysuss! - updated)) - -(defun gnus-score-regexp-bad-p (regexp) - "Test whether REGEXP is safe for Gnus scoring. -A regexp is unsafe if it matches newline or a buffer boundary. - -If the regexp is good, return nil. If the regexp is bad, return a -cons cell (SYM . STRING), where the symbol SYM is `new' or `bad'. -In the `new' case, the string is a safe replacement for REGEXP. -In the `bad' case, the string is a unsafe subexpression of REGEXP, -and we do not have a simple replacement to suggest. - -See `(Gnus)Scoring Tips' for examples of good regular expressions." - (let (case-fold-search) - (and - ;; First, try a relatively fast necessary condition. - ;; Notice ranges (like [^:] or [\t-\r]), \s>, \Sw, \W, \', \`: - (string-match "\n\\|\\\\[SsW`']\\|\\[\\^\\|[\0-\n]-" regexp) - ;; Now break the regexp into tokens, and check each: - (let ((tail regexp) ; remaining regexp to check - tok ; current token - bad ; nil, or bad subexpression - new ; nil, or replacement regexp so far - end) ; length of current token - (while (and (not bad) - (string-match - "\\`\\(\\\\[sS]?.\\|\\[\\^?]?[^]]*]\\|[^\\]\\)" - tail)) - (setq end (match-end 0) - tok (substring tail 0 end) - tail (substring tail end)) - (if;; Is token `bad' (matching newline or buffer ends)? - (or (member tok '("\n" "\\W" "\\`" "\\'")) - ;; This next handles "[...]", "\\s.", and "\\S.": - (and (> end 2) (string-match tok "\n"))) - (let ((newtok - ;; Try to suggest a replacement for tok ... - (cond ((string-equal tok "\\`") "^") ; or "\\(^\\)" - ((string-equal tok "\\'") "$") ; or "\\($\\)" - ((string-match "\\[\\^" tok) ; very common - (concat (substring tok 0 -1) "\n]"))))) - (if newtok - (setq new - (concat - (or new - ;; good prefix so far: - (substring regexp 0 (- (+ (length tail) end)))) - newtok)) - ;; No replacement idea, so give up: - (setq bad tok))) - ;; tok is good, may need to extend new - (and new (setq new (concat new tok))))) - ;; Now return a value: - (cond - (bad (cons 'bad bad)) - (new (cons 'new new)) - ;; or nil - ))))) - -(provide 'gnus-score) - -;;; gnus-score.el ends here diff --git a/lisp/gnus-setup.el b/lisp/gnus-setup.el deleted file mode 100644 index ae9909b..0000000 --- a/lisp/gnus-setup.el +++ /dev/null @@ -1,217 +0,0 @@ -;;; gnus-setup.el --- Initialization & Setup for Gnus 5 -;; Copyright (C) 1995, 96 Free Software Foundation, Inc. - -;; Author: Steven L. Baur -;; Keywords: news - -;; This file is part of GNU Emacs. - -;; GNU Emacs is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 2, or (at your option) -;; any later version. - -;; GNU Emacs is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs; see the file COPYING. If not, write to the -;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. - -;;; Commentary: -;; My head is starting to spin with all the different mail/news packages. -;; Stop The Madness! - -;; Given that Emacs Lisp byte codes may be diverging, it is probably best -;; not to byte compile this, and just arrange to have the .el loaded out -;; of .emacs. - -;;; Code: - -(eval-when-compile (require 'cl)) - -(defvar running-xemacs (string-match "XEmacs\\|Lucid" emacs-version)) - -(defvar gnus-use-installed-gnus t - "*If non-nil Use installed version of Gnus.") - -(defvar gnus-use-installed-tm running-xemacs - "*If non-nil use installed version of tm.") - -(defvar gnus-use-installed-mailcrypt running-xemacs - "*If non-nil use installed version of mailcrypt.") - -(defvar gnus-emacs-lisp-directory (if running-xemacs - "/usr/local/lib/xemacs/" - "/usr/local/share/emacs/") - "Directory where Emacs site lisp is located.") - -(defvar gnus-gnus-lisp-directory (concat gnus-emacs-lisp-directory - "gnus-5.0.15/lisp/") - "Directory where Gnus Emacs lisp is found.") - -(defvar gnus-tm-lisp-directory (concat gnus-emacs-lisp-directory - "site-lisp/") - "Directory where TM Emacs lisp is found.") - -(defvar gnus-mailcrypt-lisp-directory (concat gnus-emacs-lisp-directory - "site-lisp/mailcrypt-3.4/") - "Directory where Mailcrypt Emacs Lisp is found.") - -(defvar gnus-bbdb-lisp-directory (concat gnus-emacs-lisp-directory - "site-lisp/bbdb-1.51/") - "Directory where Big Brother Database is found.") - -(defvar gnus-use-tm running-xemacs - "Set this if you want MIME support for Gnus") -(defvar gnus-use-mhe nil - "Set this if you want to use MH-E for mail reading") -(defvar gnus-use-rmail nil - "Set this if you want to use RMAIL for mail reading") -(defvar gnus-use-sendmail t - "Set this if you want to use SENDMAIL for mail reading") -(defvar gnus-use-vm nil - "Set this if you want to use the VM package for mail reading") -(defvar gnus-use-sc nil - "Set this if you want to use Supercite") -(defvar gnus-use-mailcrypt t - "Set this if you want to use Mailcrypt for dealing with PGP messages") -(defvar gnus-use-bbdb nil - "Set this if you want to use the Big Brother DataBase") - -(when (and (not gnus-use-installed-gnus) - (null (member gnus-gnus-lisp-directory load-path))) - (push gnus-gnus-lisp-directory load-path)) - -;;; We can't do this until we know where Gnus is. -(require 'message) - -;;; Tools for MIME by -;;; UMEDA Masanobu -;;; MORIOKA Tomohiko - -(when gnus-use-tm - (when (and (not gnus-use-installed-tm) - (null (member gnus-tm-lisp-directory load-path))) - (setq load-path (cons gnus-tm-lisp-directory load-path))) - ;; tm may or may not be dumped with XEmacs. In Sunpro it is, otherwise - ;; it isn't. - (unless (featurep 'mime-setup) - (load "mime-setup"))) - -;;; Mailcrypt by -;;; Jin Choi -;;; Patrick LoPresti - -(when gnus-use-mailcrypt - (when (and (not gnus-use-installed-mailcrypt) - (null (member gnus-mailcrypt-lisp-directory load-path))) - (setq load-path (cons gnus-mailcrypt-lisp-directory load-path))) - (autoload 'mc-install-write-mode "mailcrypt" nil t) - (autoload 'mc-install-read-mode "mailcrypt" nil t) - (add-hook 'message-mode-hook 'mc-install-write-mode) - (add-hook 'gnus-summary-mode-hook 'mc-install-read-mode) - (when gnus-use-mhe - (add-hook 'mh-folder-mode-hook 'mc-install-read-mode) - (add-hook 'mh-letter-mode-hook 'mc-install-write-mode))) - -;;; BBDB by -;;; Jamie Zawinski - -(when gnus-use-bbdb - ;; bbdb will never be installed with emacs. - (when (null (member gnus-bbdb-lisp-directory load-path)) - (setq load-path (cons gnus-bbdb-lisp-directory load-path))) - (autoload 'bbdb "bbdb-com" - "Insidious Big Brother Database" t) - (autoload 'bbdb-name "bbdb-com" - "Insidious Big Brother Database" t) - (autoload 'bbdb-company "bbdb-com" - "Insidious Big Brother Database" t) - (autoload 'bbdb-net "bbdb-com" - "Insidious Big Brother Database" t) - (autoload 'bbdb-notes "bbdb-com" - "Insidious Big Brother Database" t) - - (when gnus-use-vm - (autoload 'bbdb-insinuate-vm "bbdb-vm" - "Hook BBDB into VM" t)) - - (when gnus-use-rmail - (autoload 'bbdb-insinuate-rmail "bbdb-rmail" - "Hook BBDB into RMAIL" t) - (add-hook 'rmail-mode-hook 'bbdb-insinuate-rmail)) - - (when gnus-use-mhe - (autoload 'bbdb-insinuate-mh "bbdb-mh" - "Hook BBDB into MH-E" t) - (add-hook 'mh-folder-mode-hook 'bbdb-insinuate-mh)) - - (autoload 'bbdb-insinuate-gnus "bbdb-gnus" - "Hook BBDB into Gnus" t) - (add-hook 'gnus-startup-hook 'bbdb-insinuate-gnus) - - (when gnus-use-sendmail - (autoload 'bbdb-insinuate-sendmail "bbdb" - "Insidious Big Brother Database" t) - (add-hook 'mail-setup-hook 'bbdb-insinuate-sendmail) - (add-hook 'message-setup-hook 'bbdb-insinuate-sendmail))) - -(when gnus-use-sc - (add-hook 'mail-citation-hook 'sc-cite-original) - (setq message-cite-function 'sc-cite-original) - (autoload 'sc-cite-original "supercite")) - -;;;### (autoloads (gnus gnus-slave gnus-no-server) "gnus" "lisp/gnus.el" (12473 2137)) -;;; Generated autoloads from lisp/gnus.el - -;; Don't redo this if autoloads already exist -(unless (fboundp 'gnus) - (autoload 'gnus-slave-no-server "gnus" "\ -Read network news as a slave without connecting to local server." t nil) - - (autoload 'gnus-no-server "gnus" "\ -Read network news. -If ARG is a positive number, Gnus will use that as the -startup level. If ARG is nil, Gnus will be started at level 2. -If ARG is non-nil and not a positive number, Gnus will -prompt the user for the name of an NNTP server to use. -As opposed to `gnus', this command will not connect to the local server." t nil) - - (autoload 'gnus-slave "gnus" "\ -Read news as a slave." t nil) - - (autoload 'gnus "gnus" "\ -Read network news. -If ARG is non-nil and a positive number, Gnus will use that as the -startup level. If ARG is non-nil and not a positive number, Gnus will -prompt the user for the name of an NNTP server to use." t nil) - -;;;*** - -;;; These have moved out of gnus.el into other files. -;;; FIX FIX FIX: should other things be in gnus-setup? or these not in it? - (autoload 'gnus-update-format "gnus-spec" "\ -Update the format specification near point." t nil) - - (autoload 'gnus-fetch-group "gnus-group" "\ -Start Gnus if necessary and enter GROUP. -Returns whether the fetching was successful or not." t nil) - - (defalias 'gnus-batch-kill 'gnus-batch-score) - - (autoload 'gnus-batch-score "gnus-kill" "\ -Run batched scoring. -Usage: emacs -batch -l gnus -f gnus-batch-score ... -Newsgroups is a list of strings in Bnews format. If you want to score -the comp hierarchy, you'd say \"comp.all\". If you would not like to -score the alt hierarchy, you'd say \"!alt.all\"." t nil)) - -(provide 'gnus-setup) - -(run-hooks 'gnus-setup-load-hook) - -;;; gnus-setup.el ends here diff --git a/lisp/gnus-soup.el b/lisp/gnus-soup.el deleted file mode 100644 index 3d97829..0000000 --- a/lisp/gnus-soup.el +++ /dev/null @@ -1,570 +0,0 @@ -;;; gnus-soup.el --- SOUP packet writing support for Gnus -;; Copyright (C) 1995,96,97,98 Free Software Foundation, Inc. - -;; Author: Per Abrahamsen -;; Lars Magne Ingebrigtsen -;; Keywords: news, mail - -;; This file is part of GNU Emacs. - -;; GNU Emacs is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 2, or (at your option) -;; any later version. - -;; GNU Emacs is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs; see the file COPYING. If not, write to the -;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. - -;;; Commentary: - -;;; Code: - -(eval-when-compile (require 'cl)) - -(require 'gnus) -(require 'gnus-art) -(require 'message) -(require 'gnus-start) -(require 'gnus-range) - -;;; User Variables: - -(defvar gnus-soup-directory (nnheader-concat gnus-home-directory "SoupBrew/") - "*Directory containing an unpacked SOUP packet.") - -(defvar gnus-soup-replies-directory - (nnheader-concat gnus-soup-directory "SoupReplies/") - "*Directory where Gnus will do processing of replies.") - -(defvar gnus-soup-prefix-file "gnus-prefix" - "*Name of the file where Gnus stores the last used prefix.") - -(defvar gnus-soup-packer "tar cf - %s | gzip > $HOME/Soupout%d.tgz" - "Format string command for packing a SOUP packet. -The SOUP files will be inserted where the %s is in the string. -This string MUST contain both %s and %d. The file number will be -inserted where %d appears.") - -(defvar gnus-soup-unpacker "gunzip -c %s | tar xvf -" - "*Format string command for unpacking a SOUP packet. -The SOUP packet file name will be inserted at the %s.") - -(defvar gnus-soup-packet-directory gnus-home-directory - "*Where gnus-soup will look for REPLIES packets.") - -(defvar gnus-soup-packet-regexp "Soupin" - "*Regular expression matching SOUP REPLIES packets in `gnus-soup-packet-directory'.") - -(defvar gnus-soup-ignored-headers "^Xref:" - "*Regexp to match headers to be removed when brewing SOUP packets.") - -;;; Internal Variables: - -(defvar gnus-soup-encoding-type ?n - "*Soup encoding type. -`n' is news format, `m' is Unix mbox format, and `M' is MMDF mailbox -format.") - -(defvar gnus-soup-index-type ?c - "*Soup index type. -`n' means no index file and `c' means standard Cnews overview -format.") - -(defvar gnus-soup-areas nil) -(defvar gnus-soup-last-prefix nil) -(defvar gnus-soup-prev-prefix nil) -(defvar gnus-soup-buffers nil) - -;;; Access macros: - -(defmacro gnus-soup-area-prefix (area) - `(aref ,area 0)) -(defmacro gnus-soup-set-area-prefix (area prefix) - `(aset ,area 0 ,prefix)) -(defmacro gnus-soup-area-name (area) - `(aref ,area 1)) -(defmacro gnus-soup-area-encoding (area) - `(aref ,area 2)) -(defmacro gnus-soup-area-description (area) - `(aref ,area 3)) -(defmacro gnus-soup-area-number (area) - `(aref ,area 4)) -(defmacro gnus-soup-area-set-number (area value) - `(aset ,area 4 ,value)) - -(defmacro gnus-soup-encoding-format (encoding) - `(aref ,encoding 0)) -(defmacro gnus-soup-encoding-index (encoding) - `(aref ,encoding 1)) -(defmacro gnus-soup-encoding-kind (encoding) - `(aref ,encoding 2)) - -(defmacro gnus-soup-reply-prefix (reply) - `(aref ,reply 0)) -(defmacro gnus-soup-reply-kind (reply) - `(aref ,reply 1)) -(defmacro gnus-soup-reply-encoding (reply) - `(aref ,reply 2)) - -;;; Commands: - -(defun gnus-soup-send-replies () - "Unpack and send all replies in the reply packet." - (interactive) - (let ((packets (directory-files - gnus-soup-packet-directory t gnus-soup-packet-regexp))) - (while packets - (when (gnus-soup-send-packet (car packets)) - (delete-file (car packets))) - (setq packets (cdr packets))))) - -(defun gnus-soup-add-article (n) - "Add the current article to SOUP packet. -If N is a positive number, add the N next articles. -If N is a negative number, add the N previous articles. -If N is nil and any articles have been marked with the process mark, -move those articles instead." - (interactive "P") - (let* ((articles (gnus-summary-work-articles n)) - (tmp-buf (gnus-get-buffer-create "*soup work*")) - (area (gnus-soup-area gnus-newsgroup-name)) - (prefix (gnus-soup-area-prefix area)) - headers) - (buffer-disable-undo tmp-buf) - (save-excursion - (while articles - ;; Find the header of the article. - (set-buffer gnus-summary-buffer) - (when (setq headers (gnus-summary-article-header (car articles))) - ;; Put the article in a buffer. - (set-buffer tmp-buf) - (when (gnus-request-article-this-buffer - (car articles) gnus-newsgroup-name) - (save-restriction - (message-narrow-to-head) - (message-remove-header gnus-soup-ignored-headers t)) - (gnus-soup-store gnus-soup-directory prefix headers - gnus-soup-encoding-type - gnus-soup-index-type) - (gnus-soup-area-set-number - area (1+ (or (gnus-soup-area-number area) 0))))) - ;; Mark article as read. - (set-buffer gnus-summary-buffer) - (gnus-summary-remove-process-mark (car articles)) - (gnus-summary-mark-as-read (car articles) gnus-souped-mark) - (setq articles (cdr articles))) - (kill-buffer tmp-buf)) - (gnus-soup-save-areas) - (gnus-set-mode-line 'summary))) - -(defun gnus-soup-pack-packet () - "Make a SOUP packet from the SOUP areas." - (interactive) - (gnus-soup-read-areas) - (unless (file-exists-p gnus-soup-directory) - (message "No such directory: %s" gnus-soup-directory)) - (when (null (directory-files gnus-soup-directory nil "\\.MSG$")) - (message "No files to pack.")) - (gnus-soup-pack gnus-soup-directory gnus-soup-packer)) - -(defun gnus-group-brew-soup (n) - "Make a soup packet from the current group. -Uses the process/prefix convention." - (interactive "P") - (let ((groups (gnus-group-process-prefix n))) - (while groups - (gnus-group-remove-mark (car groups)) - (gnus-soup-group-brew (car groups) t) - (setq groups (cdr groups))) - (gnus-soup-save-areas))) - -(defun gnus-brew-soup (&optional level) - "Go through all groups on LEVEL or less and make a soup packet." - (interactive "P") - (let ((level (or level gnus-level-subscribed)) - (newsrc (cdr gnus-newsrc-alist))) - (while newsrc - (when (<= (nth 1 (car newsrc)) level) - (gnus-soup-group-brew (caar newsrc) t)) - (setq newsrc (cdr newsrc))) - (gnus-soup-save-areas))) - -;;;###autoload -(defun gnus-batch-brew-soup () - "Brew a SOUP packet from groups mention on the command line. -Will use the remaining command line arguments as regular expressions -for matching on group names. - -For instance, if you want to brew on all the nnml groups, as well as -groups with \"emacs\" in the name, you could say something like: - -$ emacs -batch -f gnus-batch-brew-soup ^nnml \".*emacs.*\" - -Note -- this function hasn't been implemented yet." - (interactive) - nil) - -;;; Internal Functions: - -;; Store the current buffer. -(defun gnus-soup-store (directory prefix headers format index) - ;; Create the directory, if needed. - (gnus-make-directory directory) - (let* ((msg-buf (nnheader-find-file-noselect - (concat directory prefix ".MSG"))) - (idx-buf (if (= index ?n) - nil - (nnheader-find-file-noselect - (concat directory prefix ".IDX")))) - (article-buf (current-buffer)) - from head-line beg type) - (setq gnus-soup-buffers (cons msg-buf (delq msg-buf gnus-soup-buffers))) - (buffer-disable-undo msg-buf) - (when idx-buf - (push idx-buf gnus-soup-buffers) - (buffer-disable-undo idx-buf)) - (save-excursion - ;; Make sure the last char in the buffer is a newline. - (goto-char (point-max)) - (unless (= (current-column) 0) - (insert "\n")) - ;; Find the "from". - (goto-char (point-min)) - (setq from - (gnus-mail-strip-quoted-names - (or (mail-fetch-field "from") - (mail-fetch-field "really-from") - (mail-fetch-field "sender")))) - (goto-char (point-min)) - ;; Depending on what encoding is supposed to be used, we make - ;; a soup header. - (setq head-line - (cond - ((= gnus-soup-encoding-type ?n) - (format "#! rnews %d\n" (buffer-size))) - ((= gnus-soup-encoding-type ?m) - (while (search-forward "\nFrom " nil t) - (replace-match "\n>From " t t)) - (concat "From " (or from "unknown") - " " (current-time-string) "\n")) - ((= gnus-soup-encoding-type ?M) - "\^a\^a\^a\^a\n") - (t (error "Unsupported type: %c" gnus-soup-encoding-type)))) - ;; Insert the soup header and the article in the MSG buf. - (set-buffer msg-buf) - (goto-char (point-max)) - (insert head-line) - (setq beg (point)) - (insert-buffer-substring article-buf) - ;; Insert the index in the IDX buf. - (cond ((= index ?c) - (set-buffer idx-buf) - (gnus-soup-insert-idx beg headers)) - ((/= index ?n) - (error "Unknown index type: %c" type))) - ;; Return the MSG buf. - msg-buf))) - -(defun gnus-soup-group-brew (group &optional not-all) - "Enter GROUP and add all articles to a SOUP package. -If NOT-ALL, don't pack ticked articles." - (let ((gnus-expert-user t) - (gnus-large-newsgroup nil) - (entry (gnus-gethash group gnus-newsrc-hashtb))) - (when (or (null entry) - (eq (car entry) t) - (and (car entry) - (> (car entry) 0)) - (and (not not-all) - (gnus-range-length (cdr (assq 'tick (gnus-info-marks - (nth 2 entry))))))) - (when (gnus-summary-read-group group nil t) - (setq gnus-newsgroup-processable - (reverse - (if (not not-all) - (append gnus-newsgroup-marked gnus-newsgroup-unreads) - gnus-newsgroup-unreads))) - (gnus-soup-add-article nil) - (gnus-summary-exit))))) - -(defun gnus-soup-insert-idx (offset header) - ;; [number subject from date id references chars lines xref] - (goto-char (point-max)) - (insert - (format "%d\t%s\t%s\t%s\t%s\t%s\t%d\t%s\t\t\n" - offset - (or (mail-header-subject header) "(none)") - (or (mail-header-from header) "(nobody)") - (or (mail-header-date header) "") - (or (mail-header-id header) - (concat "soup-dummy-id-" - (mapconcat - (lambda (time) (int-to-string time)) - (current-time) "-"))) - (or (mail-header-references header) "") - (or (mail-header-chars header) 0) - (or (mail-header-lines header) "0")))) - -(defun gnus-soup-save-areas () - "Write all SOUP buffers." - (interactive) - (gnus-soup-write-areas) - (save-excursion - (let (buf) - (while gnus-soup-buffers - (setq buf (car gnus-soup-buffers) - gnus-soup-buffers (cdr gnus-soup-buffers)) - (if (not (buffer-name buf)) - () - (set-buffer buf) - (when (buffer-modified-p) - (save-buffer)) - (kill-buffer (current-buffer))))) - (gnus-soup-write-prefixes))) - -(defun gnus-soup-write-prefixes () - (let ((prefixes gnus-soup-last-prefix) - prefix) - (save-excursion - (gnus-set-work-buffer) - (while (setq prefix (pop prefixes)) - (erase-buffer) - (insert (format "(setq gnus-soup-prev-prefix %d)\n" (cdr prefix))) - (gnus-write-buffer (concat (car prefix) gnus-soup-prefix-file)))))) - -(defun gnus-soup-pack (dir packer) - (let* ((files (mapconcat 'identity - '("AREAS" "*.MSG" "*.IDX" "INFO" - "LIST" "REPLIES" "COMMANDS" "ERRORS") - " ")) - (packer (if (< (string-match "%s" packer) - (string-match "%d" packer)) - (format packer files - (string-to-int (gnus-soup-unique-prefix dir))) - (format packer - (string-to-int (gnus-soup-unique-prefix dir)) - files))) - (dir (expand-file-name dir))) - (gnus-make-directory dir) - (setq gnus-soup-areas nil) - (gnus-message 4 "Packing %s..." packer) - (if (zerop (call-process shell-file-name - nil nil nil shell-command-switch - (concat "cd " dir " ; " packer))) - (progn - (call-process shell-file-name nil nil nil shell-command-switch - (concat "cd " dir " ; rm " files)) - (gnus-message 4 "Packing...done" packer)) - (error "Couldn't pack packet")))) - -(defun gnus-soup-parse-areas (file) - "Parse soup area file FILE. -The result is a of vectors, each containing one entry from the AREA file. -The vector contain five strings, - [prefix name encoding description number] -though the two last may be nil if they are missing." - (let (areas) - (when (file-exists-p file) - (save-excursion - (set-buffer (nnheader-find-file-noselect file 'force)) - (buffer-disable-undo (current-buffer)) - (goto-char (point-min)) - (while (not (eobp)) - (push (vector (gnus-soup-field) - (gnus-soup-field) - (gnus-soup-field) - (and (eq (preceding-char) ?\t) - (gnus-soup-field)) - (and (eq (preceding-char) ?\t) - (string-to-int (gnus-soup-field)))) - areas) - (when (eq (preceding-char) ?\t) - (beginning-of-line 2))) - (kill-buffer (current-buffer)))) - areas)) - -(defun gnus-soup-parse-replies (file) - "Parse soup REPLIES file FILE. -The result is a of vectors, each containing one entry from the REPLIES -file. The vector contain three strings, [prefix name encoding]." - (let (replies) - (save-excursion - (set-buffer (nnheader-find-file-noselect file)) - (buffer-disable-undo (current-buffer)) - (goto-char (point-min)) - (while (not (eobp)) - (push (vector (gnus-soup-field) (gnus-soup-field) - (gnus-soup-field)) - replies) - (when (eq (preceding-char) ?\t) - (beginning-of-line 2))) - (kill-buffer (current-buffer))) - replies)) - -(defun gnus-soup-field () - (prog1 - (buffer-substring (point) (progn (skip-chars-forward "^\t\n") (point))) - (forward-char 1))) - -(defun gnus-soup-read-areas () - (or gnus-soup-areas - (setq gnus-soup-areas - (gnus-soup-parse-areas (concat gnus-soup-directory "AREAS"))))) - -(defun gnus-soup-write-areas () - "Write the AREAS file." - (interactive) - (when gnus-soup-areas - (nnheader-temp-write (concat gnus-soup-directory "AREAS") - (let ((areas gnus-soup-areas) - area) - (while (setq area (pop areas)) - (insert - (format - "%s\t%s\t%s%s\n" - (gnus-soup-area-prefix area) - (gnus-soup-area-name area) - (gnus-soup-area-encoding area) - (if (or (gnus-soup-area-description area) - (gnus-soup-area-number area)) - (concat "\t" (or (gnus-soup-area-description - area) "") - (if (gnus-soup-area-number area) - (concat "\t" (int-to-string - (gnus-soup-area-number area))) - "")) "")))))))) - -(defun gnus-soup-write-replies (dir areas) - "Write a REPLIES file in DIR containing AREAS." - (nnheader-temp-write (concat dir "REPLIES") - (let (area) - (while (setq area (pop areas)) - (insert (format "%s\t%s\t%s\n" - (gnus-soup-reply-prefix area) - (gnus-soup-reply-kind area) - (gnus-soup-reply-encoding area))))))) - -(defun gnus-soup-area (group) - (gnus-soup-read-areas) - (let ((areas gnus-soup-areas) - (real-group (gnus-group-real-name group)) - area result) - (while areas - (setq area (car areas) - areas (cdr areas)) - (when (equal (gnus-soup-area-name area) real-group) - (setq result area))) - (unless result - (setq result - (vector (gnus-soup-unique-prefix) - real-group - (format "%c%c%c" - gnus-soup-encoding-type - gnus-soup-index-type - (if (gnus-member-of-valid 'mail group) ?m ?n)) - nil nil) - gnus-soup-areas (cons result gnus-soup-areas))) - result)) - -(defun gnus-soup-unique-prefix (&optional dir) - (let* ((dir (file-name-as-directory (or dir gnus-soup-directory))) - (entry (assoc dir gnus-soup-last-prefix)) - gnus-soup-prev-prefix) - (if entry - () - (when (file-exists-p (concat dir gnus-soup-prefix-file)) - (ignore-errors - (load (concat dir gnus-soup-prefix-file) nil t t))) - (push (setq entry (cons dir (or gnus-soup-prev-prefix 0))) - gnus-soup-last-prefix)) - (setcdr entry (1+ (cdr entry))) - (gnus-soup-write-prefixes) - (int-to-string (cdr entry)))) - -(defun gnus-soup-unpack-packet (dir unpacker packet) - "Unpack PACKET into DIR using UNPACKER. -Return whether the unpacking was successful." - (gnus-make-directory dir) - (gnus-message 4 "Unpacking: %s" (format unpacker packet)) - (prog1 - (zerop (call-process - shell-file-name nil nil nil shell-command-switch - (format "cd %s ; %s" (expand-file-name dir) - (format unpacker packet)))) - (gnus-message 4 "Unpacking...done"))) - -(defun gnus-soup-send-packet (packet) - (gnus-soup-unpack-packet - gnus-soup-replies-directory gnus-soup-unpacker packet) - (let ((replies (gnus-soup-parse-replies - (concat gnus-soup-replies-directory "REPLIES")))) - (save-excursion - (while replies - (let* ((msg-file (concat gnus-soup-replies-directory - (gnus-soup-reply-prefix (car replies)) - ".MSG")) - (msg-buf (and (file-exists-p msg-file) - (nnheader-find-file-noselect msg-file))) - (tmp-buf (gnus-get-buffer-create " *soup send*")) - beg end) - (cond - ((/= (gnus-soup-encoding-format - (gnus-soup-reply-encoding (car replies))) - ?n) - (error "Unsupported encoding")) - ((null msg-buf) - t) - (t - (buffer-disable-undo msg-buf) - (set-buffer msg-buf) - (goto-char (point-min)) - (while (not (eobp)) - (unless (looking-at "#! *rnews +\\([0-9]+\\)") - (error "Bad header")) - (forward-line 1) - (setq beg (point) - end (+ (point) (string-to-int - (buffer-substring - (match-beginning 1) (match-end 1))))) - (switch-to-buffer tmp-buf) - (erase-buffer) - (insert-buffer-substring msg-buf beg end) - (goto-char (point-min)) - (search-forward "\n\n") - (forward-char -1) - (insert mail-header-separator) - (setq message-user-agent (gnus-extended-version)) - (cond - ((string= (gnus-soup-reply-kind (car replies)) "news") - (gnus-message 5 "Sending news message to %s..." - (mail-fetch-field "newsgroups")) - (sit-for 1) - (let ((message-syntax-checks - 'dont-check-for-anything-just-trust-me)) - (funcall message-send-news-function))) - ((string= (gnus-soup-reply-kind (car replies)) "mail") - (gnus-message 5 "Sending mail to %s..." - (mail-fetch-field "to")) - (sit-for 1) - (message-send-mail)) - (t - (error "Unknown reply kind"))) - (set-buffer msg-buf) - (goto-char end)) - (delete-file (buffer-file-name)) - (kill-buffer msg-buf) - (kill-buffer tmp-buf) - (gnus-message 4 "Sent packet")))) - (setq replies (cdr replies))) - t))) - -(provide 'gnus-soup) - -;;; gnus-soup.el ends here diff --git a/lisp/gnus-spec.el b/lisp/gnus-spec.el deleted file mode 100644 index 2a1e355..0000000 --- a/lisp/gnus-spec.el +++ /dev/null @@ -1,546 +0,0 @@ -;;; gnus-spec.el --- format spec functions for Gnus -;; Copyright (C) 1996,97,98 Free Software Foundation, Inc. - -;; Author: Lars Magne Ingebrigtsen -;; Keywords: news - -;; This file is part of GNU Emacs. - -;; GNU Emacs is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 2, or (at your option) -;; any later version. - -;; GNU Emacs is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs; see the file COPYING. If not, write to the -;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. - -;;; Commentary: - -;;; Code: - -(eval-when-compile (require 'cl)) - -(require 'gnus) - -;;; Internal variables. - -(defvar gnus-summary-mark-positions nil) -(defvar gnus-group-mark-positions nil) -(defvar gnus-group-indentation "") - -;; Format specs. The chunks below are the machine-generated forms -;; that are to be evaled as the result of the default format strings. -;; We write them in here to get them byte-compiled. That way the -;; default actions will be quite fast, while still retaining the full -;; flexibility of the user-defined format specs. - -;; First we have lots of dummy defvars to let the compiler know these -;; are really dynamic variables. - -(defvar gnus-tmp-unread) -(defvar gnus-tmp-replied) -(defvar gnus-tmp-score-char) -(defvar gnus-tmp-indentation) -(defvar gnus-tmp-opening-bracket) -(defvar gnus-tmp-lines) -(defvar gnus-tmp-name) -(defvar gnus-tmp-closing-bracket) -(defvar gnus-tmp-subject-or-nil) -(defvar gnus-tmp-subject) -(defvar gnus-tmp-marked) -(defvar gnus-tmp-marked-mark) -(defvar gnus-tmp-subscribed) -(defvar gnus-tmp-process-marked) -(defvar gnus-tmp-number-of-unread) -(defvar gnus-tmp-group-name) -(defvar gnus-tmp-group) -(defvar gnus-tmp-article-number) -(defvar gnus-tmp-unread-and-unselected) -(defvar gnus-tmp-news-method) -(defvar gnus-tmp-news-server) -(defvar gnus-tmp-article-number) -(defvar gnus-mouse-face) -(defvar gnus-mouse-face-prop) - -(defun gnus-summary-line-format-spec () - (insert gnus-tmp-unread gnus-tmp-replied - gnus-tmp-score-char gnus-tmp-indentation) - (gnus-put-text-property - (point) - (progn - (insert - gnus-tmp-opening-bracket - (format "%4d: %-20s" - gnus-tmp-lines - (if (> (length gnus-tmp-name) 20) - (substring gnus-tmp-name 0 20) - gnus-tmp-name)) - gnus-tmp-closing-bracket) - (point)) - gnus-mouse-face-prop gnus-mouse-face) - (insert " " gnus-tmp-subject-or-nil "\n")) - -(defvar gnus-summary-line-format-spec - (gnus-byte-code 'gnus-summary-line-format-spec)) - -(defun gnus-summary-dummy-line-format-spec () - (insert "* ") - (gnus-put-text-property - (point) - (progn - (insert ": :") - (point)) - gnus-mouse-face-prop gnus-mouse-face) - (insert " " gnus-tmp-subject "\n")) - -(defvar gnus-summary-dummy-line-format-spec - (gnus-byte-code 'gnus-summary-dummy-line-format-spec)) - -(defun gnus-group-line-format-spec () - (insert gnus-tmp-marked-mark gnus-tmp-subscribed - gnus-tmp-process-marked - gnus-group-indentation - (format "%5s: " gnus-tmp-number-of-unread)) - (gnus-put-text-property - (point) - (progn - (insert gnus-tmp-group "\n") - (1- (point))) - gnus-mouse-face-prop gnus-mouse-face)) -(defvar gnus-group-line-format-spec - (gnus-byte-code 'gnus-group-line-format-spec)) - -(defvar gnus-format-specs - `((version . ,emacs-version) - (group "%M\%S\%p\%P\%5y: %(%g%)%l\n" ,gnus-group-line-format-spec) - (summary-dummy "* %(: :%) %S\n" - ,gnus-summary-dummy-line-format-spec) - (summary "%U\%R\%z\%I\%(%[%4L: %-20,20n%]%) %s\n" - ,gnus-summary-line-format-spec)) - "Alist of format specs.") - -(defvar gnus-article-mode-line-format-spec nil) -(defvar gnus-summary-mode-line-format-spec nil) -(defvar gnus-group-mode-line-format-spec nil) - -;;; Phew. All that gruft is over, fortunately. - -;;;###autoload -(defun gnus-update-format (var) - "Update the format specification near point." - (interactive - (list - (save-excursion - (eval-defun nil) - ;; Find the end of the current word. - (re-search-forward "[ \t\n]" nil t) - ;; Search backward. - (when (re-search-backward "\\(gnus-[-a-z]+-line-format\\)" nil t) - (match-string 1))))) - (let* ((type (intern (progn (string-match "gnus-\\([-a-z]+\\)-line" var) - (match-string 1 var)))) - (entry (assq type gnus-format-specs)) - value spec) - (when entry - (setq gnus-format-specs (delq entry gnus-format-specs))) - (set - (intern (format "%s-spec" var)) - (gnus-parse-format (setq value (symbol-value (intern var))) - (symbol-value (intern (format "%s-alist" var))) - (not (string-match "mode" var)))) - (setq spec (symbol-value (intern (format "%s-spec" var)))) - (push (list type value spec) gnus-format-specs) - - (pop-to-buffer "*Gnus Format*") - (erase-buffer) - (lisp-interaction-mode) - (insert (pp-to-string spec)))) - -(defun gnus-update-format-specifications (&optional force &rest types) - "Update all (necessary) format specifications." - ;; Make the indentation array. - ;; See whether all the stored info needs to be flushed. - (when (or force - (not (equal emacs-version - (cdr (assq 'version gnus-format-specs))))) - (setq gnus-format-specs nil)) - - ;; Go through all the formats and see whether they need updating. - (let (new-format entry type val) - (while (setq type (pop types)) - ;; Jump to the proper buffer to find out the value of - ;; the variable, if possible. (It may be buffer-local.) - (save-excursion - (let ((buffer (intern (format "gnus-%s-buffer" type))) - val) - (when (and (boundp buffer) - (setq val (symbol-value buffer)) - (gnus-buffer-exists-p val)) - (set-buffer val)) - (setq new-format (symbol-value - (intern (format "gnus-%s-line-format" type))))) - (setq entry (cdr (assq type gnus-format-specs))) - (if (and (car entry) - (equal (car entry) new-format)) - ;; Use the old format. - (set (intern (format "gnus-%s-line-format-spec" type)) - (cadr entry)) - ;; This is a new format. - (setq val - (if (not (stringp new-format)) - ;; This is a function call or something. - new-format - ;; This is a "real" format. - (gnus-parse-format - new-format - (symbol-value - (intern (format "gnus-%s-line-format-alist" - (if (eq type 'article-mode) - 'summary-mode type)))) - (not (string-match "mode$" (symbol-name type)))))) - ;; Enter the new format spec into the list. - (if entry - (progn - (setcar (cdr entry) val) - (setcar entry new-format)) - (push (list type new-format val) gnus-format-specs)) - (set (intern (format "gnus-%s-line-format-spec" type)) val))))) - - (unless (assq 'version gnus-format-specs) - (push (cons 'version emacs-version) gnus-format-specs))) - -(defvar gnus-mouse-face-0 'highlight) -(defvar gnus-mouse-face-1 'highlight) -(defvar gnus-mouse-face-2 'highlight) -(defvar gnus-mouse-face-3 'highlight) -(defvar gnus-mouse-face-4 'highlight) - -(defun gnus-mouse-face-function (form type) - `(gnus-put-text-property - (point) (progn ,@form (point)) - gnus-mouse-face-prop - ,(if (equal type 0) - 'gnus-mouse-face - `(quote ,(symbol-value (intern (format "gnus-mouse-face-%d" type))))))) - -(defvar gnus-face-0 'bold) -(defvar gnus-face-1 'italic) -(defvar gnus-face-2 'bold-italic) -(defvar gnus-face-3 'bold) -(defvar gnus-face-4 'bold) - -(defun gnus-face-face-function (form type) - `(gnus-add-text-properties - (point) (progn ,@form (point)) - '(gnus-face t face ,(symbol-value (intern (format "gnus-face-%d" type)))))) - -(defun gnus-tilde-max-form (el max-width) - "Return a form that limits EL to MAX-WIDTH." - (let ((max (abs max-width))) - (if (symbolp el) - `(if (> (length ,el) ,max) - ,(if (< max-width 0) - `(substring ,el (- (length el) ,max)) - `(substring ,el 0 ,max)) - ,el) - `(let ((val (eval ,el))) - (if (> (length val) ,max) - ,(if (< max-width 0) - `(substring val (- (length val) ,max)) - `(substring val 0 ,max)) - val))))) - -(defun gnus-tilde-cut-form (el cut-width) - "Return a form that cuts CUT-WIDTH off of EL." - (let ((cut (abs cut-width))) - (if (symbolp el) - `(if (> (length ,el) ,cut) - ,(if (< cut-width 0) - `(substring ,el 0 (- (length el) ,cut)) - `(substring ,el ,cut)) - ,el) - `(let ((val (eval ,el))) - (if (> (length val) ,cut) - ,(if (< cut-width 0) - `(substring val 0 (- (length val) ,cut)) - `(substring val ,cut)) - val))))) - -(defun gnus-tilde-ignore-form (el ignore-value) - "Return a form that is blank when EL is IGNORE-VALUE." - (if (symbolp el) - `(if (equal ,el ,ignore-value) - "" ,el) - `(let ((val (eval ,el))) - (if (equal val ,ignore-value) - "" val)))) - -(defun gnus-parse-format (format spec-alist &optional insert) - ;; This function parses the FORMAT string with the help of the - ;; SPEC-ALIST and returns a list that can be eval'ed to return the - ;; string. If the FORMAT string contains the specifiers %( and %) - ;; the text between them will have the mouse-face text property. - (if (string-match - "\\`\\(.*\\)%[0-9]?[{(]\\(.*\\)%[0-9]?[})]\\(.*\n?\\)\\'" - format) - (gnus-parse-complex-format format spec-alist) - ;; This is a simple format. - (gnus-parse-simple-format format spec-alist insert))) - -(defun gnus-parse-complex-format (format spec-alist) - (save-excursion - (gnus-set-work-buffer) - (insert format) - (goto-char (point-min)) - (while (re-search-forward "\"" nil t) - (replace-match "\\\"" nil t)) - (goto-char (point-min)) - (insert "(\"") - (while (re-search-forward "%\\([0-9]+\\)?\\([{}()]\\)" nil t) - (let ((number (if (match-beginning 1) - (match-string 1) "0")) - (delim (aref (match-string 2) 0))) - (if (or (= delim ?\() - (= delim ?\{)) - (replace-match (concat "\"(" (if (= delim ?\() "mouse" "face") - " " number " \"")) - (replace-match "\")\"")))) - (goto-char (point-max)) - (insert "\")") - (goto-char (point-min)) - (let ((form (read (current-buffer)))) - (cons 'progn (gnus-complex-form-to-spec form spec-alist))))) - -(defun gnus-complex-form-to-spec (form spec-alist) - (delq nil - (mapcar - (lambda (sform) - (if (stringp sform) - (gnus-parse-simple-format sform spec-alist t) - (funcall (intern (format "gnus-%s-face-function" (car sform))) - (gnus-complex-form-to-spec (cddr sform) spec-alist) - (nth 1 sform)))) - form))) - -(defun gnus-parse-simple-format (format spec-alist &optional insert) - ;; This function parses the FORMAT string with the help of the - ;; SPEC-ALIST and returns a list that can be eval'ed to return a - ;; string. - (let (max-width - spec flist fstring elem result dontinsert user-defined - type value pad-width spec-beg cut-width ignore-value - tilde-form tilde elem-type - (xemacs-mule-p (and gnus-xemacs (featurep 'mule)))) - (save-excursion - (gnus-set-work-buffer) - (insert format) - (goto-char (point-min)) - (while (search-forward "%" nil t) - (setq user-defined nil - spec-beg nil - pad-width nil - max-width nil - cut-width nil - ignore-value nil - tilde-form nil) - (setq spec-beg (1- (point))) - - ;; Parse this spec fully. - (while - (cond - ((looking-at "\\([-.0-9]+\\)\\(,[-0-9]+\\)?") - (setq pad-width (string-to-number (match-string 1))) - (when (match-beginning 2) - (setq max-width (string-to-number (buffer-substring - (1+ (match-beginning 2)) - (match-end 2))))) - (goto-char (match-end 0))) - ((looking-at "~") - (forward-char 1) - (setq tilde (read (current-buffer)) - type (car tilde) - value (cadr tilde)) - (cond - ((memq type '(pad pad-left)) - (setq pad-width value)) - ((eq type 'pad-right) - (setq pad-width (- value))) - ((memq type '(max-right max)) - (setq max-width value)) - ((eq type 'max-left) - (setq max-width (- value))) - ((memq type '(cut cut-left)) - (setq cut-width value)) - ((eq type 'cut-right) - (setq cut-width (- value))) - ((eq type 'ignore) - (setq ignore-value - (if (stringp value) value (format "%s" value)))) - ((eq type 'form) - (setq tilde-form value)) - (t - (error "Unknown tilde type: %s" tilde))) - t) - (t - nil))) - ;; User-defined spec -- find the spec name. - (when (= (setq spec (following-char)) ?u) - (forward-char 1) - (setq user-defined (following-char))) - (forward-char 1) - (delete-region spec-beg (point)) - - ;; Now we have all the relevant data on this spec, so - ;; we start doing stuff. - (insert "%") - (if (eq spec ?%) - ;; "%%" just results in a "%". - (insert "%") - (cond - ;; Do tilde forms. - ((eq spec ?@) - (setq elem (list tilde-form ?s))) - ;; Treat user defined format specifiers specially. - (user-defined - (setq elem - (list - (list (intern (format "gnus-user-format-function-%c" - user-defined)) - 'gnus-tmp-header) - ?s))) - ;; Find the specification from `spec-alist'. - ((setq elem (cdr (assq spec spec-alist)))) - (t - (setq elem '("*" ?s)))) - (setq elem-type (cadr elem)) - ;; Insert the new format elements. - (and pad-width (not xemacs-mule-p) - (insert (number-to-string pad-width))) - ;; Create the form to be evaled. - (if (or max-width cut-width ignore-value - (and pad-width xemacs-mule-p)) - (progn - (insert ?s) - (let ((el (car elem))) - (cond ((= (cadr elem) ?c) - (setq el (list 'char-to-string el))) - ((= (cadr elem) ?d) - (setq el (list 'int-to-string el)))) - (when ignore-value - (setq el (gnus-tilde-ignore-form el ignore-value))) - (when cut-width - (setq el (gnus-tilde-cut-form el cut-width))) - (when max-width - (setq el (gnus-tilde-max-form el max-width))) - (and pad-width xemacs-mule-p - (setq el (gnus-tilde-pad-form el pad-width))) - (push el flist))) - (insert elem-type) - (push (car elem) flist)))) - (setq fstring (buffer-string))) - - ;; Do some postprocessing to increase efficiency. - (setq - result - (cond - ;; Emptyness. - ((string= fstring "") - nil) - ;; Not a format string. - ((not (string-match "%" fstring)) - (list fstring)) - ;; A format string with just a single string spec. - ((string= fstring "%s") - (list (car flist))) - ;; A single character. - ((string= fstring "%c") - (list (car flist))) - ;; A single number. - ((string= fstring "%d") - (setq dontinsert) - (if insert - (list `(princ ,(car flist))) - (list `(int-to-string ,(car flist))))) - ;; Just lots of chars and strings. - ((string-match "\\`\\(%[cs]\\)+\\'" fstring) - (nreverse flist)) - ;; A single string spec at the beginning of the spec. - ((string-match "\\`%[sc][^%]+\\'" fstring) - (list (car flist) (substring fstring 2))) - ;; A single string spec in the middle of the spec. - ((string-match "\\`\\([^%]+\\)%[sc]\\([^%]+\\)\\'" fstring) - (list (match-string 1 fstring) (car flist) (match-string 2 fstring))) - ;; A single string spec in the end of the spec. - ((string-match "\\`\\([^%]+\\)%[sc]\\'" fstring) - (list (match-string 1 fstring) (car flist))) - ;; A more complex spec. - (t - (list (cons 'format (cons fstring (nreverse flist))))))) - - (if insert - (when result - (if dontinsert - result - (cons 'insert result))) - (cond ((stringp result) - result) - ((consp result) - (cons 'concat result)) - (t ""))))) - -(defun gnus-eval-format (format &optional alist props) - "Eval the format variable FORMAT, using ALIST. -If PROPS, insert the result." - (let ((form (gnus-parse-format format alist props))) - (if props - (gnus-add-text-properties (point) (progn (eval form) (point)) props) - (eval form)))) - -(defun gnus-compile () - "Byte-compile the user-defined format specs." - (interactive) - (require 'bytecomp) - (let ((entries gnus-format-specs) - (byte-compile-warnings '(unresolved callargs redefine)) - entry gnus-tmp-func) - (save-excursion - (gnus-message 7 "Compiling format specs...") - - (while entries - (setq entry (pop entries)) - (if (eq (car entry) 'version) - (setq gnus-format-specs (delq entry gnus-format-specs)) - (let ((form (caddr entry))) - (when (and (listp form) - ;; Under GNU Emacs, it's (byte-code ...) - (not (eq 'byte-code (car form))) - ;; Under XEmacs, it's (funcall #) - (not (and (eq 'funcall (car form)) - (compiled-function-p (cadr form))))) - (fset 'gnus-tmp-func `(lambda () ,form)) - (byte-compile 'gnus-tmp-func) - (setcar (cddr entry) (gnus-byte-code 'gnus-tmp-func)))))) - - (push (cons 'version emacs-version) gnus-format-specs) - ;; Mark the .newsrc.eld file as "dirty". - (gnus-dribble-touch) - (gnus-message 7 "Compiling user specs...done")))) - -(defun gnus-set-format (type &optional insertable) - (set (intern (format "gnus-%s-line-format-spec" type)) - (gnus-parse-format - (symbol-value (intern (format "gnus-%s-line-format" type))) - (symbol-value (intern (format "gnus-%s-line-format-alist" type))) - insertable))) - - -(provide 'gnus-spec) - -;;; gnus-spec.el ends here diff --git a/lisp/gnus-srvr.el b/lisp/gnus-srvr.el deleted file mode 100644 index 21abf17..0000000 --- a/lisp/gnus-srvr.el +++ /dev/null @@ -1,775 +0,0 @@ -;;; gnus-srvr.el --- virtual server support for Gnus -;; Copyright (C) 1995,96,97,98 Free Software Foundation, Inc. - -;; Author: Lars Magne Ingebrigtsen -;; Keywords: news - -;; This file is part of GNU Emacs. - -;; GNU Emacs is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 2, or (at your option) -;; any later version. - -;; GNU Emacs is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs; see the file COPYING. If not, write to the -;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. - -;;; Commentary: - -;;; Code: - -(eval-when-compile (require 'cl)) - -(require 'gnus) -(require 'gnus-spec) -(require 'gnus-group) -(require 'gnus-int) -(require 'gnus-range) - -(defvar gnus-server-mode-hook nil - "Hook run in `gnus-server-mode' buffers.") - -(defconst gnus-server-line-format " {%(%h:%w%)} %s\n" - "Format of server lines. -It works along the same lines as a normal formatting string, -with some simple extensions. - -The following specs are understood: - -%h backend -%n name -%w address -%s status") - -(defvar gnus-server-mode-line-format "Gnus: %%b" - "The format specification for the server mode line.") - -(defvar gnus-server-exit-hook nil - "*Hook run when exiting the server buffer.") - -;;; Internal variables. - -(defvar gnus-inserted-opened-servers nil) - -(defvar gnus-server-line-format-alist - `((?h gnus-tmp-how ?s) - (?n gnus-tmp-name ?s) - (?w gnus-tmp-where ?s) - (?s gnus-tmp-status ?s))) - -(defvar gnus-server-mode-line-format-alist - `((?S gnus-tmp-news-server ?s) - (?M gnus-tmp-news-method ?s) - (?u gnus-tmp-user-defined ?s))) - -(defvar gnus-server-line-format-spec nil) -(defvar gnus-server-mode-line-format-spec nil) -(defvar gnus-server-killed-servers nil) - -(defvar gnus-server-mode-map) - -(defvar gnus-server-menu-hook nil - "*Hook run after the creation of the server mode menu.") - -(defun gnus-server-make-menu-bar () - (gnus-turn-off-edit-menu 'server) - (unless (boundp 'gnus-server-server-menu) - (easy-menu-define - gnus-server-server-menu gnus-server-mode-map "" - '("Server" - ["Add" gnus-server-add-server t] - ["Browse" gnus-server-read-server t] - ["Scan" gnus-server-scan-server t] - ["List" gnus-server-list-servers t] - ["Kill" gnus-server-kill-server t] - ["Yank" gnus-server-yank-server t] - ["Copy" gnus-server-copy-server t] - ["Edit" gnus-server-edit-server t] - ["Regenerate" gnus-server-regenerate-server t] - ["Exit" gnus-server-exit t])) - - (easy-menu-define - gnus-server-connections-menu gnus-server-mode-map "" - '("Connections" - ["Open" gnus-server-open-server t] - ["Close" gnus-server-close-server t] - ["Deny" gnus-server-deny-server t] - "---" - ["Open All" gnus-server-open-all-servers t] - ["Close All" gnus-server-close-all-servers t] - ["Reset All" gnus-server-remove-denials t])) - - (gnus-run-hooks 'gnus-server-menu-hook))) - -(defvar gnus-server-mode-map nil) -(put 'gnus-server-mode 'mode-class 'special) - -(unless gnus-server-mode-map - (setq gnus-server-mode-map (make-sparse-keymap)) - (suppress-keymap gnus-server-mode-map) - - (gnus-define-keys gnus-server-mode-map - " " gnus-server-read-server - "\r" gnus-server-read-server - gnus-mouse-2 gnus-server-pick-server - "q" gnus-server-exit - "l" gnus-server-list-servers - "k" gnus-server-kill-server - "y" gnus-server-yank-server - "c" gnus-server-copy-server - "a" gnus-server-add-server - "e" gnus-server-edit-server - "s" gnus-server-scan-server - - "O" gnus-server-open-server - "\M-o" gnus-server-open-all-servers - "C" gnus-server-close-server - "\M-c" gnus-server-close-all-servers - "D" gnus-server-deny-server - "R" gnus-server-remove-denials - - "g" gnus-server-regenerate-server - - "\C-c\C-i" gnus-info-find-node - "\C-c\C-b" gnus-bug)) - -(defun gnus-server-mode () - "Major mode for listing and editing servers. - -All normal editing commands are switched off. -\\ -For more in-depth information on this mode, read the manual -(`\\[gnus-info-find-node]'). - -The following commands are available: - -\\{gnus-server-mode-map}" - (interactive) - (when (gnus-visual-p 'server-menu 'menu) - (gnus-server-make-menu-bar)) - (kill-all-local-variables) - (gnus-simplify-mode-line) - (setq major-mode 'gnus-server-mode) - (setq mode-name "Server") - (gnus-set-default-directory) - (setq mode-line-process nil) - (use-local-map gnus-server-mode-map) - (buffer-disable-undo (current-buffer)) - (setq truncate-lines t) - (setq buffer-read-only t) - (gnus-run-hooks 'gnus-server-mode-hook)) - -(defun gnus-server-insert-server-line (gnus-tmp-name method) - (let* ((gnus-tmp-how (car method)) - (gnus-tmp-where (nth 1 method)) - (elem (assoc method gnus-opened-servers)) - (gnus-tmp-status (cond ((eq (nth 1 elem) 'denied) - "(denied)") - ((or (gnus-server-opened method) - (eq (nth 1 elem) 'ok)) - "(opened)") - (t - "(closed)")))) - (beginning-of-line) - (gnus-add-text-properties - (point) - (prog1 (1+ (point)) - ;; Insert the text. - (eval gnus-server-line-format-spec)) - (list 'gnus-server (intern gnus-tmp-name))))) - -(defun gnus-enter-server-buffer () - "Set up the server buffer." - (gnus-server-setup-buffer) - (gnus-configure-windows 'server) - (gnus-server-prepare)) - -(defun gnus-server-setup-buffer () - "Initialize the server buffer." - (unless (get-buffer gnus-server-buffer) - (save-excursion - (set-buffer (gnus-get-buffer-create gnus-server-buffer)) - (gnus-server-mode) - (when gnus-carpal - (gnus-carpal-setup-buffer 'server))))) - -(defun gnus-server-prepare () - (gnus-set-format 'server-mode) - (gnus-set-format 'server t) - (let ((alist gnus-server-alist) - (buffer-read-only nil) - (opened gnus-opened-servers) - done server op-ser) - (erase-buffer) - (setq gnus-inserted-opened-servers nil) - ;; First we do the real list of servers. - (while alist - (unless (member (cdar alist) done) - (push (cdar alist) done) - (cdr (setq server (pop alist))) - (when (and server (car server) (cdr server)) - (gnus-server-insert-server-line (car server) (cdr server)))) - (when (member (cdar alist) done) - (pop alist))) - ;; Then we insert the list of servers that have been opened in - ;; this session. - (while opened - (when (and (not (member (caar opened) done)) - ;; Just ignore ephemeral servers. - (not (member (caar opened) gnus-ephemeral-servers))) - (push (caar opened) done) - (gnus-server-insert-server-line - (setq op-ser (format "%s:%s" (caaar opened) (nth 1 (caar opened)))) - (caar opened)) - (push (list op-ser (caar opened)) gnus-inserted-opened-servers)) - (setq opened (cdr opened)))) - (goto-char (point-min)) - (gnus-server-position-point)) - -(defun gnus-server-server-name () - (let ((server (get-text-property (gnus-point-at-bol) 'gnus-server))) - (and server (symbol-name server)))) - -(defalias 'gnus-server-position-point 'gnus-goto-colon) - -(defconst gnus-server-edit-buffer "*Gnus edit server*") - -(defun gnus-server-update-server (server) - (save-excursion - (set-buffer gnus-server-buffer) - (let* ((buffer-read-only nil) - (entry (assoc server gnus-server-alist)) - (oentry (assoc (gnus-server-to-method server) - gnus-opened-servers))) - (when entry - (gnus-dribble-enter - (concat "(gnus-server-set-info \"" server "\" '" - (prin1-to-string (cdr entry)) ")\n"))) - (when (or entry oentry) - ;; Buffer may be narrowed. - (save-restriction - (widen) - (when (gnus-server-goto-server server) - (gnus-delete-line)) - (if entry - (gnus-server-insert-server-line (car entry) (cdr entry)) - (gnus-server-insert-server-line - (format "%s:%s" (caar oentry) (nth 1 (car oentry))) - (car oentry))) - (gnus-server-position-point)))))) - -(defun gnus-server-set-info (server info) - ;; Enter a select method into the virtual server alist. - (when (and server info) - (gnus-dribble-enter - (concat "(gnus-server-set-info \"" server "\" '" - (prin1-to-string info) ")")) - (let* ((server (nth 1 info)) - (entry (assoc server gnus-server-alist))) - (if entry (setcdr entry info) - (setq gnus-server-alist - (nconc gnus-server-alist (list (cons server info)))))))) - -;;; Interactive server functions. - -(defun gnus-server-kill-server (server) - "Kill the server on the current line." - (interactive (list (gnus-server-server-name))) - (unless (gnus-server-goto-server server) - (if server (error "No such server: %s" server) - (error "No server on the current line"))) - (unless (assoc server gnus-server-alist) - (error "Read-only server %s" server)) - (gnus-dribble-touch) - (let ((buffer-read-only nil)) - (gnus-delete-line)) - (push (assoc server gnus-server-alist) gnus-server-killed-servers) - (setq gnus-server-alist (delq (car gnus-server-killed-servers) - gnus-server-alist)) - (gnus-server-position-point)) - -(defun gnus-server-yank-server () - "Yank the previously killed server." - (interactive) - (unless gnus-server-killed-servers - (error "No killed servers to be yanked")) - (let ((alist gnus-server-alist) - (server (gnus-server-server-name)) - (killed (car gnus-server-killed-servers))) - (if (not server) - (setq gnus-server-alist (nconc gnus-server-alist (list killed))) - (if (string= server (caar gnus-server-alist)) - (push killed gnus-server-alist) - (while (and (cdr alist) - (not (string= server (caadr alist)))) - (setq alist (cdr alist))) - (if alist - (setcdr alist (cons killed (cdr alist))) - (setq gnus-server-alist (list killed))))) - (gnus-server-update-server (car killed)) - (setq gnus-server-killed-servers (cdr gnus-server-killed-servers)) - (gnus-server-position-point))) - -(defun gnus-server-exit () - "Return to the group buffer." - (interactive) - (gnus-run-hooks 'gnus-server-exit-hook) - (kill-buffer (current-buffer)) - (gnus-configure-windows 'group t)) - -(defun gnus-server-list-servers () - "List all available servers." - (interactive) - (let ((cur (gnus-server-server-name))) - (gnus-server-prepare) - (if cur (gnus-server-goto-server cur) - (goto-char (point-max)) - (forward-line -1)) - (gnus-server-position-point))) - -(defun gnus-server-set-status (method status) - "Make METHOD have STATUS." - (let ((entry (assoc method gnus-opened-servers))) - (if entry - (setcar (cdr entry) status) - (push (list method status) gnus-opened-servers)))) - -(defun gnus-opened-servers-remove (method) - "Remove METHOD from the list of opened servers." - (setq gnus-opened-servers (delq (assoc method gnus-opened-servers) - gnus-opened-servers))) - -(defun gnus-server-open-server (server) - "Force an open of SERVER." - (interactive (list (gnus-server-server-name))) - (let ((method (gnus-server-to-method server))) - (unless method - (error "No such server: %s" server)) - (gnus-server-set-status method 'ok) - (prog1 - (or (gnus-open-server method) - (progn (message "Couldn't open %s" server) nil)) - (gnus-server-update-server server) - (gnus-server-position-point)))) - -(defun gnus-server-open-all-servers () - "Open all servers." - (interactive) - (let ((servers gnus-inserted-opened-servers)) - (while servers - (gnus-server-open-server (car (pop servers)))))) - -(defun gnus-server-close-server (server) - "Close SERVER." - (interactive (list (gnus-server-server-name))) - (let ((method (gnus-server-to-method server))) - (unless method - (error "No such server: %s" server)) - (gnus-server-set-status method 'closed) - (prog1 - (gnus-close-server method) - (gnus-server-update-server server) - (gnus-server-position-point)))) - -(defun gnus-server-close-all-servers () - "Close all servers." - (interactive) - (let ((servers gnus-inserted-opened-servers)) - (while servers - (gnus-server-close-server (car (pop servers)))))) - -(defun gnus-server-deny-server (server) - "Make sure SERVER will never be attempted opened." - (interactive (list (gnus-server-server-name))) - (let ((method (gnus-server-to-method server))) - (unless method - (error "No such server: %s" server)) - (gnus-server-set-status method 'denied)) - (gnus-server-update-server server) - (gnus-server-position-point) - t) - -(defun gnus-server-remove-denials () - "Make all denied servers into closed servers." - (interactive) - (let ((servers gnus-opened-servers)) - (while servers - (when (eq (nth 1 (car servers)) 'denied) - (setcar (nthcdr 1 (car servers)) 'closed)) - (setq servers (cdr servers)))) - (gnus-server-list-servers)) - -(defun gnus-server-copy-server (from to) - (interactive - (list - (or (gnus-server-server-name) - (error "No server on the current line")) - (read-string "Copy to: "))) - (unless from - (error "No server on current line")) - (unless (and to (not (string= to ""))) - (error "No name to copy to")) - (when (assoc to gnus-server-alist) - (error "%s already exists" to)) - (unless (gnus-server-to-method from) - (error "%s: no such server" from)) - (let ((to-entry (cons from (gnus-copy-sequence - (gnus-server-to-method from))))) - (setcar to-entry to) - (setcar (nthcdr 2 to-entry) to) - (push to-entry gnus-server-killed-servers) - (gnus-server-yank-server))) - -(defun gnus-server-add-server (how where) - (interactive - (list (intern (completing-read "Server method: " - gnus-valid-select-methods nil t)) - (read-string "Server name: "))) - (when (assq where gnus-server-alist) - (error "Server with that name already defined")) - (push (list where how where) gnus-server-killed-servers) - (gnus-server-yank-server)) - -(defun gnus-server-goto-server (server) - "Jump to a server line." - (interactive - (list (completing-read "Goto server: " gnus-server-alist nil t))) - (let ((to (text-property-any (point-min) (point-max) - 'gnus-server (intern server)))) - (when to - (goto-char to) - (gnus-server-position-point)))) - -(defun gnus-server-edit-server (server) - "Edit the server on the current line." - (interactive (list (gnus-server-server-name))) - (unless server - (error "No server on current line")) - (unless (assoc server gnus-server-alist) - (error "This server can't be edited")) - (let ((info (cdr (assoc server gnus-server-alist)))) - (gnus-close-server info) - (gnus-edit-form - info "Editing the server." - `(lambda (form) - (gnus-server-set-info ,server form) - (gnus-server-list-servers) - (gnus-server-position-point))))) - -(defun gnus-server-scan-server (server) - "Request a scan from the current server." - (interactive (list (gnus-server-server-name))) - (let ((method (gnus-server-to-method server))) - (if (not (gnus-get-function method 'request-scan)) - (error "Server %s can't scan" (car method)) - (gnus-message 3 "Scanning %s..." server) - (gnus-request-scan nil method) - (gnus-message 3 "Scanning %s...done" server)))) - -(defun gnus-server-read-server (server) - "Browse a server." - (interactive (list (gnus-server-server-name))) - (let ((buf (current-buffer))) - (prog1 - (gnus-browse-foreign-server server buf) - (save-excursion - (set-buffer buf) - (gnus-server-update-server (gnus-server-server-name)) - (gnus-server-position-point))))) - -(defun gnus-server-pick-server (e) - (interactive "e") - (mouse-set-point e) - (gnus-server-read-server (gnus-server-server-name))) - - -;;; -;;; Browse Server Mode -;;; - -(defvar gnus-browse-menu-hook nil - "*Hook run after the creation of the browse mode menu.") - -(defvar gnus-browse-mode-hook nil) -(defvar gnus-browse-mode-map nil) -(put 'gnus-browse-mode 'mode-class 'special) - -(unless gnus-browse-mode-map - (setq gnus-browse-mode-map (make-keymap)) - (suppress-keymap gnus-browse-mode-map) - - (gnus-define-keys - gnus-browse-mode-map - " " gnus-browse-read-group - "=" gnus-browse-select-group - "n" gnus-browse-next-group - "p" gnus-browse-prev-group - "\177" gnus-browse-prev-group - [delete] gnus-browse-prev-group - "N" gnus-browse-next-group - "P" gnus-browse-prev-group - "\M-n" gnus-browse-next-group - "\M-p" gnus-browse-prev-group - "\r" gnus-browse-select-group - "u" gnus-browse-unsubscribe-current-group - "l" gnus-browse-exit - "L" gnus-browse-exit - "q" gnus-browse-exit - "Q" gnus-browse-exit - "\C-c\C-c" gnus-browse-exit - "?" gnus-browse-describe-briefly - - "\C-c\C-i" gnus-info-find-node - "\C-c\C-b" gnus-bug)) - -(defun gnus-browse-make-menu-bar () - (gnus-turn-off-edit-menu 'browse) - (unless (boundp 'gnus-browse-menu) - (easy-menu-define - gnus-browse-menu gnus-browse-mode-map "" - '("Browse" - ["Subscribe" gnus-browse-unsubscribe-current-group t] - ["Read" gnus-browse-read-group t] - ["Select" gnus-browse-select-group t] - ["Next" gnus-browse-next-group t] - ["Prev" gnus-browse-next-group t] - ["Exit" gnus-browse-exit t])) - (gnus-run-hooks 'gnus-browse-menu-hook))) - -(defvar gnus-browse-current-method nil) -(defvar gnus-browse-return-buffer nil) - -(defvar gnus-browse-buffer "*Gnus Browse Server*") - -(defun gnus-browse-foreign-server (server &optional return-buffer) - "Browse the server SERVER." - (setq gnus-browse-current-method server) - (setq gnus-browse-return-buffer return-buffer) - (let* ((method (gnus-server-to-method server)) - (gnus-select-method method) - groups group) - (gnus-message 5 "Connecting to %s..." (nth 1 method)) - (cond - ((not (gnus-check-server method)) - (gnus-message - 1 "Unable to contact server %s: %s" (nth 1 method) - (gnus-status-message method)) - nil) - ((not - (prog2 - (gnus-message 6 "Reading active file...") - (gnus-request-list method) - (gnus-message 6 "Reading active file...done"))) - (gnus-message - 1 "Couldn't request list: %s" (gnus-status-message method)) - nil) - (t - (gnus-get-buffer-create gnus-browse-buffer) - (when gnus-carpal - (gnus-carpal-setup-buffer 'browse)) - (gnus-configure-windows 'browse) - (buffer-disable-undo (current-buffer)) - (let ((buffer-read-only nil)) - (erase-buffer)) - (gnus-browse-mode) - (setq mode-line-buffer-identification - (list - (format - "Gnus: %%b {%s:%s}" (car method) (cadr method)))) - (save-excursion - (set-buffer nntp-server-buffer) - (let ((cur (current-buffer))) - (goto-char (point-min)) - (unless (string= gnus-ignored-newsgroups "") - (delete-matching-lines gnus-ignored-newsgroups)) - (while (re-search-forward - "\\(^[^ \t]+\\)[ \t]+[0-9]+[ \t]+[0-9]+" nil t) - (goto-char (match-end 1)) - (condition-case () - (push (cons (match-string 1) - (max 0 (- (1+ (read cur)) (read cur)))) - groups) - (error nil))))) - (setq groups (sort groups - (lambda (l1 l2) - (string< (car l1) (car l2))))) - (let ((buffer-read-only nil)) - (while groups - (setq group (car groups)) - (insert - (format "K%7d: %s\n" (cdr group) (car group))) - (setq groups (cdr groups)))) - (switch-to-buffer (current-buffer)) - (goto-char (point-min)) - (gnus-group-position-point) - (gnus-message 5 "Connecting to %s...done" (nth 1 method)) - t)))) - -(defun gnus-browse-mode () - "Major mode for browsing a foreign server. - -All normal editing commands are switched off. - -\\ -The only things you can do in this buffer is - -1) `\\[gnus-browse-unsubscribe-current-group]' to subscribe to a group. -The group will be inserted into the group buffer upon exit from this -buffer. - -2) `\\[gnus-browse-read-group]' to read a group ephemerally. - -3) `\\[gnus-browse-exit]' to return to the group buffer." - (interactive) - (kill-all-local-variables) - (when (gnus-visual-p 'browse-menu 'menu) - (gnus-browse-make-menu-bar)) - (gnus-simplify-mode-line) - (setq major-mode 'gnus-browse-mode) - (setq mode-name "Browse Server") - (setq mode-line-process nil) - (use-local-map gnus-browse-mode-map) - (buffer-disable-undo (current-buffer)) - (setq truncate-lines t) - (gnus-set-default-directory) - (setq buffer-read-only t) - (gnus-run-hooks 'gnus-browse-mode-hook)) - -(defun gnus-browse-read-group (&optional no-article) - "Enter the group at the current line." - (interactive) - (let ((group (gnus-browse-group-name))) - (if (or (not (gnus-get-info group)) - (gnus-ephemeral-group-p group)) - (unless (gnus-group-read-ephemeral-group - group gnus-browse-current-method nil - (cons (current-buffer) 'browse)) - (error "Couldn't enter %s" group)) - (unless (gnus-group-read-group nil no-article group) - (error "Couldn't enter %s" group))))) - -(defun gnus-browse-select-group () - "Select the current group." - (interactive) - (gnus-browse-read-group 'no)) - -(defun gnus-browse-next-group (n) - "Go to the next group." - (interactive "p") - (prog1 - (forward-line n) - (gnus-group-position-point))) - -(defun gnus-browse-prev-group (n) - "Go to the next group." - (interactive "p") - (gnus-browse-next-group (- n))) - -(defun gnus-browse-unsubscribe-current-group (arg) - "(Un)subscribe to the next ARG groups." - (interactive "p") - (when (eobp) - (error "No group at current line")) - (let ((ward (if (< arg 0) -1 1)) - (arg (abs arg))) - (while (and (> arg 0) - (not (eobp)) - (gnus-browse-unsubscribe-group) - (zerop (gnus-browse-next-group ward))) - (decf arg)) - (gnus-group-position-point) - (when (/= 0 arg) - (gnus-message 7 "No more newsgroups")) - arg)) - -(defun gnus-browse-group-name () - (save-excursion - (beginning-of-line) - (when (re-search-forward ": \\(.*\\)$" (gnus-point-at-eol) t) - (gnus-group-prefixed-name - ;; Remove text props. - (format "%s" (match-string 1)) - gnus-browse-current-method)))) - -(defun gnus-browse-unsubscribe-group () - "Toggle subscription of the current group in the browse buffer." - (let ((sub nil) - (buffer-read-only nil) - group) - (save-excursion - (beginning-of-line) - ;; If this group it killed, then we want to subscribe it. - (when (= (following-char) ?K) - (setq sub t)) - (setq group (gnus-browse-group-name)) - (when (and sub - (cadr (gnus-gethash group gnus-newsrc-hashtb))) - (error "Group already subscribed")) - (delete-char 1) - (if sub - (progn - ;; Make sure the group has been properly removed before we - ;; subscribe to it. - (gnus-kill-ephemeral-group group) - (gnus-group-change-level - (list t group gnus-level-default-subscribed - nil nil (if (gnus-server-equal - gnus-browse-current-method "native") - nil - gnus-browse-current-method)) - gnus-level-default-subscribed gnus-level-killed - (and (car (nth 1 gnus-newsrc-alist)) - (gnus-gethash (car (nth 1 gnus-newsrc-alist)) - gnus-newsrc-hashtb)) - t) - (insert ? )) - (gnus-group-change-level - group gnus-level-killed gnus-level-default-subscribed) - (insert ?K))) - t)) - -(defun gnus-browse-exit () - "Quit browsing and return to the group buffer." - (interactive) - (when (eq major-mode 'gnus-browse-mode) - (kill-buffer (current-buffer))) - ;; Insert the newly subscribed groups in the group buffer. - (save-excursion - (set-buffer gnus-group-buffer) - (gnus-group-list-groups nil)) - (if gnus-browse-return-buffer - (gnus-configure-windows 'server 'force) - (gnus-configure-windows 'group 'force))) - -(defun gnus-browse-describe-briefly () - "Give a one line description of the group mode commands." - (interactive) - (gnus-message 6 - (substitute-command-keys "\\\\[gnus-group-next-group]:Forward \\[gnus-group-prev-group]:Backward \\[gnus-browse-exit]:Exit \\[gnus-info-find-node]:Run Info \\[gnus-browse-describe-briefly]:This help"))) - -(defun gnus-server-regenerate-server () - "Issue a command to the server to regenerate all its data structures." - (interactive) - (let ((server (gnus-server-server-name))) - (unless server - (error "No server on the current line")) - (if (not (gnus-check-backend-function - 'request-regenerate (car (gnus-server-to-method server)))) - (error "This backend doesn't support regeneration") - (gnus-message 5 "Requesting regeneration of %s..." server) - (unless (gnus-open-server server) - (error "Couldn't open server")) - (if (gnus-request-regenerate server) - (gnus-message 5 "Requesting regeneration of %s...done" server) - (gnus-message 5 "Couldn't regenerate %s" server))))) - -(provide 'gnus-srvr) - -;;; gnus-srvr.el ends here. diff --git a/lisp/gnus-start.el b/lisp/gnus-start.el deleted file mode 100644 index 95a3527..0000000 --- a/lisp/gnus-start.el +++ /dev/null @@ -1,2565 +0,0 @@ -;;; gnus-start.el --- startup functions for Gnus -;; Copyright (C) 1996,97,98 Free Software Foundation, Inc. - -;; Author: Lars Magne Ingebrigtsen -;; Keywords: news - -;; This file is part of GNU Emacs. - -;; GNU Emacs is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 2, or (at your option) -;; any later version. - -;; GNU Emacs is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs; see the file COPYING. If not, write to the -;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. - -;;; Commentary: - -;;; Code: - -(require 'gnus) -(require 'gnus-win) -(require 'gnus-int) -(require 'gnus-spec) -(require 'gnus-range) -(require 'gnus-util) -(require 'message) -(eval-when-compile (require 'cl)) - -(defcustom gnus-startup-file (nnheader-concat gnus-home-directory ".newsrc") - "Your `.newsrc' file. -`.newsrc-SERVER' will be used instead if that exists." - :group 'gnus-start - :type 'file) - -(defcustom gnus-init-file (nnheader-concat gnus-home-directory ".gnus") - "Your Gnus Emacs-Lisp startup file name. -If a file with the `.el' or `.elc' suffixes exists, it will be read instead." - :group 'gnus-start - :type 'file) - -(defcustom gnus-site-init-file - (condition-case nil - (concat (file-name-directory - (directory-file-name installation-directory)) - "site-lisp/gnus-init") - (error nil)) - "*The site-wide Gnus Emacs-Lisp startup file name, or nil if none. -If a file with the `.el' or `.elc' suffixes exists, it will be read instead." - :group 'gnus-start - :type '(choice file (const nil))) - -(defcustom gnus-default-subscribed-newsgroups nil - "List of newsgroups to subscribe, when a user runs Gnus the first time. -The value should be a list of strings. -If it is t, Gnus will not do anything special the first time it is -started; it'll just use the normal newsgroups subscription methods." - :group 'gnus-start - :type '(choice (repeat string) (const :tag "Nothing special" t))) - -(defcustom gnus-use-dribble-file t - "*Non-nil means that Gnus will use a dribble file to store user updates. -If Emacs should crash without saving the .newsrc files, complete -information can be restored from the dribble file." - :group 'gnus-dribble-file - :type 'boolean) - -(defcustom gnus-dribble-directory nil - "*The directory where dribble files will be saved. -If this variable is nil, the directory where the .newsrc files are -saved will be used." - :group 'gnus-dribble-file - :type '(choice directory (const nil))) - -(defcustom gnus-check-new-newsgroups 'ask-server - "*Non-nil means that Gnus will run `gnus-find-new-newsgroups' at startup. -This normally finds new newsgroups by comparing the active groups the -servers have already reported with those Gnus already knows, either alive -or killed. - -When any of the following are true, `gnus-find-new-newsgroups' will instead -ask the servers (primary, secondary, and archive servers) to list new -groups since the last time it checked: - 1. This variable is `ask-server'. - 2. This variable is a list of select methods (see below). - 3. `gnus-read-active-file' is nil or `some'. - 4. A prefix argument is given to `gnus-find-new-newsgroups' interactively. - -Thus, if this variable is `ask-server' or a list of select methods or -`gnus-read-active-file' is nil or `some', then the killed list is no -longer necessary, so you could safely set `gnus-save-killed-list' to nil. - -This variable can be a list of select methods which Gnus will query with -the `ask-server' method in addition to the primary, secondary, and archive -servers. - -Eg. - (setq gnus-check-new-newsgroups - '((nntp \"some.server\") (nntp \"other.server\"))) - -If this variable is nil, then you have to tell Gnus explicitly to -check for new newsgroups with \\\\[gnus-find-new-newsgroups]." - :group 'gnus-start - :type '(choice (const :tag "no" nil) - (const :tag "by brute force" t) - (const :tag "ask servers" ask-server) - (repeat :menu-tag "ask additional servers" - :tag "ask additional servers" - :value ((nntp "")) - (sexp :format "%v")))) - -(defcustom gnus-check-bogus-newsgroups nil - "*Non-nil means that Gnus will check and remove bogus newsgroup at startup. -If this variable is nil, then you have to tell Gnus explicitly to -check for bogus newsgroups with \\\\[gnus-group-check-bogus-groups]." - :group 'gnus-start-server - :type 'boolean) - -(defcustom gnus-read-active-file 'some - "*Non-nil means that Gnus will read the entire active file at startup. -If this variable is nil, Gnus will only know about the groups in your -`.newsrc' file. - -If this variable is `some', Gnus will try to only read the relevant -parts of the active file from the server. Not all servers support -this, and it might be quite slow with other servers, but this should -generally be faster than both the t and nil value. - -If you set this variable to nil or `some', you probably still want to -be told about new newsgroups that arrive. To do that, set -`gnus-check-new-newsgroups' to `ask-server'. This may not work -properly with all servers." - :group 'gnus-start-server - :type '(choice (const nil) - (const some) - (const t))) - -(defcustom gnus-level-subscribed 5 - "*Groups with levels less than or equal to this variable are subscribed." - :group 'gnus-group-levels - :type 'integer) - -(defcustom gnus-level-unsubscribed 7 - "*Groups with levels less than or equal to this variable are unsubscribed. -Groups with levels less than `gnus-level-subscribed', which should be -less than this variable, are subscribed." - :group 'gnus-group-levels - :type 'integer) - -(defcustom gnus-level-zombie 8 - "*Groups with this level are zombie groups." - :group 'gnus-group-levels - :type 'integer) - -(defcustom gnus-level-killed 9 - "*Groups with this level are killed." - :group 'gnus-group-levels - :type 'integer) - -(defcustom gnus-level-default-subscribed 3 - "*New subscribed groups will be subscribed at this level." - :group 'gnus-group-levels - :type 'integer) - -(defcustom gnus-level-default-unsubscribed 6 - "*New unsubscribed groups will be unsubscribed at this level." - :group 'gnus-group-levels - :type 'integer) - -(defcustom gnus-activate-level (1+ gnus-level-subscribed) - "*Groups higher than this level won't be activated on startup. -Setting this variable to something low might save lots of time when -you have many groups that you aren't interested in." - :group 'gnus-group-levels - :type 'integer) - -(defcustom gnus-activate-foreign-newsgroups 4 - "*If nil, Gnus will not check foreign newsgroups at startup. -If it is non-nil, it should be a number between one and nine. Foreign -newsgroups that have a level lower or equal to this number will be -activated on startup. For instance, if you want to active all -subscribed newsgroups, but not the rest, you'd set this variable to -`gnus-level-subscribed'. - -If you subscribe to lots of newsgroups from different servers, startup -might take a while. By setting this variable to nil, you'll save time, -but you won't be told how many unread articles there are in the -groups." - :group 'gnus-group-levels - :type '(choice integer - (const :tag "none" nil))) - -(defcustom gnus-save-newsrc-file t - "*Non-nil means that Gnus will save the `.newsrc' file. -Gnus always saves its own startup file, which is called -\".newsrc.eld\". The file called \".newsrc\" is in a format that can -be readily understood by other newsreaders. If you don't plan on -using other newsreaders, set this variable to nil to save some time on -exit." - :group 'gnus-newsrc - :type 'boolean) - -(defcustom gnus-save-killed-list t - "*If non-nil, save the list of killed groups to the startup file. -If you set this variable to nil, you'll save both time (when starting -and quitting) and space (both memory and disk), but it will also mean -that Gnus has no record of which groups are new and which are old, so -the automatic new newsgroups subscription methods become meaningless. - -You should always set `gnus-check-new-newsgroups' to `ask-server' or -nil if you set this variable to nil. - -This variable can also be a regexp. In that case, all groups that do -not match this regexp will be removed before saving the list." - :group 'gnus-newsrc - :type 'boolean) - -(defcustom gnus-ignored-newsgroups - (purecopy (mapconcat 'identity - '("^to\\." ; not "real" groups - "^[0-9. \t]+ " ; all digits in name - "[][\"#'()]" ; bogus characters - ) - "\\|")) - "*A regexp to match uninteresting newsgroups in the active file. -Any lines in the active file matching this regular expression are -removed from the newsgroup list before anything else is done to it, -thus making them effectively non-existent." - :group 'gnus-group-new - :type 'regexp) - -(defcustom gnus-subscribe-newsgroup-method 'gnus-subscribe-zombies - "*Function called with a group name when new group is detected. -A few pre-made functions are supplied: `gnus-subscribe-randomly' -inserts new groups at the beginning of the list of groups; -`gnus-subscribe-alphabetically' inserts new groups in strict -alphabetic order; `gnus-subscribe-hierarchically' inserts new groups -in hierarchical newsgroup order; `gnus-subscribe-interactively' asks -for your decision; `gnus-subscribe-killed' kills all new groups; -`gnus-subscribe-zombies' will make all new groups into zombies." - :group 'gnus-group-new - :type '(radio (function-item gnus-subscribe-randomly) - (function-item gnus-subscribe-alphabetically) - (function-item gnus-subscribe-hierarchically) - (function-item gnus-subscribe-interactively) - (function-item gnus-subscribe-killed) - (function-item gnus-subscribe-zombies) - function)) - -(defcustom gnus-subscribe-options-newsgroup-method - 'gnus-subscribe-alphabetically - "*This function is called to subscribe newsgroups mentioned on \"options -n\" lines. -If, for instance, you want to subscribe to all newsgroups in the -\"no\" and \"alt\" hierarchies, you'd put the following in your -.newsrc file: - -options -n no.all alt.all - -Gnus will the subscribe all new newsgroups in these hierarchies with -the subscription method in this variable." - :group 'gnus-group-new - :type '(radio (function-item gnus-subscribe-randomly) - (function-item gnus-subscribe-alphabetically) - (function-item gnus-subscribe-hierarchically) - (function-item gnus-subscribe-interactively) - (function-item gnus-subscribe-killed) - (function-item gnus-subscribe-zombies) - function)) - -(defcustom gnus-subscribe-hierarchical-interactive nil - "*If non-nil, Gnus will offer to subscribe hierarchically. -When a new hierarchy appears, Gnus will ask the user: - -'alt.binaries': Do you want to subscribe to this hierarchy? ([d]ys): - -If the user pressed `d', Gnus will descend the hierarchy, `y' will -subscribe to all newsgroups in the hierarchy and `s' will skip this -hierarchy in its entirety." - :group 'gnus-group-new - :type 'boolean) - -(defcustom gnus-auto-subscribed-groups - "nnml\\|^nnfolder\\|^nnmbox\\|^nnmh\\|^nnbabyl" - "*All new groups that match this regexp will be subscribed automatically. -Note that this variable only deals with new groups. It has no effect -whatsoever on old groups. - -New groups that match this regexp will not be handled by -`gnus-subscribe-newsgroup-method'. Instead, they will -be subscribed using `gnus-subscribe-options-newsgroup-method'." - :group 'gnus-group-new - :type 'regexp) - -(defcustom gnus-options-subscribe nil - "*All new groups matching this regexp will be subscribed unconditionally. -Note that this variable deals only with new newsgroups. This variable -does not affect old newsgroups. - -New groups that match this regexp will not be handled by -`gnus-subscribe-newsgroup-method'. Instead, they will -be subscribed using `gnus-subscribe-options-newsgroup-method'." - :group 'gnus-group-new - :type '(choice regexp - (const :tag "none" nil))) - -(defcustom gnus-options-not-subscribe nil - "*All new groups matching this regexp will be ignored. -Note that this variable deals only with new newsgroups. This variable -does not affect old (already subscribed) newsgroups." - :group 'gnus-group-new - :type '(choice regexp - (const :tag "none" nil))) - -(defcustom gnus-modtime-botch nil - "*Non-nil means .newsrc should be deleted prior to save. -Its use is due to the bogus appearance that .newsrc was modified on -disc." - :group 'gnus-newsrc - :type 'boolean) - -(defcustom gnus-check-bogus-groups-hook nil - "A hook run after removing bogus groups." - :group 'gnus-start-server - :type 'hook) - -(defcustom gnus-startup-hook nil - "A hook called at startup. -This hook is called after Gnus is connected to the NNTP server." - :group 'gnus-start - :type 'hook) - -(defcustom gnus-before-startup-hook nil - "A hook called at before startup. -This hook is called as the first thing when Gnus is started." - :group 'gnus-start - :type 'hook) - -(defcustom gnus-started-hook nil - "A hook called as the last thing after startup." - :group 'gnus-start - :type 'hook) - -(defcustom gnus-setup-news-hook nil - "A hook after reading the .newsrc file, but before generating the buffer." - :group 'gnus-start - :type 'hook) - -(defcustom gnus-get-new-news-hook nil - "A hook run just before Gnus checks for new news." - :group 'gnus-group-new - :type 'hook) - -(defcustom gnus-after-getting-new-news-hook - (when (gnus-boundp 'display-time-timer) - '(display-time-event-handler)) - "*A hook run after Gnus checks for new news." - :group 'gnus-group-new - :type 'hook) - -(defcustom gnus-save-newsrc-hook nil - "A hook called before saving any of the newsrc files." - :group 'gnus-newsrc - :type 'hook) - -(defcustom gnus-save-quick-newsrc-hook nil - "A hook called just before saving the quick newsrc file. -Can be used to turn version control on or off." - :group 'gnus-newsrc - :type 'hook) - -(defcustom gnus-save-standard-newsrc-hook nil - "A hook called just before saving the standard newsrc file. -Can be used to turn version control on or off." - :group 'gnus-newsrc - :type 'hook) - -(defcustom gnus-always-read-dribble-file nil - "Uncoditionally read the dribble file." - :group 'gnus-newsrc - :type 'boolean) - -(defvar gnus-startup-file-coding-system 'ctext - "*Coding system for startup file.") - -;;; Internal variables - -(defvar gnus-newsrc-file-version nil) -(defvar gnus-override-subscribe-method nil) -(defvar gnus-dribble-buffer nil) -(defvar gnus-newsrc-options nil - "Options line in the .newsrc file.") - -(defvar gnus-newsrc-options-n nil - "List of regexps representing groups to be subscribed/ignored unconditionally.") - -(defvar gnus-newsrc-last-checked-date nil - "Date Gnus last asked server for new newsgroups.") - -(defvar gnus-current-startup-file nil - "Startup file for the current host.") - -;; Byte-compiler warning. -(defvar gnus-group-line-format) - -;; Suggested by Brian Edmonds . -(defvar gnus-init-inhibit nil) -(defun gnus-read-init-file (&optional inhibit-next) - ;; Don't load .gnus if the -q option was used. - (when init-file-user - (if gnus-init-inhibit - (setq gnus-init-inhibit nil) - (setq gnus-init-inhibit inhibit-next) - (let ((files (list gnus-site-init-file gnus-init-file)) - file) - (while files - (and (setq file (pop files)) - (or (and (file-exists-p file) - ;; Don't try to load a directory. - (not (file-directory-p file))) - (file-exists-p (concat file ".el")) - (file-exists-p (concat file ".elc"))) - (condition-case var - (load file nil t) - (error - (error "Error in %s: %s" file var))))))))) - -;; For subscribing new newsgroup - -(defun gnus-subscribe-hierarchical-interactive (groups) - (let ((groups (sort groups 'string<)) - prefixes prefix start ans group starts) - (while groups - (setq prefixes (list "^")) - (while (and groups prefixes) - (while (not (string-match (car prefixes) (car groups))) - (setq prefixes (cdr prefixes))) - (setq prefix (car prefixes)) - (setq start (1- (length prefix))) - (if (and (string-match "[^\\.]\\." (car groups) start) - (cdr groups) - (setq prefix - (concat "^" (substring (car groups) 0 (match-end 0)))) - (string-match prefix (cadr groups))) - (progn - (push prefix prefixes) - (message "Descend hierarchy %s? ([y]nsq): " - (substring prefix 1 (1- (length prefix)))) - (while (not (memq (setq ans (read-char-exclusive)) - '(?y ?\n ?\r ?n ?s ?q))) - (ding) - (message "Descend hierarchy %s? ([y]nsq): " - (substring prefix 1 (1- (length prefix))))) - (cond ((= ans ?n) - (while (and groups - (string-match prefix - (setq group (car groups)))) - (push group gnus-killed-list) - (gnus-sethash group group gnus-killed-hashtb) - (setq groups (cdr groups))) - (setq starts (cdr starts))) - ((= ans ?s) - (while (and groups - (string-match prefix - (setq group (car groups)))) - (gnus-sethash group group gnus-killed-hashtb) - (gnus-subscribe-alphabetically (car groups)) - (setq groups (cdr groups))) - (setq starts (cdr starts))) - ((= ans ?q) - (while groups - (setq group (car groups)) - (push group gnus-killed-list) - (gnus-sethash group group gnus-killed-hashtb) - (setq groups (cdr groups)))) - (t nil))) - (message "Subscribe %s? ([n]yq)" (car groups)) - (while (not (memq (setq ans (read-char-exclusive)) - '(?y ?\n ?\r ?q ?n))) - (ding) - (message "Subscribe %s? ([n]yq)" (car groups))) - (setq group (car groups)) - (cond ((= ans ?y) - (gnus-subscribe-alphabetically (car groups)) - (gnus-sethash group group gnus-killed-hashtb)) - ((= ans ?q) - (while groups - (setq group (car groups)) - (push group gnus-killed-list) - (gnus-sethash group group gnus-killed-hashtb) - (setq groups (cdr groups)))) - (t - (push group gnus-killed-list) - (gnus-sethash group group gnus-killed-hashtb))) - (setq groups (cdr groups))))))) - -(defun gnus-subscribe-randomly (newsgroup) - "Subscribe new NEWSGROUP by making it the first newsgroup." - (gnus-subscribe-newsgroup newsgroup)) - -(defun gnus-subscribe-alphabetically (newgroup) - "Subscribe new NEWSGROUP and insert it in alphabetical order." - (let ((groups (cdr gnus-newsrc-alist)) - before) - (while (and (not before) groups) - (if (string< newgroup (caar groups)) - (setq before (caar groups)) - (setq groups (cdr groups)))) - (gnus-subscribe-newsgroup newgroup before))) - -(defun gnus-subscribe-hierarchically (newgroup) - "Subscribe new NEWSGROUP and insert it in hierarchical newsgroup order." - ;; Basic ideas by mike-w@cs.aukuni.ac.nz (Mike Williams) - (save-excursion - (set-buffer (nnheader-find-file-noselect gnus-current-startup-file)) - (let ((groupkey newgroup) - before) - (while (and (not before) groupkey) - (goto-char (point-min)) - (let ((groupkey-re - (concat "^\\(" (regexp-quote groupkey) ".*\\)[!:]"))) - (while (and (re-search-forward groupkey-re nil t) - (progn - (setq before (match-string 1)) - (string< before newgroup))))) - ;; Remove tail of newsgroup name (eg. a.b.c -> a.b) - (setq groupkey - (when (string-match "^\\(.*\\)\\.[^.]+$" groupkey) - (substring groupkey (match-beginning 1) (match-end 1))))) - (gnus-subscribe-newsgroup newgroup before)) - (kill-buffer (current-buffer)))) - -(defun gnus-subscribe-interactively (group) - "Subscribe the new GROUP interactively. -It is inserted in hierarchical newsgroup order if subscribed. If not, -it is killed." - (if (gnus-y-or-n-p (format "Subscribe new newsgroup: %s " group)) - (gnus-subscribe-hierarchically group) - (push group gnus-killed-list))) - -(defun gnus-subscribe-zombies (group) - "Make the new GROUP into a zombie group." - (push group gnus-zombie-list)) - -(defun gnus-subscribe-killed (group) - "Make the new GROUP a killed group." - (push group gnus-killed-list)) - -(defun gnus-subscribe-newsgroup (newsgroup &optional next) - "Subscribe new NEWSGROUP. -If NEXT is non-nil, it is inserted before NEXT. Otherwise it is made -the first newsgroup." - (save-excursion - (goto-char (point-min)) - ;; We subscribe the group by changing its level to `subscribed'. - (gnus-group-change-level - newsgroup gnus-level-default-subscribed - gnus-level-killed (gnus-gethash (or next "dummy.group") - gnus-newsrc-hashtb)) - (gnus-message 5 "Subscribe newsgroup: %s" newsgroup))) - -(defun gnus-read-active-file-p () - "Say whether the active file has been read from `gnus-select-method'." - (memq gnus-select-method gnus-have-read-active-file)) - -;;; General various misc type functions. - -;; Silence byte-compiler. -(defvar gnus-current-headers) -(defvar gnus-thread-indent-array) -(defvar gnus-newsgroup-name) -(defvar gnus-newsgroup-headers) -(defvar gnus-group-list-mode) -(defvar gnus-group-mark-positions) -(defvar gnus-newsgroup-data) -(defvar gnus-newsgroup-unreads) -(defvar nnoo-state-alist) -(defvar gnus-current-select-method) - -(defun gnus-clear-system () - "Clear all variables and buffers." - ;; Clear Gnus variables. - (let ((variables gnus-variable-list)) - (while variables - (set (car variables) nil) - (setq variables (cdr variables)))) - ;; Clear other internal variables. - (setq gnus-list-of-killed-groups nil - gnus-have-read-active-file nil - gnus-newsrc-alist nil - gnus-newsrc-hashtb nil - gnus-killed-list nil - gnus-zombie-list nil - gnus-killed-hashtb nil - gnus-active-hashtb nil - gnus-moderated-hashtb nil - gnus-description-hashtb nil - gnus-current-headers nil - gnus-thread-indent-array nil - gnus-newsgroup-headers nil - gnus-newsgroup-name nil - gnus-server-alist nil - gnus-group-list-mode nil - gnus-opened-servers nil - gnus-group-mark-positions nil - gnus-newsgroup-data nil - gnus-newsgroup-unreads nil - nnoo-state-alist nil - gnus-current-select-method nil - gnus-ephemeral-servers nil) - (gnus-shutdown 'gnus) - ;; Kill the startup file. - (and gnus-current-startup-file - (get-file-buffer gnus-current-startup-file) - (kill-buffer (get-file-buffer gnus-current-startup-file))) - ;; Clear the dribble buffer. - (gnus-dribble-clear) - ;; Kill global KILL file buffer. - (when (get-file-buffer (gnus-newsgroup-kill-file nil)) - (kill-buffer (get-file-buffer (gnus-newsgroup-kill-file nil)))) - (gnus-kill-buffer nntp-server-buffer) - ;; Kill Gnus buffers. - (let ((buffers (gnus-buffers))) - (when buffers - (mapcar 'kill-buffer buffers))) - ;; Remove Gnus frames. - (gnus-kill-gnus-frames)) - -(defun gnus-no-server-1 (&optional arg slave) - "Read network news. -If ARG is a positive number, Gnus will use that as the -startup level. If ARG is nil, Gnus will be started at level 2. -If ARG is non-nil and not a positive number, Gnus will -prompt the user for the name of an NNTP server to use. -As opposed to `gnus', this command will not connect to the local server." - (interactive "P") - (let ((val (or arg (1- gnus-level-default-subscribed)))) - (gnus val t slave) - (make-local-variable 'gnus-group-use-permanent-levels) - (setq gnus-group-use-permanent-levels val))) - -(defun gnus-1 (&optional arg dont-connect slave) - "Read network news. -If ARG is non-nil and a positive number, Gnus will use that as the -startup level. If ARG is non-nil and not a positive number, Gnus will -prompt the user for the name of an NNTP server to use." - (interactive "P") - - (if (gnus-alive-p) - (progn - (switch-to-buffer gnus-group-buffer) - (gnus-group-get-new-news - (and (numberp arg) - (> arg 0) - (max (car gnus-group-list-mode) arg)))) - - (gnus-clear-system) - (gnus-splash) - (gnus-run-hooks 'gnus-before-startup-hook) - (nnheader-init-server-buffer) - (setq gnus-slave slave) - (gnus-read-init-file) - - (when gnus-simple-splash - (setq gnus-simple-splash nil) - (cond - (gnus-xemacs - (gnus-xmas-splash)) - ((and (eq window-system 'x) - (= (frame-height) (1+ (window-height)))) - (gnus-x-splash)))) - - (let ((level (and (numberp arg) (> arg 0) arg)) - did-connect) - (unwind-protect - (progn - (unless dont-connect - (setq did-connect - (gnus-start-news-server (and arg (not level)))))) - (if (and (not dont-connect) - (not did-connect)) - (gnus-group-quit) - (gnus-run-hooks 'gnus-startup-hook) - ;; NNTP server is successfully open. - - ;; Find the current startup file name. - (setq gnus-current-startup-file - (gnus-make-newsrc-file gnus-startup-file)) - - ;; Read the dribble file. - (when (or gnus-slave gnus-use-dribble-file) - (gnus-dribble-read-file)) - - ;; Allow using GroupLens predictions. - (when gnus-use-grouplens - (bbb-login) - (add-hook 'gnus-summary-mode-hook 'gnus-grouplens-mode)) - - ;; Do the actual startup. - (gnus-setup-news nil level dont-connect) - (gnus-run-hooks 'gnus-setup-news-hook) - (gnus-start-draft-setup) - ;; Generate the group buffer. - (gnus-group-list-groups level) - (gnus-group-first-unread-group) - (gnus-configure-windows 'group) - (gnus-group-set-mode-line) - (gnus-run-hooks 'gnus-started-hook)))))) - -(defun gnus-start-draft-setup () - "Make sure the draft group exists." - (gnus-request-create-group "drafts" '(nndraft "")) - (unless (gnus-gethash "nndraft:drafts" gnus-newsrc-hashtb) - (let ((gnus-level-default-subscribed 1)) - (gnus-subscribe-group "nndraft:drafts" nil '(nndraft ""))) - (gnus-group-set-parameter - "nndraft:drafts" 'gnus-dummy '((gnus-draft-mode))))) - -;;;###autoload -(defun gnus-unload () - "Unload all Gnus features." - (interactive) - (unless (boundp 'load-history) - (error "Sorry, `gnus-unload' is not implemented in this Emacs version")) - (let ((history load-history) - feature) - (while history - (and (string-match "^\\(gnus\\|nn\\)" (caar history)) - (setq feature (cdr (assq 'provide (car history)))) - (unload-feature feature 'force)) - (setq history (cdr history))))) - - -;;; -;;; Dribble file -;;; - -(defvar gnus-dribble-ignore nil) -(defvar gnus-dribble-eval-file nil) - -(defun gnus-dribble-file-name () - "Return the dribble file for the current .newsrc." - (concat - (if gnus-dribble-directory - (concat (file-name-as-directory gnus-dribble-directory) - (file-name-nondirectory gnus-current-startup-file)) - gnus-current-startup-file) - "-dribble")) - -(defun gnus-dribble-enter (string) - "Enter STRING into the dribble buffer." - (when (and (not gnus-dribble-ignore) - gnus-dribble-buffer - (buffer-name gnus-dribble-buffer)) - (let ((obuf (current-buffer))) - (set-buffer gnus-dribble-buffer) - (goto-char (point-max)) - (insert string "\n") - (set-window-point (get-buffer-window (current-buffer)) (point-max)) - (bury-buffer gnus-dribble-buffer) - (save-excursion - (set-buffer gnus-group-buffer) - (gnus-group-set-mode-line)) - (set-buffer obuf)))) - -(defun gnus-dribble-touch () - "Touch the dribble buffer." - (gnus-dribble-enter "")) - -(defun gnus-dribble-read-file () - "Read the dribble file from disk." - (let ((dribble-file (gnus-dribble-file-name))) - (save-excursion - (set-buffer (setq gnus-dribble-buffer - (gnus-get-buffer-create - (file-name-nondirectory dribble-file)))) - (erase-buffer) - (setq buffer-file-name dribble-file) - (auto-save-mode t) - (buffer-disable-undo (current-buffer)) - (bury-buffer (current-buffer)) - (set-buffer-modified-p nil) - (let ((auto (make-auto-save-file-name)) - (gnus-dribble-ignore t) - modes) - (when (or (file-exists-p auto) (file-exists-p dribble-file)) - ;; Load whichever file is newest -- the auto save file - ;; or the "real" file. - (if (file-newer-than-file-p auto dribble-file) - (nnheader-insert-file-contents auto) - (nnheader-insert-file-contents dribble-file)) - (unless (zerop (buffer-size)) - (set-buffer-modified-p t)) - ;; Set the file modes to reflect the .newsrc file modes. - (save-buffer) - (when (and (file-exists-p gnus-current-startup-file) - (file-exists-p dribble-file) - (setq modes (file-modes gnus-current-startup-file))) - (set-file-modes dribble-file modes)) - ;; Possibly eval the file later. - (when (or gnus-always-read-dribble-file - (gnus-y-or-n-p - "Gnus auto-save file exists. Do you want to read it? ")) - (setq gnus-dribble-eval-file t))))))) - -(defun gnus-dribble-eval-file () - (when gnus-dribble-eval-file - (setq gnus-dribble-eval-file nil) - (save-excursion - (let ((gnus-dribble-ignore t)) - (set-buffer gnus-dribble-buffer) - (eval-buffer (current-buffer)))))) - -(defun gnus-dribble-delete-file () - (when (file-exists-p (gnus-dribble-file-name)) - (delete-file (gnus-dribble-file-name))) - (when gnus-dribble-buffer - (save-excursion - (set-buffer gnus-dribble-buffer) - (let ((auto (make-auto-save-file-name))) - (when (file-exists-p auto) - (delete-file auto)) - (erase-buffer) - (set-buffer-modified-p nil))))) - -(defun gnus-dribble-save () - (when (and gnus-dribble-buffer - (buffer-name gnus-dribble-buffer)) - (save-excursion - (set-buffer gnus-dribble-buffer) - (save-buffer)))) - -(defun gnus-dribble-clear () - (when (gnus-buffer-exists-p gnus-dribble-buffer) - (save-excursion - (set-buffer gnus-dribble-buffer) - (erase-buffer) - (set-buffer-modified-p nil) - (setq buffer-saved-size (buffer-size))))) - - -;;; -;;; Active & Newsrc File Handling -;;; - -(defun gnus-setup-news (&optional rawfile level dont-connect) - "Setup news information. -If RAWFILE is non-nil, the .newsrc file will also be read. -If LEVEL is non-nil, the news will be set up at level LEVEL." - (let ((init (not (and gnus-newsrc-alist gnus-active-hashtb (not rawfile))))) - - (when init - ;; Clear some variables to re-initialize news information. - (setq gnus-newsrc-alist nil - gnus-active-hashtb nil) - ;; Read the newsrc file and create `gnus-newsrc-hashtb'. - (gnus-read-newsrc-file rawfile)) - - ;; Make sure the archive server is available to all and sundry. - (when gnus-message-archive-method - (setq gnus-server-alist (delq (assoc "archive" gnus-server-alist) - gnus-server-alist)) - (push (cons "archive" gnus-message-archive-method) - gnus-server-alist)) - - ;; If we don't read the complete active file, we fill in the - ;; hashtb here. - (when (or (null gnus-read-active-file) - (eq gnus-read-active-file 'some)) - (gnus-update-active-hashtb-from-killed)) - - ;; Read the active file and create `gnus-active-hashtb'. - ;; If `gnus-read-active-file' is nil, then we just create an empty - ;; hash table. The partial filling out of the hash table will be - ;; done in `gnus-get-unread-articles'. - (and gnus-read-active-file - (not level) - (gnus-read-active-file nil dont-connect)) - - (unless gnus-active-hashtb - (setq gnus-active-hashtb (gnus-make-hashtable 4096))) - - ;; Initialize the cache. - (when gnus-use-cache - (gnus-cache-open)) - - ;; Possibly eval the dribble file. - (and init - (or gnus-use-dribble-file gnus-slave) - (gnus-dribble-eval-file)) - - ;; Slave Gnusii should then clear the dribble buffer. - (when (and init gnus-slave) - (gnus-dribble-clear)) - - (gnus-update-format-specifications) - - ;; See whether we need to read the description file. - (when (and (boundp 'gnus-group-line-format) - (let ((case-fold-search nil)) - (string-match "%[-,0-9]*D" gnus-group-line-format)) - (not gnus-description-hashtb) - (not dont-connect) - gnus-read-active-file) - (gnus-read-all-descriptions-files)) - - ;; Find new newsgroups and treat them. - (when (and init gnus-check-new-newsgroups (not level) - (gnus-check-server gnus-select-method) - (not gnus-slave) - gnus-plugged) - (gnus-find-new-newsgroups)) - - ;; We might read in new NoCeM messages here. - (when (and gnus-use-nocem - (not level) - (not dont-connect)) - (gnus-nocem-scan-groups)) - - ;; Read any slave files. - (gnus-master-read-slave-newsrc) - - ;; Find the number of unread articles in each non-dead group. - (let ((gnus-read-active-file (and (not level) gnus-read-active-file))) - (gnus-get-unread-articles level)) - - (when (and init gnus-check-bogus-newsgroups - gnus-read-active-file (not level) - (gnus-server-opened gnus-select-method)) - (gnus-check-bogus-newsgroups)))) - -(defun gnus-find-new-newsgroups (&optional arg) - "Search for new newsgroups and add them. -Each new newsgroup will be treated with `gnus-subscribe-newsgroup-method.' -The `-n' option line from .newsrc is respected. - -With 1 C-u, use the `ask-server' method to query the server for new -groups. -With 2 C-u's, use most complete method possible to query the server -for new groups, and subscribe the new groups as zombies." - (interactive "p") - (let* ((gnus-subscribe-newsgroup-method - gnus-subscribe-newsgroup-method) - (check (cond - ((or (and (= (or arg 1) 4) - (not (listp gnus-check-new-newsgroups))) - (null gnus-read-active-file) - (eq gnus-read-active-file 'some)) - 'ask-server) - ((= (or arg 1) 16) - (setq gnus-subscribe-newsgroup-method - 'gnus-subscribe-zombies) - t) - (t gnus-check-new-newsgroups)))) - (unless (gnus-check-first-time-used) - (if (or (consp check) - (eq check 'ask-server)) - ;; Ask the server for new groups. - (gnus-ask-server-for-new-groups) - ;; Go through the active hashtb and look for new groups. - (let ((groups 0) - group new-newsgroups) - (gnus-message 5 "Looking for new newsgroups...") - (unless gnus-have-read-active-file - (gnus-read-active-file)) - (setq gnus-newsrc-last-checked-date (current-time-string)) - (unless gnus-killed-hashtb - (gnus-make-hashtable-from-killed)) - ;; Go though every newsgroup in `gnus-active-hashtb' and compare - ;; with `gnus-newsrc-hashtb' and `gnus-killed-hashtb'. - (mapatoms - (lambda (sym) - (if (or (null (setq group (symbol-name sym))) - (not (boundp sym)) - (null (symbol-value sym)) - (gnus-gethash group gnus-killed-hashtb) - (gnus-gethash group gnus-newsrc-hashtb)) - () - (let ((do-sub (gnus-matches-options-n group))) - (cond - ((eq do-sub 'subscribe) - (setq groups (1+ groups)) - (gnus-sethash group group gnus-killed-hashtb) - (funcall gnus-subscribe-options-newsgroup-method group)) - ((eq do-sub 'ignore) - nil) - (t - (setq groups (1+ groups)) - (gnus-sethash group group gnus-killed-hashtb) - (if gnus-subscribe-hierarchical-interactive - (push group new-newsgroups) - (funcall gnus-subscribe-newsgroup-method group))))))) - gnus-active-hashtb) - (when new-newsgroups - (gnus-subscribe-hierarchical-interactive new-newsgroups)) - (if (> groups 0) - (gnus-message 5 "%d new newsgroup%s arrived." - groups (if (> groups 1) "s have" " has")) - (gnus-message 5 "No new newsgroups."))))))) - -(defun gnus-matches-options-n (group) - ;; Returns `subscribe' if the group is to be unconditionally - ;; subscribed, `ignore' if it is to be ignored, and nil if there is - ;; no match for the group. - - ;; First we check the two user variables. - (cond - ((and gnus-options-subscribe - (string-match gnus-options-subscribe group)) - 'subscribe) - ((and gnus-auto-subscribed-groups - (string-match gnus-auto-subscribed-groups group)) - 'subscribe) - ((and gnus-options-not-subscribe - (string-match gnus-options-not-subscribe group)) - 'ignore) - ;; Then we go through the list that was retrieved from the .newsrc - ;; file. This list has elements on the form - ;; `(REGEXP . {ignore,subscribe})'. The first match found (the list - ;; is in the reverse order of the options line) is returned. - (t - (let ((regs gnus-newsrc-options-n)) - (while (and regs - (not (string-match (caar regs) group))) - (setq regs (cdr regs))) - (and regs (cdar regs)))))) - -(defun gnus-ask-server-for-new-groups () - (let* ((date (or gnus-newsrc-last-checked-date (current-time-string))) - (methods (cons gnus-select-method - (nconc - (when (gnus-archive-server-wanted-p) - (list "archive")) - (append - (and (consp gnus-check-new-newsgroups) - gnus-check-new-newsgroups) - gnus-secondary-select-methods)))) - (groups 0) - (new-date (current-time-string)) - group new-newsgroups got-new method hashtb - gnus-override-subscribe-method) - (unless gnus-killed-hashtb - (gnus-make-hashtable-from-killed)) - ;; Go through both primary and secondary select methods and - ;; request new newsgroups. - (while (setq method (gnus-server-get-method nil (pop methods))) - (setq new-newsgroups nil - gnus-override-subscribe-method method) - (when (and (gnus-check-server method) - (gnus-request-newgroups date method)) - (save-excursion - (setq got-new t - hashtb (gnus-make-hashtable 100)) - (set-buffer nntp-server-buffer) - ;; Enter all the new groups into a hashtable. - (gnus-active-to-gnus-format method hashtb 'ignore)) - ;; Now all new groups from `method' are in `hashtb'. - (mapatoms - (lambda (group-sym) - (if (or (null (setq group (symbol-name group-sym))) - (not (boundp group-sym)) - (null (symbol-value group-sym)) - (gnus-gethash group gnus-newsrc-hashtb) - (member group gnus-zombie-list) - (member group gnus-killed-list)) - ;; The group is already known. - () - ;; Make this group active. - (when (symbol-value group-sym) - (gnus-set-active group (symbol-value group-sym))) - ;; Check whether we want it or not. - (let ((do-sub (gnus-matches-options-n group))) - (cond - ((eq do-sub 'subscribe) - (incf groups) - (gnus-sethash group group gnus-killed-hashtb) - (funcall gnus-subscribe-options-newsgroup-method group)) - ((eq do-sub 'ignore) - nil) - (t - (incf groups) - (gnus-sethash group group gnus-killed-hashtb) - (if gnus-subscribe-hierarchical-interactive - (push group new-newsgroups) - (funcall gnus-subscribe-newsgroup-method group))))))) - hashtb)) - (when new-newsgroups - (gnus-subscribe-hierarchical-interactive new-newsgroups))) - (if (> groups 0) - (gnus-message 5 "%d new newsgroup%s arrived" - groups (if (> groups 1) "s have" " has")) - (gnus-message 5 "No new newsgroups")) - (when got-new - (setq gnus-newsrc-last-checked-date new-date)) - got-new)) - -(defun gnus-check-first-time-used () - (if (or (> (length gnus-newsrc-alist) 1) - (file-exists-p gnus-startup-file) - (file-exists-p (concat gnus-startup-file ".el")) - (file-exists-p (concat gnus-startup-file ".eld"))) - nil - (gnus-message 6 "First time user; subscribing you to default groups") - (unless (gnus-read-active-file-p) - (let ((gnus-read-active-file t)) - (gnus-read-active-file))) - (setq gnus-newsrc-last-checked-date (current-time-string)) - (let ((groups gnus-default-subscribed-newsgroups) - group) - (if (eq groups t) - nil - (setq groups (or groups gnus-backup-default-subscribed-newsgroups)) - (mapatoms - (lambda (sym) - (if (null (setq group (symbol-name sym))) - () - (let ((do-sub (gnus-matches-options-n group))) - (cond - ((eq do-sub 'subscribe) - (gnus-sethash group group gnus-killed-hashtb) - (funcall gnus-subscribe-options-newsgroup-method group)) - ((eq do-sub 'ignore) - nil) - (t - (push group gnus-killed-list)))))) - gnus-active-hashtb) - (while groups - (when (gnus-active (car groups)) - (gnus-group-change-level - (car groups) gnus-level-default-subscribed gnus-level-killed)) - (setq groups (cdr groups))) - (save-excursion - (set-buffer gnus-group-buffer) - (gnus-group-make-help-group)) - (when gnus-novice-user - (gnus-message 7 "`A k' to list killed groups")))))) - -(defun gnus-subscribe-group (group previous &optional method) - (gnus-group-change-level - (if method - (list t group gnus-level-default-subscribed nil nil method) - group) - gnus-level-default-subscribed gnus-level-killed previous t)) - -;; `gnus-group-change-level' is the fundamental function for changing -;; subscription levels of newsgroups. This might mean just changing -;; from level 1 to 2, which is pretty trivial, from 2 to 6 or back -;; again, which subscribes/unsubscribes a group, which is equally -;; trivial. Changing from 1-7 to 8-9 means that you kill a group, and -;; from 8-9 to 1-7 means that you remove the group from the list of -;; killed (or zombie) groups and add them to the (kinda) subscribed -;; groups. And last but not least, moving from 8 to 9 and 9 to 8, -;; which is trivial. -;; ENTRY can either be a string (newsgroup name) or a list (if -;; FROMKILLED is t, it's a list on the format (NUM INFO-LIST), -;; otherwise it's a list in the format of the `gnus-newsrc-hashtb' -;; entries. -;; LEVEL is the new level of the group, OLDLEVEL is the old level and -;; PREVIOUS is the group (in hashtb entry format) to insert this group -;; after. -(defun gnus-group-change-level (entry level &optional oldlevel - previous fromkilled) - (let (group info active num) - ;; Glean what info we can from the arguments - (if (consp entry) - (if fromkilled (setq group (nth 1 entry)) - (setq group (car (nth 2 entry)))) - (setq group entry)) - (when (and (stringp entry) - oldlevel - (< oldlevel gnus-level-zombie)) - (setq entry (gnus-gethash entry gnus-newsrc-hashtb))) - (if (and (not oldlevel) - (consp entry)) - (setq oldlevel (gnus-info-level (nth 2 entry))) - (setq oldlevel (or oldlevel gnus-level-killed))) - (when (stringp previous) - (setq previous (gnus-gethash previous gnus-newsrc-hashtb))) - - (if (and (>= oldlevel gnus-level-zombie) - (gnus-gethash group gnus-newsrc-hashtb)) - ;; We are trying to subscribe a group that is already - ;; subscribed. - () ; Do nothing. - - (unless (gnus-ephemeral-group-p group) - (gnus-dribble-enter - (format "(gnus-group-change-level %S %S %S %S %S)" - group level oldlevel (car (nth 2 previous)) fromkilled))) - - ;; Then we remove the newgroup from any old structures, if needed. - ;; If the group was killed, we remove it from the killed or zombie - ;; list. If not, and it is in fact going to be killed, we remove - ;; it from the newsrc hash table and assoc. - (cond - ((>= oldlevel gnus-level-zombie) - (if (= oldlevel gnus-level-zombie) - (setq gnus-zombie-list (delete group gnus-zombie-list)) - (setq gnus-killed-list (delete group gnus-killed-list)))) - (t - (when (and (>= level gnus-level-zombie) - entry) - (gnus-sethash (car (nth 2 entry)) nil gnus-newsrc-hashtb) - (when (nth 3 entry) - (setcdr (gnus-gethash (car (nth 3 entry)) - gnus-newsrc-hashtb) - (cdr entry))) - (setcdr (cdr entry) (cdddr entry))))) - - ;; Finally we enter (if needed) the list where it is supposed to - ;; go, and change the subscription level. If it is to be killed, - ;; we enter it into the killed or zombie list. - (cond - ((>= level gnus-level-zombie) - ;; Remove from the hash table. - (gnus-sethash group nil gnus-newsrc-hashtb) - ;; We do not enter foreign groups into the list of dead - ;; groups. - (unless (gnus-group-foreign-p group) - (if (= level gnus-level-zombie) - (push group gnus-zombie-list) - (push group gnus-killed-list)))) - (t - ;; If the list is to be entered into the newsrc assoc, and - ;; it was killed, we have to create an entry in the newsrc - ;; hashtb format and fix the pointers in the newsrc assoc. - (if (< oldlevel gnus-level-zombie) - ;; It was alive, and it is going to stay alive, so we - ;; just change the level and don't change any pointers or - ;; hash table entries. - (setcar (cdaddr entry) level) - (if (listp entry) - (setq info (cdr entry) - num (car entry)) - (setq active (gnus-active group)) - (setq num - (if active (- (1+ (cdr active)) (car active)) t)) - ;; Check whether the group is foreign. If so, the - ;; foreign select method has to be entered into the - ;; info. - (let ((method (or gnus-override-subscribe-method - (gnus-group-method group)))) - (if (eq method gnus-select-method) - (setq info (list group level nil)) - (setq info (list group level nil nil method))))) - (unless previous - (setq previous - (let ((p gnus-newsrc-alist)) - (while (cddr p) - (setq p (cdr p))) - p))) - (setq entry (cons info (cddr previous))) - (if (cdr previous) - (progn - (setcdr (cdr previous) entry) - (gnus-sethash group (cons num (cdr previous)) - gnus-newsrc-hashtb)) - (setcdr previous entry) - (gnus-sethash group (cons num previous) - gnus-newsrc-hashtb)) - (when (cdr entry) - (setcdr (gnus-gethash (caadr entry) gnus-newsrc-hashtb) entry)) - (gnus-dribble-enter - (format - "(gnus-group-set-info '%S)" info))))) - (when gnus-group-change-level-function - (funcall gnus-group-change-level-function - group level oldlevel previous))))) - -(defun gnus-kill-newsgroup (newsgroup) - "Obsolete function. Kills a newsgroup." - (gnus-group-change-level - (gnus-gethash newsgroup gnus-newsrc-hashtb) gnus-level-killed)) - -(defun gnus-check-bogus-newsgroups (&optional confirm) - "Remove bogus newsgroups. -If CONFIRM is non-nil, the user has to confirm the deletion of every -newsgroup." - (let ((newsrc (cdr gnus-newsrc-alist)) - bogus group entry info) - (gnus-message 5 "Checking bogus newsgroups...") - (unless (gnus-read-active-file-p) - (gnus-read-active-file t)) - (when (gnus-read-active-file-p) - ;; Find all bogus newsgroup that are subscribed. - (while newsrc - (setq info (pop newsrc) - group (gnus-info-group info)) - (unless (or (gnus-active group) ; Active - (gnus-info-method info)) ; Foreign - ;; Found a bogus newsgroup. - (push group bogus))) - (if confirm - (map-y-or-n-p - "Remove bogus group %s? " - (lambda (group) - ;; Remove all bogus subscribed groups by first killing them, and - ;; then removing them from the list of killed groups. - (when (setq entry (gnus-gethash group gnus-newsrc-hashtb)) - (gnus-group-change-level entry gnus-level-killed) - (setq gnus-killed-list (delete group gnus-killed-list)))) - bogus '("group" "groups" "remove")) - (while (setq group (pop bogus)) - ;; Remove all bogus subscribed groups by first killing them, and - ;; then removing them from the list of killed groups. - (when (setq entry (gnus-gethash group gnus-newsrc-hashtb)) - (gnus-group-change-level entry gnus-level-killed) - (setq gnus-killed-list (delete group gnus-killed-list))))) - ;; Then we remove all bogus groups from the list of killed and - ;; zombie groups. They are removed without confirmation. - (let ((dead-lists '(gnus-killed-list gnus-zombie-list)) - killed) - (while dead-lists - (setq killed (symbol-value (car dead-lists))) - (while killed - (unless (gnus-active (setq group (pop killed))) - ;; The group is bogus. - ;; !!!Slow as hell. - (set (car dead-lists) - (delete group (symbol-value (car dead-lists)))))) - (setq dead-lists (cdr dead-lists)))) - (gnus-run-hooks 'gnus-check-bogus-groups-hook) - (gnus-message 5 "Checking bogus newsgroups...done")))) - -(defun gnus-check-duplicate-killed-groups () - "Remove duplicates from the list of killed groups." - (interactive) - (let ((killed gnus-killed-list)) - (while killed - (gnus-message 9 "%d" (length killed)) - (setcdr killed (delete (car killed) (cdr killed))) - (setq killed (cdr killed))))) - -;; We want to inline a function from gnus-cache, so we cheat here: -(eval-when-compile - (defvar gnus-cache-active-hashtb) - (defun gnus-cache-possibly-alter-active (group active) - "Alter the ACTIVE info for GROUP to reflect the articles in the cache." - (when gnus-cache-active-hashtb - (let ((cache-active (gnus-gethash group gnus-cache-active-hashtb))) - (when cache-active - (when (< (car cache-active) (car active)) - (setcar active (car cache-active))) - (when (> (cdr cache-active) (cdr active)) - (setcdr active (cdr cache-active)))))))) - -(defun gnus-activate-group (group &optional scan dont-check method) - ;; Check whether a group has been activated or not. - ;; If SCAN, request a scan of that group as well. - (let ((method (or method (inline (gnus-find-method-for-group group)))) - active) - (and (inline (gnus-check-server method)) - ;; We escape all bugs and quit here to make it possible to - ;; continue if a group is so out-there that it reports bugs - ;; and stuff. - (progn - (and scan - (gnus-check-backend-function 'request-scan (car method)) - (gnus-request-scan group method)) - t) - (condition-case () - (inline (gnus-request-group group dont-check method)) - (error nil) - (quit nil)) - (setq active (gnus-parse-active)) - ;; If there are no articles in the group, the GROUP - ;; command may have responded with the `(0 . 0)'. We - ;; ignore this if we already have an active entry - ;; for the group. - (if (and (zerop (car active)) - (zerop (cdr active)) - (gnus-active group)) - (gnus-active group) - (gnus-set-active group active) - ;; Return the new active info. - active)))) - -(defun gnus-get-unread-articles-in-group (info active &optional update) - (when active - ;; Allow the backend to update the info in the group. - (when (and update - (gnus-request-update-info - info (inline (gnus-find-method-for-group - (gnus-info-group info))))) - (gnus-activate-group (gnus-info-group info) nil t)) - - (let* ((range (gnus-info-read info)) - (num 0)) - ;; If a cache is present, we may have to alter the active info. - (when (and gnus-use-cache info) - (inline (gnus-cache-possibly-alter-active - (gnus-info-group info) active))) - ;; Modify the list of read articles according to what articles - ;; are available; then tally the unread articles and add the - ;; number to the group hash table entry. - (cond - ((zerop (cdr active)) - (setq num 0)) - ((not range) - (setq num (- (1+ (cdr active)) (car active)))) - ((not (listp (cdr range))) - ;; Fix a single (num . num) range according to the - ;; active hash table. - ;; Fix by Carsten Bormann . - (and (< (cdr range) (car active)) (setcdr range (1- (car active)))) - (and (> (cdr range) (cdr active)) (setcdr range (cdr active))) - ;; Compute number of unread articles. - (setq num (max 0 (- (cdr active) (- (1+ (cdr range)) (car range)))))) - (t - ;; The read list is a list of ranges. Fix them according to - ;; the active hash table. - ;; First peel off any elements that are below the lower - ;; active limit. - (while (and (cdr range) - (>= (car active) - (or (and (atom (cadr range)) (cadr range)) - (caadr range)))) - (if (numberp (car range)) - (setcar range - (cons (car range) - (or (and (numberp (cadr range)) - (cadr range)) - (cdadr range)))) - (setcdr (car range) - (or (and (numberp (nth 1 range)) (nth 1 range)) - (cdadr range)))) - (setcdr range (cddr range))) - ;; Adjust the first element to be the same as the lower limit. - (when (and (not (atom (car range))) - (< (cdar range) (car active))) - (setcdr (car range) (1- (car active)))) - ;; Then we want to peel off any elements that are higher - ;; than the upper active limit. - (let ((srange range)) - ;; Go past all legal elements. - (while (and (cdr srange) - (<= (or (and (atom (cadr srange)) - (cadr srange)) - (caadr srange)) - (cdr active))) - (setq srange (cdr srange))) - (when (cdr srange) - ;; Nuke all remaining illegal elements. - (setcdr srange nil)) - - ;; Adjust the final element. - (when (and (not (atom (car srange))) - (> (cdar srange) (cdr active))) - (setcdr (car srange) (cdr active)))) - ;; Compute the number of unread articles. - (while range - (setq num (+ num (- (1+ (or (and (atom (car range)) (car range)) - (cdar range))) - (or (and (atom (car range)) (car range)) - (caar range))))) - (setq range (cdr range))) - (setq num (max 0 (- (cdr active) num))))) - ;; Set the number of unread articles. - (when info - (setcar (gnus-gethash (gnus-info-group info) gnus-newsrc-hashtb) num)) - num))) - -;; Go though `gnus-newsrc-alist' and compare with `gnus-active-hashtb' -;; and compute how many unread articles there are in each group. -(defun gnus-get-unread-articles (&optional level) - (let* ((newsrc (cdr gnus-newsrc-alist)) - (level (or level gnus-activate-level (1+ gnus-level-subscribed))) - (foreign-level - (min - (cond ((and gnus-activate-foreign-newsgroups - (not (numberp gnus-activate-foreign-newsgroups))) - (1+ gnus-level-subscribed)) - ((numberp gnus-activate-foreign-newsgroups) - gnus-activate-foreign-newsgroups) - (t 0)) - level)) - info group active method) - (gnus-message 5 "Checking new news...") - - (while newsrc - (setq active (gnus-active (setq group (gnus-info-group - (setq info (pop newsrc)))))) - - ;; Check newsgroups. If the user doesn't want to check them, or - ;; they can't be checked (for instance, if the news server can't - ;; be reached) we just set the number of unread articles in this - ;; newsgroup to t. This means that Gnus thinks that there are - ;; unread articles, but it has no idea how many. - (if (and (setq method (gnus-info-method info)) - (not (inline - (gnus-server-equal - gnus-select-method - (setq method (gnus-server-get-method nil method))))) - (not (gnus-secondary-method-p method))) - ;; These groups are foreign. Check the level. - (when (<= (gnus-info-level info) foreign-level) - (setq active (gnus-activate-group group 'scan)) - ;; Let the Gnus agent save the active file. - (when (and gnus-agent gnus-plugged active) - (gnus-agent-save-group-info - method (gnus-group-real-name group) active)) - (unless (inline (gnus-virtual-group-p group)) - (inline (gnus-close-group group))) - (when (fboundp (intern (concat (symbol-name (car method)) - "-request-update-info"))) - (inline (gnus-request-update-info info method)))) - ;; These groups are native or secondary. - (when (and (<= (gnus-info-level info) level) - (not gnus-read-active-file)) - (setq active (gnus-activate-group group 'scan)) - (inline (gnus-close-group group)))) - - ;; Get the number of unread articles in the group. - (if active - (inline (gnus-get-unread-articles-in-group info active t)) - ;; The group couldn't be reached, so we nix out the number of - ;; unread articles and stuff. - (gnus-set-active group nil) - (setcar (gnus-gethash group gnus-newsrc-hashtb) t))) - - (gnus-message 5 "Checking new news...done"))) - -;; Create a hash table out of the newsrc alist. The `car's of the -;; alist elements are used as keys. -(defun gnus-make-hashtable-from-newsrc-alist () - (let ((alist gnus-newsrc-alist) - (ohashtb gnus-newsrc-hashtb) - prev) - (setq gnus-newsrc-hashtb (gnus-make-hashtable (length alist))) - (setq alist - (setq prev (setq gnus-newsrc-alist - (if (equal (caar gnus-newsrc-alist) - "dummy.group") - gnus-newsrc-alist - (cons (list "dummy.group" 0 nil) alist))))) - (while alist - (gnus-sethash - (caar alist) - ;; Preserve number of unread articles in groups. - (cons (and ohashtb (car (gnus-gethash (caar alist) ohashtb))) - prev) - gnus-newsrc-hashtb) - (setq prev alist - alist (cdr alist))))) - -(defun gnus-make-hashtable-from-killed () - "Create a hash table from the killed and zombie lists." - (let ((lists '(gnus-killed-list gnus-zombie-list)) - list) - (setq gnus-killed-hashtb - (gnus-make-hashtable - (+ (length gnus-killed-list) (length gnus-zombie-list)))) - (while lists - (setq list (symbol-value (pop lists))) - (while list - (gnus-sethash (car list) (pop list) gnus-killed-hashtb))))) - -(defun gnus-parse-active () - "Parse active info in the nntp server buffer." - (save-excursion - (set-buffer nntp-server-buffer) - (goto-char (point-min)) - ;; Parse the result we got from `gnus-request-group'. - (when (looking-at "[0-9]+ [0-9]+ \\([0-9]+\\) [0-9]+") - (goto-char (match-beginning 1)) - (cons (read (current-buffer)) - (read (current-buffer)))))) - -(defun gnus-make-articles-unread (group articles) - "Mark ARTICLES in GROUP as unread." - (let* ((info (nth 2 (or (gnus-gethash group gnus-newsrc-hashtb) - (gnus-gethash (gnus-group-real-name group) - gnus-newsrc-hashtb)))) - (ranges (gnus-info-read info)) - news article) - (while articles - (when (gnus-member-of-range - (setq article (pop articles)) ranges) - (push article news))) - (when news - (gnus-info-set-read - info (gnus-remove-from-range (gnus-info-read info) (nreverse news))) - (gnus-group-update-group group t)))) - -;; Enter all dead groups into the hashtb. -(defun gnus-update-active-hashtb-from-killed () - (let ((hashtb (setq gnus-active-hashtb (gnus-make-hashtable 4096))) - (lists (list gnus-killed-list gnus-zombie-list)) - killed) - (while lists - (setq killed (car lists)) - (while killed - (gnus-sethash (car killed) nil hashtb) - (setq killed (cdr killed))) - (setq lists (cdr lists))))) - -(defun gnus-get-killed-groups () - "Go through the active hashtb and mark all unknown groups as killed." - ;; First make sure active file has been read. - (unless (gnus-read-active-file-p) - (let ((gnus-read-active-file t)) - (gnus-read-active-file))) - (unless gnus-killed-hashtb - (gnus-make-hashtable-from-killed)) - ;; Go through all newsgroups that are known to Gnus - enlarge kill list. - (mapatoms - (lambda (sym) - (let ((groups 0) - (group (symbol-name sym))) - (if (or (null group) - (gnus-gethash group gnus-killed-hashtb) - (gnus-gethash group gnus-newsrc-hashtb)) - () - (let ((do-sub (gnus-matches-options-n group))) - (if (or (eq do-sub 'subscribe) (eq do-sub 'ignore)) - () - (setq groups (1+ groups)) - (push group gnus-killed-list) - (gnus-sethash group group gnus-killed-hashtb)))))) - gnus-active-hashtb) - (gnus-dribble-touch)) - -;; Get the active file(s) from the backend(s). -(defun gnus-read-active-file (&optional force not-native) - (gnus-group-set-mode-line) - (let ((methods - (append - (if (and (not not-native) - (gnus-check-server gnus-select-method)) - ;; The native server is available. - (cons gnus-select-method gnus-secondary-select-methods) - ;; The native server is down, so we just do the - ;; secondary ones. - gnus-secondary-select-methods) - ;; Also read from the archive server. - (when (gnus-archive-server-wanted-p) - (list "archive")))) - list-type) - (setq gnus-have-read-active-file nil) - (save-excursion - (set-buffer nntp-server-buffer) - (while methods - (let* ((method (if (stringp (car methods)) - (gnus-server-get-method nil (car methods)) - (car methods))) - (where (nth 1 method)) - (mesg (format "Reading active file%s via %s..." - (if (and where (not (zerop (length where)))) - (concat " from " where) "") - (car method)))) - (gnus-message 5 mesg) - (when (gnus-check-server method) - ;; Request that the backend scan its incoming messages. - (when (gnus-check-backend-function 'request-scan (car method)) - (gnus-request-scan nil method)) - (cond - ((and (eq gnus-read-active-file 'some) - (gnus-check-backend-function 'retrieve-groups (car method)) - (not force)) - (let ((newsrc (cdr gnus-newsrc-alist)) - (gmethod (gnus-server-get-method nil method)) - groups info) - (while (setq info (pop newsrc)) - (when (inline - (gnus-server-equal - (inline - (gnus-find-method-for-group - (gnus-info-group info) info)) - gmethod)) - (push (gnus-group-real-name (gnus-info-group info)) - groups))) - (when groups - (gnus-check-server method) - (setq list-type (gnus-retrieve-groups groups method)) - (cond - ((not list-type) - (gnus-error - 1.2 "Cannot read partial active file from %s server." - (car method))) - ((eq list-type 'active) - (gnus-active-to-gnus-format - method gnus-active-hashtb nil t)) - (t - (gnus-groups-to-gnus-format - method gnus-active-hashtb t)))))) - ((null method) - t) - (t - (if (not (gnus-request-list method)) - (unless (equal method gnus-message-archive-method) - (gnus-error 1 "Cannot read active file from %s server" - (car method))) - (gnus-message 5 mesg) - (gnus-active-to-gnus-format method gnus-active-hashtb nil t) - ;; We mark this active file as read. - (push method gnus-have-read-active-file) - (gnus-message 5 "%sdone" mesg)))))) - (setq methods (cdr methods)))))) - - -(defun gnus-ignored-newsgroups-has-to-p () - "Non-nil iff gnus-ignored-newsgroups includes \"^to\\\\.\" as an element." - ;; note this regexp is the same as: - ;; (concat (regexp-quote "^to\\.") "\\($\\|" (regexp-quote "\\|") "\\)") - (string-match "\\^to\\\\\\.\\($\\|\\\\|\\)" gnus-ignored-newsgroups)) - -;; Read an active file and place the results in `gnus-active-hashtb'. -(defun gnus-active-to-gnus-format (&optional method hashtb ignore-errors - real-active) - (unless method - (setq method gnus-select-method)) - (let ((cur (current-buffer)) - (hashtb (or hashtb - (if (and gnus-active-hashtb - (not (equal method gnus-select-method))) - gnus-active-hashtb - (setq gnus-active-hashtb - (if (equal method gnus-select-method) - (gnus-make-hashtable - (count-lines (point-min) (point-max))) - (gnus-make-hashtable 4096))))))) - ;; Delete unnecessary lines. - (goto-char (point-min)) - (cond ((gnus-ignored-newsgroups-has-to-p) - (delete-matching-lines gnus-ignored-newsgroups)) - ((string= gnus-ignored-newsgroups "") - (delete-matching-lines "^to\\.")) - (t - (delete-matching-lines (concat "^to\\.\\|" - gnus-ignored-newsgroups)))) - - ;; Make the group names readable as a lisp expression even if they - ;; contain special characters. - (goto-char (point-max)) - (while (re-search-backward "[][';?()#]" nil t) - (insert ?\\)) - - ;; Let the Gnus agent save the active file. - (when (and gnus-agent real-active) - (gnus-agent-save-active method)) - - ;; If these are groups from a foreign select method, we insert the - ;; group prefix in front of the group names. - (when (not (gnus-server-equal - (gnus-server-get-method nil method) - (gnus-server-get-method nil gnus-select-method))) - (let ((prefix (gnus-group-prefixed-name "" method))) - (goto-char (point-min)) - (while (and (not (eobp)) - (progn (insert prefix) - (zerop (forward-line 1))))))) - ;; Store the active file in a hash table. - (goto-char (point-min)) - (let (group max min) - (while (not (eobp)) - (condition-case () - (progn - (narrow-to-region (point) (gnus-point-at-eol)) - ;; group gets set to a symbol interned in the hash table - ;; (what a hack!!) - jwz - (setq group (let ((obarray hashtb)) (read cur))) - (if (and (numberp (setq max (read cur))) - (numberp (setq min (read cur))) - (progn - (skip-chars-forward " \t") - (not - (or (= (following-char) ?=) - (= (following-char) ?x) - (= (following-char) ?j))))) - (progn - (set group (cons min max)) - ;; if group is moderated, stick in moderation table - (when (= (following-char) ?m) - (unless gnus-moderated-hashtb - (setq gnus-moderated-hashtb (gnus-make-hashtable))) - (gnus-sethash (symbol-name group) t - gnus-moderated-hashtb))) - (set group nil))) - (error - (and group - (symbolp group) - (set group nil)) - (unless ignore-errors - (gnus-message 3 "Warning - illegal active: %s" - (buffer-substring - (gnus-point-at-bol) (gnus-point-at-eol)))))) - (widen) - (forward-line 1))))) - -(defun gnus-groups-to-gnus-format (method &optional hashtb real-active) - ;; Parse a "groups" active file. - (let ((cur (current-buffer)) - (hashtb (or hashtb - (if (and method gnus-active-hashtb) - gnus-active-hashtb - (setq gnus-active-hashtb - (gnus-make-hashtable - (count-lines (point-min) (point-max))))))) - (prefix (and method - (not (gnus-server-equal - (gnus-server-get-method nil method) - (gnus-server-get-method nil gnus-select-method))) - (gnus-group-prefixed-name "" method)))) - - ;; Let the Gnus agent save the active file. - (when (and gnus-agent real-active) - (gnus-agent-save-groups method)) - - (goto-char (point-min)) - ;; We split this into to separate loops, one with the prefix - ;; and one without to speed the reading up somewhat. - (if prefix - (let (min max opoint group) - (while (not (eobp)) - (condition-case () - (progn - (read cur) (read cur) - (setq min (read cur) - max (read cur) - opoint (point)) - (skip-chars-forward " \t") - (insert prefix) - (goto-char opoint) - (set (let ((obarray hashtb)) (read cur)) - (cons min max))) - (error (and group (symbolp group) (set group nil)))) - (forward-line 1))) - (let (min max group) - (while (not (eobp)) - (condition-case () - (when (= (following-char) ?2) - (read cur) (read cur) - (setq min (read cur) - max (read cur)) - (set (setq group (let ((obarray hashtb)) (read cur))) - (cons min max))) - (error (and group (symbolp group) (set group nil)))) - (forward-line 1)))))) - -(defun gnus-read-newsrc-file (&optional force) - "Read startup file. -If FORCE is non-nil, the .newsrc file is read." - ;; Reset variables that might be defined in the .newsrc.eld file. - (let ((variables gnus-variable-list)) - (while variables - (set (car variables) nil) - (setq variables (cdr variables)))) - (let* ((newsrc-file gnus-current-startup-file) - (quick-file (concat newsrc-file ".el"))) - (save-excursion - ;; We always load the .newsrc.eld file. If always contains - ;; much information that can not be gotten from the .newsrc - ;; file (ticked articles, killed groups, foreign methods, etc.) - (gnus-read-newsrc-el-file quick-file) - - (when (and (file-exists-p gnus-current-startup-file) - (or force - (and (file-newer-than-file-p newsrc-file quick-file) - (file-newer-than-file-p newsrc-file - (concat quick-file "d"))) - (not gnus-newsrc-alist))) - ;; We read the .newsrc file. Note that if there if a - ;; .newsrc.eld file exists, it has already been read, and - ;; the `gnus-newsrc-hashtb' has been created. While reading - ;; the .newsrc file, Gnus will only use the information it - ;; can find there for changing the data already read - - ;; i. e., reading the .newsrc file will not trash the data - ;; already read (except for read articles). - (save-excursion - (gnus-message 5 "Reading %s..." newsrc-file) - (set-buffer (nnheader-find-file-noselect newsrc-file)) - (buffer-disable-undo (current-buffer)) - (gnus-newsrc-to-gnus-format) - (kill-buffer (current-buffer)) - (gnus-message 5 "Reading %s...done" newsrc-file))) - - ;; Convert old to new. - (gnus-convert-old-newsrc)))) - -(defun gnus-convert-old-newsrc () - "Convert old newsrc into the new format, if needed." - (let ((fcv (and gnus-newsrc-file-version - (gnus-continuum-version gnus-newsrc-file-version)))) - (cond - ;; No .newsrc.eld file was loaded. - ((null fcv) nil) - ;; Gnus 5 .newsrc.eld was loaded. - ((< fcv (gnus-continuum-version "September Gnus v0.1")) - (gnus-convert-old-ticks))))) - -(defun gnus-convert-old-ticks () - (let ((newsrc (cdr gnus-newsrc-alist)) - marks info dormant ticked) - (while (setq info (pop newsrc)) - (when (setq marks (gnus-info-marks info)) - (setq dormant (cdr (assq 'dormant marks)) - ticked (cdr (assq 'tick marks))) - (when (or dormant ticked) - (gnus-info-set-read - info - (gnus-add-to-range - (gnus-info-read info) - (nconc (gnus-uncompress-range dormant) - (gnus-uncompress-range ticked))))))))) - -(defun gnus-read-newsrc-el-file (file) - (let ((ding-file (concat file "d"))) - ;; We always, always read the .eld file. - (gnus-message 5 "Reading %s..." ding-file) - (let (gnus-newsrc-assoc) - (condition-case nil - (let ((coding-system-for-read gnus-startup-file-coding-system)) - (load ding-file t t t)) - (error - (ding) - (unless (gnus-yes-or-no-p - (format "Error in %s; continue? " ding-file)) - (error "Error in %s" ding-file)))) - (when gnus-newsrc-assoc - (setq gnus-newsrc-alist gnus-newsrc-assoc))) - (gnus-make-hashtable-from-newsrc-alist) - (when (file-newer-than-file-p file ding-file) - ;; Old format quick file - (gnus-message 5 "Reading %s..." file) - ;; The .el file is newer than the .eld file, so we read that one - ;; as well. - (gnus-read-old-newsrc-el-file file)))) - -;; Parse the old-style quick startup file -(defun gnus-read-old-newsrc-el-file (file) - (let (newsrc killed marked group m info) - (prog1 - (let ((gnus-killed-assoc nil) - gnus-marked-assoc gnus-newsrc-alist gnus-newsrc-assoc) - (prog1 - (ignore-errors - (load file t t t)) - (setq newsrc gnus-newsrc-assoc - killed gnus-killed-assoc - marked gnus-marked-assoc))) - (setq gnus-newsrc-alist nil) - (while (setq group (pop newsrc)) - (if (setq info (gnus-get-info (car group))) - (progn - (gnus-info-set-read info (cddr group)) - (gnus-info-set-level - info (if (nth 1 group) gnus-level-default-subscribed - gnus-level-default-unsubscribed)) - (push info gnus-newsrc-alist)) - (push (setq info - (list (car group) - (if (nth 1 group) gnus-level-default-subscribed - gnus-level-default-unsubscribed) - (cddr group))) - gnus-newsrc-alist)) - ;; Copy marks into info. - (when (setq m (assoc (car group) marked)) - (unless (nthcdr 3 info) - (nconc info (list nil))) - (gnus-info-set-marks - info (list (cons 'tick (gnus-compress-sequence - (sort (cdr m) '<) t)))))) - (setq newsrc killed) - (while newsrc - (setcar newsrc (caar newsrc)) - (setq newsrc (cdr newsrc))) - (setq gnus-killed-list killed)) - ;; The .el file version of this variable does not begin with - ;; "options", while the .eld version does, so we just add it if it - ;; isn't there. - (when - gnus-newsrc-options - (when (not (string-match "^ *options" gnus-newsrc-options)) - (setq gnus-newsrc-options (concat "options " gnus-newsrc-options))) - (when (not (string-match "\n$" gnus-newsrc-options)) - (setq gnus-newsrc-options (concat gnus-newsrc-options "\n"))) - ;; Finally, if we read some options lines, we parse them. - (unless (string= gnus-newsrc-options "") - (gnus-newsrc-parse-options gnus-newsrc-options))) - - (setq gnus-newsrc-alist (nreverse gnus-newsrc-alist)) - (gnus-make-hashtable-from-newsrc-alist))) - -(defun gnus-make-newsrc-file (file) - "Make server dependent file name by catenating FILE and server host name." - (let* ((file (expand-file-name file nil)) - (real-file (concat file "-" (nth 1 gnus-select-method)))) - (if (or (file-exists-p real-file) - (file-exists-p (concat real-file ".el")) - (file-exists-p (concat real-file ".eld"))) - real-file - file))) - -(defun gnus-newsrc-to-gnus-format () - (setq gnus-newsrc-options "") - (setq gnus-newsrc-options-n nil) - - (unless gnus-active-hashtb - (setq gnus-active-hashtb (gnus-make-hashtable 4096))) - (let ((buf (current-buffer)) - (already-read (> (length gnus-newsrc-alist) 1)) - group subscribed options-symbol newsrc Options-symbol - symbol reads num1) - (goto-char (point-min)) - ;; We intern the symbol `options' in the active hashtb so that we - ;; can `eq' against it later. - (set (setq options-symbol (intern "options" gnus-active-hashtb)) nil) - (set (setq Options-symbol (intern "Options" gnus-active-hashtb)) nil) - - (while (not (eobp)) - ;; We first read the first word on the line by narrowing and - ;; then reading into `gnus-active-hashtb'. Most groups will - ;; already exist in that hashtb, so this will save some string - ;; space. - (narrow-to-region - (point) - (progn (skip-chars-forward "^ \t!:\n") (point))) - (goto-char (point-min)) - (setq symbol - (and (/= (point-min) (point-max)) - (let ((obarray gnus-active-hashtb)) (read buf)))) - (widen) - ;; Now, the symbol we have read is either `options' or a group - ;; name. If it is an options line, we just add it to a string. - (cond - ((or (eq symbol options-symbol) - (eq symbol Options-symbol)) - (setq gnus-newsrc-options - ;; This concating is quite inefficient, but since our - ;; thorough studies show that approx 99.37% of all - ;; .newsrc files only contain a single options line, we - ;; don't give a damn, frankly, my dear. - (concat gnus-newsrc-options - (buffer-substring - (gnus-point-at-bol) - ;; Options may continue on the next line. - (or (and (re-search-forward "^[^ \t]" nil 'move) - (progn (beginning-of-line) (point))) - (point))))) - (forward-line -1)) - (symbol - ;; Group names can be just numbers. - (when (numberp symbol) - (setq symbol (intern (int-to-string symbol) gnus-active-hashtb))) - (unless (boundp symbol) - (set symbol nil)) - ;; It was a group name. - (setq subscribed (= (following-char) ?:) - group (symbol-name symbol) - reads nil) - (if (eolp) - ;; If the line ends here, this is clearly a buggy line, so - ;; we put point a the beginning of line and let the cond - ;; below do the error handling. - (beginning-of-line) - ;; We skip to the beginning of the ranges. - (skip-chars-forward "!: \t")) - ;; We are now at the beginning of the list of read articles. - ;; We read them range by range. - (while - (cond - ((looking-at "[0-9]+") - ;; We narrow and read a number instead of buffer-substring/ - ;; string-to-int because it's faster. narrow/widen is - ;; faster than save-restriction/narrow, and save-restriction - ;; produces a garbage object. - (setq num1 (progn - (narrow-to-region (match-beginning 0) (match-end 0)) - (read buf))) - (widen) - ;; If the next character is a dash, then this is a range. - (if (= (following-char) ?-) - (progn - ;; We read the upper bound of the range. - (forward-char 1) - (if (not (looking-at "[0-9]+")) - ;; This is a buggy line, by we pretend that - ;; it's kinda OK. Perhaps the user should be - ;; dinged? - (push num1 reads) - (push - (cons num1 - (progn - (narrow-to-region (match-beginning 0) - (match-end 0)) - (read buf))) - reads) - (widen))) - ;; It was just a simple number, so we add it to the - ;; list of ranges. - (push num1 reads)) - ;; If the next char in ?\n, then we have reached the end - ;; of the line and return nil. - (/= (following-char) ?\n)) - ((= (following-char) ?\n) - ;; End of line, so we end. - nil) - (t - ;; Not numbers and not eol, so this might be a buggy - ;; line... - (unless (eobp) - ;; If it was eob instead of ?\n, we allow it. - ;; The line was buggy. - (setq group nil) - (gnus-error 3.1 "Mangled line: %s" - (buffer-substring (gnus-point-at-bol) - (gnus-point-at-eol)))) - nil)) - ;; Skip past ", ". Spaces are illegal in these ranges, but - ;; we allow them, because it's a common mistake to put a - ;; space after the comma. - (skip-chars-forward ", ")) - - ;; We have already read .newsrc.eld, so we gently update the - ;; data in the hash table with the information we have just - ;; read. - (when group - (let ((info (gnus-get-info group)) - level) - (if info - ;; There is an entry for this file in the alist. - (progn - (gnus-info-set-read info (nreverse reads)) - ;; We update the level very gently. In fact, we - ;; only change it if there's been a status change - ;; from subscribed to unsubscribed, or vice versa. - (setq level (gnus-info-level info)) - (cond ((and (<= level gnus-level-subscribed) - (not subscribed)) - (setq level (if reads - gnus-level-default-unsubscribed - (1+ gnus-level-default-unsubscribed)))) - ((and (> level gnus-level-subscribed) subscribed) - (setq level gnus-level-default-subscribed))) - (gnus-info-set-level info level)) - ;; This is a new group. - (setq info (list group - (if subscribed - gnus-level-default-subscribed - (if reads - (1+ gnus-level-subscribed) - gnus-level-default-unsubscribed)) - (nreverse reads)))) - (push info newsrc))))) - (forward-line 1)) - - (setq newsrc (nreverse newsrc)) - - (if (not already-read) - () - ;; We now have two newsrc lists - `newsrc', which is what we - ;; have read from .newsrc, and `gnus-newsrc-alist', which is - ;; what we've read from .newsrc.eld. We have to merge these - ;; lists. We do this by "attaching" any (foreign) groups in the - ;; gnus-newsrc-alist to the (native) group that precedes them. - (let ((rc (cdr gnus-newsrc-alist)) - (prev gnus-newsrc-alist) - entry mentry) - (while rc - (or (null (nth 4 (car rc))) ; It's a native group. - (assoc (caar rc) newsrc) ; It's already in the alist. - (if (setq entry (assoc (caar prev) newsrc)) - (setcdr (setq mentry (memq entry newsrc)) - (cons (car rc) (cdr mentry))) - (push (car rc) newsrc))) - (setq prev rc - rc (cdr rc))))) - - (setq gnus-newsrc-alist newsrc) - ;; We make the newsrc hashtb. - (gnus-make-hashtable-from-newsrc-alist) - - ;; Finally, if we read some options lines, we parse them. - (unless (string= gnus-newsrc-options "") - (gnus-newsrc-parse-options gnus-newsrc-options)))) - -;; Parse options lines to find "options -n !all rec.all" and stuff. -;; The return value will be a list on the form -;; ((regexp1 . ignore) -;; (regexp2 . subscribe)...) -;; When handling new newsgroups, groups that match a `ignore' regexp -;; will be ignored, and groups that match a `subscribe' regexp will be -;; subscribed. A line like -;; options -n !all rec.all -;; will lead to a list that looks like -;; (("^rec\\..+" . subscribe) -;; ("^.+" . ignore)) -;; So all "rec.*" groups will be subscribed, while all the other -;; groups will be ignored. Note that "options -n !all rec.all" is very -;; different from "options -n rec.all !all". -(defun gnus-newsrc-parse-options (options) - (let (out eol) - (save-excursion - (gnus-set-work-buffer) - (insert (regexp-quote options)) - ;; First we treat all continuation lines. - (goto-char (point-min)) - (while (re-search-forward "\n[ \t]+" nil t) - (replace-match " " t t)) - ;; Then we transform all "all"s into ".+"s. - (goto-char (point-min)) - (while (re-search-forward "\\ball\\b" nil t) - (replace-match ".+" t t)) - (goto-char (point-min)) - ;; We remove all other options than the "-n" ones. - (while (re-search-forward "[ \t]-[^n][^-]*" nil t) - (replace-match " ") - (forward-char -1)) - (goto-char (point-min)) - - ;; We are only interested in "options -n" lines - we - ;; ignore the other option lines. - (while (re-search-forward "[ \t]-n" nil t) - (setq eol - (or (save-excursion - (and (re-search-forward "[ \t]-n" (gnus-point-at-eol) t) - (- (point) 2))) - (gnus-point-at-eol))) - ;; Search for all "words"... - (while (re-search-forward "[^ \t,\n]+" eol t) - (if (= (char-after (match-beginning 0)) ?!) - ;; If the word begins with a bang (!), this is a "not" - ;; spec. We put this spec (minus the bang) and the - ;; symbol `ignore' into the list. - (push (cons (concat - "^" (buffer-substring - (1+ (match-beginning 0)) - (match-end 0)) - "\\($\\|\\.\\)") - 'ignore) - out) - ;; There was no bang, so this is a "yes" spec. - (push (cons (concat "^" (match-string 0) "\\($\\|\\.\\)") - 'subscribe) - out)))) - - (setq gnus-newsrc-options-n out)))) - -(defun gnus-save-newsrc-file (&optional force) - "Save .newsrc file." - ;; Note: We cannot save .newsrc file if all newsgroups are removed - ;; from the variable gnus-newsrc-alist. - (when (and (or gnus-newsrc-alist gnus-killed-list) - gnus-current-startup-file) - (save-excursion - (if (and (or gnus-use-dribble-file gnus-slave) - (not force) - (or (not gnus-dribble-buffer) - (not (buffer-name gnus-dribble-buffer)) - (zerop (save-excursion - (set-buffer gnus-dribble-buffer) - (buffer-size))))) - (gnus-message 4 "(No changes need to be saved)") - (gnus-run-hooks 'gnus-save-newsrc-hook) - (if gnus-slave - (gnus-slave-save-newsrc) - ;; Save .newsrc. - (when gnus-save-newsrc-file - (gnus-message 8 "Saving %s..." gnus-current-startup-file) - (gnus-gnus-to-newsrc-format) - (gnus-message 8 "Saving %s...done" gnus-current-startup-file)) - ;; Save .newsrc.eld. - (set-buffer (gnus-get-buffer-create " *Gnus-newsrc*")) - (make-local-variable 'version-control) - (setq version-control 'never) - (setq buffer-file-name - (concat gnus-current-startup-file ".eld")) - (setq default-directory (file-name-directory buffer-file-name)) - (buffer-disable-undo (current-buffer)) - (erase-buffer) - (gnus-message 5 "Saving %s.eld..." gnus-current-startup-file) - (gnus-gnus-to-quick-newsrc-format) - (gnus-run-hooks 'gnus-save-quick-newsrc-hook) - (let ((coding-system-for-write gnus-startup-file-coding-system)) - (save-buffer)) - (kill-buffer (current-buffer)) - (gnus-message - 5 "Saving %s.eld...done" gnus-current-startup-file)) - (gnus-dribble-delete-file) - (gnus-group-set-mode-line))))) - -(defun gnus-gnus-to-quick-newsrc-format () - "Insert Gnus variables such as gnus-newsrc-alist in lisp format." - (let ((print-quoted t) - (print-escape-newlines t)) - (insert ";; -*- emacs-lisp -*-\n") - (insert ";; Gnus startup file.\n") - (insert "\ -;; Never delete this file -- if you want to force Gnus to read the -;; .newsrc file (if you have one), touch .newsrc instead.\n") - (insert "(setq gnus-newsrc-file-version " - (prin1-to-string gnus-version) ")\n") - (let* ((gnus-killed-list - (if (and gnus-save-killed-list - (stringp gnus-save-killed-list)) - (gnus-strip-killed-list) - gnus-killed-list)) - (variables - (if gnus-save-killed-list gnus-variable-list - ;; Remove the `gnus-killed-list' from the list of variables - ;; to be saved, if required. - (delq 'gnus-killed-list (copy-sequence gnus-variable-list)))) - ;; Peel off the "dummy" group. - (gnus-newsrc-alist (cdr gnus-newsrc-alist)) - variable) - ;; Insert the variables into the file. - (while variables - (when (and (boundp (setq variable (pop variables))) - (symbol-value variable)) - (insert "(setq " (symbol-name variable) " '") - (gnus-prin1 (symbol-value variable)) - (insert ")\n")))))) - -(defun gnus-strip-killed-list () - "Return the killed list minus the groups that match `gnus-save-killed-list'." - (let ((list gnus-killed-list) - olist) - (while list - (when (string-match gnus-save-killed-list (car list)) - (push (car list) olist)) - (pop list)) - (nreverse olist))) - -(defun gnus-gnus-to-newsrc-format () - ;; Generate and save the .newsrc file. - (save-excursion - (set-buffer (create-file-buffer gnus-current-startup-file)) - (let ((newsrc (cdr gnus-newsrc-alist)) - (standard-output (current-buffer)) - info ranges range method) - (setq buffer-file-name gnus-current-startup-file) - (setq default-directory (file-name-directory buffer-file-name)) - (buffer-disable-undo (current-buffer)) - (erase-buffer) - ;; Write options. - (when gnus-newsrc-options - (insert gnus-newsrc-options)) - ;; Write subscribed and unsubscribed. - (while (setq info (pop newsrc)) - ;; Don't write foreign groups to .newsrc. - (when (or (null (setq method (gnus-info-method info))) - (equal method "native") - (inline (gnus-server-equal method gnus-select-method))) - (insert (gnus-info-group info) - (if (> (gnus-info-level info) gnus-level-subscribed) - "!" ":")) - (when (setq ranges (gnus-info-read info)) - (insert " ") - (if (not (listp (cdr ranges))) - (if (= (car ranges) (cdr ranges)) - (princ (car ranges)) - (princ (car ranges)) - (insert "-") - (princ (cdr ranges))) - (while (setq range (pop ranges)) - (if (or (atom range) (= (car range) (cdr range))) - (princ (or (and (atom range) range) (car range))) - (princ (car range)) - (insert "-") - (princ (cdr range))) - (when ranges - (insert ","))))) - (insert "\n"))) - (make-local-variable 'version-control) - (setq version-control 'never) - ;; It has been reported that sometime the modtime on the .newsrc - ;; file seems to be off. We really do want to overwrite it, so - ;; we clear the modtime here before saving. It's a bit odd, - ;; though... - ;; sometimes the modtime clear isn't sufficient. most brute force: - ;; delete the silly thing entirely first. but this fails to provide - ;; such niceties as .newsrc~ creation. - (if gnus-modtime-botch - (delete-file gnus-startup-file) - (clear-visited-file-modtime)) - (gnus-run-hooks 'gnus-save-standard-newsrc-hook) - (save-buffer) - (kill-buffer (current-buffer))))) - - -;;; -;;; Slave functions. -;;; - -(defvar gnus-slave-mode nil) - -(defun gnus-slave-mode () - "Minor mode for slave Gnusae." - (gnus-add-minor-mode 'gnus-slave-mode " Slave" (make-sparse-keymap)) - (gnus-run-hooks 'gnus-slave-mode-hook)) - -(defun gnus-slave-save-newsrc () - (save-excursion - (set-buffer gnus-dribble-buffer) - (let ((slave-name - (make-temp-name (concat gnus-current-startup-file "-slave-"))) - (modes (ignore-errors - (file-modes (concat gnus-current-startup-file ".eld"))))) - (gnus-write-buffer slave-name) - (when modes - (set-file-modes slave-name modes))))) - -(defun gnus-master-read-slave-newsrc () - (let ((slave-files - (directory-files - (file-name-directory gnus-current-startup-file) - t (concat - "^" (regexp-quote - (concat - (file-name-nondirectory gnus-current-startup-file) - "-slave-"))) - t)) - file) - (if (not slave-files) - () ; There are no slave files to read. - (gnus-message 7 "Reading slave newsrcs...") - (save-excursion - (set-buffer (gnus-get-buffer-create " *gnus slave*")) - (buffer-disable-undo (current-buffer)) - (setq slave-files - (sort (mapcar (lambda (file) - (list (nth 5 (file-attributes file)) file)) - slave-files) - (lambda (f1 f2) - (or (< (caar f1) (caar f2)) - (< (nth 1 (car f1)) (nth 1 (car f2))))))) - (while slave-files - (erase-buffer) - (setq file (nth 1 (car slave-files))) - (insert-file-contents file) - (when (condition-case () - (progn - (eval-buffer (current-buffer)) - t) - (error - (gnus-error 3.2 "Possible error in %s" file) - nil)) - (unless gnus-slave ; Slaves shouldn't delete these files. - (ignore-errors - (delete-file file)))) - (setq slave-files (cdr slave-files)))) - (gnus-dribble-touch) - (gnus-message 7 "Reading slave newsrcs...done")))) - - -;;; -;;; Group description. -;;; - -(defun gnus-read-all-descriptions-files () - (let ((methods (cons gnus-select-method - (nconc - (when (gnus-archive-server-wanted-p) - (list "archive")) - gnus-secondary-select-methods)))) - (while methods - (gnus-read-descriptions-file (car methods)) - (setq methods (cdr methods))) - t)) - -(defun gnus-read-descriptions-file (&optional method) - (let ((method (or method gnus-select-method)) - group) - (when (stringp method) - (setq method (gnus-server-to-method method))) - ;; We create the hashtable whether we manage to read the desc file - ;; to avoid trying to re-read after a failed read. - (unless gnus-description-hashtb - (setq gnus-description-hashtb - (gnus-make-hashtable (length gnus-active-hashtb)))) - ;; Mark this method's desc file as read. - (gnus-sethash (gnus-group-prefixed-name "" method) "Has read" - gnus-description-hashtb) - - (gnus-message 5 "Reading descriptions file via %s..." (car method)) - (cond - ((not (gnus-check-server method)) - (gnus-message 1 "Couldn't open server") - nil) - ((not (gnus-request-list-newsgroups method)) - (gnus-message 1 "Couldn't read newsgroups descriptions") - nil) - (t - (save-excursion - (save-restriction - (set-buffer nntp-server-buffer) - (goto-char (point-min)) - (when (or (search-forward "\n.\n" nil t) - (goto-char (point-max))) - (beginning-of-line) - (narrow-to-region (point-min) (point))) - ;; If these are groups from a foreign select method, we insert the - ;; group prefix in front of the group names. - (and method (not (inline - (gnus-server-equal - (gnus-server-get-method nil method) - (gnus-server-get-method - nil gnus-select-method)))) - (let ((prefix (gnus-group-prefixed-name "" method))) - (goto-char (point-min)) - (while (and (not (eobp)) - (progn (insert prefix) - (zerop (forward-line 1))))))) - (goto-char (point-min)) - (while (not (eobp)) - ;; If we get an error, we set group to 0, which is not a - ;; symbol... - (setq group - (condition-case () - (let ((obarray gnus-description-hashtb)) - ;; Group is set to a symbol interned in this - ;; hash table. - (read nntp-server-buffer)) - (error 0))) - (skip-chars-forward " \t") - ;; ... which leads to this line being effectively ignored. - (when (symbolp group) - (let ((str (buffer-substring - (point) (progn (end-of-line) (point)))) - (coding - (and (boundp 'enable-multibyte-characters) - enable-multibyte-characters - (fboundp 'gnus-mule-get-coding-system) - (gnus-mule-get-coding-system (symbol-name group))))) - (if coding - (setq str (gnus-decode-coding-string str (car coding)))) - (set group str))) - (forward-line 1)))) - (gnus-message 5 "Reading descriptions file...done") - t)))) - -(defun gnus-group-get-description (group) - "Get the description of a group by sending XGTITLE to the server." - (when (gnus-request-group-description group) - (save-excursion - (set-buffer nntp-server-buffer) - (goto-char (point-min)) - (when (looking-at "[^ \t]+[ \t]+\\(.*\\)") - (match-string 1))))) - -;;;###autoload -(defun gnus-declare-backend (name &rest abilities) - "Declare backend NAME with ABILITIES as a Gnus backend." - (setq gnus-valid-select-methods - (nconc gnus-valid-select-methods - (list (apply 'list name abilities))))) - -(defun gnus-set-default-directory () - "Set the default directory in the current buffer to `gnus-default-directory'. -If this variable is nil, don't do anything." - (setq default-directory - (if (and gnus-default-directory - (file-exists-p gnus-default-directory)) - (file-name-as-directory (expand-file-name gnus-default-directory)) - default-directory))) - -(provide 'gnus-start) - -;;; gnus-start.el ends here diff --git a/lisp/gnus-sum.el b/lisp/gnus-sum.el deleted file mode 100644 index 77b13c8..0000000 --- a/lisp/gnus-sum.el +++ /dev/null @@ -1,9011 +0,0 @@ -;;; gnus-sum.el --- summary mode commands for Semi-gnus -;; Copyright (C) 1996,97,98 Free Software Foundation, Inc. - -;; Author: Lars Magne Ingebrigtsen -;; MORIOKA Tomohiko -;; Keywords: mail, news, MIME - -;; This file is part of GNU Emacs. - -;; GNU Emacs is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 2, or (at your option) -;; any later version. - -;; GNU Emacs is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs; see the file COPYING. If not, write to the -;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. - -;;; Commentary: - -;;; Code: - -(eval-when-compile (require 'cl)) - -(require 'gnus) -(require 'gnus-group) -(require 'gnus-spec) -(require 'gnus-range) -(require 'gnus-int) -(require 'gnus-undo) -(require 'mime-view) - -(autoload 'gnus-summary-limit-include-cached "gnus-cache" nil t) -(autoload 'gnus-set-summary-default-charset "gnus-i18n" nil t) - -(defcustom gnus-kill-summary-on-exit t - "*If non-nil, kill the summary buffer when you exit from it. -If nil, the summary will become a \"*Dead Summary*\" buffer, and -it will be killed sometime later." - :group 'gnus-summary-exit - :type 'boolean) - -(defcustom gnus-fetch-old-headers nil - "*Non-nil means that Gnus will try to build threads by grabbing old headers. -If an unread article in the group refers to an older, already read (or -just marked as read) article, the old article will not normally be -displayed in the Summary buffer. If this variable is non-nil, Gnus -will attempt to grab the headers to the old articles, and thereby -build complete threads. If it has the value `some', only enough -headers to connect otherwise loose threads will be displayed. This -variable can also be a number. In that case, no more than that number -of old headers will be fetched. If it has the value `invisible', all -old headers will be fetched, but none will be displayed. - -The server has to support NOV for any of this to work." - :group 'gnus-thread - :type '(choice (const :tag "off" nil) - (const some) - number - (sexp :menu-tag "other" t))) - -(defcustom gnus-refer-thread-limit 200 - "*The number of old headers to fetch when doing \\\\[gnus-summary-refer-thread]. -If t, fetch all the available old headers." - :group 'gnus-thread - :type '(choice number - (sexp :menu-tag "other" t))) - -(defcustom gnus-summary-make-false-root 'adopt - "*nil means that Gnus won't gather loose threads. -If the root of a thread has expired or been read in a previous -session, the information necessary to build a complete thread has been -lost. Instead of having many small sub-threads from this original thread -scattered all over the summary buffer, Gnus can gather them. - -If non-nil, Gnus will try to gather all loose sub-threads from an -original thread into one large thread. - -If this variable is non-nil, it should be one of `none', `adopt', -`dummy' or `empty'. - -If this variable is `none', Gnus will not make a false root, but just -present the sub-threads after another. -If this variable is `dummy', Gnus will create a dummy root that will -have all the sub-threads as children. -If this variable is `adopt', Gnus will make one of the \"children\" -the parent and mark all the step-children as such. -If this variable is `empty', the \"children\" are printed with empty -subject fields. (Or rather, they will be printed with a string -given by the `gnus-summary-same-subject' variable.)" - :group 'gnus-thread - :type '(choice (const :tag "off" nil) - (const none) - (const dummy) - (const adopt) - (const empty))) - -(defcustom gnus-summary-gather-exclude-subject "^ *$\\|^(none)$" - "*A regexp to match subjects to be excluded from loose thread gathering. -As loose thread gathering is done on subjects only, that means that -there can be many false gatherings performed. By rooting out certain -common subjects, gathering might become saner." - :group 'gnus-thread - :type 'regexp) - -(defcustom gnus-summary-gather-subject-limit nil - "*Maximum length of subject comparisons when gathering loose threads. -Use nil to compare full subjects. Setting this variable to a low -number will help gather threads that have been corrupted by -newsreaders chopping off subject lines, but it might also mean that -unrelated articles that have subject that happen to begin with the -same few characters will be incorrectly gathered. - -If this variable is `fuzzy', Gnus will use a fuzzy algorithm when -comparing subjects." - :group 'gnus-thread - :type '(choice (const :tag "off" nil) - (const fuzzy) - (sexp :menu-tag "on" t))) - -(defcustom gnus-simplify-subject-functions nil - "List of functions taking a string argument that simplify subjects. -The functions are applied recursively. - -Useful functions to put in this list include: `gnus-simplify-subject-re', -`gnus-simplify-subject-fuzzy' and `gnus-simplify-whitespace'." - :group 'gnus-thread - :type '(repeat function)) - -(defcustom gnus-simplify-ignored-prefixes nil - "*Regexp, matches for which are removed from subject lines when simplifying fuzzily." - :group 'gnus-thread - :type '(choice (const :tag "off" nil) - regexp)) - -(defcustom gnus-build-sparse-threads nil - "*If non-nil, fill in the gaps in threads. -If `some', only fill in the gaps that are needed to tie loose threads -together. If `more', fill in all leaf nodes that Gnus can find. If -non-nil and non-`some', fill in all gaps that Gnus manages to guess." - :group 'gnus-thread - :type '(choice (const :tag "off" nil) - (const some) - (const more) - (sexp :menu-tag "all" t))) - -(defcustom gnus-summary-thread-gathering-function - 'gnus-gather-threads-by-subject - "*Function used for gathering loose threads. -There are two pre-defined functions: `gnus-gather-threads-by-subject', -which only takes Subjects into consideration; and -`gnus-gather-threads-by-references', which compared the References -headers of the articles to find matches." - :group 'gnus-thread - :type '(radio (function-item gnus-gather-threads-by-subject) - (function-item gnus-gather-threads-by-references) - (function :tag "other"))) - -(defcustom gnus-summary-same-subject "" - "*String indicating that the current article has the same subject as the previous. -This variable will only be used if the value of -`gnus-summary-make-false-root' is `empty'." - :group 'gnus-summary-format - :type 'string) - -(defcustom gnus-summary-goto-unread t - "*If t, marking commands will go to the next unread article. -If `never', commands that usually go to the next unread article, will -go to the next article, whether it is read or not. -If nil, only the marking commands will go to the next (un)read article." - :group 'gnus-summary-marks - :link '(custom-manual "(gnus)Setting Marks") - :type '(choice (const :tag "off" nil) - (const never) - (sexp :menu-tag "on" t))) - -(defcustom gnus-summary-default-score 0 - "*Default article score level. -All scores generated by the score files will be added to this score. -If this variable is nil, scoring will be disabled." - :group 'gnus-score-default - :type '(choice (const :tag "disable") - integer)) - -(defcustom gnus-summary-zcore-fuzz 0 - "*Fuzziness factor for the zcore in the summary buffer. -Articles with scores closer than this to `gnus-summary-default-score' -will not be marked." - :group 'gnus-summary-format - :type 'integer) - -(defcustom gnus-simplify-subject-fuzzy-regexp nil - "*Strings to be removed when doing fuzzy matches. -This can either be a regular expression or list of regular expressions -that will be removed from subject strings if fuzzy subject -simplification is selected." - :group 'gnus-thread - :type '(repeat regexp)) - -(defcustom gnus-show-threads t - "*If non-nil, display threads in summary mode." - :group 'gnus-thread - :type 'boolean) - -(defcustom gnus-thread-hide-subtree nil - "*If non-nil, hide all threads initially. -If threads are hidden, you have to run the command -`gnus-summary-show-thread' by hand or use `gnus-select-article-hook' -to expose hidden threads." - :group 'gnus-thread - :type 'boolean) - -(defcustom gnus-thread-hide-killed t - "*If non-nil, hide killed threads automatically." - :group 'gnus-thread - :type 'boolean) - -(defcustom gnus-thread-ignore-subject t - "*If non-nil, which is the default, ignore subjects and do all threading based on the Reference header. -If nil, articles that have different subjects from their parents will -start separate threads." - :group 'gnus-thread - :type 'boolean) - -(defcustom gnus-thread-operation-ignore-subject t - "*If non-nil, subjects will be ignored when doing thread commands. -This affects commands like `gnus-summary-kill-thread' and -`gnus-summary-lower-thread'. - -If this variable is nil, articles in the same thread with different -subjects will not be included in the operation in question. If this -variable is `fuzzy', only articles that have subjects that are fuzzily -equal will be included." - :group 'gnus-thread - :type '(choice (const :tag "off" nil) - (const fuzzy) - (sexp :tag "on" t))) - -(defcustom gnus-thread-indent-level 4 - "*Number that says how much each sub-thread should be indented." - :group 'gnus-thread - :type 'integer) - -(defcustom gnus-auto-extend-newsgroup t - "*If non-nil, extend newsgroup forward and backward when requested." - :group 'gnus-summary-choose - :type 'boolean) - -(defcustom gnus-auto-select-first t - "*If nil, don't select the first unread article when entering a group. -If this variable is `best', select the highest-scored unread article -in the group. If neither nil nor `best', select the first unread -article. - -If you want to prevent automatic selection of the first unread article -in some newsgroups, set the variable to nil in -`gnus-select-group-hook'." - :group 'gnus-group-select - :type '(choice (const :tag "none" nil) - (const best) - (sexp :menu-tag "first" t))) - -(defcustom gnus-auto-select-next t - "*If non-nil, offer to go to the next group from the end of the previous. -If the value is t and the next newsgroup is empty, Gnus will exit -summary mode and go back to group mode. If the value is neither nil -nor t, Gnus will select the following unread newsgroup. In -particular, if the value is the symbol `quietly', the next unread -newsgroup will be selected without any confirmation, and if it is -`almost-quietly', the next group will be selected without any -confirmation if you are located on the last article in the group. -Finally, if this variable is `slightly-quietly', the `Z n' command -will go to the next group without confirmation." - :group 'gnus-summary-maneuvering - :type '(choice (const :tag "off" nil) - (const quietly) - (const almost-quietly) - (const slightly-quietly) - (sexp :menu-tag "on" t))) - -(defcustom gnus-auto-select-same nil - "*If non-nil, select the next article with the same subject. -If there are no more articles with the same subject, go to -the first unread article." - :group 'gnus-summary-maneuvering - :type 'boolean) - -(defcustom gnus-summary-check-current nil - "*If non-nil, consider the current article when moving. -The \"unread\" movement commands will stay on the same line if the -current article is unread." - :group 'gnus-summary-maneuvering - :type 'boolean) - -(defcustom gnus-auto-center-summary t - "*If non-nil, always center the current summary buffer. -In particular, if `vertical' do only vertical recentering. If non-nil -and non-`vertical', do both horizontal and vertical recentering." - :group 'gnus-summary-maneuvering - :type '(choice (const :tag "none" nil) - (const vertical) - (sexp :menu-tag "both" t))) - -(defcustom gnus-show-all-headers nil - "*If non-nil, don't hide any headers." - :group 'gnus-article-hiding - :group 'gnus-article-headers - :type 'boolean) - -(defcustom gnus-summary-ignore-duplicates nil - "*If non-nil, ignore articles with identical Message-ID headers." - :group 'gnus-summary - :type 'boolean) - -(defcustom gnus-single-article-buffer t - "*If non-nil, display all articles in the same buffer. -If nil, each group will get its own article buffer." - :group 'gnus-article-various - :type 'boolean) - -(defcustom gnus-break-pages t - "*If non-nil, do page breaking on articles. -The page delimiter is specified by the `gnus-page-delimiter' -variable." - :group 'gnus-article-various - :type 'boolean) - -(defcustom gnus-show-mime t - "*If non-nil, do mime processing of articles. -The articles will simply be fed to the function given by -`gnus-show-mime-method'." - :group 'gnus-article-mime - :type 'boolean) - -(defcustom gnus-move-split-methods nil - "*Variable used to suggest where articles are to be moved to. -It uses the same syntax as the `gnus-split-methods' variable." - :group 'gnus-summary-mail - :type '(repeat (choice (list :value (fun) function) - (cons :value ("" "") regexp (repeat string)) - (sexp :value nil)))) - -(defcustom gnus-unread-mark ? - "*Mark used for unread articles." - :group 'gnus-summary-marks - :type 'character) - -(defcustom gnus-ticked-mark ?! - "*Mark used for ticked articles." - :group 'gnus-summary-marks - :type 'character) - -(defcustom gnus-dormant-mark ?? - "*Mark used for dormant articles." - :group 'gnus-summary-marks - :type 'character) - -(defcustom gnus-del-mark ?r - "*Mark used for del'd articles." - :group 'gnus-summary-marks - :type 'character) - -(defcustom gnus-read-mark ?R - "*Mark used for read articles." - :group 'gnus-summary-marks - :type 'character) - -(defcustom gnus-expirable-mark ?E - "*Mark used for expirable articles." - :group 'gnus-summary-marks - :type 'character) - -(defcustom gnus-killed-mark ?K - "*Mark used for killed articles." - :group 'gnus-summary-marks - :type 'character) - -(defcustom gnus-souped-mark ?F - "*Mark used for killed articles." - :group 'gnus-summary-marks - :type 'character) - -(defcustom gnus-kill-file-mark ?X - "*Mark used for articles killed by kill files." - :group 'gnus-summary-marks - :type 'character) - -(defcustom gnus-low-score-mark ?Y - "*Mark used for articles with a low score." - :group 'gnus-summary-marks - :type 'character) - -(defcustom gnus-catchup-mark ?C - "*Mark used for articles that are caught up." - :group 'gnus-summary-marks - :type 'character) - -(defcustom gnus-replied-mark ?A - "*Mark used for articles that have been replied to." - :group 'gnus-summary-marks - :type 'character) - -(defcustom gnus-cached-mark ?* - "*Mark used for articles that are in the cache." - :group 'gnus-summary-marks - :type 'character) - -(defcustom gnus-saved-mark ?S - "*Mark used for articles that have been saved to." - :group 'gnus-summary-marks - :type 'character) - -(defcustom gnus-ancient-mark ?O - "*Mark used for ancient articles." - :group 'gnus-summary-marks - :type 'character) - -(defcustom gnus-sparse-mark ?Q - "*Mark used for sparsely reffed articles." - :group 'gnus-summary-marks - :type 'character) - -(defcustom gnus-canceled-mark ?G - "*Mark used for canceled articles." - :group 'gnus-summary-marks - :type 'character) - -(defcustom gnus-duplicate-mark ?M - "*Mark used for duplicate articles." - :group 'gnus-summary-marks - :type 'character) - -(defcustom gnus-undownloaded-mark ?@ - "*Mark used for articles that weren't downloaded." - :group 'gnus-summary-marks - :type 'character) - -(defcustom gnus-downloadable-mark ?% - "*Mark used for articles that are to be downloaded." - :group 'gnus-summary-marks - :type 'character) - -(defcustom gnus-unsendable-mark ?= - "*Mark used for articles that won't be sent." - :group 'gnus-summary-marks - :type 'character) - -(defcustom gnus-score-over-mark ?+ - "*Score mark used for articles with high scores." - :group 'gnus-summary-marks - :type 'character) - -(defcustom gnus-score-below-mark ?- - "*Score mark used for articles with low scores." - :group 'gnus-summary-marks - :type 'character) - -(defcustom gnus-empty-thread-mark ? - "*There is no thread under the article." - :group 'gnus-summary-marks - :type 'character) - -(defcustom gnus-not-empty-thread-mark ?= - "*There is a thread under the article." - :group 'gnus-summary-marks - :type 'character) - -(defcustom gnus-view-pseudo-asynchronously nil - "*If non-nil, Gnus will view pseudo-articles asynchronously." - :group 'gnus-extract-view - :type 'boolean) - -(defcustom gnus-view-pseudos nil - "*If `automatic', pseudo-articles will be viewed automatically. -If `not-confirm', pseudos will be viewed automatically, and the user -will not be asked to confirm the command." - :group 'gnus-extract-view - :type '(choice (const :tag "off" nil) - (const automatic) - (const not-confirm))) - -(defcustom gnus-view-pseudos-separately t - "*If non-nil, one pseudo-article will be created for each file to be viewed. -If nil, all files that use the same viewing command will be given as a -list of parameters to that command." - :group 'gnus-extract-view - :type 'boolean) - -(defcustom gnus-insert-pseudo-articles t - "*If non-nil, insert pseudo-articles when decoding articles." - :group 'gnus-extract-view - :type 'boolean) - -(defcustom gnus-summary-dummy-line-format - " %(: :%) %S\n" - "*The format specification for the dummy roots in the summary buffer. -It works along the same lines as a normal formatting string, -with some simple extensions. - -%S The subject" - :group 'gnus-threading - :type 'string) - -(defcustom gnus-summary-mode-line-format "Gnus: %%b [%A] %Z" - "*The format specification for the summary mode line. -It works along the same lines as a normal formatting string, -with some simple extensions: - -%G Group name -%p Unprefixed group name -%A Current article number -%z Current article score -%V Gnus version -%U Number of unread articles in the group -%e Number of unselected articles in the group -%Z A string with unread/unselected article counts -%g Shortish group name -%S Subject of the current article -%u User-defined spec -%s Current score file name -%d Number of dormant articles -%r Number of articles that have been marked as read in this session -%E Number of articles expunged by the score files" - :group 'gnus-summary-format - :type 'string) - -(defcustom gnus-summary-mark-below 0 - "*Mark all articles with a score below this variable as read. -This variable is local to each summary buffer and usually set by the -score file." - :group 'gnus-score-default - :type 'integer) - -(defcustom gnus-article-sort-functions '(gnus-article-sort-by-number) - "*List of functions used for sorting articles in the summary buffer. -This variable is only used when not using a threaded display." - :group 'gnus-summary-sort - :type '(repeat (choice (function-item gnus-article-sort-by-number) - (function-item gnus-article-sort-by-author) - (function-item gnus-article-sort-by-subject) - (function-item gnus-article-sort-by-date) - (function-item gnus-article-sort-by-score) - (function :tag "other")))) - -(defcustom gnus-thread-sort-functions '(gnus-thread-sort-by-number) - "*List of functions used for sorting threads in the summary buffer. -By default, threads are sorted by article number. - -Each function takes two threads and return non-nil if the first thread -should be sorted before the other. If you use more than one function, -the primary sort function should be the last. You should probably -always include `gnus-thread-sort-by-number' in the list of sorting -functions -- preferably first. - -Ready-made functions include `gnus-thread-sort-by-number', -`gnus-thread-sort-by-author', `gnus-thread-sort-by-subject', -`gnus-thread-sort-by-date', `gnus-thread-sort-by-score' and -`gnus-thread-sort-by-total-score' (see `gnus-thread-score-function')." - :group 'gnus-summary-sort - :type '(repeat (choice (function-item gnus-thread-sort-by-number) - (function-item gnus-thread-sort-by-author) - (function-item gnus-thread-sort-by-subject) - (function-item gnus-thread-sort-by-date) - (function-item gnus-thread-sort-by-score) - (function-item gnus-thread-sort-by-total-score) - (function :tag "other")))) - -(defcustom gnus-thread-score-function '+ - "*Function used for calculating the total score of a thread. - -The function is called with the scores of the article and each -subthread and should then return the score of the thread. - -Some functions you can use are `+', `max', or `min'." - :group 'gnus-summary-sort - :type 'function) - -(defcustom gnus-summary-expunge-below nil - "All articles that have a score less than this variable will be expunged. -This variable is local to the summary buffers." - :group 'gnus-score-default - :type '(choice (const :tag "off" nil) - integer)) - -(defcustom gnus-thread-expunge-below nil - "All threads that have a total score less than this variable will be expunged. -See `gnus-thread-score-function' for en explanation of what a -\"thread score\" is. - -This variable is local to the summary buffers." - :group 'gnus-treading - :group 'gnus-score-default - :type '(choice (const :tag "off" nil) - integer)) - -(defcustom gnus-summary-mode-hook nil - "*A hook for Gnus summary mode. -This hook is run before any variables are set in the summary buffer." - :group 'gnus-summary-various - :type 'hook) - -(defcustom gnus-summary-menu-hook nil - "*Hook run after the creation of the summary mode menu." - :group 'gnus-summary-visual - :type 'hook) - -(defcustom gnus-summary-exit-hook nil - "*A hook called on exit from the summary buffer. -It will be called with point in the group buffer." - :group 'gnus-summary-exit - :type 'hook) - -(defcustom gnus-summary-prepare-hook nil - "*A hook called after the summary buffer has been generated. -If you want to modify the summary buffer, you can use this hook." - :group 'gnus-summary-various - :type 'hook) - -(defcustom gnus-summary-prepared-hook nil - "*A hook called as the last thing after the summary buffer has been generated." - :group 'gnus-summary-various - :type 'hook) - -(defcustom gnus-summary-generate-hook nil - "*A hook run just before generating the summary buffer. -This hook is commonly used to customize threading variables and the -like." - :group 'gnus-summary-various - :type 'hook) - -(defcustom gnus-select-group-hook nil - "*A hook called when a newsgroup is selected. - -If you'd like to simplify subjects like the -`gnus-summary-next-same-subject' command does, you can use the -following hook: - - (setq gnus-select-group-hook - (list - (lambda () - (mapcar (lambda (header) - (mail-header-set-subject - header - (gnus-simplify-subject - (mail-header-subject header) 're-only))) - gnus-newsgroup-headers))))" - :group 'gnus-group-select - :type 'hook) - -(defcustom gnus-select-article-hook nil - "*A hook called when an article is selected." - :group 'gnus-summary-choose - :type 'hook) - -(defcustom gnus-visual-mark-article-hook - (list 'gnus-highlight-selected-summary) - "*Hook run after selecting an article in the summary buffer. -It is meant to be used for highlighting the article in some way. It -is not run if `gnus-visual' is nil." - :group 'gnus-summary-visual - :type 'hook) - -(defcustom gnus-parse-headers-hook - '(gnus-set-summary-default-charset) - "*A hook called before parsing the headers." - :group 'gnus-various - :type 'hook) - -(defcustom gnus-exit-group-hook nil - "*A hook called when exiting (not quitting) summary mode." - :group 'gnus-various - :type 'hook) - -(defcustom gnus-summary-update-hook - (list 'gnus-summary-highlight-line) - "*A hook called when a summary line is changed. -The hook will not be called if `gnus-visual' is nil. - -The default function `gnus-summary-highlight-line' will -highlight the line according to the `gnus-summary-highlight' -variable." - :group 'gnus-summary-visual - :type 'hook) - -(defcustom gnus-mark-article-hook '(gnus-summary-mark-read-and-unread-as-read) - "*A hook called when an article is selected for the first time. -The hook is intended to mark an article as read (or unread) -automatically when it is selected." - :group 'gnus-summary-choose - :type 'hook) - -(defcustom gnus-group-no-more-groups-hook nil - "*A hook run when returning to group mode having no more (unread) groups." - :group 'gnus-group-select - :type 'hook) - -(defcustom gnus-ps-print-hook nil - "*A hook run before ps-printing something from Gnus." - :group 'gnus-summary - :type 'hook) - -(defcustom gnus-summary-selected-face 'gnus-summary-selected-face - "Face used for highlighting the current article in the summary buffer." - :group 'gnus-summary-visual - :type 'face) - -(defcustom gnus-summary-highlight - '(((= mark gnus-canceled-mark) - . gnus-summary-cancelled-face) - ((and (> score default) - (or (= mark gnus-dormant-mark) - (= mark gnus-ticked-mark))) - . gnus-summary-high-ticked-face) - ((and (< score default) - (or (= mark gnus-dormant-mark) - (= mark gnus-ticked-mark))) - . gnus-summary-low-ticked-face) - ((or (= mark gnus-dormant-mark) - (= mark gnus-ticked-mark)) - . gnus-summary-normal-ticked-face) - ((and (> score default) (= mark gnus-ancient-mark)) - . gnus-summary-high-ancient-face) - ((and (< score default) (= mark gnus-ancient-mark)) - . gnus-summary-low-ancient-face) - ((= mark gnus-ancient-mark) - . gnus-summary-normal-ancient-face) - ((and (> score default) (= mark gnus-unread-mark)) - . gnus-summary-high-unread-face) - ((and (< score default) (= mark gnus-unread-mark)) - . gnus-summary-low-unread-face) - ((= mark gnus-unread-mark) - . gnus-summary-normal-unread-face) - ((and (> score default) (memq mark (list gnus-downloadable-mark - gnus-undownloaded-mark))) - . gnus-summary-high-unread-face) - ((and (< score default) (memq mark (list gnus-downloadable-mark - gnus-undownloaded-mark))) - . gnus-summary-low-unread-face) - ((memq mark (list gnus-downloadable-mark gnus-undownloaded-mark)) - . gnus-summary-normal-unread-face) - ((> score default) - . gnus-summary-high-read-face) - ((< score default) - . gnus-summary-low-read-face) - (t - . gnus-summary-normal-read-face)) - "*Controls the highlighting of summary buffer lines. - -A list of (FORM . FACE) pairs. When deciding how a a particular -summary line should be displayed, each form is evaluated. The content -of the face field after the first true form is used. You can change -how those summary lines are displayed, by editing the face field. - -You can use the following variables in the FORM field. - -score: The articles score -default: The default article score. -below: The score below which articles are automatically marked as read. -mark: The articles mark." - :group 'gnus-summary-visual - :type '(repeat (cons (sexp :tag "Form" nil) - face))) - -(defcustom gnus-alter-header-function nil - "Function called to allow alteration of article header structures. -The function is called with one parameter, the article header vector, -which it may alter in any way.") - -;;; Internal variables - -(defvar gnus-scores-exclude-files nil) -(defvar gnus-page-broken nil) - -(defvar gnus-original-article nil) -(defvar gnus-article-internal-prepare-hook nil) -(defvar gnus-newsgroup-process-stack nil) - -(defvar gnus-thread-indent-array nil) -(defvar gnus-thread-indent-array-level gnus-thread-indent-level) - -;; Avoid highlighting in kill files. -(defvar gnus-summary-inhibit-highlight nil) -(defvar gnus-newsgroup-selected-overlay nil) -(defvar gnus-inhibit-limiting nil) -(defvar gnus-newsgroup-adaptive-score-file nil) -(defvar gnus-current-score-file nil) -(defvar gnus-current-move-group nil) -(defvar gnus-current-copy-group nil) -(defvar gnus-current-crosspost-group nil) - -(defvar gnus-newsgroup-dependencies nil) -(defvar gnus-newsgroup-adaptive nil) -(defvar gnus-summary-display-article-function nil) -(defvar gnus-summary-highlight-line-function nil - "Function called after highlighting a summary line.") - -(defvar gnus-summary-line-format-alist - `((?N ,(macroexpand '(mail-header-number gnus-tmp-header)) ?d) - (?S ,(macroexpand '(mail-header-subject gnus-tmp-header)) ?s) - (?s gnus-tmp-subject-or-nil ?s) - (?n gnus-tmp-name ?s) - (?A (car (cdr (funcall gnus-extract-address-components gnus-tmp-from))) - ?s) - (?a (or (car (funcall gnus-extract-address-components gnus-tmp-from)) - gnus-tmp-from) ?s) - (?F gnus-tmp-from ?s) - (?x ,(macroexpand '(mail-header-xref gnus-tmp-header)) ?s) - (?D ,(macroexpand '(mail-header-date gnus-tmp-header)) ?s) - (?d (gnus-dd-mmm (mail-header-date gnus-tmp-header)) ?s) - (?o (gnus-date-iso8601 (mail-header-date gnus-tmp-header)) ?s) - (?M ,(macroexpand '(mail-header-id gnus-tmp-header)) ?s) - (?r ,(macroexpand '(mail-header-references gnus-tmp-header)) ?s) - (?c (or (mail-header-chars gnus-tmp-header) 0) ?d) - (?L gnus-tmp-lines ?d) - (?I gnus-tmp-indentation ?s) - (?T (if (= gnus-tmp-level 0) "" (make-string (frame-width) ? )) ?s) - (?R gnus-tmp-replied ?c) - (?\[ gnus-tmp-opening-bracket ?c) - (?\] gnus-tmp-closing-bracket ?c) - (?\> (make-string gnus-tmp-level ? ) ?s) - (?\< (make-string (max 0 (- 20 gnus-tmp-level)) ? ) ?s) - (?i gnus-tmp-score ?d) - (?z gnus-tmp-score-char ?c) - (?l (bbb-grouplens-score gnus-tmp-header) ?s) - (?V (gnus-thread-total-score (and (boundp 'thread) (car thread))) ?d) - (?U gnus-tmp-unread ?c) - (?t (gnus-summary-number-of-articles-in-thread - (and (boundp 'thread) (car thread)) gnus-tmp-level) - ?d) - (?e (gnus-summary-number-of-articles-in-thread - (and (boundp 'thread) (car thread)) gnus-tmp-level t) - ?c) - (?u gnus-tmp-user-defined ?s) - (?P (gnus-pick-line-number) ?d)) - "An alist of format specifications that can appear in summary lines, -and what variables they correspond with, along with the type of the -variable (string, integer, character, etc).") - -(defvar gnus-summary-dummy-line-format-alist - `((?S gnus-tmp-subject ?s) - (?N gnus-tmp-number ?d) - (?u gnus-tmp-user-defined ?s))) - -(defvar gnus-summary-mode-line-format-alist - `((?G gnus-tmp-group-name ?s) - (?g (gnus-short-group-name gnus-tmp-group-name) ?s) - (?p (gnus-group-real-name gnus-tmp-group-name) ?s) - (?A gnus-tmp-article-number ?d) - (?Z gnus-tmp-unread-and-unselected ?s) - (?V gnus-version ?s) - (?U gnus-tmp-unread-and-unticked ?d) - (?S gnus-tmp-subject ?s) - (?e gnus-tmp-unselected ?d) - (?u gnus-tmp-user-defined ?s) - (?d (length gnus-newsgroup-dormant) ?d) - (?t (length gnus-newsgroup-marked) ?d) - (?r (length gnus-newsgroup-reads) ?d) - (?z (gnus-summary-article-score gnus-tmp-article-number) ?d) - (?E gnus-newsgroup-expunged-tally ?d) - (?s (gnus-current-score-file-nondirectory) ?s))) - -(defvar gnus-last-search-regexp nil - "Default regexp for article search command.") - -(defvar gnus-last-shell-command nil - "Default shell command on article.") - -(defvar gnus-newsgroup-begin nil) -(defvar gnus-newsgroup-end nil) -(defvar gnus-newsgroup-last-rmail nil) -(defvar gnus-newsgroup-last-mail nil) -(defvar gnus-newsgroup-last-folder nil) -(defvar gnus-newsgroup-last-file nil) -(defvar gnus-newsgroup-auto-expire nil) -(defvar gnus-newsgroup-active nil) - -(defvar gnus-newsgroup-data nil) -(defvar gnus-newsgroup-data-reverse nil) -(defvar gnus-newsgroup-limit nil) -(defvar gnus-newsgroup-limits nil) - -(defvar gnus-newsgroup-unreads nil - "List of unread articles in the current newsgroup.") - -(defvar gnus-newsgroup-unselected nil - "List of unselected unread articles in the current newsgroup.") - -(defvar gnus-newsgroup-reads nil - "Alist of read articles and article marks in the current newsgroup.") - -(defvar gnus-newsgroup-expunged-tally nil) - -(defvar gnus-newsgroup-marked nil - "List of ticked articles in the current newsgroup (a subset of unread art).") - -(defvar gnus-newsgroup-killed nil - "List of ranges of articles that have been through the scoring process.") - -(defvar gnus-newsgroup-cached nil - "List of articles that come from the article cache.") - -(defvar gnus-newsgroup-saved nil - "List of articles that have been saved.") - -(defvar gnus-newsgroup-kill-headers nil) - -(defvar gnus-newsgroup-replied nil - "List of articles that have been replied to in the current newsgroup.") - -(defvar gnus-newsgroup-expirable nil - "List of articles in the current newsgroup that can be expired.") - -(defvar gnus-newsgroup-processable nil - "List of articles in the current newsgroup that can be processed.") - -(defvar gnus-newsgroup-downloadable nil - "List of articles in the current newsgroup that can be processed.") - -(defvar gnus-newsgroup-undownloaded nil - "List of articles in the current newsgroup that haven't been downloaded..") - -(defvar gnus-newsgroup-unsendable nil - "List of articles in the current newsgroup that won't be sent.") - -(defvar gnus-newsgroup-bookmarks nil - "List of articles in the current newsgroup that have bookmarks.") - -(defvar gnus-newsgroup-dormant nil - "List of dormant articles in the current newsgroup.") - -(defvar gnus-newsgroup-scored nil - "List of scored articles in the current newsgroup.") - -(defvar gnus-newsgroup-headers nil - "List of article headers in the current newsgroup.") - -(defvar gnus-newsgroup-threads nil) - -(defvar gnus-newsgroup-prepared nil - "Whether the current group has been prepared properly.") - -(defvar gnus-newsgroup-ancient nil - "List of `gnus-fetch-old-headers' articles in the current newsgroup.") - -(defvar gnus-newsgroup-sparse nil) - -(defvar gnus-current-article nil) -(defvar gnus-article-current nil) -(defvar gnus-current-headers nil) -(defvar gnus-have-all-headers nil) -(defvar gnus-last-article nil) -(defvar gnus-newsgroup-history nil) - -(defconst gnus-summary-local-variables - '(gnus-newsgroup-name - gnus-newsgroup-begin gnus-newsgroup-end - gnus-newsgroup-last-rmail gnus-newsgroup-last-mail - gnus-newsgroup-last-folder gnus-newsgroup-last-file - gnus-newsgroup-auto-expire gnus-newsgroup-unreads - gnus-newsgroup-unselected gnus-newsgroup-marked - gnus-newsgroup-reads gnus-newsgroup-saved - gnus-newsgroup-replied gnus-newsgroup-expirable - gnus-newsgroup-processable gnus-newsgroup-killed - gnus-newsgroup-downloadable gnus-newsgroup-undownloaded - gnus-newsgroup-unsendable - gnus-newsgroup-bookmarks gnus-newsgroup-dormant - gnus-newsgroup-headers gnus-newsgroup-threads - gnus-newsgroup-prepared gnus-summary-highlight-line-function - gnus-current-article gnus-current-headers gnus-have-all-headers - gnus-last-article gnus-article-internal-prepare-hook - gnus-newsgroup-dependencies gnus-newsgroup-selected-overlay - gnus-newsgroup-scored gnus-newsgroup-kill-headers - gnus-thread-expunge-below - gnus-score-alist gnus-current-score-file gnus-summary-expunge-below - (gnus-summary-mark-below . global) - gnus-newsgroup-active gnus-scores-exclude-files - gnus-newsgroup-history gnus-newsgroup-ancient - gnus-newsgroup-sparse gnus-newsgroup-process-stack - (gnus-newsgroup-adaptive . gnus-use-adaptive-scoring) - gnus-newsgroup-adaptive-score-file (gnus-reffed-article-number . -1) - (gnus-newsgroup-expunged-tally . 0) - gnus-cache-removable-articles gnus-newsgroup-cached - gnus-newsgroup-data gnus-newsgroup-data-reverse - gnus-newsgroup-limit gnus-newsgroup-limits) - "Variables that are buffer-local to the summary buffers.") - -;; Byte-compiler warning. -(defvar gnus-article-mode-map) - -;; Subject simplification. - -(defun gnus-simplify-whitespace (str) - "Remove excessive whitespace." - (let ((mystr str)) - ;; Multiple spaces. - (while (string-match "[ \t][ \t]+" mystr) - (setq mystr (concat (substring mystr 0 (match-beginning 0)) - " " - (substring mystr (match-end 0))))) - ;; Leading spaces. - (when (string-match "^[ \t]+" mystr) - (setq mystr (substring mystr (match-end 0)))) - ;; Trailing spaces. - (when (string-match "[ \t]+$" mystr) - (setq mystr (substring mystr 0 (match-beginning 0)))) - mystr)) - -(defsubst gnus-simplify-subject-re (subject) - "Remove \"Re:\" from subject lines." - (if (string-match "^[Rr][Ee]: *" subject) - (substring subject (match-end 0)) - subject)) - -(defun gnus-simplify-subject (subject &optional re-only) - "Remove `Re:' and words in parentheses. -If RE-ONLY is non-nil, strip leading `Re:'s only." - (let ((case-fold-search t)) ;Ignore case. - ;; Remove `Re:', `Re^N:', `Re(n)', and `Re[n]:'. - (when (string-match "\\`\\(re\\([[(^][0-9]+[])]?\\)?:[ \t]*\\)+" subject) - (setq subject (substring subject (match-end 0)))) - ;; Remove uninteresting prefixes. - (when (and (not re-only) - gnus-simplify-ignored-prefixes - (string-match gnus-simplify-ignored-prefixes subject)) - (setq subject (substring subject (match-end 0)))) - ;; Remove words in parentheses from end. - (unless re-only - (while (string-match "[ \t\n]*([^()]*)[ \t\n]*\\'" subject) - (setq subject (substring subject 0 (match-beginning 0))))) - ;; Return subject string. - subject)) - -;; Remove any leading "re:"s, any trailing paren phrases, and simplify -;; all whitespace. -(defsubst gnus-simplify-buffer-fuzzy-step (regexp &optional newtext) - (goto-char (point-min)) - (while (re-search-forward regexp nil t) - (replace-match (or newtext "")))) - -(defun gnus-simplify-buffer-fuzzy () - "Simplify string in the buffer fuzzily. -The string in the accessible portion of the current buffer is simplified. -It is assumed to be a single-line subject. -Whitespace is generally cleaned up, and miscellaneous leading/trailing -matter is removed. Additional things can be deleted by setting -gnus-simplify-subject-fuzzy-regexp." - (let ((case-fold-search t) - (modified-tick)) - (gnus-simplify-buffer-fuzzy-step "\t" " ") - - (while (not (eq modified-tick (buffer-modified-tick))) - (setq modified-tick (buffer-modified-tick)) - (cond - ((listp gnus-simplify-subject-fuzzy-regexp) - (mapcar 'gnus-simplify-buffer-fuzzy-step - gnus-simplify-subject-fuzzy-regexp)) - (gnus-simplify-subject-fuzzy-regexp - (gnus-simplify-buffer-fuzzy-step gnus-simplify-subject-fuzzy-regexp))) - (gnus-simplify-buffer-fuzzy-step "^ *\\[[-+?*!][-+?*!]\\] *") - (gnus-simplify-buffer-fuzzy-step - "^ *\\(re\\|fw\\|fwd\\)[[{(^0-9]*[])}]?[:;] *") - (gnus-simplify-buffer-fuzzy-step "^[[].*:\\( .*\\)[]]$" "\\1")) - - (gnus-simplify-buffer-fuzzy-step " *[[{(][^()\n]*[]})] *$") - (gnus-simplify-buffer-fuzzy-step " +" " ") - (gnus-simplify-buffer-fuzzy-step " $") - (gnus-simplify-buffer-fuzzy-step "^ +"))) - -(defun gnus-simplify-subject-fuzzy (subject) - "Simplify a subject string fuzzily. -See `gnus-simplify-buffer-fuzzy' for details." - (save-excursion - (gnus-set-work-buffer) - (let ((case-fold-search t)) - ;; Remove uninteresting prefixes. - (when (and gnus-simplify-ignored-prefixes - (string-match gnus-simplify-ignored-prefixes subject)) - (setq subject (substring subject (match-end 0)))) - (insert subject) - (inline (gnus-simplify-buffer-fuzzy)) - (buffer-string)))) - -(defsubst gnus-simplify-subject-fully (subject) - "Simplify a subject string according to gnus-summary-gather-subject-limit." - (cond - (gnus-simplify-subject-functions - (gnus-map-function gnus-simplify-subject-functions subject)) - ((null gnus-summary-gather-subject-limit) - (gnus-simplify-subject-re subject)) - ((eq gnus-summary-gather-subject-limit 'fuzzy) - (gnus-simplify-subject-fuzzy subject)) - ((numberp gnus-summary-gather-subject-limit) - (gnus-limit-string (gnus-simplify-subject-re subject) - gnus-summary-gather-subject-limit)) - (t - subject))) - -(defsubst gnus-subject-equal (s1 s2 &optional simple-first) - "Check whether two subjects are equal. -If optional argument simple-first is t, first argument is already -simplified." - (cond - ((null simple-first) - (equal (gnus-simplify-subject-fully s1) - (gnus-simplify-subject-fully s2))) - (t - (equal s1 - (gnus-simplify-subject-fully s2))))) - -(defun gnus-summary-bubble-group () - "Increase the score of the current group. -This is a handy function to add to `gnus-summary-exit-hook' to -increase the score of each group you read." - (gnus-group-add-score gnus-newsgroup-name)) - - -;;; -;;; Gnus summary mode -;;; - -(put 'gnus-summary-mode 'mode-class 'special) - -(when t - ;; Non-orthogonal keys - - (gnus-define-keys gnus-summary-mode-map - " " gnus-summary-next-page - "\177" gnus-summary-prev-page - [delete] gnus-summary-prev-page - [backspace] gnus-summary-prev-page - "\r" gnus-summary-scroll-up - "\M-\r" gnus-summary-scroll-down - "n" gnus-summary-next-unread-article - "p" gnus-summary-prev-unread-article - "N" gnus-summary-next-article - "P" gnus-summary-prev-article - "\M-\C-n" gnus-summary-next-same-subject - "\M-\C-p" gnus-summary-prev-same-subject - "\M-n" gnus-summary-next-unread-subject - "\M-p" gnus-summary-prev-unread-subject - "." gnus-summary-first-unread-article - "," gnus-summary-best-unread-article - "\M-s" gnus-summary-search-article-forward - "\M-r" gnus-summary-search-article-backward - "<" gnus-summary-beginning-of-article - ">" gnus-summary-end-of-article - "j" gnus-summary-goto-article - "^" gnus-summary-refer-parent-article - "\M-^" gnus-summary-refer-article - "u" gnus-summary-tick-article-forward - "!" gnus-summary-tick-article-forward - "U" gnus-summary-tick-article-backward - "d" gnus-summary-mark-as-read-forward - "D" gnus-summary-mark-as-read-backward - "E" gnus-summary-mark-as-expirable - "\M-u" gnus-summary-clear-mark-forward - "\M-U" gnus-summary-clear-mark-backward - "k" gnus-summary-kill-same-subject-and-select - "\C-k" gnus-summary-kill-same-subject - "\M-\C-k" gnus-summary-kill-thread - "\M-\C-l" gnus-summary-lower-thread - "e" gnus-summary-edit-article - "#" gnus-summary-mark-as-processable - "\M-#" gnus-summary-unmark-as-processable - "\M-\C-t" gnus-summary-toggle-threads - "\M-\C-s" gnus-summary-show-thread - "\M-\C-h" gnus-summary-hide-thread - "\M-\C-f" gnus-summary-next-thread - "\M-\C-b" gnus-summary-prev-thread - "\M-\C-u" gnus-summary-up-thread - "\M-\C-d" gnus-summary-down-thread - "&" gnus-summary-execute-command - "c" gnus-summary-catchup-and-exit - "\C-w" gnus-summary-mark-region-as-read - "\C-t" gnus-summary-toggle-truncation - "?" gnus-summary-mark-as-dormant - "\C-c\M-\C-s" gnus-summary-limit-include-expunged - "\C-c\C-s\C-n" gnus-summary-sort-by-number - "\C-c\C-s\C-l" gnus-summary-sort-by-lines - "\C-c\C-s\C-a" gnus-summary-sort-by-author - "\C-c\C-s\C-s" gnus-summary-sort-by-subject - "\C-c\C-s\C-d" gnus-summary-sort-by-date - "\C-c\C-s\C-i" gnus-summary-sort-by-score - "=" gnus-summary-expand-window - "\C-x\C-s" gnus-summary-reselect-current-group - "\M-g" gnus-summary-rescan-group - "w" gnus-summary-stop-page-breaking - "\C-c\C-r" gnus-summary-caesar-message - "\M-t" gnus-summary-toggle-mime - "f" gnus-summary-followup - "F" gnus-summary-followup-with-original - "C" gnus-summary-cancel-article - "r" gnus-summary-reply - "R" gnus-summary-reply-with-original - "\C-c\C-f" gnus-summary-mail-forward - "o" gnus-summary-save-article - "\C-o" gnus-summary-save-article-mail - "|" gnus-summary-pipe-output - "\M-k" gnus-summary-edit-local-kill - "\M-K" gnus-summary-edit-global-kill - ;; "V" gnus-version - "\C-c\C-d" gnus-summary-describe-group - "q" gnus-summary-exit - "Q" gnus-summary-exit-no-update - "\C-c\C-i" gnus-info-find-node - gnus-mouse-2 gnus-mouse-pick-article - "m" gnus-summary-mail-other-window - "a" gnus-summary-post-news - "x" gnus-summary-limit-to-unread - "s" gnus-summary-isearch-article - "t" gnus-article-hide-headers - "g" gnus-summary-show-article - "l" gnus-summary-goto-last-article - "v" gnus-summary-preview-mime-message - "\C-c\C-v\C-v" gnus-uu-decode-uu-view - "\C-d" gnus-summary-enter-digest-group - "\M-\C-d" gnus-summary-read-document - "\M-\C-e" gnus-summary-edit-parameters - "\C-c\C-b" gnus-bug - "*" gnus-cache-enter-article - "\M-*" gnus-cache-remove-article - "\M-&" gnus-summary-universal-argument - "\C-l" gnus-recenter - "I" gnus-summary-increase-score - "L" gnus-summary-lower-score - "\M-i" gnus-symbolic-argument - "h" gnus-summary-select-article-buffer - - "V" gnus-summary-score-map - "X" gnus-uu-extract-map - "S" gnus-summary-send-map) - - ;; Sort of orthogonal keymap - (gnus-define-keys (gnus-summary-mark-map "M" gnus-summary-mode-map) - "t" gnus-summary-tick-article-forward - "!" gnus-summary-tick-article-forward - "d" gnus-summary-mark-as-read-forward - "r" gnus-summary-mark-as-read-forward - "c" gnus-summary-clear-mark-forward - " " gnus-summary-clear-mark-forward - "e" gnus-summary-mark-as-expirable - "x" gnus-summary-mark-as-expirable - "?" gnus-summary-mark-as-dormant - "b" gnus-summary-set-bookmark - "B" gnus-summary-remove-bookmark - "#" gnus-summary-mark-as-processable - "\M-#" gnus-summary-unmark-as-processable - "S" gnus-summary-limit-include-expunged - "C" gnus-summary-catchup - "H" gnus-summary-catchup-to-here - "\C-c" gnus-summary-catchup-all - "k" gnus-summary-kill-same-subject-and-select - "K" gnus-summary-kill-same-subject - "P" gnus-uu-mark-map) - - (gnus-define-keys (gnus-summary-mscore-map "V" gnus-summary-mark-map) - "c" gnus-summary-clear-above - "u" gnus-summary-tick-above - "m" gnus-summary-mark-above - "k" gnus-summary-kill-below) - - (gnus-define-keys (gnus-summary-limit-map "/" gnus-summary-mode-map) - "/" gnus-summary-limit-to-subject - "n" gnus-summary-limit-to-articles - "w" gnus-summary-pop-limit - "s" gnus-summary-limit-to-subject - "a" gnus-summary-limit-to-author - "u" gnus-summary-limit-to-unread - "m" gnus-summary-limit-to-marks - "v" gnus-summary-limit-to-score - "*" gnus-summary-limit-include-cached - "D" gnus-summary-limit-include-dormant - "T" gnus-summary-limit-include-thread - "d" gnus-summary-limit-exclude-dormant - "t" gnus-summary-limit-to-age - "E" gnus-summary-limit-include-expunged - "c" gnus-summary-limit-exclude-childless-dormant - "C" gnus-summary-limit-mark-excluded-as-read) - - (gnus-define-keys (gnus-summary-goto-map "G" gnus-summary-mode-map) - "n" gnus-summary-next-unread-article - "p" gnus-summary-prev-unread-article - "N" gnus-summary-next-article - "P" gnus-summary-prev-article - "\C-n" gnus-summary-next-same-subject - "\C-p" gnus-summary-prev-same-subject - "\M-n" gnus-summary-next-unread-subject - "\M-p" gnus-summary-prev-unread-subject - "f" gnus-summary-first-unread-article - "b" gnus-summary-best-unread-article - "j" gnus-summary-goto-article - "g" gnus-summary-goto-subject - "l" gnus-summary-goto-last-article - "o" gnus-summary-pop-article) - - (gnus-define-keys (gnus-summary-thread-map "T" gnus-summary-mode-map) - "k" gnus-summary-kill-thread - "l" gnus-summary-lower-thread - "i" gnus-summary-raise-thread - "T" gnus-summary-toggle-threads - "t" gnus-summary-rethread-current - "^" gnus-summary-reparent-thread - "s" gnus-summary-show-thread - "S" gnus-summary-show-all-threads - "h" gnus-summary-hide-thread - "H" gnus-summary-hide-all-threads - "n" gnus-summary-next-thread - "p" gnus-summary-prev-thread - "u" gnus-summary-up-thread - "o" gnus-summary-top-thread - "d" gnus-summary-down-thread - "#" gnus-uu-mark-thread - "\M-#" gnus-uu-unmark-thread) - - (gnus-define-keys (gnus-summary-buffer-map "Y" gnus-summary-mode-map) - "g" gnus-summary-prepare - "c" gnus-summary-insert-cached-articles) - - (gnus-define-keys (gnus-summary-exit-map "Z" gnus-summary-mode-map) - "c" gnus-summary-catchup-and-exit - "C" gnus-summary-catchup-all-and-exit - "E" gnus-summary-exit-no-update - "Q" gnus-summary-exit - "Z" gnus-summary-exit - "n" gnus-summary-catchup-and-goto-next-group - "R" gnus-summary-reselect-current-group - "G" gnus-summary-rescan-group - "N" gnus-summary-next-group - "s" gnus-summary-save-newsrc - "P" gnus-summary-prev-group) - - (gnus-define-keys (gnus-summary-article-map "A" gnus-summary-mode-map) - " " gnus-summary-next-page - "n" gnus-summary-next-page - "\177" gnus-summary-prev-page - [delete] gnus-summary-prev-page - "p" gnus-summary-prev-page - "\r" gnus-summary-scroll-up - "\M-\r" gnus-summary-scroll-down - "<" gnus-summary-beginning-of-article - ">" gnus-summary-end-of-article - "b" gnus-summary-beginning-of-article - "e" gnus-summary-end-of-article - "^" gnus-summary-refer-parent-article - "r" gnus-summary-refer-parent-article - "R" gnus-summary-refer-references - "T" gnus-summary-refer-thread - "g" gnus-summary-show-article - "s" gnus-summary-isearch-article - "P" gnus-summary-print-article) - - (gnus-define-keys (gnus-summary-wash-map "W" gnus-summary-mode-map) - "b" gnus-article-add-buttons - "B" gnus-article-add-buttons-to-head - "o" gnus-article-treat-overstrike - "e" gnus-article-emphasize - "w" gnus-article-fill-cited-article - "c" gnus-article-remove-cr - "f" gnus-article-display-x-face - "l" gnus-summary-stop-page-breaking - "r" gnus-summary-caesar-message - "t" gnus-article-hide-headers - "v" gnus-summary-verbose-headers - "m" gnus-summary-toggle-mime - "h" gnus-article-treat-html - "d" gnus-article-treat-dumbquotes) - - (gnus-define-keys (gnus-summary-wash-hide-map "W" gnus-summary-wash-map) - "a" gnus-article-hide - "h" gnus-article-hide-headers - "b" gnus-article-hide-boring-headers - "s" gnus-article-hide-signature - "c" gnus-article-hide-citation - "C" gnus-article-hide-citation-in-followups - "p" gnus-article-hide-pgp - "P" gnus-article-hide-pem - "\C-c" gnus-article-hide-citation-maybe) - - (gnus-define-keys (gnus-summary-wash-highlight-map "H" gnus-summary-wash-map) - "a" gnus-article-highlight - "h" gnus-article-highlight-headers - "c" gnus-article-highlight-citation - "s" gnus-article-highlight-signature) - - (gnus-define-keys (gnus-summary-wash-time-map "T" gnus-summary-wash-map) - "z" gnus-article-date-ut - "u" gnus-article-date-ut - "l" gnus-article-date-local - "e" gnus-article-date-lapsed - "o" gnus-article-date-original - "i" gnus-article-date-iso8601 - "s" gnus-article-date-user) - - (gnus-define-keys (gnus-summary-wash-empty-map "E" gnus-summary-wash-map) - "t" gnus-article-remove-trailing-blank-lines - "l" gnus-article-strip-leading-blank-lines - "m" gnus-article-strip-multiple-blank-lines - "a" gnus-article-strip-blank-lines - "A" gnus-article-strip-all-blank-lines - "s" gnus-article-strip-leading-space) - - (gnus-define-keys (gnus-summary-help-map "H" gnus-summary-mode-map) - "v" gnus-version - "f" gnus-summary-fetch-faq - "d" gnus-summary-describe-group - "h" gnus-summary-describe-briefly - "i" gnus-info-find-node) - - (gnus-define-keys (gnus-summary-backend-map "B" gnus-summary-mode-map) - "e" gnus-summary-expire-articles - "\M-\C-e" gnus-summary-expire-articles-now - "\177" gnus-summary-delete-article - [delete] gnus-summary-delete-article - "m" gnus-summary-move-article - "r" gnus-summary-respool-article - "w" gnus-summary-edit-article - "c" gnus-summary-copy-article - "B" gnus-summary-crosspost-article - "q" gnus-summary-respool-query - "t" gnus-summary-respool-trace - "i" gnus-summary-import-article - "p" gnus-summary-article-posted-p) - - (gnus-define-keys (gnus-summary-save-map "O" gnus-summary-mode-map) - "o" gnus-summary-save-article - "m" gnus-summary-save-article-mail - "F" gnus-summary-write-article-file - "r" gnus-summary-save-article-rmail - "f" gnus-summary-save-article-file - "b" gnus-summary-save-article-body-file - "h" gnus-summary-save-article-folder - "v" gnus-summary-save-article-vm - "p" gnus-summary-pipe-output - "s" gnus-soup-add-article)) - -(defun gnus-summary-make-menu-bar () - (gnus-turn-off-edit-menu 'summary) - - (unless (boundp 'gnus-summary-misc-menu) - - (easy-menu-define - gnus-summary-kill-menu gnus-summary-mode-map "" - (cons - "Score" - (nconc - (list - ["Enter score..." gnus-summary-score-entry t] - ["Customize" gnus-score-customize t]) - (gnus-make-score-map 'increase) - (gnus-make-score-map 'lower) - '(("Mark" - ["Kill below" gnus-summary-kill-below t] - ["Mark above" gnus-summary-mark-above t] - ["Tick above" gnus-summary-tick-above t] - ["Clear above" gnus-summary-clear-above t]) - ["Current score" gnus-summary-current-score t] - ["Set score" gnus-summary-set-score t] - ["Switch current score file..." gnus-score-change-score-file t] - ["Set mark below..." gnus-score-set-mark-below t] - ["Set expunge below..." gnus-score-set-expunge-below t] - ["Edit current score file" gnus-score-edit-current-scores t] - ["Edit score file" gnus-score-edit-file t] - ["Trace score" gnus-score-find-trace t] - ["Find words" gnus-score-find-favourite-words t] - ["Rescore buffer" gnus-summary-rescore t] - ["Increase score..." gnus-summary-increase-score t] - ["Lower score..." gnus-summary-lower-score t])))) - - ;; Define both the Article menu in the summary buffer and the equivalent - ;; Commands menu in the article buffer here for consistency. - (let ((innards - '(("Hide" - ["All" gnus-article-hide t] - ["Headers" gnus-article-hide-headers t] - ["Signature" gnus-article-hide-signature t] - ["Citation" gnus-article-hide-citation t] - ["PGP" gnus-article-hide-pgp t] - ["Boring headers" gnus-article-hide-boring-headers t]) - ("Highlight" - ["All" gnus-article-highlight t] - ["Headers" gnus-article-highlight-headers t] - ["Signature" gnus-article-highlight-signature t] - ["Citation" gnus-article-highlight-citation t]) - ("Date" - ["Local" gnus-article-date-local t] - ["ISO8601" gnus-article-date-iso8601 t] - ["UT" gnus-article-date-ut t] - ["Original" gnus-article-date-original t] - ["Lapsed" gnus-article-date-lapsed t] - ["User-defined" gnus-article-date-user t]) - ("Washing" - ("Remove Blanks" - ["Leading" gnus-article-strip-leading-blank-lines t] - ["Multiple" gnus-article-strip-multiple-blank-lines t] - ["Trailing" gnus-article-remove-trailing-blank-lines t] - ["All of the above" gnus-article-strip-blank-lines t] - ["All" gnus-article-strip-all-blank-lines t] - ["Leading space" gnus-article-strip-leading-space t]) - ["Overstrike" gnus-article-treat-overstrike t] - ["Dumb quotes" gnus-article-treat-dumbquotes t] - ["Emphasis" gnus-article-emphasize t] - ["Word wrap" gnus-article-fill-cited-article t] - ["CR" gnus-article-remove-cr t] - ["Show X-Face" gnus-article-display-x-face t] - ["UnHTMLize" gnus-article-treat-html t] - ["Rot 13" gnus-summary-caesar-message t] - ["Unix pipe" gnus-summary-pipe-message t] - ["Add buttons" gnus-article-add-buttons t] - ["Add buttons to head" gnus-article-add-buttons-to-head t] - ["Stop page breaking" gnus-summary-stop-page-breaking t] - ["Toggle MIME" gnus-summary-toggle-mime t] - ["Verbose header" gnus-summary-verbose-headers t] - ["Toggle header" gnus-summary-toggle-header t]) - ("Output" - ["Save in default format" gnus-summary-save-article t] - ["Save in file" gnus-summary-save-article-file t] - ["Save in Unix mail format" gnus-summary-save-article-mail t] - ["Save in MH folder" gnus-summary-save-article-folder t] - ["Save in VM folder" gnus-summary-save-article-vm t] - ["Save in RMAIL mbox" gnus-summary-save-article-rmail t] - ["Save body in file" gnus-summary-save-article-body-file t] - ["Pipe through a filter" gnus-summary-pipe-output t] - ["Add to SOUP packet" gnus-soup-add-article t] - ["Print" gnus-summary-print-article t]) - ("Backend" - ["Respool article..." gnus-summary-respool-article t] - ["Move article..." gnus-summary-move-article - (gnus-check-backend-function - 'request-move-article gnus-newsgroup-name)] - ["Copy article..." gnus-summary-copy-article t] - ["Crosspost article..." gnus-summary-crosspost-article - (gnus-check-backend-function - 'request-replace-article gnus-newsgroup-name)] - ["Import file..." gnus-summary-import-article t] - ["Check if posted" gnus-summary-article-posted-p t] - ["Edit article" gnus-summary-edit-article - (not (gnus-group-read-only-p))] - ["Delete article" gnus-summary-delete-article - (gnus-check-backend-function - 'request-expire-articles gnus-newsgroup-name)] - ["Query respool" gnus-summary-respool-query t] - ["Trace respool" gnus-summary-respool-trace t] - ["Delete expirable articles" gnus-summary-expire-articles-now - (gnus-check-backend-function - 'request-expire-articles gnus-newsgroup-name)]) - ("Extract" - ["Uudecode" gnus-uu-decode-uu t] - ["Uudecode and save" gnus-uu-decode-uu-and-save t] - ["Unshar" gnus-uu-decode-unshar t] - ["Unshar and save" gnus-uu-decode-unshar-and-save t] - ["Save" gnus-uu-decode-save t] - ["Binhex" gnus-uu-decode-binhex t] - ["Postscript" gnus-uu-decode-postscript t]) - ("Cache" - ["Enter article" gnus-cache-enter-article t] - ["Remove article" gnus-cache-remove-article t]) - ["Select article buffer" gnus-summary-select-article-buffer t] - ["Enter digest buffer" gnus-summary-enter-digest-group t] - ["Isearch article..." gnus-summary-isearch-article t] - ["Beginning of the article" gnus-summary-beginning-of-article t] - ["End of the article" gnus-summary-end-of-article t] - ["Fetch parent of article" gnus-summary-refer-parent-article t] - ["Fetch referenced articles" gnus-summary-refer-references t] - ["Fetch current thread" gnus-summary-refer-thread t] - ["Fetch article with id..." gnus-summary-refer-article t] - ["Redisplay" gnus-summary-show-article t]))) - (easy-menu-define - gnus-summary-article-menu gnus-summary-mode-map "" - (cons "Article" innards)) - - (easy-menu-define - gnus-article-commands-menu gnus-article-mode-map "" - (cons "Commands" innards))) - - (easy-menu-define - gnus-summary-thread-menu gnus-summary-mode-map "" - '("Threads" - ["Toggle threading" gnus-summary-toggle-threads t] - ["Hide threads" gnus-summary-hide-all-threads t] - ["Show threads" gnus-summary-show-all-threads t] - ["Hide thread" gnus-summary-hide-thread t] - ["Show thread" gnus-summary-show-thread t] - ["Go to next thread" gnus-summary-next-thread t] - ["Go to previous thread" gnus-summary-prev-thread t] - ["Go down thread" gnus-summary-down-thread t] - ["Go up thread" gnus-summary-up-thread t] - ["Top of thread" gnus-summary-top-thread t] - ["Mark thread as read" gnus-summary-kill-thread t] - ["Lower thread score" gnus-summary-lower-thread t] - ["Raise thread score" gnus-summary-raise-thread t] - ["Rethread current" gnus-summary-rethread-current t] - )) - - (easy-menu-define - gnus-summary-post-menu gnus-summary-mode-map "" - '("Post" - ["Post an article" gnus-summary-post-news t] - ["Followup" gnus-summary-followup t] - ["Followup and yank" gnus-summary-followup-with-original t] - ["Supersede article" gnus-summary-supersede-article t] - ["Cancel article" gnus-summary-cancel-article t] - ["Reply" gnus-summary-reply t] - ["Reply and yank" gnus-summary-reply-with-original t] - ["Wide reply" gnus-summary-wide-reply t] - ["Wide reply and yank" gnus-summary-wide-reply-with-original t] - ["Mail forward" gnus-summary-mail-forward t] - ["Post forward" gnus-summary-post-forward t] - ["Digest and mail" gnus-summary-mail-digest t] - ["Digest and post" gnus-summary-post-digest t] - ["Resend message" gnus-summary-resend-message t] - ["Send bounced mail" gnus-summary-resend-bounced-mail t] - ["Send a mail" gnus-summary-mail-other-window t] - ["Uuencode and post" gnus-uu-post-news t] - ["Followup via news" gnus-summary-followup-to-mail t] - ["Followup via news and yank" - gnus-summary-followup-to-mail-with-original t] - ;;("Draft" - ;;["Send" gnus-summary-send-draft t] - ;;["Send bounced" gnus-resend-bounced-mail t]) - )) - - (easy-menu-define - gnus-summary-misc-menu gnus-summary-mode-map "" - '("Misc" - ("Mark Read" - ["Mark as read" gnus-summary-mark-as-read-forward t] - ["Mark same subject and select" - gnus-summary-kill-same-subject-and-select t] - ["Mark same subject" gnus-summary-kill-same-subject t] - ["Catchup" gnus-summary-catchup t] - ["Catchup all" gnus-summary-catchup-all t] - ["Catchup to here" gnus-summary-catchup-to-here t] - ["Catchup region" gnus-summary-mark-region-as-read t] - ["Mark excluded" gnus-summary-limit-mark-excluded-as-read t]) - ("Mark Various" - ["Tick" gnus-summary-tick-article-forward t] - ["Mark as dormant" gnus-summary-mark-as-dormant t] - ["Remove marks" gnus-summary-clear-mark-forward t] - ["Set expirable mark" gnus-summary-mark-as-expirable t] - ["Set bookmark" gnus-summary-set-bookmark t] - ["Remove bookmark" gnus-summary-remove-bookmark t]) - ("Mark Limit" - ["Marks..." gnus-summary-limit-to-marks t] - ["Subject..." gnus-summary-limit-to-subject t] - ["Author..." gnus-summary-limit-to-author t] - ["Age..." gnus-summary-limit-to-age t] - ["Score" gnus-summary-limit-to-score t] - ["Unread" gnus-summary-limit-to-unread t] - ["Non-dormant" gnus-summary-limit-exclude-dormant t] - ["Articles" gnus-summary-limit-to-articles t] - ["Pop limit" gnus-summary-pop-limit t] - ["Show dormant" gnus-summary-limit-include-dormant t] - ["Hide childless dormant" - gnus-summary-limit-exclude-childless-dormant t] - ;;["Hide thread" gnus-summary-limit-exclude-thread t] - ["Show expunged" gnus-summary-show-all-expunged t]) - ("Process Mark" - ["Set mark" gnus-summary-mark-as-processable t] - ["Remove mark" gnus-summary-unmark-as-processable t] - ["Remove all marks" gnus-summary-unmark-all-processable t] - ["Mark above" gnus-uu-mark-over t] - ["Mark series" gnus-uu-mark-series t] - ["Mark region" gnus-uu-mark-region t] - ["Unmark region" gnus-uu-unmark-region t] - ["Mark by regexp..." gnus-uu-mark-by-regexp t] - ["Unmark by regexp..." gnus-uu-unmark-by-regexp t] - ["Mark all" gnus-uu-mark-all t] - ["Mark buffer" gnus-uu-mark-buffer t] - ["Mark sparse" gnus-uu-mark-sparse t] - ["Mark thread" gnus-uu-mark-thread t] - ["Unmark thread" gnus-uu-unmark-thread t] - ("Process Mark Sets" - ["Kill" gnus-summary-kill-process-mark t] - ["Yank" gnus-summary-yank-process-mark - gnus-newsgroup-process-stack] - ["Save" gnus-summary-save-process-mark t])) - ("Scroll article" - ["Page forward" gnus-summary-next-page t] - ["Page backward" gnus-summary-prev-page t] - ["Line forward" gnus-summary-scroll-up t]) - ("Move" - ["Next unread article" gnus-summary-next-unread-article t] - ["Previous unread article" gnus-summary-prev-unread-article t] - ["Next article" gnus-summary-next-article t] - ["Previous article" gnus-summary-prev-article t] - ["Next unread subject" gnus-summary-next-unread-subject t] - ["Previous unread subject" gnus-summary-prev-unread-subject t] - ["Next article same subject" gnus-summary-next-same-subject t] - ["Previous article same subject" gnus-summary-prev-same-subject t] - ["First unread article" gnus-summary-first-unread-article t] - ["Best unread article" gnus-summary-best-unread-article t] - ["Go to subject number..." gnus-summary-goto-subject t] - ["Go to article number..." gnus-summary-goto-article t] - ["Go to the last article" gnus-summary-goto-last-article t] - ["Pop article off history" gnus-summary-pop-article t]) - ("Sort" - ["Sort by number" gnus-summary-sort-by-number t] - ["Sort by author" gnus-summary-sort-by-author t] - ["Sort by subject" gnus-summary-sort-by-subject t] - ["Sort by date" gnus-summary-sort-by-date t] - ["Sort by score" gnus-summary-sort-by-score t] - ["Sort by lines" gnus-summary-sort-by-lines t]) - ("Help" - ["Fetch group FAQ" gnus-summary-fetch-faq t] - ["Describe group" gnus-summary-describe-group t] - ["Read manual" gnus-info-find-node t]) - ("Modes" - ["Pick and read" gnus-pick-mode t] - ["Binary" gnus-binary-mode t]) - ("Regeneration" - ["Regenerate" gnus-summary-prepare t] - ["Insert cached articles" gnus-summary-insert-cached-articles t] - ["Toggle threading" gnus-summary-toggle-threads t]) - ["Filter articles..." gnus-summary-execute-command t] - ["Run command on subjects..." gnus-summary-universal-argument t] - ["Search articles forward..." gnus-summary-search-article-forward t] - ["Search articles backward..." gnus-summary-search-article-backward t] - ["Toggle line truncation" gnus-summary-toggle-truncation t] - ["Expand window" gnus-summary-expand-window t] - ["Expire expirable articles" gnus-summary-expire-articles - (gnus-check-backend-function - 'request-expire-articles gnus-newsgroup-name)] - ["Edit local kill file" gnus-summary-edit-local-kill t] - ["Edit main kill file" gnus-summary-edit-global-kill t] - ["Edit group parameters" gnus-summary-edit-parameters t] - ["Send a bug report" gnus-bug t] - ("Exit" - ["Catchup and exit" gnus-summary-catchup-and-exit t] - ["Catchup all and exit" gnus-summary-catchup-all-and-exit t] - ["Catchup and goto next" gnus-summary-catchup-and-goto-next-group t] - ["Exit group" gnus-summary-exit t] - ["Exit group without updating" gnus-summary-exit-no-update t] - ["Exit and goto next group" gnus-summary-next-group t] - ["Exit and goto prev group" gnus-summary-prev-group t] - ["Reselect group" gnus-summary-reselect-current-group t] - ["Rescan group" gnus-summary-rescan-group t] - ["Update dribble" gnus-summary-save-newsrc t]))) - - (gnus-run-hooks 'gnus-summary-menu-hook))) - -(defun gnus-score-set-default (var value) - "A version of set that updates the GNU Emacs menu-bar." - (set var value) - ;; It is the message that forces the active status to be updated. - (message "")) - -(defun gnus-make-score-map (type) - "Make a summary score map of type TYPE." - (if t - nil - (let ((headers '(("author" "from" string) - ("subject" "subject" string) - ("article body" "body" string) - ("article head" "head" string) - ("xref" "xref" string) - ("lines" "lines" number) - ("followups to author" "followup" string))) - (types '((number ("less than" <) - ("greater than" >) - ("equal" =)) - (string ("substring" s) - ("exact string" e) - ("fuzzy string" f) - ("regexp" r)))) - (perms '(("temporary" (current-time-string)) - ("permanent" nil) - ("immediate" now))) - header) - (list - (apply - 'nconc - (list - (if (eq type 'lower) - "Lower score" - "Increase score")) - (let (outh) - (while headers - (setq header (car headers)) - (setq outh - (cons - (apply - 'nconc - (list (car header)) - (let ((ts (cdr (assoc (nth 2 header) types))) - outt) - (while ts - (setq outt - (cons - (apply - 'nconc - (list (caar ts)) - (let ((ps perms) - outp) - (while ps - (setq outp - (cons - (vector - (caar ps) - (list - 'gnus-summary-score-entry - (nth 1 header) - (if (or (string= (nth 1 header) - "head") - (string= (nth 1 header) - "body")) - "" - (list 'gnus-summary-header - (nth 1 header))) - (list 'quote (nth 1 (car ts))) - (list 'gnus-score-default nil) - (nth 1 (car ps)) - t) - t) - outp)) - (setq ps (cdr ps))) - (list (nreverse outp)))) - outt)) - (setq ts (cdr ts))) - (list (nreverse outt)))) - outh)) - (setq headers (cdr headers))) - (list (nreverse outh)))))))) - - - -(defun gnus-summary-mode (&optional group) - "Major mode for reading articles. - -All normal editing commands are switched off. -\\ -Each line in this buffer represents one article. To read an -article, you can, for instance, type `\\[gnus-summary-next-page]'. To move forwards -and backwards while displaying articles, type `\\[gnus-summary-next-unread-article]' and `\\[gnus-summary-prev-unread-article]', -respectively. - -You can also post articles and send mail from this buffer. To -follow up an article, type `\\[gnus-summary-followup]'. To mail a reply to the author -of an article, type `\\[gnus-summary-reply]'. - -There are approx. one gazillion commands you can execute in this -buffer; read the info pages for more information (`\\[gnus-info-find-node]'). - -The following commands are available: - -\\{gnus-summary-mode-map}" - (interactive) - (when (gnus-visual-p 'summary-menu 'menu) - (gnus-summary-make-menu-bar)) - (kill-all-local-variables) - (gnus-summary-make-local-variables) - (gnus-make-thread-indent-array) - (gnus-simplify-mode-line) - (setq major-mode 'gnus-summary-mode) - (setq mode-name "Summary") - (make-local-variable 'minor-mode-alist) - (use-local-map gnus-summary-mode-map) - (buffer-disable-undo (current-buffer)) - (setq buffer-read-only t) ;Disable modification - (setq truncate-lines t) - (setq selective-display t) - (setq selective-display-ellipses t) ;Display `...' - (gnus-summary-set-display-table) - (gnus-set-default-directory) - (setq gnus-newsgroup-name group) - (make-local-variable 'gnus-summary-line-format) - (make-local-variable 'gnus-summary-line-format-spec) - (make-local-variable 'gnus-summary-dummy-line-format) - (make-local-variable 'gnus-summary-dummy-line-format-spec) - (make-local-variable 'gnus-summary-mark-positions) - (make-local-hook 'post-command-hook) - (add-hook 'post-command-hook 'gnus-clear-inboxes-moved nil t) - (make-local-hook 'pre-command-hook) - (add-hook 'pre-command-hook 'gnus-set-global-variables nil t) - (gnus-run-hooks 'gnus-summary-mode-hook) - (gnus-update-format-specifications nil 'summary 'summary-mode 'summary-dummy) - (gnus-update-summary-mark-positions)) - -(defun gnus-summary-make-local-variables () - "Make all the local summary buffer variables." - (let ((locals gnus-summary-local-variables) - global local) - (while (setq local (pop locals)) - (if (consp local) - (progn - (if (eq (cdr local) 'global) - ;; Copy the global value of the variable. - (setq global (symbol-value (car local))) - ;; Use the value from the list. - (setq global (eval (cdr local)))) - (make-local-variable (car local)) - (set (car local) global)) - ;; Simple nil-valued local variable. - (make-local-variable local) - (set local nil))))) - -(defun gnus-summary-clear-local-variables () - (let ((locals gnus-summary-local-variables)) - (while locals - (if (consp (car locals)) - (and (vectorp (caar locals)) - (set (caar locals) nil)) - (and (vectorp (car locals)) - (set (car locals) nil))) - (setq locals (cdr locals))))) - -;; Summary data functions. - -(defmacro gnus-data-number (data) - `(car ,data)) - -(defmacro gnus-data-set-number (data number) - `(setcar ,data ,number)) - -(defmacro gnus-data-mark (data) - `(nth 1 ,data)) - -(defmacro gnus-data-set-mark (data mark) - `(setcar (nthcdr 1 ,data) ,mark)) - -(defmacro gnus-data-pos (data) - `(nth 2 ,data)) - -(defmacro gnus-data-set-pos (data pos) - `(setcar (nthcdr 2 ,data) ,pos)) - -(defmacro gnus-data-header (data) - `(nth 3 ,data)) - -(defmacro gnus-data-set-header (data header) - `(setf (nth 3 ,data) ,header)) - -(defmacro gnus-data-level (data) - `(nth 4 ,data)) - -(defmacro gnus-data-unread-p (data) - `(= (nth 1 ,data) gnus-unread-mark)) - -(defmacro gnus-data-read-p (data) - `(/= (nth 1 ,data) gnus-unread-mark)) - -(defmacro gnus-data-pseudo-p (data) - `(consp (nth 3 ,data))) - -(defmacro gnus-data-find (number) - `(assq ,number gnus-newsgroup-data)) - -(defmacro gnus-data-find-list (number &optional data) - `(let ((bdata ,(or data 'gnus-newsgroup-data))) - (memq (assq ,number bdata) - bdata))) - -(defmacro gnus-data-make (number mark pos header level) - `(list ,number ,mark ,pos ,header ,level)) - -(defun gnus-data-enter (after-article number mark pos header level offset) - (let ((data (gnus-data-find-list after-article))) - (unless data - (error "No such article: %d" after-article)) - (setcdr data (cons (gnus-data-make number mark pos header level) - (cdr data))) - (setq gnus-newsgroup-data-reverse nil) - (gnus-data-update-list (cddr data) offset))) - -(defun gnus-data-enter-list (after-article list &optional offset) - (when list - (let ((data (and after-article (gnus-data-find-list after-article))) - (ilist list)) - (if (not (or data - after-article)) - (let ((odata gnus-newsgroup-data)) - (setq gnus-newsgroup-data (nconc list gnus-newsgroup-data)) - (when offset - (gnus-data-update-list odata offset))) - ;; Find the last element in the list to be spliced into the main - ;; list. - (while (cdr list) - (setq list (cdr list))) - (if (not data) - (progn - (setcdr list gnus-newsgroup-data) - (setq gnus-newsgroup-data ilist) - (when offset - (gnus-data-update-list (cdr list) offset))) - (setcdr list (cdr data)) - (setcdr data ilist) - (when offset - (gnus-data-update-list (cdr list) offset)))) - (setq gnus-newsgroup-data-reverse nil)))) - -(defun gnus-data-remove (article &optional offset) - (let ((data gnus-newsgroup-data)) - (if (= (gnus-data-number (car data)) article) - (progn - (setq gnus-newsgroup-data (cdr gnus-newsgroup-data) - gnus-newsgroup-data-reverse nil) - (when offset - (gnus-data-update-list gnus-newsgroup-data offset))) - (while (cdr data) - (when (= (gnus-data-number (cadr data)) article) - (setcdr data (cddr data)) - (when offset - (gnus-data-update-list (cdr data) offset)) - (setq data nil - gnus-newsgroup-data-reverse nil)) - (setq data (cdr data)))))) - -(defmacro gnus-data-list (backward) - `(if ,backward - (or gnus-newsgroup-data-reverse - (setq gnus-newsgroup-data-reverse - (reverse gnus-newsgroup-data))) - gnus-newsgroup-data)) - -(defun gnus-data-update-list (data offset) - "Add OFFSET to the POS of all data entries in DATA." - (setq gnus-newsgroup-data-reverse nil) - (while data - (setcar (nthcdr 2 (car data)) (+ offset (nth 2 (car data)))) - (setq data (cdr data)))) - -(defun gnus-data-compute-positions () - "Compute the positions of all articles." - (setq gnus-newsgroup-data-reverse nil) - (let ((data gnus-newsgroup-data)) - (save-excursion - (gnus-save-hidden-threads - (gnus-summary-show-all-threads) - (goto-char (point-min)) - (while data - (while (get-text-property (point) 'gnus-intangible) - (forward-line 1)) - (gnus-data-set-pos (car data) (+ (point) 3)) - (setq data (cdr data)) - (forward-line 1)))))) - -(defun gnus-summary-article-pseudo-p (article) - "Say whether this article is a pseudo article or not." - (not (vectorp (gnus-data-header (gnus-data-find article))))) - -(defmacro gnus-summary-article-sparse-p (article) - "Say whether this article is a sparse article or not." - `(memq ,article gnus-newsgroup-sparse)) - -(defmacro gnus-summary-article-ancient-p (article) - "Say whether this article is a sparse article or not." - `(memq ,article gnus-newsgroup-ancient)) - -(defun gnus-article-parent-p (number) - "Say whether this article is a parent or not." - (let ((data (gnus-data-find-list number))) - (and (cdr data) ; There has to be an article after... - (< (gnus-data-level (car data)) ; And it has to have a higher level. - (gnus-data-level (nth 1 data)))))) - -(defun gnus-article-children (number) - "Return a list of all children to NUMBER." - (let* ((data (gnus-data-find-list number)) - (level (gnus-data-level (car data))) - children) - (setq data (cdr data)) - (while (and data - (= (gnus-data-level (car data)) (1+ level))) - (push (gnus-data-number (car data)) children) - (setq data (cdr data))) - children)) - -(defmacro gnus-summary-skip-intangible () - "If the current article is intangible, then jump to a different article." - '(let ((to (get-text-property (point) 'gnus-intangible))) - (and to (gnus-summary-goto-subject to)))) - -(defmacro gnus-summary-article-intangible-p () - "Say whether this article is intangible or not." - '(get-text-property (point) 'gnus-intangible)) - -(defun gnus-article-read-p (article) - "Say whether ARTICLE is read or not." - (not (or (memq article gnus-newsgroup-marked) - (memq article gnus-newsgroup-unreads) - (memq article gnus-newsgroup-unselected) - (memq article gnus-newsgroup-dormant)))) - -;; Some summary mode macros. - -(defmacro gnus-summary-article-number () - "The article number of the article on the current line. -If there isn's an article number here, then we return the current -article number." - '(progn - (gnus-summary-skip-intangible) - (or (get-text-property (point) 'gnus-number) - (gnus-summary-last-subject)))) - -(defmacro gnus-summary-article-header (&optional number) - "Return the header of article NUMBER." - `(gnus-data-header (gnus-data-find - ,(or number '(gnus-summary-article-number))))) - -(defmacro gnus-summary-thread-level (&optional number) - "Return the level of thread that starts with article NUMBER." - `(if (and (eq gnus-summary-make-false-root 'dummy) - (get-text-property (point) 'gnus-intangible)) - 0 - (gnus-data-level (gnus-data-find - ,(or number '(gnus-summary-article-number)))))) - -(defmacro gnus-summary-article-mark (&optional number) - "Return the mark of article NUMBER." - `(gnus-data-mark (gnus-data-find - ,(or number '(gnus-summary-article-number))))) - -(defmacro gnus-summary-article-pos (&optional number) - "Return the position of the line of article NUMBER." - `(gnus-data-pos (gnus-data-find - ,(or number '(gnus-summary-article-number))))) - -(defalias 'gnus-summary-subject-string 'gnus-summary-article-subject) -(defmacro gnus-summary-article-subject (&optional number) - "Return current subject string or nil if nothing." - `(let ((headers - ,(if number - `(gnus-data-header (assq ,number gnus-newsgroup-data)) - '(gnus-data-header (assq (gnus-summary-article-number) - gnus-newsgroup-data))))) - (and headers - (vectorp headers) - (mail-header-subject headers)))) - -(defmacro gnus-summary-article-score (&optional number) - "Return current article score." - `(or (cdr (assq ,(or number '(gnus-summary-article-number)) - gnus-newsgroup-scored)) - gnus-summary-default-score 0)) - -(defun gnus-summary-article-children (&optional number) - "Return a list of article numbers that are children of article NUMBER." - (let* ((data (gnus-data-find-list (or number (gnus-summary-article-number)))) - (level (gnus-data-level (car data))) - l children) - (while (and (setq data (cdr data)) - (> (setq l (gnus-data-level (car data))) level)) - (and (= (1+ level) l) - (push (gnus-data-number (car data)) - children))) - (nreverse children))) - -(defun gnus-summary-article-parent (&optional number) - "Return the article number of the parent of article NUMBER." - (let* ((data (gnus-data-find-list (or number (gnus-summary-article-number)) - (gnus-data-list t))) - (level (gnus-data-level (car data)))) - (if (zerop level) - () ; This is a root. - ;; We search until we find an article with a level less than - ;; this one. That function has to be the parent. - (while (and (setq data (cdr data)) - (not (< (gnus-data-level (car data)) level)))) - (and data (gnus-data-number (car data)))))) - -(defun gnus-unread-mark-p (mark) - "Say whether MARK is the unread mark." - (= mark gnus-unread-mark)) - -(defun gnus-read-mark-p (mark) - "Say whether MARK is one of the marks that mark as read. -This is all marks except unread, ticked, dormant, and expirable." - (not (or (= mark gnus-unread-mark) - (= mark gnus-ticked-mark) - (= mark gnus-dormant-mark) - (= mark gnus-expirable-mark)))) - -(defmacro gnus-article-mark (number) - "Return the MARK of article NUMBER. -This macro should only be used when computing the mark the \"first\" -time; i.e., when generating the summary lines. After that, -`gnus-summary-article-mark' should be used to examine the -marks of articles." - `(cond - ((memq ,number gnus-newsgroup-unsendable) gnus-unsendable-mark) - ((memq ,number gnus-newsgroup-undownloaded) gnus-undownloaded-mark) - ((memq ,number gnus-newsgroup-downloadable) gnus-downloadable-mark) - ((memq ,number gnus-newsgroup-unreads) gnus-unread-mark) - ((memq ,number gnus-newsgroup-marked) gnus-ticked-mark) - ((memq ,number gnus-newsgroup-dormant) gnus-dormant-mark) - ((memq ,number gnus-newsgroup-expirable) gnus-expirable-mark) - (t (or (cdr (assq ,number gnus-newsgroup-reads)) - gnus-ancient-mark)))) - -;; Saving hidden threads. - -(put 'gnus-save-hidden-threads 'lisp-indent-function 0) -(put 'gnus-save-hidden-threads 'edebug-form-spec '(body)) - -(defmacro gnus-save-hidden-threads (&rest forms) - "Save hidden threads, eval FORMS, and restore the hidden threads." - (let ((config (make-symbol "config"))) - `(let ((,config (gnus-hidden-threads-configuration))) - (unwind-protect - (save-excursion - ,@forms) - (gnus-restore-hidden-threads-configuration ,config))))) - -(defun gnus-hidden-threads-configuration () - "Return the current hidden threads configuration." - (save-excursion - (let (config) - (goto-char (point-min)) - (while (search-forward "\r" nil t) - (push (1- (point)) config)) - config))) - -(defun gnus-restore-hidden-threads-configuration (config) - "Restore hidden threads configuration from CONFIG." - (let (point buffer-read-only) - (while (setq point (pop config)) - (when (and (< point (point-max)) - (goto-char point) - (= (following-char) ?\n)) - (subst-char-in-region point (1+ point) ?\n ?\r))))) - -;; Various summary mode internalish functions. - -(defun gnus-mouse-pick-article (e) - (interactive "e") - (mouse-set-point e) - (gnus-summary-next-page nil t)) - -(defun gnus-summary-set-display-table () - ;; Change the display table. Odd characters have a tendency to mess - ;; up nicely formatted displays - we make all possible glyphs - ;; display only a single character. - - ;; We start from the standard display table, if any. - (let ((table (or (copy-sequence standard-display-table) - (make-display-table))) - (i 32)) - ;; Nix out all the control chars... - (while (>= (setq i (1- i)) 0) - (aset table i [??])) - ;; ... but not newline and cr, of course. (cr is necessary for the - ;; selective display). - (aset table ?\n nil) - (aset table ?\r nil) - ;; We keep TAB as well. - (aset table ?\t nil) - ;; We nix out any glyphs over 126 that are not set already. - (let ((i 256)) - (while (>= (setq i (1- i)) 127) - ;; Only modify if the entry is nil. - (unless (aref table i) - (aset table i [??])))) - (setq buffer-display-table table))) - -(defun gnus-summary-setup-buffer (group) - "Initialize summary buffer." - (let ((buffer (concat "*Summary " group "*"))) - (if (get-buffer buffer) - (progn - (set-buffer buffer) - (setq gnus-summary-buffer (current-buffer)) - (not gnus-newsgroup-prepared)) - ;; Fix by Sudish Joseph - (setq gnus-summary-buffer (set-buffer (gnus-get-buffer-create buffer))) - (gnus-summary-mode group) - (when gnus-carpal - (gnus-carpal-setup-buffer 'summary)) - (unless gnus-single-article-buffer - (make-local-variable 'gnus-article-buffer) - (make-local-variable 'gnus-article-current) - (make-local-variable 'gnus-original-article-buffer)) - (setq gnus-newsgroup-name group) - t))) - -(defun gnus-set-global-variables () - ;; Set the global equivalents of the summary buffer-local variables - ;; to the latest values they had. These reflect the summary buffer - ;; that was in action when the last article was fetched. - (when (eq major-mode 'gnus-summary-mode) - (setq gnus-summary-buffer (current-buffer)) - (let ((name gnus-newsgroup-name) - (marked gnus-newsgroup-marked) - (unread gnus-newsgroup-unreads) - (headers gnus-current-headers) - (data gnus-newsgroup-data) - (summary gnus-summary-buffer) - (article-buffer gnus-article-buffer) - (original gnus-original-article-buffer) - (gac gnus-article-current) - (reffed gnus-reffed-article-number) - (score-file gnus-current-score-file)) - (save-excursion - (set-buffer gnus-group-buffer) - (setq gnus-newsgroup-name name - gnus-newsgroup-marked marked - gnus-newsgroup-unreads unread - gnus-current-headers headers - gnus-newsgroup-data data - gnus-article-current gac - gnus-summary-buffer summary - gnus-article-buffer article-buffer - gnus-original-article-buffer original - gnus-reffed-article-number reffed - gnus-current-score-file score-file) - ;; The article buffer also has local variables. - (when (gnus-buffer-live-p gnus-article-buffer) - (set-buffer gnus-article-buffer) - (setq gnus-summary-buffer summary)))))) - -(defun gnus-summary-article-unread-p (article) - "Say whether ARTICLE is unread or not." - (memq article gnus-newsgroup-unreads)) - -(defun gnus-summary-first-article-p (&optional article) - "Return whether ARTICLE is the first article in the buffer." - (if (not (setq article (or article (gnus-summary-article-number)))) - nil - (eq article (caar gnus-newsgroup-data)))) - -(defun gnus-summary-last-article-p (&optional article) - "Return whether ARTICLE is the last article in the buffer." - (if (not (setq article (or article (gnus-summary-article-number)))) - t ; All non-existent numbers are the last article. :-) - (not (cdr (gnus-data-find-list article))))) - -(defun gnus-make-thread-indent-array () - (let ((n 200)) - (unless (and gnus-thread-indent-array - (= gnus-thread-indent-level gnus-thread-indent-array-level)) - (setq gnus-thread-indent-array (make-vector 201 "") - gnus-thread-indent-array-level gnus-thread-indent-level) - (while (>= n 0) - (aset gnus-thread-indent-array n - (make-string (* n gnus-thread-indent-level) ? )) - (setq n (1- n)))))) - -(defun gnus-update-summary-mark-positions () - "Compute where the summary marks are to go." - (save-excursion - (when (gnus-buffer-exists-p gnus-summary-buffer) - (set-buffer gnus-summary-buffer)) - (let ((gnus-replied-mark 129) - (gnus-score-below-mark 130) - (gnus-score-over-mark 130) - (gnus-download-mark 131) - (spec gnus-summary-line-format-spec) - gnus-visual pos) - (save-excursion - (gnus-set-work-buffer) - (let ((gnus-summary-line-format-spec spec) - (gnus-newsgroup-downloadable '((0 . t)))) - (gnus-summary-insert-line - (make-full-mail-header 0 "" "" "" "" "" 0 0 "") - 0 nil 128 t nil "" nil 1) - (goto-char (point-min)) - (setq pos (list (cons 'unread (and (search-forward "\200" nil t) - (- (point) 2))))) - (goto-char (point-min)) - (push (cons 'replied (and (search-forward "\201" nil t) - (- (point) 2))) - pos) - (goto-char (point-min)) - (push (cons 'score (and (search-forward "\202" nil t) (- (point) 2))) - pos) - (goto-char (point-min)) - (push (cons 'download - (and (search-forward "\203" nil t) (- (point) 2))) - pos))) - (setq gnus-summary-mark-positions pos)))) - -(defun gnus-summary-insert-dummy-line (gnus-tmp-subject gnus-tmp-number) - "Insert a dummy root in the summary buffer." - (beginning-of-line) - (gnus-add-text-properties - (point) (progn (eval gnus-summary-dummy-line-format-spec) (point)) - (list 'gnus-number gnus-tmp-number 'gnus-intangible gnus-tmp-number))) - -(defun gnus-summary-insert-line (gnus-tmp-header - gnus-tmp-level gnus-tmp-current - gnus-tmp-unread gnus-tmp-replied - gnus-tmp-expirable gnus-tmp-subject-or-nil - &optional gnus-tmp-dummy gnus-tmp-score - gnus-tmp-process) - (let* ((gnus-tmp-indentation (aref gnus-thread-indent-array gnus-tmp-level)) - (gnus-tmp-lines (mail-header-lines gnus-tmp-header)) - (gnus-tmp-score (or gnus-tmp-score gnus-summary-default-score 0)) - (gnus-tmp-score-char - (if (or (null gnus-summary-default-score) - (<= (abs (- gnus-tmp-score gnus-summary-default-score)) - gnus-summary-zcore-fuzz)) - ? - (if (< gnus-tmp-score gnus-summary-default-score) - gnus-score-below-mark gnus-score-over-mark))) - (gnus-tmp-replied - (cond (gnus-tmp-process gnus-process-mark) - ((memq gnus-tmp-current gnus-newsgroup-cached) - gnus-cached-mark) - (gnus-tmp-replied gnus-replied-mark) - ((memq gnus-tmp-current gnus-newsgroup-saved) - gnus-saved-mark) - (t gnus-unread-mark))) - (gnus-tmp-from (mail-header-from gnus-tmp-header)) - (gnus-tmp-name - (cond - ((string-match "<[^>]+> *$" gnus-tmp-from) - (let ((beg (match-beginning 0))) - (or (and (string-match "^\"[^\"]*\"" gnus-tmp-from) - (substring gnus-tmp-from (1+ (match-beginning 0)) - (1- (match-end 0)))) - (substring gnus-tmp-from 0 beg)))) - ((string-match "(.+)" gnus-tmp-from) - (substring gnus-tmp-from - (1+ (match-beginning 0)) (1- (match-end 0)))) - (t gnus-tmp-from))) - (gnus-tmp-subject (mail-header-subject gnus-tmp-header)) - (gnus-tmp-number (mail-header-number gnus-tmp-header)) - (gnus-tmp-opening-bracket (if gnus-tmp-dummy ?\< ?\[)) - (gnus-tmp-closing-bracket (if gnus-tmp-dummy ?\> ?\])) - (buffer-read-only nil)) - (when (string= gnus-tmp-name "") - (setq gnus-tmp-name gnus-tmp-from)) - (unless (numberp gnus-tmp-lines) - (setq gnus-tmp-lines 0)) - (gnus-put-text-property-excluding-characters-with-faces - (point) - (progn (eval gnus-summary-line-format-spec) (point)) - 'gnus-number gnus-tmp-number) - (when (gnus-visual-p 'summary-highlight 'highlight) - (forward-line -1) - (gnus-run-hooks 'gnus-summary-update-hook) - (forward-line 1)))) - -(defun gnus-summary-update-line (&optional dont-update) - ;; Update summary line after change. - (when (and gnus-summary-default-score - (not gnus-summary-inhibit-highlight)) - (let* ((gnus-summary-inhibit-highlight t) ; Prevent recursion. - (article (gnus-summary-article-number)) - (score (gnus-summary-article-score article))) - (unless dont-update - (if (and gnus-summary-mark-below - (< (gnus-summary-article-score) - gnus-summary-mark-below)) - ;; This article has a low score, so we mark it as read. - (when (memq article gnus-newsgroup-unreads) - (gnus-summary-mark-article-as-read gnus-low-score-mark)) - (when (eq (gnus-summary-article-mark) gnus-low-score-mark) - ;; This article was previously marked as read on account - ;; of a low score, but now it has risen, so we mark it as - ;; unread. - (gnus-summary-mark-article-as-unread gnus-unread-mark))) - (gnus-summary-update-mark - (if (or (null gnus-summary-default-score) - (<= (abs (- score gnus-summary-default-score)) - gnus-summary-zcore-fuzz)) - ? - (if (< score gnus-summary-default-score) - gnus-score-below-mark gnus-score-over-mark)) - 'score)) - ;; Do visual highlighting. - (when (gnus-visual-p 'summary-highlight 'highlight) - (gnus-run-hooks 'gnus-summary-update-hook))))) - -(defvar gnus-tmp-new-adopts nil) - -(defun gnus-summary-number-of-articles-in-thread (thread &optional level char) - "Return the number of articles in THREAD. -This may be 0 in some cases -- if none of the articles in -the thread are to be displayed." - (let* ((number - ;; Fix by Luc Van Eycken . - (cond - ((not (listp thread)) - 1) - ((and (consp thread) (cdr thread)) - (apply - '+ 1 (mapcar - 'gnus-summary-number-of-articles-in-thread (cdr thread)))) - ((null thread) - 1) - ((memq (mail-header-number (car thread)) gnus-newsgroup-limit) - 1) - (t 0)))) - (when (and level (zerop level) gnus-tmp-new-adopts) - (incf number - (apply '+ (mapcar - 'gnus-summary-number-of-articles-in-thread - gnus-tmp-new-adopts)))) - (if char - (if (> number 1) gnus-not-empty-thread-mark - gnus-empty-thread-mark) - number))) - -(defun gnus-summary-set-local-parameters (group) - "Go through the local params of GROUP and set all variable specs in that list." - (let ((params (gnus-group-find-parameter group)) - elem) - (while params - (setq elem (car params) - params (cdr params)) - (and (consp elem) ; Has to be a cons. - (consp (cdr elem)) ; The cdr has to be a list. - (symbolp (car elem)) ; Has to be a symbol in there. - (not (memq (car elem) '(quit-config))) ; Ignore quit-config. - (ignore-errors ; So we set it. - (make-local-variable (car elem)) - (set (car elem) (eval (nth 1 elem)))))))) - -(defun gnus-summary-read-group (group &optional show-all no-article - kill-buffer no-display backward - select-articles) - "Start reading news in newsgroup GROUP. -If SHOW-ALL is non-nil, already read articles are also listed. -If NO-ARTICLE is non-nil, no article is selected initially. -If NO-DISPLAY, don't generate a summary buffer." - (let (result) - (while (and group - (null (setq result - (let ((gnus-auto-select-next nil)) - (or (gnus-summary-read-group-1 - group show-all no-article - kill-buffer no-display - select-articles) - (setq show-all nil - select-articles nil))))) - (eq gnus-auto-select-next 'quietly)) - (set-buffer gnus-group-buffer) - ;; The entry function called above goes to the next - ;; group automatically, so we go two groups back - ;; if we are searching for the previous group. - (when backward - (gnus-group-prev-unread-group 2)) - (if (not (equal group (gnus-group-group-name))) - (setq group (gnus-group-group-name)) - (setq group nil))) - result)) - -(defun gnus-summary-read-group-1 (group show-all no-article - kill-buffer no-display - &optional select-articles) - ;; Killed foreign groups can't be entered. - (when (and (not (gnus-group-native-p group)) - (not (gnus-gethash group gnus-newsrc-hashtb))) - (error "Dead non-native groups can't be entered")) - (gnus-message 5 "Retrieving newsgroup: %s..." group) - (let* ((new-group (gnus-summary-setup-buffer group)) - (quit-config (gnus-group-quit-config group)) - (did-select (and new-group (gnus-select-newsgroup - group show-all select-articles)))) - (cond - ;; This summary buffer exists already, so we just select it. - ((not new-group) - (gnus-set-global-variables) - (when kill-buffer - (gnus-kill-or-deaden-summary kill-buffer)) - (gnus-configure-windows 'summary 'force) - (gnus-set-mode-line 'summary) - (gnus-summary-position-point) - (message "") - t) - ;; We couldn't select this group. - ((null did-select) - (when (and (eq major-mode 'gnus-summary-mode) - (not (equal (current-buffer) kill-buffer))) - (kill-buffer (current-buffer)) - (if (not quit-config) - (progn - ;; Update the info -- marks might need to be removed, - ;; for instance. - (gnus-summary-update-info) - (set-buffer gnus-group-buffer) - (gnus-group-jump-to-group group) - (gnus-group-next-unread-group 1)) - (gnus-handle-ephemeral-exit quit-config))) - (gnus-message 3 "Can't select group") - nil) - ;; The user did a `C-g' while prompting for number of articles, - ;; so we exit this group. - ((eq did-select 'quit) - (and (eq major-mode 'gnus-summary-mode) - (not (equal (current-buffer) kill-buffer)) - (kill-buffer (current-buffer))) - (when kill-buffer - (gnus-kill-or-deaden-summary kill-buffer)) - (if (not quit-config) - (progn - (set-buffer gnus-group-buffer) - (gnus-group-jump-to-group group) - (gnus-group-next-unread-group 1) - (gnus-configure-windows 'group 'force)) - (gnus-handle-ephemeral-exit quit-config)) - ;; Finally signal the quit. - (signal 'quit nil)) - ;; The group was successfully selected. - (t - (gnus-set-global-variables) - ;; Save the active value in effect when the group was entered. - (setq gnus-newsgroup-active - (gnus-copy-sequence - (gnus-active gnus-newsgroup-name))) - ;; You can change the summary buffer in some way with this hook. - (gnus-run-hooks 'gnus-select-group-hook) - ;; Set any local variables in the group parameters. - (gnus-summary-set-local-parameters gnus-newsgroup-name) - (gnus-update-format-specifications - nil 'summary 'summary-mode 'summary-dummy) - ;; Do score processing. - (when gnus-use-scoring - (gnus-possibly-score-headers)) - ;; Check whether to fill in the gaps in the threads. - (when gnus-build-sparse-threads - (gnus-build-sparse-threads)) - ;; Find the initial limit. - (if gnus-show-threads - (if show-all - (let ((gnus-newsgroup-dormant nil)) - (gnus-summary-initial-limit show-all)) - (gnus-summary-initial-limit show-all)) - (setq gnus-newsgroup-limit - (mapcar - (lambda (header) (mail-header-number header)) - gnus-newsgroup-headers))) - ;; Generate the summary buffer. - (unless no-display - (gnus-summary-prepare)) - (when gnus-use-trees - (gnus-tree-open group) - (setq gnus-summary-highlight-line-function - 'gnus-tree-highlight-article)) - ;; If the summary buffer is empty, but there are some low-scored - ;; articles or some excluded dormants, we include these in the - ;; buffer. - (when (and (zerop (buffer-size)) - (not no-display)) - (cond (gnus-newsgroup-dormant - (gnus-summary-limit-include-dormant)) - ((and gnus-newsgroup-scored show-all) - (gnus-summary-limit-include-expunged t)))) - ;; Function `gnus-apply-kill-file' must be called in this hook. - (gnus-run-hooks 'gnus-apply-kill-hook) - (if (and (zerop (buffer-size)) - (not no-display)) - (progn - ;; This newsgroup is empty. - (gnus-summary-catchup-and-exit nil t) - (gnus-message 6 "No unread news") - (when kill-buffer - (gnus-kill-or-deaden-summary kill-buffer)) - ;; Return nil from this function. - nil) - ;; Hide conversation thread subtrees. We cannot do this in - ;; gnus-summary-prepare-hook since kill processing may not - ;; work with hidden articles. - (and gnus-show-threads - gnus-thread-hide-subtree - (gnus-summary-hide-all-threads)) - (when kill-buffer - (gnus-kill-or-deaden-summary kill-buffer)) - ;; Show first unread article if requested. - (if (and (not no-article) - (not no-display) - gnus-newsgroup-unreads - gnus-auto-select-first) - (unless (if (eq gnus-auto-select-first 'best) - (gnus-summary-best-unread-article) - (gnus-summary-first-unread-article)) - (gnus-configure-windows 'summary)) - ;; Don't select any articles, just move point to the first - ;; article in the group. - (goto-char (point-min)) - (gnus-summary-position-point) - (gnus-configure-windows 'summary 'force) - (gnus-set-mode-line 'summary)) - (when (get-buffer-window gnus-group-buffer t) - ;; Gotta use windows, because recenter does weird stuff if - ;; the current buffer ain't the displayed window. - (let ((owin (selected-window))) - (select-window (get-buffer-window gnus-group-buffer t)) - (when (gnus-group-goto-group group) - (recenter)) - (select-window owin))) - ;; Mark this buffer as "prepared". - (setq gnus-newsgroup-prepared t) - (gnus-run-hooks 'gnus-summary-prepared-hook) - t))))) - -(defun gnus-summary-prepare () - "Generate the summary buffer." - (interactive) - (let ((buffer-read-only nil)) - (erase-buffer) - (setq gnus-newsgroup-data nil - gnus-newsgroup-data-reverse nil) - (gnus-run-hooks 'gnus-summary-generate-hook) - ;; Generate the buffer, either with threads or without. - (when gnus-newsgroup-headers - (gnus-summary-prepare-threads - (if gnus-show-threads - (gnus-sort-gathered-threads - (funcall gnus-summary-thread-gathering-function - (gnus-sort-threads - (gnus-cut-threads (gnus-make-threads))))) - ;; Unthreaded display. - (gnus-sort-articles gnus-newsgroup-headers)))) - (setq gnus-newsgroup-data (nreverse gnus-newsgroup-data)) - ;; Call hooks for modifying summary buffer. - (goto-char (point-min)) - (gnus-run-hooks 'gnus-summary-prepare-hook))) - -(defsubst gnus-general-simplify-subject (subject) - "Simply subject by the same rules as gnus-gather-threads-by-subject." - (setq subject - (cond - ;; Truncate the subject. - (gnus-simplify-subject-functions - (gnus-map-function gnus-simplify-subject-functions subject)) - ((numberp gnus-summary-gather-subject-limit) - (setq subject (gnus-simplify-subject-re subject)) - (if (> (length subject) gnus-summary-gather-subject-limit) - (substring subject 0 gnus-summary-gather-subject-limit) - subject)) - ;; Fuzzily simplify it. - ((eq 'fuzzy gnus-summary-gather-subject-limit) - (gnus-simplify-subject-fuzzy subject)) - ;; Just remove the leading "Re:". - (t - (gnus-simplify-subject-re subject)))) - - (if (and gnus-summary-gather-exclude-subject - (string-match gnus-summary-gather-exclude-subject subject)) - nil ; This article shouldn't be gathered - subject)) - -(defun gnus-summary-simplify-subject-query () - "Query where the respool algorithm would put this article." - (interactive) - (gnus-summary-select-article) - (message (gnus-general-simplify-subject (gnus-summary-article-subject)))) - -(defun gnus-gather-threads-by-subject (threads) - "Gather threads by looking at Subject headers." - (if (not gnus-summary-make-false-root) - threads - (let ((hashtb (gnus-make-hashtable 1024)) - (prev threads) - (result threads) - subject hthread whole-subject) - (while threads - (setq subject (gnus-general-simplify-subject - (setq whole-subject (mail-header-subject - (caar threads))))) - (when subject - (if (setq hthread (gnus-gethash subject hashtb)) - (progn - ;; We enter a dummy root into the thread, if we - ;; haven't done that already. - (unless (stringp (caar hthread)) - (setcar hthread (list whole-subject (car hthread)))) - ;; We add this new gathered thread to this gathered - ;; thread. - (setcdr (car hthread) - (nconc (cdar hthread) (list (car threads)))) - ;; Remove it from the list of threads. - (setcdr prev (cdr threads)) - (setq threads prev)) - ;; Enter this thread into the hash table. - (gnus-sethash subject threads hashtb))) - (setq prev threads) - (setq threads (cdr threads))) - result))) - -(defun gnus-gather-threads-by-references (threads) - "Gather threads by looking at References headers." - (let ((idhashtb (gnus-make-hashtable 1024)) - (thhashtb (gnus-make-hashtable 1024)) - (prev threads) - (result threads) - ids references id gthread gid entered ref) - (while threads - (when (setq references (mail-header-references (caar threads))) - (setq id (mail-header-id (caar threads)) - ids (gnus-split-references references) - entered nil) - (while (setq ref (pop ids)) - (setq ids (delete ref ids)) - (if (not (setq gid (gnus-gethash ref idhashtb))) - (progn - (gnus-sethash ref id idhashtb) - (gnus-sethash id threads thhashtb)) - (setq gthread (gnus-gethash gid thhashtb)) - (unless entered - ;; We enter a dummy root into the thread, if we - ;; haven't done that already. - (unless (stringp (caar gthread)) - (setcar gthread (list (mail-header-subject (caar gthread)) - (car gthread)))) - ;; We add this new gathered thread to this gathered - ;; thread. - (setcdr (car gthread) - (nconc (cdar gthread) (list (car threads))))) - ;; Add it into the thread hash table. - (gnus-sethash id gthread thhashtb) - (setq entered t) - ;; Remove it from the list of threads. - (setcdr prev (cdr threads)) - (setq threads prev)))) - (setq prev threads) - (setq threads (cdr threads))) - result)) - -(defun gnus-sort-gathered-threads (threads) - "Sort subtreads inside each gathered thread by article number." - (let ((result threads)) - (while threads - (when (stringp (caar threads)) - (setcdr (car threads) - (sort (cdar threads) 'gnus-thread-sort-by-number))) - (setq threads (cdr threads))) - result)) - -(defun gnus-thread-loop-p (root thread) - "Say whether ROOT is in THREAD." - (let ((stack (list thread)) - (infloop 0) - th) - (while (setq thread (pop stack)) - (setq th (cdr thread)) - (while (and th - (not (eq (caar th) root))) - (pop th)) - (if th - ;; We have found a loop. - (let (ref-dep) - (setcdr thread (delq (car th) (cdr thread))) - (if (boundp (setq ref-dep (intern "none" - gnus-newsgroup-dependencies))) - (setcdr (symbol-value ref-dep) - (nconc (cdr (symbol-value ref-dep)) - (list (car th)))) - (set ref-dep (list nil (car th)))) - (setq infloop 1 - stack nil)) - ;; Push all the subthreads onto the stack. - (push (cdr thread) stack))) - infloop)) - -(defun gnus-make-threads () - "Go through the dependency hashtb and find the roots. Return all threads." - (let (threads) - (while (catch 'infloop - (mapatoms - (lambda (refs) - ;; Deal with self-referencing References loops. - (when (and (car (symbol-value refs)) - (not (zerop - (apply - '+ - (mapcar - (lambda (thread) - (gnus-thread-loop-p - (car (symbol-value refs)) thread)) - (cdr (symbol-value refs))))))) - (setq threads nil) - (throw 'infloop t)) - (unless (car (symbol-value refs)) - ;; These threads do not refer back to any other articles, - ;; so they're roots. - (setq threads (append (cdr (symbol-value refs)) threads)))) - gnus-newsgroup-dependencies))) - threads)) - -;; Build the thread tree. -(defun gnus-dependencies-add-header (header dependencies force-new) - "Enter HEADER into the DEPENDENCIES table if it is not already there. - -If FORCE-NEW is not nil, enter HEADER into the DEPENDENCIES table even -if it was already present. - -If `gnus-summary-ignore-duplicates' is nil then duplicate Message-IDs -will not be entered in the DEPENDENCIES table. Otherwise duplicate -Message-IDs will be renamed be renamed to a unique Message-ID before -being entered. - -Returns HEADER if it was entered in the DEPENDENCIES. Returns nil otherwise." - (let* ((id (mail-header-id header)) - (id-dep (and id (intern id dependencies))) - ref ref-dep ref-header) - ;; Enter this `header' in the `dependencies' table. - (cond - ((not id-dep) - (setq header nil)) - ;; The first two cases do the normal part: enter a new `header' - ;; in the `dependencies' table. - ((not (boundp id-dep)) - (set id-dep (list header))) - ((null (car (symbol-value id-dep))) - (setcar (symbol-value id-dep) header)) - - ;; From here the `header' was already present in the - ;; `dependencies' table. - (force-new - ;; Overrides an existing entry; - ;; just set the header part of the entry. - (setcar (symbol-value id-dep) header)) - - ;; Renames the existing `header' to a unique Message-ID. - ((not gnus-summary-ignore-duplicates) - ;; An article with this Message-ID has already been seen. - ;; We rename the Message-ID. - (set (setq id-dep (intern (setq id (nnmail-message-id)) dependencies)) - (list header)) - (mail-header-set-id header id)) - - ;; The last case ignores an existing entry, except it adds any - ;; additional Xrefs (in case the two articles came from different - ;; servers. - ;; Also sets `header' to `nil' meaning that the `dependencies' - ;; table was *not* modified. - (t - (mail-header-set-xref - (car (symbol-value id-dep)) - (concat (or (mail-header-xref (car (symbol-value id-dep))) - "") - (or (mail-header-xref header) ""))) - (setq header nil))) - - (when header - ;; First check if that we are not creating a References loop. - (setq ref (gnus-parent-id (mail-header-references header))) - (while (and ref - (setq ref-dep (intern-soft ref dependencies)) - (boundp ref-dep) - (setq ref-header (car (symbol-value ref-dep)))) - (if (string= id ref) - ;; Yuk! This is a reference loop. Make the article be a - ;; root article. - (progn - (mail-header-set-references (car (symbol-value id-dep)) "none") - (setq ref nil)) - (setq ref (gnus-parent-id (mail-header-references ref-header))))) - (setq ref (gnus-parent-id (mail-header-references header))) - (setq ref-dep (intern (or ref "none") dependencies)) - (if (boundp ref-dep) - (setcdr (symbol-value ref-dep) - (nconc (cdr (symbol-value ref-dep)) - (list (symbol-value id-dep)))) - (set ref-dep (list nil (symbol-value id-dep))))) - header)) - -(defun gnus-build-sparse-threads () - (let ((headers gnus-newsgroup-headers) - (gnus-summary-ignore-duplicates t) - header references generation relations - subject child end new-child date) - ;; First we create an alist of generations/relations, where - ;; generations is how much we trust the relation, and the relation - ;; is parent/child. - (gnus-message 7 "Making sparse threads...") - (save-excursion - (nnheader-set-temp-buffer " *gnus sparse threads*") - (while (setq header (pop headers)) - (when (and (setq references (mail-header-references header)) - (not (string= references ""))) - (insert references) - (setq child (mail-header-id header) - subject (mail-header-subject header) - date (mail-header-date header) - generation 0) - (while (search-backward ">" nil t) - (setq end (1+ (point))) - (when (search-backward "<" nil t) - (setq new-child (buffer-substring (point) end)) - (push (list (incf generation) - child (setq child new-child) - subject date) - relations))) - (when child - (push (list (1+ generation) child nil subject) relations)) - (erase-buffer))) - (kill-buffer (current-buffer))) - ;; Sort over trustworthiness. - (mapcar - (lambda (relation) - (when (gnus-dependencies-add-header - (make-full-mail-header - gnus-reffed-article-number - (nth 3 relation) "" (or (nth 4 relation) "") - (nth 1 relation) - (or (nth 2 relation) "") 0 0 "") - gnus-newsgroup-dependencies nil) - (push gnus-reffed-article-number gnus-newsgroup-limit) - (push gnus-reffed-article-number gnus-newsgroup-sparse) - (push (cons gnus-reffed-article-number gnus-sparse-mark) - gnus-newsgroup-reads) - (decf gnus-reffed-article-number))) - (sort relations 'car-less-than-car)) - (gnus-message 7 "Making sparse threads...done"))) - -(defun gnus-build-old-threads () - ;; Look at all the articles that refer back to old articles, and - ;; fetch the headers for the articles that aren't there. This will - ;; build complete threads - if the roots haven't been expired by the - ;; server, that is. - (let (id heads) - (mapatoms - (lambda (refs) - (when (not (car (symbol-value refs))) - (setq heads (cdr (symbol-value refs))) - (while heads - (if (memq (mail-header-number (caar heads)) - gnus-newsgroup-dormant) - (setq heads (cdr heads)) - (setq id (symbol-name refs)) - (while (and (setq id (gnus-build-get-header id)) - (not (car (gnus-id-to-thread id))))) - (setq heads nil))))) - gnus-newsgroup-dependencies))) - -;; The following macros and functions were written by Felix Lee -;; . - -(defmacro gnus-nov-read-integer () - '(prog1 - (if (= (following-char) ?\t) - 0 - (let ((num (ignore-errors (read buffer)))) - (if (numberp num) num 0))) - (unless (eobp) - (search-forward "\t" eol 'move)))) - -(defmacro gnus-nov-skip-field () - '(search-forward "\t" eol 'move)) - -(defmacro gnus-nov-field () - '(buffer-substring (point) (if (gnus-nov-skip-field) (1- (point)) eol))) - -;; This function has to be called with point after the article number -;; on the beginning of the line. -(defsubst gnus-nov-parse-line (number dependencies &optional force-new) - (let ((eol (gnus-point-at-eol)) - (buffer (current-buffer)) - header) - - ;; overview: [num subject from date id refs chars lines misc] - (unwind-protect - (progn - (narrow-to-region (point) eol) - (unless (eobp) - (forward-char)) - - (setq header - (make-full-mail-header - number ; number - (gnus-nov-field) ; subject - (gnus-nov-field) ; from - (gnus-nov-field) ; date - (or (gnus-nov-field) - (nnheader-generate-fake-message-id)) ; id - (gnus-nov-field) ; refs - (gnus-nov-read-integer) ; chars - (gnus-nov-read-integer) ; lines - (unless (= (following-char) ?\n) - (gnus-nov-field))))) ; misc - - (widen)) - - (when gnus-alter-header-function - (funcall gnus-alter-header-function header)) - (gnus-dependencies-add-header header dependencies force-new))) - -(defun gnus-build-get-header (id) - ;; Look through the buffer of NOV lines and find the header to - ;; ID. Enter this line into the dependencies hash table, and return - ;; the id of the parent article (if any). - (let ((deps gnus-newsgroup-dependencies) - found header) - (prog1 - (save-excursion - (set-buffer nntp-server-buffer) - (let ((case-fold-search nil)) - (goto-char (point-min)) - (while (and (not found) - (search-forward id nil t)) - (beginning-of-line) - (setq found (looking-at - (format "^[^\t]*\t[^\t]*\t[^\t]*\t[^\t]*\t%s" - (regexp-quote id)))) - (or found (beginning-of-line 2))) - (when found - (beginning-of-line) - (and - (setq header (gnus-nov-parse-line - (read (current-buffer)) deps)) - (gnus-parent-id (mail-header-references header)))))) - (when header - (let ((number (mail-header-number header))) - (push number gnus-newsgroup-limit) - (push header gnus-newsgroup-headers) - (if (memq number gnus-newsgroup-unselected) - (progn - (push number gnus-newsgroup-unreads) - (setq gnus-newsgroup-unselected - (delq number gnus-newsgroup-unselected))) - (push number gnus-newsgroup-ancient))))))) - -(defun gnus-build-all-threads () - "Read all the headers." - (let ((gnus-summary-ignore-duplicates t) - (dependencies gnus-newsgroup-dependencies) - header article) - (save-excursion - (set-buffer nntp-server-buffer) - (let ((case-fold-search nil)) - (goto-char (point-min)) - (while (not (eobp)) - (ignore-errors - (setq article (read (current-buffer)) - header (gnus-nov-parse-line - article dependencies))) - (when header - (save-excursion - (set-buffer gnus-summary-buffer) - (push header gnus-newsgroup-headers) - (if (memq (setq article (mail-header-number header)) - gnus-newsgroup-unselected) - (progn - (push article gnus-newsgroup-unreads) - (setq gnus-newsgroup-unselected - (delq article gnus-newsgroup-unselected))) - (push article gnus-newsgroup-ancient))) - (forward-line 1))))))) - -(defun gnus-summary-update-article-line (article header) - "Update the line for ARTICLE using HEADERS." - (let* ((id (mail-header-id header)) - (thread (gnus-id-to-thread id))) - (unless thread - (error "Article in no thread")) - ;; Update the thread. - (setcar thread header) - (gnus-summary-goto-subject article) - (let* ((datal (gnus-data-find-list article)) - (data (car datal)) - (length (when (cdr datal) - (- (gnus-data-pos data) - (gnus-data-pos (cadr datal))))) - (buffer-read-only nil) - (level (gnus-summary-thread-level))) - (gnus-delete-line) - (gnus-summary-insert-line - header level nil (gnus-article-mark article) - (memq article gnus-newsgroup-replied) - (memq article gnus-newsgroup-expirable) - ;; Only insert the Subject string when it's different - ;; from the previous Subject string. - (if (gnus-subject-equal - (condition-case () - (mail-header-subject - (gnus-data-header - (cadr - (gnus-data-find-list - article - (gnus-data-list t))))) - ;; Error on the side of excessive subjects. - (error "")) - (mail-header-subject header)) - "" - (mail-header-subject header)) - nil (cdr (assq article gnus-newsgroup-scored)) - (memq article gnus-newsgroup-processable)) - (when length - (gnus-data-update-list - (cdr datal) (- length (- (gnus-data-pos data) (point)))))))) - -(defun gnus-summary-update-article (article &optional iheader) - "Update ARTICLE in the summary buffer." - (set-buffer gnus-summary-buffer) - (let* ((header (gnus-summary-article-header article)) - (id (mail-header-id header)) - (data (gnus-data-find article)) - (thread (gnus-id-to-thread id)) - (references (mail-header-references header)) - (parent - (gnus-id-to-thread - (or (gnus-parent-id - (when (and references - (not (equal "" references))) - references)) - "none"))) - (buffer-read-only nil) - (old (car thread))) - (when thread - (unless iheader - (setcar thread nil) - (when parent - (delq thread parent))) - (if (gnus-summary-insert-subject id header) - ;; Set the (possibly) new article number in the data structure. - (gnus-data-set-number data (gnus-id-to-article id)) - (setcar thread old) - nil)))) - -(defun gnus-rebuild-thread (id &optional line) - "Rebuild the thread containing ID. -If LINE, insert the rebuilt thread starting on line LINE." - (let ((buffer-read-only nil) - old-pos current thread data) - (if (not gnus-show-threads) - (setq thread (list (car (gnus-id-to-thread id)))) - ;; Get the thread this article is part of. - (setq thread (gnus-remove-thread id))) - (setq old-pos (gnus-point-at-bol)) - (setq current (save-excursion - (and (zerop (forward-line -1)) - (gnus-summary-article-number)))) - ;; If this is a gathered thread, we have to go some re-gathering. - (when (stringp (car thread)) - (let ((subject (car thread)) - roots thr) - (setq thread (cdr thread)) - (while thread - (unless (memq (setq thr (gnus-id-to-thread - (gnus-root-id - (mail-header-id (caar thread))))) - roots) - (push thr roots)) - (setq thread (cdr thread))) - ;; We now have all (unique) roots. - (if (= (length roots) 1) - ;; All the loose roots are now one solid root. - (setq thread (car roots)) - (setq thread (cons subject (gnus-sort-threads roots)))))) - (let (threads) - ;; We then insert this thread into the summary buffer. - (when line - (goto-char (point-min)) - (forward-line (1- line))) - (let (gnus-newsgroup-data gnus-newsgroup-threads) - (if gnus-show-threads - (gnus-summary-prepare-threads (gnus-cut-threads (list thread))) - (gnus-summary-prepare-unthreaded thread)) - (setq data (nreverse gnus-newsgroup-data)) - (setq threads gnus-newsgroup-threads)) - ;; We splice the new data into the data structure. - ;;!!! This is kinda bogus. We assume that in LINE is non-nil, - ;;!!! then we want to insert at the beginning of the buffer. - ;;!!! That happens to be true with Gnus now, but that may - ;;!!! change in the future. Perhaps. - (gnus-data-enter-list - (if line nil current) data (- (point) old-pos)) - (setq gnus-newsgroup-threads - (nconc threads gnus-newsgroup-threads)) - (gnus-data-compute-positions)))) - -(defun gnus-number-to-header (number) - "Return the header for article NUMBER." - (let ((headers gnus-newsgroup-headers)) - (while (and headers - (not (= number (mail-header-number (car headers))))) - (pop headers)) - (when headers - (car headers)))) - -(defun gnus-parent-headers (in-headers &optional generation) - "Return the headers of the GENERATIONeth parent of HEADERS." - (unless generation - (setq generation 1)) - (let ((parent t) - (headers in-headers) - references) - (while (and parent - (not (zerop generation)) - (setq references (mail-header-references headers))) - (setq headers (if (and references - (setq parent (gnus-parent-id references))) - (car (gnus-id-to-thread parent)) - nil)) - (decf generation)) - (and (not (eq headers in-headers)) - headers))) - -(defun gnus-id-to-thread (id) - "Return the (sub-)thread where ID appears." - (gnus-gethash id gnus-newsgroup-dependencies)) - -(defun gnus-id-to-article (id) - "Return the article number of ID." - (let ((thread (gnus-id-to-thread id))) - (when (and thread - (car thread)) - (mail-header-number (car thread))))) - -(defun gnus-id-to-header (id) - "Return the article headers of ID." - (car (gnus-id-to-thread id))) - -(defun gnus-article-displayed-root-p (article) - "Say whether ARTICLE is a root(ish) article." - (let ((level (gnus-summary-thread-level article)) - (refs (mail-header-references (gnus-summary-article-header article))) - particle) - (cond - ((null level) nil) - ((zerop level) t) - ((null refs) t) - ((null (gnus-parent-id refs)) t) - ((and (= 1 level) - (null (setq particle (gnus-id-to-article - (gnus-parent-id refs)))) - (null (gnus-summary-thread-level particle))))))) - -(defun gnus-root-id (id) - "Return the id of the root of the thread where ID appears." - (let (last-id prev) - (while (and id (setq prev (car (gnus-id-to-thread id)))) - (setq last-id id - id (gnus-parent-id (mail-header-references prev)))) - last-id)) - -(defun gnus-articles-in-thread (thread) - "Return the list of articles in THREAD." - (cons (mail-header-number (car thread)) - (apply 'nconc (mapcar 'gnus-articles-in-thread (cdr thread))))) - -(defun gnus-remove-thread (id &optional dont-remove) - "Remove the thread that has ID in it." - (let (headers thread last-id) - ;; First go up in this thread until we find the root. - (setq last-id (gnus-root-id id) - headers (message-flatten-list (gnus-id-to-thread last-id))) - ;; We have now found the real root of this thread. It might have - ;; been gathered into some loose thread, so we have to search - ;; through the threads to find the thread we wanted. - (let ((threads gnus-newsgroup-threads) - sub) - (while threads - (setq sub (car threads)) - (if (stringp (car sub)) - ;; This is a gathered thread, so we look at the roots - ;; below it to find whether this article is in this - ;; gathered root. - (progn - (setq sub (cdr sub)) - (while sub - (when (member (caar sub) headers) - (setq thread (car threads) - threads nil - sub nil)) - (setq sub (cdr sub)))) - ;; It's an ordinary thread, so we check it. - (when (eq (car sub) (car headers)) - (setq thread sub - threads nil))) - (setq threads (cdr threads))) - ;; If this article is in no thread, then it's a root. - (if thread - (unless dont-remove - (setq gnus-newsgroup-threads (delq thread gnus-newsgroup-threads))) - (setq thread (gnus-id-to-thread last-id))) - (when thread - (prog1 - thread ; We return this thread. - (unless dont-remove - (if (stringp (car thread)) - (progn - ;; If we use dummy roots, then we have to remove the - ;; dummy root as well. - (when (eq gnus-summary-make-false-root 'dummy) - ;; We go to the dummy root by going to - ;; the first sub-"thread", and then one line up. - (gnus-summary-goto-article - (mail-header-number (caadr thread))) - (forward-line -1) - (gnus-delete-line) - (gnus-data-compute-positions)) - (setq thread (cdr thread)) - (while thread - (gnus-remove-thread-1 (car thread)) - (setq thread (cdr thread)))) - (gnus-summary-show-all-threads) - (gnus-remove-thread-1 thread)))))))) - -(defun gnus-remove-thread-1 (thread) - "Remove the thread THREAD recursively." - (let ((number (mail-header-number (pop thread))) - d) - (setq thread (reverse thread)) - (while thread - (gnus-remove-thread-1 (pop thread))) - (when (setq d (gnus-data-find number)) - (goto-char (gnus-data-pos d)) - (gnus-data-remove - number - (- (gnus-point-at-bol) - (prog1 - (1+ (gnus-point-at-eol)) - (gnus-delete-line))))))) - -(defun gnus-sort-threads (threads) - "Sort THREADS." - (if (not gnus-thread-sort-functions) - threads - (gnus-message 8 "Sorting threads...") - (prog1 - (sort threads (gnus-make-sort-function gnus-thread-sort-functions)) - (gnus-message 8 "Sorting threads...done")))) - -(defun gnus-sort-articles (articles) - "Sort ARTICLES." - (when gnus-article-sort-functions - (gnus-message 7 "Sorting articles...") - (prog1 - (setq gnus-newsgroup-headers - (sort articles (gnus-make-sort-function - gnus-article-sort-functions))) - (gnus-message 7 "Sorting articles...done")))) - -;; Written by Hallvard B Furuseth . -(defmacro gnus-thread-header (thread) - ;; Return header of first article in THREAD. - ;; Note that THREAD must never, ever be anything else than a variable - - ;; using some other form will lead to serious barfage. - (or (symbolp thread) (signal 'wrong-type-argument '(symbolp thread))) - ;; (8% speedup to gnus-summary-prepare, just for fun :-) - (list 'byte-code "\10\211:\203\17\0\211@;\203\16\0A@@\207" ; - (vector thread) 2)) - -(defsubst gnus-article-sort-by-number (h1 h2) - "Sort articles by article number." - (< (mail-header-number h1) - (mail-header-number h2))) - -(defun gnus-thread-sort-by-number (h1 h2) - "Sort threads by root article number." - (gnus-article-sort-by-number - (gnus-thread-header h1) (gnus-thread-header h2))) - -(defsubst gnus-article-sort-by-lines (h1 h2) - "Sort articles by article Lines header." - (< (mail-header-lines h1) - (mail-header-lines h2))) - -(defun gnus-thread-sort-by-lines (h1 h2) - "Sort threads by root article Lines header." - (gnus-article-sort-by-lines - (gnus-thread-header h1) (gnus-thread-header h2))) - -(defsubst gnus-article-sort-by-author (h1 h2) - "Sort articles by root author." - (string-lessp - (let ((extract (funcall - gnus-extract-address-components - (mail-header-from h1)))) - (or (car extract) (cadr extract) "")) - (let ((extract (funcall - gnus-extract-address-components - (mail-header-from h2)))) - (or (car extract) (cadr extract) "")))) - -(defun gnus-thread-sort-by-author (h1 h2) - "Sort threads by root author." - (gnus-article-sort-by-author - (gnus-thread-header h1) (gnus-thread-header h2))) - -(defsubst gnus-article-sort-by-subject (h1 h2) - "Sort articles by root subject." - (string-lessp - (downcase (gnus-simplify-subject-re (mail-header-subject h1))) - (downcase (gnus-simplify-subject-re (mail-header-subject h2))))) - -(defun gnus-thread-sort-by-subject (h1 h2) - "Sort threads by root subject." - (gnus-article-sort-by-subject - (gnus-thread-header h1) (gnus-thread-header h2))) - -(defsubst gnus-article-sort-by-date (h1 h2) - "Sort articles by root article date." - (gnus-time-less - (gnus-date-get-time (mail-header-date h1)) - (gnus-date-get-time (mail-header-date h2)))) - -(defun gnus-thread-sort-by-date (h1 h2) - "Sort threads by root article date." - (gnus-article-sort-by-date - (gnus-thread-header h1) (gnus-thread-header h2))) - -(defsubst gnus-article-sort-by-score (h1 h2) - "Sort articles by root article score. -Unscored articles will be counted as having a score of zero." - (> (or (cdr (assq (mail-header-number h1) - gnus-newsgroup-scored)) - gnus-summary-default-score 0) - (or (cdr (assq (mail-header-number h2) - gnus-newsgroup-scored)) - gnus-summary-default-score 0))) - -(defun gnus-thread-sort-by-score (h1 h2) - "Sort threads by root article score." - (gnus-article-sort-by-score - (gnus-thread-header h1) (gnus-thread-header h2))) - -(defun gnus-thread-sort-by-total-score (h1 h2) - "Sort threads by the sum of all scores in the thread. -Unscored articles will be counted as having a score of zero." - (> (gnus-thread-total-score h1) (gnus-thread-total-score h2))) - -(defun gnus-thread-total-score (thread) - ;; This function find the total score of THREAD. - (cond ((null thread) - 0) - ((consp thread) - (if (stringp (car thread)) - (apply gnus-thread-score-function 0 - (mapcar 'gnus-thread-total-score-1 (cdr thread))) - (gnus-thread-total-score-1 thread))) - (t - (gnus-thread-total-score-1 (list thread))))) - -(defun gnus-thread-total-score-1 (root) - ;; This function find the total score of the thread below ROOT. - (setq root (car root)) - (apply gnus-thread-score-function - (or (append - (mapcar 'gnus-thread-total-score - (cdr (gnus-id-to-thread (mail-header-id root)))) - (when (> (mail-header-number root) 0) - (list (or (cdr (assq (mail-header-number root) - gnus-newsgroup-scored)) - gnus-summary-default-score 0)))) - (list gnus-summary-default-score) - '(0)))) - -;; Added by Per Abrahamsen . -(defvar gnus-tmp-prev-subject nil) -(defvar gnus-tmp-false-parent nil) -(defvar gnus-tmp-root-expunged nil) -(defvar gnus-tmp-dummy-line nil) - -(defun gnus-summary-prepare-threads (threads) - "Prepare summary buffer from THREADS and indentation LEVEL. -THREADS is either a list of `(PARENT [(CHILD1 [(GRANDCHILD ...]...) ...])' -or a straight list of headers." - (gnus-message 7 "Generating summary...") - - (setq gnus-newsgroup-threads threads) - (beginning-of-line) - - (let ((gnus-tmp-level 0) - (default-score (or gnus-summary-default-score 0)) - (gnus-visual-p (gnus-visual-p 'summary-highlight 'highlight)) - thread number subject stack state gnus-tmp-gathered beg-match - new-roots gnus-tmp-new-adopts thread-end - gnus-tmp-header gnus-tmp-unread - gnus-tmp-replied gnus-tmp-subject-or-nil - gnus-tmp-dummy gnus-tmp-indentation gnus-tmp-lines gnus-tmp-score - gnus-tmp-score-char gnus-tmp-from gnus-tmp-name - gnus-tmp-number gnus-tmp-opening-bracket gnus-tmp-closing-bracket) - - (setq gnus-tmp-prev-subject nil) - - (if (vectorp (car threads)) - ;; If this is a straight (sic) list of headers, then a - ;; threaded summary display isn't required, so we just create - ;; an unthreaded one. - (gnus-summary-prepare-unthreaded threads) - - ;; Do the threaded display. - - (while (or threads stack gnus-tmp-new-adopts new-roots) - - (if (and (= gnus-tmp-level 0) - (or (not stack) - (= (caar stack) 0)) - (not gnus-tmp-false-parent) - (or gnus-tmp-new-adopts new-roots)) - (if gnus-tmp-new-adopts - (setq gnus-tmp-level (if gnus-tmp-root-expunged 0 1) - thread (list (car gnus-tmp-new-adopts)) - gnus-tmp-header (caar thread) - gnus-tmp-new-adopts (cdr gnus-tmp-new-adopts)) - (when new-roots - (setq thread (list (car new-roots)) - gnus-tmp-header (caar thread) - new-roots (cdr new-roots)))) - - (if threads - ;; If there are some threads, we do them before the - ;; threads on the stack. - (setq thread threads - gnus-tmp-header (caar thread)) - ;; There were no current threads, so we pop something off - ;; the stack. - (setq state (car stack) - gnus-tmp-level (car state) - thread (cdr state) - stack (cdr stack) - gnus-tmp-header (caar thread)))) - - (setq gnus-tmp-false-parent nil) - (setq gnus-tmp-root-expunged nil) - (setq thread-end nil) - - (if (stringp gnus-tmp-header) - ;; The header is a dummy root. - (cond - ((eq gnus-summary-make-false-root 'adopt) - ;; We let the first article adopt the rest. - (setq gnus-tmp-new-adopts (nconc gnus-tmp-new-adopts - (cddar thread))) - (setq gnus-tmp-gathered - (nconc (mapcar - (lambda (h) (mail-header-number (car h))) - (cddar thread)) - gnus-tmp-gathered)) - (setq thread (cons (list (caar thread) - (cadar thread)) - (cdr thread))) - (setq gnus-tmp-level -1 - gnus-tmp-false-parent t)) - ((eq gnus-summary-make-false-root 'empty) - ;; We print adopted articles with empty subject fields. - (setq gnus-tmp-gathered - (nconc (mapcar - (lambda (h) (mail-header-number (car h))) - (cddar thread)) - gnus-tmp-gathered)) - (setq gnus-tmp-level -1)) - ((eq gnus-summary-make-false-root 'dummy) - ;; We remember that we probably want to output a dummy - ;; root. - (setq gnus-tmp-dummy-line gnus-tmp-header) - (setq gnus-tmp-prev-subject gnus-tmp-header)) - (t - ;; We do not make a root for the gathered - ;; sub-threads at all. - (setq gnus-tmp-level -1))) - - (setq number (mail-header-number gnus-tmp-header) - subject (mail-header-subject gnus-tmp-header)) - - (cond - ;; If the thread has changed subject, we might want to make - ;; this subthread into a root. - ((and (null gnus-thread-ignore-subject) - (not (zerop gnus-tmp-level)) - gnus-tmp-prev-subject - (not (inline - (gnus-subject-equal gnus-tmp-prev-subject subject)))) - (setq new-roots (nconc new-roots (list (car thread))) - thread-end t - gnus-tmp-header nil)) - ;; If the article lies outside the current limit, - ;; then we do not display it. - ((not (memq number gnus-newsgroup-limit)) - (setq gnus-tmp-gathered - (nconc (mapcar - (lambda (h) (mail-header-number (car h))) - (cdar thread)) - gnus-tmp-gathered)) - (setq gnus-tmp-new-adopts (if (cdar thread) - (append gnus-tmp-new-adopts - (cdar thread)) - gnus-tmp-new-adopts) - thread-end t - gnus-tmp-header nil) - (when (zerop gnus-tmp-level) - (setq gnus-tmp-root-expunged t))) - ;; Perhaps this article is to be marked as read? - ((and gnus-summary-mark-below - (< (or (cdr (assq number gnus-newsgroup-scored)) - default-score) - gnus-summary-mark-below) - ;; Don't touch sparse articles. - (not (gnus-summary-article-sparse-p number)) - (not (gnus-summary-article-ancient-p number))) - (setq gnus-newsgroup-unreads - (delq number gnus-newsgroup-unreads)) - (if gnus-newsgroup-auto-expire - (push number gnus-newsgroup-expirable) - (push (cons number gnus-low-score-mark) - gnus-newsgroup-reads)))) - - (when gnus-tmp-header - ;; We may have an old dummy line to output before this - ;; article. - (when (and gnus-tmp-dummy-line - (gnus-subject-equal - gnus-tmp-dummy-line - (mail-header-subject gnus-tmp-header))) - (gnus-summary-insert-dummy-line - gnus-tmp-dummy-line (mail-header-number gnus-tmp-header)) - (setq gnus-tmp-dummy-line nil)) - - ;; Compute the mark. - (setq gnus-tmp-unread (gnus-article-mark number)) - - (push (gnus-data-make number gnus-tmp-unread (1+ (point)) - gnus-tmp-header gnus-tmp-level) - gnus-newsgroup-data) - - ;; Actually insert the line. - (setq - gnus-tmp-subject-or-nil - (cond - ((and gnus-thread-ignore-subject - gnus-tmp-prev-subject - (not (inline (gnus-subject-equal - gnus-tmp-prev-subject subject)))) - subject) - ((zerop gnus-tmp-level) - (if (and (eq gnus-summary-make-false-root 'empty) - (memq number gnus-tmp-gathered) - gnus-tmp-prev-subject - (inline (gnus-subject-equal - gnus-tmp-prev-subject subject))) - gnus-summary-same-subject - subject)) - (t gnus-summary-same-subject))) - (if (and (eq gnus-summary-make-false-root 'adopt) - (= gnus-tmp-level 1) - (memq number gnus-tmp-gathered)) - (setq gnus-tmp-opening-bracket ?\< - gnus-tmp-closing-bracket ?\>) - (setq gnus-tmp-opening-bracket ?\[ - gnus-tmp-closing-bracket ?\])) - (setq - gnus-tmp-indentation - (aref gnus-thread-indent-array gnus-tmp-level) - gnus-tmp-lines (mail-header-lines gnus-tmp-header) - gnus-tmp-score (or (cdr (assq number gnus-newsgroup-scored)) - gnus-summary-default-score 0) - gnus-tmp-score-char - (if (or (null gnus-summary-default-score) - (<= (abs (- gnus-tmp-score gnus-summary-default-score)) - gnus-summary-zcore-fuzz)) - ? - (if (< gnus-tmp-score gnus-summary-default-score) - gnus-score-below-mark gnus-score-over-mark)) - gnus-tmp-replied - (cond ((memq number gnus-newsgroup-processable) - gnus-process-mark) - ((memq number gnus-newsgroup-cached) - gnus-cached-mark) - ((memq number gnus-newsgroup-replied) - gnus-replied-mark) - ((memq number gnus-newsgroup-saved) - gnus-saved-mark) - (t gnus-unread-mark)) - gnus-tmp-from (mail-header-from gnus-tmp-header) - gnus-tmp-name - (cond - ((string-match "<[^>]+> *$" gnus-tmp-from) - (setq beg-match (match-beginning 0)) - (or (and (string-match "^\"[^\"]*\"" gnus-tmp-from) - (substring gnus-tmp-from (1+ (match-beginning 0)) - (1- (match-end 0)))) - (substring gnus-tmp-from 0 beg-match))) - ((string-match "(.+)" gnus-tmp-from) - (substring gnus-tmp-from - (1+ (match-beginning 0)) (1- (match-end 0)))) - (t gnus-tmp-from))) - (when (string= gnus-tmp-name "") - (setq gnus-tmp-name gnus-tmp-from)) - (unless (numberp gnus-tmp-lines) - (setq gnus-tmp-lines 0)) - (gnus-put-text-property-excluding-characters-with-faces - (point) - (progn (eval gnus-summary-line-format-spec) (point)) - 'gnus-number number) - (when gnus-visual-p - (forward-line -1) - (gnus-run-hooks 'gnus-summary-update-hook) - (forward-line 1)) - - (setq gnus-tmp-prev-subject subject))) - - (when (nth 1 thread) - (push (cons (max 0 gnus-tmp-level) (nthcdr 1 thread)) stack)) - (incf gnus-tmp-level) - (setq threads (if thread-end nil (cdar thread))) - (unless threads - (setq gnus-tmp-level 0))))) - (gnus-message 7 "Generating summary...done")) - -(defun gnus-summary-prepare-unthreaded (headers) - "Generate an unthreaded summary buffer based on HEADERS." - (let (header number mark) - - (beginning-of-line) - - (while headers - ;; We may have to root out some bad articles... - (when (memq (setq number (mail-header-number - (setq header (pop headers)))) - gnus-newsgroup-limit) - ;; Mark article as read when it has a low score. - (when (and gnus-summary-mark-below - (< (or (cdr (assq number gnus-newsgroup-scored)) - gnus-summary-default-score 0) - gnus-summary-mark-below) - (not (gnus-summary-article-ancient-p number))) - (setq gnus-newsgroup-unreads - (delq number gnus-newsgroup-unreads)) - (if gnus-newsgroup-auto-expire - (push number gnus-newsgroup-expirable) - (push (cons number gnus-low-score-mark) - gnus-newsgroup-reads))) - - (setq mark (gnus-article-mark number)) - (push (gnus-data-make number mark (1+ (point)) header 0) - gnus-newsgroup-data) - (gnus-summary-insert-line - header 0 number - mark (memq number gnus-newsgroup-replied) - (memq number gnus-newsgroup-expirable) - (mail-header-subject header) nil - (cdr (assq number gnus-newsgroup-scored)) - (memq number gnus-newsgroup-processable)))))) - -(defun gnus-select-newsgroup (group &optional read-all select-articles) - "Select newsgroup GROUP. -If READ-ALL is non-nil, all articles in the group are selected. -If SELECT-ARTICLES, only select those articles from GROUP." - (let* ((entry (gnus-gethash group gnus-newsrc-hashtb)) - ;;!!! Dirty hack; should be removed. - (gnus-summary-ignore-duplicates - (if (eq (car (gnus-find-method-for-group group)) 'nnvirtual) - t - gnus-summary-ignore-duplicates)) - (info (nth 2 entry)) - articles fetched-articles cached) - - (unless (gnus-check-server - (setq gnus-current-select-method - (gnus-find-method-for-group group))) - (error "Couldn't open server")) - - (or (and entry (not (eq (car entry) t))) ; Either it's active... - (gnus-activate-group group) ; Or we can activate it... - (progn ; Or we bug out. - (when (equal major-mode 'gnus-summary-mode) - (kill-buffer (current-buffer))) - (error "Couldn't request group %s: %s" - group (gnus-status-message group)))) - - (unless (gnus-request-group group t) - (when (equal major-mode 'gnus-summary-mode) - (kill-buffer (current-buffer))) - (error "Couldn't request group %s: %s" - group (gnus-status-message group))) - - (setq gnus-newsgroup-name group) - (setq gnus-newsgroup-unselected nil) - (setq gnus-newsgroup-unreads (gnus-list-of-unread-articles group)) - - ;; Adjust and set lists of article marks. - (when info - (gnus-adjust-marked-articles info)) - - ;; Kludge to avoid having cached articles nixed out in virtual groups. - (when (gnus-virtual-group-p group) - (setq cached gnus-newsgroup-cached)) - - (setq gnus-newsgroup-unreads - (gnus-set-difference - (gnus-set-difference gnus-newsgroup-unreads gnus-newsgroup-marked) - gnus-newsgroup-dormant)) - - (setq gnus-newsgroup-processable nil) - - (gnus-update-read-articles group gnus-newsgroup-unreads) - - (if (setq articles select-articles) - (setq gnus-newsgroup-unselected - (gnus-sorted-intersection - gnus-newsgroup-unreads - (gnus-sorted-complement gnus-newsgroup-unreads articles))) - (setq articles (gnus-articles-to-read group read-all))) - - (cond - ((null articles) - ;;(gnus-message 3 "Couldn't select newsgroup -- no articles to display") - 'quit) - ((eq articles 0) nil) - (t - ;; Init the dependencies hash table. - (setq gnus-newsgroup-dependencies - (gnus-make-hashtable (length articles))) - ;; Retrieve the headers and read them in. - (gnus-message 5 "Fetching headers for %s..." gnus-newsgroup-name) - (setq gnus-newsgroup-headers - (if (eq 'nov - (setq gnus-headers-retrieved-by - (gnus-retrieve-headers - articles gnus-newsgroup-name - ;; We might want to fetch old headers, but - ;; not if there is only 1 article. - (and (or (and - (not (eq gnus-fetch-old-headers 'some)) - (not (numberp gnus-fetch-old-headers))) - (> (length articles) 1)) - gnus-fetch-old-headers)))) - (gnus-get-newsgroup-headers-xover - articles nil nil gnus-newsgroup-name t) - (gnus-get-newsgroup-headers))) - (gnus-message 5 "Fetching headers for %s...done" gnus-newsgroup-name) - - ;; Kludge to avoid having cached articles nixed out in virtual groups. - (when cached - (setq gnus-newsgroup-cached cached)) - - ;; Suppress duplicates? - (when gnus-suppress-duplicates - (gnus-dup-suppress-articles)) - - ;; Set the initial limit. - (setq gnus-newsgroup-limit (copy-sequence articles)) - ;; Remove canceled articles from the list of unread articles. - (setq gnus-newsgroup-unreads - (gnus-set-sorted-intersection - gnus-newsgroup-unreads - (setq fetched-articles - (mapcar (lambda (headers) (mail-header-number headers)) - gnus-newsgroup-headers)))) - ;; Removed marked articles that do not exist. - (gnus-update-missing-marks - (gnus-sorted-complement fetched-articles articles)) - ;; We might want to build some more threads first. - (when (and gnus-fetch-old-headers - (eq gnus-headers-retrieved-by 'nov)) - (if (eq gnus-fetch-old-headers 'invisible) - (gnus-build-all-threads) - (gnus-build-old-threads))) - ;; Let the Gnus agent mark articles as read. - (when gnus-agent - (gnus-agent-get-undownloaded-list)) - ;; Check whether auto-expire is to be done in this group. - (setq gnus-newsgroup-auto-expire - (gnus-group-auto-expirable-p group)) - ;; Set up the article buffer now, if necessary. - (unless gnus-single-article-buffer - (gnus-article-setup-buffer)) - ;; First and last article in this newsgroup. - (when gnus-newsgroup-headers - (setq gnus-newsgroup-begin - (mail-header-number (car gnus-newsgroup-headers)) - gnus-newsgroup-end - (mail-header-number - (gnus-last-element gnus-newsgroup-headers)))) - ;; GROUP is successfully selected. - (or gnus-newsgroup-headers t))))) - -(defun gnus-articles-to-read (group &optional read-all) - ;; Find out what articles the user wants to read. - (let* ((articles - ;; Select all articles if `read-all' is non-nil, or if there - ;; are no unread articles. - (if (or read-all - (and (zerop (length gnus-newsgroup-marked)) - (zerop (length gnus-newsgroup-unreads))) - (eq (gnus-group-find-parameter group 'display) - 'all)) - (gnus-uncompress-range (gnus-active group)) - (sort (append gnus-newsgroup-dormant gnus-newsgroup-marked - (copy-sequence gnus-newsgroup-unreads)) - '<))) - (scored-list (gnus-killed-articles gnus-newsgroup-killed articles)) - (scored (length scored-list)) - (number (length articles)) - (marked (+ (length gnus-newsgroup-marked) - (length gnus-newsgroup-dormant))) - (select - (cond - ((numberp read-all) - read-all) - (t - (condition-case () - (cond - ((and (or (<= scored marked) (= scored number)) - (numberp gnus-large-newsgroup) - (> number gnus-large-newsgroup)) - (let ((input - (read-string - (format - "How many articles from %s (default %d): " - (gnus-limit-string gnus-newsgroup-name 35) - number)))) - (if (string-match "^[ \t]*$" input) number input))) - ((and (> scored marked) (< scored number) - (> (- scored number) 20)) - (let ((input - (read-string - (format "%s %s (%d scored, %d total): " - "How many articles from" - group scored number)))) - (if (string-match "^[ \t]*$" input) - number input))) - (t number)) - (quit nil)))))) - (setq select (if (stringp select) (string-to-number select) select)) - (if (or (null select) (zerop select)) - select - (if (and (not (zerop scored)) (<= (abs select) scored)) - (progn - (setq articles (sort scored-list '<)) - (setq number (length articles))) - (setq articles (copy-sequence articles))) - - (when (< (abs select) number) - (if (< select 0) - ;; Select the N oldest articles. - (setcdr (nthcdr (1- (abs select)) articles) nil) - ;; Select the N most recent articles. - (setq articles (nthcdr (- number select) articles)))) - (setq gnus-newsgroup-unselected - (gnus-sorted-intersection - gnus-newsgroup-unreads - (gnus-sorted-complement gnus-newsgroup-unreads articles))) - articles))) - -(defun gnus-killed-articles (killed articles) - (let (out) - (while articles - (when (inline (gnus-member-of-range (car articles) killed)) - (push (car articles) out)) - (setq articles (cdr articles))) - out)) - -(defun gnus-uncompress-marks (marks) - "Uncompress the mark ranges in MARKS." - (let ((uncompressed '(score bookmark)) - out) - (while marks - (if (memq (caar marks) uncompressed) - (push (car marks) out) - (push (cons (caar marks) (gnus-uncompress-range (cdar marks))) out)) - (setq marks (cdr marks))) - out)) - -(defun gnus-adjust-marked-articles (info) - "Set all article lists and remove all marks that are no longer legal." - (let* ((marked-lists (gnus-info-marks info)) - (active (gnus-active (gnus-info-group info))) - (min (car active)) - (max (cdr active)) - (types gnus-article-mark-lists) - (uncompressed '(score bookmark killed)) - marks var articles article mark) - - (while marked-lists - (setq marks (pop marked-lists)) - (set (setq var (intern (format "gnus-newsgroup-%s" - (car (rassq (setq mark (car marks)) - types))))) - (if (memq (car marks) uncompressed) (cdr marks) - (gnus-uncompress-range (cdr marks)))) - - (setq articles (symbol-value var)) - - ;; All articles have to be subsets of the active articles. - (cond - ;; Adjust "simple" lists. - ((memq mark '(tick dormant expire reply save)) - (while articles - (when (or (< (setq article (pop articles)) min) (> article max)) - (set var (delq article (symbol-value var)))))) - ;; Adjust assocs. - ((memq mark uncompressed) - (when (not (listp (cdr (symbol-value var)))) - (set var (list (symbol-value var)))) - (when (not (listp (cdr articles))) - (setq articles (list articles))) - (while articles - (when (or (not (consp (setq article (pop articles)))) - (< (car article) min) - (> (car article) max)) - (set var (delq article (symbol-value var)))))))))) - -(defun gnus-update-missing-marks (missing) - "Go through the list of MISSING articles and remove them from the mark lists." - (when missing - (let ((types gnus-article-mark-lists) - var m) - ;; Go through all types. - (while types - (setq var (intern (format "gnus-newsgroup-%s" (car (pop types))))) - (when (symbol-value var) - ;; This list has articles. So we delete all missing articles - ;; from it. - (setq m missing) - (while m - (set var (delq (pop m) (symbol-value var))))))))) - -(defun gnus-update-marks () - "Enter the various lists of marked articles into the newsgroup info list." - (let ((types gnus-article-mark-lists) - (info (gnus-get-info gnus-newsgroup-name)) - (uncompressed '(score bookmark killed)) - type list newmarked symbol) - (when info - ;; Add all marks lists that are non-nil to the list of marks lists. - (while (setq type (pop types)) - (when (setq list (symbol-value - (setq symbol - (intern (format "gnus-newsgroup-%s" - (car type)))))) - - ;; Get rid of the entries of the articles that have the - ;; default score. - (when (and (eq (cdr type) 'score) - gnus-save-score - list) - (let* ((arts list) - (prev (cons nil list)) - (all prev)) - (while arts - (if (or (not (consp (car arts))) - (= (cdar arts) gnus-summary-default-score)) - (setcdr prev (cdr arts)) - (setq prev arts)) - (setq arts (cdr arts))) - (setq list (cdr all)))) - - (push (cons (cdr type) - (if (memq (cdr type) uncompressed) list - (gnus-compress-sequence - (set symbol (sort list '<)) t))) - newmarked))) - - ;; Enter these new marks into the info of the group. - (if (nthcdr 3 info) - (setcar (nthcdr 3 info) newmarked) - ;; Add the marks lists to the end of the info. - (when newmarked - (setcdr (nthcdr 2 info) (list newmarked)))) - - ;; Cut off the end of the info if there's nothing else there. - (let ((i 5)) - (while (and (> i 2) - (not (nth i info))) - (when (nthcdr (decf i) info) - (setcdr (nthcdr i info) nil))))))) - -(defun gnus-set-mode-line (where) - "This function sets the mode line of the article or summary buffers. -If WHERE is `summary', the summary mode line format will be used." - ;; Is this mode line one we keep updated? - (when (memq where gnus-updated-mode-lines) - (let (mode-string) - (save-excursion - ;; We evaluate this in the summary buffer since these - ;; variables are buffer-local to that buffer. - (set-buffer gnus-summary-buffer) - ;; We bind all these variables that are used in the `eval' form - ;; below. - (let* ((mformat (symbol-value - (intern - (format "gnus-%s-mode-line-format-spec" where)))) - (gnus-tmp-group-name gnus-newsgroup-name) - (gnus-tmp-article-number (or gnus-current-article 0)) - (gnus-tmp-unread gnus-newsgroup-unreads) - (gnus-tmp-unread-and-unticked (length gnus-newsgroup-unreads)) - (gnus-tmp-unselected (length gnus-newsgroup-unselected)) - (gnus-tmp-unread-and-unselected - (cond ((and (zerop gnus-tmp-unread-and-unticked) - (zerop gnus-tmp-unselected)) - "") - ((zerop gnus-tmp-unselected) - (format "{%d more}" gnus-tmp-unread-and-unticked)) - (t (format "{%d(+%d) more}" - gnus-tmp-unread-and-unticked - gnus-tmp-unselected)))) - (gnus-tmp-subject - (if (and gnus-current-headers - (vectorp gnus-current-headers)) - (gnus-mode-string-quote - (mail-header-subject gnus-current-headers)) - "")) - bufname-length max-len - gnus-tmp-header);; passed as argument to any user-format-funcs - (setq mode-string (eval mformat)) - (setq bufname-length (if (string-match "%b" mode-string) - (- (length - (buffer-name - (if (eq where 'summary) - nil - (get-buffer gnus-article-buffer)))) - 2) - 0)) - (setq max-len (max 4 (if gnus-mode-non-string-length - (- (window-width) - gnus-mode-non-string-length - bufname-length) - (length mode-string)))) - ;; We might have to chop a bit of the string off... - (when (> (length mode-string) max-len) - (setq mode-string - (concat (gnus-truncate-string mode-string (- max-len 3)) - "..."))) - ;; Pad the mode string a bit. - (setq mode-string (format (format "%%-%ds" max-len) mode-string)))) - ;; Update the mode line. - (setq mode-line-buffer-identification - (gnus-mode-line-buffer-identification (list mode-string))) - (set-buffer-modified-p t)))) - -(defun gnus-create-xref-hashtb (from-newsgroup headers unreads) - "Go through the HEADERS list and add all Xrefs to a hash table. -The resulting hash table is returned, or nil if no Xrefs were found." - (let* ((virtual (gnus-virtual-group-p from-newsgroup)) - (prefix (if virtual "" (gnus-group-real-prefix from-newsgroup))) - (xref-hashtb (gnus-make-hashtable)) - start group entry number xrefs header) - (while headers - (setq header (pop headers)) - (when (and (setq xrefs (mail-header-xref header)) - (not (memq (setq number (mail-header-number header)) - unreads))) - (setq start 0) - (while (string-match "\\([^ ]+\\)[:/]\\([0-9]+\\)" xrefs start) - (setq start (match-end 0)) - (setq group (if prefix - (concat prefix (substring xrefs (match-beginning 1) - (match-end 1))) - (substring xrefs (match-beginning 1) (match-end 1)))) - (setq number - (string-to-int (substring xrefs (match-beginning 2) - (match-end 2)))) - (if (setq entry (gnus-gethash group xref-hashtb)) - (setcdr entry (cons number (cdr entry))) - (gnus-sethash group (cons number nil) xref-hashtb))))) - (and start xref-hashtb))) - -(defun gnus-mark-xrefs-as-read (from-newsgroup headers unreads) - "Look through all the headers and mark the Xrefs as read." - (let ((virtual (gnus-virtual-group-p from-newsgroup)) - name entry info xref-hashtb idlist method nth4) - (save-excursion - (set-buffer gnus-group-buffer) - (when (setq xref-hashtb - (gnus-create-xref-hashtb from-newsgroup headers unreads)) - (mapatoms - (lambda (group) - (unless (string= from-newsgroup (setq name (symbol-name group))) - (setq idlist (symbol-value group)) - ;; Dead groups are not updated. - (and (prog1 - (setq entry (gnus-gethash name gnus-newsrc-hashtb) - info (nth 2 entry)) - (when (stringp (setq nth4 (gnus-info-method info))) - (setq nth4 (gnus-server-to-method nth4)))) - ;; Only do the xrefs if the group has the same - ;; select method as the group we have just read. - (or (gnus-methods-equal-p - nth4 (gnus-find-method-for-group from-newsgroup)) - virtual - (equal nth4 (setq method (gnus-find-method-for-group - from-newsgroup))) - (and (equal (car nth4) (car method)) - (equal (nth 1 nth4) (nth 1 method)))) - gnus-use-cross-reference - (or (not (eq gnus-use-cross-reference t)) - virtual - ;; Only do cross-references on subscribed - ;; groups, if that is what is wanted. - (<= (gnus-info-level info) gnus-level-subscribed)) - (gnus-group-make-articles-read name idlist)))) - xref-hashtb))))) - -(defun gnus-compute-read-articles (group articles) - (let* ((entry (gnus-gethash group gnus-newsrc-hashtb)) - (info (nth 2 entry)) - (active (gnus-active group)) - ninfo) - (when entry - ;; First peel off all illegal article numbers. - (when active - (let ((ids articles) - id first) - (while (setq id (pop ids)) - (when (and first (> id (cdr active))) - ;; We'll end up in this situation in one particular - ;; obscure situation. If you re-scan a group and get - ;; a new article that is cross-posted to a different - ;; group that has not been re-scanned, you might get - ;; crossposted article that has a higher number than - ;; Gnus believes possible. So we re-activate this - ;; group as well. This might mean doing the - ;; crossposting thingy will *increase* the number - ;; of articles in some groups. Tsk, tsk. - (setq active (or (gnus-activate-group group) active))) - (when (or (> id (cdr active)) - (< id (car active))) - (setq articles (delq id articles)))))) - ;; If the read list is nil, we init it. - (if (and active - (null (gnus-info-read info)) - (> (car active) 1)) - (setq ninfo (cons 1 (1- (car active)))) - (setq ninfo (gnus-info-read info))) - ;; Then we add the read articles to the range. - (gnus-add-to-range - ninfo (setq articles (sort articles '<)))))) - -(defun gnus-group-make-articles-read (group articles) - "Update the info of GROUP to say that ARTICLES are read." - (let* ((num 0) - (entry (gnus-gethash group gnus-newsrc-hashtb)) - (info (nth 2 entry)) - (active (gnus-active group)) - range) - (when entry - (setq range (gnus-compute-read-articles group articles)) - (save-excursion - (set-buffer gnus-group-buffer) - (gnus-undo-register - `(progn - (gnus-info-set-marks ',info ',(gnus-info-marks info) t) - (gnus-info-set-read ',info ',(gnus-info-read info)) - (gnus-get-unread-articles-in-group ',info (gnus-active ,group)) - (gnus-group-update-group ,group t)))) - ;; Add the read articles to the range. - (gnus-info-set-read info range) - ;; Then we have to re-compute how many unread - ;; articles there are in this group. - (when active - (cond - ((not range) - (setq num (- (1+ (cdr active)) (car active)))) - ((not (listp (cdr range))) - (setq num (- (cdr active) (- (1+ (cdr range)) - (car range))))) - (t - (while range - (if (numberp (car range)) - (setq num (1+ num)) - (setq num (+ num (- (1+ (cdar range)) (caar range))))) - (setq range (cdr range))) - (setq num (- (cdr active) num)))) - ;; Update the number of unread articles. - (setcar entry num) - ;; Update the group buffer. - (gnus-group-update-group group t))))) - -(defun gnus-methods-equal-p (m1 m2) - (let ((m1 (or m1 gnus-select-method)) - (m2 (or m2 gnus-select-method))) - (or (equal m1 m2) - (and (eq (car m1) (car m2)) - (or (not (memq 'address (assoc (symbol-name (car m1)) - gnus-valid-select-methods))) - (equal (nth 1 m1) (nth 1 m2))))))) - -(defvar gnus-newsgroup-none-id 0) - -(defun gnus-get-newsgroup-headers (&optional dependencies force-new) - (let ((cur nntp-server-buffer) - (dependencies - (or dependencies - (save-excursion (set-buffer gnus-summary-buffer) - gnus-newsgroup-dependencies))) - headers id end ref) - (save-excursion - (set-buffer nntp-server-buffer) - ;; Translate all TAB characters into SPACE characters. - (subst-char-in-region (point-min) (point-max) ?\t ? t) - (gnus-run-hooks 'gnus-parse-headers-hook) - (let ((case-fold-search t) - in-reply-to header p lines chars ctype) - (goto-char (point-min)) - ;; Search to the beginning of the next header. Error messages - ;; do not begin with 2 or 3. - (while (re-search-forward "^[23][0-9]+ " nil t) - (setq id nil - ref nil) - ;; This implementation of this function, with nine - ;; search-forwards instead of the one re-search-forward and - ;; a case (which basically was the old function) is actually - ;; about twice as fast, even though it looks messier. You - ;; can't have everything, I guess. Speed and elegance - ;; doesn't always go hand in hand. - (setq - header - (make-full-mail-header - ;; Number. - (prog1 - (read cur) - (end-of-line) - (setq p (point)) - (narrow-to-region (point) - (or (and (search-forward "\n.\n" nil t) - (- (point) 2)) - (point)))) - ;; Subject. - (progn - (goto-char p) - (if (search-forward "\nsubject: " nil t) - (nnheader-header-value) - "(none)")) - ;; From. - (progn - (goto-char p) - (if (search-forward "\nfrom: " nil t) - (nnheader-header-value) - "(nobody)")) - ;; Date. - (progn - (goto-char p) - (if (search-forward "\ndate: " nil t) - (nnheader-header-value) "")) - ;; Message-ID. - (progn - (goto-char p) - (setq id (if (re-search-forward - "^message-id: *\\(<[^\n\t> ]+>\\)" nil t) - ;; We do it this way to make sure the Message-ID - ;; is (somewhat) syntactically valid. - (buffer-substring (match-beginning 1) - (match-end 1)) - ;; If there was no message-id, we just fake one - ;; to make subsequent routines simpler. - (nnheader-generate-fake-message-id)))) - ;; References. - (progn - (goto-char p) - (if (search-forward "\nreferences: " nil t) - (progn - (setq end (point)) - (prog1 - (nnheader-header-value) - (setq ref - (buffer-substring - (progn - (end-of-line) - (search-backward ">" end t) - (1+ (point))) - (progn - (search-backward "<" end t) - (point)))))) - ;; Get the references from the in-reply-to header if there - ;; were no references and the in-reply-to header looks - ;; promising. - (if (and (search-forward "\nin-reply-to: " nil t) - (setq in-reply-to (nnheader-header-value)) - (string-match "<[^>]+>" in-reply-to)) - (let (ref2) - (setq ref (substring in-reply-to (match-beginning 0) - (match-end 0))) - (while (string-match "<[^>]+>" in-reply-to (match-end 0)) - (setq ref2 (substring in-reply-to (match-beginning 0) - (match-end 0))) - (when (> (length ref2) (length ref)) - (setq ref ref2))) - ref) - (setq ref nil)))) - ;; Chars. - (progn - (goto-char p) - (if (search-forward "\nchars: " nil t) - (if (numberp (setq chars (ignore-errors (read cur)))) - chars 0) - 0)) - ;; Lines. - (progn - (goto-char p) - (if (search-forward "\nlines: " nil t) - (if (numberp (setq lines (ignore-errors (read cur)))) - lines 0) - 0)) - ;; Xref. - (progn - (goto-char p) - (and (search-forward "\nxref: " nil t) - (nnheader-header-value))))) - (goto-char p) - (if (and (search-forward "\ncontent-type: " nil t) - (setq ctype (nnheader-header-value))) - (mime-entity-set-content-type-internal - header (mime-parse-Content-Type ctype))) - (when (equal id ref) - (setq ref nil)) - - (when gnus-alter-header-function - (funcall gnus-alter-header-function header) - (setq id (mail-header-id header) - ref (gnus-parent-id (mail-header-references header)))) - - (when (setq header - (gnus-dependencies-add-header - header dependencies force-new)) - (push header headers)) - (goto-char (point-max)) - (widen)) - (nreverse headers))))) - -;; Goes through the xover lines and returns a list of vectors -(defun gnus-get-newsgroup-headers-xover (sequence &optional - force-new dependencies - group also-fetch-heads) - "Parse the news overview data in the server buffer, and return a -list of headers that match SEQUENCE (see `nntp-retrieve-headers')." - ;; Get the Xref when the users reads the articles since most/some - ;; NNTP servers do not include Xrefs when using XOVER. - (setq gnus-article-internal-prepare-hook '(gnus-article-get-xrefs)) - (let ((cur nntp-server-buffer) - (dependencies (or dependencies gnus-newsgroup-dependencies)) - number headers header) - (save-excursion - (set-buffer nntp-server-buffer) - ;; Allow the user to mangle the headers before parsing them. - (gnus-run-hooks 'gnus-parse-headers-hook) - (goto-char (point-min)) - (while (not (eobp)) - (condition-case () - (while (and sequence (not (eobp))) - (setq number (read cur)) - (while (and sequence - (< (car sequence) number)) - (setq sequence (cdr sequence))) - (and sequence - (eq number (car sequence)) - (progn - (setq sequence (cdr sequence)) - (setq header (inline - (gnus-nov-parse-line - number dependencies force-new)))) - (push header headers)) - (forward-line 1)) - (error - (gnus-error 4 "Strange nov line (%d)" - (count-lines (point-min) (point))))) - (forward-line 1)) - ;; A common bug in inn is that if you have posted an article and - ;; then retrieves the active file, it will answer correctly -- - ;; the new article is included. However, a NOV entry for the - ;; article may not have been generated yet, so this may fail. - ;; We work around this problem by retrieving the last few - ;; headers using HEAD. - (if (or (not also-fetch-heads) - (not sequence)) - ;; We (probably) got all the headers. - (nreverse headers) - (let ((gnus-nov-is-evil t)) - (nconc - (nreverse headers) - (when (gnus-retrieve-headers sequence group) - (gnus-get-newsgroup-headers)))))))) - -(defun gnus-article-get-xrefs () - "Fill in the Xref value in `gnus-current-headers', if necessary. -This is meant to be called in `gnus-article-internal-prepare-hook'." - (let ((headers (save-excursion (set-buffer gnus-summary-buffer) - gnus-current-headers))) - (or (not gnus-use-cross-reference) - (not headers) - (and (mail-header-xref headers) - (not (string= (mail-header-xref headers) ""))) - (let ((case-fold-search t) - xref) - (save-restriction - (nnheader-narrow-to-headers) - (goto-char (point-min)) - (when (or (and (eq (downcase (following-char)) ?x) - (looking-at "Xref:")) - (search-forward "\nXref:" nil t)) - (goto-char (1+ (match-end 0))) - (setq xref (buffer-substring (point) - (progn (end-of-line) (point)))) - (mail-header-set-xref headers xref))))))) - -(defun gnus-summary-insert-subject (id &optional old-header use-old-header) - "Find article ID and insert the summary line for that article. -OLD-HEADER can either be a header or a line number to insert -the subject line on." - (let* ((line (and (numberp old-header) old-header)) - (old-header (and (vectorp old-header) old-header)) - (header (cond ((and old-header use-old-header) - old-header) - ((and (numberp id) - (gnus-number-to-header id)) - (gnus-number-to-header id)) - (t - (gnus-read-header id)))) - (number (and (numberp id) id)) - d) - (when header - ;; Rebuild the thread that this article is part of and go to the - ;; article we have fetched. - (when (and (not gnus-show-threads) - old-header) - (when (and number - (setq d (gnus-data-find (mail-header-number old-header)))) - (goto-char (gnus-data-pos d)) - (gnus-data-remove - number - (- (gnus-point-at-bol) - (prog1 - (1+ (gnus-point-at-eol)) - (gnus-delete-line)))))) - (when old-header - (mail-header-set-number header (mail-header-number old-header))) - (setq gnus-newsgroup-sparse - (delq (setq number (mail-header-number header)) - gnus-newsgroup-sparse)) - (setq gnus-newsgroup-ancient (delq number gnus-newsgroup-ancient)) - (push number gnus-newsgroup-limit) - (gnus-rebuild-thread (mail-header-id header) line) - (gnus-summary-goto-subject number nil t)) - (when (and (numberp number) - (> number 0)) - ;; We have to update the boundaries even if we can't fetch the - ;; article if ID is a number -- so that the next `P' or `N' - ;; command will fetch the previous (or next) article even - ;; if the one we tried to fetch this time has been canceled. - (when (> number gnus-newsgroup-end) - (setq gnus-newsgroup-end number)) - (when (< number gnus-newsgroup-begin) - (setq gnus-newsgroup-begin number)) - (setq gnus-newsgroup-unselected - (delq number gnus-newsgroup-unselected))) - ;; Report back a success? - (and header (mail-header-number header)))) - -;;; Process/prefix in the summary buffer - -(defun gnus-summary-work-articles (n) - "Return a list of articles to be worked upon. -The prefix argument, the list of process marked articles, and the -current article will be taken into consideration." - (save-excursion - (set-buffer gnus-summary-buffer) - (cond - (n - ;; A numerical prefix has been given. - (setq n (prefix-numeric-value n)) - (let ((backward (< n 0)) - (n (abs (prefix-numeric-value n))) - articles article) - (save-excursion - (while - (and (> n 0) - (push (setq article (gnus-summary-article-number)) - articles) - (if backward - (gnus-summary-find-prev nil article) - (gnus-summary-find-next nil article))) - (decf n))) - (nreverse articles))) - ((and (gnus-region-active-p) (mark)) - (message "region active") - ;; Work on the region between point and mark. - (let ((max (max (point) (mark))) - articles article) - (save-excursion - (goto-char (min (point) (mark))) - (while - (and - (push (setq article (gnus-summary-article-number)) articles) - (gnus-summary-find-next nil article) - (< (point) max))) - (nreverse articles)))) - (gnus-newsgroup-processable - ;; There are process-marked articles present. - ;; Save current state. - (gnus-summary-save-process-mark) - ;; Return the list. - (reverse gnus-newsgroup-processable)) - (t - ;; Just return the current article. - (list (gnus-summary-article-number)))))) - -(defmacro gnus-summary-iterate (arg &rest forms) - "Iterate over the process/prefixed articles and do FORMS. -ARG is the interactive prefix given to the command. FORMS will be -executed with point over the summary line of the articles." - (let ((articles (make-symbol "gnus-summary-iterate-articles"))) - `(let ((,articles (gnus-summary-work-articles ,arg))) - (while ,articles - (gnus-summary-goto-subject (car ,articles)) - ,@forms)))) - -(put 'gnus-summary-iterate 'lisp-indent-function 1) -(put 'gnus-summary-iterate 'edebug-form-spec '(form body)) - -(defun gnus-summary-save-process-mark () - "Push the current set of process marked articles on the stack." - (interactive) - (push (copy-sequence gnus-newsgroup-processable) - gnus-newsgroup-process-stack)) - -(defun gnus-summary-kill-process-mark () - "Push the current set of process marked articles on the stack and unmark." - (interactive) - (gnus-summary-save-process-mark) - (gnus-summary-unmark-all-processable)) - -(defun gnus-summary-yank-process-mark () - "Pop the last process mark state off the stack and restore it." - (interactive) - (unless gnus-newsgroup-process-stack - (error "Empty mark stack")) - (gnus-summary-process-mark-set (pop gnus-newsgroup-process-stack))) - -(defun gnus-summary-process-mark-set (set) - "Make SET into the current process marked articles." - (gnus-summary-unmark-all-processable) - (while set - (gnus-summary-set-process-mark (pop set)))) - -;;; Searching and stuff - -(defun gnus-summary-search-group (&optional backward use-level) - "Search for next unread newsgroup. -If optional argument BACKWARD is non-nil, search backward instead." - (save-excursion - (set-buffer gnus-group-buffer) - (when (gnus-group-search-forward - backward nil (if use-level (gnus-group-group-level) nil)) - (gnus-group-group-name)))) - -(defun gnus-summary-best-group (&optional exclude-group) - "Find the name of the best unread group. -If EXCLUDE-GROUP, do not go to this group." - (save-excursion - (set-buffer gnus-group-buffer) - (save-excursion - (gnus-group-best-unread-group exclude-group)))) - -(defun gnus-summary-find-next (&optional unread article backward undownloaded) - (if backward (gnus-summary-find-prev) - (let* ((dummy (gnus-summary-article-intangible-p)) - (article (or article (gnus-summary-article-number))) - (arts (gnus-data-find-list article)) - result) - (when (and (not dummy) - (or (not gnus-summary-check-current) - (not unread) - (not (gnus-data-unread-p (car arts))))) - (setq arts (cdr arts))) - (when (setq result - (if unread - (progn - (while arts - (when (or (and undownloaded - (eq gnus-undownloaded-mark - (gnus-data-mark (car arts)))) - (gnus-data-unread-p (car arts))) - (setq result (car arts) - arts nil)) - (setq arts (cdr arts))) - result) - (car arts))) - (goto-char (gnus-data-pos result)) - (gnus-data-number result))))) - -(defun gnus-summary-find-prev (&optional unread article) - (let* ((eobp (eobp)) - (article (or article (gnus-summary-article-number))) - (arts (gnus-data-find-list article (gnus-data-list 'rev))) - result) - (when (and (not eobp) - (or (not gnus-summary-check-current) - (not unread) - (not (gnus-data-unread-p (car arts))))) - (setq arts (cdr arts))) - (when (setq result - (if unread - (progn - (while arts - (when (gnus-data-unread-p (car arts)) - (setq result (car arts) - arts nil)) - (setq arts (cdr arts))) - result) - (car arts))) - (goto-char (gnus-data-pos result)) - (gnus-data-number result)))) - -(defun gnus-summary-find-subject (subject &optional unread backward article) - (let* ((simp-subject (gnus-simplify-subject-fully subject)) - (article (or article (gnus-summary-article-number))) - (articles (gnus-data-list backward)) - (arts (gnus-data-find-list article articles)) - result) - (when (or (not gnus-summary-check-current) - (not unread) - (not (gnus-data-unread-p (car arts)))) - (setq arts (cdr arts))) - (while arts - (and (or (not unread) - (gnus-data-unread-p (car arts))) - (vectorp (gnus-data-header (car arts))) - (gnus-subject-equal - simp-subject (mail-header-subject (gnus-data-header (car arts))) t) - (setq result (car arts) - arts nil)) - (setq arts (cdr arts))) - (and result - (goto-char (gnus-data-pos result)) - (gnus-data-number result)))) - -(defun gnus-summary-search-forward (&optional unread subject backward) - "Search forward for an article. -If UNREAD, look for unread articles. If SUBJECT, look for -articles with that subject. If BACKWARD, search backward instead." - (cond (subject (gnus-summary-find-subject subject unread backward)) - (backward (gnus-summary-find-prev unread)) - (t (gnus-summary-find-next unread)))) - -(defun gnus-recenter (&optional n) - "Center point in window and redisplay frame. -Also do horizontal recentering." - (interactive "P") - (when (and gnus-auto-center-summary - (not (eq gnus-auto-center-summary 'vertical))) - (gnus-horizontal-recenter)) - (recenter n)) - -(defun gnus-summary-recenter () - "Center point in the summary window. -If `gnus-auto-center-summary' is nil, or the article buffer isn't -displayed, no centering will be performed." - ;; Suggested by earle@mahendo.JPL.NASA.GOV (Greg Earle). - ;; Recenter only when requested. Suggested by popovich@park.cs.columbia.edu. - (let* ((top (cond ((< (window-height) 4) 0) - ((< (window-height) 7) 1) - (t 2))) - (height (1- (window-height))) - (bottom (save-excursion (goto-char (point-max)) - (forward-line (- height)) - (point))) - (window (get-buffer-window (current-buffer)))) - ;; The user has to want it. - (when gnus-auto-center-summary - (when (get-buffer-window gnus-article-buffer) - ;; Only do recentering when the article buffer is displayed, - ;; Set the window start to either `bottom', which is the biggest - ;; possible valid number, or the second line from the top, - ;; whichever is the least. - (set-window-start - window (min bottom (save-excursion - (forward-line (- top)) (point))))) - ;; Do horizontal recentering while we're at it. - (when (and (get-buffer-window (current-buffer) t) - (not (eq gnus-auto-center-summary 'vertical))) - (let ((selected (selected-window))) - (select-window (get-buffer-window (current-buffer) t)) - (gnus-summary-position-point) - (gnus-horizontal-recenter) - (select-window selected)))))) - -(defun gnus-summary-jump-to-group (newsgroup) - "Move point to NEWSGROUP in group mode buffer." - ;; Keep update point of group mode buffer if visible. - (if (eq (current-buffer) (get-buffer gnus-group-buffer)) - (save-window-excursion - ;; Take care of tree window mode. - (when (get-buffer-window gnus-group-buffer) - (pop-to-buffer gnus-group-buffer)) - (gnus-group-jump-to-group newsgroup)) - (save-excursion - ;; Take care of tree window mode. - (if (get-buffer-window gnus-group-buffer) - (pop-to-buffer gnus-group-buffer) - (set-buffer gnus-group-buffer)) - (gnus-group-jump-to-group newsgroup)))) - -;; This function returns a list of article numbers based on the -;; difference between the ranges of read articles in this group and -;; the range of active articles. -(defun gnus-list-of-unread-articles (group) - (let* ((read (gnus-info-read (gnus-get-info group))) - (active (or (gnus-active group) (gnus-activate-group group))) - (last (cdr active)) - first nlast unread) - ;; If none are read, then all are unread. - (if (not read) - (setq first (car active)) - ;; If the range of read articles is a single range, then the - ;; first unread article is the article after the last read - ;; article. Sounds logical, doesn't it? - (if (not (listp (cdr read))) - (setq first (max (car active) (1+ (cdr read)))) - ;; `read' is a list of ranges. - (when (/= (setq nlast (or (and (numberp (car read)) (car read)) - (caar read))) - 1) - (setq first (car active))) - (while read - (when first - (while (< first nlast) - (push first unread) - (setq first (1+ first)))) - (setq first (1+ (if (atom (car read)) (car read) (cdar read)))) - (setq nlast (if (atom (cadr read)) (cadr read) (caadr read))) - (setq read (cdr read))))) - ;; And add the last unread articles. - (while (<= first last) - (push first unread) - (setq first (1+ first))) - ;; Return the list of unread articles. - (delq 0 (nreverse unread)))) - -(defun gnus-list-of-read-articles (group) - "Return a list of unread, unticked and non-dormant articles." - (let* ((info (gnus-get-info group)) - (marked (gnus-info-marks info)) - (active (gnus-active group))) - (and info active - (gnus-set-difference - (gnus-sorted-complement - (gnus-uncompress-range active) - (gnus-list-of-unread-articles group)) - (append - (gnus-uncompress-range (cdr (assq 'dormant marked))) - (gnus-uncompress-range (cdr (assq 'tick marked)))))))) - -;; Various summary commands - -(defun gnus-summary-select-article-buffer () - "Reconfigure windows to show article buffer." - (interactive) - (if (not (gnus-buffer-live-p gnus-article-buffer)) - (error "There is no article buffer for this summary buffer") - (gnus-configure-windows 'article) - (select-window (get-buffer-window gnus-article-buffer)))) - -(defun gnus-summary-universal-argument (arg) - "Perform any operation on all articles that are process/prefixed." - (interactive "P") - (let ((articles (gnus-summary-work-articles arg)) - func article) - (if (eq - (setq - func - (key-binding - (read-key-sequence - (substitute-command-keys - "\\\\[gnus-summary-universal-argument]" - )))) - 'undefined) - (gnus-error 1 "Undefined key") - (save-excursion - (while articles - (gnus-summary-goto-subject (setq article (pop articles))) - (let (gnus-newsgroup-processable) - (command-execute func)) - (gnus-summary-remove-process-mark article))))) - (gnus-summary-position-point)) - -(defun gnus-summary-toggle-truncation (&optional arg) - "Toggle truncation of summary lines. -With arg, turn line truncation on iff arg is positive." - (interactive "P") - (setq truncate-lines - (if (null arg) (not truncate-lines) - (> (prefix-numeric-value arg) 0))) - (redraw-display)) - -(defun gnus-summary-reselect-current-group (&optional all rescan) - "Exit and then reselect the current newsgroup. -The prefix argument ALL means to select all articles." - (interactive "P") - (when (gnus-ephemeral-group-p gnus-newsgroup-name) - (error "Ephemeral groups can't be reselected")) - (let ((current-subject (gnus-summary-article-number)) - (group gnus-newsgroup-name)) - (setq gnus-newsgroup-begin nil) - (gnus-summary-exit) - ;; We have to adjust the point of group mode buffer because - ;; point was moved to the next unread newsgroup by exiting. - (gnus-summary-jump-to-group group) - (when rescan - (save-excursion - (gnus-group-get-new-news-this-group 1))) - (gnus-group-read-group all t) - (gnus-summary-goto-subject current-subject nil t))) - -(defun gnus-summary-rescan-group (&optional all) - "Exit the newsgroup, ask for new articles, and select the newsgroup." - (interactive "P") - (gnus-summary-reselect-current-group all t)) - -(defun gnus-summary-update-info (&optional non-destructive) - (save-excursion - (let ((group gnus-newsgroup-name)) - (when group - (when gnus-newsgroup-kill-headers - (setq gnus-newsgroup-killed - (gnus-compress-sequence - (nconc - (gnus-set-sorted-intersection - (gnus-uncompress-range gnus-newsgroup-killed) - (setq gnus-newsgroup-unselected - (sort gnus-newsgroup-unselected '<))) - (setq gnus-newsgroup-unreads - (sort gnus-newsgroup-unreads '<))) - t))) - (unless (listp (cdr gnus-newsgroup-killed)) - (setq gnus-newsgroup-killed (list gnus-newsgroup-killed))) - (let ((headers gnus-newsgroup-headers)) - ;; Set the new ranges of read articles. - (save-excursion - (set-buffer gnus-group-buffer) - (gnus-undo-force-boundary)) - (gnus-update-read-articles - group (append gnus-newsgroup-unreads gnus-newsgroup-unselected)) - ;; Set the current article marks. - (let ((gnus-newsgroup-scored - (if (and (not gnus-save-score) - (not non-destructive)) - nil - gnus-newsgroup-scored))) - (save-excursion - (gnus-update-marks))) - ;; Do the cross-ref thing. - (when gnus-use-cross-reference - (gnus-mark-xrefs-as-read group headers gnus-newsgroup-unreads)) - ;; Do not switch windows but change the buffer to work. - (set-buffer gnus-group-buffer) - (unless (gnus-ephemeral-group-p group) - (gnus-group-update-group group))))))) - -(defun gnus-summary-save-newsrc (&optional force) - "Save the current number of read/marked articles in the dribble buffer. -The dribble buffer will then be saved. -If FORCE (the prefix), also save the .newsrc file(s)." - (interactive "P") - (gnus-summary-update-info t) - (if force - (gnus-save-newsrc-file) - (gnus-dribble-save))) - -(defun gnus-summary-exit (&optional temporary) - "Exit reading current newsgroup, and then return to group selection mode. -gnus-exit-group-hook is called with no arguments if that value is non-nil." - (interactive) - (gnus-set-global-variables) - (gnus-kill-save-kill-buffer) - (gnus-async-halt-prefetch) - (let* ((group gnus-newsgroup-name) - (quit-config (gnus-group-quit-config gnus-newsgroup-name)) - (mode major-mode) - (group-point nil) - (buf (current-buffer))) - (gnus-run-hooks 'gnus-summary-prepare-exit-hook) - ;; If we have several article buffers, we kill them at exit. - (unless gnus-single-article-buffer - (gnus-kill-buffer gnus-original-article-buffer) - (setq gnus-article-current nil)) - (when gnus-use-cache - (gnus-cache-possibly-remove-articles) - (gnus-cache-save-buffers)) - (gnus-async-prefetch-remove-group group) - (when gnus-suppress-duplicates - (gnus-dup-enter-articles)) - (when gnus-use-trees - (gnus-tree-close group)) - ;; Remove entries for this group. - (nnmail-purge-split-history (gnus-group-real-name group)) - ;; Make all changes in this group permanent. - (unless quit-config - (gnus-run-hooks 'gnus-exit-group-hook) - (gnus-summary-update-info) - ;; Do adaptive scoring, and possibly save score files. - (when gnus-newsgroup-adaptive - (gnus-score-adaptive)) - (when gnus-use-scoring - (gnus-score-save))) - (gnus-close-group group) - ;; Make sure where we were, and go to next newsgroup. - (set-buffer gnus-group-buffer) - (unless quit-config - (gnus-group-jump-to-group group)) - (gnus-run-hooks 'gnus-summary-exit-hook) - (unless (or quit-config - ;; If this group has disappeared from the summary - ;; buffer, don't skip forwards. - (not (string= group (gnus-group-group-name)))) - (gnus-group-next-unread-group 1)) - (setq group-point (point)) - (if temporary - nil ;Nothing to do. - ;; If we have several article buffers, we kill them at exit. - (unless gnus-single-article-buffer - (gnus-kill-buffer gnus-article-buffer) - (gnus-kill-buffer gnus-original-article-buffer) - (setq gnus-article-current nil)) - (set-buffer buf) - (if (not gnus-kill-summary-on-exit) - (gnus-deaden-summary) - ;; We set all buffer-local variables to nil. It is unclear why - ;; this is needed, but if we don't, buffer-local variables are - ;; not garbage-collected, it seems. This would the lead to en - ;; ever-growing Emacs. - (gnus-summary-clear-local-variables) - (when (get-buffer gnus-article-buffer) - (bury-buffer gnus-article-buffer)) - ;; We clear the global counterparts of the buffer-local - ;; variables as well, just to be on the safe side. - (set-buffer gnus-group-buffer) - (gnus-summary-clear-local-variables) - ;; Return to group mode buffer. - (when (eq mode 'gnus-summary-mode) - (gnus-kill-buffer buf))) - (setq gnus-current-select-method gnus-select-method) - (pop-to-buffer gnus-group-buffer) - ;; Clear the current group name. - (if (not quit-config) - (progn - (goto-char group-point) - (gnus-configure-windows 'group 'force)) - (gnus-handle-ephemeral-exit quit-config)) - (unless quit-config - (setq gnus-newsgroup-name nil))))) - -(defalias 'gnus-summary-quit 'gnus-summary-exit-no-update) -(defun gnus-summary-exit-no-update (&optional no-questions) - "Quit reading current newsgroup without updating read article info." - (interactive) - (let* ((group gnus-newsgroup-name) - (quit-config (gnus-group-quit-config group))) - (when (or no-questions - gnus-expert-user - (gnus-y-or-n-p "Discard changes to this group and exit? ")) - (gnus-async-halt-prefetch) - (gnus-run-hooks 'gnus-summary-prepare-exit-hook) - ;; If we have several article buffers, we kill them at exit. - (unless gnus-single-article-buffer - (gnus-kill-buffer gnus-article-buffer) - (gnus-kill-buffer gnus-original-article-buffer) - (setq gnus-article-current nil)) - (if (not gnus-kill-summary-on-exit) - (gnus-deaden-summary) - (gnus-close-group group) - (gnus-summary-clear-local-variables) - (set-buffer gnus-group-buffer) - (gnus-summary-clear-local-variables) - (when (get-buffer gnus-summary-buffer) - (kill-buffer gnus-summary-buffer))) - (unless gnus-single-article-buffer - (setq gnus-article-current nil)) - (when gnus-use-trees - (gnus-tree-close group)) - (gnus-async-prefetch-remove-group group) - (when (get-buffer gnus-article-buffer) - (bury-buffer gnus-article-buffer)) - ;; Return to the group buffer. - (gnus-configure-windows 'group 'force) - ;; Clear the current group name. - (setq gnus-newsgroup-name nil) - (when (equal (gnus-group-group-name) group) - (gnus-group-next-unread-group 1)) - (when quit-config - (gnus-handle-ephemeral-exit quit-config))))) - -(defun gnus-handle-ephemeral-exit (quit-config) - "Handle movement when leaving an ephemeral group. -The state which existed when entering the ephemeral is reset." - (if (not (buffer-name (car quit-config))) - (gnus-configure-windows 'group 'force) - (set-buffer (car quit-config)) - (cond ((eq major-mode 'gnus-summary-mode) - (gnus-set-global-variables)) - ((eq major-mode 'gnus-article-mode) - (save-excursion - ;; The `gnus-summary-buffer' variable may point - ;; to the old summary buffer when using a single - ;; article buffer. - (unless (gnus-buffer-live-p gnus-summary-buffer) - (set-buffer gnus-group-buffer)) - (set-buffer gnus-summary-buffer) - (gnus-set-global-variables)))) - (if (or (eq (cdr quit-config) 'article) - (eq (cdr quit-config) 'pick)) - (progn - ;; The current article may be from the ephemeral group - ;; thus it is best that we reload this article - (gnus-summary-show-article) - (if (and (boundp 'gnus-pick-mode) (symbol-value 'gnus-pick-mode)) - (gnus-configure-windows 'pick 'force) - (gnus-configure-windows (cdr quit-config) 'force))) - (gnus-configure-windows (cdr quit-config) 'force)) - (when (eq major-mode 'gnus-summary-mode) - (gnus-summary-next-subject 1 nil t) - (gnus-summary-recenter) - (gnus-summary-position-point)))) - -(defun gnus-summary-preview-mime-message (arg) - "MIME decode and play this message." - (interactive "P") - (or gnus-show-mime - (let ((gnus-break-pages nil) - (gnus-show-mime t)) - (gnus-summary-select-article t t) - )) - (select-window (get-buffer-window gnus-article-buffer)) - ) - -;;; Dead summaries. - -(defvar gnus-dead-summary-mode-map nil) - -(unless gnus-dead-summary-mode-map - (setq gnus-dead-summary-mode-map (make-keymap)) - (suppress-keymap gnus-dead-summary-mode-map) - (substitute-key-definition - 'undefined 'gnus-summary-wake-up-the-dead gnus-dead-summary-mode-map) - (let ((keys '("\C-d" "\r" "\177" [delete]))) - (while keys - (define-key gnus-dead-summary-mode-map - (pop keys) 'gnus-summary-wake-up-the-dead)))) - -(defvar gnus-dead-summary-mode nil - "Minor mode for Gnus summary buffers.") - -(defun gnus-dead-summary-mode (&optional arg) - "Minor mode for Gnus summary buffers." - (interactive "P") - (when (eq major-mode 'gnus-summary-mode) - (make-local-variable 'gnus-dead-summary-mode) - (setq gnus-dead-summary-mode - (if (null arg) (not gnus-dead-summary-mode) - (> (prefix-numeric-value arg) 0))) - (when gnus-dead-summary-mode - (gnus-add-minor-mode - 'gnus-dead-summary-mode " Dead" gnus-dead-summary-mode-map)))) - -(defun gnus-deaden-summary () - "Make the current summary buffer into a dead summary buffer." - ;; Kill any previous dead summary buffer. - (when (and gnus-dead-summary - (buffer-name gnus-dead-summary)) - (save-excursion - (set-buffer gnus-dead-summary) - (when gnus-dead-summary-mode - (kill-buffer (current-buffer))))) - ;; Make this the current dead summary. - (setq gnus-dead-summary (current-buffer)) - (gnus-dead-summary-mode 1) - (let ((name (buffer-name))) - (when (string-match "Summary" name) - (rename-buffer - (concat (substring name 0 (match-beginning 0)) "Dead " - (substring name (match-beginning 0))) - t)))) - -(defun gnus-kill-or-deaden-summary (buffer) - "Kill or deaden the summary BUFFER." - (save-excursion - (when (and (buffer-name buffer) - (not gnus-single-article-buffer)) - (save-excursion - (set-buffer buffer) - (gnus-kill-buffer gnus-article-buffer) - (gnus-kill-buffer gnus-original-article-buffer))) - (cond (gnus-kill-summary-on-exit - (when (and gnus-use-trees - (gnus-buffer-exists-p buffer)) - (save-excursion - (set-buffer buffer) - (gnus-tree-close gnus-newsgroup-name))) - (gnus-kill-buffer buffer)) - ((gnus-buffer-exists-p buffer) - (save-excursion - (set-buffer buffer) - (gnus-deaden-summary)))))) - -(defun gnus-summary-wake-up-the-dead (&rest args) - "Wake up the dead summary buffer." - (interactive) - (gnus-dead-summary-mode -1) - (let ((name (buffer-name))) - (when (string-match "Dead " name) - (rename-buffer - (concat (substring name 0 (match-beginning 0)) - (substring name (match-end 0))) - t))) - (gnus-message 3 "This dead summary is now alive again")) - -;; Suggested by Andrew Eskilsson . -(defun gnus-summary-fetch-faq (&optional faq-dir) - "Fetch the FAQ for the current group. -If FAQ-DIR (the prefix), prompt for a directory to search for the faq -in." - (interactive - (list - (when current-prefix-arg - (completing-read - "Faq dir: " (and (listp gnus-group-faq-directory) - (mapcar (lambda (file) (list file)) - gnus-group-faq-directory)))))) - (let (gnus-faq-buffer) - (when (setq gnus-faq-buffer - (gnus-group-fetch-faq gnus-newsgroup-name faq-dir)) - (gnus-configure-windows 'summary-faq)))) - -;; Suggested by Per Abrahamsen . -(defun gnus-summary-describe-group (&optional force) - "Describe the current newsgroup." - (interactive "P") - (gnus-group-describe-group force gnus-newsgroup-name)) - -(defun gnus-summary-describe-briefly () - "Describe summary mode commands briefly." - (interactive) - (gnus-message 6 - (substitute-command-keys "\\\\[gnus-summary-next-page]:Select \\[gnus-summary-next-unread-article]:Forward \\[gnus-summary-prev-unread-article]:Backward \\[gnus-summary-exit]:Exit \\[gnus-info-find-node]:Run Info \\[gnus-summary-describe-briefly]:This help"))) - -;; Walking around group mode buffer from summary mode. - -(defun gnus-summary-next-group (&optional no-article target-group backward) - "Exit current newsgroup and then select next unread newsgroup. -If prefix argument NO-ARTICLE is non-nil, no article is selected -initially. If NEXT-GROUP, go to this group. If BACKWARD, go to -previous group instead." - (interactive "P") - ;; Stop pre-fetching. - (gnus-async-halt-prefetch) - (let ((current-group gnus-newsgroup-name) - (current-buffer (current-buffer)) - entered) - ;; First we semi-exit this group to update Xrefs and all variables. - ;; We can't do a real exit, because the window conf must remain - ;; the same in case the user is prompted for info, and we don't - ;; want the window conf to change before that... - (gnus-summary-exit t) - (while (not entered) - ;; Then we find what group we are supposed to enter. - (set-buffer gnus-group-buffer) - (gnus-group-jump-to-group current-group) - (setq target-group - (or target-group - (if (eq gnus-keep-same-level 'best) - (gnus-summary-best-group gnus-newsgroup-name) - (gnus-summary-search-group backward gnus-keep-same-level)))) - (if (not target-group) - ;; There are no further groups, so we return to the group - ;; buffer. - (progn - (gnus-message 5 "Returning to the group buffer") - (setq entered t) - (when (gnus-buffer-live-p current-buffer) - (set-buffer current-buffer) - (gnus-summary-exit)) - (gnus-run-hooks 'gnus-group-no-more-groups-hook)) - ;; We try to enter the target group. - (gnus-group-jump-to-group target-group) - (let ((unreads (gnus-group-group-unread))) - (if (and (or (eq t unreads) - (and unreads (not (zerop unreads)))) - (gnus-summary-read-group - target-group nil no-article - (and (buffer-name current-buffer) current-buffer) - nil backward)) - (setq entered t) - (setq current-group target-group - target-group nil))))))) - -(defun gnus-summary-prev-group (&optional no-article) - "Exit current newsgroup and then select previous unread newsgroup. -If prefix argument NO-ARTICLE is non-nil, no article is selected initially." - (interactive "P") - (gnus-summary-next-group no-article nil t)) - -;; Walking around summary lines. - -(defun gnus-summary-first-subject (&optional unread undownloaded) - "Go to the first unread subject. -If UNREAD is non-nil, go to the first unread article. -Returns the article selected or nil if there are no unread articles." - (interactive "P") - (prog1 - (cond - ;; Empty summary. - ((null gnus-newsgroup-data) - (gnus-message 3 "No articles in the group") - nil) - ;; Pick the first article. - ((not unread) - (goto-char (gnus-data-pos (car gnus-newsgroup-data))) - (gnus-data-number (car gnus-newsgroup-data))) - ;; No unread articles. - ((null gnus-newsgroup-unreads) - (gnus-message 3 "No more unread articles") - nil) - ;; Find the first unread article. - (t - (let ((data gnus-newsgroup-data)) - (while (and data - (and (not (and undownloaded - (eq gnus-undownloaded-mark - (gnus-data-mark (car data))))) - (not (gnus-data-unread-p (car data))))) - (setq data (cdr data))) - (when data - (goto-char (gnus-data-pos (car data))) - (gnus-data-number (car data)))))) - (gnus-summary-position-point))) - -(defun gnus-summary-next-subject (n &optional unread dont-display) - "Go to next N'th summary line. -If N is negative, go to the previous N'th subject line. -If UNREAD is non-nil, only unread articles are selected. -The difference between N and the actual number of steps taken is -returned." - (interactive "p") - (let ((backward (< n 0)) - (n (abs n))) - (while (and (> n 0) - (if backward - (gnus-summary-find-prev unread) - (gnus-summary-find-next unread))) - (gnus-summary-show-thread) - (setq n (1- n))) - (when (/= 0 n) - (gnus-message 7 "No more%s articles" - (if unread " unread" ""))) - (unless dont-display - (gnus-summary-recenter) - (gnus-summary-position-point)) - n)) - -(defun gnus-summary-next-unread-subject (n) - "Go to next N'th unread summary line." - (interactive "p") - (gnus-summary-next-subject n t)) - -(defun gnus-summary-prev-subject (n &optional unread) - "Go to previous N'th summary line. -If optional argument UNREAD is non-nil, only unread article is selected." - (interactive "p") - (gnus-summary-next-subject (- n) unread)) - -(defun gnus-summary-prev-unread-subject (n) - "Go to previous N'th unread summary line." - (interactive "p") - (gnus-summary-next-subject (- n) t)) - -(defun gnus-summary-goto-subject (article &optional force silent) - "Go the subject line of ARTICLE. -If FORCE, also allow jumping to articles not currently shown." - (interactive "nArticle number: ") - (let ((b (point)) - (data (gnus-data-find article))) - ;; We read in the article if we have to. - (and (not data) - force - (gnus-summary-insert-subject - article - (if (or (numberp force) (vectorp force)) force) - t) - (setq data (gnus-data-find article))) - (goto-char b) - (if (not data) - (progn - (unless silent - (gnus-message 3 "Can't find article %d" article)) - nil) - (goto-char (gnus-data-pos data)) - (gnus-summary-position-point) - article))) - -;; Walking around summary lines with displaying articles. - -(defun gnus-summary-expand-window (&optional arg) - "Make the summary buffer take up the entire Emacs frame. -Given a prefix, will force an `article' buffer configuration." - (interactive "P") - (if arg - (gnus-configure-windows 'article 'force) - (gnus-configure-windows 'summary 'force))) - -(defun gnus-summary-display-article (article &optional all-header) - "Display ARTICLE in article buffer." - (gnus-set-global-variables) - (if (null article) - nil - (prog1 - (if gnus-summary-display-article-function - (funcall gnus-summary-display-article-function article all-header) - (gnus-article-prepare article all-header)) - (gnus-run-hooks 'gnus-select-article-hook) - (when (and gnus-current-article - (not (zerop gnus-current-article))) - (gnus-summary-goto-subject gnus-current-article)) - (gnus-summary-recenter) - (when (and gnus-use-trees gnus-show-threads) - (gnus-possibly-generate-tree article) - (gnus-highlight-selected-tree article)) - ;; Successfully display article. - (gnus-article-set-window-start - (cdr (assq article gnus-newsgroup-bookmarks)))))) - -(defun gnus-summary-select-article (&optional all-headers force pseudo article) - "Select the current article. -If ALL-HEADERS is non-nil, show all header fields. If FORCE is -non-nil, the article will be re-fetched even if it already present in -the article buffer. If PSEUDO is non-nil, pseudo-articles will also -be displayed." - ;; Make sure we are in the summary buffer to work around bbdb bug. - (unless (eq major-mode 'gnus-summary-mode) - (set-buffer gnus-summary-buffer)) - (let ((article (or article (gnus-summary-article-number))) - (all-headers (not (not all-headers))) ;Must be T or NIL. - gnus-summary-display-article-function - did) - (and (not pseudo) - (gnus-summary-article-pseudo-p article) - (error "This is a pseudo-article")) - (prog1 - (save-excursion - (set-buffer gnus-summary-buffer) - (if (or (and gnus-single-article-buffer - (or (null gnus-current-article) - (null gnus-article-current) - (null (get-buffer gnus-article-buffer)) - (not (eq article (cdr gnus-article-current))) - (not (equal (car gnus-article-current) - gnus-newsgroup-name)))) - (and (not gnus-single-article-buffer) - (or (null gnus-current-article) - (not (eq gnus-current-article article)))) - force) - ;; The requested article is different from the current article. - (prog1 - (gnus-summary-display-article article all-headers) - (setq did article)) - (when (or all-headers gnus-show-all-headers) - (gnus-article-show-all-headers)) - 'old)) - (when did - (gnus-article-set-window-start - (cdr (assq article gnus-newsgroup-bookmarks))))))) - -(defun gnus-summary-set-current-mark (&optional current-mark) - "Obsolete function." - nil) - -(defun gnus-summary-next-article (&optional unread subject backward push) - "Select the next article. -If UNREAD, only unread articles are selected. -If SUBJECT, only articles with SUBJECT are selected. -If BACKWARD, the previous article is selected instead of the next." - (interactive "P") - (cond - ;; Is there such an article? - ((and (gnus-summary-search-forward unread subject backward) - (or (gnus-summary-display-article (gnus-summary-article-number)) - (eq (gnus-summary-article-mark) gnus-canceled-mark))) - (gnus-summary-position-point)) - ;; If not, we try the first unread, if that is wanted. - ((and subject - gnus-auto-select-same - (gnus-summary-first-unread-article)) - (gnus-summary-position-point) - (gnus-message 6 "Wrapped")) - ;; Try to get next/previous article not displayed in this group. - ((and gnus-auto-extend-newsgroup - (not unread) (not subject)) - (gnus-summary-goto-article - (if backward (1- gnus-newsgroup-begin) (1+ gnus-newsgroup-end)) - nil (count-lines (point-min) (point)))) - ;; Go to next/previous group. - (t - (unless (gnus-ephemeral-group-p gnus-newsgroup-name) - (gnus-summary-jump-to-group gnus-newsgroup-name)) - (let ((cmd last-command-char) - (point - (save-excursion - (set-buffer gnus-group-buffer) - (point))) - (group - (if (eq gnus-keep-same-level 'best) - (gnus-summary-best-group gnus-newsgroup-name) - (gnus-summary-search-group backward gnus-keep-same-level)))) - ;; For some reason, the group window gets selected. We change - ;; it back. - (select-window (get-buffer-window (current-buffer))) - ;; Select next unread newsgroup automagically. - (cond - ((or (not gnus-auto-select-next) - (not cmd)) - (gnus-message 7 "No more%s articles" (if unread " unread" ""))) - ((or (eq gnus-auto-select-next 'quietly) - (and (eq gnus-auto-select-next 'slightly-quietly) - push) - (and (eq gnus-auto-select-next 'almost-quietly) - (gnus-summary-last-article-p))) - ;; Select quietly. - (if (gnus-ephemeral-group-p gnus-newsgroup-name) - (gnus-summary-exit) - (gnus-message 7 "No more%s articles (%s)..." - (if unread " unread" "") - (if group (concat "selecting " group) - "exiting")) - (gnus-summary-next-group nil group backward))) - (t - (when (gnus-key-press-event-p last-input-event) - (gnus-summary-walk-group-buffer - gnus-newsgroup-name cmd unread backward point)))))))) - -(defun gnus-summary-walk-group-buffer (from-group cmd unread backward start) - (let ((keystrokes '((?\C-n (gnus-group-next-unread-group 1)) - (?\C-p (gnus-group-prev-unread-group 1)))) - (cursor-in-echo-area t) - keve key group ended) - (save-excursion - (set-buffer gnus-group-buffer) - (goto-char start) - (setq group - (if (eq gnus-keep-same-level 'best) - (gnus-summary-best-group gnus-newsgroup-name) - (gnus-summary-search-group backward gnus-keep-same-level)))) - (while (not ended) - (gnus-message - 5 "No more%s articles%s" (if unread " unread" "") - (if (and group - (not (gnus-ephemeral-group-p gnus-newsgroup-name))) - (format " (Type %s for %s [%s])" - (single-key-description cmd) group - (car (gnus-gethash group gnus-newsrc-hashtb))) - (format " (Type %s to exit %s)" - (single-key-description cmd) - gnus-newsgroup-name))) - ;; Confirm auto selection. - (setq key (car (setq keve (gnus-read-event-char)))) - (setq ended t) - (cond - ((assq key keystrokes) - (let ((obuf (current-buffer))) - (switch-to-buffer gnus-group-buffer) - (when group - (gnus-group-jump-to-group group)) - (eval (cadr (assq key keystrokes))) - (setq group (gnus-group-group-name)) - (switch-to-buffer obuf)) - (setq ended nil)) - ((equal key cmd) - (if (or (not group) - (gnus-ephemeral-group-p gnus-newsgroup-name)) - (gnus-summary-exit) - (gnus-summary-next-group nil group backward))) - (t - (push (cdr keve) unread-command-events)))))) - -(defun gnus-summary-next-unread-article () - "Select unread article after current one." - (interactive) - (gnus-summary-next-article - (or (not (eq gnus-summary-goto-unread 'never)) - (gnus-summary-last-article-p (gnus-summary-article-number))) - (and gnus-auto-select-same - (gnus-summary-article-subject)))) - -(defun gnus-summary-prev-article (&optional unread subject) - "Select the article after the current one. -If UNREAD is non-nil, only unread articles are selected." - (interactive "P") - (gnus-summary-next-article unread subject t)) - -(defun gnus-summary-prev-unread-article () - "Select unread article before current one." - (interactive) - (gnus-summary-prev-article - (or (not (eq gnus-summary-goto-unread 'never)) - (gnus-summary-first-article-p (gnus-summary-article-number))) - (and gnus-auto-select-same - (gnus-summary-article-subject)))) - -(defun gnus-summary-next-page (&optional lines circular) - "Show next page of the selected article. -If at the end of the current article, select the next article. -LINES says how many lines should be scrolled up. - -If CIRCULAR is non-nil, go to the start of the article instead of -selecting the next article when reaching the end of the current -article." - (interactive "P") - (setq gnus-summary-buffer (current-buffer)) - (gnus-set-global-variables) - (let ((article (gnus-summary-article-number)) - (article-window (get-buffer-window gnus-article-buffer t)) - endp) - ;; If the buffer is empty, we have no article. - (unless article - (error "No article to select")) - (gnus-configure-windows 'article) - (if (eq (cdr (assq article gnus-newsgroup-reads)) gnus-canceled-mark) - (if (and (eq gnus-summary-goto-unread 'never) - (not (gnus-summary-last-article-p article))) - (gnus-summary-next-article) - (gnus-summary-next-unread-article)) - (if (or (null gnus-current-article) - (null gnus-article-current) - (/= article (cdr gnus-article-current)) - (not (equal (car gnus-article-current) gnus-newsgroup-name))) - ;; Selected subject is different from current article's. - (gnus-summary-display-article article) - (when article-window - (gnus-eval-in-buffer-window gnus-article-buffer - (setq endp (gnus-article-next-page lines))) - (when endp - (cond (circular - (gnus-summary-beginning-of-article)) - (lines - (gnus-message 3 "End of message")) - ((null lines) - (if (and (eq gnus-summary-goto-unread 'never) - (not (gnus-summary-last-article-p article))) - (gnus-summary-next-article) - (gnus-summary-next-unread-article)))))))) - (gnus-summary-recenter) - (gnus-summary-position-point))) - -(defun gnus-summary-prev-page (&optional lines move) - "Show previous page of selected article. -Argument LINES specifies lines to be scrolled down. -If MOVE, move to the previous unread article if point is at -the beginning of the buffer." - (interactive "P") - (let ((article (gnus-summary-article-number)) - (article-window (get-buffer-window gnus-article-buffer t)) - endp) - (gnus-configure-windows 'article) - (if (or (null gnus-current-article) - (null gnus-article-current) - (/= article (cdr gnus-article-current)) - (not (equal (car gnus-article-current) gnus-newsgroup-name))) - ;; Selected subject is different from current article's. - (gnus-summary-display-article article) - (gnus-summary-recenter) - (when article-window - (gnus-eval-in-buffer-window gnus-article-buffer - (setq endp (gnus-article-prev-page lines))) - (when (and move endp) - (cond (lines - (gnus-message 3 "Beginning of message")) - ((null lines) - (if (and (eq gnus-summary-goto-unread 'never) - (not (gnus-summary-first-article-p article))) - (gnus-summary-prev-article) - (gnus-summary-prev-unread-article)))))))) - (gnus-summary-position-point)) - -(defun gnus-summary-prev-page-or-article (&optional lines) - "Show previous page of selected article. -Argument LINES specifies lines to be scrolled down. -If at the beginning of the article, go to the next article." - (interactive "P") - (gnus-summary-prev-page lines t)) - -(defun gnus-summary-scroll-up (lines) - "Scroll up (or down) one line current article. -Argument LINES specifies lines to be scrolled up (or down if negative)." - (interactive "p") - (gnus-configure-windows 'article) - (gnus-summary-show-thread) - (when (eq (gnus-summary-select-article nil nil 'pseudo) 'old) - (gnus-eval-in-buffer-window gnus-article-buffer - (cond ((> lines 0) - (when (gnus-article-next-page lines) - (gnus-message 3 "End of message"))) - ((< lines 0) - (gnus-article-prev-page (- lines)))))) - (gnus-summary-recenter) - (gnus-summary-position-point)) - -(defun gnus-summary-scroll-down (lines) - "Scroll down (or up) one line current article. -Argument LINES specifies lines to be scrolled down (or up if negative)." - (interactive "p") - (gnus-summary-scroll-up (- lines))) - -(defun gnus-summary-next-same-subject () - "Select next article which has the same subject as current one." - (interactive) - (gnus-summary-next-article nil (gnus-summary-article-subject))) - -(defun gnus-summary-prev-same-subject () - "Select previous article which has the same subject as current one." - (interactive) - (gnus-summary-prev-article nil (gnus-summary-article-subject))) - -(defun gnus-summary-next-unread-same-subject () - "Select next unread article which has the same subject as current one." - (interactive) - (gnus-summary-next-article t (gnus-summary-article-subject))) - -(defun gnus-summary-prev-unread-same-subject () - "Select previous unread article which has the same subject as current one." - (interactive) - (gnus-summary-prev-article t (gnus-summary-article-subject))) - -(defun gnus-summary-first-unread-article () - "Select the first unread article. -Return nil if there are no unread articles." - (interactive) - (prog1 - (when (gnus-summary-first-subject t) - (gnus-summary-show-thread) - (gnus-summary-first-subject t) - (gnus-summary-display-article (gnus-summary-article-number))) - (gnus-summary-position-point))) - -(defun gnus-summary-first-article () - "Select the first article. -Return nil if there are no articles." - (interactive) - (prog1 - (when (gnus-summary-first-subject) - (gnus-summary-show-thread) - (gnus-summary-first-subject) - (gnus-summary-display-article (gnus-summary-article-number))) - (gnus-summary-position-point))) - -(defun gnus-summary-best-unread-article () - "Select the unread article with the highest score." - (interactive) - (let ((best -1000000) - (data gnus-newsgroup-data) - article score) - (while data - (and (gnus-data-unread-p (car data)) - (> (setq score - (gnus-summary-article-score (gnus-data-number (car data)))) - best) - (setq best score - article (gnus-data-number (car data)))) - (setq data (cdr data))) - (prog1 - (if article - (gnus-summary-goto-article article) - (error "No unread articles")) - (gnus-summary-position-point)))) - -(defun gnus-summary-last-subject () - "Go to the last displayed subject line in the group." - (let ((article (gnus-data-number (car (gnus-data-list t))))) - (when article - (gnus-summary-goto-subject article)))) - -(defun gnus-summary-goto-article (article &optional all-headers force) - "Fetch ARTICLE (article number or Message-ID) and display it if it exists. -If ALL-HEADERS is non-nil, no header lines are hidden. -If FORCE, go to the article even if it isn't displayed. If FORCE -is a number, it is the line the article is to be displayed on." - (interactive - (list - (completing-read - "Article number or Message-ID: " - (mapcar (lambda (number) (list (int-to-string number))) - gnus-newsgroup-limit)) - current-prefix-arg - t)) - (prog1 - (if (and (stringp article) - (string-match "@" article)) - (gnus-summary-refer-article article) - (when (stringp article) - (setq article (string-to-number article))) - (if (gnus-summary-goto-subject article force) - (gnus-summary-display-article article all-headers) - (gnus-message 4 "Couldn't go to article %s" article) nil)) - (gnus-summary-position-point))) - -(defun gnus-summary-goto-last-article () - "Go to the previously read article." - (interactive) - (prog1 - (when gnus-last-article - (gnus-summary-goto-article gnus-last-article nil t)) - (gnus-summary-position-point))) - -(defun gnus-summary-pop-article (number) - "Pop one article off the history and go to the previous. -NUMBER articles will be popped off." - (interactive "p") - (let (to) - (setq gnus-newsgroup-history - (cdr (setq to (nthcdr number gnus-newsgroup-history)))) - (if to - (gnus-summary-goto-article (car to) nil t) - (error "Article history empty"))) - (gnus-summary-position-point)) - -;; Summary commands and functions for limiting the summary buffer. - -(defun gnus-summary-limit-to-articles (n) - "Limit the summary buffer to the next N articles. -If not given a prefix, use the process marked articles instead." - (interactive "P") - (prog1 - (let ((articles (gnus-summary-work-articles n))) - (setq gnus-newsgroup-processable nil) - (gnus-summary-limit articles)) - (gnus-summary-position-point))) - -(defun gnus-summary-pop-limit (&optional total) - "Restore the previous limit. -If given a prefix, remove all limits." - (interactive "P") - (when total - (setq gnus-newsgroup-limits - (list (mapcar (lambda (h) (mail-header-number h)) - gnus-newsgroup-headers)))) - (unless gnus-newsgroup-limits - (error "No limit to pop")) - (prog1 - (gnus-summary-limit nil 'pop) - (gnus-summary-position-point))) - -(defun gnus-summary-limit-to-subject (subject &optional header) - "Limit the summary buffer to articles that have subjects that match a regexp." - (interactive "sLimit to subject (regexp): ") - (unless header - (setq header "subject")) - (when (not (equal "" subject)) - (prog1 - (let ((articles (gnus-summary-find-matching - (or header "subject") subject 'all))) - (unless articles - (error "Found no matches for \"%s\"" subject)) - (gnus-summary-limit articles)) - (gnus-summary-position-point)))) - -(defun gnus-summary-limit-to-author (from) - "Limit the summary buffer to articles that have authors that match a regexp." - (interactive "sLimit to author (regexp): ") - (gnus-summary-limit-to-subject from "from")) - -(defun gnus-summary-limit-to-age (age &optional younger-p) - "Limit the summary buffer to articles that are older than (or equal) AGE days. -If YOUNGER-P (the prefix) is non-nil, limit the summary buffer to -articles that are younger than AGE days." - (interactive "nTime in days: \nP") - (prog1 - (let ((data gnus-newsgroup-data) - (cutoff (nnmail-days-to-time age)) - articles d date is-younger) - (while (setq d (pop data)) - (when (and (vectorp (gnus-data-header d)) - (setq date (mail-header-date (gnus-data-header d)))) - (setq is-younger (nnmail-time-less - (nnmail-time-since (nnmail-date-to-time date)) - cutoff)) - (when (if younger-p - is-younger - (not is-younger)) - (push (gnus-data-number d) articles)))) - (gnus-summary-limit (nreverse articles))) - (gnus-summary-position-point))) - -(defalias 'gnus-summary-delete-marked-as-read 'gnus-summary-limit-to-unread) -(make-obsolete - 'gnus-summary-delete-marked-as-read 'gnus-summary-limit-to-unread) - -(defun gnus-summary-limit-to-unread (&optional all) - "Limit the summary buffer to articles that are not marked as read. -If ALL is non-nil, limit strictly to unread articles." - (interactive "P") - (if all - (gnus-summary-limit-to-marks (char-to-string gnus-unread-mark)) - (gnus-summary-limit-to-marks - ;; Concat all the marks that say that an article is read and have - ;; those removed. - (list gnus-del-mark gnus-read-mark gnus-ancient-mark - gnus-killed-mark gnus-kill-file-mark - gnus-low-score-mark gnus-expirable-mark - gnus-canceled-mark gnus-catchup-mark gnus-sparse-mark - gnus-duplicate-mark gnus-souped-mark) - 'reverse))) - -(defalias 'gnus-summary-delete-marked-with 'gnus-summary-limit-exclude-marks) -(make-obsolete 'gnus-summary-delete-marked-with - 'gnus-summary-limit-exlude-marks) - -(defun gnus-summary-limit-exclude-marks (marks &optional reverse) - "Exclude articles that are marked with MARKS (e.g. \"DK\"). -If REVERSE, limit the summary buffer to articles that are marked -with MARKS. MARKS can either be a string of marks or a list of marks. -Returns how many articles were removed." - (interactive "sMarks: ") - (gnus-summary-limit-to-marks marks t)) - -(defun gnus-summary-limit-to-marks (marks &optional reverse) - "Limit the summary buffer to articles that are marked with MARKS (e.g. \"DK\"). -If REVERSE (the prefix), limit the summary buffer to articles that are -not marked with MARKS. MARKS can either be a string of marks or a -list of marks. -Returns how many articles were removed." - (interactive "sMarks: \nP") - (prog1 - (let ((data gnus-newsgroup-data) - (marks (if (listp marks) marks - (append marks nil))) ; Transform to list. - articles) - (while data - (when (if reverse (not (memq (gnus-data-mark (car data)) marks)) - (memq (gnus-data-mark (car data)) marks)) - (push (gnus-data-number (car data)) articles)) - (setq data (cdr data))) - (gnus-summary-limit articles)) - (gnus-summary-position-point))) - -(defun gnus-summary-limit-to-score (&optional score) - "Limit to articles with score at or above SCORE." - (interactive "P") - (setq score (if score - (prefix-numeric-value score) - (or gnus-summary-default-score 0))) - (let ((data gnus-newsgroup-data) - articles) - (while data - (when (>= (gnus-summary-article-score (gnus-data-number (car data))) - score) - (push (gnus-data-number (car data)) articles)) - (setq data (cdr data))) - (prog1 - (gnus-summary-limit articles) - (gnus-summary-position-point)))) - -(defun gnus-summary-limit-include-thread (id) - "Display all the hidden articles that in the current thread." - (interactive (list (mail-header-id (gnus-summary-article-header)))) - (let ((articles (gnus-articles-in-thread - (gnus-id-to-thread (gnus-root-id id))))) - (prog1 - (gnus-summary-limit (nconc articles gnus-newsgroup-limit)) - (gnus-summary-position-point)))) - -(defun gnus-summary-limit-include-dormant () - "Display all the hidden articles that are marked as dormant. -Note that this command only works on a subset of the articles currently -fetched for this group." - (interactive) - (unless gnus-newsgroup-dormant - (error "There are no dormant articles in this group")) - (prog1 - (gnus-summary-limit (append gnus-newsgroup-dormant gnus-newsgroup-limit)) - (gnus-summary-position-point))) - -(defun gnus-summary-limit-exclude-dormant () - "Hide all dormant articles." - (interactive) - (prog1 - (gnus-summary-limit-to-marks (list gnus-dormant-mark) 'reverse) - (gnus-summary-position-point))) - -(defun gnus-summary-limit-exclude-childless-dormant () - "Hide all dormant articles that have no children." - (interactive) - (let ((data (gnus-data-list t)) - articles d children) - ;; Find all articles that are either not dormant or have - ;; children. - (while (setq d (pop data)) - (when (or (not (= (gnus-data-mark d) gnus-dormant-mark)) - (and (setq children - (gnus-article-children (gnus-data-number d))) - (let (found) - (while children - (when (memq (car children) articles) - (setq children nil - found t)) - (pop children)) - found))) - (push (gnus-data-number d) articles))) - ;; Do the limiting. - (prog1 - (gnus-summary-limit articles) - (gnus-summary-position-point)))) - -(defun gnus-summary-limit-mark-excluded-as-read (&optional all) - "Mark all unread excluded articles as read. -If ALL, mark even excluded ticked and dormants as read." - (interactive "P") - (let ((articles (gnus-sorted-complement - (sort - (mapcar (lambda (h) (mail-header-number h)) - gnus-newsgroup-headers) - '<) - (sort gnus-newsgroup-limit '<))) - article) - (setq gnus-newsgroup-unreads - (gnus-intersection gnus-newsgroup-unreads gnus-newsgroup-limit)) - (if all - (setq gnus-newsgroup-dormant nil - gnus-newsgroup-marked nil - gnus-newsgroup-reads - (nconc - (mapcar (lambda (n) (cons n gnus-catchup-mark)) articles) - gnus-newsgroup-reads)) - (while (setq article (pop articles)) - (unless (or (memq article gnus-newsgroup-dormant) - (memq article gnus-newsgroup-marked)) - (push (cons article gnus-catchup-mark) gnus-newsgroup-reads)))))) - -(defun gnus-summary-limit (articles &optional pop) - (if pop - ;; We pop the previous limit off the stack and use that. - (setq articles (car gnus-newsgroup-limits) - gnus-newsgroup-limits (cdr gnus-newsgroup-limits)) - ;; We use the new limit, so we push the old limit on the stack. - (push gnus-newsgroup-limit gnus-newsgroup-limits)) - ;; Set the limit. - (setq gnus-newsgroup-limit articles) - (let ((total (length gnus-newsgroup-data)) - (data (gnus-data-find-list (gnus-summary-article-number))) - (gnus-summary-mark-below nil) ; Inhibit this. - found) - ;; This will do all the work of generating the new summary buffer - ;; according to the new limit. - (gnus-summary-prepare) - ;; Hide any threads, possibly. - (and gnus-show-threads - gnus-thread-hide-subtree - (gnus-summary-hide-all-threads)) - ;; Try to return to the article you were at, or one in the - ;; neighborhood. - (when data - ;; We try to find some article after the current one. - (while data - (when (gnus-summary-goto-subject (gnus-data-number (car data)) nil t) - (setq data nil - found t)) - (setq data (cdr data)))) - (unless found - ;; If there is no data, that means that we were after the last - ;; article. The same goes when we can't find any articles - ;; after the current one. - (goto-char (point-max)) - (gnus-summary-find-prev)) - (gnus-set-mode-line 'summary) - ;; We return how many articles were removed from the summary - ;; buffer as a result of the new limit. - (- total (length gnus-newsgroup-data)))) - -(defsubst gnus-invisible-cut-children (threads) - (let ((num 0)) - (while threads - (when (memq (mail-header-number (caar threads)) gnus-newsgroup-limit) - (incf num)) - (pop threads)) - (< num 2))) - -(defsubst gnus-cut-thread (thread) - "Go forwards in the thread until we find an article that we want to display." - (when (or (eq gnus-fetch-old-headers 'some) - (eq gnus-fetch-old-headers 'invisible) - (eq gnus-build-sparse-threads 'some) - (eq gnus-build-sparse-threads 'more)) - ;; Deal with old-fetched headers and sparse threads. - (while (and - thread - (or - (gnus-summary-article-sparse-p (mail-header-number (car thread))) - (gnus-summary-article-ancient-p - (mail-header-number (car thread)))) - (if (or (<= (length (cdr thread)) 1) - (eq gnus-fetch-old-headers 'invisible)) - (setq gnus-newsgroup-limit - (delq (mail-header-number (car thread)) - gnus-newsgroup-limit) - thread (cadr thread)) - (when (gnus-invisible-cut-children (cdr thread)) - (let ((th (cdr thread))) - (while th - (if (memq (mail-header-number (caar th)) - gnus-newsgroup-limit) - (setq thread (car th) - th nil) - (setq th (cdr th)))))))))) - thread) - -(defun gnus-cut-threads (threads) - "Cut off all uninteresting articles from the beginning of threads." - (when (or (eq gnus-fetch-old-headers 'some) - (eq gnus-fetch-old-headers 'invisible) - (eq gnus-build-sparse-threads 'some) - (eq gnus-build-sparse-threads 'more)) - (let ((th threads)) - (while th - (setcar th (gnus-cut-thread (car th))) - (setq th (cdr th))))) - ;; Remove nixed out threads. - (delq nil threads)) - -(defun gnus-summary-initial-limit (&optional show-if-empty) - "Figure out what the initial limit is supposed to be on group entry. -This entails weeding out unwanted dormants, low-scored articles, -fetch-old-headers verbiage, and so on." - ;; Most groups have nothing to remove. - (if (or gnus-inhibit-limiting - (and (null gnus-newsgroup-dormant) - (not (eq gnus-fetch-old-headers 'some)) - (not (eq gnus-fetch-old-headers 'invisible)) - (null gnus-summary-expunge-below) - (not (eq gnus-build-sparse-threads 'some)) - (not (eq gnus-build-sparse-threads 'more)) - (null gnus-thread-expunge-below) - (not gnus-use-nocem))) - () ; Do nothing. - (push gnus-newsgroup-limit gnus-newsgroup-limits) - (setq gnus-newsgroup-limit nil) - (mapatoms - (lambda (node) - (unless (car (symbol-value node)) - ;; These threads have no parents -- they are roots. - (let ((nodes (cdr (symbol-value node))) - thread) - (while nodes - (if (and gnus-thread-expunge-below - (< (gnus-thread-total-score (car nodes)) - gnus-thread-expunge-below)) - (gnus-expunge-thread (pop nodes)) - (setq thread (pop nodes)) - (gnus-summary-limit-children thread)))))) - gnus-newsgroup-dependencies) - ;; If this limitation resulted in an empty group, we might - ;; pop the previous limit and use it instead. - (when (and (not gnus-newsgroup-limit) - show-if-empty) - (setq gnus-newsgroup-limit (pop gnus-newsgroup-limits))) - gnus-newsgroup-limit)) - -(defun gnus-summary-limit-children (thread) - "Return 1 if this subthread is visible and 0 if it is not." - ;; First we get the number of visible children to this thread. This - ;; is done by recursing down the thread using this function, so this - ;; will really go down to a leaf article first, before slowly - ;; working its way up towards the root. - (when thread - (let ((children - (if (cdr thread) - (apply '+ (mapcar 'gnus-summary-limit-children - (cdr thread))) - 0)) - (number (mail-header-number (car thread))) - score) - (if (and - (not (memq number gnus-newsgroup-marked)) - (or - ;; If this article is dormant and has absolutely no visible - ;; children, then this article isn't visible. - (and (memq number gnus-newsgroup-dormant) - (zerop children)) - ;; If this is "fetch-old-headered" and there is no - ;; visible children, then we don't want this article. - (and (eq gnus-fetch-old-headers 'some) - (gnus-summary-article-ancient-p number) - (zerop children)) - ;; If this is "fetch-old-headered" and `invisible', then - ;; we don't want this article. - (and (eq gnus-fetch-old-headers 'invisible) - (gnus-summary-article-ancient-p number)) - ;; If this is a sparsely inserted article with no children, - ;; we don't want it. - (and (eq gnus-build-sparse-threads 'some) - (gnus-summary-article-sparse-p number) - (zerop children)) - ;; If we use expunging, and this article is really - ;; low-scored, then we don't want this article. - (when (and gnus-summary-expunge-below - (< (setq score - (or (cdr (assq number gnus-newsgroup-scored)) - gnus-summary-default-score)) - gnus-summary-expunge-below)) - ;; We increase the expunge-tally here, but that has - ;; nothing to do with the limits, really. - (incf gnus-newsgroup-expunged-tally) - ;; We also mark as read here, if that's wanted. - (when (and gnus-summary-mark-below - (< score gnus-summary-mark-below)) - (setq gnus-newsgroup-unreads - (delq number gnus-newsgroup-unreads)) - (if gnus-newsgroup-auto-expire - (push number gnus-newsgroup-expirable) - (push (cons number gnus-low-score-mark) - gnus-newsgroup-reads))) - t) - ;; Check NoCeM things. - (if (and gnus-use-nocem - (gnus-nocem-unwanted-article-p - (mail-header-id (car thread)))) - (progn - (setq gnus-newsgroup-unreads - (delq number gnus-newsgroup-unreads)) - t)))) - ;; Nope, invisible article. - 0 - ;; Ok, this article is to be visible, so we add it to the limit - ;; and return 1. - (push number gnus-newsgroup-limit) - 1)))) - -(defun gnus-expunge-thread (thread) - "Mark all articles in THREAD as read." - (let* ((number (mail-header-number (car thread)))) - (incf gnus-newsgroup-expunged-tally) - ;; We also mark as read here, if that's wanted. - (setq gnus-newsgroup-unreads - (delq number gnus-newsgroup-unreads)) - (if gnus-newsgroup-auto-expire - (push number gnus-newsgroup-expirable) - (push (cons number gnus-low-score-mark) - gnus-newsgroup-reads))) - ;; Go recursively through all subthreads. - (mapcar 'gnus-expunge-thread (cdr thread))) - -;; Summary article oriented commands - -(defun gnus-summary-refer-parent-article (n) - "Refer parent article N times. -If N is negative, go to ancestor -N instead. -The difference between N and the number of articles fetched is returned." - (interactive "p") - (let ((skip 1) - error header ref) - (when (not (natnump n)) - (setq skip (abs n) - n 1)) - (while (and (> n 0) - (not error)) - (setq header (gnus-summary-article-header)) - (if (and (eq (mail-header-number header) - (cdr gnus-article-current)) - (equal gnus-newsgroup-name - (car gnus-article-current))) - ;; If we try to find the parent of the currently - ;; displayed article, then we take a look at the actual - ;; References header, since this is slightly more - ;; reliable than the References field we got from the - ;; server. - (save-excursion - (set-buffer gnus-original-article-buffer) - (nnheader-narrow-to-headers) - (unless (setq ref (message-fetch-field "references")) - (setq ref (message-fetch-field "in-reply-to"))) - (widen)) - (setq ref - ;; It's not the current article, so we take a bet on - ;; the value we got from the server. - (mail-header-references header))) - (if (and ref - (not (equal ref ""))) - (unless (gnus-summary-refer-article (gnus-parent-id ref skip)) - (gnus-message 1 "Couldn't find parent")) - (gnus-message 1 "No references in article %d" - (gnus-summary-article-number)) - (setq error t)) - (decf n)) - (gnus-summary-position-point) - n)) - -(defun gnus-summary-refer-references () - "Fetch all articles mentioned in the References header. -Return the number of articles fetched." - (interactive) - (let ((ref (mail-header-references (gnus-summary-article-header))) - (current (gnus-summary-article-number)) - (n 0)) - (if (or (not ref) - (equal ref "")) - (error "No References in the current article") - ;; For each Message-ID in the References header... - (while (string-match "<[^>]*>" ref) - (incf n) - ;; ... fetch that article. - (gnus-summary-refer-article - (prog1 (match-string 0 ref) - (setq ref (substring ref (match-end 0)))))) - (gnus-summary-goto-subject current) - (gnus-summary-position-point) - n))) - -(defun gnus-summary-refer-thread (&optional limit) - "Fetch all articles in the current thread. -If LIMIT (the numerical prefix), fetch that many old headers instead -of what's specified by the `gnus-refer-thread-limit' variable." - (interactive "P") - (let ((id (mail-header-id (gnus-summary-article-header))) - (limit (if limit (prefix-numeric-value limit) - gnus-refer-thread-limit))) - ;; We want to fetch LIMIT *old* headers, but we also have to - ;; re-fetch all the headers in the current buffer, because many of - ;; them may be undisplayed. So we adjust LIMIT. - (when (numberp limit) - (incf limit (- gnus-newsgroup-end gnus-newsgroup-begin))) - (unless (eq gnus-fetch-old-headers 'invisible) - (gnus-message 5 "Fetching headers for %s..." gnus-newsgroup-name) - ;; Retrieve the headers and read them in. - (if (eq (gnus-retrieve-headers - (list gnus-newsgroup-end) gnus-newsgroup-name limit) - 'nov) - (gnus-build-all-threads) - (error "Can't fetch thread from backends that don't support NOV")) - (gnus-message 5 "Fetching headers for %s...done" gnus-newsgroup-name)) - (gnus-summary-limit-include-thread id))) - -(defun gnus-summary-refer-article (message-id &optional arg) - "Fetch an article specified by MESSAGE-ID. -If ARG (the prefix), fetch the article using `gnus-refer-article-method' -or `gnus-select-method', no matter what backend the article comes from." - (interactive "sMessage-ID: \nP") - (when (and (stringp message-id) - (not (zerop (length message-id)))) - ;; Construct the correct Message-ID if necessary. - ;; Suggested by tale@pawl.rpi.edu. - (unless (string-match "^<" message-id) - (setq message-id (concat "<" message-id))) - (unless (string-match ">$" message-id) - (setq message-id (concat message-id ">"))) - (let* ((header (gnus-id-to-header message-id)) - (sparse (and header - (gnus-summary-article-sparse-p - (mail-header-number header)) - (memq (mail-header-number header) - gnus-newsgroup-limit)))) - (cond - ;; If the article is present in the buffer we just go to it. - ((and header - (or (not (gnus-summary-article-sparse-p - (mail-header-number header))) - sparse)) - (prog1 - (gnus-summary-goto-article - (mail-header-number header) nil t) - (when sparse - (gnus-summary-update-article (mail-header-number header))))) - (t - ;; We fetch the article - (let ((gnus-override-method - (cond ((gnus-news-group-p gnus-newsgroup-name) - gnus-refer-article-method) - (arg - (or gnus-refer-article-method gnus-select-method)) - (t nil))) - number) - ;; Start the special refer-article method, if necessary. - (when (and gnus-refer-article-method - (gnus-news-group-p gnus-newsgroup-name)) - (gnus-check-server gnus-refer-article-method)) - ;; Fetch the header, and display the article. - (if (setq number (gnus-summary-insert-subject message-id)) - (gnus-summary-select-article nil nil nil number) - (gnus-message 3 "Couldn't fetch article %s" message-id)))))))) - -(defun gnus-summary-edit-parameters () - "Edit the group parameters of the current group." - (interactive) - (gnus-group-edit-group gnus-newsgroup-name 'params)) - -(defun gnus-summary-enter-digest-group (&optional force) - "Enter an nndoc group based on the current article. -If FORCE, force a digest interpretation. If not, try -to guess what the document format is." - (interactive "P") - (let ((conf gnus-current-window-configuration)) - (save-excursion - (gnus-summary-select-article)) - (setq gnus-current-window-configuration conf) - (let* ((name (format "%s-%d" - (gnus-group-prefixed-name - gnus-newsgroup-name (list 'nndoc "")) - (save-excursion - (set-buffer gnus-summary-buffer) - gnus-current-article))) - (ogroup gnus-newsgroup-name) - (params (append (gnus-info-params (gnus-get-info ogroup)) - (list (cons 'to-group ogroup)) - (list (cons 'save-article-group ogroup)))) - (case-fold-search t) - (buf (current-buffer)) - dig) - (save-excursion - (setq dig (nnheader-set-temp-buffer " *gnus digest buffer*")) - (insert-buffer-substring gnus-original-article-buffer) - ;; Remove lines that may lead nndoc to misinterpret the - ;; document type. - (narrow-to-region - (goto-char (point-min)) - (or (search-forward "\n\n" nil t) (point))) - (goto-char (point-min)) - (delete-matching-lines "^\\(Path\\):\\|^From ") - (widen)) - (unwind-protect - (if (gnus-group-read-ephemeral-group - name `(nndoc ,name (nndoc-address ,(get-buffer dig)) - (nndoc-article-type - ,(if force 'digest 'guess))) t) - ;; Make all postings to this group go to the parent group. - (nconc (gnus-info-params (gnus-get-info name)) - params) - ;; Couldn't select this doc group. - (switch-to-buffer buf) - (gnus-set-global-variables) - (gnus-configure-windows 'summary) - (gnus-message 3 "Article couldn't be entered?")) - (kill-buffer dig))))) - -(defun gnus-summary-read-document (n) - "Open a new group based on the current article(s). -This will allow you to read digests and other similar -documents as newsgroups. -Obeys the standard process/prefix convention." - (interactive "P") - (let* ((articles (gnus-summary-work-articles n)) - (ogroup gnus-newsgroup-name) - (params (append (gnus-info-params (gnus-get-info ogroup)) - (list (cons 'to-group ogroup)))) - article group egroup groups vgroup) - (while (setq article (pop articles)) - (setq group (format "%s-%d" gnus-newsgroup-name article)) - (gnus-summary-remove-process-mark article) - (when (gnus-summary-display-article article) - (save-excursion - (nnheader-temp-write nil - (insert-buffer-substring gnus-original-article-buffer) - ;; Remove some headers that may lead nndoc to make - ;; the wrong guess. - (message-narrow-to-head) - (goto-char (point-min)) - (delete-matching-lines "^\\(Path\\):\\|^From ") - (widen) - (if (setq egroup - (gnus-group-read-ephemeral-group - group `(nndoc ,group (nndoc-address ,(current-buffer)) - (nndoc-article-type guess)) - t nil t)) - (progn - ;; Make all postings to this group go to the parent group. - (nconc (gnus-info-params (gnus-get-info egroup)) - params) - (push egroup groups)) - ;; Couldn't select this doc group. - (gnus-error 3 "Article couldn't be entered")))))) - ;; Now we have selected all the documents. - (cond - ((not groups) - (error "None of the articles could be interpreted as documents")) - ((gnus-group-read-ephemeral-group - (setq vgroup (format - "nnvirtual:%s-%s" gnus-newsgroup-name - (format-time-string "%Y%m%dT%H%M%S" (current-time)))) - `(nnvirtual ,vgroup (nnvirtual-component-groups ,groups)) - t - (cons (current-buffer) 'summary))) - (t - (error "Couldn't select virtual nndoc group"))))) - -(defun gnus-summary-isearch-article (&optional regexp-p) - "Do incremental search forward on the current article. -If REGEXP-P (the prefix) is non-nil, do regexp isearch." - (interactive "P") - (gnus-summary-select-article) - (gnus-configure-windows 'article) - (gnus-eval-in-buffer-window gnus-article-buffer - (save-restriction - (widen) - (isearch-forward regexp-p)))) - -(defun gnus-summary-search-article-forward (regexp &optional backward) - "Search for an article containing REGEXP forward. -If BACKWARD, search backward instead." - (interactive - (list (read-string - (format "Search article %s (regexp%s): " - (if current-prefix-arg "backward" "forward") - (if gnus-last-search-regexp - (concat ", default " gnus-last-search-regexp) - ""))) - current-prefix-arg)) - (if (string-equal regexp "") - (setq regexp (or gnus-last-search-regexp "")) - (setq gnus-last-search-regexp regexp)) - (if (gnus-summary-search-article regexp backward) - (gnus-summary-show-thread) - (error "Search failed: \"%s\"" regexp))) - -(defun gnus-summary-search-article-backward (regexp) - "Search for an article containing REGEXP backward." - (interactive - (list (read-string - (format "Search article backward (regexp%s): " - (if gnus-last-search-regexp - (concat ", default " gnus-last-search-regexp) - ""))))) - (gnus-summary-search-article-forward regexp 'backward)) - -(defun gnus-summary-search-article (regexp &optional backward) - "Search for an article containing REGEXP. -Optional argument BACKWARD means do search for backward. -`gnus-select-article-hook' is not called during the search." - ;; We have to require this here to make sure that the following - ;; dynamic binding isn't shadowed by autoloading. - (require 'gnus-async) - (let ((gnus-select-article-hook nil) ;Disable hook. - (gnus-article-display-hook nil) - (gnus-mark-article-hook nil) ;Inhibit marking as read. - (gnus-use-article-prefetch nil) - (gnus-xmas-force-redisplay nil) ;Inhibit XEmacs redisplay. - (gnus-use-trees nil) ;Inhibit updating tree buffer. - (sum (current-buffer)) - (found nil) - point) - (gnus-save-hidden-threads - (gnus-summary-select-article) - (set-buffer gnus-article-buffer) - (when backward - (forward-line -1)) - (while (not found) - (gnus-message 7 "Searching article: %d..." (cdr gnus-article-current)) - (if (if backward - (re-search-backward regexp nil t) - (re-search-forward regexp nil t)) - ;; We found the regexp. - (progn - (setq found 'found) - (beginning-of-line) - (set-window-start - (get-buffer-window (current-buffer)) - (point)) - (forward-line 1) - (set-buffer sum) - (setq point (point))) - ;; We didn't find it, so we go to the next article. - (set-buffer sum) - (setq found 'not) - (while (eq found 'not) - (if (not (if backward (gnus-summary-find-prev) - (gnus-summary-find-next))) - ;; No more articles. - (setq found t) - ;; Select the next article and adjust point. - (unless (gnus-summary-article-sparse-p - (gnus-summary-article-number)) - (setq found nil) - (gnus-summary-select-article) - (set-buffer gnus-article-buffer) - (widen) - (goto-char (if backward (point-max) (point-min)))))))) - (gnus-message 7 "")) - ;; Return whether we found the regexp. - (when (eq found 'found) - (goto-char point) - (gnus-summary-show-thread) - (gnus-summary-goto-subject gnus-current-article) - (gnus-summary-position-point) - t))) - -(defun gnus-summary-find-matching (header regexp &optional backward unread - not-case-fold) - "Return a list of all articles that match REGEXP on HEADER. -The search stars on the current article and goes forwards unless -BACKWARD is non-nil. If BACKWARD is `all', do all articles. -If UNREAD is non-nil, only unread articles will -be taken into consideration. If NOT-CASE-FOLD, case won't be folded -in the comparisons." - (let ((data (if (eq backward 'all) gnus-newsgroup-data - (gnus-data-find-list - (gnus-summary-article-number) (gnus-data-list backward)))) - (func `(lambda (h) (,(intern (concat "mail-header-" header)) h))) - (case-fold-search (not not-case-fold)) - articles d) - (unless (fboundp (intern (concat "mail-header-" header))) - (error "%s is not a valid header" header)) - (while data - (setq d (car data)) - (and (or (not unread) ; We want all articles... - (gnus-data-unread-p d)) ; Or just unreads. - (vectorp (gnus-data-header d)) ; It's not a pseudo. - (string-match regexp (funcall func (gnus-data-header d))) ; Match. - (push (gnus-data-number d) articles)) ; Success! - (setq data (cdr data))) - (nreverse articles))) - -(defun gnus-summary-execute-command (header regexp command &optional backward) - "Search forward for an article whose HEADER matches REGEXP and execute COMMAND. -If HEADER is an empty string (or nil), the match is done on the entire -article. If BACKWARD (the prefix) is non-nil, search backward instead." - (interactive - (list (let ((completion-ignore-case t)) - (completing-read - "Header name: " - (mapcar (lambda (string) (list string)) - '("Number" "Subject" "From" "Lines" "Date" - "Message-ID" "Xref" "References" "Body")) - nil 'require-match)) - (read-string "Regexp: ") - (read-key-sequence "Command: ") - current-prefix-arg)) - (when (equal header "Body") - (setq header "")) - ;; Hidden thread subtrees must be searched as well. - (gnus-summary-show-all-threads) - ;; We don't want to change current point nor window configuration. - (save-excursion - (save-window-excursion - (gnus-message 6 "Executing %s..." (key-description command)) - ;; We'd like to execute COMMAND interactively so as to give arguments. - (gnus-execute header regexp - `(call-interactively ',(key-binding command)) - backward) - (gnus-message 6 "Executing %s...done" (key-description command))))) - -(defun gnus-summary-beginning-of-article () - "Scroll the article back to the beginning." - (interactive) - (gnus-summary-select-article) - (gnus-configure-windows 'article) - (gnus-eval-in-buffer-window gnus-article-buffer - (widen) - (goto-char (point-min)) - (when gnus-page-broken - (gnus-narrow-to-page)))) - -(defun gnus-summary-end-of-article () - "Scroll to the end of the article." - (interactive) - (gnus-summary-select-article) - (gnus-configure-windows 'article) - (gnus-eval-in-buffer-window gnus-article-buffer - (widen) - (goto-char (point-max)) - (recenter -3) - (when gnus-page-broken - (gnus-narrow-to-page)))) - -(defun gnus-summary-print-article (&optional filename n) - "Generate and print a PostScript image of the N next (mail) articles. - -If N is negative, print the N previous articles. If N is nil and articles -have been marked with the process mark, print these instead. - -If the optional second argument FILENAME is nil, send the image to the -printer. If FILENAME is a string, save the PostScript image in a file with -that name. If FILENAME is a number, prompt the user for the name of the file -to save in." - (interactive (list (ps-print-preprint current-prefix-arg) - current-prefix-arg)) - (dolist (article (gnus-summary-work-articles n)) - (gnus-summary-select-article nil nil 'pseudo article) - (gnus-eval-in-buffer-window gnus-article-buffer - (let ((buffer (generate-new-buffer " *print*"))) - (unwind-protect - (progn - (copy-to-buffer buffer (point-min) (point-max)) - (set-buffer buffer) - (gnus-article-delete-invisible-text) - (let ((ps-left-header - (list - (concat "(" - (mail-header-subject gnus-current-headers) ")") - (concat "(" - (mail-header-from gnus-current-headers) ")"))) - (ps-right-header - (list - "/pagenumberstring load" - (concat "(" - (mail-header-date gnus-current-headers) ")")))) - (gnus-run-hooks 'gnus-ps-print-hook) - (save-excursion - (ps-print-buffer-with-faces filename)))) - (kill-buffer buffer)))))) - -(defun gnus-summary-show-article (&optional arg) - "Force re-fetching of the current article. -If ARG (the prefix) is non-nil, show the raw article without any -article massaging functions being run." - (interactive "P") - (if (not arg) - ;; Select the article the normal way. - (gnus-summary-select-article nil 'force) - ;; Bind the article treatment functions to nil. - (let ((gnus-have-all-headers t) - gnus-article-display-hook - gnus-article-prepare-hook - gnus-break-pages - gnus-show-mime - gnus-visual) - (gnus-summary-select-article nil 'force))) - (gnus-summary-goto-subject gnus-current-article) - (gnus-summary-position-point)) - -(defun gnus-summary-verbose-headers (&optional arg) - "Toggle permanent full header display. -If ARG is a positive number, turn header display on. -If ARG is a negative number, turn header display off." - (interactive "P") - (setq gnus-show-all-headers - (cond ((or (not (numberp arg)) - (zerop arg)) - (not gnus-show-all-headers)) - ((natnump arg) - t))) - (gnus-summary-show-article)) - -(defun gnus-summary-toggle-header (&optional arg) - "Show the headers if they are hidden, or hide them if they are shown. -If ARG is a positive number, show the entire header. -If ARG is a negative number, hide the unwanted header lines." - (interactive "P") - (save-excursion - (set-buffer gnus-article-buffer) - (let* ((buffer-read-only nil) - (inhibit-point-motion-hooks t) - (hidden (text-property-any - (goto-char (point-min)) (search-forward "\n\n") - 'invisible t)) - e) - (goto-char (point-min)) - (when (search-forward "\n\n" nil t) - (delete-region (point-min) (1- (point)))) - (goto-char (point-min)) - (save-excursion - (set-buffer gnus-original-article-buffer) - (goto-char (point-min)) - (setq e (1- (or (search-forward "\n\n" nil t) (point-max))))) - (insert-buffer-substring gnus-original-article-buffer 1 e) - (let ((article-inhibit-hiding t)) - (gnus-run-hooks 'gnus-article-display-hook)) - (when (or (not hidden) (and (numberp arg) (< arg 0))) - (gnus-article-hide-headers))))) - -(defun gnus-summary-show-all-headers () - "Make all header lines visible." - (interactive) - (gnus-article-show-all-headers)) - -(defun gnus-summary-toggle-mime (&optional arg) - "Toggle MIME processing. -If ARG is a positive number, turn MIME processing on." - (interactive "P") - (setq gnus-show-mime - (if (null arg) (not gnus-show-mime) - (> (prefix-numeric-value arg) 0))) - (gnus-summary-select-article t 'force)) - -(defun gnus-summary-caesar-message (&optional arg) - "Caesar rotate the current article by 13. -The numerical prefix specifies how many places to rotate each letter -forward." - (interactive "P") - (gnus-summary-select-article) - (let ((mail-header-separator "")) - (gnus-eval-in-buffer-window gnus-article-buffer - (save-restriction - (widen) - (let ((start (window-start)) - buffer-read-only) - (message-caesar-buffer-body arg) - (set-window-start (get-buffer-window (current-buffer)) start)))))) - -(defun gnus-summary-stop-page-breaking () - "Stop page breaking in the current article." - (interactive) - (gnus-summary-select-article) - (gnus-eval-in-buffer-window gnus-article-buffer - (widen) - (when (gnus-visual-p 'page-marker) - (let ((buffer-read-only nil)) - (gnus-remove-text-with-property 'gnus-prev) - (gnus-remove-text-with-property 'gnus-next)) - (setq gnus-page-broken nil)))) - -(defun gnus-summary-move-article (&optional n to-newsgroup - select-method action) - "Move the current article to a different newsgroup. -If N is a positive number, move the N next articles. -If N is a negative number, move the N previous articles. -If N is nil and any articles have been marked with the process mark, -move those articles instead. -If TO-NEWSGROUP is string, do not prompt for a newsgroup to move to. -If SELECT-METHOD is non-nil, do not move to a specific newsgroup, but -re-spool using this method. - -For this function to work, both the current newsgroup and the -newsgroup that you want to move to have to support the `request-move' -and `request-accept' functions." - (interactive "P") - (unless action - (setq action 'move)) - ;; Disable marking as read. - (let (gnus-mark-article-hook) - (save-window-excursion - (gnus-summary-select-article))) - ;; Check whether the source group supports the required functions. - (cond ((and (eq action 'move) - (not (gnus-check-backend-function - 'request-move-article gnus-newsgroup-name))) - (error "The current group does not support article moving")) - ((and (eq action 'crosspost) - (not (gnus-check-backend-function - 'request-replace-article gnus-newsgroup-name))) - (error "The current group does not support article editing"))) - (let ((articles (gnus-summary-work-articles n)) - (prefix (gnus-group-real-prefix gnus-newsgroup-name)) - (names '((move "Move" "Moving") - (copy "Copy" "Copying") - (crosspost "Crosspost" "Crossposting"))) - (copy-buf (save-excursion - (nnheader-set-temp-buffer " *copy article*"))) - art-group to-method new-xref article to-groups) - (unless (assq action names) - (error "Unknown action %s" action)) - ;; Read the newsgroup name. - (when (and (not to-newsgroup) - (not select-method)) - (setq to-newsgroup - (gnus-read-move-group-name - (cadr (assq action names)) - (symbol-value (intern (format "gnus-current-%s-group" action))) - articles prefix)) - (set (intern (format "gnus-current-%s-group" action)) to-newsgroup)) - (setq to-method (or select-method - (gnus-group-name-to-method to-newsgroup))) - ;; Check the method we are to move this article to... - (unless (gnus-check-backend-function - 'request-accept-article (car to-method)) - (error "%s does not support article copying" (car to-method))) - (unless (gnus-check-server to-method) - (error "Can't open server %s" (car to-method))) - (gnus-message 6 "%s to %s: %s..." - (caddr (assq action names)) - (or (car select-method) to-newsgroup) articles) - (while articles - (setq article (pop articles)) - (setq - art-group - (cond - ;; Move the article. - ((eq action 'move) - ;; Remove this article from future suppression. - (gnus-dup-unsuppress-article article) - (gnus-request-move-article - article ; Article to move - gnus-newsgroup-name ; From newsgroup - (nth 1 (gnus-find-method-for-group - gnus-newsgroup-name)) ; Server - (list 'gnus-request-accept-article - to-newsgroup (list 'quote select-method) - (not articles)) ; Accept form - (not articles))) ; Only save nov last time - ;; Copy the article. - ((eq action 'copy) - (save-excursion - (set-buffer copy-buf) - (when (gnus-request-article-this-buffer article gnus-newsgroup-name) - (gnus-request-accept-article - to-newsgroup select-method (not articles))))) - ;; Crosspost the article. - ((eq action 'crosspost) - (let ((xref (message-tokenize-header - (mail-header-xref (gnus-summary-article-header article)) - " "))) - (setq new-xref (concat (gnus-group-real-name gnus-newsgroup-name) - ":" article)) - (unless xref - (setq xref (list (system-name)))) - (setq new-xref - (concat - (mapconcat 'identity - (delete "Xref:" (delete new-xref xref)) - " ") - " " new-xref)) - (save-excursion - (set-buffer copy-buf) - ;; First put the article in the destination group. - (gnus-request-article-this-buffer article gnus-newsgroup-name) - (when (consp (setq art-group - (gnus-request-accept-article - to-newsgroup select-method (not articles)))) - (setq new-xref (concat new-xref " " (car art-group) - ":" (cdr art-group))) - ;; Now we have the new Xrefs header, so we insert - ;; it and replace the new article. - (nnheader-replace-header "Xref" new-xref) - (gnus-request-replace-article - (cdr art-group) to-newsgroup (current-buffer)) - art-group)))))) - (cond - ((not art-group) - (gnus-message 1 "Couldn't %s article %s" - (cadr (assq action names)) article)) - ((and (eq art-group 'junk) - (eq action 'move)) - (gnus-summary-mark-article article gnus-canceled-mark) - (gnus-message 4 "Deleted article %s" article)) - (t - (let* ((pto-group (gnus-group-prefixed-name - (car art-group) to-method)) - (entry - (gnus-gethash pto-group gnus-newsrc-hashtb)) - (info (nth 2 entry)) - (to-group (gnus-info-group info))) - ;; Update the group that has been moved to. - (when (and info - (memq action '(move copy))) - (unless (member to-group to-groups) - (push to-group to-groups)) - - (unless (memq article gnus-newsgroup-unreads) - (gnus-info-set-read - info (gnus-add-to-range (gnus-info-read info) - (list (cdr art-group))))) - - ;; Copy any marks over to the new group. - (let ((marks gnus-article-mark-lists) - (to-article (cdr art-group))) - - ;; See whether the article is to be put in the cache. - (when gnus-use-cache - (gnus-cache-possibly-enter-article - to-group to-article - (let ((header (copy-sequence - (gnus-summary-article-header article)))) - (mail-header-set-number header to-article) - header) - (memq article gnus-newsgroup-marked) - (memq article gnus-newsgroup-dormant) - (memq article gnus-newsgroup-unreads))) - - (when (and (equal to-group gnus-newsgroup-name) - (not (memq article gnus-newsgroup-unreads))) - ;; Mark this article as read in this group. - (push (cons to-article gnus-read-mark) gnus-newsgroup-reads) - (setcdr (gnus-active to-group) to-article) - (setcdr gnus-newsgroup-active to-article)) - - (while marks - (when (memq article (symbol-value - (intern (format "gnus-newsgroup-%s" - (caar marks))))) - ;; If the other group is the same as this group, - ;; then we have to add the mark to the list. - (when (equal to-group gnus-newsgroup-name) - (set (intern (format "gnus-newsgroup-%s" (caar marks))) - (cons to-article - (symbol-value - (intern (format "gnus-newsgroup-%s" - (caar marks))))))) - ;; Copy the marks to other group. - (gnus-add-marked-articles - to-group (cdar marks) (list to-article) info)) - (setq marks (cdr marks))) - - (gnus-dribble-enter - (concat "(gnus-group-set-info '" - (gnus-prin1-to-string (gnus-get-info to-group)) - ")")))) - - ;; Update the Xref header in this article to point to - ;; the new crossposted article we have just created. - (when (eq action 'crosspost) - (save-excursion - (set-buffer copy-buf) - (gnus-request-article-this-buffer article gnus-newsgroup-name) - (nnheader-replace-header "Xref" new-xref) - (gnus-request-replace-article - article gnus-newsgroup-name (current-buffer))))) - - ;;;!!!Why is this necessary? - (set-buffer gnus-summary-buffer) - - (gnus-summary-goto-subject article) - (when (eq action 'move) - (gnus-summary-mark-article article gnus-canceled-mark)))) - (gnus-summary-remove-process-mark article)) - ;; Re-activate all groups that have been moved to. - (while to-groups - (save-excursion - (set-buffer gnus-group-buffer) - (when (gnus-group-goto-group (car to-groups) t) - (gnus-group-get-new-news-this-group 1 t)) - (pop to-groups))) - - (gnus-kill-buffer copy-buf) - (gnus-summary-position-point) - (gnus-set-mode-line 'summary))) - -(defun gnus-summary-copy-article (&optional n to-newsgroup select-method) - "Move the current article to a different newsgroup. -If TO-NEWSGROUP is string, do not prompt for a newsgroup to move to. -If SELECT-METHOD is non-nil, do not move to a specific newsgroup, but -re-spool using this method." - (interactive "P") - (gnus-summary-move-article n to-newsgroup select-method 'copy)) - -(defun gnus-summary-crosspost-article (&optional n) - "Crosspost the current article to some other group." - (interactive "P") - (gnus-summary-move-article n nil nil 'crosspost)) - -(defcustom gnus-summary-respool-default-method nil - "Default method for respooling an article. -If nil, use to the current newsgroup method." - :type '(choice (gnus-select-method :value (nnml "")) - (const nil)) - :group 'gnus-summary-mail) - -(defun gnus-summary-respool-article (&optional n method) - "Respool the current article. -The article will be squeezed through the mail spooling process again, -which means that it will be put in some mail newsgroup or other -depending on `nnmail-split-methods'. -If N is a positive number, respool the N next articles. -If N is a negative number, respool the N previous articles. -If N is nil and any articles have been marked with the process mark, -respool those articles instead. - -Respooling can be done both from mail groups and \"real\" newsgroups. -In the former case, the articles in question will be moved from the -current group into whatever groups they are destined to. In the -latter case, they will be copied into the relevant groups." - (interactive - (list current-prefix-arg - (let* ((methods (gnus-methods-using 'respool)) - (methname - (symbol-name (or gnus-summary-respool-default-method - (car (gnus-find-method-for-group - gnus-newsgroup-name))))) - (method - (gnus-completing-read - methname "What backend do you want to use when respooling?" - methods nil t nil 'gnus-mail-method-history)) - ms) - (cond - ((zerop (length (setq ms (gnus-servers-using-backend - (intern method))))) - (list (intern method) "")) - ((= 1 (length ms)) - (car ms)) - (t - (let ((ms-alist (mapcar (lambda (m) (cons (cadr m) m)) ms))) - (cdr (assoc (completing-read "Server name: " ms-alist nil t) - ms-alist)))))))) - (unless method - (error "No method given for respooling")) - (if (assoc (symbol-name - (car (gnus-find-method-for-group gnus-newsgroup-name))) - (gnus-methods-using 'respool)) - (gnus-summary-move-article n nil method) - (gnus-summary-copy-article n nil method))) - -(defun gnus-summary-import-article (file) - "Import an arbitrary file into a mail newsgroup." - (interactive "fImport file: ") - (let ((group gnus-newsgroup-name) - (now (current-time)) - atts lines) - (unless (gnus-check-backend-function 'request-accept-article group) - (error "%s does not support article importing" group)) - (or (file-readable-p file) - (not (file-regular-p file)) - (error "Can't read %s" file)) - (save-excursion - (set-buffer (gnus-get-buffer-create " *import file*")) - (buffer-disable-undo (current-buffer)) - (erase-buffer) - (nnheader-insert-file-contents file) - (goto-char (point-min)) - (unless (nnheader-article-p) - ;; This doesn't look like an article, so we fudge some headers. - (setq atts (file-attributes file) - lines (count-lines (point-min) (point-max))) - (insert "From: " (read-string "From: ") "\n" - "Subject: " (read-string "Subject: ") "\n" - "Date: " (timezone-make-date-arpa-standard - (current-time-string (nth 5 atts)) - (current-time-zone now) - (current-time-zone now)) - "\n" - "Message-ID: " (message-make-message-id) "\n" - "Lines: " (int-to-string lines) "\n" - "Chars: " (int-to-string (nth 7 atts)) "\n\n")) - (gnus-request-accept-article group nil t) - (kill-buffer (current-buffer))))) - -(defun gnus-summary-article-posted-p () - "Say whether the current (mail) article is available from `gnus-select-method' as well. -This will be the case if the article has both been mailed and posted." - (interactive) - (let ((id (mail-header-references (gnus-summary-article-header))) - (gnus-override-method - (or gnus-refer-article-method gnus-select-method))) - (if (gnus-request-head id "") - (gnus-message 2 "The current message was found on %s" - gnus-override-method) - (gnus-message 2 "The current message couldn't be found on %s" - gnus-override-method) - nil))) - -(defun gnus-summary-expire-articles (&optional now) - "Expire all articles that are marked as expirable in the current group." - (interactive) - (when (gnus-check-backend-function - 'request-expire-articles gnus-newsgroup-name) - ;; This backend supports expiry. - (let* ((total (gnus-group-total-expirable-p gnus-newsgroup-name)) - (expirable (if total - (progn - ;; We need to update the info for - ;; this group for `gnus-list-of-read-articles' - ;; to give us the right answer. - (gnus-run-hooks 'gnus-exit-group-hook) - (gnus-summary-update-info) - (gnus-list-of-read-articles gnus-newsgroup-name)) - (setq gnus-newsgroup-expirable - (sort gnus-newsgroup-expirable '<)))) - (expiry-wait (if now 'immediate - (gnus-group-find-parameter - gnus-newsgroup-name 'expiry-wait))) - es) - (when expirable - ;; There are expirable articles in this group, so we run them - ;; through the expiry process. - (gnus-message 6 "Expiring articles...") - ;; The list of articles that weren't expired is returned. - (save-excursion - (if expiry-wait - (let ((nnmail-expiry-wait-function nil) - (nnmail-expiry-wait expiry-wait)) - (setq es (gnus-request-expire-articles - expirable gnus-newsgroup-name))) - (setq es (gnus-request-expire-articles - expirable gnus-newsgroup-name)))) - (unless total - (setq gnus-newsgroup-expirable es)) - ;; We go through the old list of expirable, and mark all - ;; really expired articles as nonexistent. - (unless (eq es expirable) ;If nothing was expired, we don't mark. - (let ((gnus-use-cache nil)) - (while expirable - (unless (memq (car expirable) es) - (when (gnus-data-find (car expirable)) - (gnus-summary-mark-article - (car expirable) gnus-canceled-mark))) - (setq expirable (cdr expirable))))) - (gnus-message 6 "Expiring articles...done"))))) - -(defun gnus-summary-expire-articles-now () - "Expunge all expirable articles in the current group. -This means that *all* articles that are marked as expirable will be -deleted forever, right now." - (interactive) - (or gnus-expert-user - (gnus-yes-or-no-p - "Are you really, really, really sure you want to delete all these messages? ") - (error "Phew!")) - (gnus-summary-expire-articles t)) - -;; Suggested by Jack Vinson . -(defun gnus-summary-delete-article (&optional n) - "Delete the N next (mail) articles. -This command actually deletes articles. This is not a marking -command. The article will disappear forever from your life, never to -return. -If N is negative, delete backwards. -If N is nil and articles have been marked with the process mark, -delete these instead." - (interactive "P") - (unless (gnus-check-backend-function 'request-expire-articles - gnus-newsgroup-name) - (error "The current newsgroup does not support article deletion")) - ;; Compute the list of articles to delete. - (let ((articles (sort (copy-sequence (gnus-summary-work-articles n)) '<)) - not-deleted) - (if (and gnus-novice-user - (not (gnus-yes-or-no-p - (format "Do you really want to delete %s forever? " - (if (> (length articles) 1) - (format "these %s articles" (length articles)) - "this article"))))) - () - ;; Delete the articles. - (setq not-deleted (gnus-request-expire-articles - articles gnus-newsgroup-name 'force)) - (while articles - (gnus-summary-remove-process-mark (car articles)) - ;; The backend might not have been able to delete the article - ;; after all. - (unless (memq (car articles) not-deleted) - (gnus-summary-mark-article (car articles) gnus-canceled-mark)) - (setq articles (cdr articles))) - (when not-deleted - (gnus-message 4 "Couldn't delete articles %s" not-deleted))) - (gnus-summary-position-point) - (gnus-set-mode-line 'summary) - not-deleted)) - -(defun gnus-summary-edit-article (&optional force) - "Edit the current article. -This will have permanent effect only in mail groups. -If FORCE is non-nil, allow editing of articles even in read-only -groups." - (interactive "P") - (save-excursion - (set-buffer gnus-summary-buffer) - (gnus-set-global-variables) - (when (and (not force) - (gnus-group-read-only-p)) - (error "The current newsgroup does not support article editing")) - ;; Select article if needed. - (unless (eq (gnus-summary-article-number) - gnus-current-article) - (gnus-summary-select-article t)) - (gnus-article-date-original) - (gnus-article-edit-article - `(lambda (no-highlight) - (gnus-summary-edit-article-done - ,(or (mail-header-references gnus-current-headers) "") - ,(gnus-group-read-only-p) ,gnus-summary-buffer no-highlight))))) - -(defalias 'gnus-summary-edit-article-postpone 'gnus-article-edit-exit) - -(defun gnus-summary-edit-article-done (&optional references read-only buffer - no-highlight) - "Make edits to the current article permanent." - (interactive) - ;; Replace the article. - (let ((buf (current-buffer))) - (nnheader-temp-write nil - (insert-buffer buf) - (if (and (not read-only) - (not (gnus-request-replace-article - (cdr gnus-article-current) (car gnus-article-current) - (current-buffer)))) - (error "Couldn't replace article") - ;; Update the summary buffer. - (if (and references - (equal (message-tokenize-header references " ") - (message-tokenize-header - (or (message-fetch-field "references") "") " "))) - ;; We only have to update this line. - (save-excursion - (save-restriction - (message-narrow-to-head) - (let ((head (buffer-string)) - header) - (nnheader-temp-write nil - (insert (format "211 %d Article retrieved.\n" - (cdr gnus-article-current))) - (insert head) - (insert ".\n") - (let ((nntp-server-buffer (current-buffer))) - (setq header (car (gnus-get-newsgroup-headers - (save-excursion - (set-buffer gnus-summary-buffer) - gnus-newsgroup-dependencies) - t)))) - (save-excursion - (set-buffer gnus-summary-buffer) - (gnus-data-set-header - (gnus-data-find (cdr gnus-article-current)) - header) - (gnus-summary-update-article-line - (cdr gnus-article-current) header)))))) - ;; Update threads. - (set-buffer (or buffer gnus-summary-buffer)) - (gnus-summary-update-article (cdr gnus-article-current))) - ;; Prettify the article buffer again. - (unless no-highlight - (save-excursion - (set-buffer gnus-article-buffer) - (gnus-run-hooks 'gnus-article-display-hook) - (set-buffer gnus-original-article-buffer) - (gnus-request-article - (cdr gnus-article-current) - (car gnus-article-current) (current-buffer)))) - ;; Prettify the summary buffer line. - (when (gnus-visual-p 'summary-highlight 'highlight) - (gnus-run-hooks 'gnus-visual-mark-article-hook)))))) - -(defun gnus-summary-edit-wash (key) - "Perform editing command KEY in the article buffer." - (interactive - (list - (progn - (message "%s" (concat (this-command-keys) "- ")) - (read-char)))) - (message "") - (gnus-summary-edit-article) - (execute-kbd-macro (concat (this-command-keys) key)) - (gnus-article-edit-done)) - -;;; Respooling - -(defun gnus-summary-respool-query (&optional silent trace) - "Query where the respool algorithm would put this article." - (interactive) - (let (gnus-mark-article-hook) - (gnus-summary-select-article) - (save-excursion - (set-buffer gnus-original-article-buffer) - (save-restriction - (message-narrow-to-head) - (let ((groups (nnmail-article-group 'identity trace))) - (unless silent - (if groups - (message "This message would go to %s" - (mapconcat 'car groups ", ")) - (message "This message would go to no groups")) - groups)))))) - -(defun gnus-summary-respool-trace () - "Trace where the respool algorithm would put this article. -Display a buffer showing all fancy splitting patterns which matched." - (interactive) - (gnus-summary-respool-query nil t)) - -;; Summary marking commands. - -(defun gnus-summary-kill-same-subject-and-select (&optional unmark) - "Mark articles which has the same subject as read, and then select the next. -If UNMARK is positive, remove any kind of mark. -If UNMARK is negative, tick articles." - (interactive "P") - (when unmark - (setq unmark (prefix-numeric-value unmark))) - (let ((count - (gnus-summary-mark-same-subject - (gnus-summary-article-subject) unmark))) - ;; Select next unread article. If auto-select-same mode, should - ;; select the first unread article. - (gnus-summary-next-article t (and gnus-auto-select-same - (gnus-summary-article-subject))) - (gnus-message 7 "%d article%s marked as %s" - count (if (= count 1) " is" "s are") - (if unmark "unread" "read")))) - -(defun gnus-summary-kill-same-subject (&optional unmark) - "Mark articles which has the same subject as read. -If UNMARK is positive, remove any kind of mark. -If UNMARK is negative, tick articles." - (interactive "P") - (when unmark - (setq unmark (prefix-numeric-value unmark))) - (let ((count - (gnus-summary-mark-same-subject - (gnus-summary-article-subject) unmark))) - ;; If marked as read, go to next unread subject. - (when (null unmark) - ;; Go to next unread subject. - (gnus-summary-next-subject 1 t)) - (gnus-message 7 "%d articles are marked as %s" - count (if unmark "unread" "read")))) - -(defun gnus-summary-mark-same-subject (subject &optional unmark) - "Mark articles with same SUBJECT as read, and return marked number. -If optional argument UNMARK is positive, remove any kinds of marks. -If optional argument UNMARK is negative, mark articles as unread instead." - (let ((count 1)) - (save-excursion - (cond - ((null unmark) ; Mark as read. - (while (and - (progn - (gnus-summary-mark-article-as-read gnus-killed-mark) - (gnus-summary-show-thread) t) - (gnus-summary-find-subject subject)) - (setq count (1+ count)))) - ((> unmark 0) ; Tick. - (while (and - (progn - (gnus-summary-mark-article-as-unread gnus-ticked-mark) - (gnus-summary-show-thread) t) - (gnus-summary-find-subject subject)) - (setq count (1+ count)))) - (t ; Mark as unread. - (while (and - (progn - (gnus-summary-mark-article-as-unread gnus-unread-mark) - (gnus-summary-show-thread) t) - (gnus-summary-find-subject subject)) - (setq count (1+ count))))) - (gnus-set-mode-line 'summary) - ;; Return the number of marked articles. - count))) - -(defun gnus-summary-mark-as-processable (n &optional unmark) - "Set the process mark on the next N articles. -If N is negative, mark backward instead. If UNMARK is non-nil, remove -the process mark instead. The difference between N and the actual -number of articles marked is returned." - (interactive "p") - (let ((backward (< n 0)) - (n (abs n))) - (while (and - (> n 0) - (if unmark - (gnus-summary-remove-process-mark - (gnus-summary-article-number)) - (gnus-summary-set-process-mark (gnus-summary-article-number))) - (zerop (gnus-summary-next-subject (if backward -1 1) nil t))) - (setq n (1- n))) - (when (/= 0 n) - (gnus-message 7 "No more articles")) - (gnus-summary-recenter) - (gnus-summary-position-point) - n)) - -(defun gnus-summary-unmark-as-processable (n) - "Remove the process mark from the next N articles. -If N is negative, unmark backward instead. The difference between N and -the actual number of articles unmarked is returned." - (interactive "p") - (gnus-summary-mark-as-processable n t)) - -(defun gnus-summary-unmark-all-processable () - "Remove the process mark from all articles." - (interactive) - (save-excursion - (while gnus-newsgroup-processable - (gnus-summary-remove-process-mark (car gnus-newsgroup-processable)))) - (gnus-summary-position-point)) - -(defun gnus-summary-mark-as-expirable (n) - "Mark N articles forward as expirable. -If N is negative, mark backward instead. The difference between N and -the actual number of articles marked is returned." - (interactive "p") - (gnus-summary-mark-forward n gnus-expirable-mark)) - -(defun gnus-summary-mark-article-as-replied (article) - "Mark ARTICLE replied and update the summary line." - (push article gnus-newsgroup-replied) - (let ((buffer-read-only nil)) - (when (gnus-summary-goto-subject article) - (gnus-summary-update-secondary-mark article)))) - -(defun gnus-summary-set-bookmark (article) - "Set a bookmark in current article." - (interactive (list (gnus-summary-article-number))) - (when (or (not (get-buffer gnus-article-buffer)) - (not gnus-current-article) - (not gnus-article-current) - (not (equal gnus-newsgroup-name (car gnus-article-current)))) - (error "No current article selected")) - ;; Remove old bookmark, if one exists. - (let ((old (assq article gnus-newsgroup-bookmarks))) - (when old - (setq gnus-newsgroup-bookmarks - (delq old gnus-newsgroup-bookmarks)))) - ;; Set the new bookmark, which is on the form - ;; (article-number . line-number-in-body). - (push - (cons article - (save-excursion - (set-buffer gnus-article-buffer) - (count-lines - (min (point) - (save-excursion - (goto-char (point-min)) - (search-forward "\n\n" nil t) - (point))) - (point)))) - gnus-newsgroup-bookmarks) - (gnus-message 6 "A bookmark has been added to the current article.")) - -(defun gnus-summary-remove-bookmark (article) - "Remove the bookmark from the current article." - (interactive (list (gnus-summary-article-number))) - ;; Remove old bookmark, if one exists. - (let ((old (assq article gnus-newsgroup-bookmarks))) - (if old - (progn - (setq gnus-newsgroup-bookmarks - (delq old gnus-newsgroup-bookmarks)) - (gnus-message 6 "Removed bookmark.")) - (gnus-message 6 "No bookmark in current article.")))) - -;; Suggested by Daniel Quinlan . -(defun gnus-summary-mark-as-dormant (n) - "Mark N articles forward as dormant. -If N is negative, mark backward instead. The difference between N and -the actual number of articles marked is returned." - (interactive "p") - (gnus-summary-mark-forward n gnus-dormant-mark)) - -(defun gnus-summary-set-process-mark (article) - "Set the process mark on ARTICLE and update the summary line." - (setq gnus-newsgroup-processable - (cons article - (delq article gnus-newsgroup-processable))) - (when (gnus-summary-goto-subject article) - (gnus-summary-show-thread) - (gnus-summary-goto-subject article) - (gnus-summary-update-secondary-mark article))) - -(defun gnus-summary-remove-process-mark (article) - "Remove the process mark from ARTICLE and update the summary line." - (setq gnus-newsgroup-processable (delq article gnus-newsgroup-processable)) - (when (gnus-summary-goto-subject article) - (gnus-summary-show-thread) - (gnus-summary-goto-subject article) - (gnus-summary-update-secondary-mark article))) - -(defun gnus-summary-set-saved-mark (article) - "Set the process mark on ARTICLE and update the summary line." - (push article gnus-newsgroup-saved) - (when (gnus-summary-goto-subject article) - (gnus-summary-update-secondary-mark article))) - -(defun gnus-summary-mark-forward (n &optional mark no-expire) - "Mark N articles as read forwards. -If N is negative, mark backwards instead. Mark with MARK, ?r by default. -The difference between N and the actual number of articles marked is -returned." - (interactive "p") - (let ((backward (< n 0)) - (gnus-summary-goto-unread - (and gnus-summary-goto-unread - (not (eq gnus-summary-goto-unread 'never)) - (not (memq mark (list gnus-unread-mark - gnus-ticked-mark gnus-dormant-mark))))) - (n (abs n)) - (mark (or mark gnus-del-mark))) - (while (and (> n 0) - (gnus-summary-mark-article nil mark no-expire) - (zerop (gnus-summary-next-subject - (if backward -1 1) - (and gnus-summary-goto-unread - (not (eq gnus-summary-goto-unread 'never))) - t))) - (setq n (1- n))) - (when (/= 0 n) - (gnus-message 7 "No more %sarticles" (if mark "" "unread "))) - (gnus-summary-recenter) - (gnus-summary-position-point) - (gnus-set-mode-line 'summary) - n)) - -(defun gnus-summary-mark-article-as-read (mark) - "Mark the current article quickly as read with MARK." - (let ((article (gnus-summary-article-number))) - (setq gnus-newsgroup-unreads (delq article gnus-newsgroup-unreads)) - (setq gnus-newsgroup-marked (delq article gnus-newsgroup-marked)) - (setq gnus-newsgroup-dormant (delq article gnus-newsgroup-dormant)) - (push (cons article mark) gnus-newsgroup-reads) - ;; Possibly remove from cache, if that is used. - (when gnus-use-cache - (gnus-cache-enter-remove-article article)) - ;; Allow the backend to change the mark. - (setq mark (gnus-request-update-mark gnus-newsgroup-name article mark)) - ;; Check for auto-expiry. - (when (and gnus-newsgroup-auto-expire - (or (= mark gnus-killed-mark) (= mark gnus-del-mark) - (= mark gnus-catchup-mark) (= mark gnus-low-score-mark) - (= mark gnus-ancient-mark) - (= mark gnus-read-mark) (= mark gnus-souped-mark) - (= mark gnus-duplicate-mark))) - (setq mark gnus-expirable-mark) - ;; Let the backend know about the mark change. - (setq mark (gnus-request-update-mark gnus-newsgroup-name article mark)) - (push article gnus-newsgroup-expirable)) - ;; Set the mark in the buffer. - (gnus-summary-update-mark mark 'unread) - t)) - -(defun gnus-summary-mark-article-as-unread (mark) - "Mark the current article quickly as unread with MARK." - (let* ((article (gnus-summary-article-number)) - (old-mark (gnus-summary-article-mark article))) - ;; Let the backend know about the mark change. - (setq mark (gnus-request-update-mark gnus-newsgroup-name article mark)) - (if (eq mark old-mark) - t - (if (<= article 0) - (progn - (gnus-error 1 "Can't mark negative article numbers") - nil) - (setq gnus-newsgroup-marked (delq article gnus-newsgroup-marked)) - (setq gnus-newsgroup-dormant (delq article gnus-newsgroup-dormant)) - (setq gnus-newsgroup-expirable (delq article gnus-newsgroup-expirable)) - (setq gnus-newsgroup-reads (delq article gnus-newsgroup-reads)) - (cond ((= mark gnus-ticked-mark) - (push article gnus-newsgroup-marked)) - ((= mark gnus-dormant-mark) - (push article gnus-newsgroup-dormant)) - (t - (push article gnus-newsgroup-unreads))) - (gnus-pull article gnus-newsgroup-reads) - - ;; See whether the article is to be put in the cache. - (and gnus-use-cache - (vectorp (gnus-summary-article-header article)) - (save-excursion - (gnus-cache-possibly-enter-article - gnus-newsgroup-name article - (gnus-summary-article-header article) - (= mark gnus-ticked-mark) - (= mark gnus-dormant-mark) (= mark gnus-unread-mark)))) - - ;; Fix the mark. - (gnus-summary-update-mark mark 'unread) - t)))) - -(defun gnus-summary-mark-article (&optional article mark no-expire) - "Mark ARTICLE with MARK. MARK can be any character. -Four MARK strings are reserved: `? ' (unread), `?!' (ticked), -`??' (dormant) and `?E' (expirable). -If MARK is nil, then the default character `?D' is used. -If ARTICLE is nil, then the article on the current line will be -marked." - ;; The mark might be a string. - (when (stringp mark) - (setq mark (aref mark 0))) - ;; If no mark is given, then we check auto-expiring. - (and (not no-expire) - gnus-newsgroup-auto-expire - (or (not mark) - (and (gnus-characterp mark) - (or (= mark gnus-killed-mark) (= mark gnus-del-mark) - (= mark gnus-catchup-mark) (= mark gnus-low-score-mark) - (= mark gnus-read-mark) (= mark gnus-souped-mark) - (= mark gnus-duplicate-mark)))) - (setq mark gnus-expirable-mark)) - (let* ((mark (or mark gnus-del-mark)) - (article (or article (gnus-summary-article-number))) - (old-mark (gnus-summary-article-mark article))) - ;; Let the backend know about the mark change. - (setq mark (gnus-request-update-mark gnus-newsgroup-name article mark)) - (if (eq mark old-mark) - t - (unless article - (error "No article on current line")) - (if (not (if (or (= mark gnus-unread-mark) - (= mark gnus-ticked-mark) - (= mark gnus-dormant-mark)) - (gnus-mark-article-as-unread article mark) - (gnus-mark-article-as-read article mark))) - t - ;; See whether the article is to be put in the cache. - (and gnus-use-cache - (not (= mark gnus-canceled-mark)) - (vectorp (gnus-summary-article-header article)) - (save-excursion - (gnus-cache-possibly-enter-article - gnus-newsgroup-name article - (gnus-summary-article-header article) - (= mark gnus-ticked-mark) - (= mark gnus-dormant-mark) (= mark gnus-unread-mark)))) - - (when (gnus-summary-goto-subject article nil t) - (let ((buffer-read-only nil)) - (gnus-summary-show-thread) - ;; Fix the mark. - (gnus-summary-update-mark mark 'unread) - t)))))) - -(defun gnus-summary-update-secondary-mark (article) - "Update the secondary (read, process, cache) mark." - (gnus-summary-update-mark - (cond ((memq article gnus-newsgroup-processable) - gnus-process-mark) - ((memq article gnus-newsgroup-cached) - gnus-cached-mark) - ((memq article gnus-newsgroup-replied) - gnus-replied-mark) - ((memq article gnus-newsgroup-saved) - gnus-saved-mark) - (t gnus-unread-mark)) - 'replied) - (when (gnus-visual-p 'summary-highlight 'highlight) - (gnus-run-hooks 'gnus-summary-update-hook)) - t) - -(defun gnus-summary-update-mark (mark type) - (let ((forward (cdr (assq type gnus-summary-mark-positions))) - (buffer-read-only nil)) - (re-search-backward "[\n\r]" (gnus-point-at-bol) 'move-to-limit) - (when (looking-at "\r") - (incf forward)) - (when (and forward - (<= (+ forward (point)) (point-max))) - ;; Go to the right position on the line. - (goto-char (+ forward (point))) - ;; Replace the old mark with the new mark. - (subst-char-in-region (point) (1+ (point)) (following-char) mark) - ;; Optionally update the marks by some user rule. - (when (eq type 'unread) - (gnus-data-set-mark - (gnus-data-find (gnus-summary-article-number)) mark) - (gnus-summary-update-line (eq mark gnus-unread-mark)))))) - -(defun gnus-mark-article-as-read (article &optional mark) - "Enter ARTICLE in the pertinent lists and remove it from others." - ;; Make the article expirable. - (let ((mark (or mark gnus-del-mark))) - (if (= mark gnus-expirable-mark) - (push article gnus-newsgroup-expirable) - (setq gnus-newsgroup-expirable (delq article gnus-newsgroup-expirable))) - ;; Remove from unread and marked lists. - (setq gnus-newsgroup-unreads (delq article gnus-newsgroup-unreads)) - (setq gnus-newsgroup-marked (delq article gnus-newsgroup-marked)) - (setq gnus-newsgroup-dormant (delq article gnus-newsgroup-dormant)) - (push (cons article mark) gnus-newsgroup-reads) - ;; Possibly remove from cache, if that is used. - (when gnus-use-cache - (gnus-cache-enter-remove-article article)) - t)) - -(defun gnus-mark-article-as-unread (article &optional mark) - "Enter ARTICLE in the pertinent lists and remove it from others." - (let ((mark (or mark gnus-ticked-mark))) - (if (<= article 0) - (progn - (gnus-error 1 "Can't mark negative article numbers") - nil) - (setq gnus-newsgroup-marked (delq article gnus-newsgroup-marked) - gnus-newsgroup-dormant (delq article gnus-newsgroup-dormant) - gnus-newsgroup-expirable (delq article gnus-newsgroup-expirable) - gnus-newsgroup-unreads (delq article gnus-newsgroup-unreads)) - - ;; Unsuppress duplicates? - (when gnus-suppress-duplicates - (gnus-dup-unsuppress-article article)) - - (cond ((= mark gnus-ticked-mark) - (push article gnus-newsgroup-marked)) - ((= mark gnus-dormant-mark) - (push article gnus-newsgroup-dormant)) - (t - (push article gnus-newsgroup-unreads))) - (gnus-pull article gnus-newsgroup-reads) - t))) - -(defalias 'gnus-summary-mark-as-unread-forward - 'gnus-summary-tick-article-forward) -(make-obsolete 'gnus-summary-mark-as-unread-forward - 'gnus-summary-tick-article-forward) -(defun gnus-summary-tick-article-forward (n) - "Tick N articles forwards. -If N is negative, tick backwards instead. -The difference between N and the number of articles ticked is returned." - (interactive "p") - (gnus-summary-mark-forward n gnus-ticked-mark)) - -(defalias 'gnus-summary-mark-as-unread-backward - 'gnus-summary-tick-article-backward) -(make-obsolete 'gnus-summary-mark-as-unread-backward - 'gnus-summary-tick-article-backward) -(defun gnus-summary-tick-article-backward (n) - "Tick N articles backwards. -The difference between N and the number of articles ticked is returned." - (interactive "p") - (gnus-summary-mark-forward (- n) gnus-ticked-mark)) - -(defalias 'gnus-summary-mark-as-unread 'gnus-summary-tick-article) -(make-obsolete 'gnus-summary-mark-as-unread 'gnus-summary-tick-article) -(defun gnus-summary-tick-article (&optional article clear-mark) - "Mark current article as unread. -Optional 1st argument ARTICLE specifies article number to be marked as unread. -Optional 2nd argument CLEAR-MARK remove any kinds of mark." - (interactive) - (gnus-summary-mark-article article (if clear-mark gnus-unread-mark - gnus-ticked-mark))) - -(defun gnus-summary-mark-as-read-forward (n) - "Mark N articles as read forwards. -If N is negative, mark backwards instead. -The difference between N and the actual number of articles marked is -returned." - (interactive "p") - (gnus-summary-mark-forward n gnus-del-mark t)) - -(defun gnus-summary-mark-as-read-backward (n) - "Mark the N articles as read backwards. -The difference between N and the actual number of articles marked is -returned." - (interactive "p") - (gnus-summary-mark-forward (- n) gnus-del-mark t)) - -(defun gnus-summary-mark-as-read (&optional article mark) - "Mark current article as read. -ARTICLE specifies the article to be marked as read. -MARK specifies a string to be inserted at the beginning of the line." - (gnus-summary-mark-article article mark)) - -(defun gnus-summary-clear-mark-forward (n) - "Clear marks from N articles forward. -If N is negative, clear backward instead. -The difference between N and the number of marks cleared is returned." - (interactive "p") - (gnus-summary-mark-forward n gnus-unread-mark)) - -(defun gnus-summary-clear-mark-backward (n) - "Clear marks from N articles backward. -The difference between N and the number of marks cleared is returned." - (interactive "p") - (gnus-summary-mark-forward (- n) gnus-unread-mark)) - -(defun gnus-summary-mark-unread-as-read () - "Intended to be used by `gnus-summary-mark-article-hook'." - (when (memq gnus-current-article gnus-newsgroup-unreads) - (gnus-summary-mark-article gnus-current-article gnus-read-mark))) - -(defun gnus-summary-mark-read-and-unread-as-read () - "Intended to be used by `gnus-summary-mark-article-hook'." - (let ((mark (gnus-summary-article-mark))) - (when (or (gnus-unread-mark-p mark) - (gnus-read-mark-p mark)) - (gnus-summary-mark-article gnus-current-article gnus-read-mark)))) - -(defun gnus-summary-mark-region-as-read (point mark all) - "Mark all unread articles between point and mark as read. -If given a prefix, mark all articles between point and mark as read, -even ticked and dormant ones." - (interactive "r\nP") - (save-excursion - (let (article) - (goto-char point) - (beginning-of-line) - (while (and - (< (point) mark) - (progn - (when (or all - (memq (setq article (gnus-summary-article-number)) - gnus-newsgroup-unreads)) - (gnus-summary-mark-article article gnus-del-mark)) - t) - (gnus-summary-find-next)))))) - -(defun gnus-summary-mark-below (score mark) - "Mark articles with score less than SCORE with MARK." - (interactive "P\ncMark: ") - (setq score (if score - (prefix-numeric-value score) - (or gnus-summary-default-score 0))) - (save-excursion - (set-buffer gnus-summary-buffer) - (goto-char (point-min)) - (while - (progn - (and (< (gnus-summary-article-score) score) - (gnus-summary-mark-article nil mark)) - (gnus-summary-find-next))))) - -(defun gnus-summary-kill-below (&optional score) - "Mark articles with score below SCORE as read." - (interactive "P") - (gnus-summary-mark-below score gnus-killed-mark)) - -(defun gnus-summary-clear-above (&optional score) - "Clear all marks from articles with score above SCORE." - (interactive "P") - (gnus-summary-mark-above score gnus-unread-mark)) - -(defun gnus-summary-tick-above (&optional score) - "Tick all articles with score above SCORE." - (interactive "P") - (gnus-summary-mark-above score gnus-ticked-mark)) - -(defun gnus-summary-mark-above (score mark) - "Mark articles with score over SCORE with MARK." - (interactive "P\ncMark: ") - (setq score (if score - (prefix-numeric-value score) - (or gnus-summary-default-score 0))) - (save-excursion - (set-buffer gnus-summary-buffer) - (goto-char (point-min)) - (while (and (progn - (when (> (gnus-summary-article-score) score) - (gnus-summary-mark-article nil mark)) - t) - (gnus-summary-find-next))))) - -;; Suggested by Daniel Quinlan . -(defalias 'gnus-summary-show-all-expunged 'gnus-summary-limit-include-expunged) -(defun gnus-summary-limit-include-expunged (&optional no-error) - "Display all the hidden articles that were expunged for low scores." - (interactive) - (let ((buffer-read-only nil)) - (let ((scored gnus-newsgroup-scored) - headers h) - (while scored - (unless (gnus-summary-goto-subject (caar scored)) - (and (setq h (gnus-summary-article-header (caar scored))) - (< (cdar scored) gnus-summary-expunge-below) - (push h headers))) - (setq scored (cdr scored))) - (if (not headers) - (when (not no-error) - (error "No expunged articles hidden")) - (goto-char (point-min)) - (gnus-summary-prepare-unthreaded (nreverse headers)) - (goto-char (point-min)) - (gnus-summary-position-point) - t)))) - -(defun gnus-summary-catchup (&optional all quietly to-here not-mark) - "Mark all unread articles in this newsgroup as read. -If prefix argument ALL is non-nil, ticked and dormant articles will -also be marked as read. -If QUIETLY is non-nil, no questions will be asked. -If TO-HERE is non-nil, it should be a point in the buffer. All -articles before this point will be marked as read. -Note that this function will only catch up the unread article -in the current summary buffer limitation. -The number of articles marked as read is returned." - (interactive "P") - (prog1 - (save-excursion - (when (or quietly - (not gnus-interactive-catchup) ;Without confirmation? - gnus-expert-user - (gnus-y-or-n-p - (if all - "Mark absolutely all articles as read? " - "Mark all unread articles as read? "))) - (if (and not-mark - (not gnus-newsgroup-adaptive) - (not gnus-newsgroup-auto-expire) - (not gnus-suppress-duplicates) - (or (not gnus-use-cache) - (eq gnus-use-cache 'passive))) - (progn - (when all - (setq gnus-newsgroup-marked nil - gnus-newsgroup-dormant nil)) - (setq gnus-newsgroup-unreads gnus-newsgroup-downloadable)) - ;; We actually mark all articles as canceled, which we - ;; have to do when using auto-expiry or adaptive scoring. - (gnus-summary-show-all-threads) - (when (gnus-summary-first-subject (not all) t) - (while (and - (if to-here (< (point) to-here) t) - (gnus-summary-mark-article-as-read gnus-catchup-mark) - (gnus-summary-find-next (not all) nil nil t)))) - (gnus-set-mode-line 'summary)) - t)) - (gnus-summary-position-point))) - -(defun gnus-summary-catchup-to-here (&optional all) - "Mark all unticked articles before the current one as read. -If ALL is non-nil, also mark ticked and dormant articles as read." - (interactive "P") - (save-excursion - (gnus-save-hidden-threads - (let ((beg (point))) - ;; We check that there are unread articles. - (when (or all (gnus-summary-find-prev)) - (gnus-summary-catchup all t beg))))) - (gnus-summary-position-point)) - -(defun gnus-summary-catchup-all (&optional quietly) - "Mark all articles in this newsgroup as read." - (interactive "P") - (gnus-summary-catchup t quietly)) - -(defun gnus-summary-catchup-and-exit (&optional all quietly) - "Mark all articles not marked as unread in this newsgroup as read, then exit. -If prefix argument ALL is non-nil, all articles are marked as read." - (interactive "P") - (when (gnus-summary-catchup all quietly nil 'fast) - ;; Select next newsgroup or exit. - (if (and (not (gnus-group-quit-config gnus-newsgroup-name)) - (eq gnus-auto-select-next 'quietly)) - (gnus-summary-next-group nil) - (gnus-summary-exit)))) - -(defun gnus-summary-catchup-all-and-exit (&optional quietly) - "Mark all articles in this newsgroup as read, and then exit." - (interactive "P") - (gnus-summary-catchup-and-exit t quietly)) - -;; Suggested by "Arne Eofsson" . -(defun gnus-summary-catchup-and-goto-next-group (&optional all) - "Mark all articles in this group as read and select the next group. -If given a prefix, mark all articles, unread as well as ticked, as -read." - (interactive "P") - (save-excursion - (gnus-summary-catchup all)) - (gnus-summary-next-article t nil nil t)) - -;; Thread-based commands. - -(defun gnus-summary-articles-in-thread (&optional article) - "Return a list of all articles in the current thread. -If ARTICLE is non-nil, return all articles in the thread that starts -with that article." - (let* ((article (or article (gnus-summary-article-number))) - (data (gnus-data-find-list article)) - (top-level (gnus-data-level (car data))) - (top-subject - (cond ((null gnus-thread-operation-ignore-subject) - (gnus-simplify-subject-re - (mail-header-subject (gnus-data-header (car data))))) - ((eq gnus-thread-operation-ignore-subject 'fuzzy) - (gnus-simplify-subject-fuzzy - (mail-header-subject (gnus-data-header (car data))))) - (t nil))) - (end-point (save-excursion - (if (gnus-summary-go-to-next-thread) - (point) (point-max)))) - articles) - (while (and data - (< (gnus-data-pos (car data)) end-point)) - (when (or (not top-subject) - (string= top-subject - (if (eq gnus-thread-operation-ignore-subject 'fuzzy) - (gnus-simplify-subject-fuzzy - (mail-header-subject - (gnus-data-header (car data)))) - (gnus-simplify-subject-re - (mail-header-subject - (gnus-data-header (car data))))))) - (push (gnus-data-number (car data)) articles)) - (unless (and (setq data (cdr data)) - (> (gnus-data-level (car data)) top-level)) - (setq data nil))) - ;; Return the list of articles. - (nreverse articles))) - -(defun gnus-summary-rethread-current () - "Rethread the thread the current article is part of." - (interactive) - (let* ((gnus-show-threads t) - (article (gnus-summary-article-number)) - (id (mail-header-id (gnus-summary-article-header))) - (gnus-newsgroup-threads (list (gnus-id-to-thread (gnus-root-id id))))) - (unless id - (error "No article on the current line")) - (gnus-rebuild-thread id) - (gnus-summary-goto-subject article))) - -(defun gnus-summary-reparent-thread () - "Make the current article child of the marked (or previous) article. - -Note that the re-threading will only work if `gnus-thread-ignore-subject' -is non-nil or the Subject: of both articles are the same." - (interactive) - (unless (not (gnus-group-read-only-p)) - (error "The current newsgroup does not support article editing")) - (unless (<= (length gnus-newsgroup-processable) 1) - (error "No more than one article may be marked")) - (save-window-excursion - (let ((gnus-article-buffer " *reparent*") - (current-article (gnus-summary-article-number)) - ;; First grab the marked article, otherwise one line up. - (parent-article (if (not (null gnus-newsgroup-processable)) - (car gnus-newsgroup-processable) - (save-excursion - (if (eq (forward-line -1) 0) - (gnus-summary-article-number) - (error "Beginning of summary buffer")))))) - (unless (not (eq current-article parent-article)) - (error "An article may not be self-referential")) - (let ((message-id (mail-header-id - (gnus-summary-article-header parent-article)))) - (unless (and message-id (not (equal message-id ""))) - (error "No message-id in desired parent")) - ;; We don't want the article to be marked as read. - (let (gnus-mark-article-hook) - (gnus-summary-select-article t t nil current-article)) - (set-buffer gnus-original-article-buffer) - (let ((buf (format "%s" (buffer-string)))) - (nnheader-temp-write nil - (insert buf) - (goto-char (point-min)) - (if (re-search-forward "^References: " nil t) - (progn - (re-search-forward "^[^ \t]" nil t) - (forward-line -1) - (end-of-line) - (insert " " message-id)) - (insert "References: " message-id "\n")) - (unless (gnus-request-replace-article - current-article (car gnus-article-current) - (current-buffer)) - (error "Couldn't replace article")))) - (set-buffer gnus-summary-buffer) - (gnus-summary-unmark-all-processable) - (gnus-summary-update-article current-article) - (gnus-summary-rethread-current) - (gnus-message 3 "Article %d is now the child of article %d" - current-article parent-article))))) - -(defun gnus-summary-toggle-threads (&optional arg) - "Toggle showing conversation threads. -If ARG is positive number, turn showing conversation threads on." - (interactive "P") - (let ((current (or (gnus-summary-article-number) gnus-newsgroup-end))) - (setq gnus-show-threads - (if (null arg) (not gnus-show-threads) - (> (prefix-numeric-value arg) 0))) - (gnus-summary-prepare) - (gnus-summary-goto-subject current) - (gnus-message 6 "Threading is now %s" (if gnus-show-threads "on" "off")) - (gnus-summary-position-point))) - -(defun gnus-summary-show-all-threads () - "Show all threads." - (interactive) - (save-excursion - (let ((buffer-read-only nil)) - (subst-char-in-region (point-min) (point-max) ?\^M ?\n t))) - (gnus-summary-position-point)) - -(defun gnus-summary-show-thread () - "Show thread subtrees. -Returns nil if no thread was there to be shown." - (interactive) - (let ((buffer-read-only nil) - (orig (point)) - ;; first goto end then to beg, to have point at beg after let - (end (progn (end-of-line) (point))) - (beg (progn (beginning-of-line) (point)))) - (prog1 - ;; Any hidden lines here? - (search-forward "\r" end t) - (subst-char-in-region beg end ?\^M ?\n t) - (goto-char orig) - (gnus-summary-position-point)))) - -(defun gnus-summary-hide-all-threads () - "Hide all thread subtrees." - (interactive) - (save-excursion - (goto-char (point-min)) - (gnus-summary-hide-thread) - (while (zerop (gnus-summary-next-thread 1 t)) - (gnus-summary-hide-thread))) - (gnus-summary-position-point)) - -(defun gnus-summary-hide-thread () - "Hide thread subtrees. -Returns nil if no threads were there to be hidden." - (interactive) - (let ((buffer-read-only nil) - (start (point)) - (article (gnus-summary-article-number))) - (goto-char start) - ;; Go forward until either the buffer ends or the subthread - ;; ends. - (when (and (not (eobp)) - (or (zerop (gnus-summary-next-thread 1 t)) - (goto-char (point-max)))) - (prog1 - (if (and (> (point) start) - (search-backward "\n" start t)) - (progn - (subst-char-in-region start (point) ?\n ?\^M) - (gnus-summary-goto-subject article)) - (goto-char start) - nil) - ;;(gnus-summary-position-point) - )))) - -(defun gnus-summary-go-to-next-thread (&optional previous) - "Go to the same level (or less) next thread. -If PREVIOUS is non-nil, go to previous thread instead. -Return the article number moved to, or nil if moving was impossible." - (let ((level (gnus-summary-thread-level)) - (way (if previous -1 1)) - (beg (point))) - (forward-line way) - (while (and (not (eobp)) - (< level (gnus-summary-thread-level))) - (forward-line way)) - (if (eobp) - (progn - (goto-char beg) - nil) - (setq beg (point)) - (prog1 - (gnus-summary-article-number) - (goto-char beg))))) - -(defun gnus-summary-next-thread (n &optional silent) - "Go to the same level next N'th thread. -If N is negative, search backward instead. -Returns the difference between N and the number of skips actually -done. - -If SILENT, don't output messages." - (interactive "p") - (let ((backward (< n 0)) - (n (abs n))) - (while (and (> n 0) - (gnus-summary-go-to-next-thread backward)) - (decf n)) - (unless silent - (gnus-summary-position-point)) - (when (and (not silent) (/= 0 n)) - (gnus-message 7 "No more threads")) - n)) - -(defun gnus-summary-prev-thread (n) - "Go to the same level previous N'th thread. -Returns the difference between N and the number of skips actually -done." - (interactive "p") - (gnus-summary-next-thread (- n))) - -(defun gnus-summary-go-down-thread () - "Go down one level in the current thread." - (let ((children (gnus-summary-article-children))) - (when children - (gnus-summary-goto-subject (car children))))) - -(defun gnus-summary-go-up-thread () - "Go up one level in the current thread." - (let ((parent (gnus-summary-article-parent))) - (when parent - (gnus-summary-goto-subject parent)))) - -(defun gnus-summary-down-thread (n) - "Go down thread N steps. -If N is negative, go up instead. -Returns the difference between N and how many steps down that were -taken." - (interactive "p") - (let ((up (< n 0)) - (n (abs n))) - (while (and (> n 0) - (if up (gnus-summary-go-up-thread) - (gnus-summary-go-down-thread))) - (setq n (1- n))) - (gnus-summary-position-point) - (when (/= 0 n) - (gnus-message 7 "Can't go further")) - n)) - -(defun gnus-summary-up-thread (n) - "Go up thread N steps. -If N is negative, go up instead. -Returns the difference between N and how many steps down that were -taken." - (interactive "p") - (gnus-summary-down-thread (- n))) - -(defun gnus-summary-top-thread () - "Go to the top of the thread." - (interactive) - (while (gnus-summary-go-up-thread)) - (gnus-summary-article-number)) - -(defun gnus-summary-kill-thread (&optional unmark) - "Mark articles under current thread as read. -If the prefix argument is positive, remove any kinds of marks. -If the prefix argument is negative, tick articles instead." - (interactive "P") - (when unmark - (setq unmark (prefix-numeric-value unmark))) - (let ((articles (gnus-summary-articles-in-thread))) - (save-excursion - ;; Expand the thread. - (gnus-summary-show-thread) - ;; Mark all the articles. - (while articles - (gnus-summary-goto-subject (car articles)) - (cond ((null unmark) - (gnus-summary-mark-article-as-read gnus-killed-mark)) - ((> unmark 0) - (gnus-summary-mark-article-as-unread gnus-unread-mark)) - (t - (gnus-summary-mark-article-as-unread gnus-ticked-mark))) - (setq articles (cdr articles)))) - ;; Hide killed subtrees. - (and (null unmark) - gnus-thread-hide-killed - (gnus-summary-hide-thread)) - ;; If marked as read, go to next unread subject. - (when (null unmark) - ;; Go to next unread subject. - (gnus-summary-next-subject 1 t))) - (gnus-set-mode-line 'summary)) - -;; Summary sorting commands - -(defun gnus-summary-sort-by-number (&optional reverse) - "Sort the summary buffer by article number. -Argument REVERSE means reverse order." - (interactive "P") - (gnus-summary-sort 'number reverse)) - -(defun gnus-summary-sort-by-author (&optional reverse) - "Sort the summary buffer by author name alphabetically. -If case-fold-search is non-nil, case of letters is ignored. -Argument REVERSE means reverse order." - (interactive "P") - (gnus-summary-sort 'author reverse)) - -(defun gnus-summary-sort-by-subject (&optional reverse) - "Sort the summary buffer by subject alphabetically. `Re:'s are ignored. -If case-fold-search is non-nil, case of letters is ignored. -Argument REVERSE means reverse order." - (interactive "P") - (gnus-summary-sort 'subject reverse)) - -(defun gnus-summary-sort-by-date (&optional reverse) - "Sort the summary buffer by date. -Argument REVERSE means reverse order." - (interactive "P") - (gnus-summary-sort 'date reverse)) - -(defun gnus-summary-sort-by-score (&optional reverse) - "Sort the summary buffer by score. -Argument REVERSE means reverse order." - (interactive "P") - (gnus-summary-sort 'score reverse)) - -(defun gnus-summary-sort-by-lines (&optional reverse) - "Sort the summary buffer by article length. -Argument REVERSE means reverse order." - (interactive "P") - (gnus-summary-sort 'lines reverse)) - -(defun gnus-summary-sort (predicate reverse) - "Sort summary buffer by PREDICATE. REVERSE means reverse order." - (let* ((thread (intern (format "gnus-thread-sort-by-%s" predicate))) - (article (intern (format "gnus-article-sort-by-%s" predicate))) - (gnus-thread-sort-functions - (list - (if (not reverse) - thread - `(lambda (t1 t2) - (,thread t2 t1))))) - (gnus-article-sort-functions - (list - (if (not reverse) - article - `(lambda (t1 t2) - (,article t2 t1))))) - (buffer-read-only) - (gnus-summary-prepare-hook nil)) - ;; We do the sorting by regenerating the threads. - (gnus-summary-prepare) - ;; Hide subthreads if needed. - (when (and gnus-show-threads gnus-thread-hide-subtree) - (gnus-summary-hide-all-threads)))) - -;; Summary saving commands. - -(defun gnus-summary-save-article (&optional n not-saved) - "Save the current article using the default saver function. -If N is a positive number, save the N next articles. -If N is a negative number, save the N previous articles. -If N is nil and any articles have been marked with the process mark, -save those articles instead. -The variable `gnus-default-article-saver' specifies the saver function." - (interactive "P") - (let* ((articles (gnus-summary-work-articles n)) - (save-buffer (save-excursion - (nnheader-set-temp-buffer " *Gnus Save*"))) - (num (length articles)) - header article file) - (while articles - (setq header (gnus-summary-article-header - (setq article (pop articles)))) - (if (not (vectorp header)) - ;; This is a pseudo-article. - (if (assq 'name header) - (gnus-copy-file (cdr (assq 'name header))) - (gnus-message 1 "Article %d is unsaveable" article)) - ;; This is a real article. - (save-window-excursion - (gnus-summary-select-article t nil nil article)) - (save-excursion - (set-buffer save-buffer) - (erase-buffer) - (insert-buffer-substring gnus-original-article-buffer)) - (setq file (gnus-article-save save-buffer file num)) - (gnus-summary-remove-process-mark article) - (unless not-saved - (gnus-summary-set-saved-mark article)))) - (gnus-kill-buffer save-buffer) - (gnus-summary-position-point) - (gnus-set-mode-line 'summary) - n)) - -(defun gnus-summary-pipe-output (&optional arg) - "Pipe the current article to a subprocess. -If N is a positive number, pipe the N next articles. -If N is a negative number, pipe the N previous articles. -If N is nil and any articles have been marked with the process mark, -pipe those articles instead." - (interactive "P") - (let ((gnus-default-article-saver 'gnus-summary-save-in-pipe)) - (gnus-summary-save-article arg t)) - (gnus-configure-windows 'pipe)) - -(defun gnus-summary-save-article-mail (&optional arg) - "Append the current article to an mail file. -If N is a positive number, save the N next articles. -If N is a negative number, save the N previous articles. -If N is nil and any articles have been marked with the process mark, -save those articles instead." - (interactive "P") - (let ((gnus-default-article-saver 'gnus-summary-save-in-mail)) - (gnus-summary-save-article arg))) - -(defun gnus-summary-save-article-rmail (&optional arg) - "Append the current article to an rmail file. -If N is a positive number, save the N next articles. -If N is a negative number, save the N previous articles. -If N is nil and any articles have been marked with the process mark, -save those articles instead." - (interactive "P") - (let ((gnus-default-article-saver 'gnus-summary-save-in-rmail)) - (gnus-summary-save-article arg))) - -(defun gnus-summary-save-article-file (&optional arg) - "Append the current article to a file. -If N is a positive number, save the N next articles. -If N is a negative number, save the N previous articles. -If N is nil and any articles have been marked with the process mark, -save those articles instead." - (interactive "P") - (let ((gnus-default-article-saver 'gnus-summary-save-in-file)) - (gnus-summary-save-article arg))) - -(defun gnus-summary-write-article-file (&optional arg) - "Write the current article to a file, deleting the previous file. -If N is a positive number, save the N next articles. -If N is a negative number, save the N previous articles. -If N is nil and any articles have been marked with the process mark, -save those articles instead." - (interactive "P") - (let ((gnus-default-article-saver 'gnus-summary-write-to-file)) - (gnus-summary-save-article arg))) - -(defun gnus-summary-save-article-body-file (&optional arg) - "Append the current article body to a file. -If N is a positive number, save the N next articles. -If N is a negative number, save the N previous articles. -If N is nil and any articles have been marked with the process mark, -save those articles instead." - (interactive "P") - (let ((gnus-default-article-saver 'gnus-summary-save-body-in-file)) - (gnus-summary-save-article arg))) - -(defun gnus-summary-pipe-message (program) - "Pipe the current article through PROGRAM." - (interactive "sProgram: ") - (gnus-summary-select-article) - (let ((mail-header-separator "")) - (gnus-eval-in-buffer-window gnus-article-buffer - (save-restriction - (widen) - (let ((start (window-start)) - buffer-read-only) - (message-pipe-buffer-body program) - (set-window-start (get-buffer-window (current-buffer)) start)))))) - -(defun gnus-get-split-value (methods) - "Return a value based on the split METHODS." - (let (split-name method result match) - (when methods - (save-excursion - (set-buffer gnus-original-article-buffer) - (save-restriction - (nnheader-narrow-to-headers) - (while methods - (goto-char (point-min)) - (setq method (pop methods)) - (setq match (car method)) - (when (cond - ((stringp match) - ;; Regular expression. - (ignore-errors - (re-search-forward match nil t))) - ((gnus-functionp match) - ;; Function. - (save-restriction - (widen) - (setq result (funcall match gnus-newsgroup-name)))) - ((consp match) - ;; Form. - (save-restriction - (widen) - (setq result (eval match))))) - (setq split-name (append (cdr method) split-name)) - (cond ((stringp result) - (push (expand-file-name - result gnus-article-save-directory) - split-name)) - ((consp result) - (setq split-name (append result split-name))))))))) - split-name)) - -(defun gnus-valid-move-group-p (group) - (and (boundp group) - (symbol-name group) - (memq 'respool - (assoc (symbol-name - (car (gnus-find-method-for-group - (symbol-name group)))) - gnus-valid-select-methods)))) - -(defun gnus-read-move-group-name (prompt default articles prefix) - "Read a group name." - (let* ((split-name (gnus-get-split-value gnus-move-split-methods)) - (minibuffer-confirm-incomplete nil) ; XEmacs - (prom - (format "%s %s to:" - prompt - (if (> (length articles) 1) - (format "these %d articles" (length articles)) - "this article"))) - (to-newsgroup - (cond - ((null split-name) - (gnus-completing-read default prom - gnus-active-hashtb - 'gnus-valid-move-group-p - nil prefix - 'gnus-group-history)) - ((= 1 (length split-name)) - (gnus-completing-read (car split-name) prom - gnus-active-hashtb - 'gnus-valid-move-group-p - nil nil - 'gnus-group-history)) - (t - (gnus-completing-read nil prom - (mapcar (lambda (el) (list el)) - (nreverse split-name)) - nil nil nil - 'gnus-group-history))))) - (when to-newsgroup - (if (or (string= to-newsgroup "") - (string= to-newsgroup prefix)) - (setq to-newsgroup default)) - (unless to-newsgroup - (error "No group name entered")) - (or (gnus-active to-newsgroup) - (gnus-activate-group to-newsgroup) - (if (gnus-y-or-n-p (format "No such group: %s. Create it? " - to-newsgroup)) - (or (and (gnus-request-create-group - to-newsgroup (gnus-group-name-to-method to-newsgroup)) - (gnus-activate-group to-newsgroup nil nil - (gnus-group-name-to-method - to-newsgroup))) - (error "Couldn't create group %s" to-newsgroup))) - (error "No such group: %s" to-newsgroup))) - to-newsgroup)) - -;; Summary extract commands - -(defun gnus-summary-insert-pseudos (pslist &optional not-view) - (let ((buffer-read-only nil) - (article (gnus-summary-article-number)) - after-article b e) - (unless (gnus-summary-goto-subject article) - (error "No such article: %d" article)) - (gnus-summary-position-point) - ;; If all commands are to be bunched up on one line, we collect - ;; them here. - (unless gnus-view-pseudos-separately - (let ((ps (setq pslist (sort pslist 'gnus-pseudos<))) - files action) - (while ps - (setq action (cdr (assq 'action (car ps)))) - (setq files (list (cdr (assq 'name (car ps))))) - (while (and ps (cdr ps) - (string= (or action "1") - (or (cdr (assq 'action (cadr ps))) "2"))) - (push (cdr (assq 'name (cadr ps))) files) - (setcdr ps (cddr ps))) - (when files - (when (not (string-match "%s" action)) - (push " " files)) - (push " " files) - (when (assq 'execute (car ps)) - (setcdr (assq 'execute (car ps)) - (funcall (if (string-match "%s" action) - 'format 'concat) - action - (mapconcat - (lambda (f) - (if (equal f " ") - f - (gnus-quote-arg-for-sh-or-csh f))) - files " "))))) - (setq ps (cdr ps))))) - (if (and gnus-view-pseudos (not not-view)) - (while pslist - (when (assq 'execute (car pslist)) - (gnus-execute-command (cdr (assq 'execute (car pslist))) - (eq gnus-view-pseudos 'not-confirm))) - (setq pslist (cdr pslist))) - (save-excursion - (while pslist - (setq after-article (or (cdr (assq 'article (car pslist))) - (gnus-summary-article-number))) - (gnus-summary-goto-subject after-article) - (forward-line 1) - (setq b (point)) - (insert " " (file-name-nondirectory - (cdr (assq 'name (car pslist)))) - ": " (or (cdr (assq 'execute (car pslist))) "") "\n") - (setq e (point)) - (forward-line -1) ; back to `b' - (gnus-add-text-properties - b (1- e) (list 'gnus-number gnus-reffed-article-number - gnus-mouse-face-prop gnus-mouse-face)) - (gnus-data-enter - after-article gnus-reffed-article-number - gnus-unread-mark b (car pslist) 0 (- e b)) - (push gnus-reffed-article-number gnus-newsgroup-unreads) - (setq gnus-reffed-article-number (1- gnus-reffed-article-number)) - (setq pslist (cdr pslist))))))) - -(defun gnus-pseudos< (p1 p2) - (let ((c1 (cdr (assq 'action p1))) - (c2 (cdr (assq 'action p2)))) - (and c1 c2 (string< c1 c2)))) - -(defun gnus-request-pseudo-article (props) - (cond ((assq 'execute props) - (gnus-execute-command (cdr (assq 'execute props))))) - (let ((gnus-current-article (gnus-summary-article-number))) - (gnus-run-hooks 'gnus-mark-article-hook))) - -(defun gnus-execute-command (command &optional automatic) - (save-excursion - (gnus-article-setup-buffer) - (set-buffer gnus-article-buffer) - (setq buffer-read-only nil) - (let ((command (if automatic command - (read-string "Command: " (cons command 0))))) - (erase-buffer) - (insert "$ " command "\n\n") - (if gnus-view-pseudo-asynchronously - (start-process "gnus-execute" (current-buffer) shell-file-name - shell-command-switch command) - (call-process shell-file-name nil t nil - shell-command-switch command))))) - -;; Summary kill commands. - -(defun gnus-summary-edit-global-kill (article) - "Edit the \"global\" kill file." - (interactive (list (gnus-summary-article-number))) - (gnus-group-edit-global-kill article)) - -(defun gnus-summary-edit-local-kill () - "Edit a local kill file applied to the current newsgroup." - (interactive) - (setq gnus-current-headers (gnus-summary-article-header)) - (gnus-group-edit-local-kill - (gnus-summary-article-number) gnus-newsgroup-name)) - -;;; Header reading. - -(defun gnus-read-header (id &optional header) - "Read the headers of article ID and enter them into the Gnus system." - (let ((group gnus-newsgroup-name) - (gnus-override-method - (and (gnus-news-group-p gnus-newsgroup-name) - gnus-refer-article-method)) - where) - ;; First we check to see whether the header in question is already - ;; fetched. - (if (stringp id) - ;; This is a Message-ID. - (setq header (or header (gnus-id-to-header id))) - ;; This is an article number. - (setq header (or header (gnus-summary-article-header id)))) - (if (and header - (not (gnus-summary-article-sparse-p (mail-header-number header)))) - ;; We have found the header. - header - ;; If this is a sparse article, we have to nix out its - ;; previous entry in the thread hashtb. - (when (and header - (gnus-summary-article-sparse-p (mail-header-number header))) - (let* ((parent (gnus-parent-id (mail-header-references header))) - (thread (and parent (gnus-id-to-thread parent)))) - (when thread - (delq (assq header thread) thread)))) - ;; We have to really fetch the header to this article. - (save-excursion - (set-buffer nntp-server-buffer) - (when (setq where (gnus-request-head id group)) - (nnheader-fold-continuation-lines) - (goto-char (point-max)) - (insert ".\n") - (goto-char (point-min)) - (insert "211 ") - (princ (cond - ((numberp id) id) - ((cdr where) (cdr where)) - (header (mail-header-number header)) - (t gnus-reffed-article-number)) - (current-buffer)) - (insert " Article retrieved.\n")) - (if (or (not where) - (not (setq header (car (gnus-get-newsgroup-headers nil t))))) - () ; Malformed head. - (unless (gnus-summary-article-sparse-p (mail-header-number header)) - (when (and (stringp id) - (not (string= (gnus-group-real-name group) - (car where)))) - ;; If we fetched by Message-ID and the article came - ;; from a different group, we fudge some bogus article - ;; numbers for this article. - (mail-header-set-number header gnus-reffed-article-number)) - (save-excursion - (set-buffer gnus-summary-buffer) - (decf gnus-reffed-article-number) - (gnus-remove-header (mail-header-number header)) - (push header gnus-newsgroup-headers) - (setq gnus-current-headers header) - (push (mail-header-number header) gnus-newsgroup-limit))) - header))))) - -(defun gnus-remove-header (number) - "Remove header NUMBER from `gnus-newsgroup-headers'." - (if (and gnus-newsgroup-headers - (= number (mail-header-number (car gnus-newsgroup-headers)))) - (pop gnus-newsgroup-headers) - (let ((headers gnus-newsgroup-headers)) - (while (and (cdr headers) - (not (= number (mail-header-number (cadr headers))))) - (pop headers)) - (when (cdr headers) - (setcdr headers (cddr headers)))))) - -;;; -;;; summary highlights -;;; - -(defun gnus-highlight-selected-summary () - ;; Added by Per Abrahamsen . - ;; Highlight selected article in summary buffer - (when gnus-summary-selected-face - (save-excursion - (let* ((beg (progn (beginning-of-line) (point))) - (end (progn (end-of-line) (point))) - ;; Fix by Mike Dugan . - (from (if (get-text-property beg gnus-mouse-face-prop) - beg - (or (next-single-property-change - beg gnus-mouse-face-prop nil end) - beg))) - (to - (if (= from end) - (- from 2) - (or (next-single-property-change - from gnus-mouse-face-prop nil end) - end)))) - ;; If no mouse-face prop on line we will have to = from = end, - ;; so we highlight the entire line instead. - (when (= (+ to 2) from) - (setq from beg) - (setq to end)) - (if gnus-newsgroup-selected-overlay - ;; Move old overlay. - (gnus-move-overlay - gnus-newsgroup-selected-overlay from to (current-buffer)) - ;; Create new overlay. - (gnus-overlay-put - (setq gnus-newsgroup-selected-overlay (gnus-make-overlay from to)) - 'face gnus-summary-selected-face)))))) - -;; New implementation by Christian Limpach . -(defun gnus-summary-highlight-line () - "Highlight current line according to `gnus-summary-highlight'." - (let* ((list gnus-summary-highlight) - (p (point)) - (end (progn (end-of-line) (point))) - ;; now find out where the line starts and leave point there. - (beg (progn (beginning-of-line) (point))) - (article (gnus-summary-article-number)) - (score (or (cdr (assq (or article gnus-current-article) - gnus-newsgroup-scored)) - gnus-summary-default-score 0)) - (mark (or (gnus-summary-article-mark) gnus-unread-mark)) - (inhibit-read-only t)) - ;; Eval the cars of the lists until we find a match. - (let ((default gnus-summary-default-score)) - (while (and list - (not (eval (caar list)))) - (setq list (cdr list)))) - (let ((face (cdar list))) - (unless (eq face (get-text-property beg 'face)) - (gnus-put-text-property-excluding-characters-with-faces - beg end 'face - (setq face (if (boundp face) (symbol-value face) face))) - (when gnus-summary-highlight-line-function - (funcall gnus-summary-highlight-line-function article face)))) - (goto-char p))) - -(defun gnus-update-read-articles (group unread &optional compute) - "Update the list of read articles in GROUP." - (let* ((active (or gnus-newsgroup-active (gnus-active group))) - (entry (gnus-gethash group gnus-newsrc-hashtb)) - (info (nth 2 entry)) - (prev 1) - (unread (sort (copy-sequence unread) '<)) - read) - (if (or (not info) (not active)) - ;; There is no info on this group if it was, in fact, - ;; killed. Gnus stores no information on killed groups, so - ;; there's nothing to be done. - ;; One could store the information somewhere temporarily, - ;; perhaps... Hmmm... - () - ;; Remove any negative articles numbers. - (while (and unread (< (car unread) 0)) - (setq unread (cdr unread))) - ;; Remove any expired article numbers - (while (and unread (< (car unread) (car active))) - (setq unread (cdr unread))) - ;; Compute the ranges of read articles by looking at the list of - ;; unread articles. - (while unread - (when (/= (car unread) prev) - (push (if (= prev (1- (car unread))) prev - (cons prev (1- (car unread)))) - read)) - (setq prev (1+ (car unread))) - (setq unread (cdr unread))) - (when (<= prev (cdr active)) - (push (cons prev (cdr active)) read)) - (if compute - (if (> (length read) 1) (nreverse read) read) - (save-excursion - (set-buffer gnus-group-buffer) - (gnus-undo-register - `(progn - (gnus-info-set-marks ',info ',(gnus-info-marks info) t) - (gnus-info-set-read ',info ',(gnus-info-read info)) - (gnus-get-unread-articles-in-group ',info (gnus-active ,group)) - (gnus-group-update-group ,group t)))) - ;; Enter this list into the group info. - (gnus-info-set-read - info (if (> (length read) 1) (nreverse read) read)) - ;; Set the number of unread articles in gnus-newsrc-hashtb. - (gnus-get-unread-articles-in-group info (gnus-active group)) - t)))) - -(defun gnus-offer-save-summaries () - "Offer to save all active summary buffers." - (save-excursion - (let ((buflist (buffer-list)) - buffers bufname) - ;; Go through all buffers and find all summaries. - (while buflist - (and (setq bufname (buffer-name (car buflist))) - (string-match "Summary" bufname) - (save-excursion - (set-buffer bufname) - ;; We check that this is, indeed, a summary buffer. - (and (eq major-mode 'gnus-summary-mode) - ;; Also make sure this isn't bogus. - gnus-newsgroup-prepared - ;; Also make sure that this isn't a dead summary buffer. - (not gnus-dead-summary-mode))) - (push bufname buffers)) - (setq buflist (cdr buflist))) - ;; Go through all these summary buffers and offer to save them. - (when buffers - (map-y-or-n-p - "Update summary buffer %s? " - (lambda (buf) - (switch-to-buffer buf) - (gnus-summary-exit)) - buffers))))) - - -;;; @ for mime-partial -;;; - -(defun gnus-request-partial-message () - (save-excursion - (let ((number (gnus-summary-article-number)) - (group gnus-newsgroup-name) - (mother gnus-article-buffer)) - (set-buffer (get-buffer-create " *Partial Article*")) - (erase-buffer) - (setq mime-preview-buffer mother) - (gnus-request-article-this-buffer number group) - (mime-parse-buffer) - ))) - -(autoload 'mime-combine-message/partial-pieces-automatically - "mime-partial" - "Internal method to combine message/partial messages automatically.") - -(mime-add-condition - 'action '((type . message)(subtype . partial) - (major-mode . gnus-original-article-mode) - (method . mime-combine-message/partial-pieces-automatically) - (summary-buffer-exp . gnus-summary-buffer) - (request-partial-message-method . gnus-request-partial-message) - )) - - -;;; @ end -;;; - -(gnus-ems-redefine) - -(provide 'gnus-sum) - -(run-hooks 'gnus-sum-load-hook) - -;;; gnus-sum.el ends here diff --git a/lisp/gnus-topic.el b/lisp/gnus-topic.el deleted file mode 100644 index 3f2b2af..0000000 --- a/lisp/gnus-topic.el +++ /dev/null @@ -1,1453 +0,0 @@ -;;; gnus-topic.el --- a folding minor mode for Gnus group buffers -;; Copyright (C) 1995,96,97,98 Free Software Foundation, Inc. - -;; Author: Ilja Weis -;; Lars Magne Ingebrigtsen -;; Keywords: news - -;; This file is part of GNU Emacs. - -;; GNU Emacs is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 2, or (at your option) -;; any later version. - -;; GNU Emacs is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs; see the file COPYING. If not, write to the -;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. - -;;; Commentary: - -;;; Code: - -(eval-when-compile (require 'cl)) - -(require 'gnus) -(require 'gnus-group) -(require 'gnus-start) -(require 'gnus-util) - -(defgroup gnus-topic nil - "Group topics." - :group 'gnus-group) - -(defvar gnus-topic-mode nil - "Minor mode for Gnus group buffers.") - -(defcustom gnus-topic-mode-hook nil - "Hook run in topic mode buffers." - :type 'hook - :group 'gnus-topic) - -(defcustom gnus-topic-line-format "%i[ %(%{%n%}%) -- %A ]%v\n" - "Format of topic lines. -It works along the same lines as a normal formatting string, -with some simple extensions. - -%i Indentation based on topic level. -%n Topic name. -%v Nothing if the topic is visible, \"...\" otherwise. -%g Number of groups in the topic. -%a Number of unread articles in the groups in the topic. -%A Number of unread articles in the groups in the topic and its subtopics. -" - :type 'string - :group 'gnus-topic) - -(defcustom gnus-topic-indent-level 2 - "*How much each subtopic should be indented." - :type 'integer - :group 'gnus-topic) - -(defcustom gnus-topic-display-empty-topics t - "*If non-nil, display the topic lines even of topics that have no unread articles." - :type 'boolean - :group 'gnus-topic) - -;; Internal variables. - -(defvar gnus-topic-active-topology nil) -(defvar gnus-topic-active-alist nil) -(defvar gnus-topic-unreads nil) - -(defvar gnus-topology-checked-p nil - "Whether the topology has been checked in this session.") - -(defvar gnus-topic-killed-topics nil) -(defvar gnus-topic-inhibit-change-level nil) - -(defconst gnus-topic-line-format-alist - `((?n name ?s) - (?v visible ?s) - (?i indentation ?s) - (?g number-of-groups ?d) - (?a (gnus-topic-articles-in-topic entries) ?d) - (?A total-number-of-articles ?d) - (?l level ?d))) - -(defvar gnus-topic-line-format-spec nil) - -;;; Utility functions - -(defun gnus-group-topic-name () - "The name of the topic on the current line." - (let ((topic (get-text-property (gnus-point-at-bol) 'gnus-topic))) - (and topic (symbol-name topic)))) - -(defun gnus-group-topic-level () - "The level of the topic on the current line." - (get-text-property (gnus-point-at-bol) 'gnus-topic-level)) - -(defun gnus-group-topic-unread () - "The number of unread articles in topic on the current line." - (get-text-property (gnus-point-at-bol) 'gnus-topic-unread)) - -(defun gnus-topic-unread (topic) - "Return the number of unread articles in TOPIC." - (or (cdr (assoc topic gnus-topic-unreads)) - 0)) - -(defun gnus-group-topic-p () - "Return non-nil if the current line is a topic." - (gnus-group-topic-name)) - -(defun gnus-topic-visible-p () - "Return non-nil if the current topic is visible." - (get-text-property (gnus-point-at-bol) 'gnus-topic-visible)) - -(defun gnus-topic-articles-in-topic (entries) - (let ((total 0) - number) - (while entries - (when (numberp (setq number (car (pop entries)))) - (incf total number))) - total)) - -(defun gnus-group-topic (group) - "Return the topic GROUP is a member of." - (let ((alist gnus-topic-alist) - out) - (while alist - (when (member group (cdar alist)) - (setq out (caar alist) - alist nil)) - (setq alist (cdr alist))) - out)) - -(defun gnus-group-parent-topic (group) - "Return the topic GROUP is member of by looking at the group buffer." - (save-excursion - (set-buffer gnus-group-buffer) - (if (gnus-group-goto-group group) - (gnus-current-topic) - (gnus-group-topic group)))) - -(defun gnus-topic-goto-topic (topic) - "Go to TOPIC." - (when topic - (gnus-goto-char (text-property-any (point-min) (point-max) - 'gnus-topic (intern topic))))) - -(defun gnus-current-topic () - "Return the name of the current topic." - (let ((result - (or (get-text-property (point) 'gnus-topic) - (save-excursion - (and (gnus-goto-char (previous-single-property-change - (point) 'gnus-topic)) - (get-text-property (max (1- (point)) (point-min)) - 'gnus-topic)))))) - (when result - (symbol-name result)))) - -(defun gnus-current-topics (&optional topic) - "Return a list of all current topics, lowest in hierarchy first. -If TOPIC, start with that topic." - (let ((topic (or topic (gnus-current-topic))) - topics) - (while topic - (push topic topics) - (setq topic (gnus-topic-parent-topic topic))) - (nreverse topics))) - -(defun gnus-group-active-topic-p () - "Say whether the current topic comes from the active topics." - (save-excursion - (beginning-of-line) - (get-text-property (point) 'gnus-active))) - -(defun gnus-topic-find-groups (topic &optional level all lowest) - "Return entries for all visible groups in TOPIC." - (let ((groups (cdr (assoc topic gnus-topic-alist))) - info clevel unread group params visible-groups entry active) - (setq lowest (or lowest 1)) - (setq level (or level gnus-level-unsubscribed)) - ;; We go through the newsrc to look for matches. - (while groups - (when (setq group (pop groups)) - (setq entry (gnus-gethash group gnus-newsrc-hashtb) - info (nth 2 entry) - params (gnus-info-params info) - active (gnus-active group) - unread (or (car entry) - (and (not (equal group "dummy.group")) - active - (- (1+ (cdr active)) (car active)))) - clevel (or (gnus-info-level info) - (if (member group gnus-zombie-list) - gnus-level-zombie gnus-level-killed)))) - (and - unread ; nil means that the group is dead. - (<= clevel level) - (>= clevel lowest) ; Is inside the level we want. - (or all - (if (eq unread t) - gnus-group-list-inactive-groups - (> unread 0)) - (and gnus-list-groups-with-ticked-articles - (cdr (assq 'tick (gnus-info-marks info)))) - ; Has right readedness. - ;; Check for permanent visibility. - (and gnus-permanently-visible-groups - (string-match gnus-permanently-visible-groups group)) - (memq 'visible params) - (cdr (assq 'visible params))) - ;; Add this group to the list of visible groups. - (push (or entry group) visible-groups))) - (nreverse visible-groups))) - -(defun gnus-topic-previous-topic (topic) - "Return the previous topic on the same level as TOPIC." - (let ((top (cddr (gnus-topic-find-topology - (gnus-topic-parent-topic topic))))) - (unless (equal topic (caaar top)) - (while (and top (not (equal (caaadr top) topic))) - (setq top (cdr top))) - (caaar top)))) - -(defun gnus-topic-parent-topic (topic &optional topology) - "Return the parent of TOPIC." - (unless topology - (setq topology gnus-topic-topology)) - (let ((parent (car (pop topology))) - result found) - (while (and topology - (not (setq found (equal (caaar topology) topic))) - (not (setq result (gnus-topic-parent-topic - topic (car topology))))) - (setq topology (cdr topology))) - (or result (and found parent)))) - -(defun gnus-topic-next-topic (topic &optional previous) - "Return the next sibling of TOPIC." - (let ((parentt (cddr (gnus-topic-find-topology - (gnus-topic-parent-topic topic)))) - prev) - (while (and parentt - (not (equal (caaar parentt) topic))) - (setq prev (caaar parentt) - parentt (cdr parentt))) - (if previous - prev - (caaadr parentt)))) - -(defun gnus-topic-forward-topic (num) - "Go to the next topic on the same level as the current one." - (let* ((topic (gnus-current-topic)) - (way (if (< num 0) 'gnus-topic-previous-topic - 'gnus-topic-next-topic)) - (num (abs num))) - (while (and (not (zerop num)) - (setq topic (funcall way topic))) - (when (gnus-topic-goto-topic topic) - (decf num))) - (unless (zerop num) - (goto-char (point-max))) - num)) - -(defun gnus-topic-find-topology (topic &optional topology level remove) - "Return the topology of TOPIC." - (unless topology - (setq topology gnus-topic-topology) - (setq level 0)) - (let ((top topology) - result) - (if (equal (caar topology) topic) - (progn - (when remove - (delq topology remove)) - (cons level topology)) - (setq topology (cdr topology)) - (while (and topology - (not (setq result (gnus-topic-find-topology - topic (car topology) (1+ level) - (and remove top))))) - (setq topology (cdr topology))) - result))) - -(defvar gnus-tmp-topics nil) -(defun gnus-topic-list (&optional topology) - "Return a list of all topics in the topology." - (unless topology - (setq topology gnus-topic-topology - gnus-tmp-topics nil)) - (push (caar topology) gnus-tmp-topics) - (mapcar 'gnus-topic-list (cdr topology)) - gnus-tmp-topics) - -;;; Topic parameter jazz - -(defun gnus-topic-parameters (topic) - "Return the parameters for TOPIC." - (let ((top (gnus-topic-find-topology topic))) - (when top - (nth 3 (cadr top))))) - -(defun gnus-topic-set-parameters (topic parameters) - "Set the topic parameters of TOPIC to PARAMETERS." - (let ((top (gnus-topic-find-topology topic))) - (unless top - (error "No such topic: %s" topic)) - ;; We may have to extend if there is no parameters here - ;; to begin with. - (unless (nthcdr 2 (cadr top)) - (nconc (cadr top) (list nil))) - (unless (nthcdr 3 (cadr top)) - (nconc (cadr top) (list nil))) - (setcar (nthcdr 3 (cadr top)) parameters) - (gnus-dribble-enter - (format "(gnus-topic-set-parameters %S '%S)" topic parameters)))) - -(defun gnus-group-topic-parameters (group) - "Compute the group parameters for GROUP taking into account inheritance from topics." - (let ((params-list (copy-sequence (gnus-group-get-parameter group)))) - (save-excursion - (gnus-group-goto-group group) - (nconc params-list - (gnus-topic-hierarchical-parameters (gnus-current-topic)))))) - -(defun gnus-topic-hierarchical-parameters (topic) - "Return a topic list computed for TOPIC." - (let ((topics (gnus-current-topics topic)) - params-list param out params) - (while topics - (push (gnus-topic-parameters (pop topics)) params-list)) - ;; We probably have lots of nil elements here, so - ;; we remove them. Probably faster than doing this "properly". - (setq params-list (delq nil params-list)) - ;; Now we have all the parameters, so we go through them - ;; and do inheritance in the obvious way. - (while (setq params (pop params-list)) - (while (setq param (pop params)) - (when (atom param) - (setq param (cons param t))) - ;; Override any old versions of this param. - (gnus-pull (car param) out) - (push param out))) - ;; Return the resulting parameter list. - out)) - -;;; General utility functions - -(defun gnus-topic-enter-dribble () - (gnus-dribble-enter - (format "(setq gnus-topic-topology '%S)" gnus-topic-topology))) - -;;; Generating group buffers - -(defun gnus-group-prepare-topics (level &optional all lowest regexp list-topic topic-level) - "List all newsgroups with unread articles of level LEVEL or lower. -Use the `gnus-group-topics' to sort the groups. -If ALL is non-nil, list groups that have no unread articles. -If LOWEST is non-nil, list all newsgroups of level LOWEST or higher." - (set-buffer gnus-group-buffer) - (let ((buffer-read-only nil) - (lowest (or lowest 1))) - - (when (or (not gnus-topic-alist) - (not gnus-topology-checked-p)) - (gnus-topic-check-topology)) - - (unless list-topic - (erase-buffer)) - - ;; List dead groups? - (when (and (>= level gnus-level-zombie) - (<= lowest gnus-level-zombie)) - (gnus-group-prepare-flat-list-dead - (setq gnus-zombie-list (sort gnus-zombie-list 'string<)) - gnus-level-zombie ?Z - regexp)) - - (when (and (>= level gnus-level-killed) (<= lowest gnus-level-killed)) - (gnus-group-prepare-flat-list-dead - (setq gnus-killed-list (sort gnus-killed-list 'string<)) - gnus-level-killed ?K - regexp)) - - ;; Use topics. - (prog1 - (when (< lowest gnus-level-zombie) - (if list-topic - (let ((top (gnus-topic-find-topology list-topic))) - (gnus-topic-prepare-topic (cdr top) (car top) - (or topic-level level) all - nil lowest)) - (gnus-topic-prepare-topic gnus-topic-topology 0 - (or topic-level level) all - nil lowest))) - - (gnus-group-set-mode-line) - (setq gnus-group-list-mode (cons level all)) - (gnus-run-hooks 'gnus-group-prepare-hook)))) - -(defun gnus-topic-prepare-topic (topicl level &optional list-level all silent - lowest) - "Insert TOPIC into the group buffer. -If SILENT, don't insert anything. Return the number of unread -articles in the topic and its subtopics." - (let* ((type (pop topicl)) - (entries (gnus-topic-find-groups - (car type) list-level - (or all - (cdr (assq 'visible - (gnus-topic-hierarchical-parameters - (car type))))) - lowest)) - (visiblep (and (eq (nth 1 type) 'visible) (not silent))) - (gnus-group-indentation - (make-string (* gnus-topic-indent-level level) ? )) - (beg (progn (beginning-of-line) (point))) - (topicl (reverse topicl)) - (all-entries entries) - (point-max (point-max)) - (unread 0) - (topic (car type)) - info entry end active tick) - ;; Insert any sub-topics. - (while topicl - (incf unread - (gnus-topic-prepare-topic - (pop topicl) (1+ level) list-level all - (not visiblep) lowest))) - (setq end (point)) - (goto-char beg) - ;; Insert all the groups that belong in this topic. - (while (setq entry (pop entries)) - (when visiblep - (if (stringp entry) - ;; Dead groups. - (gnus-group-insert-group-line - entry (if (member entry gnus-zombie-list) gnus-level-zombie gnus-level-killed) - nil (- (1+ (cdr (setq active (gnus-active entry)))) - (car active)) - nil) - ;; Living groups. - (when (setq info (nth 2 entry)) - (gnus-group-insert-group-line - (gnus-info-group info) - (gnus-info-level info) (gnus-info-marks info) - (car entry) (gnus-info-method info))))) - (when (and (listp entry) - (numberp (car entry))) - (incf unread (car entry))) - (when (listp entry) - (setq tick t))) - (goto-char beg) - ;; Insert the topic line. - (when (and (not silent) - (or gnus-topic-display-empty-topics ;We want empty topics - (not (zerop unread)) ;Non-empty - tick ;Ticked articles - (/= point-max (point-max)))) ;Unactivated groups - (gnus-extent-start-open (point)) - (gnus-topic-insert-topic-line - (car type) visiblep - (not (eq (nth 2 type) 'hidden)) - level all-entries unread)) - (gnus-topic-update-unreads (car type) unread) - (goto-char end) - unread)) - -(defun gnus-topic-remove-topic (&optional insert total-remove hide in-level) - "Remove the current topic." - (let ((topic (gnus-group-topic-name)) - (level (gnus-group-topic-level)) - (beg (progn (beginning-of-line) (point))) - buffer-read-only) - (when topic - (while (and (zerop (forward-line 1)) - (> (or (gnus-group-topic-level) (1+ level)) level))) - (delete-region beg (point)) - ;; Do the change in this rather odd manner because it has been - ;; reported that some topics share parts of some lists, for some - ;; reason. I have been unable to determine why this is the - ;; case, but this hack seems to take care of things. - (let ((data (cadr (gnus-topic-find-topology topic)))) - (setcdr data - (list (if insert 'visible 'invisible) - (if hide 'hide nil) - (cadddr data)))) - (if total-remove - (setq gnus-topic-alist - (delq (assoc topic gnus-topic-alist) gnus-topic-alist)) - (gnus-topic-insert-topic topic in-level))))) - -(defun gnus-topic-insert-topic (topic &optional level) - "Insert TOPIC." - (gnus-group-prepare-topics - (car gnus-group-list-mode) (cdr gnus-group-list-mode) - nil nil topic level)) - -(defun gnus-topic-fold (&optional insert) - "Remove/insert the current topic." - (let ((topic (gnus-group-topic-name))) - (when topic - (save-excursion - (if (not (gnus-group-active-topic-p)) - (gnus-topic-remove-topic - (or insert (not (gnus-topic-visible-p)))) - (let ((gnus-topic-topology gnus-topic-active-topology) - (gnus-topic-alist gnus-topic-active-alist) - (gnus-group-list-mode (cons 5 t))) - (gnus-topic-remove-topic - (or insert (not (gnus-topic-visible-p))) nil nil 9) - (gnus-topic-enter-dribble))))))) - -(defun gnus-topic-insert-topic-line (name visiblep shownp level entries - &optional unread) - (let* ((visible (if visiblep "" "...")) - (indentation (make-string (* gnus-topic-indent-level level) ? )) - (total-number-of-articles unread) - (number-of-groups (length entries)) - (active-topic (eq gnus-topic-alist gnus-topic-active-alist)) - gnus-tmp-header) - (gnus-topic-update-unreads name unread) - (beginning-of-line) - ;; Insert the text. - (gnus-add-text-properties - (point) - (prog1 (1+ (point)) - (eval gnus-topic-line-format-spec)) - (list 'gnus-topic (intern name) - 'gnus-topic-level level - 'gnus-topic-unread unread - 'gnus-active active-topic - 'gnus-topic-visible visiblep)))) - -(defun gnus-topic-update-unreads (topic unreads) - (setq gnus-topic-unreads (delq (assoc topic gnus-topic-unreads) - gnus-topic-unreads)) - (push (cons topic unreads) gnus-topic-unreads)) - -(defun gnus-topic-update-topics-containing-group (group) - "Update all topics that have GROUP as a member." - (when (and (eq major-mode 'gnus-group-mode) - gnus-topic-mode) - (save-excursion - (let ((alist gnus-topic-alist)) - ;; This is probably not entirely correct. If a topic - ;; isn't shown, then it's not updated. But the updating - ;; should be performed in any case, since the topic's - ;; parent should be updated. Pfft. - (while alist - (when (and (member group (cdar alist)) - (gnus-topic-goto-topic (caar alist))) - (gnus-topic-update-topic-line (caar alist))) - (pop alist)))))) - -(defun gnus-topic-update-topic () - "Update all parent topics to the current group." - (when (and (eq major-mode 'gnus-group-mode) - gnus-topic-mode) - (let ((group (gnus-group-group-name)) - (m (point-marker)) - (buffer-read-only nil)) - (when (and group - (gnus-get-info group) - (gnus-topic-goto-topic (gnus-current-topic))) - (gnus-topic-update-topic-line (gnus-group-topic-name)) - (goto-char m) - (set-marker m nil) - (gnus-group-position-point))))) - -(defun gnus-topic-goto-missing-group (group) - "Place point where GROUP is supposed to be inserted." - (let* ((topic (gnus-group-topic group)) - (groups (cdr (assoc topic gnus-topic-alist))) - (g (cdr (member group groups))) - (unfound t)) - ;; Try to jump to a visible group. - (while (and g (not (gnus-group-goto-group (car g) t))) - (pop g)) - ;; It wasn't visible, so we try to see where to insert it. - (when (not g) - (setq g (cdr (member group (reverse groups)))) - (while (and g unfound) - (when (gnus-group-goto-group (pop g) t) - (forward-line 1) - (setq unfound nil))) - (when (and unfound - topic - (not (gnus-topic-goto-missing-topic topic))) - (gnus-topic-insert-topic-line - topic t t (car (gnus-topic-find-topology topic)) nil 0))))) - -(defun gnus-topic-goto-missing-topic (topic) - (if (gnus-topic-goto-topic topic) - (forward-line 1) - ;; Topic not displayed. - (let* ((top (gnus-topic-find-topology - (gnus-topic-parent-topic topic))) - (tp (reverse (cddr top)))) - (while (not (equal (caaar tp) topic)) - (setq tp (cdr tp))) - (pop tp) - (while (and tp - (not (gnus-topic-goto-topic (caaar tp)))) - (pop tp)) - (if tp - (gnus-topic-forward-topic 1) - (gnus-topic-goto-missing-topic (caadr top)))) - nil)) - -(defun gnus-topic-update-topic-line (topic-name &optional reads) - (let* ((top (gnus-topic-find-topology topic-name)) - (type (cadr top)) - (children (cddr top)) - (entries (gnus-topic-find-groups - (car type) (car gnus-group-list-mode) - (cdr gnus-group-list-mode))) - (parent (gnus-topic-parent-topic topic-name)) - (all-entries entries) - (unread 0) - old-unread entry new-unread) - (when (gnus-topic-goto-topic (car type)) - ;; Tally all the groups that belong in this topic. - (if reads - (setq unread (- (gnus-group-topic-unread) reads)) - (while children - (incf unread (gnus-topic-unread (caar (pop children))))) - (while (setq entry (pop entries)) - (when (numberp (car entry)) - (incf unread (car entry))))) - (setq old-unread (gnus-group-topic-unread)) - ;; Insert the topic line. - (gnus-topic-insert-topic-line - (car type) (gnus-topic-visible-p) - (not (eq (nth 2 type) 'hidden)) - (gnus-group-topic-level) all-entries unread) - (gnus-delete-line) - (forward-line -1) - (setq new-unread (gnus-group-topic-unread))) - (when parent - (forward-line -1) - (gnus-topic-update-topic-line - parent - (- (or old-unread 0) (or new-unread 0)))) - unread)) - -(defun gnus-topic-group-indentation () - (make-string - (* gnus-topic-indent-level - (or (save-excursion - (forward-line -1) - (gnus-topic-goto-topic (gnus-current-topic)) - (gnus-group-topic-level)) - 0)) - ? )) - -;;; Initialization - -(gnus-add-shutdown 'gnus-topic-close 'gnus) - -(defun gnus-topic-close () - (setq gnus-topic-active-topology nil - gnus-topic-active-alist nil - gnus-topic-killed-topics nil - gnus-topology-checked-p nil)) - -(defun gnus-topic-check-topology () - ;; The first time we set the topology to whatever we have - ;; gotten here, which can be rather random. - (unless gnus-topic-alist - (gnus-topic-init-alist)) - - (setq gnus-topology-checked-p t) - ;; Go through the topic alist and make sure that all topics - ;; are in the topic topology. - (let ((topics (gnus-topic-list)) - (alist gnus-topic-alist) - changed) - (while alist - (unless (member (caar alist) topics) - (nconc gnus-topic-topology - (list (list (list (caar alist) 'visible)))) - (setq changed t)) - (setq alist (cdr alist))) - (when changed - (gnus-topic-enter-dribble)) - ;; Conversely, go through the topology and make sure that all - ;; topologies have alists. - (while topics - (unless (assoc (car topics) gnus-topic-alist) - (push (list (car topics)) gnus-topic-alist)) - (pop topics))) - ;; Go through all living groups and make sure that - ;; they belong to some topic. - (let* ((tgroups (apply 'append (mapcar (lambda (entry) (cdr entry)) - gnus-topic-alist))) - (entry (last (assoc (caar gnus-topic-topology) gnus-topic-alist))) - (newsrc (cdr gnus-newsrc-alist)) - group) - (while newsrc - (unless (member (setq group (gnus-info-group (pop newsrc))) tgroups) - (setcdr entry (list group)) - (setq entry (cdr entry))))) - ;; Go through all topics and make sure they contain only living groups. - (let ((alist gnus-topic-alist) - topic) - (while (setq topic (pop alist)) - (while (cdr topic) - (if (and (cadr topic) - (gnus-gethash (cadr topic) gnus-newsrc-hashtb)) - (setq topic (cdr topic)) - (setcdr topic (cddr topic))))))) - -(defun gnus-topic-init-alist () - "Initialize the topic structures." - (setq gnus-topic-topology - (cons (list "Gnus" 'visible) - (mapcar (lambda (topic) - (list (list (car topic) 'visible))) - '(("misc"))))) - (setq gnus-topic-alist - (list (cons "misc" - (mapcar (lambda (info) (gnus-info-group info)) - (cdr gnus-newsrc-alist))) - (list "Gnus"))) - (gnus-topic-enter-dribble)) - -;;; Maintenance - -(defun gnus-topic-clean-alist () - "Remove bogus groups from the topic alist." - (let ((topic-alist gnus-topic-alist) - result topic) - (unless gnus-killed-hashtb - (gnus-make-hashtable-from-killed)) - (while (setq topic (pop topic-alist)) - (let ((topic-name (pop topic)) - group filtered-topic) - (while (setq group (pop topic)) - (when (and (or (gnus-gethash group gnus-active-hashtb) - (gnus-info-method (gnus-get-info group))) - (not (gnus-gethash group gnus-killed-hashtb))) - (push group filtered-topic))) - (push (cons topic-name (nreverse filtered-topic)) result))) - (setq gnus-topic-alist (nreverse result)))) - -(defun gnus-topic-change-level (group level oldlevel &optional previous) - "Run when changing levels to enter/remove groups from topics." - (save-excursion - (set-buffer gnus-group-buffer) - (let ((buffer-read-only nil)) - (unless gnus-topic-inhibit-change-level - (gnus-group-goto-group (or (car (nth 2 previous)) group)) - (when (and gnus-topic-mode - gnus-topic-alist - (not gnus-topic-inhibit-change-level)) - ;; Remove the group from the topics. - (if (and (< oldlevel gnus-level-zombie) - (>= level gnus-level-zombie)) - (let ((alist gnus-topic-alist)) - (while (gnus-group-goto-group group) - (gnus-delete-line)) - (while alist - (when (member group (car alist)) - (setcdr (car alist) (delete group (cdar alist)))) - (pop alist))) - ;; If the group is subscribed we enter it into the topics. - (when (and (< level gnus-level-zombie) - (>= oldlevel gnus-level-zombie)) - (let* ((prev (gnus-group-group-name)) - (gnus-topic-inhibit-change-level t) - (gnus-group-indentation - (make-string - (* gnus-topic-indent-level - (or (save-excursion - (gnus-topic-goto-topic (gnus-current-topic)) - (gnus-group-topic-level)) - 0)) - ? )) - (yanked (list group)) - alist talist end) - ;; Then we enter the yanked groups into the topics they belong - ;; to. - (when (setq alist (assoc (save-excursion - (forward-line -1) - (or - (gnus-current-topic) - (caar gnus-topic-topology))) - gnus-topic-alist)) - (setq talist alist) - (when (stringp yanked) - (setq yanked (list yanked))) - (if (not prev) - (nconc alist yanked) - (if (not (cdr alist)) - (setcdr alist (nconc yanked (cdr alist))) - (while (and (not end) (cdr alist)) - (when (equal (cadr alist) prev) - (setcdr alist (nconc yanked (cdr alist))) - (setq end t)) - (setq alist (cdr alist))) - (unless end - (nconc talist yanked)))))) - (gnus-topic-update-topic)))))))) - -(defun gnus-topic-goto-next-group (group props) - "Go to group or the next group after group." - (if (not group) - (if (not (memq 'gnus-topic props)) - (goto-char (point-max)) - (gnus-topic-goto-topic (symbol-name (cadr (memq 'gnus-topic props))))) - (if (gnus-group-goto-group group) - t - ;; The group is no longer visible. - (let* ((list (assoc (gnus-group-topic group) gnus-topic-alist)) - (after (cdr (member group (cdr list))))) - ;; First try to put point on a group after the current one. - (while (and after - (not (gnus-group-goto-group (car after)))) - (setq after (cdr after))) - ;; Then try to put point on a group before point. - (unless after - (setq after (cdr (member group (reverse (cdr list))))) - (while (and after - (not (gnus-group-goto-group (car after)))) - (setq after (cdr after)))) - ;; Finally, just put point on the topic. - (if (not (car list)) - (goto-char (point-min)) - (unless after - (gnus-topic-goto-topic (car list)) - (setq after nil))) - t)))) - -;;; Topic-active functions - -(defun gnus-topic-grok-active (&optional force) - "Parse all active groups and create topic structures for them." - ;; First we make sure that we have really read the active file. - (when (or force - (not gnus-topic-active-alist)) - (let (groups) - ;; Get a list of all groups available. - (mapatoms (lambda (g) (when (symbol-value g) - (push (symbol-name g) groups))) - gnus-active-hashtb) - (setq groups (sort groups 'string<)) - ;; Init the variables. - (setq gnus-topic-active-topology (list (list "" 'visible))) - (setq gnus-topic-active-alist nil) - ;; Descend the top-level hierarchy. - (gnus-topic-grok-active-1 gnus-topic-active-topology groups) - ;; Set the top-level topic names to something nice. - (setcar (car gnus-topic-active-topology) "Gnus active") - (setcar (car gnus-topic-active-alist) "Gnus active")))) - -(defun gnus-topic-grok-active-1 (topology groups) - (let* ((name (caar topology)) - (prefix (concat "^" (regexp-quote name))) - tgroups ntopology group) - (while (and groups - (string-match prefix (setq group (car groups)))) - (if (not (string-match "\\." group (match-end 0))) - ;; There are no further hierarchies here, so we just - ;; enter this group into the list belonging to this - ;; topic. - (push (pop groups) tgroups) - ;; New sub-hierarchy, so we add it to the topology. - (nconc topology (list (setq ntopology - (list (list (substring - group 0 (match-end 0)) - 'invisible))))) - ;; Descend the hierarchy. - (setq groups (gnus-topic-grok-active-1 ntopology groups)))) - ;; We remove the trailing "." from the topic name. - (setq name - (if (string-match "\\.$" name) - (substring name 0 (match-beginning 0)) - name)) - ;; Add this topic and its groups to the topic alist. - (push (cons name (nreverse tgroups)) gnus-topic-active-alist) - (setcar (car topology) name) - ;; We return the rest of the groups that didn't belong - ;; to this topic. - groups)) - -;;; Topic mode, commands and keymap. - -(defvar gnus-topic-mode-map nil) -(defvar gnus-group-topic-map nil) - -(unless gnus-topic-mode-map - (setq gnus-topic-mode-map (make-sparse-keymap)) - - ;; Override certain group mode keys. - (gnus-define-keys gnus-topic-mode-map - "=" gnus-topic-select-group - "\r" gnus-topic-select-group - " " gnus-topic-read-group - "\C-k" gnus-topic-kill-group - "\C-y" gnus-topic-yank-group - "\M-g" gnus-topic-get-new-news-this-topic - "AT" gnus-topic-list-active - "Gp" gnus-topic-edit-parameters - "#" gnus-topic-mark-topic - "\M-#" gnus-topic-unmark-topic - [tab] gnus-topic-indent - [(meta tab)] gnus-topic-unindent - "\C-i" gnus-topic-indent - "\M-\C-i" gnus-topic-unindent - gnus-mouse-2 gnus-mouse-pick-topic) - - ;; Define a new submap. - (gnus-define-keys (gnus-group-topic-map "T" gnus-group-mode-map) - "#" gnus-topic-mark-topic - "\M-#" gnus-topic-unmark-topic - "n" gnus-topic-create-topic - "m" gnus-topic-move-group - "D" gnus-topic-remove-group - "c" gnus-topic-copy-group - "h" gnus-topic-hide-topic - "s" gnus-topic-show-topic - "M" gnus-topic-move-matching - "C" gnus-topic-copy-matching - "\C-i" gnus-topic-indent - [tab] gnus-topic-indent - "r" gnus-topic-rename - "\177" gnus-topic-delete - [delete] gnus-topic-delete - "H" gnus-topic-toggle-display-empty-topics) - - (gnus-define-keys (gnus-topic-sort-map "S" gnus-group-topic-map) - "s" gnus-topic-sort-groups - "a" gnus-topic-sort-groups-by-alphabet - "u" gnus-topic-sort-groups-by-unread - "l" gnus-topic-sort-groups-by-level - "v" gnus-topic-sort-groups-by-score - "r" gnus-topic-sort-groups-by-rank - "m" gnus-topic-sort-groups-by-method)) - -(defun gnus-topic-make-menu-bar () - (unless (boundp 'gnus-topic-menu) - (easy-menu-define - gnus-topic-menu gnus-topic-mode-map "" - '("Topics" - ["Toggle topics" gnus-topic-mode t] - ("Groups" - ["Copy" gnus-topic-copy-group t] - ["Move" gnus-topic-move-group t] - ["Remove" gnus-topic-remove-group t] - ["Copy matching" gnus-topic-copy-matching t] - ["Move matching" gnus-topic-move-matching t]) - ("Topics" - ["Show" gnus-topic-show-topic t] - ["Hide" gnus-topic-hide-topic t] - ["Delete" gnus-topic-delete t] - ["Rename" gnus-topic-rename t] - ["Create" gnus-topic-create-topic t] - ["Mark" gnus-topic-mark-topic t] - ["Indent" gnus-topic-indent t] - ["Toggle hide empty" gnus-topic-toggle-display-empty-topics t] - ["Edit parameters" gnus-topic-edit-parameters t]) - ["List active" gnus-topic-list-active t])))) - -(defun gnus-topic-mode (&optional arg redisplay) - "Minor mode for topicsifying Gnus group buffers." - (interactive (list current-prefix-arg t)) - (when (eq major-mode 'gnus-group-mode) - (make-local-variable 'gnus-topic-mode) - (setq gnus-topic-mode - (if (null arg) (not gnus-topic-mode) - (> (prefix-numeric-value arg) 0))) - ;; Infest Gnus with topics. - (if (not gnus-topic-mode) - (setq gnus-goto-missing-group-function nil) - (when (gnus-visual-p 'topic-menu 'menu) - (gnus-topic-make-menu-bar)) - (gnus-set-format 'topic t) - (gnus-add-minor-mode 'gnus-topic-mode " Topic" gnus-topic-mode-map) - (add-hook 'gnus-group-catchup-group-hook 'gnus-topic-update-topic) - (set (make-local-variable 'gnus-group-prepare-function) - 'gnus-group-prepare-topics) - (set (make-local-variable 'gnus-group-get-parameter-function) - 'gnus-group-topic-parameters) - (set (make-local-variable 'gnus-group-goto-next-group-function) - 'gnus-topic-goto-next-group) - (set (make-local-variable 'gnus-group-indentation-function) - 'gnus-topic-group-indentation) - (set (make-local-variable 'gnus-group-update-group-function) - 'gnus-topic-update-topics-containing-group) - (set (make-local-variable 'gnus-group-sort-alist-function) - 'gnus-group-sort-topic) - (setq gnus-group-change-level-function 'gnus-topic-change-level) - (setq gnus-goto-missing-group-function 'gnus-topic-goto-missing-group) - (make-local-hook 'gnus-check-bogus-groups-hook) - (add-hook 'gnus-check-bogus-groups-hook 'gnus-topic-clean-alist) - (setq gnus-topology-checked-p nil) - ;; We check the topology. - (when gnus-newsrc-alist - (gnus-topic-check-topology)) - (gnus-run-hooks 'gnus-topic-mode-hook)) - ;; Remove topic infestation. - (unless gnus-topic-mode - (remove-hook 'gnus-summary-exit-hook 'gnus-topic-update-topic) - (remove-hook 'gnus-group-change-level-function - 'gnus-topic-change-level) - (remove-hook 'gnus-check-bogus-groups-hook 'gnus-topic-clean-alist) - (setq gnus-group-prepare-function 'gnus-group-prepare-flat) - (setq gnus-group-sort-alist-function 'gnus-group-sort-flat)) - (when redisplay - (gnus-group-list-groups)))) - -(defun gnus-topic-select-group (&optional all) - "Select this newsgroup. -No article is selected automatically. -If ALL is non-nil, already read articles become readable. -If ALL is a number, fetch this number of articles. - -If performed over a topic line, toggle folding the topic." - (interactive "P") - (if (gnus-group-topic-p) - (let ((gnus-group-list-mode - (if all (cons (if (numberp all) all 7) t) gnus-group-list-mode))) - (gnus-topic-fold all)) - (gnus-group-select-group all))) - -(defun gnus-mouse-pick-topic (e) - "Select the group or topic under the mouse pointer." - (interactive "e") - (mouse-set-point e) - (gnus-topic-read-group nil)) - -(defun gnus-topic-read-group (&optional all no-article group) - "Read news in this newsgroup. -If the prefix argument ALL is non-nil, already read articles become -readable. IF ALL is a number, fetch this number of articles. If the -optional argument NO-ARTICLE is non-nil, no article will be -auto-selected upon group entry. If GROUP is non-nil, fetch that -group. - -If performed over a topic line, toggle folding the topic." - (interactive "P") - (if (gnus-group-topic-p) - (let ((gnus-group-list-mode - (if all (cons (if (numberp all) all 7) t) gnus-group-list-mode))) - (gnus-topic-fold all)) - (gnus-group-read-group all no-article group))) - -(defun gnus-topic-create-topic (topic parent &optional previous full-topic) - "Create a new TOPIC under PARENT. -When used interactively, PARENT will be the topic under point." - (interactive - (list - (read-string "New topic: ") - (gnus-current-topic))) - ;; Check whether this topic already exists. - (when (gnus-topic-find-topology topic) - (error "Topic already exists")) - (unless parent - (setq parent (caar gnus-topic-topology))) - (let ((top (cdr (gnus-topic-find-topology parent))) - (full-topic (or full-topic `((,topic visible))))) - (unless top - (error "No such parent topic: %s" parent)) - (if previous - (progn - (while (and (cdr top) - (not (equal (caaadr top) previous))) - (setq top (cdr top))) - (setcdr top (cons full-topic (cdr top)))) - (nconc top (list full-topic))) - (unless (assoc topic gnus-topic-alist) - (push (list topic) gnus-topic-alist))) - (gnus-topic-enter-dribble) - (gnus-group-list-groups) - (gnus-topic-goto-topic topic)) - -(defun gnus-topic-move-group (n topic &optional copyp) - "Move the next N groups to TOPIC. -If COPYP, copy the groups instead." - (interactive - (list current-prefix-arg - (completing-read "Move to topic: " gnus-topic-alist nil t))) - (let ((groups (gnus-group-process-prefix n)) - (topicl (assoc topic gnus-topic-alist)) - (start-group (progn (forward-line 1) (gnus-group-group-name))) - (start-topic (gnus-group-topic-name)) - entry) - (mapcar - (lambda (g) - (gnus-group-remove-mark g) - (when (and - (setq entry (assoc (gnus-current-topic) gnus-topic-alist)) - (not copyp)) - (setcdr entry (gnus-delete-first g (cdr entry)))) - (nconc topicl (list g))) - groups) - (gnus-topic-enter-dribble) - (if start-group - (gnus-group-goto-group start-group) - (gnus-topic-goto-topic start-topic)) - (gnus-group-list-groups))) - -(defun gnus-topic-remove-group (&optional arg) - "Remove the current group from the topic." - (interactive "P") - (gnus-group-iterate arg - (lambda (group) - (let ((topicl (assoc (gnus-current-topic) gnus-topic-alist)) - (buffer-read-only nil)) - (when (and topicl group) - (gnus-delete-line) - (gnus-delete-first group topicl)) - (gnus-topic-update-topic) - (gnus-group-position-point))))) - -(defun gnus-topic-copy-group (n topic) - "Copy the current group to a topic." - (interactive - (list current-prefix-arg - (completing-read "Copy to topic: " gnus-topic-alist nil t))) - (gnus-topic-move-group n topic t)) - -(defun gnus-topic-kill-group (&optional n discard) - "Kill the next N groups." - (interactive "P") - (if (gnus-group-topic-p) - (let ((topic (gnus-group-topic-name))) - (push (cons - (gnus-topic-find-topology topic) - (assoc topic gnus-topic-alist)) - gnus-topic-killed-topics) - (gnus-topic-remove-topic nil t) - (gnus-topic-find-topology topic nil nil gnus-topic-topology) - (gnus-topic-enter-dribble)) - (gnus-group-kill-group n discard) - (gnus-topic-update-topic))) - -(defun gnus-topic-yank-group (&optional arg) - "Yank the last topic." - (interactive "p") - (if gnus-topic-killed-topics - (let* ((previous - (or (gnus-group-topic-name) - (gnus-topic-next-topic (gnus-current-topic)))) - (data (pop gnus-topic-killed-topics)) - (alist (cdr data)) - (item (cdar data))) - (push alist gnus-topic-alist) - (gnus-topic-create-topic - (caar item) (gnus-topic-parent-topic previous) previous - item) - (gnus-topic-enter-dribble) - (gnus-topic-goto-topic (caar item))) - (let* ((prev (gnus-group-group-name)) - (gnus-topic-inhibit-change-level t) - (gnus-group-indentation - (make-string - (* gnus-topic-indent-level - (or (save-excursion - (gnus-topic-goto-topic (gnus-current-topic)) - (gnus-group-topic-level)) - 0)) - ? )) - yanked alist) - ;; We first yank the groups the normal way... - (setq yanked (gnus-group-yank-group arg)) - ;; Then we enter the yanked groups into the topics they belong - ;; to. - (setq alist (assoc (save-excursion - (forward-line -1) - (gnus-current-topic)) - gnus-topic-alist)) - (when (stringp yanked) - (setq yanked (list yanked))) - (if (not prev) - (nconc alist yanked) - (if (not (cdr alist)) - (setcdr alist (nconc yanked (cdr alist))) - (while (cdr alist) - (when (equal (cadr alist) prev) - (setcdr alist (nconc yanked (cdr alist))) - (setq alist nil)) - (setq alist (cdr alist)))))) - (gnus-topic-update-topic))) - -(defun gnus-topic-hide-topic () - "Hide the current topic." - (interactive) - (when (gnus-current-topic) - (gnus-topic-goto-topic (gnus-current-topic)) - (gnus-topic-remove-topic nil nil 'hidden))) - -(defun gnus-topic-show-topic () - "Show the hidden topic." - (interactive) - (when (gnus-group-topic-p) - (gnus-topic-remove-topic t nil 'shown))) - -(defun gnus-topic-mark-topic (topic &optional unmark) - "Mark all groups in the topic with the process mark." - (interactive (list (gnus-group-topic-name))) - (if (not topic) - (call-interactively 'gnus-group-mark-group) - (save-excursion - (let ((groups (gnus-topic-find-groups topic gnus-level-killed t))) - (while groups - (funcall (if unmark 'gnus-group-remove-mark 'gnus-group-set-mark) - (gnus-info-group (nth 2 (pop groups))))))))) - -(defun gnus-topic-unmark-topic (topic &optional unmark) - "Remove the process mark from all groups in the topic." - (interactive (list (gnus-group-topic-name))) - (if (not topic) - (call-interactively 'gnus-group-unmark-group) - (gnus-topic-mark-topic topic t))) - -(defun gnus-topic-get-new-news-this-topic (&optional n) - "Check for new news in the current topic." - (interactive "P") - (if (not (gnus-group-topic-p)) - (gnus-group-get-new-news-this-group n) - (gnus-topic-mark-topic (gnus-group-topic-name)) - (gnus-group-get-new-news-this-group))) - -(defun gnus-topic-move-matching (regexp topic &optional copyp) - "Move all groups that match REGEXP to some topic." - (interactive - (let (topic) - (nreverse - (list - (setq topic (completing-read "Move to topic: " gnus-topic-alist nil t)) - (read-string (format "Move to %s (regexp): " topic)))))) - (gnus-group-mark-regexp regexp) - (gnus-topic-move-group nil topic copyp)) - -(defun gnus-topic-copy-matching (regexp topic &optional copyp) - "Copy all groups that match REGEXP to some topic." - (interactive - (let (topic) - (nreverse - (list - (setq topic (completing-read "Copy to topic: " gnus-topic-alist nil t)) - (read-string (format "Copy to %s (regexp): " topic)))))) - (gnus-topic-move-matching regexp topic t)) - -(defun gnus-topic-delete (topic) - "Delete a topic." - (interactive (list (gnus-group-topic-name))) - (unless topic - (error "No topic to be deleted")) - (let ((entry (assoc topic gnus-topic-alist)) - (buffer-read-only nil)) - (when (cdr entry) - (error "Topic not empty")) - ;; Delete if visible. - (when (gnus-topic-goto-topic topic) - (gnus-delete-line)) - ;; Remove from alist. - (setq gnus-topic-alist (delq entry gnus-topic-alist)) - ;; Remove from topology. - (gnus-topic-find-topology topic nil nil 'delete) - (gnus-dribble-touch))) - -(defun gnus-topic-rename (old-name new-name) - "Rename a topic." - (interactive - (let ((topic (gnus-current-topic))) - (list topic - (read-string (format "Rename %s to: " topic))))) - ;; Check whether the new name exists. - (when (gnus-topic-find-topology new-name) - (error "Topic '%s' already exists" new-name)) - ;; "nil" is an invalid name, for reasons I'd rather not go - ;; into here. Trust me. - (when (equal new-name "nil") - (error "Invalid name: %s" nil)) - ;; Do the renaming. - (let ((top (gnus-topic-find-topology old-name)) - (entry (assoc old-name gnus-topic-alist))) - (when top - (setcar (cadr top) new-name)) - (when entry - (setcar entry new-name)) - (forward-line -1) - (gnus-dribble-touch) - (gnus-group-list-groups) - (forward-line 1))) - -(defun gnus-topic-indent (&optional unindent) - "Indent a topic -- make it a sub-topic of the previous topic. -If UNINDENT, remove an indentation." - (interactive "P") - (if unindent - (gnus-topic-unindent) - (let* ((topic (gnus-current-topic)) - (parent (gnus-topic-previous-topic topic)) - (buffer-read-only nil)) - (unless parent - (error "Nothing to indent %s into" topic)) - (when topic - (gnus-topic-goto-topic topic) - (gnus-topic-kill-group) - (push (cdar gnus-topic-killed-topics) gnus-topic-alist) - (gnus-topic-create-topic - topic parent nil (cdaar gnus-topic-killed-topics)) - (pop gnus-topic-killed-topics) - (or (gnus-topic-goto-topic topic) - (gnus-topic-goto-topic parent)))))) - -(defun gnus-topic-unindent () - "Unindent a topic." - (interactive) - (let* ((topic (gnus-current-topic)) - (parent (gnus-topic-parent-topic topic)) - (grandparent (gnus-topic-parent-topic parent))) - (unless grandparent - (error "Nothing to indent %s into" topic)) - (when topic - (gnus-topic-goto-topic topic) - (gnus-topic-kill-group) - (push (cdar gnus-topic-killed-topics) gnus-topic-alist) - (gnus-topic-create-topic - topic grandparent (gnus-topic-next-topic parent) - (cdaar gnus-topic-killed-topics)) - (pop gnus-topic-killed-topics) - (gnus-topic-goto-topic topic)))) - -(defun gnus-topic-list-active (&optional force) - "List all groups that Gnus knows about in a topicsified fashion. -If FORCE, always re-read the active file." - (interactive "P") - (when force - (gnus-get-killed-groups)) - (gnus-topic-grok-active force) - (let ((gnus-topic-topology gnus-topic-active-topology) - (gnus-topic-alist gnus-topic-active-alist) - gnus-killed-list gnus-zombie-list) - (gnus-group-list-groups gnus-level-killed nil 1))) - -(defun gnus-topic-toggle-display-empty-topics () - "Show/hide topics that have no unread articles." - (interactive) - (setq gnus-topic-display-empty-topics - (not gnus-topic-display-empty-topics)) - (gnus-group-list-groups) - (message "%s empty topics" - (if gnus-topic-display-empty-topics - "Showing" "Hiding"))) - -;;; Topic sorting functions - -(defun gnus-topic-edit-parameters (group) - "Edit the group parameters of GROUP. -If performed on a topic, edit the topic parameters instead." - (interactive (list (gnus-group-group-name))) - (if group - (gnus-group-edit-group-parameters group) - (if (not (gnus-group-topic-p)) - (error "Nothing to edit on the current line") - (let ((topic (gnus-group-topic-name))) - (gnus-edit-form - (gnus-topic-parameters topic) - (format "Editing the topic parameters for `%s'." - (or group topic)) - `(lambda (form) - (gnus-topic-set-parameters ,topic form))))))) - -(defun gnus-group-sort-topic (func reverse) - "Sort groups in the topics according to FUNC and REVERSE." - (let ((alist gnus-topic-alist)) - (while alist - ;; !!!Sometimes nil elements sneak into the alist, - ;; for some reason or other. - (setcar alist (delq nil (car alist))) - (setcar alist (delete "dummy.group" (car alist))) - (gnus-topic-sort-topic (pop alist) func reverse)))) - -(defun gnus-topic-sort-topic (topic func reverse) - ;; Each topic only lists the name of the group, while - ;; the sort predicates expect group infos as inputs. - ;; So we first transform the group names into infos, - ;; then sort, and then transform back into group names. - (setcdr - topic - (mapcar - (lambda (info) (gnus-info-group info)) - (sort - (mapcar - (lambda (group) (gnus-get-info group)) - (cdr topic)) - func))) - ;; Do the reversal, if necessary. - (when reverse - (setcdr topic (nreverse (cdr topic))))) - -(defun gnus-topic-sort-groups (func &optional reverse) - "Sort the current topic according to FUNC. -If REVERSE, reverse the sorting order." - (interactive (list gnus-group-sort-function current-prefix-arg)) - (let ((topic (assoc (gnus-current-topic) gnus-topic-alist))) - (gnus-topic-sort-topic - topic (gnus-make-sort-function func) reverse) - (gnus-group-list-groups))) - -(defun gnus-topic-sort-groups-by-alphabet (&optional reverse) - "Sort the current topic alphabetically by group name. -If REVERSE, sort in reverse order." - (interactive "P") - (gnus-topic-sort-groups 'gnus-group-sort-by-alphabet reverse)) - -(defun gnus-topic-sort-groups-by-unread (&optional reverse) - "Sort the current topic by number of unread articles. -If REVERSE, sort in reverse order." - (interactive "P") - (gnus-topic-sort-groups 'gnus-group-sort-by-unread reverse)) - -(defun gnus-topic-sort-groups-by-level (&optional reverse) - "Sort the current topic by group level. -If REVERSE, sort in reverse order." - (interactive "P") - (gnus-topic-sort-groups 'gnus-group-sort-by-level reverse)) - -(defun gnus-topic-sort-groups-by-score (&optional reverse) - "Sort the current topic by group score. -If REVERSE, sort in reverse order." - (interactive "P") - (gnus-topic-sort-groups 'gnus-group-sort-by-score reverse)) - -(defun gnus-topic-sort-groups-by-rank (&optional reverse) - "Sort the current topic by group rank. -If REVERSE, sort in reverse order." - (interactive "P") - (gnus-topic-sort-groups 'gnus-group-sort-by-rank reverse)) - -(defun gnus-topic-sort-groups-by-method (&optional reverse) - "Sort the current topic alphabetically by backend name. -If REVERSE, sort in reverse order." - (interactive "P") - (gnus-topic-sort-groups 'gnus-group-sort-by-method reverse)) - -(provide 'gnus-topic) - -;;; gnus-topic.el ends here diff --git a/lisp/gnus-undo.el b/lisp/gnus-undo.el deleted file mode 100644 index 90cf174..0000000 --- a/lisp/gnus-undo.el +++ /dev/null @@ -1,193 +0,0 @@ -;;; gnus-undo.el --- minor mode for undoing in Gnus -;; Copyright (C) 1996,97,98 Free Software Foundation, Inc. - -;; Author: Lars Magne Ingebrigtsen -;; Keywords: news - -;; This file is part of GNU Emacs. - -;; GNU Emacs is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 2, or (at your option) -;; any later version. - -;; GNU Emacs is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs; see the file COPYING. If not, write to the -;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. - -;;; Commentary: - -;; This package allows arbitrary undoing in Gnus buffers. As all the -;; Gnus buffers aren't very text-oriented (what is in the buffers is -;; just some arbitrary representation of the actual data), normal Emacs -;; undoing doesn't work at all for Gnus. -;; -;; This package works by letting Gnus register functions for reversing -;; actions, and then calling these functions when the user pushes the -;; `undo' key. As with normal `undo', there it is possible to set -;; undo boundaries and so on. -;; -;; Internally, the undo sequence is represented by the -;; `gnus-undo-actions' list, where each element is a list of functions -;; to be called, in sequence, to undo some action. (An "action" is a -;; collection of functions.) -;; -;; For instance, a function for killing a group will call -;; `gnus-undo-register' with a function that un-kills the group. This -;; package will put that function into an action. - -;;; Code: - -(eval-when-compile (require 'cl)) - -(require 'gnus-util) -(require 'gnus) -(require 'custom) - -(defgroup gnus-undo nil - "Undoing in Gnus buffers." - :group 'gnus) - -(defcustom gnus-undo-limit 2000 - "The number of undoable actions recorded." - :type 'integer - :group 'gnus-undo) - -(defcustom gnus-undo-mode nil - "Minor mode for undoing in Gnus buffers." - :type 'boolean - :group 'gnus-undo) - -(defcustom gnus-undo-mode-hook nil - "Hook called in all `gnus-undo-mode' buffers." - :type 'hook - :group 'gnus-undo) - -;;; Internal variables. - -(defvar gnus-undo-actions nil) -(defvar gnus-undo-boundary t) -(defvar gnus-undo-last nil) -(defvar gnus-undo-boundary-inhibit nil) - -;;; Minor mode definition. - -(defvar gnus-undo-mode-map nil) - -(unless gnus-undo-mode-map - (setq gnus-undo-mode-map (make-sparse-keymap)) - - (gnus-define-keys gnus-undo-mode-map - "\M-\C-_" gnus-undo - "\C-_" gnus-undo - "\C-xu" gnus-undo - ;; many people are used to type `C-/' on X terminals and get `C-_'. - [(control /)] gnus-undo)) - -(defun gnus-undo-make-menu-bar () - ;; This is disabled for the time being. - (when nil - (define-key-after (current-local-map) [menu-bar file gnus-undo] - (cons "Undo" 'gnus-undo-actions) - [menu-bar file whatever]))) - -(defun gnus-undo-mode (&optional arg) - "Minor mode for providing `undo' in Gnus buffers. - -\\{gnus-undo-mode-map}" - (interactive "P") - (set (make-local-variable 'gnus-undo-mode) - (if (null arg) (not gnus-undo-mode) - (> (prefix-numeric-value arg) 0))) - (set (make-local-variable 'gnus-undo-actions) nil) - (set (make-local-variable 'gnus-undo-boundary) t) - (when gnus-undo-mode - ;; Set up the menu. - (when (gnus-visual-p 'undo-menu 'menu) - (gnus-undo-make-menu-bar)) - (gnus-add-minor-mode 'gnus-undo-mode "" gnus-undo-mode-map) - (make-local-hook 'post-command-hook) - (add-hook 'post-command-hook 'gnus-undo-boundary nil t) - (gnus-run-hooks 'gnus-undo-mode-hook))) - -;;; Interface functions. - -(defun gnus-disable-undo (&optional buffer) - "Disable undoing in the current buffer." - (interactive) - (save-excursion - (when buffer - (set-buffer buffer)) - (gnus-undo-mode -1))) - -(defun gnus-undo-boundary () - "Set Gnus undo boundary." - (if gnus-undo-boundary-inhibit - (setq gnus-undo-boundary-inhibit nil) - (setq gnus-undo-boundary t))) - -(defun gnus-undo-force-boundary () - "Set Gnus undo boundary." - (setq gnus-undo-boundary-inhibit nil - gnus-undo-boundary t)) - -(defun gnus-undo-register (form) - "Register FORMS as something to be performed to undo a change. -FORMS may use backtick quote syntax." - (when gnus-undo-mode - (gnus-undo-register-1 - `(lambda () - ,form)))) - -(put 'gnus-undo-register 'lisp-indent-function 0) -(put 'gnus-undo-register 'edebug-form-spec '(body)) - -(defun gnus-undo-register-1 (function) - "Register FUNCTION as something to be performed to undo a change." - (when gnus-undo-mode - (cond - ;; We are on a boundary, so we create a new action. - (gnus-undo-boundary - (push (list function) gnus-undo-actions) - (setq gnus-undo-boundary nil)) - ;; Prepend the function to an old action. - (gnus-undo-actions - (setcar gnus-undo-actions (cons function (car gnus-undo-actions)))) - ;; Initialize list. - (t - (setq gnus-undo-actions (list (list function))))) - ;; Limit the length of the undo list. - (let ((next (nthcdr gnus-undo-limit gnus-undo-actions))) - (when next - (setcdr next nil))) - ;; We are not at a boundary... - (setq gnus-undo-boundary-inhibit t))) - -(defun gnus-undo (n) - "Undo some previous changes in Gnus buffers. -Repeat this command to undo more changes. -A numeric argument serves as a repeat count." - (interactive "p") - (unless gnus-undo-mode - (error "Undoing is not enabled in this buffer")) - (message "%s" last-command) - (when (or (not (eq last-command 'gnus-undo)) - (not gnus-undo-last)) - (setq gnus-undo-last gnus-undo-actions)) - (let ((action (pop gnus-undo-last))) - (unless action - (error "Nothing further to undo")) - (setq gnus-undo-actions (delq action gnus-undo-actions)) - (setq gnus-undo-boundary t) - (while action - (funcall (pop action))))) - -(provide 'gnus-undo) - -;;; gnus-undo.el ends here diff --git a/lisp/gnus-util.el b/lisp/gnus-util.el deleted file mode 100644 index 5359dda..0000000 --- a/lisp/gnus-util.el +++ /dev/null @@ -1,994 +0,0 @@ -;;; gnus-util.el --- utility functions for Semi-gnus -;; Copyright (C) 1996,97,98 Free Software Foundation, Inc. - -;; Author: Lars Magne Ingebrigtsen -;; Keywords: mail, news, MIME - -;; This file is part of GNU Emacs. - -;; GNU Emacs is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 2, or (at your option) -;; any later version. - -;; GNU Emacs is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs; see the file COPYING. If not, write to the -;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. - -;;; Commentary: - -;; Nothing in this file depends on any other parts of Gnus -- all -;; functions and macros in this file are utility functions that are -;; used by Gnus and may be used by any other package without loading -;; Gnus first. - -;;; Code: - -(require 'custom) -(eval-when-compile (require 'cl)) -(require 'nnheader) -(require 'timezone) -(require 'message) - -(eval-and-compile - (autoload 'nnmail-date-to-time "nnmail") - (autoload 'rmail-insert-rmail-file-header "rmail") - (autoload 'rmail-count-new-messages "rmail") - (autoload 'rmail-show-message "rmail")) - -(defun gnus-boundp (variable) - "Return non-nil if VARIABLE is bound and non-nil." - (and (boundp variable) - (symbol-value variable))) - -(defmacro gnus-eval-in-buffer-window (buffer &rest forms) - "Pop to BUFFER, evaluate FORMS, and then return to the original window." - (let ((tempvar (make-symbol "GnusStartBufferWindow")) - (w (make-symbol "w")) - (buf (make-symbol "buf"))) - `(let* ((,tempvar (selected-window)) - (,buf ,buffer) - (,w (get-buffer-window ,buf 'visible))) - (unwind-protect - (progn - (if ,w - (progn - (select-window ,w) - (set-buffer (window-buffer ,w))) - (pop-to-buffer ,buf)) - ,@forms) - (select-window ,tempvar))))) - -(put 'gnus-eval-in-buffer-window 'lisp-indent-function 1) -(put 'gnus-eval-in-buffer-window 'edebug-form-spec '(form body)) - -(defmacro gnus-intern-safe (string hashtable) - "Set hash value. Arguments are STRING, VALUE, and HASHTABLE." - `(let ((symbol (intern ,string ,hashtable))) - (or (boundp symbol) - (set symbol nil)) - symbol)) - -;; Avoid byte-compile warning. -;; In Mule, this function will be redefined to `truncate-string', -;; which takes 3 or 4 args. -(defun gnus-truncate-string (str width &rest ignore) - (substring str 0 width)) - -;; Added by Geoffrey T. Dairiki . A safe way -;; to limit the length of a string. This function is necessary since -;; `(substr "abc" 0 30)' pukes with "Args out of range". -(defsubst gnus-limit-string (str width) - (if (> (length str) width) - (substring str 0 width) - str)) - -(defsubst gnus-functionp (form) - "Return non-nil if FORM is funcallable." - (or (and (symbolp form) (fboundp form)) - (and (listp form) (eq (car form) 'lambda)) - (byte-code-function-p form))) - -(defsubst gnus-goto-char (point) - (and point (goto-char point))) - -(defmacro gnus-buffer-exists-p (buffer) - `(let ((buffer ,buffer)) - (when buffer - (funcall (if (stringp buffer) 'get-buffer 'buffer-name) - buffer)))) - -(defmacro gnus-kill-buffer (buffer) - `(let ((buf ,buffer)) - (when (gnus-buffer-exists-p buf) - (kill-buffer buf)))) - -(if (fboundp 'point-at-bol) - (fset 'gnus-point-at-bol 'point-at-bol) - (defun gnus-point-at-bol () - "Return point at the beginning of the line." - (let ((p (point))) - (beginning-of-line) - (prog1 - (point) - (goto-char p))))) - -(if (fboundp 'point-at-eol) - (fset 'gnus-point-at-eol 'point-at-eol) - (defun gnus-point-at-eol () - "Return point at the end of the line." - (let ((p (point))) - (end-of-line) - (prog1 - (point) - (goto-char p))))) - -(defun gnus-delete-first (elt list) - "Delete by side effect the first occurrence of ELT as a member of LIST." - (if (equal (car list) elt) - (cdr list) - (let ((total list)) - (while (and (cdr list) - (not (equal (cadr list) elt))) - (setq list (cdr list))) - (when (cdr list) - (setcdr list (cddr list))) - total))) - -;; Delete the current line (and the next N lines). -(defmacro gnus-delete-line (&optional n) - `(delete-region (progn (beginning-of-line) (point)) - (progn (forward-line ,(or n 1)) (point)))) - -(defun gnus-byte-code (func) - "Return a form that can be `eval'ed based on FUNC." - (let ((fval (indirect-function func))) - (if (byte-code-function-p fval) - (let ((flist (append fval nil))) - (setcar flist 'byte-code) - flist) - (cons 'progn (cddr fval))))) - -(defun gnus-extract-address-components (from) - (let (name address) - ;; First find the address - the thing with the @ in it. This may - ;; not be accurate in mail addresses, but does the trick most of - ;; the time in news messages. - (when (string-match "\\b[^@ \t<>]+[!@][^@ \t<>]+\\b" from) - (setq address (substring from (match-beginning 0) (match-end 0)))) - ;; Then we check whether the "name

" format is used. - (and address - ;; Linear white space is not required. - (string-match (concat "[ \t]*<" (regexp-quote address) ">") from) - (and (setq name (substring from 0 (match-beginning 0))) - ;; Strip any quotes from the name. - (string-match "\".*\"" name) - (setq name (substring name 1 (1- (match-end 0)))))) - ;; If not, then "address (name)" is used. - (or name - (and (string-match "(.+)" from) - (setq name (substring from (1+ (match-beginning 0)) - (1- (match-end 0))))) - (and (string-match "()" from) - (setq name address)) - ;; XOVER might not support folded From headers. - (and (string-match "(.*" from) - (setq name (substring from (1+ (match-beginning 0)) - (match-end 0))))) - ;; Fix by Hallvard B Furuseth . - (list (or name from) (or address from)))) - -(defun gnus-fetch-field (field) - "Return the value of the header FIELD of current article." - (save-excursion - (save-restriction - (let ((case-fold-search t) - (inhibit-point-motion-hooks t)) - (nnheader-narrow-to-headers) - (message-fetch-field field))))) - -(defun gnus-goto-colon () - (beginning-of-line) - (search-forward ":" (gnus-point-at-eol) t)) - -(defun gnus-remove-text-with-property (prop) - "Delete all text in the current buffer with text property PROP." - (save-excursion - (goto-char (point-min)) - (while (not (eobp)) - (while (get-text-property (point) prop) - (delete-char 1)) - (goto-char (next-single-property-change (point) prop nil (point-max)))))) - -(defun gnus-newsgroup-directory-form (newsgroup) - "Make hierarchical directory name from NEWSGROUP name." - (let ((newsgroup (gnus-newsgroup-savable-name newsgroup)) - (len (length newsgroup)) - idx) - ;; If this is a foreign group, we don't want to translate the - ;; entire name. - (if (setq idx (string-match ":" newsgroup)) - (aset newsgroup idx ?/) - (setq idx 0)) - ;; Replace all occurrences of `.' with `/'. - (while (< idx len) - (when (= (aref newsgroup idx) ?.) - (aset newsgroup idx ?/)) - (setq idx (1+ idx))) - newsgroup)) - -(defun gnus-newsgroup-savable-name (group) - ;; Replace any slashes in a group name (eg. an ange-ftp nndoc group) - ;; with dots. - (nnheader-replace-chars-in-string group ?/ ?.)) - -(defun gnus-string> (s1 s2) - (not (or (string< s1 s2) - (string= s1 s2)))) - -;;; Time functions. - -(defun gnus-days-between (date1 date2) - ;; Return the number of days between date1 and date2. - (- (gnus-day-number date1) (gnus-day-number date2))) - -(defun gnus-day-number (date) - (let ((dat (mapcar (lambda (s) (and s (string-to-int s)) ) - (timezone-parse-date date)))) - (timezone-absolute-from-gregorian - (nth 1 dat) (nth 2 dat) (car dat)))) - -(defun gnus-time-to-day (time) - "Convert TIME to day number." - (let ((tim (decode-time time))) - (timezone-absolute-from-gregorian - (nth 4 tim) (nth 3 tim) (nth 5 tim)))) - -(defun gnus-encode-date (date) - "Convert DATE to internal time." - (let* ((parse (timezone-parse-date date)) - (date (mapcar (lambda (d) (and d (string-to-int d))) parse)) - (time (mapcar 'string-to-int (timezone-parse-time (aref parse 3))))) - (encode-time (caddr time) (cadr time) (car time) - (caddr date) (cadr date) (car date) - (* 60 (timezone-zone-to-minute (nth 4 date)))))) - -(defun gnus-time-minus (t1 t2) - "Subtract two internal times." - (let ((borrow (< (cadr t1) (cadr t2)))) - (list (- (car t1) (car t2) (if borrow 1 0)) - (- (+ (if borrow 65536 0) (cadr t1)) (cadr t2))))) - -(defun gnus-time-less (t1 t2) - "Say whether time T1 is less than time T2." - (or (< (car t1) (car t2)) - (and (= (car t1) (car t2)) - (< (nth 1 t1) (nth 1 t2))))) - -(defun gnus-file-newer-than (file date) - (let ((fdate (nth 5 (file-attributes file)))) - (or (> (car fdate) (car date)) - (and (= (car fdate) (car date)) - (> (nth 1 fdate) (nth 1 date)))))) - -;;; Keymap macros. - -(defmacro gnus-local-set-keys (&rest plist) - "Set the keys in PLIST in the current keymap." - `(gnus-define-keys-1 (current-local-map) ',plist)) - -(defmacro gnus-define-keys (keymap &rest plist) - "Define all keys in PLIST in KEYMAP." - `(gnus-define-keys-1 (quote ,keymap) (quote ,plist))) - -(defmacro gnus-define-keys-safe (keymap &rest plist) - "Define all keys in PLIST in KEYMAP without overwriting previous definitions." - `(gnus-define-keys-1 (quote ,keymap) (quote ,plist) t)) - -(put 'gnus-define-keys 'lisp-indent-function 1) -(put 'gnus-define-keys-safe 'lisp-indent-function 1) -(put 'gnus-local-set-keys 'lisp-indent-function 1) - -(defmacro gnus-define-keymap (keymap &rest plist) - "Define all keys in PLIST in KEYMAP." - `(gnus-define-keys-1 ,keymap (quote ,plist))) - -(put 'gnus-define-keymap 'lisp-indent-function 1) - -(defun gnus-define-keys-1 (keymap plist &optional safe) - (when (null keymap) - (error "Can't set keys in a null keymap")) - (cond ((symbolp keymap) - (setq keymap (symbol-value keymap))) - ((keymapp keymap)) - ((listp keymap) - (set (car keymap) nil) - (define-prefix-command (car keymap)) - (define-key (symbol-value (caddr keymap)) (cadr keymap) (car keymap)) - (setq keymap (symbol-value (car keymap))))) - (let (key) - (while plist - (when (symbolp (setq key (pop plist))) - (setq key (symbol-value key))) - (if (or (not safe) - (eq (lookup-key keymap key) 'undefined)) - (define-key keymap key (pop plist)) - (pop plist))))) - -(defun gnus-completing-read (default prompt &rest args) - ;; Like `completing-read', except that DEFAULT is the default argument. - (let* ((prompt (if default - (concat prompt " (default " default ") ") - (concat prompt " "))) - (answer (apply 'completing-read prompt args))) - (if (or (null answer) (zerop (length answer))) - default - answer))) - -;; Two silly functions to ensure that all `y-or-n-p' questions clear -;; the echo area. -(defun gnus-y-or-n-p (prompt) - (prog1 - (y-or-n-p prompt) - (message ""))) - -(defun gnus-yes-or-no-p (prompt) - (prog1 - (yes-or-no-p prompt) - (message ""))) - -(defun gnus-dd-mmm (messy-date) - "Return a string like DD-MMM from a big messy string." - (let ((datevec (ignore-errors (timezone-parse-date messy-date)))) - (if (or (not datevec) - (string-equal "0" (aref datevec 1))) - "??-???" - (format "%2s-%s" - (condition-case () - ;; Make sure leading zeroes are stripped. - (number-to-string (string-to-number (aref datevec 2))) - (error "??")) - (capitalize - (or (car - (nth (1- (string-to-number (aref datevec 1))) - timezone-months-assoc)) - "???")))))) - -(defmacro gnus-date-get-time (date) - "Convert DATE string to Emacs time. -Cache the result as a text property stored in DATE." - ;; Either return the cached value... - `(let ((d ,date)) - (if (equal "" d) - '(0 0) - (or (get-text-property 0 'gnus-time d) - ;; or compute the value... - (let ((time (nnmail-date-to-time d))) - ;; and store it back in the string. - (put-text-property 0 1 'gnus-time time d) - time))))) - -(defsubst gnus-time-iso8601 (time) - "Return a string of TIME in YYMMDDTHHMMSS format." - (format-time-string "%Y%m%dT%H%M%S" time)) - -(defun gnus-date-iso8601 (date) - "Convert the DATE to YYMMDDTHHMMSS." - (condition-case () - (gnus-time-iso8601 (gnus-date-get-time date)) - (error ""))) - -(defun gnus-mode-string-quote (string) - "Quote all \"%\"'s in STRING." - (save-excursion - (gnus-set-work-buffer) - (insert string) - (goto-char (point-min)) - (while (search-forward "%" nil t) - (insert "%")) - (buffer-string))) - -;; Make a hash table (default and minimum size is 256). -;; Optional argument HASHSIZE specifies the table size. -(defun gnus-make-hashtable (&optional hashsize) - (make-vector (if hashsize (max (gnus-create-hash-size hashsize) 256) 256) 0)) - -;; Make a number that is suitable for hashing; bigger than MIN and -;; equal to some 2^x. Many machines (such as sparcs) do not have a -;; hardware modulo operation, so they implement it in software. On -;; many sparcs over 50% of the time to intern is spent in the modulo. -;; Yes, it's slower than actually computing the hash from the string! -;; So we use powers of 2 so people can optimize the modulo to a mask. -(defun gnus-create-hash-size (min) - (let ((i 1)) - (while (< i min) - (setq i (* 2 i))) - i)) - -(defcustom gnus-verbose 7 - "*Integer that says how verbose Gnus should be. -The higher the number, the more messages Gnus will flash to say what -it's doing. At zero, Gnus will be totally mute; at five, Gnus will -display most important messages; and at ten, Gnus will keep on -jabbering all the time." - :group 'gnus-start - :type 'integer) - -;; Show message if message has a lower level than `gnus-verbose'. -;; Guideline for numbers: -;; 1 - error messages, 3 - non-serious error messages, 5 - messages -;; for things that take a long time, 7 - not very important messages -;; on stuff, 9 - messages inside loops. -(defun gnus-message (level &rest args) - (if (<= level gnus-verbose) - (apply 'message args) - ;; We have to do this format thingy here even if the result isn't - ;; shown - the return value has to be the same as the return value - ;; from `message'. - (apply 'format args))) - -(defun gnus-error (level &rest args) - "Beep an error if LEVEL is equal to or less than `gnus-verbose'." - (when (<= (floor level) gnus-verbose) - (apply 'message args) - (ding) - (let (duration) - (when (and (floatp level) - (not (zerop (setq duration (* 10 (- level (floor level))))))) - (sit-for duration)))) - nil) - -(defun gnus-split-references (references) - "Return a list of Message-IDs in REFERENCES." - (let ((beg 0) - ids) - (while (string-match "<[^>]+>" references beg) - (push (substring references (match-beginning 0) (setq beg (match-end 0))) - ids)) - (nreverse ids))) - -(defun gnus-parent-id (references &optional n) - "Return the last Message-ID in REFERENCES. -If N, return the Nth ancestor instead." - (when references - (let ((ids (inline (gnus-split-references references)))) - (while (nthcdr (or n 1) ids) - (setq ids (cdr ids))) - (car ids)))) - -(defsubst gnus-buffer-live-p (buffer) - "Say whether BUFFER is alive or not." - (and buffer - (get-buffer buffer) - (buffer-name (get-buffer buffer)))) - -(defun gnus-horizontal-recenter () - "Recenter the current buffer horizontally." - (if (< (current-column) (/ (window-width) 2)) - (set-window-hscroll (get-buffer-window (current-buffer) t) 0) - (let* ((orig (point)) - (end (window-end (get-buffer-window (current-buffer) t))) - (max 0)) - (when end - ;; Find the longest line currently displayed in the window. - (goto-char (window-start)) - (while (and (not (eobp)) - (< (point) end)) - (end-of-line) - (setq max (max max (current-column))) - (forward-line 1)) - (goto-char orig) - ;; Scroll horizontally to center (sort of) the point. - (if (> max (window-width)) - (set-window-hscroll - (get-buffer-window (current-buffer) t) - (min (- (current-column) (/ (window-width) 3)) - (+ 2 (- max (window-width))))) - (set-window-hscroll (get-buffer-window (current-buffer) t) 0)) - max)))) - -(defun gnus-read-event-char () - "Get the next event." - (let ((event (read-event))) - ;; should be gnus-characterp, but this can't be called in XEmacs anyway - (cons (and (numberp event) event) event))) - -(defun gnus-sortable-date (date) - "Make sortable string by string-lessp from DATE. -Timezone package is used." - (condition-case () - (progn - (setq date (inline (timezone-fix-time - date nil - (aref (inline (timezone-parse-date date)) 4)))) - (inline - (timezone-make-sortable-date - (aref date 0) (aref date 1) (aref date 2) - (inline - (timezone-make-time-string - (aref date 3) (aref date 4) (aref date 5)))))) - (error ""))) - -(defun gnus-copy-file (file &optional to) - "Copy FILE to TO." - (interactive - (list (read-file-name "Copy file: " default-directory) - (read-file-name "Copy file to: " default-directory))) - (unless to - (setq to (read-file-name "Copy file to: " default-directory))) - (when (file-directory-p to) - (setq to (concat (file-name-as-directory to) - (file-name-nondirectory file)))) - (copy-file file to)) - -(defun gnus-kill-all-overlays () - "Delete all overlays in the current buffer." - (let* ((overlayss (overlay-lists)) - (buffer-read-only nil) - (overlays (delq nil (nconc (car overlayss) (cdr overlayss))))) - (while overlays - (delete-overlay (pop overlays))))) - -(defvar gnus-work-buffer " *gnus work*") - -(defun gnus-set-work-buffer () - "Put point in the empty Gnus work buffer." - (if (get-buffer gnus-work-buffer) - (progn - (set-buffer gnus-work-buffer) - (erase-buffer)) - (set-buffer (gnus-get-buffer-create gnus-work-buffer)) - (kill-all-local-variables) - (buffer-disable-undo (current-buffer)))) - -(defmacro gnus-group-real-name (group) - "Find the real name of a foreign newsgroup." - `(let ((gname ,group)) - (if (string-match "^[^:]+:" gname) - (substring gname (match-end 0)) - gname))) - -(defun gnus-make-sort-function (funs) - "Return a composite sort condition based on the functions in FUNC." - (cond - ((not (listp funs)) funs) - ((null funs) funs) - ((cdr funs) - `(lambda (t1 t2) - ,(gnus-make-sort-function-1 (reverse funs)))) - (t - (car funs)))) - -(defun gnus-make-sort-function-1 (funs) - "Return a composite sort condition based on the functions in FUNC." - (if (cdr funs) - `(or (,(car funs) t1 t2) - (and (not (,(car funs) t2 t1)) - ,(gnus-make-sort-function-1 (cdr funs)))) - `(,(car funs) t1 t2))) - -(defun gnus-turn-off-edit-menu (type) - "Turn off edit menu in `gnus-TYPE-mode-map'." - (define-key (symbol-value (intern (format "gnus-%s-mode-map" type))) - [menu-bar edit] 'undefined)) - -(defun gnus-prin1 (form) - "Use `prin1' on FORM in the current buffer. -Bind `print-quoted' and `print-readably' to t while printing." - (let ((print-quoted t) - (print-readably t) - (print-escape-multibyte nil) - print-level print-length) - (prin1 form (current-buffer)))) - -(defun gnus-prin1-to-string (form) - "The same as `prin1', but bind `print-quoted' and `print-readably' to t." - (let ((print-quoted t) - (print-readably t)) - (prin1-to-string form))) - -(defun gnus-make-directory (directory) - "Make DIRECTORY (and all its parents) if it doesn't exist." - (when (and directory - (not (file-exists-p directory))) - (make-directory directory t)) - t) - -(defun gnus-write-buffer (file) - "Write the current buffer's contents to FILE." - ;; Make sure the directory exists. - (gnus-make-directory (file-name-directory file)) - ;; Write the buffer. - (write-region (point-min) (point-max) file nil 'quietly)) - -(defun gnus-delete-file (file) - "Delete FILE if it exists." - (when (file-exists-p file) - (delete-file file))) - -(defun gnus-strip-whitespace (string) - "Return STRING stripped of all whitespace." - (while (string-match "[\r\n\t ]+" string) - (setq string (replace-match "" t t string))) - string) - -(defun gnus-put-text-property-excluding-newlines (beg end prop val) - "The same as `put-text-property', but don't put this prop on any newlines in the region." - (save-match-data - (save-excursion - (save-restriction - (goto-char beg) - (while (re-search-forward "[ \t]*\n" end 'move) - (gnus-put-text-property beg (match-beginning 0) prop val) - (setq beg (point))) - (gnus-put-text-property beg (point) prop val))))) - -(defun gnus-put-text-property-excluding-characters-with-faces (beg end - prop val) - "The same as `put-text-property', but don't put props on characters with the `gnus-face' property." - (let ((b beg)) - (while (/= b end) - (when (get-text-property b 'gnus-face) - (setq b (next-single-property-change b 'gnus-face nil end))) - (when (/= b end) - (gnus-put-text-property - b (setq b (next-single-property-change b 'gnus-face nil end)) - prop val))))) - -;;; Protected and atomic operations. dmoore@ucsd.edu 21.11.1996 -;;; The primary idea here is to try to protect internal datastructures -;;; from becoming corrupted when the user hits C-g, or if a hook or -;;; similar blows up. Often in Gnus multiple tables/lists need to be -;;; updated at the same time, or information can be lost. - -(defvar gnus-atomic-be-safe t - "If t, certain operations will be protected from interruption by C-g.") - -(defmacro gnus-atomic-progn (&rest forms) - "Evaluate FORMS atomically, which means to protect the evaluation -from being interrupted by the user. An error from the forms themselves -will return without finishing the operation. Since interrupts from -the user are disabled, it is recommended that only the most minimal -operations are performed by FORMS. If you wish to assign many -complicated values atomically, compute the results into temporary -variables and then do only the assignment atomically." - `(let ((inhibit-quit gnus-atomic-be-safe)) - ,@forms)) - -(put 'gnus-atomic-progn 'lisp-indent-function 0) - -(defmacro gnus-atomic-progn-assign (protect &rest forms) - "Evaluate FORMS, but insure that the variables listed in PROTECT -are not changed if anything in FORMS signals an error or otherwise -non-locally exits. The variables listed in PROTECT are updated atomically. -It is safe to use gnus-atomic-progn-assign with long computations. - -Note that if any of the symbols in PROTECT were unbound, they will be -set to nil on a sucessful assignment. In case of an error or other -non-local exit, it will still be unbound." - (let* ((temp-sym-map (mapcar (lambda (x) (list (make-symbol - (concat (symbol-name x) - "-tmp")) - x)) - protect)) - (sym-temp-map (mapcar (lambda (x) (list (cadr x) (car x))) - temp-sym-map)) - (temp-sym-let (mapcar (lambda (x) (list (car x) - `(and (boundp ',(cadr x)) - ,(cadr x)))) - temp-sym-map)) - (sym-temp-let sym-temp-map) - (temp-sym-assign (apply 'append temp-sym-map)) - (sym-temp-assign (apply 'append sym-temp-map)) - (result (make-symbol "result-tmp"))) - `(let (,@temp-sym-let - ,result) - (let ,sym-temp-let - (setq ,result (progn ,@forms)) - (setq ,@temp-sym-assign)) - (let ((inhibit-quit gnus-atomic-be-safe)) - (setq ,@sym-temp-assign)) - ,result))) - -(put 'gnus-atomic-progn-assign 'lisp-indent-function 1) -;(put 'gnus-atomic-progn-assign 'edebug-form-spec '(sexp body)) - -(defmacro gnus-atomic-setq (&rest pairs) - "Similar to setq, except that the real symbols are only assigned when -there are no errors. And when the real symbols are assigned, they are -done so atomically. If other variables might be changed via side-effect, -see gnus-atomic-progn-assign. It is safe to use gnus-atomic-setq -with potentially long computations." - (let ((tpairs pairs) - syms) - (while tpairs - (push (car tpairs) syms) - (setq tpairs (cddr tpairs))) - `(gnus-atomic-progn-assign ,syms - (setq ,@pairs)))) - -;(put 'gnus-atomic-setq 'edebug-form-spec '(body)) - - -;;; Functions for saving to babyl/mail files. - -(defvar rmail-default-rmail-file) -(defun gnus-output-to-rmail (filename &optional ask) - "Append the current article to an Rmail file named FILENAME." - (require 'rmail) - ;; Most of these codes are borrowed from rmailout.el. - (setq filename (expand-file-name filename)) - (setq rmail-default-rmail-file filename) - (let ((artbuf (current-buffer)) - (tmpbuf (gnus-get-buffer-create " *Gnus-output*"))) - (save-excursion - (or (get-file-buffer filename) - (file-exists-p filename) - (if (or (not ask) - (gnus-yes-or-no-p - (concat "\"" filename "\" does not exist, create it? "))) - (let ((file-buffer (create-file-buffer filename))) - (save-excursion - (set-buffer file-buffer) - (rmail-insert-rmail-file-header) - (let ((require-final-newline nil)) - (gnus-write-buffer filename))) - (kill-buffer file-buffer)) - (error "Output file does not exist"))) - (set-buffer tmpbuf) - (erase-buffer) - (insert-buffer-substring artbuf) - (gnus-convert-article-to-rmail) - ;; Decide whether to append to a file or to an Emacs buffer. - (let ((outbuf (get-file-buffer filename))) - (if (not outbuf) - (append-to-file (point-min) (point-max) filename) - ;; File has been visited, in buffer OUTBUF. - (set-buffer outbuf) - (let ((buffer-read-only nil) - (msg (and (boundp 'rmail-current-message) - (symbol-value 'rmail-current-message)))) - ;; If MSG is non-nil, buffer is in RMAIL mode. - (when msg - (widen) - (narrow-to-region (point-max) (point-max))) - (insert-buffer-substring tmpbuf) - (when msg - (goto-char (point-min)) - (widen) - (search-backward "\n\^_") - (narrow-to-region (point) (point-max)) - (rmail-count-new-messages t) - (when (rmail-summary-exists) - (rmail-select-summary - (rmail-update-summary))) - (rmail-count-new-messages t) - (rmail-show-message msg)) - (save-buffer))))) - (kill-buffer tmpbuf))) - -(defun gnus-output-to-mail (filename &optional ask) - "Append the current article to a mail file named FILENAME." - (setq filename (expand-file-name filename)) - (let ((artbuf (current-buffer)) - (tmpbuf (gnus-get-buffer-create " *Gnus-output*"))) - (save-excursion - ;; Create the file, if it doesn't exist. - (when (and (not (get-file-buffer filename)) - (not (file-exists-p filename))) - (if (or (not ask) - (gnus-y-or-n-p - (concat "\"" filename "\" does not exist, create it? "))) - (let ((file-buffer (create-file-buffer filename))) - (save-excursion - (set-buffer file-buffer) - (let ((require-final-newline nil) - (coding-system-for-write 'binary)) - (gnus-write-buffer filename))) - (kill-buffer file-buffer)) - (error "Output file does not exist"))) - (set-buffer tmpbuf) - (erase-buffer) - (insert-buffer-substring artbuf) - (goto-char (point-min)) - (if (looking-at "From ") - (forward-line 1) - (insert "From nobody " (current-time-string) "\n")) - (let (case-fold-search) - (while (re-search-forward "^From " nil t) - (beginning-of-line) - (insert ">"))) - ;; Decide whether to append to a file or to an Emacs buffer. - (let ((outbuf (get-file-buffer filename))) - (if (not outbuf) - (let ((buffer-read-only nil) - (coding-system-for-write 'binary)) - (save-excursion - (goto-char (point-max)) - (forward-char -2) - (unless (looking-at "\n\n") - (goto-char (point-max)) - (unless (bolp) - (insert "\n")) - (insert "\n")) - (goto-char (point-max)) - (append-to-file (point-min) (point-max) filename))) - ;; File has been visited, in buffer OUTBUF. - (set-buffer outbuf) - (let ((buffer-read-only nil)) - (goto-char (point-max)) - (unless (eobp) - (insert "\n")) - (insert "\n") - (insert-buffer-substring tmpbuf))))) - (kill-buffer tmpbuf))) - -(defun gnus-convert-article-to-rmail () - "Convert article in current buffer to Rmail message format." - (let ((buffer-read-only nil)) - ;; Convert article directly into Babyl format. - (goto-char (point-min)) - (insert "\^L\n0, unseen,,\n*** EOOH ***\n") - (while (search-forward "\n\^_" nil t) ;single char - (replace-match "\n^_" t t)) ;2 chars: "^" and "_" - (goto-char (point-max)) - (insert "\^_"))) - -(defun gnus-map-function (funs arg) - "Applies the result of the first function in FUNS to the second, and so on. -ARG is passed to the first function." - (let ((myfuns funs)) - (while myfuns - (setq arg (funcall (pop myfuns) arg))) - arg)) - -(defun gnus-run-hooks (&rest funcs) - "Does the same as `run-hooks', but saves excursion." - (let ((buf (current-buffer))) - (unwind-protect - (apply 'run-hooks funcs) - (set-buffer buf)))) - -;;; -;;; .netrc and .authinforc parsing -;;; - -(defvar gnus-netrc-syntax-table - (let ((table (copy-syntax-table text-mode-syntax-table))) - (modify-syntax-entry ?@ "w" table) - (modify-syntax-entry ?- "w" table) - (modify-syntax-entry ?_ "w" table) - (modify-syntax-entry ?! "w" table) - (modify-syntax-entry ?. "w" table) - (modify-syntax-entry ?, "w" table) - (modify-syntax-entry ?: "w" table) - (modify-syntax-entry ?\; "w" table) - (modify-syntax-entry ?% "w" table) - (modify-syntax-entry ?) "w" table) - (modify-syntax-entry ?( "w" table) - table) - "Syntax table when parsing .netrc files.") - -(defun gnus-parse-netrc (file) - "Parse FILE and return an list of all entries in the file." - (if (not (file-exists-p file)) - () - (save-excursion - (let ((tokens '("machine" "default" "login" - "password" "account" "macdef" "force")) - alist elem result pair) - (nnheader-set-temp-buffer " *netrc*") - (unwind-protect - (progn - (set-syntax-table gnus-netrc-syntax-table) - (insert-file-contents file) - (goto-char (point-min)) - ;; Go through the file, line by line. - (while (not (eobp)) - (narrow-to-region (point) (gnus-point-at-eol)) - ;; For each line, get the tokens and values. - (while (not (eobp)) - (skip-chars-forward "\t ") - (unless (eobp) - (setq elem (buffer-substring - (point) (progn (forward-sexp 1) (point)))) - (cond - ((equal elem "macdef") - ;; We skip past the macro definition. - (widen) - (while (and (zerop (forward-line 1)) - (looking-at "$"))) - (narrow-to-region (point) (point))) - ((member elem tokens) - ;; Tokens that don't have a following value are ignored, - ;; except "default". - (when (and pair (or (cdr pair) - (equal (car pair) "default"))) - (push pair alist)) - (setq pair (list elem))) - (t - ;; Values that haven't got a preceding token are ignored. - (when pair - (setcdr pair elem) - (push pair alist) - (setq pair nil)))))) - (if alist - (push (nreverse alist) result)) - (setq alist nil - pair nil) - (widen) - (forward-line 1)) - (nreverse result)) - (kill-buffer " *netrc*")))))) - -(defun gnus-netrc-machine (list machine) - "Return the netrc values from LIST for MACHINE or for the default entry." - (let ((rest list)) - (while (and list - (not (equal (cdr (assoc "machine" (car list))) machine))) - (pop list)) - (car (or list - (progn (while (and rest (not (assoc "default" (car rest)))) - (pop rest)) - rest))))) - -(defun gnus-netrc-get (alist type) - "Return the value of token TYPE from ALIST." - (cdr (assoc type alist))) - -;;; Various - -(defvar gnus-group-buffer) ; Compiler directive -(defun gnus-alive-p () - "Say whether Gnus is running or not." - (and (boundp 'gnus-group-buffer) - (get-buffer gnus-group-buffer) - (save-excursion - (set-buffer gnus-group-buffer) - (eq major-mode 'gnus-group-mode)))) - -(defun gnus-remove-duplicates (list) - (let (new (tail list)) - (while tail - (or (member (car tail) new) - (setq new (cons (car tail) new))) - (setq tail (cdr tail))) - (nreverse new))) - -(defun gnus-delete-if (predicate list) - "Delete elements from LIST that satisfy PREDICATE." - (let (out) - (while list - (unless (funcall predicate (car list)) - (push (car list) out)) - (pop list)) - (nreverse out))) - -(defun gnus-delete-alist (key alist) - "Delete all entries in ALIST that have a key eq to KEY." - (let (entry) - (while (setq entry (assq key alist)) - (setq alist (delq entry alist))) - alist)) - -(defmacro gnus-pull (key alist) - "Modify ALIST to be without KEY." - (unless (symbolp alist) - (error "Not a symbol: %s" alist)) - `(setq ,alist (delq (assq ,key ,alist) ,alist))) - -(defun gnus-globalify-regexp (re) - "Returns a regexp that matches a whole line, iff RE matches a part of it." - (concat (unless (string-match "^\\^" re) "^.*") - re - (unless (string-match "\\$$" re) ".*$"))) - -(provide 'gnus-util) - -;;; gnus-util.el ends here diff --git a/lisp/gnus-uu.el b/lisp/gnus-uu.el deleted file mode 100644 index 19929f3..0000000 --- a/lisp/gnus-uu.el +++ /dev/null @@ -1,2044 +0,0 @@ -;;; gnus-uu.el --- extract (uu)encoded files in Gnus -;; Copyright (C) 1985,86,87,93,94,95,96,97,98 Free Software Foundation, Inc. - -;; Author: Lars Magne Ingebrigtsen -;; Created: 2 Oct 1993 -;; Keyword: news - -;; This file is part of GNU Emacs. - -;; GNU Emacs is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 2, or (at your option) -;; any later version. - -;; GNU Emacs is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs; see the file COPYING. If not, write to the -;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. - -;;; Commentary: - -;;; Code: - -(eval-when-compile (require 'cl)) - -(require 'gnus) -(require 'gnus-art) -(require 'message) -(require 'gnus-msg) - -(defgroup gnus-extract nil - "Extracting encoded files." - :prefix "gnus-uu-" - :group 'gnus) - -(defgroup gnus-extract-view nil - "Viewwing extracted files." - :group 'gnus-extract) - -(defgroup gnus-extract-archive nil - "Extracting encoded archives." - :group 'gnus-extract) - -(defgroup gnus-extract-post nil - "Extracting encoded archives." - :prefix "gnus-uu-post" - :group 'gnus-extract) - -;; Default viewing action rules - -(defcustom gnus-uu-default-view-rules - '(("\\.te?xt$\\|\\.doc$\\|read.*me\\|\\.c?$\\|\\.h$\\|\\.bat$\\|\\.asm$\\|makefile" "cat %s | sed 's/\r$//'") - ("\\.pas$" "cat %s | sed 's/\r$//'") - ("\\.[1-9]$" "groff -mandoc -Tascii %s | sed s/\b.//g") - ("\\.\\(jpe?g\\|gif\\|tiff?\\|p[pgb]m\\|xwd\\|xbm\\|pcx\\)$" "xv") - ("\\.tga$" "tgatoppm %s | xv -") - ("\\.\\(wav\\|aiff\\|hcom\\|u[blw]\\|s[bfw]\\|voc\\|smp\\)$" - "sox -v .5 %s -t .au -u - > /dev/audio") - ("\\.au$" "cat %s > /dev/audio") - ("\\.midi?$" "playmidi -f") - ("\\.mod$" "str32") - ("\\.ps$" "ghostview") - ("\\.dvi$" "xdvi") - ("\\.html$" "xmosaic") - ("\\.mpe?g$" "mpeg_play") - ("\\.\\(flc\\|fli\\|rle\\|iff\\|pfx\\|avi\\|sme\\|rpza\\|dl\\|qt\\|rsrc\\|mov\\)$" "xanim") - ("\\.\\(tar\\|arj\\|zip\\|zoo\\|arc\\|gz\\|Z\\|lzh\\|ar\\|lha\\)$" - "gnus-uu-archive")) - "*Default actions to be taken when the user asks to view a file. -To change the behaviour, you can either edit this variable or set -`gnus-uu-user-view-rules' to something useful. - -For example: - -To make gnus-uu use 'xli' to display JPEG and GIF files, put the -following in your .emacs file: - - (setq gnus-uu-user-view-rules '((\"jpg$\\\\|gif$\" \"xli\"))) - -Both these variables are lists of lists with two string elements. The -first string is a regular expression. If the file name matches this -regular expression, the command in the second string is executed with -the file as an argument. - -If the command string contains \"%s\", the file name will be inserted -at that point in the command string. If there's no \"%s\" in the -command string, the file name will be appended to the command string -before executing. - -There are several user variables to tailor the behaviour of gnus-uu to -your needs. First we have `gnus-uu-user-view-rules', which is the -variable gnus-uu first consults when trying to decide how to view a -file. If this variable contains no matches, gnus-uu examines the -default rule variable provided in this package. If gnus-uu finds no -match here, it uses `gnus-uu-user-view-rules-end' to try to make a -match." - :group 'gnus-extract-view - :type '(repeat (group regexp (string :tag "Command")))) - -(defcustom gnus-uu-user-view-rules nil - "What actions are to be taken to view a file. -See the documentation on the `gnus-uu-default-view-rules' variable for -details." - :group 'gnus-extract-view - :type '(repeat (group regexp (string :tag "Command")))) - -(defcustom gnus-uu-user-view-rules-end - '(("" "file")) - "*What actions are to be taken if no rule matched the file name. -See the documentation on the `gnus-uu-default-view-rules' variable for -details." - :group 'gnus-extract-view - :type '(repeat (group regexp (string :tag "Command")))) - -;; Default unpacking commands - -(defcustom gnus-uu-default-archive-rules - '(("\\.tar$" "tar xf") - ("\\.zip$" "unzip -o") - ("\\.ar$" "ar x") - ("\\.arj$" "unarj x") - ("\\.zoo$" "zoo -e") - ("\\.\\(lzh\\|lha\\)$" "lha x") - ("\\.Z$" "uncompress") - ("\\.gz$" "gunzip") - ("\\.arc$" "arc -x")) - "*See `gnus-uu-user-archive-rules'." - :group 'gnus-extract-archive - :type '(repeat (group regexp (string :tag "Command")))) - -(defvar gnus-uu-destructive-archivers - (list "uncompress" "gunzip")) - -(defcustom gnus-uu-user-archive-rules nil - "A list that can be set to override the default archive unpacking commands. -To use, for instance, 'untar' to unpack tar files and 'zip -x' to -unpack zip files, say the following: - (setq gnus-uu-user-archive-rules - '((\"\\\\.tar$\" \"untar\") - (\"\\\\.zip$\" \"zip -x\")))" - :group 'gnus-extract-archive - :type '(repeat (group regexp (string :tag "Command")))) - -(defcustom gnus-uu-ignore-files-by-name nil - "*A regular expression saying what files should not be viewed based on name. -If, for instance, you want gnus-uu to ignore all .au and .wav files, -you could say something like - - (setq gnus-uu-ignore-files-by-name \"\\\\.au$\\\\|\\\\.wav$\") - -Note that this variable can be used in conjunction with the -`gnus-uu-ignore-files-by-type' variable." - :group 'gnus-extract - :type '(choice (const :tag "off" nil) - (regexp :format "%v"))) - -(defcustom gnus-uu-ignore-files-by-type nil - "*A regular expression saying what files that shouldn't be viewed, based on MIME file type. -If, for instance, you want gnus-uu to ignore all audio files and all mpegs, -you could say something like - - (setq gnus-uu-ignore-files-by-type \"audio/\\\\|video/mpeg\") - -Note that this variable can be used in conjunction with the -`gnus-uu-ignore-files-by-name' variable." - :group 'gnus-extract - :type '(choice (const :tag "off" nil) - (regexp :format "%v"))) - -;; Pseudo-MIME support - -(defconst gnus-uu-ext-to-mime-list - '(("\\.gif$" "image/gif") - ("\\.jpe?g$" "image/jpeg") - ("\\.tiff?$" "image/tiff") - ("\\.xwd$" "image/xwd") - ("\\.pbm$" "image/pbm") - ("\\.pgm$" "image/pgm") - ("\\.ppm$" "image/ppm") - ("\\.xbm$" "image/xbm") - ("\\.pcx$" "image/pcx") - ("\\.tga$" "image/tga") - ("\\.ps$" "image/postscript") - ("\\.fli$" "video/fli") - ("\\.wav$" "audio/wav") - ("\\.aiff$" "audio/aiff") - ("\\.hcom$" "audio/hcom") - ("\\.voc$" "audio/voc") - ("\\.smp$" "audio/smp") - ("\\.mod$" "audio/mod") - ("\\.dvi$" "image/dvi") - ("\\.mpe?g$" "video/mpeg") - ("\\.au$" "audio/basic") - ("\\.\\(te?xt\\|doc\\|c\\|h\\)$" "text/plain") - ("\\.\\(c\\|h\\)$" "text/source") - ("read.*me" "text/plain") - ("\\.html$" "text/html") - ("\\.bat$" "text/bat") - ("\\.[1-6]$" "text/man") - ("\\.flc$" "video/flc") - ("\\.rle$" "video/rle") - ("\\.pfx$" "video/pfx") - ("\\.avi$" "video/avi") - ("\\.sme$" "video/sme") - ("\\.rpza$" "video/prza") - ("\\.dl$" "video/dl") - ("\\.qt$" "video/qt") - ("\\.rsrc$" "video/rsrc") - ("\\..*$" "unknown/unknown"))) - -;; Various variables users may set - -(defcustom gnus-uu-tmp-dir "/tmp/" - "*Variable saying where gnus-uu is to do its work. -Default is \"/tmp/\"." - :group 'gnus-extract - :type 'directory) - -(defcustom gnus-uu-do-not-unpack-archives nil - "*Non-nil means that gnus-uu won't peek inside archives looking for files to display. -Default is nil." - :group 'gnus-extract-archive - :type 'boolean) - -(defcustom gnus-uu-ignore-default-view-rules nil - "*Non-nil means that gnus-uu will ignore the default viewing rules. -Only the user viewing rules will be consulted. Default is nil." - :group 'gnus-extract-view - :type 'boolean) - -(defcustom gnus-uu-grabbed-file-functions nil - "Functions run on each file after successful decoding. -They will be called with the name of the file as the argument. -Likely functions you can use in this list are `gnus-uu-grab-view' -and `gnus-uu-grab-move'." - :group 'gnus-extract - :options '(gnus-uu-grab-view gnus-uu-grab-move) - :type 'hook) - -(defcustom gnus-uu-ignore-default-archive-rules nil - "*Non-nil means that gnus-uu will ignore the default archive unpacking commands. -Only the user unpacking commands will be consulted. Default is nil." - :group 'gnus-extract-archive - :type 'boolean) - -(defcustom gnus-uu-kill-carriage-return t - "*Non-nil means that gnus-uu will strip all carriage returns from articles. -Default is t." - :group 'gnus-extract - :type 'boolean) - -(defcustom gnus-uu-view-with-metamail nil - "*Non-nil means that files will be viewed with metamail. -The gnus-uu viewing functions will be ignored and gnus-uu will try -to guess at a content-type based on file name suffixes. Default -it nil." - :group 'gnus-extract - :type 'boolean) - -(defcustom gnus-uu-unmark-articles-not-decoded nil - "*Non-nil means that gnus-uu will mark articles that were unsuccessfully decoded as unread. -Default is nil." - :group 'gnus-extract - :type 'boolean) - -(defcustom gnus-uu-correct-stripped-uucode nil - "*Non-nil means that gnus-uu will *try* to fix uuencoded files that have had trailing spaces deleted. -Default is nil." - :group 'gnus-extract - :type 'boolean) - -(defcustom gnus-uu-save-in-digest nil - "*Non-nil means that gnus-uu, when asked to save without decoding, will save in digests. -If this variable is nil, gnus-uu will just save everything in a -file without any embellishments. The digesting almost conforms to RFC1153 - -no easy way to specify any meaningful volume and issue numbers were found, -so I simply dropped them." - :group 'gnus-extract - :type 'boolean) - -(defcustom gnus-uu-pre-uudecode-hook nil - "Hook run before sending a message to uudecode." - :group 'gnus-extract - :type 'hook) - -(defcustom gnus-uu-digest-headers - '("^Date:" "^From:" "^To:" "^Cc:" "^Subject:" "^Message-ID:" "^Keywords:" - "^Summary:" "^References:" "^Content-Type:" "^Content-Transfer-Encoding:") - "*List of regexps to match headers included in digested messages. -The headers will be included in the sequence they are matched." - :group 'gnus-extract - :type '(repeat regexp)) - -(defcustom gnus-uu-save-separate-articles nil - "*Non-nil means that gnus-uu will save articles in separate files." - :group 'gnus-extract - :type 'boolean) - -(defcustom gnus-uu-be-dangerous 'ask - "*Specifies what to do if unusual situations arise during decoding. -If nil, be as conservative as possible. If t, ignore things that -didn't work, and overwrite existing files. Otherwise, ask each time." - :group 'gnus-extract - :type '(choice (const :tag "conservative" nil) - (const :tag "ask" ask) - (const :tag "liberal" t))) - -;; Internal variables - -(defvar gnus-uu-saved-article-name nil) - -(defvar gnus-uu-begin-string "^begin[ \t]+[0-7][0-7][0-7][ \t]+\\(.*\\)$") -(defvar gnus-uu-end-string "^end[ \t]*$") - -(defvar gnus-uu-body-line "^M") -(let ((i 61)) - (while (> (setq i (1- i)) 0) - (setq gnus-uu-body-line (concat gnus-uu-body-line "[^a-z]"))) - (setq gnus-uu-body-line (concat gnus-uu-body-line ".?$"))) - -;"^M.............................................................?$" - -(defvar gnus-uu-shar-begin-string "^#! */bin/sh") - -(defvar gnus-uu-shar-file-name nil) -(defvar gnus-uu-shar-name-marker "begin [0-7][0-7][0-7][ \t]+\\(\\(\\w\\|\\.\\)*\\b\\)") - -(defvar gnus-uu-postscript-begin-string "^%!PS-") -(defvar gnus-uu-postscript-end-string "^%%EOF$") - -(defvar gnus-uu-file-name nil) -(defvar gnus-uu-uudecode-process nil) -(defvar gnus-uu-binhex-article-name nil) - -(defvar gnus-uu-work-dir nil) - -(defvar gnus-uu-output-buffer-name " *Gnus UU Output*") - -(defvar gnus-uu-default-dir gnus-article-save-directory) -(defvar gnus-uu-digest-from-subject nil) - -;; Keymaps - -(gnus-define-keys (gnus-uu-mark-map "P" gnus-summary-mark-map) - "p" gnus-summary-mark-as-processable - "u" gnus-summary-unmark-as-processable - "U" gnus-summary-unmark-all-processable - "v" gnus-uu-mark-over - "s" gnus-uu-mark-series - "r" gnus-uu-mark-region - "g" gnus-uu-unmark-region - "R" gnus-uu-mark-by-regexp - "G" gnus-uu-unmark-by-regexp - "t" gnus-uu-mark-thread - "T" gnus-uu-unmark-thread - "a" gnus-uu-mark-all - "b" gnus-uu-mark-buffer - "S" gnus-uu-mark-sparse - "k" gnus-summary-kill-process-mark - "y" gnus-summary-yank-process-mark - "w" gnus-summary-save-process-mark - "i" gnus-uu-invert-processable) - -(gnus-define-keys (gnus-uu-extract-map "X" gnus-summary-mode-map) - ;;"x" gnus-uu-extract-any - ;;"m" gnus-uu-extract-mime - "u" gnus-uu-decode-uu - "U" gnus-uu-decode-uu-and-save - "s" gnus-uu-decode-unshar - "S" gnus-uu-decode-unshar-and-save - "o" gnus-uu-decode-save - "O" gnus-uu-decode-save - "b" gnus-uu-decode-binhex - "B" gnus-uu-decode-binhex - "p" gnus-uu-decode-postscript - "P" gnus-uu-decode-postscript-and-save) - -(gnus-define-keys - (gnus-uu-extract-view-map "v" gnus-uu-extract-map) - "u" gnus-uu-decode-uu-view - "U" gnus-uu-decode-uu-and-save-view - "s" gnus-uu-decode-unshar-view - "S" gnus-uu-decode-unshar-and-save-view - "o" gnus-uu-decode-save-view - "O" gnus-uu-decode-save-view - "b" gnus-uu-decode-binhex-view - "B" gnus-uu-decode-binhex-view - "p" gnus-uu-decode-postscript-view - "P" gnus-uu-decode-postscript-and-save-view) - - -;; Commands. - -(defun gnus-uu-decode-uu (&optional n) - "Uudecodes the current article." - (interactive "P") - (gnus-uu-decode-with-method 'gnus-uu-uustrip-article n)) - -(defun gnus-uu-decode-uu-and-save (n dir) - "Decodes and saves the resulting file." - (interactive - (list current-prefix-arg - (file-name-as-directory - (read-file-name "Uudecode and save in dir: " - gnus-uu-default-dir - gnus-uu-default-dir t)))) - (gnus-uu-decode-with-method 'gnus-uu-uustrip-article n dir nil nil t)) - -(defun gnus-uu-decode-unshar (&optional n) - "Unshars the current article." - (interactive "P") - (gnus-uu-decode-with-method 'gnus-uu-unshar-article n nil nil 'scan t)) - -(defun gnus-uu-decode-unshar-and-save (n dir) - "Unshars and saves the current article." - (interactive - (list current-prefix-arg - (file-name-as-directory - (read-file-name "Unshar and save in dir: " - gnus-uu-default-dir - gnus-uu-default-dir t)))) - (gnus-uu-decode-with-method 'gnus-uu-unshar-article n dir nil 'scan t)) - -(defun gnus-uu-decode-save (n file) - "Saves the current article." - (interactive - (list current-prefix-arg - (read-file-name - (if gnus-uu-save-separate-articles - "Save articles is dir: " - "Save articles in file: ") - gnus-uu-default-dir - gnus-uu-default-dir))) - (setq gnus-uu-saved-article-name file) - (gnus-uu-decode-with-method 'gnus-uu-save-article n nil t)) - -(defun gnus-uu-decode-binhex (n dir) - "Unbinhexes the current article." - (interactive - (list current-prefix-arg - (file-name-as-directory - (read-file-name "Unbinhex and save in dir: " - gnus-uu-default-dir - gnus-uu-default-dir)))) - (setq gnus-uu-binhex-article-name - (make-temp-name (concat gnus-uu-work-dir "binhex"))) - (gnus-uu-decode-with-method 'gnus-uu-binhex-article n dir)) - -(defun gnus-uu-decode-uu-view (&optional n) - "Uudecodes and views the current article." - (interactive "P") - (let ((gnus-view-pseudos (or gnus-view-pseudos 'automatic))) - (gnus-uu-decode-uu n))) - -(defun gnus-uu-decode-uu-and-save-view (n dir) - "Decodes, views and saves the resulting file." - (interactive - (list current-prefix-arg - (read-file-name "Uudecode, view and save in dir: " - gnus-uu-default-dir - gnus-uu-default-dir t))) - (let ((gnus-view-pseudos (or gnus-view-pseudos 'automatic))) - (gnus-uu-decode-uu-and-save n dir))) - -(defun gnus-uu-decode-unshar-view (&optional n) - "Unshars and views the current article." - (interactive "P") - (let ((gnus-view-pseudos (or gnus-view-pseudos 'automatic))) - (gnus-uu-decode-unshar n))) - -(defun gnus-uu-decode-unshar-and-save-view (n dir) - "Unshars and saves the current article." - (interactive - (list current-prefix-arg - (read-file-name "Unshar, view and save in dir: " - gnus-uu-default-dir - gnus-uu-default-dir t))) - (let ((gnus-view-pseudos (or gnus-view-pseudos 'automatic))) - (gnus-uu-decode-unshar-and-save n dir))) - -(defun gnus-uu-decode-save-view (n file) - "Saves and views the current article." - (interactive - (list current-prefix-arg - (read-file-name (if gnus-uu-save-separate-articles - "Save articles is dir: " - "Save articles in file: ") - gnus-uu-default-dir gnus-uu-default-dir))) - (let ((gnus-view-pseudos (or gnus-view-pseudos 'automatic))) - (gnus-uu-decode-save n file))) - -(defun gnus-uu-decode-binhex-view (n file) - "Unbinhexes and views the current article." - (interactive - (list current-prefix-arg - (read-file-name "Unbinhex, view and save in dir: " - gnus-uu-default-dir gnus-uu-default-dir))) - (setq gnus-uu-binhex-article-name - (make-temp-name (concat gnus-uu-work-dir "binhex"))) - (let ((gnus-view-pseudos (or gnus-view-pseudos 'automatic))) - (gnus-uu-decode-binhex n file))) - - -;; Digest and forward articles - -(defun gnus-uu-digest-mail-forward (&optional n post) - "Digests and forwards all articles in this series." - (interactive "P") - (let ((gnus-uu-save-in-digest t) - (file (make-temp-name (nnheader-concat gnus-uu-tmp-dir "forward"))) - buf subject from) - (gnus-setup-message 'forward - (setq gnus-uu-digest-from-subject nil) - (gnus-uu-decode-save n file) - (setq buf (switch-to-buffer - (gnus-get-buffer-create " *gnus-uu-forward*"))) - (erase-buffer) - (insert-file file) - (let ((fs gnus-uu-digest-from-subject)) - (when fs - (setq from (caar fs) - subject (gnus-simplify-subject-fuzzy (cdar fs)) - fs (cdr fs)) - (while (and fs (or from subject)) - (when from - (unless (string= from (caar fs)) - (setq from nil))) - (when subject - (unless (string= (gnus-simplify-subject-fuzzy (cdar fs)) - subject) - (setq subject nil))) - (setq fs (cdr fs)))) - (unless subject - (setq subject "Digested Articles")) - (unless from - (setq from - (if (gnus-news-group-p gnus-newsgroup-name) - gnus-newsgroup-name - "Various")))) - (goto-char (point-min)) - (when (re-search-forward "^Subject: ") - (delete-region (point) (gnus-point-at-eol)) - (insert subject)) - (goto-char (point-min)) - (when (re-search-forward "^From: ") - (delete-region (point) (gnus-point-at-eol)) - (insert from)) - (message-forward post)) - (delete-file file) - (kill-buffer buf) - (setq gnus-uu-digest-from-subject nil))) - -(defun gnus-uu-digest-post-forward (&optional n) - "Digest and forward to a newsgroup." - (interactive "P") - (gnus-uu-digest-mail-forward n t)) - -;; Process marking. - -(defun gnus-uu-mark-by-regexp (regexp &optional unmark) - "Ask for a regular expression and set the process mark on all articles that match." - (interactive (list (read-from-minibuffer "Mark (regexp): "))) - (let ((articles (gnus-uu-find-articles-matching regexp))) - (while articles - (if unmark - (gnus-summary-remove-process-mark (pop articles)) - (gnus-summary-set-process-mark (pop articles)))) - (message "")) - (gnus-summary-position-point)) - -(defun gnus-uu-unmark-by-regexp (regexp &optional unmark) - "Ask for a regular expression and remove the process mark on all articles that match." - (interactive (list (read-from-minibuffer "Mark (regexp): "))) - (gnus-uu-mark-by-regexp regexp t)) - -(defun gnus-uu-mark-series () - "Mark the current series with the process mark." - (interactive) - (let ((articles (gnus-uu-find-articles-matching))) - (while articles - (gnus-summary-set-process-mark (car articles)) - (setq articles (cdr articles))) - (message "")) - (gnus-summary-position-point)) - -(defun gnus-uu-mark-region (beg end &optional unmark) - "Set the process mark on all articles between point and mark." - (interactive "r") - (save-excursion - (goto-char beg) - (while (< (point) end) - (if unmark - (gnus-summary-remove-process-mark (gnus-summary-article-number)) - (gnus-summary-set-process-mark (gnus-summary-article-number))) - (forward-line 1))) - (gnus-summary-position-point)) - -(defun gnus-uu-unmark-region (beg end) - "Remove the process mark from all articles between point and mark." - (interactive "r") - (gnus-uu-mark-region beg end t)) - -(defun gnus-uu-mark-buffer () - "Set the process mark on all articles in the buffer." - (interactive) - (gnus-uu-mark-region (point-min) (point-max))) - -(defun gnus-uu-unmark-buffer () - "Remove the process mark on all articles in the buffer." - (interactive) - (gnus-uu-mark-region (point-min) (point-max) t)) - -(defun gnus-uu-mark-thread () - "Marks all articles downwards in this thread." - (interactive) - (let ((level (gnus-summary-thread-level))) - (while (and (gnus-summary-set-process-mark (gnus-summary-article-number)) - (zerop (gnus-summary-next-subject 1)) - (> (gnus-summary-thread-level) level)))) - (gnus-summary-position-point)) - -(defun gnus-uu-unmark-thread () - "Unmarks all articles downwards in this thread." - (interactive) - (let ((level (gnus-summary-thread-level))) - (while (and (gnus-summary-remove-process-mark - (gnus-summary-article-number)) - (zerop (gnus-summary-next-subject 1)) - (> (gnus-summary-thread-level) level)))) - (gnus-summary-position-point)) - -(defun gnus-uu-invert-processable () - "Invert the list of process-marked articles." - (interactive) - (let ((data gnus-newsgroup-data) - number) - (save-excursion - (while data - (if (memq (setq number (gnus-data-number (pop data))) - gnus-newsgroup-processable) - (gnus-summary-remove-process-mark number) - (gnus-summary-set-process-mark number))))) - (gnus-summary-position-point)) - -(defun gnus-uu-mark-over (&optional score) - "Mark all articles with a score over SCORE (the prefix)." - (interactive "P") - (let ((score (gnus-score-default score)) - (data gnus-newsgroup-data)) - (save-excursion - (while data - (when (> (or (cdr (assq (gnus-data-number (car data)) - gnus-newsgroup-scored)) - gnus-summary-default-score 0) - score) - (gnus-summary-set-process-mark (caar data))) - (setq data (cdr data)))) - (gnus-summary-position-point))) - -(defun gnus-uu-mark-sparse () - "Mark all series that have some articles marked." - (interactive) - (let ((marked (nreverse gnus-newsgroup-processable)) - subject articles total headers) - (unless marked - (error "No articles marked with the process mark")) - (setq gnus-newsgroup-processable nil) - (save-excursion - (while marked - (and (vectorp (setq headers - (gnus-summary-article-header (car marked)))) - (setq subject (mail-header-subject headers) - articles (gnus-uu-find-articles-matching - (gnus-uu-reginize-string subject)) - total (nconc total articles))) - (while articles - (gnus-summary-set-process-mark (car articles)) - (setcdr marked (delq (car articles) (cdr marked))) - (setq articles (cdr articles))) - (setq marked (cdr marked))) - (setq gnus-newsgroup-processable (nreverse total))) - (gnus-summary-position-point))) - -(defun gnus-uu-mark-all () - "Mark all articles in \"series\" order." - (interactive) - (setq gnus-newsgroup-processable nil) - (save-excursion - (let ((data gnus-newsgroup-data) - number) - (while data - (when (and (not (memq (setq number (gnus-data-number (car data))) - gnus-newsgroup-processable)) - (vectorp (gnus-data-header (car data)))) - (gnus-summary-goto-subject number) - (gnus-uu-mark-series)) - (setq data (cdr data))))) - (gnus-summary-position-point)) - -;; All PostScript functions written by Erik Selberg . - -(defun gnus-uu-decode-postscript (&optional n) - "Gets postscript of the current article." - (interactive "P") - (gnus-uu-decode-with-method 'gnus-uu-decode-postscript-article n)) - -(defun gnus-uu-decode-postscript-view (&optional n) - "Gets and views the current article." - (interactive "P") - (let ((gnus-view-pseudos (or gnus-view-pseudos 'automatic))) - (gnus-uu-decode-postscript n))) - -(defun gnus-uu-decode-postscript-and-save (n dir) - "Extracts postscript and saves the current article." - (interactive - (list current-prefix-arg - (file-name-as-directory - (read-file-name "Save in dir: " - gnus-uu-default-dir - gnus-uu-default-dir t)))) - (gnus-uu-decode-with-method 'gnus-uu-decode-postscript-article - n dir nil nil t)) - -(defun gnus-uu-decode-postscript-and-save-view (n dir) - "Decodes, views and saves the resulting file." - (interactive - (list current-prefix-arg - (read-file-name "Where do you want to save the file(s)? " - gnus-uu-default-dir - gnus-uu-default-dir t))) - (let ((gnus-view-pseudos (or gnus-view-pseudos 'automatic))) - (gnus-uu-decode-postscript-and-save n dir))) - - -;; Internal functions. - -(defun gnus-uu-decode-with-method (method n &optional save not-insert - scan cdir) - (gnus-uu-initialize scan) - (when save - (setq gnus-uu-default-dir save)) - ;; Create the directory we save to. - (when (and scan cdir save - (not (file-exists-p save))) - (make-directory save t)) - (let ((articles (gnus-uu-get-list-of-articles n)) - files) - (setq files (gnus-uu-grab-articles articles method t)) - (let ((gnus-current-article (car articles))) - (when scan - (setq files (gnus-uu-scan-directory gnus-uu-work-dir)))) - (when save - (gnus-uu-save-files files save)) - (when (eq gnus-uu-do-not-unpack-archives nil) - (setq files (gnus-uu-unpack-files files))) - (setq files (nreverse (gnus-uu-get-actions files))) - (or not-insert (not gnus-insert-pseudo-articles) - (gnus-summary-insert-pseudos files save)))) - -(defun gnus-uu-scan-directory (dir &optional rec) - "Return a list of all files under DIR." - (let ((files (directory-files dir t)) - out file) - (while (setq file (pop files)) - (unless (member (file-name-nondirectory file) '("." "..")) - (push (list (cons 'name file) - (cons 'article gnus-current-article)) - out) - (when (file-directory-p file) - (setq out (nconc (gnus-uu-scan-directory file t) out))))) - (if rec - out - (nreverse out)))) - -(defun gnus-uu-save-files (files dir) - "Save FILES in DIR." - (let ((len (length files)) - (reg (concat "^" (regexp-quote gnus-uu-work-dir))) - to-file file fromdir) - (while (setq file (cdr (assq 'name (pop files)))) - (when (file-exists-p file) - (string-match reg file) - (setq fromdir (substring file (match-end 0))) - (if (file-directory-p file) - (gnus-make-directory (concat dir fromdir)) - (setq to-file (concat dir fromdir)) - (when (or (not (file-exists-p to-file)) - (eq gnus-uu-be-dangerous t) - (and gnus-uu-be-dangerous - (gnus-y-or-n-p (format "%s exists; overwrite? " - to-file)))) - (copy-file file to-file t t))))) - (gnus-message 5 "Saved %d file%s" len (if (= len 1) "" "s")))) - -;; Functions for saving and possibly digesting articles without -;; any decoding. - -;; Function called by gnus-uu-grab-articles to treat each article. -(defun gnus-uu-save-article (buffer in-state) - (cond - (gnus-uu-save-separate-articles - (save-excursion - (set-buffer buffer) - (gnus-write-buffer - (concat gnus-uu-saved-article-name gnus-current-article)) - (cond ((eq in-state 'first) (list gnus-uu-saved-article-name 'begin)) - ((eq in-state 'first-and-last) (list gnus-uu-saved-article-name - 'begin 'end)) - ((eq in-state 'last) (list 'end)) - (t (list 'middle))))) - ((not gnus-uu-save-in-digest) - (save-excursion - (set-buffer buffer) - (write-region (point-min) (point-max) gnus-uu-saved-article-name t) - (cond ((eq in-state 'first) (list gnus-uu-saved-article-name 'begin)) - ((eq in-state 'first-and-last) (list gnus-uu-saved-article-name - 'begin 'end)) - ((eq in-state 'last) (list 'end)) - (t (list 'middle))))) - (t - (let ((header (gnus-summary-article-header))) - (push (cons (mail-header-from header) - (mail-header-subject header)) - gnus-uu-digest-from-subject)) - (let ((name (file-name-nondirectory gnus-uu-saved-article-name)) - beg subj headers headline sorthead body end-string state) - (if (or (eq in-state 'first) - (eq in-state 'first-and-last)) - (progn - (setq state (list 'begin)) - (save-excursion (set-buffer (gnus-get-buffer-create "*gnus-uu-body*")) - (erase-buffer)) - (save-excursion - (set-buffer (gnus-get-buffer-create "*gnus-uu-pre*")) - (erase-buffer) - (insert (format - "Date: %s\nFrom: %s\nSubject: %s Digest\n\nTopics:\n" - (current-time-string) name name)))) - (when (not (eq in-state 'end)) - (setq state (list 'middle)))) - (save-excursion - (set-buffer "*gnus-uu-body*") - (goto-char (setq beg (point-max))) - (save-excursion - (save-restriction - (set-buffer buffer) - (let (buffer-read-only) - (gnus-set-text-properties (point-min) (point-max) nil) - ;; These two are necessary for XEmacs 19.12 fascism. - (put-text-property (point-min) (point-max) 'invisible nil) - (put-text-property (point-min) (point-max) 'intangible nil)) - (goto-char (point-min)) - (re-search-forward "\n\n") - ;; Quote all 30-dash lines. - (save-excursion - (while (re-search-forward "^-" nil t) - (beginning-of-line) - (delete-char 1) - (insert "- "))) - (setq body (buffer-substring (1- (point)) (point-max))) - (narrow-to-region (point-min) (point)) - (if (not (setq headers gnus-uu-digest-headers)) - (setq sorthead (buffer-substring (point-min) (point-max))) - (while headers - (setq headline (car headers)) - (setq headers (cdr headers)) - (goto-char (point-min)) - (while (re-search-forward headline nil t) - (setq sorthead - (concat sorthead - (buffer-substring - (match-beginning 0) - (or (and (re-search-forward "^[^ \t]" nil t) - (1- (point))) - (progn (forward-line 1) (point))))))))) - (widen))) - (insert sorthead) (goto-char (point-max)) - (insert body) (goto-char (point-max)) - (insert (concat "\n" (make-string 30 ?-) "\n\n")) - (goto-char beg) - (when (re-search-forward "^Subject: \\(.*\\)$" nil t) - (setq subj (buffer-substring (match-beginning 1) (match-end 1))) - (save-excursion - (set-buffer "*gnus-uu-pre*") - (insert (format " %s\n" subj))))) - (when (or (eq in-state 'last) - (eq in-state 'first-and-last)) - (save-excursion - (set-buffer "*gnus-uu-pre*") - (insert (format "\n\n%s\n\n" (make-string 70 ?-))) - (gnus-write-buffer gnus-uu-saved-article-name)) - (save-excursion - (set-buffer "*gnus-uu-body*") - (goto-char (point-max)) - (insert - (concat (setq end-string (format "End of %s Digest" name)) - "\n")) - (insert (concat (make-string (length end-string) ?*) "\n")) - (write-region - (point-min) (point-max) gnus-uu-saved-article-name t)) - (gnus-kill-buffer "*gnus-uu-pre*") - (gnus-kill-buffer "*gnus-uu-body*") - (push 'end state)) - (if (memq 'begin state) - (cons gnus-uu-saved-article-name state) - state))))) - -;; Binhex treatment - not very advanced. - -(defvar gnus-uu-binhex-body-line - "^[^:]...............................................................$") -(defvar gnus-uu-binhex-begin-line - "^:...............................................................$") -(defvar gnus-uu-binhex-end-line - ":$") - -(defun gnus-uu-binhex-article (buffer in-state) - (let (state start-char) - (save-excursion - (set-buffer buffer) - (widen) - (goto-char (point-min)) - (when (not (re-search-forward gnus-uu-binhex-begin-line nil t)) - (when (not (re-search-forward gnus-uu-binhex-body-line nil t)) - (setq state (list 'wrong-type)))) - - (if (memq 'wrong-type state) - () - (beginning-of-line) - (setq start-char (point)) - (if (looking-at gnus-uu-binhex-begin-line) - (progn - (setq state (list 'begin)) - (write-region 1 1 gnus-uu-binhex-article-name)) - (setq state (list 'middle))) - (goto-char (point-max)) - (re-search-backward (concat gnus-uu-binhex-body-line "\\|" - gnus-uu-binhex-end-line) - nil t) - (when (looking-at gnus-uu-binhex-end-line) - (setq state (if (memq 'begin state) - (cons 'end state) - (list 'end)))) - (beginning-of-line) - (forward-line 1) - (when (file-exists-p gnus-uu-binhex-article-name) - (append-to-file start-char (point) gnus-uu-binhex-article-name)))) - (if (memq 'begin state) - (cons gnus-uu-binhex-article-name state) - state))) - -;; PostScript - -(defun gnus-uu-decode-postscript-article (process-buffer in-state) - (let ((state (list 'ok)) - start-char end-char file-name) - (save-excursion - (set-buffer process-buffer) - (goto-char (point-min)) - (if (not (re-search-forward gnus-uu-postscript-begin-string nil t)) - (setq state (list 'wrong-type)) - (beginning-of-line) - (setq start-char (point)) - (if (not (re-search-forward gnus-uu-postscript-end-string nil t)) - (setq state (list 'wrong-type)) - (setq end-char (point)) - (set-buffer (gnus-get-buffer-create gnus-uu-output-buffer-name)) - (insert-buffer-substring process-buffer start-char end-char) - (setq file-name (concat gnus-uu-work-dir - (cdr gnus-article-current) ".ps")) - (write-region (point-min) (point-max) file-name) - (setq state (list file-name 'begin 'end))))) - state)) - - -;; Find actions. - -(defun gnus-uu-get-actions (files) - (let ((ofiles files) - action name) - (while files - (setq name (cdr (assq 'name (car files)))) - (and - (setq action (gnus-uu-get-action name)) - (setcar files (nconc (list (if (string= action "gnus-uu-archive") - (cons 'action "file") - (cons 'action action)) - (cons 'execute (gnus-uu-command - action name))) - (car files)))) - (setq files (cdr files))) - ofiles)) - -(defun gnus-uu-get-action (file-name) - (let (action) - (setq action - (gnus-uu-choose-action - file-name - (append - gnus-uu-user-view-rules - (if gnus-uu-ignore-default-view-rules - nil - gnus-uu-default-view-rules) - gnus-uu-user-view-rules-end))) - (when (and (not (string= (or action "") "gnus-uu-archive")) - gnus-uu-view-with-metamail) - (when (setq action - (gnus-uu-choose-action file-name gnus-uu-ext-to-mime-list)) - (setq action (format "metamail -d -b -c \"%s\"" action)))) - action)) - - -;; Functions for treating subjects and collecting series. - -(defun gnus-uu-reginize-string (string) - ;; Takes a string and puts a \ in front of every special character; - ;; replaces the last thing that looks like "2/3" with "[0-9]+/3" - ;; or, if it can't find something like that, tries "2 of 3", then - ;; finally just replaces the next to last number with "[0-9]+". - (save-excursion - (set-buffer (gnus-get-buffer-create gnus-uu-output-buffer-name)) - (buffer-disable-undo (current-buffer)) - (erase-buffer) - (insert (regexp-quote string)) - - (setq case-fold-search nil) - - (end-of-line) - (if (re-search-backward "\\([^0-9]\\)[0-9]+/\\([0-9]+\\)" nil t) - (replace-match "\\1[0-9]+/\\2") - - (end-of-line) - (if (re-search-backward "\\([^0-9]\\)[0-9]+[ \t]*of[ \t]*\\([0-9]+\\)" - nil t) - (replace-match "\\1[0-9]+ of \\2") - - (end-of-line) - (if (re-search-backward "\\([^0-9]\\)[0-9]+\\([^0-9]+\\)[0-9]+" - nil t) - (replace-match "\\1[0-9]+\\2[0-9]+" t nil nil nil)))) - - (goto-char 1) - (while (re-search-forward "[ \t]+" nil t) - (replace-match "[ \t]+" t t)) - - (buffer-substring 1 (point-max)))) - -(defun gnus-uu-get-list-of-articles (n) - ;; If N is non-nil, the article numbers of the N next articles - ;; will be returned. - ;; If any articles have been marked as processable, they will be - ;; returned. - ;; Failing that, articles that have subjects that are part of the - ;; same "series" as the current will be returned. - (let (articles) - (cond - (n - (setq n (prefix-numeric-value n)) - (let ((backward (< n 0)) - (n (abs n))) - (save-excursion - (while (and (> n 0) - (push (gnus-summary-article-number) - articles) - (gnus-summary-search-forward nil nil backward)) - (setq n (1- n)))) - (nreverse articles))) - (gnus-newsgroup-processable - (reverse gnus-newsgroup-processable)) - (t - (gnus-uu-find-articles-matching))))) - -(defun gnus-uu-string< (l1 l2) - (string< (car l1) (car l2))) - -(defun gnus-uu-find-articles-matching - (&optional subject only-unread do-not-translate) - ;; Finds all articles that matches the regexp SUBJECT. If it is - ;; nil, the current article name will be used. If ONLY-UNREAD is - ;; non-nil, only unread articles are chosen. If DO-NOT-TRANSLATE is - ;; non-nil, article names are not equalized before sorting. - (let ((subject (or subject - (gnus-uu-reginize-string (gnus-summary-article-subject)))) - list-of-subjects) - (save-excursion - (when subject - ;; Collect all subjects matching subject. - (let ((case-fold-search t) - (data gnus-newsgroup-data) - subj mark d) - (while data - (setq d (pop data)) - (and (not (gnus-data-pseudo-p d)) - (or (not only-unread) - (= (setq mark (gnus-data-mark d)) - gnus-unread-mark) - (= mark gnus-ticked-mark) - (= mark gnus-dormant-mark)) - (setq subj (mail-header-subject (gnus-data-header d))) - (string-match subject subj) - (push (cons subj (gnus-data-number d)) - list-of-subjects)))) - - ;; Expand numbers, sort, and return the list of article - ;; numbers. - (mapcar (lambda (sub) (cdr sub)) - (sort (gnus-uu-expand-numbers - list-of-subjects - (not do-not-translate)) - 'gnus-uu-string<)))))) - -(defun gnus-uu-expand-numbers (string-list &optional translate) - ;; Takes a list of strings and "expands" all numbers in all the - ;; strings. That is, this function makes all numbers equal length by - ;; prepending lots of zeroes before each number. This is to ease later - ;; sorting to find out what sequence the articles are supposed to be - ;; decoded in. Returns the list of expanded strings. - (let ((out-list string-list) - string) - (save-excursion - (set-buffer (gnus-get-buffer-create gnus-uu-output-buffer-name)) - (buffer-disable-undo (current-buffer)) - (while string-list - (erase-buffer) - (insert (caar string-list)) - ;; Translate multiple spaces to one space. - (goto-char (point-min)) - (while (re-search-forward "[ \t]+" nil t) - (replace-match " ")) - ;; Translate all characters to "a". - (goto-char (point-min)) - (when translate - (while (re-search-forward "[A-Za-z]" nil t) - (replace-match "a" t t))) - ;; Expand numbers. - (goto-char (point-min)) - (while (re-search-forward "[0-9]+" nil t) - (replace-match - (format "%06d" - (string-to-int (buffer-substring - (match-beginning 0) (match-end 0)))))) - (setq string (buffer-substring 1 (point-max))) - (setcar (car string-list) string) - (setq string-list (cdr string-list)))) - out-list)) - - -;; `gnus-uu-grab-articles' is the general multi-article treatment -;; function. It takes a list of articles to be grabbed and a function -;; to apply to each article. -;; -;; The function to be called should take two parameters. The first -;; parameter is the article buffer. The function should leave the -;; result, if any, in this buffer. Most treatment functions will just -;; generate files... -;; -;; The second parameter is the state of the list of articles, and can -;; have four values: `first', `middle', `last' and `first-and-last'. -;; -;; The function should return a list. The list may contain the -;; following symbols: -;; `error' if an error occurred -;; `begin' if the beginning of an encoded file has been received -;; If the list returned contains a `begin', the first element of -;; the list *must* be a string with the file name of the decoded -;; file. -;; `end' if the end of an encoded file has been received -;; `middle' if the article was a body part of an encoded file -;; `wrong-type' if the article was not a part of an encoded file -;; `ok', which can be used everything is ok - -(defvar gnus-uu-has-been-grabbed nil) - -(defun gnus-uu-unmark-list-of-grabbed (&optional dont-unmark-last-article) - (let (art) - (if (not (and gnus-uu-has-been-grabbed - gnus-uu-unmark-articles-not-decoded)) - () - (when dont-unmark-last-article - (setq art (car gnus-uu-has-been-grabbed)) - (setq gnus-uu-has-been-grabbed (cdr gnus-uu-has-been-grabbed))) - (while gnus-uu-has-been-grabbed - (gnus-summary-tick-article (car gnus-uu-has-been-grabbed) t) - (setq gnus-uu-has-been-grabbed (cdr gnus-uu-has-been-grabbed))) - (when dont-unmark-last-article - (setq gnus-uu-has-been-grabbed (list art)))))) - -;; This function takes a list of articles and a function to apply to -;; each article grabbed. -;; -;; This function returns a list of files decoded if the grabbing and -;; the process-function has been successful and nil otherwise. -(defun gnus-uu-grab-articles (articles process-function - &optional sloppy limit no-errors) - (let ((state 'first) - (gnus-asynchronous nil) - has-been-begin article result-file result-files process-state - gnus-summary-display-article-function - gnus-article-display-hook gnus-article-prepare-hook - article-series files) - - (while (and articles - (not (memq 'error process-state)) - (or sloppy - (not (memq 'end process-state)))) - - (setq article (pop articles)) - (when (vectorp (gnus-summary-article-header article)) - (push article article-series) - - (unless articles - (if (eq state 'first) - (setq state 'first-and-last) - (setq state 'last))) - - (let ((part (gnus-uu-part-number article))) - (gnus-message 6 "Getting article %d%s..." - article (if (string= part "") "" (concat ", " part)))) - (gnus-summary-display-article article) - - ;; Push the article to the processing function. - (save-excursion - (set-buffer gnus-original-article-buffer) - (let ((buffer-read-only nil)) - (save-excursion - (set-buffer gnus-summary-buffer) - (setq process-state - (funcall process-function - gnus-original-article-buffer state))))) - - (gnus-summary-remove-process-mark article) - - ;; If this is the beginning of a decoded file, we push it - ;; on to a list. - (when (or (memq 'begin process-state) - (and (or (eq state 'first) - (eq state 'first-and-last)) - (memq 'ok process-state))) - (when has-been-begin - ;; If there is a `result-file' here, that means that the - ;; file was unsuccessfully decoded, so we delete it. - (when (and result-file - (file-exists-p result-file) - (not gnus-uu-be-dangerous) - (or (eq gnus-uu-be-dangerous t) - (gnus-y-or-n-p - (format "Delete unsuccessfully decoded file %s" - result-file)))) - (delete-file result-file))) - (when (memq 'begin process-state) - (setq result-file (car process-state))) - (setq has-been-begin t)) - - ;; Check whether we have decoded one complete file. - (when (memq 'end process-state) - (setq article-series nil) - (setq has-been-begin nil) - (if (stringp result-file) - (setq files (list result-file)) - (setq files result-file)) - (setq result-file (car files)) - (while files - (push (list (cons 'name (pop files)) - (cons 'article article)) - result-files)) - ;; Allow user-defined functions to be run on this file. - (when gnus-uu-grabbed-file-functions - (let ((funcs gnus-uu-grabbed-file-functions)) - (unless (listp funcs) - (setq funcs (list funcs))) - (while funcs - (funcall (pop funcs) result-file)))) - (setq result-file nil) - ;; Check whether we have decoded enough articles. - (and limit (= (length result-files) limit) - (setq articles nil))) - - ;; If this is the last article to be decoded, and - ;; we still haven't reached the end, then we delete - ;; the partially decoded file. - (and (or (eq state 'last) (eq state 'first-and-last)) - (not (memq 'end process-state)) - result-file - (file-exists-p result-file) - (not gnus-uu-be-dangerous) - (or (eq gnus-uu-be-dangerous t) - (gnus-y-or-n-p - (format "Delete incomplete file %s? " result-file))) - (delete-file result-file)) - - ;; If this was a file of the wrong sort, then - (when (and (or (memq 'wrong-type process-state) - (memq 'error process-state)) - gnus-uu-unmark-articles-not-decoded) - (gnus-summary-tick-article article t)) - - ;; Set the new series state. - (if (and (not has-been-begin) - (not sloppy) - (or (memq 'end process-state) - (memq 'middle process-state))) - (progn - (setq process-state (list 'error)) - (gnus-message 2 "No begin part at the beginning") - (sleep-for 2)) - (setq state 'middle))) - - ;; When there are no result-files, then something must be wrong. - (if result-files - (message "") - (cond - ((not has-been-begin) - (gnus-message 2 "Wrong type file")) - ((memq 'error process-state) - (gnus-message 2 "An error occurred during decoding")) - ((not (or (memq 'ok process-state) - (memq 'end process-state))) - (gnus-message 2 "End of articles reached before end of file"))) - ;; Make unsuccessfully decoded articles unread. - (when gnus-uu-unmark-articles-not-decoded - (while article-series - (gnus-summary-tick-article (pop article-series) t))))) - - result-files)) - -(defun gnus-uu-grab-view (file) - "View FILE using the gnus-uu methods." - (let ((action (gnus-uu-get-action file))) - (gnus-execute-command - (if (string-match "%" action) - (format action file) - (concat action " " file)) - (eq gnus-view-pseudos 'not-confirm)))) - -(defun gnus-uu-grab-move (file) - "Move FILE to somewhere." - (when gnus-uu-default-dir - (let ((to-file (concat (file-name-as-directory gnus-uu-default-dir) - (file-name-nondirectory file)))) - (rename-file file to-file) - (unless (file-exists-p file) - (make-symbolic-link to-file file))))) - -(defun gnus-uu-part-number (article) - (let* ((header (gnus-summary-article-header article)) - (subject (and header (mail-header-subject header))) - (part nil)) - (if subject - (while (string-match "[0-9]+/[0-9]+\\|[0-9]+[ \t]+of[ \t]+[0-9]+" - subject) - (setq part (match-string 0 subject)) - (setq subject (substring subject (match-end 0))))) - (or part - (while (string-match "\\([0-9]+\\)[^0-9]+\\([0-9]+\\)" subject) - (setq part (match-string 0 subject)) - (setq subject (substring subject (match-end 0))))) - (or part ""))) - -(defun gnus-uu-uudecode-sentinel (process event) - (delete-process (get-process process))) - -(defun gnus-uu-uustrip-article (process-buffer in-state) - ;; Uudecodes a file asynchronously. - (save-excursion - (set-buffer process-buffer) - (let ((state (list 'wrong-type)) - process-connection-type case-fold-search buffer-read-only - files start-char) - (goto-char (point-min)) - - ;; Deal with ^M at the end of the lines. - (when gnus-uu-kill-carriage-return - (save-excursion - (while (search-forward "\r" nil t) - (delete-backward-char 1)))) - - (while (or (re-search-forward gnus-uu-begin-string nil t) - (re-search-forward gnus-uu-body-line nil t)) - (setq state (list 'ok)) - ;; Ok, we are at the first uucoded line. - (beginning-of-line) - (setq start-char (point)) - - (if (not (looking-at gnus-uu-begin-string)) - (setq state (list 'middle)) - ;; This is the beginning of a uuencoded article. - ;; We replace certain characters that could make things messy. - (setq gnus-uu-file-name - (let ((nnheader-file-name-translation-alist - '((?/ . ?,) (? . ?_) (?* . ?_) (?$ . ?_)))) - (nnheader-translate-file-chars (match-string 1)))) - (replace-match (concat "begin 644 " gnus-uu-file-name) t t) - - ;; Remove any non gnus-uu-body-line right after start. - (forward-line 1) - (while (and (not (eobp)) - (not (looking-at gnus-uu-body-line))) - (gnus-delete-line)) - - ;; If a process is running, we kill it. - (when (and gnus-uu-uudecode-process - (memq (process-status gnus-uu-uudecode-process) - '(run stop))) - (delete-process gnus-uu-uudecode-process) - (gnus-uu-unmark-list-of-grabbed t)) - - ;; Start a new uudecoding process. - (let ((cdir default-directory)) - (unwind-protect - (progn - (cd gnus-uu-work-dir) - (setq gnus-uu-uudecode-process - (start-process - "*uudecode*" - (gnus-get-buffer-create gnus-uu-output-buffer-name) - shell-file-name shell-command-switch - (format "cd %s %s uudecode" gnus-uu-work-dir - gnus-shell-command-separator)))) - (cd cdir))) - (set-process-sentinel - gnus-uu-uudecode-process 'gnus-uu-uudecode-sentinel) - (setq state (list 'begin)) - (push (concat gnus-uu-work-dir gnus-uu-file-name) files)) - - ;; We look for the end of the thing to be decoded. - (if (re-search-forward gnus-uu-end-string nil t) - (push 'end state) - (goto-char (point-max)) - (re-search-backward gnus-uu-body-line nil t)) - - (forward-line 1) - - (when gnus-uu-uudecode-process - (when (memq (process-status gnus-uu-uudecode-process) '(run stop)) - ;; Try to correct mishandled uucode. - (when gnus-uu-correct-stripped-uucode - (gnus-uu-check-correct-stripped-uucode start-char (point))) - (gnus-run-hooks 'gnus-uu-pre-uudecode-hook) - - ;; Send the text to the process. - (condition-case nil - (process-send-region - gnus-uu-uudecode-process start-char (point)) - (error - (progn - (delete-process gnus-uu-uudecode-process) - (gnus-message 2 "gnus-uu: Couldn't uudecode") - (setq state (list 'wrong-type))))) - - (if (memq 'end state) - (progn - ;; Send an EOF, just in case. - (ignore-errors - (process-send-eof gnus-uu-uudecode-process)) - (while (memq (process-status gnus-uu-uudecode-process) - '(open run)) - (accept-process-output gnus-uu-uudecode-process 1))) - (when (or (not gnus-uu-uudecode-process) - (not (memq (process-status gnus-uu-uudecode-process) - '(run stop)))) - (setq state (list 'wrong-type))))))) - - (if (memq 'begin state) - (cons (if (= (length files) 1) (car files) files) state) - state)))) - -;; This function is used by `gnus-uu-grab-articles' to treat -;; a shared article. -(defun gnus-uu-unshar-article (process-buffer in-state) - (let ((state (list 'ok)) - start-char) - (save-excursion - (set-buffer process-buffer) - (goto-char (point-min)) - (if (not (re-search-forward gnus-uu-shar-begin-string nil t)) - (setq state (list 'wrong-type)) - (beginning-of-line) - (setq start-char (point)) - (call-process-region - start-char (point-max) shell-file-name nil - (gnus-get-buffer-create gnus-uu-output-buffer-name) nil - shell-command-switch - (concat "cd " gnus-uu-work-dir " " - gnus-shell-command-separator " sh")))) - state)) - -;; Returns the name of what the shar file is going to unpack. -(defun gnus-uu-find-name-in-shar () - (let ((oldpoint (point)) - res) - (goto-char (point-min)) - (when (re-search-forward gnus-uu-shar-name-marker nil t) - (setq res (buffer-substring (match-beginning 1) (match-end 1)))) - (goto-char oldpoint) - res)) - -;; `gnus-uu-choose-action' chooses what action to perform given the name -;; and `gnus-uu-file-action-list'. Returns either nil if no action is -;; found, or the name of the command to run if such a rule is found. -(defun gnus-uu-choose-action (file-name file-action-list &optional no-ignore) - (let ((action-list (copy-sequence file-action-list)) - (case-fold-search t) - rule action) - (and - (unless no-ignore - (and (not - (and gnus-uu-ignore-files-by-name - (string-match gnus-uu-ignore-files-by-name file-name))) - (not - (and gnus-uu-ignore-files-by-type - (string-match gnus-uu-ignore-files-by-type - (or (gnus-uu-choose-action - file-name gnus-uu-ext-to-mime-list t) - "")))))) - (while (not (or (eq action-list ()) action)) - (setq rule (car action-list)) - (setq action-list (cdr action-list)) - (when (string-match (car rule) file-name) - (setq action (cadr rule))))) - action)) - -(defun gnus-uu-treat-archive (file-path) - ;; Unpacks an archive. Returns t if unpacking is successful. - (let ((did-unpack t) - action command dir) - (setq action (gnus-uu-choose-action - file-path (append gnus-uu-user-archive-rules - (if gnus-uu-ignore-default-archive-rules - nil - gnus-uu-default-archive-rules)))) - - (when (not action) - (error "No unpackers for the file %s" file-path)) - - (string-match "/[^/]*$" file-path) - (setq dir (substring file-path 0 (match-beginning 0))) - - (when (member action gnus-uu-destructive-archivers) - (copy-file file-path (concat file-path "~") t)) - - (setq command (format "cd %s ; %s" dir (gnus-uu-command action file-path))) - - (save-excursion - (set-buffer (gnus-get-buffer-create gnus-uu-output-buffer-name)) - (erase-buffer)) - - (gnus-message 5 "Unpacking: %s..." (gnus-uu-command action file-path)) - - (if (= 0 (call-process shell-file-name nil - (gnus-get-buffer-create gnus-uu-output-buffer-name) - nil shell-command-switch command)) - (message "") - (gnus-message 2 "Error during unpacking of archive") - (setq did-unpack nil)) - - (when (member action gnus-uu-destructive-archivers) - (rename-file (concat file-path "~") file-path t)) - - did-unpack)) - -(defun gnus-uu-dir-files (dir) - (let ((dirs (directory-files dir t "[^/][^\\.][^\\.]?$")) - files file) - (while dirs - (if (file-directory-p (setq file (car dirs))) - (setq files (append files (gnus-uu-dir-files file))) - (push file files)) - (setq dirs (cdr dirs))) - files)) - -(defun gnus-uu-unpack-files (files &optional ignore) - ;; Go through FILES and look for files to unpack. - (let* ((totfiles (gnus-uu-ls-r gnus-uu-work-dir)) - (ofiles files) - file did-unpack) - (while files - (setq file (cdr (assq 'name (car files)))) - (when (and (not (member file ignore)) - (equal (gnus-uu-get-action (file-name-nondirectory file)) - "gnus-uu-archive")) - (push file did-unpack) - (unless (gnus-uu-treat-archive file) - (gnus-message 2 "Error during unpacking of %s" file)) - (let* ((newfiles (gnus-uu-ls-r gnus-uu-work-dir)) - (nfiles newfiles)) - (while nfiles - (unless (member (car nfiles) totfiles) - (push (list (cons 'name (car nfiles)) - (cons 'original file)) - ofiles)) - (setq nfiles (cdr nfiles))) - (setq totfiles newfiles))) - (setq files (cdr files))) - (if did-unpack - (gnus-uu-unpack-files ofiles (append did-unpack ignore)) - ofiles))) - -(defun gnus-uu-ls-r (dir) - (let* ((files (gnus-uu-directory-files dir t)) - (ofiles files)) - (while files - (when (file-directory-p (car files)) - (setq ofiles (delete (car files) ofiles)) - (setq ofiles (append ofiles (gnus-uu-ls-r (car files))))) - (setq files (cdr files))) - ofiles)) - -;; Various stuff - -(defun gnus-uu-directory-files (dir &optional full) - (let (files out file) - (setq files (directory-files dir full)) - (while files - (setq file (car files)) - (setq files (cdr files)) - (unless (member (file-name-nondirectory file) '("." "..")) - (push file out))) - (setq out (nreverse out)) - out)) - -(defun gnus-uu-check-correct-stripped-uucode (start end) - (save-excursion - (let (found beg length) - (if (not gnus-uu-correct-stripped-uucode) - () - (goto-char start) - - (if (re-search-forward " \\|`" end t) - (progn - (goto-char start) - (while (not (eobp)) - (progn - (when (looking-at "\n") - (replace-match "")) - (forward-line 1)))) - - (while (not (eobp)) - (if (looking-at (concat gnus-uu-begin-string "\\|" - gnus-uu-end-string)) - () - (when (not found) - (beginning-of-line) - (setq beg (point)) - (end-of-line) - (setq length (- (point) beg))) - (setq found t) - (beginning-of-line) - (setq beg (point)) - (end-of-line) - (when (not (= length (- (point) beg))) - (insert (make-string (- length (- (point) beg)) ? )))) - (forward-line 1))))))) - -(defvar gnus-uu-tmp-alist nil) - -(defun gnus-uu-initialize (&optional scan) - (let (entry) - (if (and (not scan) - (when (setq entry (assoc gnus-newsgroup-name gnus-uu-tmp-alist)) - (if (file-exists-p (cdr entry)) - (setq gnus-uu-work-dir (cdr entry)) - (setq gnus-uu-tmp-alist (delq entry gnus-uu-tmp-alist)) - nil))) - t - (setq gnus-uu-tmp-dir (file-name-as-directory - (expand-file-name gnus-uu-tmp-dir))) - (if (not (file-directory-p gnus-uu-tmp-dir)) - (error "Temp directory %s doesn't exist" gnus-uu-tmp-dir) - (when (not (file-writable-p gnus-uu-tmp-dir)) - (error "Temp directory %s can't be written to" - gnus-uu-tmp-dir))) - - (setq gnus-uu-work-dir - (make-temp-name (concat gnus-uu-tmp-dir "gnus"))) - (gnus-make-directory gnus-uu-work-dir) - (set-file-modes gnus-uu-work-dir 448) - (setq gnus-uu-work-dir (file-name-as-directory gnus-uu-work-dir)) - (push (cons gnus-newsgroup-name gnus-uu-work-dir) - gnus-uu-tmp-alist)))) - - -;; Kills the temporary uu buffers, kills any processes, etc. -(defun gnus-uu-clean-up () - (let (buf) - (and gnus-uu-uudecode-process - (memq (process-status (or gnus-uu-uudecode-process "nevair")) - '(stop run)) - (delete-process gnus-uu-uudecode-process)) - (when (setq buf (get-buffer gnus-uu-output-buffer-name)) - (kill-buffer buf)))) - -(defun gnus-quote-arg-for-sh-or-csh (arg) - (let ((pos 0) new-pos accum) - ;; *** bug: we don't handle newline characters properly - (while (setq new-pos (string-match "[!`\"$\\& \t{}]" arg pos)) - (push (substring arg pos new-pos) accum) - (push "\\" accum) - (push (list (aref arg new-pos)) accum) - (setq pos (1+ new-pos))) - (if (= pos 0) - arg - (apply 'concat (nconc (nreverse accum) (list (substring arg pos))))))) - -;; Inputs an action and a filename and returns a full command, making sure -;; that the filename will be treated as a single argument when the shell -;; executes the command. -(defun gnus-uu-command (action file) - (let ((quoted-file (gnus-quote-arg-for-sh-or-csh file))) - (if (string-match "%s" action) - (format action quoted-file) - (concat action " " quoted-file)))) - -(defun gnus-uu-delete-work-dir (&optional dir) - "Delete recursively all files and directories under `gnus-uu-work-dir'." - (if dir - (gnus-message 7 "Deleting directory %s..." dir) - (setq dir gnus-uu-work-dir)) - (when (and dir - (file-exists-p dir)) - (let ((files (directory-files dir t nil t)) - file) - (while (setq file (pop files)) - (unless (member (file-name-nondirectory file) '("." "..")) - (if (file-directory-p file) - (gnus-uu-delete-work-dir file) - (gnus-message 9 "Deleting file %s..." file) - (delete-file file)))) - (delete-directory dir))) - (gnus-message 7 "")) - -;; Initializing - -(add-hook 'gnus-exit-group-hook 'gnus-uu-clean-up) -(add-hook 'gnus-exit-group-hook 'gnus-uu-delete-work-dir) - - - -;;; -;;; uuencoded posting -;;; - -;; Any function that is to be used as and encoding method will take two -;; parameters: PATH-NAME and FILE-NAME. (E.g. "/home/gaga/spiral.jpg" -;; and "spiral.jpg", respectively.) The function should return nil if -;; the encoding wasn't successful. -(defcustom gnus-uu-post-encode-method 'gnus-uu-post-encode-uuencode - "Function used for encoding binary files. -There are three functions supplied with gnus-uu for encoding files: -`gnus-uu-post-encode-uuencode', which does straight uuencoding; -`gnus-uu-post-encode-mime', which encodes with base64 and adds MIME -headers; and `gnus-uu-post-encode-mime-uuencode', which encodes with -uuencode and adds MIME headers." - :group 'gnus-extract-post - :type '(radio (function-item gnus-uu-post-encode-uuencode) - (function-item gnus-uu-post-encode-mime) - (function-item gnus-uu-post-encode-mime-uuencode) - (function :tag "Other"))) - -(defcustom gnus-uu-post-include-before-composing nil - "Non-nil means that gnus-uu will ask for a file to encode before you compose the article. -If this variable is t, you can either include an encoded file with -\\[gnus-uu-post-insert-binary-in-article] or have one included for you when you post the article." - :group 'gnus-extract-post - :type 'boolean) - -(defcustom gnus-uu-post-length 990 - "Maximum length of an article. -The encoded file will be split into how many articles it takes to -post the entire file." - :group 'gnus-extract-post - :type 'integer) - -(defcustom gnus-uu-post-threaded nil - "Non-nil means that gnus-uu will post the encoded file in a thread. -This may not be smart, as no other decoder I have seen are able to -follow threads when collecting uuencoded articles. (Well, I have seen -one package that does that - gnus-uu, but somehow, I don't think that -counts...) The default is nil." - :group 'gnus-extract-post - :type 'boolean) - -(defcustom gnus-uu-post-separate-description t - "Non-nil means that the description will be posted in a separate article. -The first article will typically be numbered (0/x). If this variable -is nil, the description the user enters will be included at the -beginning of the first article, which will be numbered (1/x). Default -is t." - :group 'gnus-extract-post - :type 'boolean) - -(defvar gnus-uu-post-binary-separator "--binary follows this line--") -(defvar gnus-uu-post-message-id nil) -(defvar gnus-uu-post-inserted-file-name nil) -(defvar gnus-uu-winconf-post-news nil) - -(defun gnus-uu-post-news () - "Compose an article and post an encoded file." - (interactive) - (setq gnus-uu-post-inserted-file-name nil) - (setq gnus-uu-winconf-post-news (current-window-configuration)) - - (gnus-summary-post-news) - - (use-local-map (copy-keymap (current-local-map))) - (local-set-key "\C-c\C-c" 'gnus-summary-edit-article-done) - (local-set-key "\C-c\C-c" 'gnus-uu-post-news-inews) - (local-set-key "\C-c\C-s" 'gnus-uu-post-news-inews) - (local-set-key "\C-c\C-i" 'gnus-uu-post-insert-binary-in-article) - - (when gnus-uu-post-include-before-composing - (save-excursion (setq gnus-uu-post-inserted-file-name - (gnus-uu-post-insert-binary))))) - -(defun gnus-uu-post-insert-binary-in-article () - "Inserts an encoded file in the buffer. -The user will be asked for a file name." - (interactive) - (save-excursion - (setq gnus-uu-post-inserted-file-name (gnus-uu-post-insert-binary)))) - -;; Encodes with uuencode and substitutes all spaces with backticks. -(defun gnus-uu-post-encode-uuencode (path file-name) - (when (gnus-uu-post-encode-file "uuencode" path file-name) - (goto-char (point-min)) - (forward-line 1) - (while (re-search-forward " " nil t) - (replace-match "`")) - t)) - -;; Encodes with uuencode and adds MIME headers. -(defun gnus-uu-post-encode-mime-uuencode (path file-name) - (when (gnus-uu-post-encode-uuencode path file-name) - (gnus-uu-post-make-mime file-name "x-uue") - t)) - -;; Encodes with base64 and adds MIME headers -(defun gnus-uu-post-encode-mime (path file-name) - (when (zerop (call-process shell-file-name nil t nil shell-command-switch - (format "%s %s -o %s" "mmencode" path file-name))) - (gnus-uu-post-make-mime file-name "base64") - t)) - -;; Adds MIME headers. -(defun gnus-uu-post-make-mime (file-name encoding) - (goto-char (point-min)) - (insert (format "Content-Type: %s; name=\"%s\"\n" - (gnus-uu-choose-action file-name gnus-uu-ext-to-mime-list) - file-name)) - (insert (format "Content-Transfer-Encoding: %s\n\n" encoding)) - (save-restriction - (set-buffer gnus-message-buffer) - (goto-char (point-min)) - (re-search-forward (concat "^" (regexp-quote mail-header-separator) "$")) - (forward-line -1) - (narrow-to-region 1 (point)) - (unless (mail-fetch-field "mime-version") - (widen) - (insert "MIME-Version: 1.0\n")) - (widen))) - -;; Encodes a file PATH with COMMAND, leaving the result in the -;; current buffer. -(defun gnus-uu-post-encode-file (command path file-name) - (= 0 (call-process shell-file-name nil t nil shell-command-switch - (format "%s %s %s" command path file-name)))) - -(defun gnus-uu-post-news-inews () - "Posts the composed news article and encoded file. -If no file has been included, the user will be asked for a file." - (interactive) - - (let (file-name) - - (if gnus-uu-post-inserted-file-name - (setq file-name gnus-uu-post-inserted-file-name) - (setq file-name (gnus-uu-post-insert-binary))) - - (gnus-uu-post-encoded file-name gnus-uu-post-threaded)) - (setq gnus-uu-post-inserted-file-name nil) - (when gnus-uu-winconf-post-news - (set-window-configuration gnus-uu-winconf-post-news))) - -;; Asks for a file to encode, encodes it and inserts the result in -;; the current buffer. Returns the file name the user gave. -(defun gnus-uu-post-insert-binary () - (let ((uuencode-buffer-name "*uuencode buffer*") - file-path uubuf file-name) - - (setq file-path (read-file-name - "What file do you want to encode? ")) - (when (not (file-exists-p file-path)) - (error "%s: No such file" file-path)) - - (goto-char (point-max)) - (insert (format "\n%s\n" gnus-uu-post-binary-separator)) - - ;; #### Unix-specific? - (when (string-match "^~/" file-path) - (setq file-path (concat "$HOME" (substring file-path 1)))) - ;; #### Unix-specific? - (if (string-match "/[^/]*$" file-path) - (setq file-name (substring file-path (1+ (match-beginning 0)))) - (setq file-name file-path)) - - (unwind-protect - (if (save-excursion - (set-buffer (setq uubuf - (gnus-get-buffer-create uuencode-buffer-name))) - (erase-buffer) - (funcall gnus-uu-post-encode-method file-path file-name)) - (insert-buffer-substring uubuf) - (error "Encoding unsuccessful")) - (kill-buffer uubuf)) - file-name)) - -;; Posts the article and all of the encoded file. -(defun gnus-uu-post-encoded (file-name &optional threaded) - (let ((send-buffer-name "*uuencode send buffer*") - (encoded-buffer-name "*encoded buffer*") - (top-string "[ cut here %s (%s %d/%d) %s gnus-uu ]") - (separator (concat mail-header-separator "\n\n")) - uubuf length parts header i end beg - beg-line minlen post-buf whole-len beg-binary end-binary) - - (setq post-buf (current-buffer)) - - (goto-char (point-min)) - (when (not (re-search-forward - (if gnus-uu-post-separate-description - (concat "^" (regexp-quote gnus-uu-post-binary-separator) - "$") - (concat "^" (regexp-quote mail-header-separator) "$")) - nil t)) - (error "Internal error: No binary/header separator")) - (beginning-of-line) - (forward-line 1) - (setq beg-binary (point)) - (setq end-binary (point-max)) - - (save-excursion - (set-buffer (setq uubuf (gnus-get-buffer-create encoded-buffer-name))) - (erase-buffer) - (insert-buffer-substring post-buf beg-binary end-binary) - (goto-char (point-min)) - (setq length (count-lines 1 (point-max))) - (setq parts (/ length gnus-uu-post-length)) - (unless (< (% length gnus-uu-post-length) 4) - (incf parts))) - - (when gnus-uu-post-separate-description - (forward-line -1)) - (delete-region (point) (point-max)) - - (goto-char (point-min)) - (re-search-forward - (concat "^" (regexp-quote mail-header-separator) "$") nil t) - (beginning-of-line) - (setq header (buffer-substring 1 (point))) - - (goto-char (point-min)) - (when gnus-uu-post-separate-description - (when (re-search-forward "^Subject: " nil t) - (end-of-line) - (insert (format " (0/%d)" parts))) - (save-excursion - (message-send)) - (setq gnus-uu-post-message-id (message-fetch-field "message-id"))) - - (save-excursion - (setq i 1) - (setq beg 1) - (while (not (> i parts)) - (set-buffer (gnus-get-buffer-create send-buffer-name)) - (erase-buffer) - (insert header) - (when (and threaded gnus-uu-post-message-id) - (insert "References: " gnus-uu-post-message-id "\n")) - (insert separator) - (setq whole-len - (- 62 (length (format top-string "" file-name i parts "")))) - (when (> 1 (setq minlen (/ whole-len 2))) - (setq minlen 1)) - (setq - beg-line - (format top-string - (make-string minlen ?-) - file-name i parts - (make-string - (if (= 0 (% whole-len 2)) (1- minlen) minlen) ?-))) - - (goto-char (point-min)) - (when (re-search-forward "^Subject: " nil t) - (end-of-line) - (insert (format " (%d/%d)" i parts))) - - (goto-char (point-max)) - (save-excursion - (set-buffer uubuf) - (goto-char beg) - (if (= i parts) - (goto-char (point-max)) - (forward-line gnus-uu-post-length)) - (when (and (= (1+ i) parts) (< (count-lines (point) (point-max)) 4)) - (forward-line -4)) - (setq end (point))) - (insert-buffer-substring uubuf beg end) - (insert beg-line "\n") - (setq beg end) - (incf i) - (goto-char (point-min)) - (re-search-forward - (concat "^" (regexp-quote mail-header-separator) "$") nil t) - (beginning-of-line) - (forward-line 2) - (when (re-search-forward - (concat "^" (regexp-quote gnus-uu-post-binary-separator) "$") - nil t) - (replace-match "") - (forward-line 1)) - (insert beg-line) - (insert "\n") - (let (message-sent-message-via) - (save-excursion - (message-send)) - (setq gnus-uu-post-message-id - (concat (message-fetch-field "references") " " - (message-fetch-field "message-id")))))) - - (gnus-kill-buffer send-buffer-name) - (gnus-kill-buffer encoded-buffer-name) - - (when (not gnus-uu-post-separate-description) - (set-buffer-modified-p nil) - (when (fboundp 'bury-buffer) - (bury-buffer))))) - -(provide 'gnus-uu) - -;; gnus-uu.el ends here diff --git a/lisp/gnus-vm.el b/lisp/gnus-vm.el deleted file mode 100644 index bbefaac..0000000 --- a/lisp/gnus-vm.el +++ /dev/null @@ -1,105 +0,0 @@ -;;; gnus-vm.el --- vm interface for Gnus -;; Copyright (C) 1994,95,96,97,98 Free Software Foundation, Inc. - -;; Author: Per Persson -;; Keywords: news, mail - -;; This file is part of GNU Emacs. - -;; GNU Emacs is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 2, or (at your option) -;; any later version. - -;; GNU Emacs is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs; see the file COPYING. If not, write to the -;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. - -;;; Commentary: - -;; Major contributors: -;; Christian Limpach -;; Some code stolen from: -;; Rick Sladkey - -;;; Code: - -(require 'sendmail) -(require 'message) -(require 'gnus) -(require 'gnus-msg) - -(eval-when-compile - (autoload 'vm-mode "vm") - (autoload 'vm-save-message "vm") - (autoload 'vm-forward-message "vm") - (autoload 'vm-reply "vm") - (autoload 'vm-mail "vm")) - -(defvar gnus-vm-inhibit-window-system nil - "Inhibit loading `win-vm' if using a window-system. -Has to be set before gnus-vm is loaded.") - -(or gnus-vm-inhibit-window-system - (condition-case nil - (when window-system - (require 'win-vm)) - (error nil))) - -(when (not (featurep 'vm)) - (load "vm")) - -(defun gnus-vm-make-folder (&optional buffer) - (let ((article (or buffer (current-buffer))) - (tmp-folder (generate-new-buffer " *tmp-folder*")) - (start (point-min)) - (end (point-max))) - (set-buffer tmp-folder) - (insert-buffer-substring article start end) - (goto-char (point-min)) - (if (looking-at "^\\(From [^ ]+ \\).*$") - (replace-match (concat "\\1" (current-time-string))) - (insert "From " gnus-newsgroup-name " " - (current-time-string) "\n")) - (while (re-search-forward "\n\nFrom " nil t) - (replace-match "\n\n>From ")) - ;; insert a newline, otherwise the last line gets lost - (goto-char (point-max)) - (insert "\n") - (vm-mode) - tmp-folder)) - -(defun gnus-summary-save-article-vm (&optional arg) - "Append the current article to a vm folder. -If N is a positive number, save the N next articles. -If N is a negative number, save the N previous articles. -If N is nil and any articles have been marked with the process mark, -save those articles instead." - (interactive "P") - (let ((gnus-default-article-saver 'gnus-summary-save-in-vm)) - (gnus-summary-save-article arg))) - -(defun gnus-summary-save-in-vm (&optional folder) - (interactive) - (setq folder - (gnus-read-save-file-name - "Save %s in VM folder:" folder - gnus-mail-save-name gnus-newsgroup-name - gnus-current-headers 'gnus-newsgroup-last-mail)) - (gnus-eval-in-buffer-window gnus-original-article-buffer - (save-excursion - (save-restriction - (widen) - (let ((vm-folder (gnus-vm-make-folder))) - (vm-save-message folder) - (kill-buffer vm-folder)))))) - -(provide 'gnus-vm) - -;;; gnus-vm.el ends here. diff --git a/lisp/gnus-win.el b/lisp/gnus-win.el deleted file mode 100644 index c41fbae..0000000 --- a/lisp/gnus-win.el +++ /dev/null @@ -1,539 +0,0 @@ -;;; gnus-win.el --- window configuration functions for Gnus -;; Copyright (C) 1996,97,98 Free Software Foundation, Inc. - -;; Author: Lars Magne Ingebrigtsen -;; Keywords: news - -;; This file is part of GNU Emacs. - -;; GNU Emacs is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 2, or (at your option) -;; any later version. - -;; GNU Emacs is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs; see the file COPYING. If not, write to the -;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. - -;;; Commentary: - -;;; Code: - -(eval-when-compile (require 'cl)) - -(require 'gnus) - -(defgroup gnus-windows nil - "Window configuration." - :group 'gnus) - -(defcustom gnus-use-full-window t - "*If non-nil, use the entire Emacs screen." - :group 'gnus-windows - :type 'boolean) - -(defvar gnus-window-configuration nil - "Obsolete variable. See `gnus-buffer-configuration'.") - -(defcustom gnus-window-min-width 2 - "*Minimum width of Gnus buffers." - :group 'gnus-windows - :type 'integer) - -(defcustom gnus-window-min-height 1 - "*Minimum height of Gnus buffers." - :group 'gnus-windows - :type 'integer) - -(defcustom gnus-always-force-window-configuration nil - "*If non-nil, always force the Gnus window configurations." - :group 'gnus-windows - :type 'boolean) - -(defvar gnus-buffer-configuration - '((group - (vertical 1.0 - (group 1.0 point) - (if gnus-carpal '(group-carpal 4)))) - (summary - (vertical 1.0 - (summary 1.0 point) - (if gnus-carpal '(summary-carpal 4)))) - (article - (cond - ((and gnus-use-picons - (eq gnus-picons-display-where 'picons)) - '(frame 1.0 - (vertical 1.0 - (summary 0.25 point) - (if gnus-carpal '(summary-carpal 4)) - (article 1.0)) - (vertical ((height . 5) (width . 15) - (user-position . t) - (left . -1) (top . 1)) - (picons 1.0)))) - (gnus-use-trees - '(vertical 1.0 - (summary 0.25 point) - (tree 0.25) - (article 1.0))) - (t - '(vertical 1.0 - (summary 0.25 point) - (if gnus-carpal '(summary-carpal 4)) - (article 1.0))))) - (server - (vertical 1.0 - (server 1.0 point) - (if gnus-carpal '(server-carpal 2)))) - (browse - (vertical 1.0 - (browse 1.0 point) - (if gnus-carpal '(browse-carpal 2)))) - (message - (vertical 1.0 - (message 1.0 point))) - (pick - (vertical 1.0 - (article 1.0 point))) - (info - (vertical 1.0 - (info 1.0 point))) - (summary-faq - (vertical 1.0 - (summary 0.25) - (faq 1.0 point))) - (edit-article - (vertical 1.0 - (article 1.0 point))) - (edit-form - (vertical 1.0 - (group 0.5) - (edit-form 1.0 point))) - (edit-score - (vertical 1.0 - (summary 0.25) - (edit-score 1.0 point))) - (post - (vertical 1.0 - (post 1.0 point))) - (reply - (vertical 1.0 - (article-copy 0.5) - (message 1.0 point))) - (forward - (vertical 1.0 - (message 1.0 point))) - (reply-yank - (vertical 1.0 - (message 1.0 point))) - (mail-bounce - (vertical 1.0 - (article 0.5) - (message 1.0 point))) - (pipe - (vertical 1.0 - (summary 0.25 point) - (if gnus-carpal '(summary-carpal 4)) - ("*Shell Command Output*" 1.0))) - (bug - (vertical 1.0 - ("*Gnus Help Bug*" 0.5) - ("*Gnus Bug*" 1.0 point))) - (score-trace - (vertical 1.0 - (summary 0.5 point) - ("*Score Trace*" 1.0))) - (score-words - (vertical 1.0 - (summary 0.5 point) - ("*Score Words*" 1.0))) - (split-trace - (vertical 1.0 - (summary 0.5 point) - ("*Split Trace*" 1.0))) - (category - (vertical 1.0 - (category 1.0))) - (compose-bounce - (vertical 1.0 - (article 0.5) - (message 1.0 point)))) - "Window configuration for all possible Gnus buffers. -See the Gnus manual for an explanation of the syntax used.") - -(defvar gnus-window-to-buffer - '((group . gnus-group-buffer) - (summary . gnus-summary-buffer) - (article . gnus-article-buffer) - (server . gnus-server-buffer) - (browse . "*Gnus Browse Server*") - (edit-group . gnus-group-edit-buffer) - (edit-form . gnus-edit-form-buffer) - (edit-server . gnus-server-edit-buffer) - (group-carpal . gnus-carpal-group-buffer) - (summary-carpal . gnus-carpal-summary-buffer) - (server-carpal . gnus-carpal-server-buffer) - (browse-carpal . gnus-carpal-browse-buffer) - (edit-score . gnus-score-edit-buffer) - (message . gnus-message-buffer) - (mail . gnus-message-buffer) - (post-news . gnus-message-buffer) - (faq . gnus-faq-buffer) - (picons . gnus-picons-buffer-name) - (tree . gnus-tree-buffer) - (score-trace . "*Score Trace*") - (split-trace . "*Split Trace*") - (info . gnus-info-buffer) - (category . gnus-category-buffer) - (article-copy . gnus-article-copy) - (draft . gnus-draft-buffer)) - "Mapping from short symbols to buffer names or buffer variables.") - -;;; Internal variables. - -(defvar gnus-current-window-configuration nil - "The most recently set window configuration.") - -(defvar gnus-created-frames nil) -(defvar gnus-window-frame-focus nil) - -(defun gnus-kill-gnus-frames () - "Kill all frames Gnus has created." - (while gnus-created-frames - (when (frame-live-p (car gnus-created-frames)) - ;; We slap a condition-case around this `delete-frame' to ensure - ;; against errors if we try do delete the single frame that's left. - (ignore-errors - (delete-frame (car gnus-created-frames)))) - (pop gnus-created-frames))) - -(defun gnus-window-configuration-element (list) - (while (and list - (not (assq (car list) gnus-window-configuration))) - (pop list)) - (cadr (assq (car list) gnus-window-configuration))) - -(defun gnus-windows-old-to-new (setting) - ;; First we take care of the really, really old Gnus 3 actions. - (when (symbolp setting) - (setq setting - ;; Take care of ooold GNUS 3.x values. - (cond ((eq setting 'SelectArticle) 'article) - ((memq setting '(SelectNewsgroup SelectSubject ExpandSubject)) - 'summary) - ((memq setting '(ExitNewsgroup)) 'group) - (t setting)))) - (if (or (listp setting) - (not (and gnus-window-configuration - (memq setting '(group summary article))))) - setting - (let* ((elem - (cond - ((eq setting 'group) - (gnus-window-configuration-element - '(group newsgroups ExitNewsgroup))) - ((eq setting 'summary) - (gnus-window-configuration-element - '(summary SelectNewsgroup SelectSubject ExpandSubject))) - ((eq setting 'article) - (gnus-window-configuration-element - '(article SelectArticle))))) - (total (apply '+ elem)) - (types '(group summary article)) - (pbuf (if (eq setting 'newsgroups) 'group 'summary)) - (i 0) - perc out) - (while (< i 3) - (or (not (numberp (nth i elem))) - (zerop (nth i elem)) - (progn - (setq perc (if (= i 2) - 1.0 - (/ (float (nth i elem)) total))) - (push (if (eq pbuf (nth i types)) - (list (nth i types) perc 'point) - (list (nth i types) perc)) - out))) - (incf i)) - `(vertical 1.0 ,@(nreverse out))))) - -;;;###autoload -(defun gnus-add-configuration (conf) - "Add the window configuration CONF to `gnus-buffer-configuration'." - (setq gnus-buffer-configuration - (cons conf (delq (assq (car conf) gnus-buffer-configuration) - gnus-buffer-configuration)))) - -(defvar gnus-frame-list nil) - -(defun gnus-window-to-buffer-helper (obj) - (cond ((not (symbolp obj)) - obj) - ((boundp obj) - (symbol-value obj)) - ((fboundp obj) - (funcall obj)) - (t - nil))) - -(defun gnus-configure-frame (split &optional window) - "Split WINDOW according to SPLIT." - (unless window - (setq window (get-buffer-window (current-buffer)))) - (select-window window) - ;; This might be an old-stylee buffer config. - (when (vectorp split) - (setq split (append split nil))) - (when (or (consp (car split)) - (vectorp (car split))) - (push 1.0 split) - (push 'vertical split)) - ;; The SPLIT might be something that is to be evaled to - ;; return a new SPLIT. - (while (and (not (assq (car split) gnus-window-to-buffer)) - (gnus-functionp (car split))) - (setq split (eval split))) - (let* ((type (car split)) - (subs (cddr split)) - (len (if (eq type 'horizontal) (window-width) (window-height))) - (total 0) - (window-min-width (or gnus-window-min-width window-min-width)) - (window-min-height (or gnus-window-min-height window-min-height)) - s result new-win rest comp-subs size sub) - (cond - ;; Nothing to do here. - ((null split)) - ;; Don't switch buffers. - ((null type) - (and (memq 'point split) window)) - ;; This is a buffer to be selected. - ((not (memq type '(frame horizontal vertical))) - (let ((buffer (cond ((stringp type) type) - (t (cdr (assq type gnus-window-to-buffer)))))) - (unless buffer - (error "Illegal buffer type: %s" type)) - (switch-to-buffer (gnus-get-buffer-create - (gnus-window-to-buffer-helper buffer))) - (when (memq 'frame-focus split) - (setq gnus-window-frame-focus window)) - ;; We return the window if it has the `point' spec. - (and (memq 'point split) window))) - ;; This is a frame split. - ((eq type 'frame) - (unless gnus-frame-list - (setq gnus-frame-list (list (window-frame - (get-buffer-window (current-buffer)))))) - (let ((i 0) - params frame fresult) - (while (< i (length subs)) - ;; Frame parameter is gotten from the sub-split. - (setq params (cadr (elt subs i))) - ;; It should be a list. - (unless (listp params) - (setq params nil)) - ;; Create a new frame? - (unless (setq frame (elt gnus-frame-list i)) - (nconc gnus-frame-list (list (setq frame (make-frame params)))) - (push frame gnus-created-frames)) - ;; Is the old frame still alive? - (unless (frame-live-p frame) - (setcar (nthcdr i gnus-frame-list) - (setq frame (make-frame params)))) - ;; Select the frame in question and do more splits there. - (select-frame frame) - (setq fresult (or (gnus-configure-frame (elt subs i)) fresult)) - (incf i)) - ;; Select the frame that has the selected buffer. - (when fresult - (select-frame (window-frame fresult))))) - ;; This is a normal split. - (t - (when (> (length subs) 0) - ;; First we have to compute the sizes of all new windows. - (while subs - (setq sub (append (pop subs) nil)) - (while (and (not (assq (car sub) gnus-window-to-buffer)) - (gnus-functionp (car sub))) - (setq sub (eval sub))) - (when sub - (push sub comp-subs) - (setq size (cadar comp-subs)) - (cond ((equal size 1.0) - (setq rest (car comp-subs)) - (setq s 0)) - ((floatp size) - (setq s (floor (* size len)))) - ((integerp size) - (setq s size)) - (t - (error "Illegal size: %s" size))) - ;; Try to make sure that we are inside the safe limits. - (cond ((zerop s)) - ((eq type 'horizontal) - (setq s (max s window-min-width))) - ((eq type 'vertical) - (setq s (max s window-min-height)))) - (setcar (cdar comp-subs) s) - (incf total s))) - ;; Take care of the "1.0" spec. - (if rest - (setcar (cdr rest) (- len total)) - (error "No 1.0 specs in %s" split)) - ;; The we do the actual splitting in a nice recursive - ;; fashion. - (setq comp-subs (nreverse comp-subs)) - (while comp-subs - (if (null (cdr comp-subs)) - (setq new-win window) - (setq new-win - (split-window window (cadar comp-subs) - (eq type 'horizontal)))) - (setq result (or (gnus-configure-frame - (car comp-subs) window) - result)) - (select-window new-win) - (setq window new-win) - (setq comp-subs (cdr comp-subs)))) - ;; Return the proper window, if any. - (when result - (select-window result)))))) - -(defvar gnus-frame-split-p nil) - -(defun gnus-configure-windows (setting &optional force) - (setq gnus-current-window-configuration setting) - (setq force (or force gnus-always-force-window-configuration)) - (setq setting (gnus-windows-old-to-new setting)) - (let ((split (if (symbolp setting) - (cadr (assq setting gnus-buffer-configuration)) - setting)) - all-visible) - - (setq gnus-frame-split-p nil) - - (unless split - (error "No such setting: %s" setting)) - - (if (and (setq all-visible (gnus-all-windows-visible-p split)) - (not force)) - ;; All the windows mentioned are already visible, so we just - ;; put point in the assigned buffer, and do not touch the - ;; winconf. - (select-window all-visible) - - ;; Either remove all windows or just remove all Gnus windows. - (let ((frame (selected-frame))) - (unwind-protect - (if gnus-use-full-window - ;; We want to remove all other windows. - (if (not gnus-frame-split-p) - ;; This is not a `frame' split, so we ignore the - ;; other frames. - (delete-other-windows) - ;; This is a `frame' split, so we delete all windows - ;; on all frames. - (gnus-delete-windows-in-gnusey-frames)) - ;; Just remove some windows. - (gnus-remove-some-windows) - (switch-to-buffer nntp-server-buffer)) - (select-frame frame))) - - (switch-to-buffer nntp-server-buffer) - (let (gnus-window-frame-focus) - (gnus-configure-frame split (get-buffer-window (current-buffer))) - (when gnus-window-frame-focus - (select-frame (window-frame gnus-window-frame-focus))))))) - -(defun gnus-delete-windows-in-gnusey-frames () - "Do a `delete-other-windows' in all frames that have Gnus windows." - (let ((buffers (gnus-buffers))) - (mapcar - (lambda (frame) - (unless (eq (cdr (assq 'minibuffer - (frame-parameters frame))) - 'only) - (select-frame frame) - (let (do-delete) - (walk-windows - (lambda (window) - (when (memq (window-buffer window) buffers) - (setq do-delete t)))) - (when do-delete - (delete-other-windows))))) - (frame-list)))) - -(defun gnus-all-windows-visible-p (split) - "Say whether all buffers in SPLIT are currently visible. -In particular, the value returned will be the window that -should have point." - (let ((stack (list split)) - (all-visible t) - type buffer win buf) - (while (and (setq split (pop stack)) - all-visible) - ;; Be backwards compatible. - (when (vectorp split) - (setq split (append split nil))) - (when (or (consp (car split)) - (vectorp (car split))) - (push 1.0 split) - (push 'vertical split)) - ;; The SPLIT might be something that is to be evaled to - ;; return a new SPLIT. - (while (and (not (assq (car split) gnus-window-to-buffer)) - (gnus-functionp (car split))) - (setq split (eval split))) - - (setq type (elt split 0)) - (cond - ;; Nothing here. - ((null split) t) - ;; A buffer. - ((not (memq type '(horizontal vertical frame))) - (setq buffer (cond ((stringp type) type) - (t (cdr (assq type gnus-window-to-buffer))))) - (unless buffer - (error "Illegal buffer type: %s" type)) - (if (and (setq buf (get-buffer (gnus-window-to-buffer-helper buffer))) - (setq win (get-buffer-window buf t))) - (if (memq 'point split) - (setq all-visible win)) - (setq all-visible nil))) - (t - (when (eq type 'frame) - (setq gnus-frame-split-p t)) - (setq stack (append (cddr split) stack))))) - (unless (eq all-visible t) - all-visible))) - -(defun gnus-window-top-edge (&optional window) - (nth 1 (window-edges window))) - -(defun gnus-remove-some-windows () - (let ((buffers (gnus-buffers)) - buf bufs lowest-buf lowest) - (save-excursion - ;; Remove windows on all known Gnus buffers. - (while (setq buf (pop buffers)) - (when (get-buffer-window buf) - (push buf bufs) - (pop-to-buffer buf) - (when (or (not lowest) - (< (gnus-window-top-edge) lowest)) - (setq lowest (gnus-window-top-edge) - lowest-buf buf)))) - (when lowest-buf - (pop-to-buffer lowest-buf) - (switch-to-buffer nntp-server-buffer)) - (mapcar (lambda (b) (delete-windows-on b t)) bufs)))) - -(provide 'gnus-win) - -;;; gnus-win.el ends here diff --git a/lisp/gnus-xmas.el b/lisp/gnus-xmas.el deleted file mode 100644 index d8106d1..0000000 --- a/lisp/gnus-xmas.el +++ /dev/null @@ -1,935 +0,0 @@ -;;; gnus-xmas.el --- Gnus functions for XEmacs -;; Copyright (C) 1995,96,97,98 Free Software Foundation, Inc. - -;; Author: Lars Magne Ingebrigtsen -;; Keywords: news - -;; This file is part of GNU Emacs. - -;; GNU Emacs is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 2, or (at your option) -;; any later version. - -;; GNU Emacs is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs; see the file COPYING. If not, write to the -;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. - -;;; Commentary: - -;;; Code: - -(require 'text-props) -(defvar menu-bar-mode (featurep 'menubar)) -(require 'messagexmas) - -(defgroup gnus-xmas nil - "XEmacsoid support for Gnus" - :group 'gnus) - -(defcustom gnus-xmas-glyph-directory nil - "Directory where Gnus logos and icons are located. -If this variable is nil, Gnus will try to locate the directory -automatically." - :type '(choice (const :tag "autodetect" nil) - directory) - :group 'gnus-xmas) - -(defvar gnus-xmas-logo-color-alist - '((flame "#cc3300" "#ff2200") - (pine "#c0cc93" "#f8ffb8") - (moss "#a1cc93" "#d2ffb8") - (irish "#04cc90" "#05ff97") - (sky "#049acc" "#05deff") - (tin "#6886cc" "#82b6ff") - (velvet "#7c68cc" "#8c82ff") - (grape "#b264cc" "#cf7df") - (labia "#cc64c2" "#fd7dff") - (berry "#cc6485" "#ff7db5") - (neutral "#b4b4b4" "#878787") - (september "#bf9900" "#ffcc00")) - "Color alist used for the Gnus logo.") - -(defcustom gnus-xmas-logo-color-style 'moss - "*Color styles used for the Gnus logo." - :type '(choice (const flame) (const pine) (const moss) - (const irish) (const sky) (const tin) - (const velvet) (const grape) (const labia) - (const berry) (const neutral) (const september)) - :group 'gnus-xmas) - -(defvar gnus-xmas-logo-colors - (cdr (assq gnus-xmas-logo-color-style gnus-xmas-logo-color-alist)) - "Colors used for the Gnus logo.") - -(defcustom gnus-article-x-face-command - (if (or (featurep 'xface) - (featurep 'xpm)) - 'gnus-xmas-article-display-xface - "{ echo '/* Width=48, Height=48 */'; uncompface; } | icontopbm | xv -quit -") - "*String or function to be executed to display an X-Face header. -If it is a string, the command will be executed in a sub-shell -asynchronously. The compressed face will be piped to this command." - :type '(choice string function)) - -;;; Internal variables. - -;; Don't warn about these undefined variables. - -(defvar gnus-group-mode-hook) -(defvar gnus-summary-mode-hook) -(defvar gnus-article-mode-hook) - -;;defined in gnus.el -(defvar gnus-active-hashtb) -(defvar gnus-article-buffer) -(defvar gnus-auto-center-summary) -(defvar gnus-current-headers) -(defvar gnus-level-killed) -(defvar gnus-level-zombie) -(defvar gnus-newsgroup-bookmarks) -(defvar gnus-newsgroup-dependencies) -(defvar gnus-newsgroup-selected-overlay) -(defvar gnus-newsrc-hashtb) -(defvar gnus-read-mark) -(defvar gnus-refer-article-method) -(defvar gnus-reffed-article-number) -(defvar gnus-unread-mark) -(defvar gnus-version) -(defvar gnus-view-pseudos) -(defvar gnus-view-pseudos-separately) -(defvar gnus-visual) -(defvar gnus-zombie-list) -;;defined in gnus-msg.el -(defvar gnus-article-copy) -(defvar gnus-check-before-posting) -;;defined in gnus-vis.el -(defvar gnus-article-button-face) -(defvar gnus-article-mouse-face) -(defvar gnus-summary-selected-face) -(defvar gnus-group-reading-menu) -(defvar gnus-group-group-menu) -(defvar gnus-group-misc-menu) -(defvar gnus-summary-article-menu) -(defvar gnus-summary-thread-menu) -(defvar gnus-summary-misc-menu) -(defvar gnus-summary-post-menu) -(defvar gnus-summary-kill-menu) -(defvar gnus-article-article-menu) -(defvar gnus-article-treatment-menu) -(defvar gnus-mouse-2) -(defvar standard-display-table) -(defvar gnus-tree-minimize-window) - -(defun gnus-xmas-set-text-properties (start end props &optional buffer) - "You should NEVER use this function. It is ideologically blasphemous. -It is provided only to ease porting of broken FSF Emacs programs." - (if (stringp buffer) - nil - (map-extents (lambda (extent ignored) - (remove-text-properties - start end - (list (extent-property extent 'text-prop) nil) - buffer) - nil) - buffer start end nil nil 'text-prop) - (gnus-add-text-properties start end props buffer))) - -(defun gnus-xmas-highlight-selected-summary () - ;; Highlight selected article in summary buffer - (when gnus-summary-selected-face - (when gnus-newsgroup-selected-overlay - (delete-extent gnus-newsgroup-selected-overlay)) - (setq gnus-newsgroup-selected-overlay - (make-extent (gnus-point-at-bol) (gnus-point-at-eol))) - (set-extent-face gnus-newsgroup-selected-overlay - gnus-summary-selected-face))) - -(defcustom gnus-xmas-force-redisplay nil - "*If non-nil, force a redisplay before recentering the summary buffer. -This is ugly, but it works around a bug in `window-displayed-height'." - :type 'boolean - :group 'gnus-xmas) - -(defun gnus-xmas-switch-horizontal-scrollbar-off () - (when (featurep 'scrollbar) - (set-specifier scrollbar-height (cons (current-buffer) 0)))) - -(defun gnus-xmas-summary-recenter () - "\"Center\" point in the summary window. -If `gnus-auto-center-summary' is nil, or the article buffer isn't -displayed, no centering will be performed." - ;; Suggested by earle@mahendo.JPL.NASA.GOV (Greg Earle). - ;; Recenter only when requested. Suggested by popovich@park.cs.columbia.edu. - ;; Force redisplay to get properly computed window height. - (when gnus-xmas-force-redisplay - (sit-for 0)) - (when gnus-auto-center-summary - (let* ((height (if (fboundp 'window-displayed-height) - (window-displayed-height) - (- (window-height) 2))) - (top (cond ((< height 4) 0) - ((< height 7) 1) - (t 2))) - (bottom (save-excursion (goto-char (point-max)) - (forward-line (- height)) - (point))) - (window (get-buffer-window (current-buffer)))) - (when (get-buffer-window gnus-article-buffer) - ;; Only do recentering when the article buffer is displayed, - ;; Set the window start to either `bottom', which is the biggest - ;; possible valid number, or the second line from the top, - ;; whichever is the least. - (set-window-start - window (min bottom (save-excursion (forward-line (- top)) (point))))) - ;; Do horizontal recentering while we're at it. - (when (and (get-buffer-window (current-buffer) t) - (not (eq gnus-auto-center-summary 'vertical))) - (let ((selected (selected-window))) - (select-window (get-buffer-window (current-buffer) t)) - (gnus-summary-position-point) - (gnus-horizontal-recenter) - (select-window selected)))))) - -(defun gnus-xmas-summary-set-display-table () - ;; Setup the display table -- like `gnus-summary-setup-display-table', - ;; but done in an XEmacsish way. - (let ((table (make-display-table)) - (i 32)) - ;; Nix out all the control chars... - (while (>= (setq i (1- i)) 0) - (aset table i [??])) - ;; ... but not newline and cr, of course. (cr is necessary for the - ;; selective display). - (aset table ?\n nil) - (aset table ?\r nil) - ;; We keep TAB as well. - (aset table ?\t nil) - ;; We nix out any glyphs over 126 below ctl-arrow. - (let ((i (if (integerp ctl-arrow) ctl-arrow 160))) - (while (>= (setq i (1- i)) 127) - (unless (aref table i) - (aset table i [??])))) - ;; Can't use `set-specifier' because of a bug in 19.14 and earlier - (add-spec-to-specifier current-display-table table (current-buffer) nil))) - -(defun gnus-xmas-add-text-properties (start end props &optional object) - (add-text-properties start end props object) - (put-text-property start end 'start-closed nil object)) - -(defun gnus-xmas-put-text-property (start end prop value &optional object) - (put-text-property start end prop value object) - (put-text-property start end 'start-closed nil object)) - -(defun gnus-xmas-extent-start-open (point) - (map-extents (lambda (extent arg) - (set-extent-property extent 'start-open t)) - nil point (min (1+ (point)) (point-max)))) - -(defun gnus-xmas-article-push-button (event) - "Check text under the mouse pointer for a callback function. -If the text under the mouse pointer has a `gnus-callback' property, -call it with the value of the `gnus-data' text property." - (interactive "e") - (set-buffer (window-buffer (event-window event))) - (let* ((pos (event-closest-point event)) - (data (get-text-property pos 'gnus-data)) - (fun (get-text-property pos 'gnus-callback))) - (when fun - (funcall fun data)))) - -(defun gnus-xmas-move-overlay (extent start end &optional buffer) - (set-extent-endpoints extent start end buffer)) - -(defun gnus-xmas-kill-all-overlays () - "Delete all extents in the current buffer." - (map-extents (lambda (extent ignore) - (delete-extent extent) - nil))) - -;; Fixed by Christopher Davis . -(defun gnus-xmas-article-add-button (from to fun &optional data) - "Create a button between FROM and TO with callback FUN and data DATA." - (when gnus-article-button-face - (gnus-overlay-put (gnus-make-overlay from to) - 'face gnus-article-button-face)) - (gnus-add-text-properties - from to - (nconc - (and gnus-article-mouse-face - (list 'mouse-face gnus-article-mouse-face)) - (list 'gnus-callback fun) - (and data (list 'gnus-data data)) - (list 'highlight t)))) - -(defun gnus-xmas-window-top-edge (&optional window) - (nth 1 (window-pixel-edges window))) - -(defun gnus-xmas-tree-minimize () - (when (and gnus-tree-minimize-window - (not (one-window-p))) - (let* ((window-min-height 2) - (height (1+ (count-lines (point-min) (point-max)))) - (min (max (1- window-min-height) height)) - (tot (if (numberp gnus-tree-minimize-window) - (min gnus-tree-minimize-window min) - min)) - (win (get-buffer-window (current-buffer))) - (wh (and win (1- (window-height win))))) - (when (and win - (not (eq tot wh))) - (let ((selected (selected-window))) - (select-window win) - (enlarge-window (- tot wh)) - (select-window selected)))))) - -;; Select the lowest window on the frame. -(defun gnus-xmas-appt-select-lowest-window () - (let* ((lowest-window (selected-window)) - (bottom-edge (car (cdr (cdr (cdr (window-pixel-edges)))))) - (last-window (previous-window)) - (window-search t)) - (while window-search - (let* ((this-window (next-window)) - (next-bottom-edge (car (cdr (cdr (cdr - (window-pixel-edges - this-window))))))) - (when (< bottom-edge next-bottom-edge) - (setq bottom-edge next-bottom-edge) - (setq lowest-window this-window)) - - (select-window this-window) - (when (eq last-window this-window) - (select-window lowest-window) - (setq window-search nil)))))) - -(defmacro gnus-xmas-menu-add (type &rest menus) - `(gnus-xmas-menu-add-1 ',type ',menus)) -(put 'gnus-xmas-menu-add 'lisp-indent-function 1) - -(defun gnus-xmas-menu-add-1 (type menus) - (when (and menu-bar-mode - (gnus-visual-p (intern (format "%s-menu" type)) 'menu)) - (while menus - (easy-menu-add (symbol-value (pop menus)))))) - -(defun gnus-xmas-group-menu-add () - (gnus-xmas-menu-add group - gnus-group-reading-menu gnus-group-group-menu gnus-group-misc-menu)) - -(defun gnus-xmas-summary-menu-add () - (gnus-xmas-menu-add summary - gnus-summary-misc-menu gnus-summary-kill-menu - gnus-summary-article-menu gnus-summary-thread-menu - gnus-summary-post-menu )) - -(defun gnus-xmas-article-menu-add () - (gnus-xmas-menu-add article - gnus-article-article-menu gnus-article-treatment-menu)) - -(defun gnus-xmas-score-menu-add () - (gnus-xmas-menu-add score - gnus-score-menu)) - -(defun gnus-xmas-pick-menu-add () - (gnus-xmas-menu-add pick - gnus-pick-menu)) - -(defun gnus-xmas-topic-menu-add () - (gnus-xmas-menu-add topic - gnus-topic-menu)) - -(defun gnus-xmas-binary-menu-add () - (gnus-xmas-menu-add binary - gnus-binary-menu)) - -(defun gnus-xmas-agent-summary-menu-add () - (gnus-xmas-menu-add agent-summary - gnus-agent-summary-menu)) - -(defun gnus-xmas-agent-group-menu-add () - (gnus-xmas-menu-add agent-group - gnus-agent-group-menu)) - -(defun gnus-xmas-agent-server-menu-add () - (gnus-xmas-menu-add agent-server - gnus-agent-server-menu)) - -(defun gnus-xmas-tree-menu-add () - (gnus-xmas-menu-add tree - gnus-tree-menu)) - -(defun gnus-xmas-draft-menu-add () - (gnus-xmas-menu-add draft - gnus-draft-menu)) - -(defun gnus-xmas-server-menu-add () - (gnus-xmas-menu-add menu - gnus-server-server-menu gnus-server-connections-menu)) - -(defun gnus-xmas-browse-menu-add () - (gnus-xmas-menu-add browse - gnus-browse-menu)) - -(defun gnus-xmas-grouplens-menu-add () - (gnus-xmas-menu-add grouplens - gnus-grouplens-menu)) - -(defun gnus-xmas-read-event-char () - "Get the next event." - (let ((event (next-command-event))) - (sit-for 0) - ;; We junk all non-key events. Is this naughty? - (while (not (or (key-press-event-p event) - (button-press-event-p event))) - (dispatch-event event) - (setq event (next-command-event))) - (cons (and (key-press-event-p event) - (event-to-character event)) - event))) - -(defun gnus-xmas-seconds-since-epoch (date) - "Return a floating point number that says how many seconds have lapsed between Jan 1 12:00:00 1970 and DATE." - (let* ((tdate (mapcar (lambda (ti) (and ti (string-to-int ti))) - (timezone-parse-date date))) - (ttime (mapcar (lambda (ti) (and ti (string-to-int ti))) - (timezone-parse-time - (aref (timezone-parse-date date) 3)))) - (edate (mapcar (lambda (ti) (and ti (string-to-int ti))) - (timezone-parse-date "Jan 1 12:00:00 1970"))) - (tday (- (timezone-absolute-from-gregorian - (nth 1 tdate) (nth 2 tdate) (nth 0 tdate)) - (timezone-absolute-from-gregorian - (nth 1 edate) (nth 2 edate) (nth 0 edate))))) - (+ (nth 2 ttime) - (* (nth 1 ttime) 60) - (* (float (nth 0 ttime)) 60 60) - (* (float tday) 60 60 24)))) - -(defun gnus-xmas-define () - (setq gnus-mouse-2 [button2]) - - (unless (memq 'underline (face-list)) - (and (fboundp 'make-face) - (funcall (intern "make-face") 'underline))) - ;; Must avoid calling set-face-underline-p directly, because it - ;; is a defsubst in emacs19, and will make the .elc files non - ;; portable! - (unless (face-differs-from-default-p 'underline) - (funcall (intern "set-face-underline-p") 'underline t)) - - (cond - ((fboundp 'char-or-char-int-p) - ;; Handle both types of marks for XEmacs-20.x. - (fset 'gnus-characterp 'char-or-char-int-p)) - ;; V19 of XEmacs, probably. - (t - (fset 'gnus-characterp 'characterp))) - - (fset 'gnus-make-overlay 'make-extent) - (fset 'gnus-delete-overlay 'delete-extent) - (fset 'gnus-overlay-put 'set-extent-property) - (fset 'gnus-move-overlay 'gnus-xmas-move-overlay) - (fset 'gnus-overlay-end 'extent-end-position) - (fset 'gnus-kill-all-overlays 'gnus-xmas-kill-all-overlays) - (fset 'gnus-extent-detached-p 'extent-detached-p) - (fset 'gnus-add-text-properties 'gnus-xmas-add-text-properties) - (fset 'gnus-put-text-property 'gnus-xmas-put-text-property) - (fset 'gnus-deactivate-mark 'ignore) - (fset 'gnus-window-edges 'window-pixel-edges) - - (if (and (<= emacs-major-version 19) - (< emacs-minor-version 14)) - (fset 'gnus-set-text-properties 'gnus-xmas-set-text-properties)) - - (when (fboundp 'turn-off-scroll-in-place) - (add-hook 'gnus-article-mode-hook 'turn-off-scroll-in-place)) - - (unless (boundp 'standard-display-table) - (setq standard-display-table nil)) - - (defvar gnus-mouse-face-prop 'highlight) - - (unless (fboundp 'encode-time) - (defun encode-time (sec minute hour day month year &optional zone) - (let ((seconds - (gnus-xmas-seconds-since-epoch - (timezone-make-arpa-date - year month day (timezone-make-time-string hour minute sec) - zone)))) - (list (floor (/ seconds (expt 2 16))) - (round (mod seconds (expt 2 16))))))) - - (defun gnus-byte-code (func) - "Return a form that can be `eval'ed based on FUNC." - (let ((fval (indirect-function func))) - (if (compiled-function-p fval) - (list 'funcall fval) - (cons 'progn (cdr (cdr fval)))))) - - (fset 'gnus-x-color-values - (if (fboundp 'x-color-values) - 'x-color-values - (lambda (color) - (color-instance-rgb-components - (make-color-instance color))))) - - (when (featurep 'mule) - (defun gnus-tilde-pad-form (el pad-width) - "Return a form that pads EL to PAD-WIDTH." - (let ((pad (abs pad-width))) - (if (symbolp el) - (if (< pad-width 0) - `(concat ,el (make-string - (max 0 (- ,pad (string-width ,el))) ?\ )) - `(concat (make-string - (max 0 (- ,pad (string-width ,el))) ?\ ) - ,el)) - (if (< pad-width 0) - `(let ((val (eval ,el))) - (concat val (make-string - (max 0 (- ,pad (string-width val))) ?\ ))) - `(let ((val (eval ,el))) - (concat (make-string - (max 0 (- ,pad (string-width val))) ?\ ) - val)))))) - )) - -(defun gnus-xmas-redefine () - "Redefine lots of Gnus functions for XEmacs." - (fset 'gnus-summary-set-display-table 'gnus-xmas-summary-set-display-table) - (fset 'gnus-visual-turn-off-edit-menu 'identity) - (fset 'gnus-summary-recenter 'gnus-xmas-summary-recenter) - (fset 'gnus-extent-start-open 'gnus-xmas-extent-start-open) - (fset 'gnus-article-push-button 'gnus-xmas-article-push-button) - (fset 'gnus-article-add-button 'gnus-xmas-article-add-button) - (fset 'gnus-window-top-edge 'gnus-xmas-window-top-edge) - (fset 'gnus-read-event-char 'gnus-xmas-read-event-char) - (fset 'gnus-group-startup-message 'gnus-xmas-group-startup-message) - (fset 'gnus-tree-minimize 'gnus-xmas-tree-minimize) - (fset 'gnus-appt-select-lowest-window - 'gnus-xmas-appt-select-lowest-window) - (fset 'gnus-mail-strip-quoted-names 'gnus-xmas-mail-strip-quoted-names) - (fset 'gnus-character-to-event 'character-to-event) - (fset 'gnus-mode-line-buffer-identification - 'gnus-xmas-mode-line-buffer-identification) - (fset 'gnus-key-press-event-p 'key-press-event-p) - (fset 'gnus-region-active-p 'region-active-p) - - (add-hook 'gnus-group-mode-hook 'gnus-xmas-group-menu-add) - (add-hook 'gnus-summary-mode-hook 'gnus-xmas-summary-menu-add) - (add-hook 'gnus-article-mode-hook 'gnus-xmas-article-menu-add) - (add-hook 'gnus-score-mode-hook 'gnus-xmas-score-menu-add) - - (add-hook 'gnus-pick-mode-hook 'gnus-xmas-pick-menu-add) - (add-hook 'gnus-topic-mode-hook 'gnus-xmas-topic-menu-add) - (add-hook 'gnus-tree-mode-hook 'gnus-xmas-tree-menu-add) - (add-hook 'gnus-binary-mode-hook 'gnus-xmas-binary-menu-add) - (add-hook 'gnus-grouplens-mode-hook 'gnus-xmas-grouplens-menu-add) - (add-hook 'gnus-server-mode-hook 'gnus-xmas-server-menu-add) - (add-hook 'gnus-browse-mode-hook 'gnus-xmas-browse-menu-add) - - (add-hook 'gnus-group-mode-hook 'gnus-xmas-setup-group-toolbar) - (add-hook 'gnus-summary-mode-hook 'gnus-xmas-setup-summary-toolbar) - - (add-hook 'gnus-agent-summary-mode-hook 'gnus-xmas-agent-summary-menu-add) - (add-hook 'gnus-agent-group-mode-hook 'gnus-xmas-agent-group-menu-add) - (add-hook 'gnus-agent-server-mode-hook 'gnus-xmas-agent-server-menu-add) - - (add-hook 'gnus-draft-mode-hook 'gnus-xmas-draft-menu-add) - (add-hook 'gnus-summary-mode-hook - 'gnus-xmas-switch-horizontal-scrollbar-off) - (add-hook 'gnus-tree-mode-hook 'gnus-xmas-switch-horizontal-scrollbar-off) - - (when (featurep 'mule) - (defun gnus-truncate-string (str end-column &optional start-column padding) - "Truncate string STR to end at column END-COLUMN. -The optional 2nd arg START-COLUMN, if non-nil, specifies -the starting column; that means to return the characters occupying -columns START-COLUMN ... END-COLUMN of STR. - -The optional 3rd arg PADDING, if non-nil, specifies a padding character -to add at the end of the result if STR doesn't reach column END-COLUMN, -or if END-COLUMN comes in the middle of a character in STR. -PADDING is also added at the beginning of the result -if column START-COLUMN appears in the middle of a character in STR. - -If PADDING is nil, no padding is added in these cases, so -the resulting string may be narrower than END-COLUMN. -\[Emacs 20.3 emulating function]" - (or start-column - (setq start-column 0)) - (let ((len (length str)) - (idx 0) - (column 0) - (head-padding "") (tail-padding "") - ch last-column last-idx from-idx) - (condition-case nil - (while (< column start-column) - (setq ch (aref str idx) - column (+ column (char-width ch)) - idx (1+ idx))) - (args-out-of-range (setq idx len))) - (if (< column start-column) - (if padding (make-string end-column padding) "") - (if (and padding (> column start-column)) - (setq head-padding - (make-string (- column start-column) padding))) - (setq from-idx idx) - (if (< end-column column) - (setq idx from-idx) - (condition-case nil - (while (< column end-column) - (setq last-column column - last-idx idx - ch (aref str idx) - column (+ column (char-width ch)) - idx (1+ idx))) - (args-out-of-range (setq idx len))) - (if (> column end-column) - (setq column last-column idx last-idx)) - (if (and padding (< column end-column)) - (setq tail-padding - (make-string (- end-column column) padding)))) - (setq str (substring str from-idx idx)) - (if padding - (concat head-padding str tail-padding) - str)))) - - (defun gnus-tilde-max-form (el max-width) - "Return a form that limits EL to MAX-WIDTH." - (let ((max (abs max-width))) - (if (symbolp el) - (if (< max-width 0) - `(let ((width (string-width ,el))) - (gnus-truncate-string ,el width (- width ,max))) - `(gnus-truncate-string ,el ,max)) - (if (< max-width 0) - `(let* ((val (eval ,el)) - (width (string-width val))) - (gnus-truncate-string val width (- width ,max))) - `(let ((val (eval ,el))) - (gnus-truncate-string val ,max)))))) - - (defun gnus-tilde-cut-form (el cut-width) - "Return a form that cuts CUT-WIDTH off of EL." - (let ((cut (abs cut-width))) - (if (symbolp el) - (if (< cut-width 0) - `(gnus-truncate-string ,el (- (string-width ,el) ,cut)) - `(gnus-truncate-string ,el (string-width ,el) ,cut)) - (if (< cut-width 0) - `(let ((val (eval ,el))) - (gnus-truncate-string val (- (string-width val) ,cut))) - `(let ((val (eval ,el))) - (gnus-truncate-string val (string-width val) ,cut)))))) - )) - -;;; XEmacs logo and toolbar. - -(defun gnus-xmas-group-startup-message (&optional x y) - "Insert startup message in current buffer." - ;; Insert the message. - (setq gnus-xmas-glyph-directory (message-xmas-find-glyph-directory "gnus")) - (erase-buffer) - (cond - ((and (console-on-window-system-p) - (or (featurep 'xpm) - (featurep 'xbm))) - (let* ((logo-xpm (expand-file-name "gnus.xpm" gnus-xmas-glyph-directory)) - (logo-xbm (expand-file-name "gnus.xbm" gnus-xmas-glyph-directory)) - (glyph (make-glyph - (cond ((featurep 'xpm) - `[xpm - :file ,logo-xpm - :color-symbols - (("thing" . ,(car gnus-xmas-logo-colors)) - ("shadow" . ,(cadr gnus-xmas-logo-colors)) - ("background" . ,(face-background 'default)))]) - ((featurep 'xbm) - `[xbm :file ,logo-xbm]) - (t [nothing]))))) - (insert " ") - (set-extent-begin-glyph (make-extent (point) (point)) glyph) - (goto-char (point-min)) - (while (not (eobp)) - (insert (make-string (/ (max (- (window-width) (or x 35)) 0) 2) - ?\ )) - (forward-line 1)) - (setq gnus-simple-splash nil)) - (goto-char (point-min)) - (let* ((pheight (+ 20 (count-lines (point-min) (point-max)))) - (wheight (window-height)) - (rest (- wheight pheight))) - (insert (make-string (max 0 (* 2 (/ rest 3))) ?\n)))) - (t - (insert - (format " %s - _ ___ _ _ - _ ___ __ ___ __ _ ___ - __ _ ___ __ ___ - _ ___ _ - _ _ __ _ - ___ __ _ - __ _ - _ _ _ - _ _ _ - _ _ _ - __ ___ - _ _ _ _ - _ _ - _ _ - _ _ - _ - __ - -" - "")) - ;; And then hack it. - (gnus-indent-rigidly (point-min) (point-max) - (/ (max (- (window-width) (or x 46)) 0) 2)) - (goto-char (point-min)) - (forward-line 1) - (let* ((pheight (count-lines (point-min) (point-max))) - (wheight (window-height)) - (rest (- wheight pheight))) - (insert (make-string (max 0 (* 2 (/ rest 3))) ?\n))) - ;; Paint it. - (put-text-property (point-min) (point-max) 'face 'gnus-splash-face))) - (setq modeline-buffer-identification - (list (concat gnus-version ": *Group*"))) - (set-buffer-modified-p t)) - - -;;; The toolbar. - -(defcustom gnus-use-toolbar (if (featurep 'toolbar) - 'default-toolbar - nil) - "*If nil, do not use a toolbar. -If it is non-nil, it must be a toolbar. The five legal values are -`default-toolbar', `top-toolbar', `bottom-toolbar', -`right-toolbar', and `left-toolbar'." - :type '(choice (const default-toolbar) - (const top-toolbar) (const bottom-toolbar) - (const left-toolbar) (const right-toolbar) - (const :tag "no toolbar" nil)) - :group 'gnus-xmas) - -(defvar gnus-group-toolbar - '([gnus-group-get-new-news gnus-group-get-new-news t "Get new news"] - [gnus-group-get-new-news-this-group - gnus-group-get-new-news-this-group t "Get new news in this group"] - [gnus-group-catchup-current - gnus-group-catchup-current t "Catchup group"] - [gnus-group-describe-group - gnus-group-describe-group t "Describe group"] - [gnus-group-unsubscribe gnus-group-unsubscribe t "Unsubscribe group"] - [gnus-group-subscribe gnus-group-subscribe t "Subscribe group"] - [gnus-group-kill-group gnus-group-kill-group t "Kill group"] - [gnus-group-exit gnus-group-exit t "Exit Gnus"] - ) - "The group buffer toolbar.") - -(defvar gnus-summary-toolbar - '([gnus-summary-prev-unread - gnus-summary-prev-page-or-article t "Page up"] - [gnus-summary-next-unread - gnus-summary-next-page t "Page down"] - [gnus-summary-post-news - gnus-summary-post-news t "Post an article"] - [gnus-summary-followup-with-original - gnus-summary-followup-with-original t - "Post a followup and yank the original"] - [gnus-summary-followup - gnus-summary-followup t "Post a followup"] - [gnus-summary-reply-with-original - gnus-summary-reply-with-original t "Mail a reply and yank the original"] - [gnus-summary-reply - gnus-summary-reply t "Mail a reply"] - [gnus-summary-caesar-message - gnus-summary-caesar-message t "Rot 13"] - [gnus-uu-decode-uu - gnus-uu-decode-uu t "Decode uuencoded articles"] - [gnus-summary-save-article-file - gnus-summary-save-article-file t "Save article in file"] - [gnus-summary-save-article - gnus-summary-save-article t "Save article"] - [gnus-uu-post-news - gnus-uu-post-news t "Post a uuencoded article"] - [gnus-summary-cancel-article - gnus-summary-cancel-article t "Cancel article"] - [gnus-summary-catchup - gnus-summary-catchup t "Catchup"] - [gnus-summary-catchup-and-exit - gnus-summary-catchup-and-exit t "Catchup and exit"] - [gnus-summary-exit gnus-summary-exit t "Exit this summary"] - ) - "The summary buffer toolbar.") - -(defvar gnus-summary-mail-toolbar - '( - [gnus-summary-prev-unread - gnus-summary-prev-unread-article t "Prev unread article"] - [gnus-summary-next-unread - gnus-summary-next-unread-article t "Next unread article"] - [gnus-summary-mail-reply gnus-summary-reply t "Reply"] -; [gnus-summary-mail-get gnus-mail-get t "Message get"] - [gnus-summary-mail-originate gnus-summary-post-news t "Originate"] - [gnus-summary-mail-save gnus-summary-save-article t "Save"] - [gnus-summary-mail-copy gnus-summary-copy-article t "Copy message"] -; [gnus-summary-mail-delete gnus-summary-delete-article t "Delete message"] - [gnus-summary-mail-forward gnus-summary-mail-forward t "Forward message"] -; [gnus-summary-mail-spell gnus-mail-spell t "Spell"] -; [gnus-summary-mail-help gnus-mail-help t "Message help"] - [gnus-summary-caesar-message - gnus-summary-caesar-message t "Rot 13"] - [gnus-uu-decode-uu - gnus-uu-decode-uu t "Decode uuencoded articles"] - [gnus-summary-save-article-file - gnus-summary-save-article-file t "Save article in file"] - [gnus-summary-save-article - gnus-summary-save-article t "Save article"] - [gnus-summary-catchup - gnus-summary-catchup t "Catchup"] - [gnus-summary-catchup-and-exit - gnus-summary-catchup-and-exit t "Catchup and exit"] - [gnus-summary-exit gnus-summary-exit t "Exit this summary"] - ) - "The summary buffer mail toolbar.") - -(defun gnus-xmas-setup-group-toolbar () - (and gnus-use-toolbar - (message-xmas-setup-toolbar gnus-group-toolbar nil "gnus") - (set-specifier (symbol-value gnus-use-toolbar) - (cons (current-buffer) gnus-group-toolbar)))) - -(defun gnus-xmas-setup-summary-toolbar () - (let ((bar (if (gnus-news-group-p gnus-newsgroup-name) - gnus-summary-toolbar gnus-summary-mail-toolbar))) - (and gnus-use-toolbar - (message-xmas-setup-toolbar bar nil "gnus") - (set-specifier (symbol-value gnus-use-toolbar) - (cons (current-buffer) bar))))) - -(defun gnus-xmas-mail-strip-quoted-names (address) - "Protect mail-strip-quoted-names from NIL input. -XEmacs compatibility workaround." - (if (null address) - nil - (mail-strip-quoted-names address))) - -(defun gnus-xmas-call-region (command &rest args) - (apply - 'call-process-region (point-min) (point-max) command t '(t nil) nil - args)) - -(defface gnus-x-face '((t (:foreground "black" :background "white"))) - "Face to show X face" - :group 'gnus-xmas) - -(defun gnus-xmas-article-display-xface (beg end) - "Display any XFace headers in the current article." - (save-excursion - (let ((xface-glyph - (cond ((featurep 'xface) - (make-glyph (vector 'xface :data - (concat "X-Face: " - (buffer-substring beg end))))) - ((featurep 'xpm) - (let ((cur (current-buffer))) - (save-excursion - (gnus-set-work-buffer) - (insert (format "%s" (buffer-substring beg end cur))) - (gnus-xmas-call-region "uncompface") - (goto-char (point-min)) - (insert "/* Width=48, Height=48 */\n") - (gnus-xmas-call-region "icontopbm") - (gnus-xmas-call-region "ppmtoxpm") - (make-glyph - (vector 'xpm :data (buffer-string)))))) - (t - (make-glyph [nothing])))) - (ext (make-extent (progn - (goto-char (point-min)) - (re-search-forward "^From:" nil t) - (point)) - (1+ (point))))) - (set-glyph-face xface-glyph 'gnus-x-face) - (set-extent-begin-glyph ext xface-glyph) - (set-extent-property ext 'duplicable t)))) - -;;(defvar gnus-xmas-pointer-glyph -;; (progn -;; (setq gnus-xmas-glyph-directory (message-xmas-find-glyph-directory -;; "gnus")) -;; (let ((file-xpm (expand-file-name "gnus-pointer.xpm" -;; gnus-xmas-glyph-directory)) -;; (file-xbm (expand-file-name "gnus-pointer.xbm" -;; gnus-xmas-glyph-directory))) -;; (make-pointer-glyph -;; (list (vector 'xpm ':file file-xpm) -;; (vector 'xbm ':file file-xbm)))))) - -(defvar gnus-xmas-modeline-left-extent - (let ((ext (copy-extent modeline-buffer-id-left-extent))) -; (set-extent-property ext 'pointer gnus-xmas-pointer-glyph) - ext)) - -(defvar gnus-xmas-modeline-right-extent - (let ((ext (copy-extent modeline-buffer-id-right-extent))) -; (set-extent-property ext 'pointer gnus-xmas-pointer-glyph) - ext)) - -(defvar gnus-xmas-modeline-glyph - (progn - (setq gnus-xmas-glyph-directory (message-xmas-find-glyph-directory "gnus")) - (let* ((file-xpm (expand-file-name "gnus-pointer.xpm" - gnus-xmas-glyph-directory)) - (file-xbm (expand-file-name "gnus-pointer.xbm" - gnus-xmas-glyph-directory)) - (glyph (make-glyph - ;; Gag gag gag. - (cond ((featurep 'xpm) - ;; Let's try a nifty XPM - `[xpm :file ,file-xpm]) - ((featurep 'xbm) - ;; Then a not-so-nifty XBM - [xbm :file ,file-xbm]) - ;; Then the simple string - (t [string :data "Gnus:"]))))) - (set-glyph-face glyph 'modeline-buffer-id) - glyph))) - -(defun gnus-xmas-mode-line-buffer-identification (line) - (let ((line (car line)) - chop) - (cond - ;; This is some weird type of id. - ((not (stringp line)) - (list line)) - ;; This is non-standard, so we just pass it through. - ((not (string-match "^Gnus:" line)) - (list line)) - ;; We have a standard line, so we colorize and glyphize it a bit. - (t - (setq chop (match-end 0)) - (list - (if gnus-xmas-modeline-glyph - (cons gnus-xmas-modeline-left-extent gnus-xmas-modeline-glyph) - (cons gnus-xmas-modeline-left-extent (substring line 0 chop))) - (cons gnus-xmas-modeline-right-extent (substring line chop))))))) - -(defun gnus-xmas-splash () - (when (eq (device-type) 'x) - (gnus-splash))) - -(provide 'gnus-xmas) - -;;; gnus-xmas.el ends here diff --git a/lisp/gnus.el b/lisp/gnus.el deleted file mode 100644 index eb8b619..0000000 --- a/lisp/gnus.el +++ /dev/null @@ -1,2794 +0,0 @@ -;;; gnus.el --- a newsreader for GNU Emacs -;; Copyright (C) 1987,88,89,90,93,94,95,96,97,98 Free Software Foundation, Inc. - -;; Author: Masanobu UMEDA -;; Lars Magne Ingebrigtsen -;; Keywords: news, mail - -;; This file is part of GNU Emacs. - -;; GNU Emacs is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 2, or (at your option) -;; any later version. - -;; GNU Emacs is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs; see the file COPYING. If not, write to the -;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. - -;;; Commentary: - -;;; Code: - -(eval '(run-hooks 'gnus-load-hook)) - -(eval-when-compile (require 'cl)) - -(require 'custom) -(eval-and-compile - (if (< emacs-major-version 20) - (require 'gnus-load))) -(require 'message) - -(defgroup gnus nil - "The coffee-brewing, all singing, all dancing, kitchen sink newsreader." - :group 'news - :group 'mail) - -(defgroup gnus-cache nil - "Cache interface." - :group 'gnus) - -(defgroup gnus-start nil - "Starting your favorite newsreader." - :group 'gnus) - -(defgroup gnus-start-server nil - "Server options at startup." - :group 'gnus-start) - -;; These belong to gnus-group.el. -(defgroup gnus-group nil - "Group buffers." - :link '(custom-manual "(gnus)The Group Buffer") - :group 'gnus) - -(defgroup gnus-group-foreign nil - "Foreign groups." - :link '(custom-manual "(gnus)Foreign Groups") - :group 'gnus-group) - -(defgroup gnus-group-new nil - "Automatic subscription of new groups." - :group 'gnus-group) - -(defgroup gnus-group-levels nil - "Group levels." - :link '(custom-manual "(gnus)Group Levels") - :group 'gnus-group) - -(defgroup gnus-group-select nil - "Selecting a Group." - :link '(custom-manual "(gnus)Selecting a Group") - :group 'gnus-group) - -(defgroup gnus-group-listing nil - "Showing slices of the group list." - :link '(custom-manual "(gnus)Listing Groups") - :group 'gnus-group) - -(defgroup gnus-group-visual nil - "Sorting the group buffer." - :link '(custom-manual "(gnus)Group Buffer Format") - :group 'gnus-group - :group 'gnus-visual) - -(defgroup gnus-group-various nil - "Various group options." - :link '(custom-manual "(gnus)Scanning New Messages") - :group 'gnus-group) - -;; These belong to gnus-sum.el. -(defgroup gnus-summary nil - "Summary buffers." - :link '(custom-manual "(gnus)The Summary Buffer") - :group 'gnus) - -(defgroup gnus-summary-exit nil - "Leaving summary buffers." - :link '(custom-manual "(gnus)Exiting the Summary Buffer") - :group 'gnus-summary) - -(defgroup gnus-summary-marks nil - "Marks used in summary buffers." - :link '(custom-manual "(gnus)Marking Articles") - :group 'gnus-summary) - -(defgroup gnus-thread nil - "Ordering articles according to replies." - :link '(custom-manual "(gnus)Threading") - :group 'gnus-summary) - -(defgroup gnus-summary-format nil - "Formatting of the summary buffer." - :link '(custom-manual "(gnus)Summary Buffer Format") - :group 'gnus-summary) - -(defgroup gnus-summary-choose nil - "Choosing Articles." - :link '(custom-manual "(gnus)Choosing Articles") - :group 'gnus-summary) - -(defgroup gnus-summary-maneuvering nil - "Summary movement commands." - :link '(custom-manual "(gnus)Summary Maneuvering") - :group 'gnus-summary) - -(defgroup gnus-summary-mail nil - "Mail group commands." - :link '(custom-manual "(gnus)Mail Group Commands") - :group 'gnus-summary) - -(defgroup gnus-summary-sort nil - "Sorting the summary buffer." - :link '(custom-manual "(gnus)Sorting") - :group 'gnus-summary) - -(defgroup gnus-summary-visual nil - "Highlighting and menus in the summary buffer." - :link '(custom-manual "(gnus)Summary Highlighting") - :group 'gnus-visual - :group 'gnus-summary) - -(defgroup gnus-summary-various nil - "Various summary buffer options." - :link '(custom-manual "(gnus)Various Summary Stuff") - :group 'gnus-summary) - -(defgroup gnus-summary-pick nil - "Pick mode in the summary buffer." - :link '(custom-manual "(gnus)Pick and Read") - :prefix "gnus-pick-" - :group 'gnus-summary) - -(defgroup gnus-summary-tree nil - "Tree display of threads in the summary buffer." - :link '(custom-manual "(gnus)Tree Display") - :prefix "gnus-tree-" - :group 'gnus-summary) - -;; Belongs to gnus-uu.el -(defgroup gnus-extract-view nil - "Viewing extracted files." - :link '(custom-manual "(gnus)Viewing Files") - :group 'gnus-extract) - -;; Belongs to gnus-score.el -(defgroup gnus-score nil - "Score and kill file handling." - :group 'gnus) - -(defgroup gnus-score-kill nil - "Kill files." - :group 'gnus-score) - -(defgroup gnus-score-adapt nil - "Adaptive score files." - :group 'gnus-score) - -(defgroup gnus-score-default nil - "Default values for score files." - :group 'gnus-score) - -(defgroup gnus-score-expire nil - "Expiring score rules." - :group 'gnus-score) - -(defgroup gnus-score-decay nil - "Decaying score rules." - :group 'gnus-score) - -(defgroup gnus-score-files nil - "Score and kill file names." - :group 'gnus-score - :group 'gnus-files) - -(defgroup gnus-score-various nil - "Various scoring and killing options." - :group 'gnus-score) - -;; Other -(defgroup gnus-visual nil - "Options controling the visual fluff." - :group 'gnus - :group 'faces) - -(defgroup gnus-agent nil - "Offline support for Gnus." - :group 'gnus) - -(defgroup gnus-files nil - "Files used by Gnus." - :group 'gnus) - -(defgroup gnus-dribble-file nil - "Auto save file." - :link '(custom-manual "(gnus)Auto Save") - :group 'gnus-files) - -(defgroup gnus-newsrc nil - "Storing Gnus state." - :group 'gnus-files) - -(defgroup gnus-server nil - "Options related to newsservers and other servers used by Gnus." - :group 'gnus) - -(defgroup gnus-message '((message custom-group)) - "Composing replies and followups in Gnus." - :group 'gnus) - -(defgroup gnus-meta nil - "Meta variables controling major portions of Gnus. -In general, modifying these variables does not take affect until Gnus -is restarted, and sometimes reloaded." - :group 'gnus) - -(defgroup gnus-various nil - "Other Gnus options." - :link '(custom-manual "(gnus)Various Various") - :group 'gnus) - -(defgroup gnus-exit nil - "Exiting gnus." - :link '(custom-manual "(gnus)Exiting Gnus") - :group 'gnus) - -(defconst gnus-product-name "Chao-gnus" - "Product name of this version of gnus.") - -(defconst gnus-version-number "6.9.2" - "Version number for this version of gnus.") - -(defconst gnus-version - (format "%s %s (based on Gnus 5.6.44; for SEMI 1.8, Chao 1.11)" - gnus-product-name gnus-version-number) - "Version string for this version of gnus.") - -(defcustom gnus-inhibit-startup-message nil - "If non-nil, the startup message will not be displayed. -This variable is used before `.gnus.el' is loaded, so it should -be set in `.emacs' instead." - :group 'gnus-start - :type 'boolean) - -(defcustom gnus-play-startup-jingle nil - "If non-nil, play the Gnus jingle at startup." - :group 'gnus-start - :type 'boolean) - -;;; Kludges to help the transition from the old `custom.el'. - -(unless (featurep 'gnus-xmas) - (defalias 'gnus-make-overlay 'make-overlay) - (defalias 'gnus-delete-overlay 'delete-overlay) - (defalias 'gnus-overlay-put 'overlay-put) - (defalias 'gnus-move-overlay 'move-overlay) - (defalias 'gnus-overlay-end 'overlay-end) - (defalias 'gnus-extent-detached-p 'ignore) - (defalias 'gnus-extent-start-open 'ignore) - (defalias 'gnus-set-text-properties 'set-text-properties) - (defalias 'gnus-group-remove-excess-properties 'ignore) - (defalias 'gnus-appt-select-lowest-window 'appt-select-lowest-window) - (defalias 'gnus-mail-strip-quoted-names 'mail-strip-quoted-names) - (defalias 'gnus-character-to-event 'identity) - (defalias 'gnus-add-text-properties 'add-text-properties) - (defalias 'gnus-put-text-property 'put-text-property) - (defalias 'gnus-mode-line-buffer-identification 'identity) - (defalias 'gnus-characterp 'numberp) - (defalias 'gnus-deactivate-mark 'deactivate-mark) - (defalias 'gnus-window-edges 'window-edges) - (defalias 'gnus-key-press-event-p 'numberp)) - -;; We define these group faces here to avoid the display -;; update forced when creating new faces. - -(defface gnus-group-news-1-face - '((((class color) - (background dark)) - (:foreground "PaleTurquoise" :bold t)) - (((class color) - (background light)) - (:foreground "ForestGreen" :bold t)) - (t - ())) - "Level 1 newsgroup face.") - -(defface gnus-group-news-1-empty-face - '((((class color) - (background dark)) - (:foreground "PaleTurquoise")) - (((class color) - (background light)) - (:foreground "ForestGreen")) - (t - ())) - "Level 1 empty newsgroup face.") - -(defface gnus-group-news-2-face - '((((class color) - (background dark)) - (:foreground "turquoise" :bold t)) - (((class color) - (background light)) - (:foreground "CadetBlue4" :bold t)) - (t - ())) - "Level 2 newsgroup face.") - -(defface gnus-group-news-2-empty-face - '((((class color) - (background dark)) - (:foreground "turquoise")) - (((class color) - (background light)) - (:foreground "CadetBlue4")) - (t - ())) - "Level 2 empty newsgroup face.") - -(defface gnus-group-news-3-face - '((((class color) - (background dark)) - (:bold t)) - (((class color) - (background light)) - (:bold t)) - (t - ())) - "Level 3 newsgroup face.") - -(defface gnus-group-news-3-empty-face - '((((class color) - (background dark)) - ()) - (((class color) - (background light)) - ()) - (t - ())) - "Level 3 empty newsgroup face.") - -(defface gnus-group-news-low-face - '((((class color) - (background dark)) - (:foreground "DarkTurquoise" :bold t)) - (((class color) - (background light)) - (:foreground "DarkGreen" :bold t)) - (t - ())) - "Low level newsgroup face.") - -(defface gnus-group-news-low-empty-face - '((((class color) - (background dark)) - (:foreground "DarkTurquoise")) - (((class color) - (background light)) - (:foreground "DarkGreen")) - (t - ())) - "Low level empty newsgroup face.") - -(defface gnus-group-mail-1-face - '((((class color) - (background dark)) - (:foreground "aquamarine1" :bold t)) - (((class color) - (background light)) - (:foreground "DeepPink3" :bold t)) - (t - (:bold t))) - "Level 1 mailgroup face.") - -(defface gnus-group-mail-1-empty-face - '((((class color) - (background dark)) - (:foreground "aquamarine1")) - (((class color) - (background light)) - (:foreground "DeepPink3")) - (t - (:italic t :bold t))) - "Level 1 empty mailgroup face.") - -(defface gnus-group-mail-2-face - '((((class color) - (background dark)) - (:foreground "aquamarine2" :bold t)) - (((class color) - (background light)) - (:foreground "HotPink3" :bold t)) - (t - (:bold t))) - "Level 2 mailgroup face.") - -(defface gnus-group-mail-2-empty-face - '((((class color) - (background dark)) - (:foreground "aquamarine2")) - (((class color) - (background light)) - (:foreground "HotPink3")) - (t - (:bold t))) - "Level 2 empty mailgroup face.") - -(defface gnus-group-mail-3-face - '((((class color) - (background dark)) - (:foreground "aquamarine3" :bold t)) - (((class color) - (background light)) - (:foreground "magenta4" :bold t)) - (t - (:bold t))) - "Level 3 mailgroup face.") - -(defface gnus-group-mail-3-empty-face - '((((class color) - (background dark)) - (:foreground "aquamarine3")) - (((class color) - (background light)) - (:foreground "magenta4")) - (t - ())) - "Level 3 empty mailgroup face.") - -(defface gnus-group-mail-low-face - '((((class color) - (background dark)) - (:foreground "aquamarine4" :bold t)) - (((class color) - (background light)) - (:foreground "DeepPink4" :bold t)) - (t - (:bold t))) - "Low level mailgroup face.") - -(defface gnus-group-mail-low-empty-face - '((((class color) - (background dark)) - (:foreground "aquamarine4")) - (((class color) - (background light)) - (:foreground "DeepPink4")) - (t - (:bold t))) - "Low level empty mailgroup face.") - -;; Summary mode faces. - -(defface gnus-summary-selected-face '((t - (:underline t))) - "Face used for selected articles.") - -(defface gnus-summary-cancelled-face - '((((class color)) - (:foreground "yellow" :background "black"))) - "Face used for cancelled articles.") - -(defface gnus-summary-high-ticked-face - '((((class color) - (background dark)) - (:foreground "pink" :bold t)) - (((class color) - (background light)) - (:foreground "firebrick" :bold t)) - (t - (:bold t))) - "Face used for high interest ticked articles.") - -(defface gnus-summary-low-ticked-face - '((((class color) - (background dark)) - (:foreground "pink" :italic t)) - (((class color) - (background light)) - (:foreground "firebrick" :italic t)) - (t - (:italic t))) - "Face used for low interest ticked articles.") - -(defface gnus-summary-normal-ticked-face - '((((class color) - (background dark)) - (:foreground "pink")) - (((class color) - (background light)) - (:foreground "firebrick")) - (t - ())) - "Face used for normal interest ticked articles.") - -(defface gnus-summary-high-ancient-face - '((((class color) - (background dark)) - (:foreground "SkyBlue" :bold t)) - (((class color) - (background light)) - (:foreground "RoyalBlue" :bold t)) - (t - (:bold t))) - "Face used for high interest ancient articles.") - -(defface gnus-summary-low-ancient-face - '((((class color) - (background dark)) - (:foreground "SkyBlue" :italic t)) - (((class color) - (background light)) - (:foreground "RoyalBlue" :italic t)) - (t - (:italic t))) - "Face used for low interest ancient articles.") - -(defface gnus-summary-normal-ancient-face - '((((class color) - (background dark)) - (:foreground "SkyBlue")) - (((class color) - (background light)) - (:foreground "RoyalBlue")) - (t - ())) - "Face used for normal interest ancient articles.") - -(defface gnus-summary-high-unread-face - '((t - (:bold t))) - "Face used for high interest unread articles.") - -(defface gnus-summary-low-unread-face - '((t - (:italic t))) - "Face used for low interest unread articles.") - -(defface gnus-summary-normal-unread-face - '((t - ())) - "Face used for normal interest unread articles.") - -(defface gnus-summary-high-read-face - '((((class color) - (background dark)) - (:foreground "PaleGreen" - :bold t)) - (((class color) - (background light)) - (:foreground "DarkGreen" - :bold t)) - (t - (:bold t))) - "Face used for high interest read articles.") - -(defface gnus-summary-low-read-face - '((((class color) - (background dark)) - (:foreground "PaleGreen" - :italic t)) - (((class color) - (background light)) - (:foreground "DarkGreen" - :italic t)) - (t - (:italic t))) - "Face used for low interest read articles.") - -(defface gnus-summary-normal-read-face - '((((class color) - (background dark)) - (:foreground "PaleGreen")) - (((class color) - (background light)) - (:foreground "DarkGreen")) - (t - ())) - "Face used for normal interest read articles.") - - -;;; -;;; Gnus buffers -;;; - -(defvar gnus-buffers nil) - -(defun gnus-get-buffer-create (name) - "Do the same as `get-buffer-create', but store the created buffer." - (or (get-buffer name) - (car (push (get-buffer-create name) gnus-buffers)))) - -(defun gnus-add-buffer () - "Add the current buffer to the list of Gnus buffers." - (push (current-buffer) gnus-buffers)) - -(defun gnus-buffers () - "Return a list of live Gnus buffers." - (while (and gnus-buffers - (not (buffer-name (car gnus-buffers)))) - (pop gnus-buffers)) - (let ((buffers gnus-buffers)) - (while (cdr buffers) - (if (buffer-name (cadr buffers)) - (pop buffers) - (setcdr buffers (cddr buffers))))) - gnus-buffers) - -;;; Splash screen. - -(defvar gnus-group-buffer "*Group*") - -(eval-and-compile - (autoload 'gnus-play-jingle "gnus-audio")) - -(defface gnus-splash-face - '((((class color) - (background dark)) - (:foreground "ForestGreen")) - (((class color) - (background light)) - (:foreground "ForestGreen")) - (t - ())) - "Level 1 newsgroup face.") - -(defun gnus-splash () - (save-excursion - (switch-to-buffer (gnus-get-buffer-create gnus-group-buffer)) - (let ((buffer-read-only nil)) - (erase-buffer) - (unless gnus-inhibit-startup-message - (gnus-group-startup-message) - (sit-for 0) - (when gnus-play-startup-jingle - (gnus-play-jingle)))))) - -(defun gnus-indent-rigidly (start end arg) - "Indent rigidly using only spaces and no tabs." - (save-excursion - (save-restriction - (narrow-to-region start end) - (let ((tab-width 8)) - (indent-rigidly start end arg) - ;; We translate tabs into spaces -- not everybody uses - ;; an 8-character tab. - (goto-char (point-min)) - (while (search-forward "\t" nil t) - (replace-match " " t t)))))) - -(defvar gnus-simple-splash nil) - -(defun gnus-group-startup-message (&optional x y) - "Insert startup message in current buffer." - ;; Insert the message. - (erase-buffer) - (insert - (format " %s - _ ___ _ _ - _ ___ __ ___ __ _ ___ - __ _ ___ __ ___ - _ ___ _ - _ _ __ _ - ___ __ _ - __ _ - _ _ _ - _ _ _ - _ _ _ - __ ___ - _ _ _ _ - _ _ - _ _ - _ _ - _ - __ - -" - "")) - ;; And then hack it. - (gnus-indent-rigidly (point-min) (point-max) - (/ (max (- (window-width) (or x 46)) 0) 2)) - (goto-char (point-min)) - (forward-line 1) - (let* ((pheight (count-lines (point-min) (point-max))) - (wheight (window-height)) - (rest (- wheight pheight))) - (insert (make-string (max 0 (* 2 (/ rest 3))) ?\n))) - ;; Fontify some. - (put-text-property (point-min) (point-max) 'face 'gnus-splash-face) - (goto-char (point-min)) - (setq mode-line-buffer-identification (concat " " gnus-version)) - (setq gnus-simple-splash t) - (set-buffer-modified-p t)) - -(eval-when (load) - (let ((command (format "%s" this-command))) - (if (and (string-match "gnus" command) - (not (string-match "gnus-other-frame" command))) - (gnus-splash) - (gnus-get-buffer-create gnus-group-buffer)))) - -;;; Do the rest. - -(require 'custom) -(require 'gnus-util) -(require 'nnheader) - -(defcustom gnus-home-directory "~/" - "Directory variable that specifies the \"home\" directory. -All other Gnus path variables are initialized from this variable." - :group 'gnus-files - :type 'directory) - -(defcustom gnus-directory (or (getenv "SAVEDIR") - (nnheader-concat gnus-home-directory "News/")) - "*Directory variable from which all other Gnus file variables are derived. - -Note that Gnus is mostly loaded when the `.gnus.el' file is read. -This means that other directory variables that are initialized from -this variable won't be set properly if you set this variable in `.gnus.el'. -Set this variable in `.emacs' instead." - :group 'gnus-files - :type 'directory) - -(defcustom gnus-default-directory nil - "*Default directory for all Gnus buffers." - :group 'gnus-files - :type '(choice (const :tag "current" nil) - directory)) - -;; Site dependent variables. These variables should be defined in -;; paths.el. - -(defvar gnus-default-nntp-server nil - "Specify a default NNTP server. -This variable should be defined in paths.el, and should never be set -by the user. -If you want to change servers, you should use `gnus-select-method'. -See the documentation to that variable.") - -;; Don't touch this variable. -(defvar gnus-nntp-service "nntp" - "NNTP service name (\"nntp\" or 119). -This is an obsolete variable, which is scarcely used. If you use an -nntp server for your newsgroup and want to change the port number -used to 899, you would say something along these lines: - - (setq gnus-select-method '(nntp \"my.nntp.server\" (nntp-port-number 899)))") - -(defcustom gnus-nntpserver-file "/etc/nntpserver" - "A file with only the name of the nntp server in it." - :group 'gnus-files - :group 'gnus-server - :type 'file) - -;; This function is used to check both the environment variable -;; NNTPSERVER and the /etc/nntpserver file to see whether one can find -;; an nntp server name default. -(defun gnus-getenv-nntpserver () - (or (getenv "NNTPSERVER") - (and (file-readable-p gnus-nntpserver-file) - (save-excursion - (set-buffer (gnus-get-buffer-create " *gnus nntp*")) - (buffer-disable-undo (current-buffer)) - (insert-file-contents gnus-nntpserver-file) - (let ((name (buffer-string))) - (prog1 - (if (string-match "^[ \t\n]*$" name) - nil - name) - (kill-buffer (current-buffer)))))))) - -(defcustom gnus-select-method - (condition-case nil - (nconc - (list 'nntp (or (condition-case nil - (gnus-getenv-nntpserver) - (error nil)) - (when (and gnus-default-nntp-server - (not (string= gnus-default-nntp-server ""))) - gnus-default-nntp-server) - "news")) - (if (or (null gnus-nntp-service) - (equal gnus-nntp-service "nntp")) - nil - (list gnus-nntp-service))) - (error nil)) - "*Default method for selecting a newsgroup. -This variable should be a list, where the first element is how the -news is to be fetched, the second is the address. - -For instance, if you want to get your news via NNTP from -\"flab.flab.edu\", you could say: - -\(setq gnus-select-method '(nntp \"flab.flab.edu\")) - -If you want to use your local spool, say: - -\(setq gnus-select-method (list 'nnspool (system-name))) - -If you use this variable, you must set `gnus-nntp-server' to nil. - -There is a lot more to know about select methods and virtual servers - -see the manual for details." - :group 'gnus-server - :type 'gnus-select-method) - -(defcustom gnus-message-archive-method - `(nnfolder - "archive" - (nnfolder-directory ,(nnheader-concat message-directory "archive")) - (nnfolder-active-file - ,(nnheader-concat message-directory "archive/active")) - (nnfolder-get-new-mail nil) - (nnfolder-inhibit-expiry t)) - "*Method used for archiving messages you've sent. -This should be a mail method. - -It's probably not a very effective to change this variable once you've -run Gnus once. After doing that, you must edit this server from the -server buffer." - :group 'gnus-server - :group 'gnus-message - :type 'gnus-select-method) - -(defcustom gnus-message-archive-group nil - "*Name of the group in which to save the messages you've written. -This can either be a string; a list of strings; or an alist -of regexps/functions/forms to be evaluated to return a string (or a list -of strings). The functions are called with the name of the current -group (or nil) as a parameter. - -If you want to save your mail in one group and the news articles you -write in another group, you could say something like: - - \(setq gnus-message-archive-group - '((if (message-news-p) - \"misc-news\" - \"misc-mail\"))) - -Normally the group names returned by this variable should be -unprefixed -- which implicitly means \"store on the archive server\". -However, you may wish to store the message on some other server. In -that case, just return a fully prefixed name of the group -- -\"nnml+private:mail.misc\", for instance." - :group 'gnus-message - :type '(choice (const :tag "none" nil) - sexp - string)) - -(defcustom gnus-secondary-servers nil - "List of NNTP servers that the user can choose between interactively. -To make Gnus query you for a server, you have to give `gnus' a -non-numeric prefix - `C-u M-x gnus', in short." - :group 'gnus-server - :type '(repeat string)) - -(defcustom gnus-nntp-server nil - "*The name of the host running the NNTP server. -This variable is semi-obsolete. Use the `gnus-select-method' -variable instead." - :group 'gnus-server - :type '(choice (const :tag "disable" nil) - string)) - -(defcustom gnus-secondary-select-methods nil - "A list of secondary methods that will be used for reading news. -This is a list where each element is a complete select method (see -`gnus-select-method'). - -If, for instance, you want to read your mail with the nnml backend, -you could set this variable: - -\(setq gnus-secondary-select-methods '((nnml \"\")))" -:group 'gnus-server -:type '(repeat gnus-select-method)) - -(defvar gnus-backup-default-subscribed-newsgroups - '("news.announce.newusers" "news.groups.questions" "gnu.emacs.gnus") - "Default default new newsgroups the first time Gnus is run. -Should be set in paths.el, and shouldn't be touched by the user.") - -(defcustom gnus-local-domain nil - "Local domain name without a host name. -The DOMAINNAME environment variable is used instead if it is defined. -If the `system-name' function returns the full Internet name, there is -no need to set this variable." - :group 'gnus-message - :type '(choice (const :tag "default" nil) - string)) - -(defvar gnus-local-organization nil - "String with a description of what organization (if any) the user belongs to. -Obsolete variable; use `message-user-organization' instead.") - -;; Customization variables - -(defcustom gnus-refer-article-method nil - "Preferred method for fetching an article by Message-ID. -If you are reading news from the local spool (with nnspool), fetching -articles by Message-ID is painfully slow. By setting this method to an -nntp method, you might get acceptable results. - -The value of this variable must be a valid select method as discussed -in the documentation of `gnus-select-method'." - :group 'gnus-server - :type '(choice (const :tag "default" nil) - gnus-select-method)) - -(defcustom gnus-group-faq-directory - '("/ftp@mirrors.aol.com:/pub/rtfm/usenet/" - "/ftp@sunsite.auc.dk:/pub/usenet/" - "/ftp@sunsite.doc.ic.ac.uk:/pub/usenet/news-faqs/" - "/ftp@src.doc.ic.ac.uk:/usenet/news-FAQS/" - "/ftp@ftp.seas.gwu.edu:/pub/rtfm/" - "/ftp@rtfm.mit.edu:/pub/usenet/" - "/ftp@ftp.uni-paderborn.de:/pub/FAQ/" - "/ftp@ftp.sunet.se:/pub/usenet/" - "/ftp@nctuccca.edu.tw:/USENET/FAQ/" - "/ftp@hwarang.postech.ac.kr:/pub/usenet/" - "/ftp@ftp.hk.super.net:/mirror/faqs/") - "*Directory where the group FAQs are stored. -This will most commonly be on a remote machine, and the file will be -fetched by ange-ftp. - -This variable can also be a list of directories. In that case, the -first element in the list will be used by default. The others can -be used when being prompted for a site. - -Note that Gnus uses an aol machine as the default directory. If this -feels fundamentally unclean, just think of it as a way to finally get -something of value back from them. - -If the default site is too slow, try one of these: - - North America: mirrors.aol.com /pub/rtfm/usenet - ftp.seas.gwu.edu /pub/rtfm - rtfm.mit.edu /pub/usenet - Europe: ftp.uni-paderborn.de /pub/FAQ - src.doc.ic.ac.uk /usenet/news-FAQS - ftp.sunet.se /pub/usenet - sunsite.auc.dk /pub/usenet - Asia: nctuccca.edu.tw /USENET/FAQ - hwarang.postech.ac.kr /pub/usenet - ftp.hk.super.net /mirror/faqs" - :group 'gnus-group-various - :type '(choice directory - (repeat directory))) - -(defcustom gnus-use-cross-reference t - "*Non-nil means that cross referenced articles will be marked as read. -If nil, ignore cross references. If t, mark articles as read in -subscribed newsgroups. If neither t nor nil, mark as read in all -newsgroups." - :group 'gnus-server - :type '(choice (const :tag "off" nil) - (const :tag "subscribed" t) - (sexp :format "all" - :value always))) - -(defcustom gnus-process-mark ?# - "*Process mark." - :group 'gnus-group-visual - :group 'gnus-summary-marks - :type 'character) - -(defcustom gnus-asynchronous nil - "*If non-nil, Gnus will supply backends with data needed for async article fetching." - :group 'gnus-asynchronous - :type 'boolean) - -(defcustom gnus-large-newsgroup 200 - "*The number of articles which indicates a large newsgroup. -If the number of articles in a newsgroup is greater than this value, -confirmation is required for selecting the newsgroup." - :group 'gnus-group-select - :type 'integer) - -(defcustom gnus-use-long-file-name (not (memq system-type '(usg-unix-v xenix))) - "*Non-nil means that the default name of a file to save articles in is the group name. -If it's nil, the directory form of the group name is used instead. - -If this variable is a list, and the list contains the element -`not-score', long file names will not be used for score files; if it -contains the element `not-save', long file names will not be used for -saving; and if it contains the element `not-kill', long file names -will not be used for kill files. - -Note that the default for this variable varies according to what system -type you're using. On `usg-unix-v' and `xenix' this variable defaults -to nil while on all other systems it defaults to t." - :group 'gnus-start - :type 'boolean) - -(defcustom gnus-kill-files-directory gnus-directory - "*Name of the directory where kill files will be stored (default \"~/News\")." - :group 'gnus-score-files - :group 'gnus-score-kill - :type 'directory) - -(defcustom gnus-save-score nil - "*If non-nil, save group scoring info." - :group 'gnus-score-various - :group 'gnus-start - :type 'boolean) - -(defcustom gnus-use-undo t - "*If non-nil, allow undoing in Gnus group mode buffers." - :group 'gnus-meta - :type 'boolean) - -(defcustom gnus-use-adaptive-scoring nil - "*If non-nil, use some adaptive scoring scheme. -If a list, then the values `word' and `line' are meaningful. The -former will perform adaption on individual words in the subject -header while `line' will perform adaption on several headers." - :group 'gnus-meta - :group 'gnus-score-adapt - :type '(set (const word) (const line))) - -(defcustom gnus-use-cache 'passive - "*If nil, Gnus will ignore the article cache. -If `passive', it will allow entering (and reading) articles -explicitly entered into the cache. If anything else, use the -cache to the full extent of the law." - :group 'gnus-meta - :group 'gnus-cache - :type '(choice (const :tag "off" nil) - (const :tag "passive" passive) - (const :tag "active" t))) - -(defcustom gnus-use-trees nil - "*If non-nil, display a thread tree buffer." - :group 'gnus-meta - :type 'boolean) - -(defcustom gnus-use-grouplens nil - "*If non-nil, use GroupLens ratings." - :group 'gnus-meta - :type 'boolean) - -(defcustom gnus-keep-backlog nil - "*If non-nil, Gnus will keep read articles for later re-retrieval. -If it is a number N, then Gnus will only keep the last N articles -read. If it is neither nil nor a number, Gnus will keep all read -articles. This is not a good idea." - :group 'gnus-meta - :type '(choice (const :tag "off" nil) - integer - (sexp :format "all" - :value t))) - -(defcustom gnus-use-nocem nil - "*If non-nil, Gnus will read NoCeM cancel messages." - :group 'gnus-meta - :type 'boolean) - -(defcustom gnus-suppress-duplicates nil - "*If non-nil, Gnus will mark duplicate copies of the same article as read." - :group 'gnus-meta - :type 'boolean) - -(defcustom gnus-use-demon nil - "If non-nil, Gnus might use some demons." - :group 'gnus-meta - :type 'boolean) - -(defcustom gnus-use-scoring t - "*If non-nil, enable scoring." - :group 'gnus-meta - :type 'boolean) - -(defcustom gnus-use-picons nil - "*If non-nil, display picons." - :group 'gnus-meta - :type 'boolean) - -(defcustom gnus-summary-prepare-exit-hook - '(gnus-summary-expire-articles) - "*A hook called when preparing to exit from the summary buffer. -It calls `gnus-summary-expire-articles' by default." - :group 'gnus-summary-exit - :type 'hook) - -(defcustom gnus-novice-user t - "*Non-nil means that you are a usenet novice. -If non-nil, verbose messages may be displayed and confirmations may be -required." - :group 'gnus-meta - :type 'boolean) - -(defcustom gnus-expert-user nil - "*Non-nil means that you will never be asked for confirmation about anything. -That doesn't mean *anything* anything; particularly destructive -commands will still require prompting." - :group 'gnus-meta - :type 'boolean) - -(defcustom gnus-interactive-catchup t - "*If non-nil, require your confirmation when catching up a group." - :group 'gnus-group-select - :type 'boolean) - -(defcustom gnus-interactive-exit t - "*If non-nil, require your confirmation when exiting Gnus." - :group 'gnus-exit - :type 'boolean) - -(defcustom gnus-extract-address-components 'gnus-extract-address-components - "*Function for extracting address components from a From header. -Two pre-defined function exist: `gnus-extract-address-components', -which is the default, quite fast, and too simplistic solution, and -`mail-extract-address-components', which works much better, but is -slower." - :group 'gnus-summary-format - :type '(radio (function-item gnus-extract-address-components) - (function-item mail-extract-address-components) - (function-item std11-extract-address-components) - (function :tag "Other"))) - -(defcustom gnus-carpal nil - "*If non-nil, display clickable icons." - :group 'gnus-meta - :type 'boolean) - -(defcustom gnus-shell-command-separator ";" - "String used to separate to shell commands." - :group 'gnus-files - :type 'string) - -(defcustom gnus-valid-select-methods - '(("nntp" post address prompt-address physical-address) - ("nnspool" post address) - ("nnvirtual" post-mail virtual prompt-address) - ("nnmbox" mail respool address) - ("nnml" mail respool address) - ("nnmh" mail respool address) - ("nndir" post-mail prompt-address physical-address) - ("nneething" none address prompt-address physical-address) - ("nndoc" none address prompt-address) - ("nnbabyl" mail address respool) - ("nnkiboze" post virtual) - ("nnsoup" post-mail address) - ("nndraft" post-mail) - ("nnfolder" mail respool address) - ("nngateway" post-mail address prompt-address physical-address) - ("nnweb" none) - ("nnlistserv" none) - ("nnagent" post-mail)) - "*An alist of valid select methods. -The first element of each list lists should be a string with the name -of the select method. The other elements may be the category of -this method (i. e., `post', `mail', `none' or whatever) or other -properties that this method has (like being respoolable). -If you implement a new select method, all you should have to change is -this variable. I think." - :group 'gnus-server - :type '(repeat (group (string :tag "Name") - (radio-button-choice (const :format "%v " post) - (const :format "%v " mail) - (const :format "%v " none) - (const post-mail)) - (checklist :inline t - (const :format "%v " address) - (const :format "%v " prompt-address) - (const :format "%v " physical-address) - (const :format "%v " virtual) - (const respool))))) - -(define-widget 'gnus-select-method 'list - "Widget for entering a select method." - :args `((choice :tag "Method" - ,@(mapcar (lambda (entry) - (list 'const :format "%v\n" - (intern (car entry)))) - gnus-valid-select-methods)) - (string :tag "Address") - (editable-list :inline t - (list :format "%v" - variable - (sexp :tag "Value"))))) - -(defcustom gnus-updated-mode-lines '(group article summary tree) - "List of buffers that should update their mode lines. -The list may contain the symbols `group', `article', `tree' and -`summary'. If the corresponding symbol is present, Gnus will keep -that mode line updated with information that may be pertinent. -If this variable is nil, screen refresh may be quicker." - :group 'gnus-various - :type '(set (const group) - (const article) - (const summary) - (const tree))) - -;; Added by Keinonen Kari . -(defcustom gnus-mode-non-string-length nil - "*Max length of mode-line non-string contents. -If this is nil, Gnus will take space as is needed, leaving the rest -of the modeline intact. Note that the default of nil is unlikely -to be desirable; see the manual for further details." - :group 'gnus-various - :type '(choice (const nil) - integer)) - -(defcustom gnus-auto-expirable-newsgroups nil - "*Groups in which to automatically mark read articles as expirable. -If non-nil, this should be a regexp that should match all groups in -which to perform auto-expiry. This only makes sense for mail groups." - :group 'nnmail-expire - :type '(choice (const nil) - regexp)) - -(defcustom gnus-total-expirable-newsgroups nil - "*Groups in which to perform expiry of all read articles. -Use with extreme caution. All groups that match this regexp will be -expiring - which means that all read articles will be deleted after -\(say) one week. (This only goes for mail groups and the like, of -course.)" - :group 'nnmail-expire - :type '(choice (const nil) - regexp)) - -(defcustom gnus-group-uncollapsed-levels 1 - "Number of group name elements to leave alone when making a short group name." - :group 'gnus-group-visual - :type 'integer) - -(defcustom gnus-group-use-permanent-levels nil - "*If non-nil, once you set a level, Gnus will use this level." - :group 'gnus-group-levels - :type 'boolean) - -;; Hooks. - -(defcustom gnus-load-hook nil - "A hook run while Gnus is loaded." - :group 'gnus-start - :type 'hook) - -(defcustom gnus-apply-kill-hook '(gnus-apply-kill-file) - "A hook called to apply kill files to a group. -This hook is intended to apply a kill file to the selected newsgroup. -The function `gnus-apply-kill-file' is called by default. - -Since a general kill file is too heavy to use only for a few -newsgroups, I recommend you to use a lighter hook function. For -example, if you'd like to apply a kill file to articles which contains -a string `rmgroup' in subject in newsgroup `control', you can use the -following hook: - - (setq gnus-apply-kill-hook - (list - (lambda () - (cond ((string-match \"control\" gnus-newsgroup-name) - (gnus-kill \"Subject\" \"rmgroup\") - (gnus-expunge \"X\"))))))" - :group 'gnus-score-kill - :options '(gnus-apply-kill-file) - :type 'hook) - -(defcustom gnus-group-change-level-function nil - "Function run when a group level is changed. -It is called with three parameters -- GROUP, LEVEL and OLDLEVEL." - :group 'gnus-group-level - :type 'function) - -;;; Face thingies. - -(defcustom gnus-visual - '(summary-highlight group-highlight article-highlight - mouse-face - summary-menu group-menu article-menu - tree-highlight menu highlight - browse-menu server-menu - page-marker tree-menu binary-menu pick-menu - grouplens-menu) - "*Enable visual features. -If `visual' is disabled, there will be no menus and few faces. Most of -the visual customization options below will be ignored. Gnus will use -less space and be faster as a result. - -This variable can also be a list of visual elements to switch on. For -instance, to switch off all visual things except menus, you can say: - - (setq gnus-visual '(menu)) - -Valid elements include `summary-highlight', `group-highlight', -`article-highlight', `mouse-face', `summary-menu', `group-menu', -`article-menu', `tree-highlight', `menu', `highlight', `browse-menu', -`server-menu', `page-marker', `tree-menu', `binary-menu', `pick-menu', -and `grouplens-menu'." - :group 'gnus-meta - :group 'gnus-visual - :type '(set (const summary-highlight) - (const group-highlight) - (const article-highlight) - (const mouse-face) - (const summary-menu) - (const group-menu) - (const article-menu) - (const tree-highlight) - (const menu) - (const highlight) - (const browse-menu) - (const server-menu) - (const page-marker) - (const tree-menu) - (const binary-menu) - (const pick-menu) - (const grouplens-menu))) - -(defcustom gnus-mouse-face - (condition-case () - (if (gnus-visual-p 'mouse-face 'highlight) - (if (boundp 'gnus-mouse-face) - (or gnus-mouse-face 'highlight) - 'highlight) - 'default) - (error 'highlight)) - "*Face used for group or summary buffer mouse highlighting. -The line beneath the mouse pointer will be highlighted with this -face." - :group 'gnus-visual - :type 'face) - -(defcustom gnus-article-display-hook - (if (and (string-match "XEmacs" emacs-version) - (featurep 'xface)) - '(gnus-article-hide-headers-if-wanted - gnus-article-hide-boring-headers - gnus-article-treat-overstrike - gnus-article-maybe-highlight - gnus-article-display-x-face) - '(gnus-article-hide-headers-if-wanted - gnus-article-hide-boring-headers - gnus-article-treat-overstrike - gnus-article-maybe-highlight)) - "*Controls how the article buffer will look. - -If you leave the list empty, the article will appear exactly as it is -stored on the disk. The list entries will hide or highlight various -parts of the article, making it easier to find the information you -want." - :group 'gnus-article-highlight - :group 'gnus-visual - :type 'hook - :options '(gnus-article-add-buttons - gnus-article-add-buttons-to-head - gnus-article-emphasize - gnus-article-fill-cited-article - gnus-article-remove-cr - gnus-summary-stop-page-breaking - ;; gnus-summary-caesar-message - ;; gnus-summary-verbose-headers - gnus-summary-toggle-mime - gnus-article-hide - gnus-article-hide-headers - gnus-article-hide-boring-headers - gnus-article-hide-signature - gnus-article-hide-citation - gnus-article-hide-pgp - gnus-article-hide-pem - gnus-article-highlight - gnus-article-highlight-headers - gnus-article-highlight-citation - gnus-article-highlight-signature - gnus-article-date-ut - gnus-article-date-local - gnus-article-date-lapsed - gnus-article-date-original - gnus-article-remove-trailing-blank-lines - gnus-article-strip-leading-blank-lines - gnus-article-strip-multiple-blank-lines - gnus-article-strip-blank-lines - gnus-article-treat-overstrike - gnus-article-display-x-face - gnus-smiley-display)) - -(defcustom gnus-article-save-directory gnus-directory - "*Name of the directory articles will be saved in (default \"~/News\")." - :group 'gnus-article-saving - :type 'directory) - -(defvar gnus-plugged t - "Whether Gnus is plugged or not.") - - -;;; Internal variables - -(defvar gnus-group-get-parameter-function 'gnus-group-get-parameter) -(defvar gnus-original-article-buffer " *Original Article*") -(defvar gnus-newsgroup-name nil) -(defvar gnus-ephemeral-servers nil) - -(defvar gnus-agent nil - "Whether we want to use the Gnus agent or not.") - -(defvar gnus-command-method nil - "Dynamically bound variable that says what the current backend is.") - -(defvar gnus-current-select-method nil - "The current method for selecting a newsgroup.") - -(defvar gnus-tree-buffer "*Tree*" - "Buffer where Gnus thread trees are displayed.") - -;; Dummy variable. -(defvar gnus-use-generic-from nil) - -;; Variable holding the user answers to all method prompts. -(defvar gnus-method-history nil) - -;; Variable holding the user answers to all mail method prompts. -(defvar gnus-mail-method-history nil) - -;; Variable holding the user answers to all group prompts. -(defvar gnus-group-history nil) - -(defvar gnus-server-alist nil - "List of available servers.") - -(defcustom gnus-cache-directory - (nnheader-concat gnus-directory "cache/") - "*The directory where cached articles will be stored." - :group 'gnus-cache - :type 'directory) - -(defvar gnus-predefined-server-alist - `(("cache" - nnspool "cache" - (nnspool-spool-directory ,gnus-cache-directory) - (nnspool-nov-directory ,gnus-cache-directory) - (nnspool-active-file - ,(nnheader-concat gnus-cache-directory "active")))) - "List of predefined (convenience) servers.") - -(defvar gnus-topic-indentation "") ;; Obsolete variable. - -(defconst gnus-article-mark-lists - '((marked . tick) (replied . reply) - (expirable . expire) (killed . killed) - (bookmarks . bookmark) (dormant . dormant) - (scored . score) (saved . save) - (cached . cache) (downloadable . download) - (unsendable . unsend))) - -(defvar gnus-headers-retrieved-by nil) -(defvar gnus-article-reply nil) -(defvar gnus-override-method nil) -(defvar gnus-article-check-size nil) -(defvar gnus-opened-servers nil) - -(defvar gnus-current-kill-article nil) - -(defvar gnus-have-read-active-file nil) - -(defconst gnus-maintainer - "bugs@gnus.org (The Gnus Bugfixing Girls + Boys)" - "The mail address of the Gnus maintainers.") - -(defconst semi-gnus-developers - "Semi-gnus Developers: - semi-gnus-en@meadow.scphys.kyoto-u.ac.jp (In English),\ - semi-gnus-ja@meadow.scphys.kyoto-u.ac.jp (In Japanese);" - "The mail address of the Semi-gnus developers.") - -(defvar gnus-info-nodes - '((gnus-group-mode "(gnus)The Group Buffer") - (gnus-summary-mode "(gnus)The Summary Buffer") - (gnus-article-mode "(gnus)The Article Buffer") - (mime/viewer-mode "(gnus)The Article Buffer") - (gnus-server-mode "(gnus)The Server Buffer") - (gnus-browse-mode "(gnus)Browse Foreign Server") - (gnus-tree-mode "(gnus)Tree Display")) - "Alist of major modes and related Info nodes.") - -(defvar gnus-group-buffer "*Group*") -(defvar gnus-summary-buffer "*Summary*") -(defvar gnus-article-buffer "*Article*") -(defvar gnus-server-buffer "*Server*") - -(defvar gnus-slave nil - "Whether this Gnus is a slave or not.") - -(defvar gnus-batch-mode nil - "Whether this Gnus is running in batch mode or not.") - -(defvar gnus-variable-list - '(gnus-newsrc-options gnus-newsrc-options-n - gnus-newsrc-last-checked-date - gnus-newsrc-alist gnus-server-alist - gnus-killed-list gnus-zombie-list - gnus-topic-topology gnus-topic-alist - gnus-format-specs) - "Gnus variables saved in the quick startup file.") - -(defvar gnus-newsrc-alist nil - "Assoc list of read articles. -gnus-newsrc-hashtb should be kept so that both hold the same information.") - -(defvar gnus-newsrc-hashtb nil - "Hashtable of gnus-newsrc-alist.") - -(defvar gnus-killed-list nil - "List of killed newsgroups.") - -(defvar gnus-killed-hashtb nil - "Hash table equivalent of gnus-killed-list.") - -(defvar gnus-zombie-list nil - "List of almost dead newsgroups.") - -(defvar gnus-description-hashtb nil - "Descriptions of newsgroups.") - -(defvar gnus-list-of-killed-groups nil - "List of newsgroups that have recently been killed by the user.") - -(defvar gnus-active-hashtb nil - "Hashtable of active articles.") - -(defvar gnus-moderated-hashtb nil - "Hashtable of moderated newsgroups.") - -;; Save window configuration. -(defvar gnus-prev-winconf nil) - -(defvar gnus-reffed-article-number nil) - -;;; Let the byte-compiler know that we know about this variable. -(defvar rmail-default-rmail-file) - -(defvar gnus-dead-summary nil) - -;;; End of variables. - -;; Define some autoload functions Gnus might use. -(eval-and-compile - - ;; This little mapcar goes through the list below and marks the - ;; symbols in question as autoloaded functions. - (mapcar - (lambda (package) - (let ((interactive (nth 1 (memq ':interactive package)))) - (mapcar - (lambda (function) - (let (keymap) - (when (consp function) - (setq keymap (car (memq 'keymap function))) - (setq function (car function))) - (autoload function (car package) nil interactive keymap))) - (if (eq (nth 1 package) ':interactive) - (cdddr package) - (cdr package))))) - '(("info" Info-goto-node) - ("hexl" hexl-hex-string-to-integer) - ("pp" pp pp-to-string pp-eval-expression) - ("ps-print" ps-print-preprint) - ("mail-extr" mail-extract-address-components) - ("browse-url" browse-url) - ("message" :interactive t - message-send-and-exit message-yank-original) - ("nnmail" nnmail-split-fancy nnmail-article-group nnmail-date-to-time) - ("nnvirtual" nnvirtual-catchup-group nnvirtual-convert-headers) - ("timezone" timezone-make-date-arpa-standard timezone-fix-time - timezone-make-sortable-date timezone-make-time-string) - ("rmailout" rmail-output) - ("rmail" rmail-insert-rmail-file-header rmail-count-new-messages - rmail-show-message) - ("gnus-audio" :interactive t gnus-audio-play) - ("gnus-xmas" gnus-xmas-splash) - ("gnus-soup" :interactive t - gnus-group-brew-soup gnus-brew-soup gnus-soup-add-article - gnus-soup-send-replies gnus-soup-save-areas gnus-soup-pack-packet) - ("nnsoup" nnsoup-pack-replies) - ("score-mode" :interactive t gnus-score-mode) - ("gnus-mh" gnus-summary-save-article-folder - gnus-Folder-save-name gnus-folder-save-name) - ("gnus-mh" :interactive t gnus-summary-save-in-folder) - ("gnus-demon" gnus-demon-add-nocem gnus-demon-add-scanmail - gnus-demon-add-rescan gnus-demon-add-scan-timestamps - gnus-demon-add-disconnection gnus-demon-add-handler - gnus-demon-remove-handler) - ("gnus-demon" :interactive t - gnus-demon-init gnus-demon-cancel) - ("gnus-salt" gnus-highlight-selected-tree gnus-possibly-generate-tree - gnus-tree-open gnus-tree-close gnus-carpal-setup-buffer) - ("gnus-nocem" gnus-nocem-scan-groups gnus-nocem-close - gnus-nocem-unwanted-article-p) - ("gnus-srvr" gnus-enter-server-buffer gnus-server-set-info - gnus-server-server-name) - ("gnus-srvr" gnus-browse-foreign-server) - ("gnus-cite" :interactive t - gnus-article-highlight-citation gnus-article-hide-citation-maybe - gnus-article-hide-citation gnus-article-fill-cited-article - gnus-article-hide-citation-in-followups) - ("gnus-kill" gnus-kill gnus-apply-kill-file-internal - gnus-kill-file-edit-file gnus-kill-file-raise-followups-to-author - gnus-execute gnus-expunge) - ("gnus-cache" gnus-cache-possibly-enter-article gnus-cache-save-buffers - gnus-cache-possibly-remove-articles gnus-cache-request-article - gnus-cache-retrieve-headers gnus-cache-possibly-alter-active - gnus-cache-enter-remove-article gnus-cached-article-p - gnus-cache-open gnus-cache-close gnus-cache-update-article) - ("gnus-cache" :interactive t gnus-jog-cache gnus-cache-enter-article - gnus-cache-remove-article gnus-summary-insert-cached-articles) - ("gnus-score" :interactive t - gnus-summary-increase-score gnus-summary-set-score - gnus-summary-raise-thread gnus-summary-raise-same-subject - gnus-summary-raise-score gnus-summary-raise-same-subject-and-select - gnus-summary-lower-thread gnus-summary-lower-same-subject - gnus-summary-lower-score gnus-summary-lower-same-subject-and-select - gnus-summary-current-score gnus-score-default - gnus-score-flush-cache gnus-score-close - gnus-possibly-score-headers gnus-score-followup-article - gnus-score-followup-thread) - ("gnus-score" - (gnus-summary-score-map keymap) gnus-score-save gnus-score-headers - gnus-current-score-file-nondirectory gnus-score-adaptive - gnus-score-find-trace gnus-score-file-name) - ("gnus-cus" :interactive t gnus-group-customize gnus-score-customize) - ("gnus-topic" :interactive t gnus-topic-mode) - ("gnus-topic" gnus-topic-remove-group gnus-topic-set-parameters) - ("gnus-salt" :interactive t gnus-pick-mode gnus-binary-mode) - ("gnus-uu" (gnus-uu-extract-map keymap) (gnus-uu-mark-map keymap)) - ("gnus-uu" :interactive t - gnus-uu-digest-mail-forward gnus-uu-digest-post-forward - gnus-uu-mark-series gnus-uu-mark-region gnus-uu-mark-buffer - gnus-uu-mark-by-regexp gnus-uu-mark-all - gnus-uu-mark-sparse gnus-uu-mark-thread gnus-uu-decode-uu - gnus-uu-decode-uu-and-save gnus-uu-decode-unshar - gnus-uu-decode-unshar-and-save gnus-uu-decode-save - gnus-uu-decode-binhex gnus-uu-decode-uu-view - gnus-uu-decode-uu-and-save-view gnus-uu-decode-unshar-view - gnus-uu-decode-unshar-and-save-view gnus-uu-decode-save-view - gnus-uu-decode-binhex-view gnus-uu-unmark-thread - gnus-uu-mark-over gnus-uu-post-news gnus-uu-post-news) - ("gnus-uu" gnus-uu-delete-work-dir gnus-quote-arg-for-sh-or-csh - gnus-uu-unmark-thread) - ("gnus-msg" (gnus-summary-send-map keymap) - gnus-article-mail gnus-copy-article-buffer gnus-extended-version) - ("gnus-msg" :interactive t - gnus-group-post-news gnus-group-mail gnus-summary-post-news - gnus-summary-followup gnus-summary-followup-with-original - gnus-summary-cancel-article gnus-summary-supersede-article - gnus-post-news gnus-summary-reply gnus-summary-reply-with-original - gnus-summary-mail-forward gnus-summary-mail-other-window - gnus-summary-resend-message gnus-summary-resend-bounced-mail - gnus-summary-wide-reply gnus-summary-followup-to-mail - gnus-summary-followup-to-mail-with-original gnus-bug - gnus-summary-wide-reply-with-original - gnus-summary-post-forward gnus-summary-wide-reply-with-original - gnus-summary-post-forward) - ("gnus-picon" :interactive t gnus-article-display-picons - gnus-group-display-picons gnus-picons-article-display-x-face - gnus-picons-display-x-face) - ("gnus-gl" bbb-login bbb-logout bbb-grouplens-group-p - gnus-grouplens-mode) - ("smiley" :interactive t gnus-smiley-display) - ("gnus-win" gnus-configure-windows gnus-add-configuration) - ("gnus-sum" gnus-summary-insert-line gnus-summary-read-group - gnus-list-of-unread-articles gnus-list-of-read-articles - gnus-offer-save-summaries gnus-make-thread-indent-array - gnus-summary-exit gnus-update-read-articles gnus-summary-last-subject - gnus-summary-skip-intangible gnus-summary-article-number - gnus-data-header gnus-data-find) - ("gnus-group" gnus-group-insert-group-line gnus-group-quit - gnus-group-list-groups gnus-group-first-unread-group - gnus-group-set-mode-line gnus-group-set-info gnus-group-save-newsrc - gnus-group-setup-buffer gnus-group-get-new-news - gnus-group-make-help-group gnus-group-update-group - gnus-clear-inboxes-moved gnus-group-iterate - gnus-group-group-name) - ("gnus-bcklg" gnus-backlog-request-article gnus-backlog-enter-article - gnus-backlog-remove-article) - ("gnus-art" gnus-article-read-summary-keys gnus-article-save - gnus-article-prepare gnus-article-set-window-start - gnus-article-next-page gnus-article-prev-page - gnus-request-article-this-buffer gnus-article-mode - gnus-article-setup-buffer gnus-narrow-to-page - gnus-article-delete-invisible-text gnus-hack-decode-rfc1522) - ("gnus-art" :interactive t - gnus-article-hide-headers gnus-article-hide-boring-headers - gnus-article-treat-overstrike gnus-article-word-wrap - gnus-article-remove-cr gnus-article-remove-trailing-blank-lines - gnus-article-display-x-face - gnus-article-mime-decode-quoted-printable gnus-article-hide-pgp - gnus-article-hide-pem gnus-article-hide-signature - gnus-article-strip-leading-blank-lines gnus-article-date-local - gnus-article-date-original gnus-article-date-lapsed - gnus-article-show-all-headers - gnus-article-edit-mode gnus-article-edit-article - gnus-article-edit-done gnus-decode-rfc1522 article-decode-rfc1522 - gnus-start-date-timer gnus-stop-date-timer) - ("gnus-int" gnus-request-type) - ("gnus-start" gnus-newsrc-parse-options gnus-1 gnus-no-server-1 - gnus-dribble-enter gnus-read-init-file gnus-dribble-touch) - ("gnus-dup" gnus-dup-suppress-articles gnus-dup-unsuppress-article - gnus-dup-enter-articles) - ("gnus-range" gnus-copy-sequence) - ("gnus-eform" gnus-edit-form) - ("gnus-move" :interactive t - gnus-group-move-group-to-server gnus-change-server) - ("gnus-logic" gnus-score-advanced) - ("gnus-undo" gnus-undo-mode gnus-undo-register) - ("gnus-async" gnus-async-request-fetched-article gnus-async-prefetch-next - gnus-async-prefetch-article gnus-async-prefetch-remove-group - gnus-async-halt-prefetch) - ("gnus-agent" gnus-open-agent gnus-agent-get-function - gnus-agent-save-groups gnus-agent-save-active gnus-agent-method-p - gnus-agent-get-undownloaded-list gnus-agent-fetch-session - gnus-summary-set-agent-mark gnus-agent-save-group-info) - ("gnus-agent" :interactive t - gnus-unplugged gnus-agentize gnus-agent-batch) - ("gnus-vm" :interactive t gnus-summary-save-in-vm - gnus-summary-save-article-vm) - ("gnus-draft" :interactive t gnus-draft-mode gnus-group-send-drafts)))) - -;;; gnus-sum.el thingies - - -(defcustom gnus-summary-line-format "%U%R%z%I%(%[%4L: %-20,20n%]%) %s\n" - "*The format specification of the lines in the summary buffer. - -It works along the same lines as a normal formatting string, -with some simple extensions. - -%N Article number, left padded with spaces (string) -%S Subject (string) -%s Subject if it is at the root of a thread, and \"\" otherwise (string) -%n Name of the poster (string) -%a Extracted name of the poster (string) -%A Extracted address of the poster (string) -%F Contents of the From: header (string) -%x Contents of the Xref: header (string) -%D Date of the article (string) -%d Date of the article (string) in DD-MMM format -%M Message-id of the article (string) -%r References of the article (string) -%c Number of characters in the article (integer) -%L Number of lines in the article (integer) -%I Indentation based on thread level (a string of spaces) -%T A string with two possible values: 80 spaces if the article - is on thread level two or larger and 0 spaces on level one -%R \"A\" if this article has been replied to, \" \" otherwise (character) -%U Status of this article (character, \"R\", \"K\", \"-\" or \" \") -%[ Opening bracket (character, \"[\" or \"<\") -%] Closing bracket (character, \"]\" or \">\") -%> Spaces of length thread-level (string) -%< Spaces of length (- 20 thread-level) (string) -%i Article score (number) -%z Article zcore (character) -%t Number of articles under the current thread (number). -%e Whether the thread is empty or not (character). -%l GroupLens score (string). -%V Total thread score (number). -%P The line number (number). -%O Download mark (character). -%u User defined specifier. The next character in the format string should - be a letter. Gnus will call the function gnus-user-format-function-X, - where X is the letter following %u. The function will be passed the - current header as argument. The function should return a string, which - will be inserted into the summary just like information from any other - summary specifier. - -Text between %( and %) will be highlighted with `gnus-mouse-face' -when the mouse point is placed inside the area. There can only be one -such area. - -The %U (status), %R (replied) and %z (zcore) specs have to be handled -with care. For reasons of efficiency, Gnus will compute what column -these characters will end up in, and \"hard-code\" that. This means that -it is illegal to have these specs after a variable-length spec. Well, -you might not be arrested, but your summary buffer will look strange, -which is bad enough. - -The smart choice is to have these specs as for to the left as -possible. - -This restriction may disappear in later versions of Gnus." - :type 'string - :group 'gnus-summary-format) - -;;; -;;; Skeleton keymaps -;;; - -(defun gnus-suppress-keymap (keymap) - (suppress-keymap keymap) - (let ((keys `([backspace] [delete] "\177" "\M-u"))) ;gnus-mouse-2 - (while keys - (define-key keymap (pop keys) 'undefined)))) - -(defvar gnus-article-mode-map - (let ((keymap (make-keymap))) - (gnus-suppress-keymap keymap) - keymap)) -(defvar gnus-summary-mode-map - (let ((keymap (make-keymap))) - (gnus-suppress-keymap keymap) - keymap)) -(defvar gnus-group-mode-map - (let ((keymap (make-keymap))) - (gnus-suppress-keymap keymap) - keymap)) - - - -;; Fix by Hallvard B Furuseth . -;; If you want the cursor to go somewhere else, set these two -;; functions in some startup hook to whatever you want. -(defalias 'gnus-summary-position-point 'gnus-goto-colon) -(defalias 'gnus-group-position-point 'gnus-goto-colon) - -;;; Various macros and substs. - -(defun gnus-header-from (header) - (mail-header-from header)) - -(defmacro gnus-gethash (string hashtable) - "Get hash value of STRING in HASHTABLE." - `(symbol-value (intern-soft ,string ,hashtable))) - -(defmacro gnus-sethash (string value hashtable) - "Set hash value. Arguments are STRING, VALUE, and HASHTABLE." - `(set (intern ,string ,hashtable) ,value)) -(put 'gnus-sethash 'edebug-form-spec '(form form form)) - -(defmacro gnus-group-unread (group) - "Get the currently computed number of unread articles in GROUP." - `(car (gnus-gethash ,group gnus-newsrc-hashtb))) - -(defmacro gnus-group-entry (group) - "Get the newsrc entry for GROUP." - `(gnus-gethash ,group gnus-newsrc-hashtb)) - -(defmacro gnus-active (group) - "Get active info on GROUP." - `(gnus-gethash ,group gnus-active-hashtb)) - -(defmacro gnus-set-active (group active) - "Set GROUP's active info." - `(gnus-sethash ,group ,active gnus-active-hashtb)) - -;; Info access macros. - -(defmacro gnus-info-group (info) - `(nth 0 ,info)) -(defmacro gnus-info-rank (info) - `(nth 1 ,info)) -(defmacro gnus-info-read (info) - `(nth 2 ,info)) -(defmacro gnus-info-marks (info) - `(nth 3 ,info)) -(defmacro gnus-info-method (info) - `(nth 4 ,info)) -(defmacro gnus-info-params (info) - `(nth 5 ,info)) - -(defmacro gnus-info-level (info) - `(let ((rank (gnus-info-rank ,info))) - (if (consp rank) - (car rank) - rank))) -(defmacro gnus-info-score (info) - `(let ((rank (gnus-info-rank ,info))) - (or (and (consp rank) (cdr rank)) 0))) - -(defmacro gnus-info-set-group (info group) - `(setcar ,info ,group)) -(defmacro gnus-info-set-rank (info rank) - `(setcar (nthcdr 1 ,info) ,rank)) -(defmacro gnus-info-set-read (info read) - `(setcar (nthcdr 2 ,info) ,read)) -(defmacro gnus-info-set-marks (info marks &optional extend) - (if extend - `(gnus-info-set-entry ,info ,marks 3) - `(setcar (nthcdr 3 ,info) ,marks))) -(defmacro gnus-info-set-method (info method &optional extend) - (if extend - `(gnus-info-set-entry ,info ,method 4) - `(setcar (nthcdr 4 ,info) ,method))) -(defmacro gnus-info-set-params (info params &optional extend) - (if extend - `(gnus-info-set-entry ,info ,params 5) - `(setcar (nthcdr 5 ,info) ,params))) - -(defun gnus-info-set-entry (info entry number) - ;; Extend the info until we have enough elements. - (while (<= (length info) number) - (nconc info (list nil))) - ;; Set the entry. - (setcar (nthcdr number info) entry)) - -(defmacro gnus-info-set-level (info level) - `(let ((rank (cdr ,info))) - (if (consp (car rank)) - (setcar (car rank) ,level) - (setcar rank ,level)))) -(defmacro gnus-info-set-score (info score) - `(let ((rank (cdr ,info))) - (if (consp (car rank)) - (setcdr (car rank) ,score) - (setcar rank (cons (car rank) ,score))))) - -(defmacro gnus-get-info (group) - `(nth 2 (gnus-gethash ,group gnus-newsrc-hashtb))) - -;; Byte-compiler warning. -(defvar gnus-visual) -;; Find out whether the gnus-visual TYPE is wanted. -(defun gnus-visual-p (&optional type class) - (and gnus-visual ; Has to be non-nil, at least. - (if (not type) ; We don't care about type. - gnus-visual - (if (listp gnus-visual) ; It's a list, so we check it. - (or (memq type gnus-visual) - (memq class gnus-visual)) - t)))) - -;;; Load the compatability functions. - -(require 'gnus-ems) - - -;;; -;;; Shutdown -;;; - -(defvar gnus-shutdown-alist nil) - -(defun gnus-add-shutdown (function &rest symbols) - "Run FUNCTION whenever one of SYMBOLS is shut down." - (push (cons function symbols) gnus-shutdown-alist)) - -(defun gnus-shutdown (symbol) - "Shut down everything that waits for SYMBOL." - (let ((alist gnus-shutdown-alist) - entry) - (while (setq entry (pop alist)) - (when (memq symbol (cdr entry)) - (funcall (car entry)))))) - - -;;; -;;; Gnus Utility Functions -;;; - - -(defmacro gnus-string-or (&rest strings) - "Return the first element of STRINGS that is a non-blank string. -STRINGS will be evaluated in normal `or' order." - `(gnus-string-or-1 ',strings)) - -(defun gnus-string-or-1 (strings) - (let (string) - (while strings - (setq string (eval (pop strings))) - (if (string-match "^[ \t]*$" string) - (setq string nil) - (setq strings nil))) - string)) - -(defun gnus-version (&optional arg) - "Version number of this version of Gnus. -If ARG, insert string at point." - (interactive "P") - (if arg - (insert (message gnus-version)) - (message gnus-version))) - -(defun gnus-continuum-version (version) - "Return VERSION as a floating point number." - (when (or (string-match "^\\([^ ]+\\)? ?Gnus v?\\([0-9.]+\\)$" version) - (string-match "^\\(.?\\)gnus-\\([0-9.]+\\)$" version)) - (let ((alpha (and (match-beginning 1) (match-string 1 version))) - (number (match-string 2 version)) - major minor least) - (unless (string-match - "\\([0-9]\\)\\.\\([0-9]+\\)\\.?\\([0-9]+\\)?" number) - (error "Invalid version string: %s" version)) - (setq major (string-to-number (match-string 1 number)) - minor (string-to-number (match-string 2 number)) - least (if (match-beginning 3) - (string-to-number (match-string 3 number)) - 0)) - (string-to-number - (if (zerop major) - (format "%s00%02d%02d" - (cond - ((member alpha '("(ding)" "d")) "4.99") - ((member alpha '("September" "s")) "5.01") - ((member alpha '("Red" "r")) "5.03") - ((member alpha '("Quassia" "q")) "5.05") - ((member alpha '("p")) "5.07") - ((member alpha '("o")) "5.09") - ((member alpha '("n")) "5.11")) - minor least) - (format "%d.%02d%02d" major minor least)))))) - -(defun gnus-info-find-node () - "Find Info documentation of Gnus." - (interactive) - ;; Enlarge info window if needed. - (let (gnus-info-buffer) - (Info-goto-node (cadr (assq major-mode gnus-info-nodes))) - (setq gnus-info-buffer (current-buffer)) - (gnus-configure-windows 'info))) - -;;; -;;; gnus-interactive -;;; - -(defvar gnus-current-prefix-symbol nil - "Current prefix symbol.") - -(defvar gnus-current-prefix-symbols nil - "List of current prefix symbols.") - -(defun gnus-interactive (string &optional params) - "Return a list that can be fed to `interactive'. -See `interactive' for full documentation. - -Adds the following specs: - -y -- The current symbolic prefix. -Y -- A list of the current symbolic prefix(es). -A -- Article number. -H -- Article header. -g -- Group name." - (let ((i 0) - out c prompt) - (while (< i (length string)) - (string-match ".\\([^\n]*\\)\n?" string i) - (setq c (aref string i)) - (when (match-end 1) - (setq prompt (match-string 1 string))) - (setq i (match-end 0)) - ;; We basically emulate just about everything that - ;; `interactive' does, but add the specs listed above. - (push - (cond - ((= c ?a) - (completing-read prompt obarray 'fboundp t)) - ((= c ?b) - (read-buffer prompt (current-buffer) t)) - ((= c ?B) - (read-buffer prompt (other-buffer (current-buffer)))) - ((= c ?c) - (read-char)) - ((= c ?C) - (completing-read prompt obarray 'commandp t)) - ((= c ?d) - (point)) - ((= c ?D) - (read-file-name prompt nil default-directory 'lambda)) - ((= c ?f) - (read-file-name prompt nil nil 'lambda)) - ((= c ?F) - (read-file-name prompt)) - ((= c ?k) - (read-key-sequence prompt)) - ((= c ?K) - (error "Not implemented spec")) - ((= c ?e) - (error "Not implemented spec")) - ((= c ?m) - (mark)) - ((= c ?N) - (error "Not implemented spec")) - ((= c ?n) - (string-to-number (read-from-minibuffer prompt))) - ((= c ?p) - (prefix-numeric-value current-prefix-arg)) - ((= c ?P) - current-prefix-arg) - ((= c ?r) - 'gnus-prefix-nil) - ((= c ?s) - (read-string prompt)) - ((= c ?S) - (intern (read-string prompt))) - ((= c ?v) - (read-variable prompt)) - ((= c ?x) - (read-minibuffer prompt)) - ((= c ?x) - (eval-minibuffer prompt)) - ;; And here the new specs come. - ((= c ?y) - gnus-current-prefix-symbol) - ((= c ?Y) - gnus-current-prefix-symbols) - ((= c ?g) - (gnus-group-group-name)) - ((= c ?A) - (gnus-summary-skip-intangible) - (or (get-text-property (point) 'gnus-number) - (gnus-summary-last-subject))) - ((= c ?H) - (gnus-data-header (gnus-data-find (gnus-summary-article-number)))) - (t - (error "Non-implemented spec"))) - out) - (cond - ((= c ?r) - (push (if (< (point) (mark) (point) (mark))) out) - (push (if (> (point) (mark) (point) (mark))) out)))) - (setq out (delq 'gnus-prefix-nil out)) - (nreverse out))) - -(defun gnus-symbolic-argument (&optional arg) - "Read a symbolic argument and a command, and then execute command." - (interactive "P") - (let* ((in-command (this-command-keys)) - (command in-command) - gnus-current-prefix-symbols - gnus-current-prefix-symbol - syms) - (while (equal in-command command) - (message "%s-" (key-description (this-command-keys))) - (push (intern (char-to-string (read-char))) syms) - (setq command (read-key-sequence nil t))) - (setq gnus-current-prefix-symbols (nreverse syms) - gnus-current-prefix-symbol (car gnus-current-prefix-symbols)) - (call-interactively (key-binding command t)))) - -;;; More various functions. - -(defsubst gnus-check-backend-function (func group) - "Check whether GROUP supports function FUNC. -GROUP can either be a string (a group name) or a select method." - (ignore-errors - (let ((method (if (stringp group) - (car (gnus-find-method-for-group group)) - group))) - (unless (featurep method) - (require method)) - (fboundp (intern (format "%s-%s" method func)))))) - -(defun gnus-group-read-only-p (&optional group) - "Check whether GROUP supports editing or not. -If GROUP is nil, `gnus-newsgroup-name' will be checked instead. Note -that that variable is buffer-local to the summary buffers." - (let ((group (or group gnus-newsgroup-name))) - (not (gnus-check-backend-function 'request-replace-article group)))) - -(defun gnus-group-total-expirable-p (group) - "Check whether GROUP is total-expirable or not." - (let ((params (gnus-group-find-parameter group)) - val) - (cond - ((memq 'total-expire params) - t) - ((setq val (assq 'total-expire params)) ; (auto-expire . t) - (cdr val)) - (gnus-total-expirable-newsgroups ; Check var. - (string-match gnus-total-expirable-newsgroups group))))) - -(defun gnus-group-auto-expirable-p (group) - "Check whether GROUP is auto-expirable or not." - (let ((params (gnus-group-find-parameter group)) - val) - (cond - ((memq 'auto-expire params) - t) - ((setq val (assq 'auto-expire params)) ; (auto-expire . t) - (cdr val)) - (gnus-auto-expirable-newsgroups ; Check var. - (string-match gnus-auto-expirable-newsgroups group))))) - -(defun gnus-virtual-group-p (group) - "Say whether GROUP is virtual or not." - (memq 'virtual (assoc (symbol-name (car (gnus-find-method-for-group group))) - gnus-valid-select-methods))) - -(defun gnus-news-group-p (group &optional article) - "Return non-nil if GROUP (and ARTICLE) come from a news server." - (or (gnus-member-of-valid 'post group) ; Ordinary news group. - (and (gnus-member-of-valid 'post-mail group) ; Combined group. - (if (or (null article) - (not (< article 0))) - (eq (gnus-request-type group article) 'news) - (if (not (vectorp article)) - nil - ;; It's a real article. - (eq (gnus-request-type group (mail-header-id article)) - 'news)))))) - -;; Returns a list of writable groups. -(defun gnus-writable-groups () - (let ((alist gnus-newsrc-alist) - groups group) - (while (setq group (car (pop alist))) - (unless (gnus-group-read-only-p group) - (push group groups))) - (nreverse groups))) - -;; Check whether to use long file names. -(defun gnus-use-long-file-name (symbol) - ;; The variable has to be set... - (and gnus-use-long-file-name - ;; If it isn't a list, then we return t. - (or (not (listp gnus-use-long-file-name)) - ;; If it is a list, and the list contains `symbol', we - ;; return nil. - (not (memq symbol gnus-use-long-file-name))))) - -;; Generate a unique new group name. -(defun gnus-generate-new-group-name (leaf) - (let ((name leaf) - (num 0)) - (while (gnus-gethash name gnus-newsrc-hashtb) - (setq name (concat leaf "<" (int-to-string (setq num (1+ num))) ">"))) - name)) - -(defun gnus-ephemeral-group-p (group) - "Say whether GROUP is ephemeral or not." - (gnus-group-get-parameter group 'quit-config t)) - -(defun gnus-group-quit-config (group) - "Return the quit-config of GROUP." - (gnus-group-get-parameter group 'quit-config t)) - -(defun gnus-kill-ephemeral-group (group) - "Remove ephemeral GROUP from relevant structures." - (gnus-sethash group nil gnus-newsrc-hashtb)) - -(defun gnus-simplify-mode-line () - "Make mode lines a bit simpler." - (setq mode-line-modified (cdr gnus-mode-line-modified)) - (when (listp mode-line-format) - (make-local-variable 'mode-line-format) - (setq mode-line-format (copy-sequence mode-line-format)) - (when (equal (nth 3 mode-line-format) " ") - (setcar (nthcdr 3 mode-line-format) " ")))) - -;;; Servers and groups. - -(defsubst gnus-server-add-address (method) - (let ((method-name (symbol-name (car method)))) - (if (and (memq 'address (assoc method-name gnus-valid-select-methods)) - (not (assq (intern (concat method-name "-address")) method)) - (memq 'physical-address (assq (car method) - gnus-valid-select-methods))) - (append method (list (list (intern (concat method-name "-address")) - (nth 1 method)))) - method))) - -(defsubst gnus-server-get-method (group method) - ;; Input either a server name, and extended server name, or a - ;; select method, and return a select method. - (cond ((stringp method) - (gnus-server-to-method method)) - ((equal method gnus-select-method) - gnus-select-method) - ((and (stringp (car method)) - group) - (gnus-server-extend-method group method)) - ((and method - (not group) - (equal (cadr method) "")) - method) - (t - (gnus-server-add-address method)))) - -(defun gnus-server-to-method (server) - "Map virtual server names to select methods." - (or - ;; Is this a method, perhaps? - (and server (listp server) server) - ;; Perhaps this is the native server? - (and (equal server "native") gnus-select-method) - ;; It should be in the server alist. - (cdr (assoc server gnus-server-alist)) - ;; It could be in the predefined server alist. - (cdr (assoc server gnus-predefined-server-alist)) - ;; If not, we look through all the opened server - ;; to see whether we can find it there. - (let ((opened gnus-opened-servers)) - (while (and opened - (not (equal server (format "%s:%s" (caaar opened) - (cadaar opened))))) - (pop opened)) - (caar opened)))) - -(defmacro gnus-method-equal (ss1 ss2) - "Say whether two servers are equal." - `(let ((s1 ,ss1) - (s2 ,ss2)) - (or (equal s1 s2) - (and (= (length s1) (length s2)) - (progn - (while (and s1 (member (car s1) s2)) - (setq s1 (cdr s1))) - (null s1)))))) - -(defun gnus-server-equal (m1 m2) - "Say whether two methods are equal." - (let ((m1 (cond ((null m1) gnus-select-method) - ((stringp m1) (gnus-server-to-method m1)) - (t m1))) - (m2 (cond ((null m2) gnus-select-method) - ((stringp m2) (gnus-server-to-method m2)) - (t m2)))) - (gnus-method-equal m1 m2))) - -(defun gnus-servers-using-backend (backend) - "Return a list of known servers using BACKEND." - (let ((opened gnus-opened-servers) - out) - (while opened - (when (eq backend (caaar opened)) - (push (caar opened) out)) - (pop opened)) - out)) - -(defun gnus-archive-server-wanted-p () - "Say whether the user wants to use the archive server." - (cond - ((or (not gnus-message-archive-method) - (not gnus-message-archive-group)) - nil) - ((and gnus-message-archive-method gnus-message-archive-group) - t) - (t - (let ((active (cadr (assq 'nnfolder-active-file - gnus-message-archive-method)))) - (and active - (file-exists-p active)))))) - -(defun gnus-group-prefixed-name (group method) - "Return the whole name from GROUP and METHOD." - (and (stringp method) (setq method (gnus-server-to-method method))) - (if (or (not method) - (gnus-server-equal method "native")) - group - (concat (format "%s" (car method)) - (when (and - (or (assoc (format "%s" (car method)) - (gnus-methods-using 'address)) - (gnus-server-equal method gnus-message-archive-method)) - (nth 1 method) - (not (string= (nth 1 method) ""))) - (concat "+" (nth 1 method))) - ":" group))) - -(defun gnus-group-real-prefix (group) - "Return the prefix of the current group name." - (if (string-match "^[^:]+:" group) - (substring group 0 (match-end 0)) - "")) - -(defun gnus-group-method (group) - "Return the server or method used for selecting GROUP. -You should probably use `gnus-find-method-for-group' instead." - (let ((prefix (gnus-group-real-prefix group))) - (if (equal prefix "") - gnus-select-method - (let ((servers gnus-opened-servers) - (server "") - backend possible found) - (if (string-match "^[^\\+]+\\+" prefix) - (setq backend (intern (substring prefix 0 (1- (match-end 0)))) - server (substring prefix (match-end 0) (1- (length prefix)))) - (setq backend (intern (substring prefix 0 (1- (length prefix)))))) - (while servers - (when (eq (caaar servers) backend) - (setq possible (caar servers)) - (when (equal (cadaar servers) server) - (setq found (caar servers)))) - (pop servers)) - (or (car (rassoc found gnus-server-alist)) - found - (car (rassoc possible gnus-server-alist)) - possible - (list backend server)))))) - -(defsubst gnus-secondary-method-p (method) - "Return whether METHOD is a secondary select method." - (let ((methods gnus-secondary-select-methods) - (gmethod (gnus-server-get-method nil method))) - (while (and methods - (not (equal (gnus-server-get-method nil (car methods)) - gmethod))) - (setq methods (cdr methods))) - methods)) - -(defun gnus-groups-from-server (server) - "Return a list of all groups that are fetched from SERVER." - (let ((alist (cdr gnus-newsrc-alist)) - info groups) - (while (setq info (pop alist)) - (when (gnus-server-equal (gnus-info-method info) server) - (push (gnus-info-group info) groups))) - (sort groups 'string<))) - -(defun gnus-group-foreign-p (group) - "Say whether a group is foreign or not." - (and (not (gnus-group-native-p group)) - (not (gnus-group-secondary-p group)))) - -(defun gnus-group-native-p (group) - "Say whether the group is native or not." - (not (string-match ":" group))) - -(defun gnus-group-secondary-p (group) - "Say whether the group is secondary or not." - (gnus-secondary-method-p (gnus-find-method-for-group group))) - -(defun gnus-group-find-parameter (group &optional symbol allow-list) - "Return the group parameters for GROUP. -If SYMBOL, return the value of that symbol in the group parameters." - (save-excursion - (set-buffer gnus-group-buffer) - (let ((parameters (funcall gnus-group-get-parameter-function group))) - (if symbol - (gnus-group-parameter-value parameters symbol allow-list) - parameters)))) - -(defun gnus-group-get-parameter (group &optional symbol allow-list) - "Return the group parameters for GROUP. -If SYMBOL, return the value of that symbol in the group parameters. -Most functions should use `gnus-group-find-parameter', which -also examines the topic parameters." - (let ((params (gnus-info-params (gnus-get-info group)))) - (if symbol - (gnus-group-parameter-value params symbol allow-list) - params))) - -(defun gnus-group-parameter-value (params symbol &optional allow-list) - "Return the value of SYMBOL in group PARAMS." - ;; We only wish to return group parameters (dotted lists) and - ;; not local variables, which may have the same names. - ;; But first we handle single elements... - (or (car (memq symbol params)) - ;; Handle alist. - (let (elem) - (catch 'found - (while (setq elem (pop params)) - (when (and (consp elem) - (eq (car elem) symbol) - (or allow-list - (atom (cdr elem)))) - (throw 'found (cdr elem)))))))) - -(defun gnus-group-add-parameter (group param) - "Add parameter PARAM to GROUP." - (let ((info (gnus-get-info group))) - (when info - (gnus-group-remove-parameter group (if (consp param) (car param) param)) - ;; Cons the new param to the old one and update. - (gnus-group-set-info (cons param (gnus-info-params info)) - group 'params)))) - -(defun gnus-group-set-parameter (group name value) - "Set parameter NAME to VALUE in GROUP." - (let ((info (gnus-get-info group))) - (when info - (gnus-group-remove-parameter group name) - (let ((old-params (gnus-info-params info)) - (new-params (list (cons name value)))) - (while old-params - (when (or (not (listp (car old-params))) - (not (eq (caar old-params) name))) - (setq new-params (append new-params (list (car old-params))))) - (setq old-params (cdr old-params))) - (gnus-group-set-info new-params group 'params))))) - -(defun gnus-group-remove-parameter (group name) - "Remove parameter NAME from GROUP." - (let ((info (gnus-get-info group))) - (when info - (let ((params (gnus-info-params info))) - (when params - (setq params (delq name params)) - (while (assq name params) - (gnus-pull name params)) - (gnus-info-set-params info params)))))) - -(defun gnus-group-add-score (group &optional score) - "Add SCORE to the GROUP score. -If SCORE is nil, add 1 to the score of GROUP." - (let ((info (gnus-get-info group))) - (when info - (gnus-info-set-score info (+ (gnus-info-score info) (or score 1)))))) - -;; Function written by Stainless Steel Rat -(defun gnus-short-group-name (group &optional levels) - "Collapse GROUP name LEVELS. -Select methods are stripped and any remote host name is stripped down to -just the host name." - (let* ((name "") - (foreign "") - (depth 0) - (skip 1) - (levels (or levels - (progn - (while (string-match "\\." group skip) - (setq skip (match-end 0) - depth (+ depth 1))) - depth)))) - ;; separate foreign select method from group name and collapse. - ;; if method contains a server, collapse to non-domain server name, - ;; otherwise collapse to select method - (when (string-match ":" group) - (cond ((string-match "+" group) - (let* ((plus (string-match "+" group)) - (colon (string-match ":" group (or plus 0))) - (dot (string-match "\\." group))) - (setq foreign (concat - (substring group (+ 1 plus) - (cond ((null dot) colon) - ((< colon dot) colon) - ((< dot colon) dot))) - ":") - group (substring group (+ 1 colon))))) - (t - (let* ((colon (string-match ":" group))) - (setq foreign (concat (substring group 0 (+ 1 colon))) - group (substring group (+ 1 colon))))))) - ;; collapse group name leaving LEVELS uncollapsed elements - (while group - (if (and (string-match "\\." group) (> levels 0)) - (setq name (concat name (substring group 0 1)) - group (substring group (match-end 0)) - levels (- levels 1) - name (concat name ".")) - (setq name (concat foreign name group) - group nil))) - name)) - -(defun gnus-narrow-to-body () - "Narrow to the body of an article." - (narrow-to-region - (progn - (goto-char (point-min)) - (or (search-forward "\n\n" nil t) - (point-max))) - (point-max))) - - -;;; -;;; Kill file handling. -;;; - -(defun gnus-apply-kill-file () - "Apply a kill file to the current newsgroup. -Returns the number of articles marked as read." - (if (or (file-exists-p (gnus-newsgroup-kill-file nil)) - (file-exists-p (gnus-newsgroup-kill-file gnus-newsgroup-name))) - (gnus-apply-kill-file-internal) - 0)) - -(defun gnus-kill-save-kill-buffer () - (let ((file (gnus-newsgroup-kill-file gnus-newsgroup-name))) - (when (get-file-buffer file) - (save-excursion - (set-buffer (get-file-buffer file)) - (when (buffer-modified-p) - (save-buffer)) - (kill-buffer (current-buffer)))))) - -(defcustom gnus-kill-file-name "KILL" - "Suffix of the kill files." - :group 'gnus-score-kill - :group 'gnus-score-files - :type 'string) - -(defun gnus-newsgroup-kill-file (newsgroup) - "Return the name of a kill file name for NEWSGROUP. -If NEWSGROUP is nil, return the global kill file name instead." - (cond - ;; The global KILL file is placed at top of the directory. - ((or (null newsgroup) - (string-equal newsgroup "")) - (expand-file-name gnus-kill-file-name - gnus-kill-files-directory)) - ;; Append ".KILL" to newsgroup name. - ((gnus-use-long-file-name 'not-kill) - (expand-file-name (concat (gnus-newsgroup-savable-name newsgroup) - "." gnus-kill-file-name) - gnus-kill-files-directory)) - ;; Place "KILL" under the hierarchical directory. - (t - (expand-file-name (concat (gnus-newsgroup-directory-form newsgroup) - "/" gnus-kill-file-name) - gnus-kill-files-directory)))) - -;;; Server things. - -(defun gnus-member-of-valid (symbol group) - "Find out if GROUP has SYMBOL as part of its \"valid\" spec." - (memq symbol (assoc - (symbol-name (car (gnus-find-method-for-group group))) - gnus-valid-select-methods))) - -(defun gnus-method-option-p (method option) - "Return non-nil if select METHOD has OPTION as a parameter." - (when (stringp method) - (setq method (gnus-server-to-method method))) - (memq option (assoc (format "%s" (car method)) - gnus-valid-select-methods))) - -(defun gnus-similar-server-opened (method) - (let ((opened gnus-opened-servers)) - (while (and method opened) - (when (and (equal (cadr method) (cadaar opened)) - (not (equal method (caar opened)))) - (setq method nil)) - (pop opened)) - (not method))) - -(defun gnus-server-extend-method (group method) - ;; This function "extends" a virtual server. If the server is - ;; "hello", and the select method is ("hello" (my-var "something")) - ;; in the group "alt.alt", this will result in a new virtual server - ;; called "hello+alt.alt". - (if (or (not (inline (gnus-similar-server-opened method))) - (not (cddr method))) - method - `(,(car method) ,(concat (cadr method) "+" group) - (,(intern (format "%s-address" (car method))) ,(cadr method)) - ,@(cddr method)))) - -(defun gnus-server-status (method) - "Return the status of METHOD." - (nth 1 (assoc method gnus-opened-servers))) - -(defun gnus-group-name-to-method (group) - "Guess a select method based on GROUP." - (if (string-match ":" group) - (let ((server (substring group 0 (match-beginning 0)))) - (if (string-match "\\+" server) - (list (intern (substring server 0 (match-beginning 0))) - (substring server (match-end 0))) - (list (intern server) ""))) - gnus-select-method)) - -(defun gnus-find-method-for-group (group &optional info) - "Find the select method that GROUP uses." - (or gnus-override-method - (and (not group) - gnus-select-method) - (let ((info (or info (gnus-get-info group))) - method) - (if (or (not info) - (not (setq method (gnus-info-method info))) - (equal method "native")) - gnus-select-method - (setq method - (cond ((stringp method) - (inline (gnus-server-to-method method))) - ((stringp (cadr method)) - (inline (gnus-server-extend-method group method))) - (t - method))) - (cond ((equal (cadr method) "") - method) - ((null (cadr method)) - (list (car method) "")) - (t - (gnus-server-add-address method))))))) - -(defun gnus-methods-using (feature) - "Find all methods that have FEATURE." - (let ((valids gnus-valid-select-methods) - outs) - (while valids - (when (memq feature (car valids)) - (push (car valids) outs)) - (setq valids (cdr valids))) - outs)) - -(defun gnus-read-group (prompt &optional default) - "Prompt the user for a group name. -Disallow illegal group names." - (let ((prefix "") - group) - (while (not group) - (when (string-match - "[: `'\"/]\\|^$" - (setq group (read-string (concat prefix prompt) - (cons (or default "") 0) - 'gnus-group-history))) - (setq prefix (format "Illegal group name: \"%s\". " group) - group nil))) - group)) - -(defun gnus-read-method (prompt) - "Prompt the user for a method. -Allow completion over sensible values." - (let* ((servers - (append gnus-valid-select-methods - gnus-predefined-server-alist - gnus-server-alist)) - (method - (completing-read - prompt servers - nil t nil 'gnus-method-history))) - (cond - ((equal method "") - (setq method gnus-select-method)) - ((assoc method gnus-valid-select-methods) - (list (intern method) - (if (memq 'prompt-address - (assoc method gnus-valid-select-methods)) - (read-string "Address: ") - ""))) - ((assoc method servers) - method) - (t - (list (intern method) ""))))) - -;;; User-level commands. - -;;;###autoload -(defun gnus-slave-no-server (&optional arg) - "Read network news as a slave, without connecting to local server." - (interactive "P") - (gnus-no-server arg t)) - -;;;###autoload -(defun gnus-no-server (&optional arg slave) - "Read network news. -If ARG is a positive number, Gnus will use that as the -startup level. If ARG is nil, Gnus will be started at level 2. -If ARG is non-nil and not a positive number, Gnus will -prompt the user for the name of an NNTP server to use. -As opposed to `gnus', this command will not connect to the local server." - (interactive "P") - (gnus-no-server-1 arg slave)) - -;;;###autoload -(defun gnus-slave (&optional arg) - "Read news as a slave." - (interactive "P") - (gnus arg nil 'slave)) - -;;;###autoload -(defun gnus-other-frame (&optional arg) - "Pop up a frame to read news." - (interactive "P") - (let ((window (get-buffer-window gnus-group-buffer))) - (cond (window - (select-frame (window-frame window))) - ((= (length (frame-list)) 1) - (select-frame (make-frame))) - (t - (other-frame 1)))) - (gnus arg)) - -;;;###autoload -(defun gnus (&optional arg dont-connect slave) - "Read network news. -If ARG is non-nil and a positive number, Gnus will use that as the -startup level. If ARG is non-nil and not a positive number, Gnus will -prompt the user for the name of an NNTP server to use." - (interactive "P") - (gnus-1 arg dont-connect slave)) - -;; Allow redefinition of Gnus functions. - -(gnus-ems-redefine) - -(provide 'gnus) - -;;; gnus.el ends here diff --git a/lisp/lpath.el b/lisp/lpath.el deleted file mode 100644 index c8ee274..0000000 --- a/lisp/lpath.el +++ /dev/null @@ -1,70 +0,0 @@ -;; Shut up. - -(defvar byte-compile-default-warnings) - -(or (featurep 'path-util) - (load "apel/path-util")) -(add-path "apel") -(add-path "flim") -(add-path "semi") - -(defun maybe-fbind (args) - (while args - (or (fboundp (car args)) - (fset (car args) 'ignore)) - (setq args (cdr args)))) - -(defun maybe-bind (args) - (mapcar (lambda (var) (unless (boundp var) (set var nil))) args)) - -(if (string-match "XEmacs" emacs-version) - (progn - (defvar track-mouse nil) - (maybe-fbind '(posn-point - event-start x-popup-menu - facemenu-get-face window-at coordinates-in-window-p - compute-motion x-defined-colors easy-menu-create-keymaps - read-event internal-find-face internal-next-face-id - make-face-internal set-frame-face-alist frame-face-alist - facemenu-add-new-face make-face-x-resource-internal - set-font-size set-font-family posn-window - run-with-idle-timer mouse-minibuffer-check window-edges - event-click-count track-mouse read-event mouse-movement-p - event-end mouse-scroll-subr overlay-lists delete-overlay - set-face-stipple mail-abbrevs-setup char-int - make-char-table set-char-table-range font-create-object - x-color-values widget-make-intangible error-message-string - w3-form-encode-xwfu gnus-mule-get-coding-system - decode-coding-string mail-aliases-setup)) - (maybe-bind '(global-face-data - mark-active transient-mark-mode mouse-selection-click-count - mouse-selection-click-count-buffer buffer-display-table - font-lock-defaults user-full-name user-login-name - gnus-newsgroup-name gnus-article-x-face-too-ugly - mail-mode-hook enable-multibyte-characters - adaptive-fill-first-line-regexp adaptive-fill-regexp))) - (maybe-bind '(mail-mode-hook - enable-multibyte-characters browse-url-browser-function - adaptive-fill-first-line-regexp adaptive-fill-regexp)) - (maybe-fbind '(color-instance-rgb-components - make-color-instance color-instance-name specifier-instance - device-type device-class get-popup-menu-response event-object - x-defined-colors read-color add-submenu set-font-family - font-create-object set-font-size frame-device find-face - set-extent-property make-extent characterp display-error - set-face-doc-string frame-property face-doc-string - button-press-event-p next-command-event - widget-make-intangible glyphp make-glyph set-glyph-image - set-glyph-property event-glyph glyph-property event-point - device-on-window-system-p make-gui-button Info-goto-node - pp-to-string color-name - gnus-mule-get-coding-system decode-coding-string - mail-aliases-setup))) - -(setq load-path (cons "." load-path)) -(require 'custom) - -(defun md5 (a &optional b c) - ) - -(provide 'lpath) diff --git a/lisp/mailheader.el b/lisp/mailheader.el deleted file mode 100644 index 5e2b097..0000000 --- a/lisp/mailheader.el +++ /dev/null @@ -1,182 +0,0 @@ -;;; mail-header.el --- Mail header parsing, merging, formatting - -;; Copyright (C) 1996 by Free Software Foundation, Inc. - -;; Author: Erik Naggum -;; Keywords: tools, mail, news - -;; This file is part of GNU Emacs. - -;; GNU Emacs is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 2, or (at your option) -;; any later version. - -;; GNU Emacs is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs; see the file COPYING. If not, write to -;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. - -;;; Commentary: - -;; This package provides an abstraction to RFC822-style messages, used in -;; mail news, and some other systems. The simple syntactic rules for such -;; headers, such as quoting and line folding, are routinely reimplemented -;; in many individual packages. This package removes the need for this -;; redundancy by representing message headers as association lists, -;; offering functions to extract the set of headers from a message, to -;; parse individual headers, to merge sets of headers, and to format a set -;; of headers. - -;; The car of each element in the message-header alist is a symbol whose -;; print name is the name of the header, in all lower-case. The cdr of an -;; element depends on the operation. After extracting headers from a -;; message, it is a string, the value of the header. An extracted set of -;; headers may be parsed further, which may turn it into a list, whose car -;; is the original value and whose subsequent elements depend on the -;; header. For formatting, it is evaluated to obtain the strings to be -;; inserted. For merging, one set of headers consists of strings, while -;; the other set will be evaluated with the symbols in the first set of -;; headers bound to their respective values. - -;;; Code: - -(require 'cl) - -;; Make the byte-compiler shut up. -(defvar headers) - -(defun mail-header-extract () - "Extract headers from current buffer after point. -Returns a header alist, where each element is a cons cell (name . value), -where NAME is a symbol, and VALUE is the string value of the header having -that name." - (let ((message-headers ()) (top (point)) - start end) - (while (and (setq start (point)) - (> (skip-chars-forward "^\0- :") 0) - (= (following-char) ?:) - (setq end (point)) - (progn (forward-char) - (> (skip-chars-forward " \t") 0))) - (let ((header (intern (downcase (buffer-substring start end)))) - (value (list (buffer-substring - (point) (progn (end-of-line) (point)))))) - (while (progn (forward-char) (> (skip-chars-forward " \t") 0)) - (push (buffer-substring (point) (progn (end-of-line) (point))) - value)) - (push (if (cdr value) - (cons header (mapconcat #'identity (nreverse value) " ")) - (cons header (car value))) - message-headers))) - (goto-char top) - (nreverse message-headers))) - -(defun mail-header-extract-no-properties () - "Extract headers from current buffer after point, without properties. -Returns a header alist, where each element is a cons cell (name . value), -where NAME is a symbol, and VALUE is the string value of the header having -that name." - (mapcar - (lambda (elt) - (set-text-properties 0 (length (cdr elt)) nil (cdr elt)) - elt) - (mail-header-extract))) - -(defun mail-header-parse (parsing-rules headers) - "Apply PARSING-RULES to HEADERS. -PARSING-RULES is an alist whose keys are header names (symbols) and whose -value is a parsing function. The function takes one argument, a string, -and return a list of values, which will destructively replace the value -associated with the key in HEADERS, after being prepended with the original -value." - (dolist (rule parsing-rules) - (let ((header (assq (car rule) headers))) - (when header - (if (consp (cdr header)) - (setf (cddr header) (funcall (cdr rule) (cadr header))) - (setf (cdr header) - (cons (cdr header) (funcall (cdr rule) (cdr header)))))))) - headers) - -(defsubst mail-header (header &optional header-alist) - "Return the value associated with header HEADER in HEADER-ALIST. -If the value is a string, it is the original value of the header. If the -value is a list, its first element is the original value of the header, -with any subsequent elements being the result of parsing the value. -If HEADER-ALIST is nil, the dynamically bound variable `headers' is used." - (cdr (assq header (or header-alist headers)))) - -(defun mail-header-set (header value &optional header-alist) - "Set the value associated with header HEADER to VALUE in HEADER-ALIST. -HEADER-ALIST defaults to the dynamically bound variable `headers' if nil. -See `mail-header' for the semantics of VALUE." - (let* ((alist (or header-alist headers)) - (entry (assq header alist))) - (if entry - (setf (cdr entry) value) - (nconc alist (list (cons header value))))) - value) - -(defsetf mail-header (header &optional header-alist) (value) - `(mail-header-set ,header ,value ,header-alist)) - -(defun mail-header-merge (merge-rules headers) - "Return a new header alist with MERGE-RULES applied to HEADERS. -MERGE-RULES is an alist whose keys are header names (symbols) and whose -values are forms to evaluate, the results of which are the new headers. It -should be a string or a list of string. The first element may be nil to -denote that the formatting functions must use the remaining elements, or -skip the header altogether if there are no other elements. - The macro `mail-header' can be used to access headers in HEADERS." - (mapcar - (lambda (rule) - (cons (car rule) (eval (cdr rule)))) - merge-rules)) - -(defvar mail-header-format-function - (lambda (header value) - "Function to format headers without a specified formatting function." - (insert (capitalize (symbol-name header)) - ": " - (if (consp value) (car value) value) - "\n"))) - -(defun mail-header-format (format-rules headers) - "Use FORMAT-RULES to format HEADERS and insert into current buffer. -FORMAT-RULES is an alist whose keys are header names (symbols), and whose -values are functions that format the header, the results of which are -inserted, unless it is nil. The function takes two arguments, the header -symbol, and the value of that header. If the function itself is nil, the -default action is to insert the value of the header, unless it is nil. -The headers are inserted in the order of the FORMAT-RULES. -A key of t represents any otherwise unmentioned headers. -A key of nil has as its value a list of defaulted headers to ignore." - (let ((ignore (append (cdr (assq nil format-rules)) - (mapcar #'car format-rules)))) - (dolist (rule format-rules) - (let* ((header (car rule)) - (value (mail-header header))) - (cond ((null header) 'ignore) - ((eq header t) - (dolist (defaulted headers) - (unless (memq (car defaulted) ignore) - (let* ((header (car defaulted)) - (value (cdr defaulted))) - (if (cdr rule) - (funcall (cdr rule) header value) - (funcall mail-header-format-function header value)))))) - (value - (if (cdr rule) - (funcall (cdr rule) header value) - (funcall mail-header-format-function header value)))))) - (insert "\n"))) - -(provide 'mailheader) - -;;; mail-header.el ends here diff --git a/lisp/md5.el b/lisp/md5.el deleted file mode 100644 index 3fabf29..0000000 --- a/lisp/md5.el +++ /dev/null @@ -1,409 +0,0 @@ -;;; md5.el -- MD5 Message Digest Algorithm -;;; Gareth Rees - -;; LCD Archive Entry: -;; md5|Gareth Rees|gdr11@cl.cam.ac.uk| -;; MD5 cryptographic message digest algorithm| -;; 13-Nov-95|1.0|~/misc/md5.el.Z| - -;;; Details: ------------------------------------------------------------------ - -;; This is a direct translation into Emacs LISP of the reference C -;; implementation of the MD5 Message-Digest Algorithm written by RSA -;; Data Security, Inc. -;; -;; The algorithm takes a message (that is, a string of bytes) and -;; computes a 16-byte checksum or "digest" for the message. This digest -;; is supposed to be cryptographically strong in the sense that if you -;; are given a 16-byte digest D, then there is no easier way to -;; construct a message whose digest is D than to exhaustively search the -;; space of messages. However, the robustness of the algorithm has not -;; been proven, and a similar algorithm (MD4) was shown to be unsound, -;; so treat with caution! -;; -;; The C algorithm uses 32-bit integers; because GNU Emacs -;; implementations provide 28-bit integers (with 24-bit integers on -;; versions prior to 19.29), the code represents a 32-bit integer as the -;; cons of two 16-bit integers. The most significant word is stored in -;; the car and the least significant in the cdr. The algorithm requires -;; at least 17 bits of integer representation in order to represent the -;; carry from a 16-bit addition. - -;;; Usage: -------------------------------------------------------------------- - -;; To compute the MD5 Message Digest for a message M (represented as a -;; string or as a vector of bytes), call -;; -;; (md5-encode M) -;; -;; which returns the message digest as a vector of 16 bytes. If you -;; need to supply the message in pieces M1, M2, ... Mn, then call -;; -;; (md5-init) -;; (md5-update M1) -;; (md5-update M2) -;; ... -;; (md5-update Mn) -;; (md5-final) - -;;; Copyright and licence: ---------------------------------------------------- - -;; Copyright (C) 1995 by Gareth Rees -;; Derived from the RSA Data Security, Inc. MD5 Message-Digest Algorithm -;; -;; md5.el is free software; you can redistribute it and/or modify it -;; under the terms of the GNU General Public License as published by the -;; Free Software Foundation; either version 2, or (at your option) any -;; later version. -;; -;; md5.el is distributed in the hope that it will be useful, but WITHOUT -;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -;; FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -;; for more details. -;; -;; The original copyright notice is given below, as required by the -;; licence for the original code. This code is distributed under *both* -;; RSA's original licence and the GNU General Public Licence. (There -;; should be no problems, as the former is more liberal than the -;; latter). - -;;; Original copyright notice: ------------------------------------------------ - -;; Copyright (C) 1990, RSA Data Security, Inc. All rights reserved. -;; -;; License to copy and use this software is granted provided that it is -;; identified as the "RSA Data Security, Inc. MD5 Message- Digest -;; Algorithm" in all material mentioning or referencing this software or -;; this function. -;; -;; License is also granted to make and use derivative works provided -;; that such works are identified as "derived from the RSA Data -;; Security, Inc. MD5 Message-Digest Algorithm" in all material -;; mentioning or referencing the derived work. -;; -;; RSA Data Security, Inc. makes no representations concerning either -;; the merchantability of this software or the suitability of this -;; software for any particular purpose. It is provided "as is" without -;; express or implied warranty of any kind. -;; -;; These notices must be retained in any copies of any part of this -;; documentation and/or software. - -;;; Code: --------------------------------------------------------------------- - -(defvar md5-program "md5sum" - "*Program that reads a message on its standard input and writes an -MD5 digest on its output.") - -(defvar md5-maximum-internal-length 4096 - "*The maximum size of a piece of data that should use the MD5 routines -written in lisp. If a message exceeds this, it will be run through an -external filter for processing. Also see the `md5-program' variable. -This variable has no effect if you call the md5-init|update|final -functions - only used by the `md5' function's simpler interface.") - -(defvar md5-bits (make-vector 4 0) - "Number of bits handled, modulo 2^64. -Represented as four 16-bit numbers, least significant first.") -(defvar md5-buffer (make-vector 4 '(0 . 0)) - "Scratch buffer (four 32-bit integers).") -(defvar md5-input (make-vector 64 0) - "Input buffer (64 bytes).") - -(defun md5-unhex (x) - (if (> x ?9) - (if (>= x ?a) - (+ 10 (- x ?a)) - (+ 10 (- x ?A))) - (- x ?0))) - -(defun md5-encode (message) - "Encodes MESSAGE using the MD5 message digest algorithm. -MESSAGE must be a string or an array of bytes. -Returns a vector of 16 bytes containing the message digest." - (if (<= (length message) md5-maximum-internal-length) - (progn - (md5-init) - (md5-update message) - (md5-final)) - (save-excursion - (set-buffer (get-buffer-create " *md5-work*")) - (erase-buffer) - (insert message) - (call-process-region (point-min) (point-max) - (or shell-file-name "/bin/sh") - t (current-buffer) nil - "-c" md5-program) - ;; MD5 digest is 32 chars long - ;; mddriver adds a newline to make neaten output for tty - ;; viewing, make sure we leave it behind. - (let ((data (buffer-substring (point-min) (+ (point-min) 32))) - (vec (make-vector 16 0)) - (ctr 0)) - (while (< ctr 16) - (aset vec ctr (+ (* 16 (md5-unhex (aref data (* ctr 2)))) - (md5-unhex (aref data (1+ (* ctr 2)))))) - (setq ctr (1+ ctr))))))) - -(defsubst md5-add (x y) - "Return 32-bit sum of 32-bit integers X and Y." - (let ((m (+ (car x) (car y))) - (l (+ (cdr x) (cdr y)))) - (cons (logand 65535 (+ m (lsh l -16))) (logand l 65535)))) - -;; FF, GG, HH and II are basic MD5 functions, providing transformations -;; for rounds 1, 2, 3 and 4 respectively. Each function follows this -;; pattern of computation (where ROTATE(x,y) means rotate 32-bit value x -;; by y bits to the left): -;; -;; FF(a,b,c,d,x,s,ac) = ROTATE(a + F(b,c,d) + x + ac,s) + b -;; -;; so we use the macro `md5-make-step' to construct each one. The -;; helper functions F, G, H and I operate on 16-bit numbers; the full -;; operation splits its inputs, operates on the halves separately and -;; then puts the results together. - -(defsubst md5-F (x y z) (logior (logand x y) (logand (lognot x) z))) -(defsubst md5-G (x y z) (logior (logand x z) (logand y (lognot z)))) -(defsubst md5-H (x y z) (logxor x y z)) -(defsubst md5-I (x y z) (logxor y (logior x (logand 65535 (lognot z))))) - -(defmacro md5-make-step (name func) - (` - (defun (, name) (a b c d x s ac) - (let* - ((m1 (+ (car a) ((, func) (car b) (car c) (car d)) (car x) (car ac))) - (l1 (+ (cdr a) ((, func) (cdr b) (cdr c) (cdr d)) (cdr x) (cdr ac))) - (m2 (logand 65535 (+ m1 (lsh l1 -16)))) - (l2 (logand 65535 l1)) - (m3 (logand 65535 (if (> s 15) - (+ (lsh m2 (- s 32)) (lsh l2 (- s 16))) - (+ (lsh m2 s) (lsh l2 (- s 16)))))) - (l3 (logand 65535 (if (> s 15) - (+ (lsh l2 (- s 32)) (lsh m2 (- s 16))) - (+ (lsh l2 s) (lsh m2 (- s 16))))))) - (md5-add (cons m3 l3) b))))) - -(md5-make-step md5-FF md5-F) -(md5-make-step md5-GG md5-G) -(md5-make-step md5-HH md5-H) -(md5-make-step md5-II md5-I) - -(defun md5-init () - "Initialise the state of the message-digest routines." - (aset md5-bits 0 0) - (aset md5-bits 1 0) - (aset md5-bits 2 0) - (aset md5-bits 3 0) - (aset md5-buffer 0 '(26437 . 8961)) - (aset md5-buffer 1 '(61389 . 43913)) - (aset md5-buffer 2 '(39098 . 56574)) - (aset md5-buffer 3 '( 4146 . 21622))) - -(defun md5-update (string) - "Update the current MD5 state with STRING (an array of bytes)." - (let ((len (length string)) - (i 0) - (j 0)) - (while (< i len) - ;; Compute number of bytes modulo 64 - (setq j (% (/ (aref md5-bits 0) 8) 64)) - - ;; Store this byte (truncating to 8 bits to be sure) - (aset md5-input j (logand 255 (aref string i))) - - ;; Update number of bits by 8 (modulo 2^64) - (let ((c 8) (k 0)) - (while (and (> c 0) (< k 4)) - (let ((b (aref md5-bits k))) - (aset md5-bits k (logand 65535 (+ b c))) - (setq c (if (> b (- 65535 c)) 1 0) - k (1+ k))))) - - ;; Increment number of bytes processed - (setq i (1+ i)) - - ;; When 64 bytes accumulated, pack them into sixteen 32-bit - ;; integers in the array `in' and then tranform them. - (if (= j 63) - (let ((in (make-vector 16 (cons 0 0))) - (k 0) - (kk 0)) - (while (< k 16) - (aset in k (md5-pack md5-input kk)) - (setq k (+ k 1) kk (+ kk 4))) - (md5-transform in)))))) - -(defun md5-pack (array i) - "Pack the four bytes at ARRAY reference I to I+3 into a 32-bit integer." - (cons (+ (lsh (aref array (+ i 3)) 8) (aref array (+ i 2))) - (+ (lsh (aref array (+ i 1)) 8) (aref array (+ i 0))))) - -(defun md5-byte (array n b) - "Unpack byte B (0 to 3) from Nth member of ARRAY of 32-bit integers." - (let ((e (aref array n))) - (cond ((eq b 0) (logand 255 (cdr e))) - ((eq b 1) (lsh (cdr e) -8)) - ((eq b 2) (logand 255 (car e))) - ((eq b 3) (lsh (car e) -8))))) - -(defun md5-final () - (let ((in (make-vector 16 (cons 0 0))) - (j 0) - (digest (make-vector 16 0)) - (padding)) - - ;; Save the number of bits in the message - (aset in 14 (cons (aref md5-bits 1) (aref md5-bits 0))) - (aset in 15 (cons (aref md5-bits 3) (aref md5-bits 2))) - - ;; Compute number of bytes modulo 64 - (setq j (% (/ (aref md5-bits 0) 8) 64)) - - ;; Pad out computation to 56 bytes modulo 64 - (setq padding (make-vector (if (< j 56) (- 56 j) (- 120 j)) 0)) - (aset padding 0 128) - (md5-update padding) - - ;; Append length in bits and transform - (let ((k 0) (kk 0)) - (while (< k 14) - (aset in k (md5-pack md5-input kk)) - (setq k (+ k 1) kk (+ kk 4)))) - (md5-transform in) - - ;; Store the results in the digest - (let ((k 0) (kk 0)) - (while (< k 4) - (aset digest (+ kk 0) (md5-byte md5-buffer k 0)) - (aset digest (+ kk 1) (md5-byte md5-buffer k 1)) - (aset digest (+ kk 2) (md5-byte md5-buffer k 2)) - (aset digest (+ kk 3) (md5-byte md5-buffer k 3)) - (setq k (+ k 1) kk (+ kk 4)))) - - ;; Return digest - digest)) - -;; It says in the RSA source, "Note that if the Mysterious Constants are -;; arranged backwards in little-endian order and decrypted with the DES -;; they produce OCCULT MESSAGES!" Security through obscurity? - -(defun md5-transform (in) - "Basic MD5 step. Transform md5-buffer based on array IN." - (let ((a (aref md5-buffer 0)) - (b (aref md5-buffer 1)) - (c (aref md5-buffer 2)) - (d (aref md5-buffer 3))) - (setq - a (md5-FF a b c d (aref in 0) 7 '(55146 . 42104)) - d (md5-FF d a b c (aref in 1) 12 '(59591 . 46934)) - c (md5-FF c d a b (aref in 2) 17 '( 9248 . 28891)) - b (md5-FF b c d a (aref in 3) 22 '(49597 . 52974)) - a (md5-FF a b c d (aref in 4) 7 '(62844 . 4015)) - d (md5-FF d a b c (aref in 5) 12 '(18311 . 50730)) - c (md5-FF c d a b (aref in 6) 17 '(43056 . 17939)) - b (md5-FF b c d a (aref in 7) 22 '(64838 . 38145)) - a (md5-FF a b c d (aref in 8) 7 '(27008 . 39128)) - d (md5-FF d a b c (aref in 9) 12 '(35652 . 63407)) - c (md5-FF c d a b (aref in 10) 17 '(65535 . 23473)) - b (md5-FF b c d a (aref in 11) 22 '(35164 . 55230)) - a (md5-FF a b c d (aref in 12) 7 '(27536 . 4386)) - d (md5-FF d a b c (aref in 13) 12 '(64920 . 29075)) - c (md5-FF c d a b (aref in 14) 17 '(42617 . 17294)) - b (md5-FF b c d a (aref in 15) 22 '(18868 . 2081)) - a (md5-GG a b c d (aref in 1) 5 '(63006 . 9570)) - d (md5-GG d a b c (aref in 6) 9 '(49216 . 45888)) - c (md5-GG c d a b (aref in 11) 14 '( 9822 . 23121)) - b (md5-GG b c d a (aref in 0) 20 '(59830 . 51114)) - a (md5-GG a b c d (aref in 5) 5 '(54831 . 4189)) - d (md5-GG d a b c (aref in 10) 9 '( 580 . 5203)) - c (md5-GG c d a b (aref in 15) 14 '(55457 . 59009)) - b (md5-GG b c d a (aref in 4) 20 '(59347 . 64456)) - a (md5-GG a b c d (aref in 9) 5 '( 8673 . 52710)) - d (md5-GG d a b c (aref in 14) 9 '(49975 . 2006)) - c (md5-GG c d a b (aref in 3) 14 '(62677 . 3463)) - b (md5-GG b c d a (aref in 8) 20 '(17754 . 5357)) - a (md5-GG a b c d (aref in 13) 5 '(43491 . 59653)) - d (md5-GG d a b c (aref in 2) 9 '(64751 . 41976)) - c (md5-GG c d a b (aref in 7) 14 '(26479 . 729)) - b (md5-GG b c d a (aref in 12) 20 '(36138 . 19594)) - a (md5-HH a b c d (aref in 5) 4 '(65530 . 14658)) - d (md5-HH d a b c (aref in 8) 11 '(34673 . 63105)) - c (md5-HH c d a b (aref in 11) 16 '(28061 . 24866)) - b (md5-HH b c d a (aref in 14) 23 '(64997 . 14348)) - a (md5-HH a b c d (aref in 1) 4 '(42174 . 59972)) - d (md5-HH d a b c (aref in 4) 11 '(19422 . 53161)) - c (md5-HH c d a b (aref in 7) 16 '(63163 . 19296)) - b (md5-HH b c d a (aref in 10) 23 '(48831 . 48240)) - a (md5-HH a b c d (aref in 13) 4 '(10395 . 32454)) - d (md5-HH d a b c (aref in 0) 11 '(60065 . 10234)) - c (md5-HH c d a b (aref in 3) 16 '(54511 . 12421)) - b (md5-HH b c d a (aref in 6) 23 '( 1160 . 7429)) - a (md5-HH a b c d (aref in 9) 4 '(55764 . 53305)) - d (md5-HH d a b c (aref in 12) 11 '(59099 . 39397)) - c (md5-HH c d a b (aref in 15) 16 '( 8098 . 31992)) - b (md5-HH b c d a (aref in 2) 23 '(50348 . 22117)) - a (md5-II a b c d (aref in 0) 6 '(62505 . 8772)) - d (md5-II d a b c (aref in 7) 10 '(17194 . 65431)) - c (md5-II c d a b (aref in 14) 15 '(43924 . 9127)) - b (md5-II b c d a (aref in 5) 21 '(64659 . 41017)) - a (md5-II a b c d (aref in 12) 6 '(25947 . 22979)) - d (md5-II d a b c (aref in 3) 10 '(36620 . 52370)) - c (md5-II c d a b (aref in 10) 15 '(65519 . 62589)) - b (md5-II b c d a (aref in 1) 21 '(34180 . 24017)) - a (md5-II a b c d (aref in 8) 6 '(28584 . 32335)) - d (md5-II d a b c (aref in 15) 10 '(65068 . 59104)) - c (md5-II c d a b (aref in 6) 15 '(41729 . 17172)) - b (md5-II b c d a (aref in 13) 21 '(19976 . 4513)) - a (md5-II a b c d (aref in 4) 6 '(63315 . 32386)) - d (md5-II d a b c (aref in 11) 10 '(48442 . 62005)) - c (md5-II c d a b (aref in 2) 15 '(10967 . 53947)) - b (md5-II b c d a (aref in 9) 21 '(60294 . 54161))) - - (aset md5-buffer 0 (md5-add (aref md5-buffer 0) a)) - (aset md5-buffer 1 (md5-add (aref md5-buffer 1) b)) - (aset md5-buffer 2 (md5-add (aref md5-buffer 2) c)) - (aset md5-buffer 3 (md5-add (aref md5-buffer 3) d)))) - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;; Here begins the merger with the XEmacs API and the md5.el from the URL -;;; package. Courtesy wmperry@spry.com -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -(defun md5 (object &optional start end) - "Return the MD5 (a secure message digest algorithm) of an object. -OBJECT is either a string or a buffer. -Optional arguments START and END denote buffer positions for computing the -hash of a portion of OBJECT." - (let ((buffer nil)) - (unwind-protect - (save-excursion - (setq buffer (generate-new-buffer " *md5-work*")) - (set-buffer buffer) - (cond - ((bufferp object) - (insert-buffer-substring object start end)) - ((stringp object) - (insert (if (or start end) - (substring object start end) - object))) - (t nil)) - (prog1 - (if (<= (point-max) md5-maximum-internal-length) - (mapconcat - (function (lambda (node) (format "%02x" node))) - (md5-encode (buffer-string)) - "") - (call-process-region (point-min) (point-max) - (or shell-file-name "/bin/sh") - t buffer nil - "-c" md5-program) - ;; MD5 digest is 32 chars long - ;; mddriver adds a newline to make neaten output for tty - ;; viewing, make sure we leave it behind. - (buffer-substring (point-min) (+ (point-min) 32))) - (kill-buffer buffer))) - (and buffer (kill-buffer buffer) nil)))) - -(provide 'md5) - -;;; md5.el ends here ---------------------------------------------------------- diff --git a/lisp/message.el b/lisp/message.el deleted file mode 100644 index e3c0872..0000000 --- a/lisp/message.el +++ /dev/null @@ -1,4338 +0,0 @@ -;;; message.el --- composing mail and news messages -;; Copyright (C) 1996,97,98 Free Software Foundation, Inc. - -;; Author: Lars Magne Ingebrigtsen -;; MORIOKA Tomohiko -;; Shuhei KOBAYASHI -;; Keiichi Suzuki -;; Keywords: mail, news, MIME - -;; This file is part of GNU Emacs. - -;; GNU Emacs is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 2, or (at your option) -;; any later version. - -;; GNU Emacs is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs; see the file COPYING. If not, write to the -;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. - -;;; Commentary: - -;; This mode provides mail-sending facilities from within Emacs. It -;; consists mainly of large chunks of code from the sendmail.el, -;; gnus-msg.el and rnewspost.el files. - -;;; Code: - -(eval-when-compile - (require 'cl) - (require 'smtp) - ) - -(require 'mailheader) -(require 'nnheader) -(require 'timezone) -(require 'easymenu) -(require 'custom) -(if (string-match "XEmacs\\|Lucid" emacs-version) - (require 'mail-abbrevs) - (require 'mailabbrev)) -(require 'mime-edit) - -(defgroup message '((user-mail-address custom-variable) - (user-full-name custom-variable)) - "Mail and news message composing." - :link '(custom-manual "(message)Top") - :group 'mail - :group 'news) - -(put 'user-mail-address 'custom-type 'string) -(put 'user-full-name 'custom-type 'string) - -(defgroup message-various nil - "Various Message Variables" - :link '(custom-manual "(message)Various Message Variables") - :group 'message) - -(defgroup message-buffers nil - "Message Buffers" - :link '(custom-manual "(message)Message Buffers") - :group 'message) - -(defgroup message-sending nil - "Message Sending" - :link '(custom-manual "(message)Sending Variables") - :group 'message) - -(defgroup message-interface nil - "Message Interface" - :link '(custom-manual "(message)Interface") - :group 'message) - -(defgroup message-forwarding nil - "Message Forwarding" - :link '(custom-manual "(message)Forwarding") - :group 'message-interface) - -(defgroup message-insertion nil - "Message Insertion" - :link '(custom-manual "(message)Insertion") - :group 'message) - -(defgroup message-headers nil - "Message Headers" - :link '(custom-manual "(message)Message Headers") - :group 'message) - -(defgroup message-news nil - "Composing News Messages" - :group 'message) - -(defgroup message-mail nil - "Composing Mail Messages" - :group 'message) - -(defgroup message-faces nil - "Faces used for message composing." - :group 'message - :group 'faces) - -(defgroup message-frames nil - "Message frames" - :group 'message) - -(defcustom message-directory "~/Mail/" - "*Directory from which all other mail file variables are derived." - :group 'message-various - :type 'directory) - -(defcustom message-max-buffers 10 - "*How many buffers to keep before starting to kill them off." - :group 'message-buffers - :type 'integer) - -(defcustom message-send-rename-function nil - "Function called to rename the buffer after sending it." - :group 'message-buffers - :type 'function) - -(defcustom message-fcc-handler-function 'message-output - "*A function called to save outgoing articles. -This function will be called with the name of the file to store the -article in. The default function is `message-output' which saves in Unix -mailbox format." - :type '(radio (function-item message-output) - (function :tag "Other")) - :group 'message-sending) - -(defcustom message-encode-function 'message-maybe-encode - "*A function called to encode messages." - :group 'message-sending - :type 'function) - -(defcustom message-courtesy-message - "The following message is a courtesy copy of an article\nthat has been posted to %s as well.\n\n" - "*This is inserted at the start of a mailed copy of a posted message. -If the string contains the format spec \"%s\", the Newsgroups -the article has been posted to will be inserted there. -If this variable is nil, no such courtesy message will be added." - :group 'message-sending - :type 'string) - -(defcustom message-ignored-bounced-headers "^\\(Received\\|Return-Path\\):" - "*Regexp that matches headers to be removed in resent bounced mail." - :group 'message-interface - :type 'regexp) - -;;;###autoload -(defcustom message-from-style 'default - "*Specifies how \"From\" headers look. - -If `nil', they contain just the return address like: - king@grassland.com -If `parens', they look like: - king@grassland.com (Elvis Parsley) -If `angles', they look like: - Elvis Parsley - -Otherwise, most addresses look like `angles', but they look like -`parens' if `angles' would need quoting and `parens' would not." - :type '(choice (const :tag "simple" nil) - (const parens) - (const angles) - (const default)) - :group 'message-headers) - -(defcustom message-syntax-checks nil - ; Guess this one shouldn't be easy to customize... - "*Controls what syntax checks should not be performed on outgoing posts. -To disable checking of long signatures, for instance, add - `(signature . disabled)' to this list. - -Don't touch this variable unless you really know what you're doing. - -Checks include subject-cmsg multiple-headers sendsys message-id from -long-lines control-chars size new-text redirected-followup signature -approved sender empty empty-headers message-id from subject -shorten-followup-to existing-newsgroups buffer-file-name unchanged." - :group 'message-news) - -(defcustom message-required-news-headers - '(From Newsgroups Subject Date Message-ID - (optional . Organization) Lines - (optional . User-Agent)) - "*Headers to be generated or prompted for when posting an article. -RFC977 and RFC1036 require From, Date, Newsgroups, Subject, -Message-ID. Organization, Lines, In-Reply-To, Expires, and -User-Agent are optional. If don't you want message to insert some -header, remove it from this list." - :group 'message-news - :group 'message-headers - :type '(repeat sexp)) - -(defcustom message-required-mail-headers - '(From Subject Date (optional . In-Reply-To) Message-ID Lines - (optional . User-Agent)) - "*Headers to be generated or prompted for when mailing a message. -RFC822 required that From, Date, To, Subject and Message-ID be -included. Organization, Lines and User-Agent are optional." - :group 'message-mail - :group 'message-headers - :type '(repeat sexp)) - -(defcustom message-deletable-headers '(Message-ID Date Lines) - "Headers to be deleted if they already exist and were generated by message previously." - :group 'message-headers - :type 'sexp) - -(defcustom message-ignored-news-headers - "^NNTP-Posting-Host:\\|^Xref:\\|^[BGF]cc:\\|^Resent-Fcc:" - "*Regexp of headers to be removed unconditionally before posting." - :group 'message-news - :group 'message-headers - :type 'regexp) - -(defcustom message-ignored-mail-headers "^[GF]cc:\\|^Resent-Fcc:\\|^Xref:" - "*Regexp of headers to be removed unconditionally before mailing." - :group 'message-mail - :group 'message-headers - :type 'regexp) - -(defcustom message-ignored-supersedes-headers "^Path:\\|^Date\\|^NNTP-Posting-Host:\\|^Xref:\\|^Lines:\\|^Received:\\|^X-From-Line:\\|^X-Trace:\\|^X-Complaints-To:\\|Return-Path:\\|^Supersedes:\\|^X-Trace:\\|^X-Complaints-To:" - "*Header lines matching this regexp will be deleted before posting. -It's best to delete old Path and Date headers before posting to avoid -any confusion." - :group 'message-interface - :type 'regexp) - -(defcustom message-subject-re-regexp "^[ \t]*\\([Rr][Ee]:[ \t]*\\)*[ \t]*" - "*Regexp matching \"Re: \" in the subject line." - :group 'message-various - :type 'regexp) - -;;;###autoload -(defcustom message-signature-separator "^-- *$" - "Regexp matching the signature separator." - :type 'regexp - :group 'message-various) - -(defcustom message-elide-elipsis "\n[...]\n\n" - "*The string which is inserted for elided text." - :type 'string - :group 'message-various) - -(defcustom message-interactive nil - "Non-nil means when sending a message wait for and display errors. -nil means let mailer mail back a message to report errors." - :group 'message-sending - :group 'message-mail - :type 'boolean) - -(defcustom message-generate-new-buffers t - "*Non-nil means that a new message buffer will be created whenever `message-setup' is called. -If this is a function, call that function with three parameters: The type, -the to address and the group name. (Any of these may be nil.) The function -should return the new buffer name." - :group 'message-buffers - :type '(choice (const :tag "off" nil) - (const :tag "on" t) - (function fun))) - -(defcustom message-kill-buffer-on-exit nil - "*Non-nil means that the message buffer will be killed after sending a message." - :group 'message-buffers - :type 'boolean) - -(defvar gnus-local-organization) -(defcustom message-user-organization - (or (and (boundp 'gnus-local-organization) - (stringp gnus-local-organization) - gnus-local-organization) - (getenv "ORGANIZATION") - t) - "*String to be used as an Organization header. -If t, use `message-user-organization-file'." - :group 'message-headers - :type '(choice string - (const :tag "consult file" t))) - -;;;###autoload -(defcustom message-user-organization-file "/usr/lib/news/organization" - "*Local news organization file." - :type 'file - :group 'message-headers) - -(defcustom message-forward-start-separator - (concat (mime-make-tag "message" "rfc822") "\n") - "*Delimiter inserted before forwarded messages." - :group 'message-forwarding - :type 'string) - -(defcustom message-forward-end-separator - (concat (mime-make-tag "text" "plain") "\n") - "*Delimiter inserted after forwarded messages." - :group 'message-forwarding - :type 'string) - -(defcustom message-signature-before-forwarded-message t - "*If non-nil, put the signature before any included forwarded message." - :group 'message-forwarding - :type 'boolean) - -(defcustom message-included-forward-headers - "^From:\\|^Newsgroups:\\|^Subject:\\|^Date:\\|^Followup-To:\\|^Reply-To:\\|^Organization:\\|^Summary:\\|^Keywords:\\|^To:\\|^Cc:\\|^Posted-To:\\|^Mail-Copies-To:\\|^Apparently-To:\\|^Gnus-Warning:\\|^Resent-\\|^Message-ID:\\|^References:\\|^Content-Transfer-Encoding:\\|^Content-Type:\\|^MIME-Version:" - "*Regexp matching headers to be included in forwarded messages." - :group 'message-forwarding - :type 'regexp) - -(defcustom message-make-forward-subject-function - 'message-forward-subject-author-subject - "*A list of functions that are called to generate a subject header for forwarded messages. -The subject generated by the previous function is passed into each -successive function. - -The provided functions are: - -* message-forward-subject-author-subject (Source of article (author or - newsgroup)), in brackets followed by the subject -* message-forward-subject-fwd (Subject of article with 'Fwd:' prepended - to it." - :group 'message-forwarding - :type '(radio (function-item message-forward-subject-author-subject) - (function-item message-forward-subject-fwd))) - -(defcustom message-wash-forwarded-subjects nil - "*If non-nil, try to remove as much old cruft as possible from the subject of messages before generating the new subject of a forward." - :group 'message-forwarding - :type 'boolean) - -(defcustom message-ignored-resent-headers "^Return-receipt" - "*All headers that match this regexp will be deleted when resending a message." - :group 'message-interface - :type 'regexp) - -(defcustom message-ignored-cited-headers "." - "*Delete these headers from the messages you yank." - :group 'message-insertion - :type 'regexp) - -(defcustom message-cancel-message "I am canceling my own article." - "Message to be inserted in the cancel message." - :group 'message-interface - :type 'string) - -;; Useful to set in site-init.el -;;;###autoload -(defcustom message-send-mail-function 'message-send-mail-with-sendmail - "Function to call to send the current buffer as mail. -The headers should be delimited by a line whose contents match the -variable `mail-header-separator'. - -Legal values include `message-send-mail-with-sendmail' (the default), -`message-send-mail-with-mh', `message-send-mail-with-qmail' and -`message-send-mail-with-smtp'." - :type '(radio (function-item message-send-mail-with-sendmail) - (function-item message-send-mail-with-mh) - (function-item message-send-mail-with-qmail) - (function-item message-send-mail-with-smtp) - (function :tag "Other")) - :group 'message-sending - :group 'message-mail) - -;; 1997-09-29 by MORIOKA Tomohiko -(defcustom message-send-news-function 'message-send-news-with-gnus - "Function to call to send the current buffer as news. -The headers should be delimited by a line whose contents match the -variable `mail-header-separator'." - :group 'message-sending - :group 'message-news - :type 'function) - -(defcustom message-reply-to-function nil - "Function that should return a list of headers. -This function should pick out addresses from the To, Cc, and From headers -and respond with new To and Cc headers." - :group 'message-interface - :type 'function) - -(defcustom message-wide-reply-to-function nil - "Function that should return a list of headers. -This function should pick out addresses from the To, Cc, and From headers -and respond with new To and Cc headers." - :group 'message-interface - :type 'function) - -(defcustom message-followup-to-function nil - "Function that should return a list of headers. -This function should pick out addresses from the To, Cc, and From headers -and respond with new To and Cc headers." - :group 'message-interface - :type 'function) - -(defcustom message-use-followup-to 'ask - "*Specifies what to do with Followup-To header. -If nil, always ignore the header. If it is t, use its value, but -query before using the \"poster\" value. If it is the symbol `ask', -always query the user whether to use the value. If it is the symbol -`use', always use the value." - :group 'message-interface - :type '(choice (const :tag "ignore" nil) - (const use) - (const ask))) - -;; stuff relating to broken sendmail in MMDF -(defcustom message-sendmail-f-is-evil nil - "*Non-nil means that \"-f username\" should not be added to the sendmail -command line, because it is even more evil than leaving it out." - :group 'message-sending - :type 'boolean) - -;; qmail-related stuff -(defcustom message-qmail-inject-program "/var/qmail/bin/qmail-inject" - "Location of the qmail-inject program." - :group 'message-sending - :type 'file) - -(defcustom message-qmail-inject-args nil - "Arguments passed to qmail-inject programs. -This should be a list of strings, one string for each argument. - -For e.g., if you wish to set the envelope sender address so that bounces -go to the right place or to deal with listserv's usage of that address, you -might set this variable to '(\"-f\" \"you@some.where\")." - :group 'message-sending - :type '(repeat string)) - -(defvar gnus-post-method) -(defvar gnus-select-method) -(defcustom message-post-method - (cond ((and (boundp 'gnus-post-method) - (listp gnus-post-method) - gnus-post-method) - gnus-post-method) - ((boundp 'gnus-select-method) - gnus-select-method) - (t '(nnspool ""))) - "*Method used to post news. -Note that when posting from inside Gnus, for instance, this -variable isn't used." - :group 'message-news - :group 'message-sending - ;; This should be the `gnus-select-method' widget, but that might - ;; create a dependence to `gnus.el'. - :type 'sexp) - -(defcustom message-generate-headers-first nil - "*If non-nil, generate all possible headers before composing." - :group 'message-headers - :type 'boolean) - -(defcustom message-setup-hook - '(message-maybe-setup-default-charset turn-on-mime-edit) - "Normal hook, run each time a new outgoing message is initialized. -The function `message-setup' runs this hook." - :group 'message-various - :type 'hook) - -(defcustom message-signature-setup-hook nil - "Normal hook, run each time a new outgoing message is initialized. -It is run after the headers have been inserted and before -the signature is inserted." - :group 'message-various - :type 'hook) - -(defcustom message-mode-hook nil - "Hook run in message mode buffers." - :group 'message-various - :type 'hook) - -(defcustom message-header-hook '(eword-encode-header) - "Hook run in a message mode buffer narrowed to the headers." - :group 'message-various - :type 'hook) - -(defcustom message-header-setup-hook nil - "Hook called narrowed to the headers when setting up a message buffer." - :group 'message-various - :type 'hook) - -;;;###autoload -(defcustom message-citation-line-function 'message-insert-citation-line - "*Function called to insert the \"Whomever writes:\" line." - :type 'function - :group 'message-insertion) - -;;;###autoload -(defcustom message-yank-prefix "> " - "*Prefix inserted on the lines of yanked messages. -nil means use indentation." - :type 'string - :group 'message-insertion) - -(defcustom message-indentation-spaces 3 - "*Number of spaces to insert at the beginning of each cited line. -Used by `message-yank-original' via `message-yank-cite'." - :group 'message-insertion - :type 'integer) - -;;;###autoload -(defcustom message-cite-function 'message-cite-original - "*Function for citing an original message. -Predefined functions include `message-cite-original' and -`message-cite-original-without-signature'. -Note that `message-cite-original' uses `mail-citation-hook' if that is non-nil." - :type '(radio (function-item message-cite-original) - (function-item sc-cite-original) - (function :tag "Other")) - :group 'message-insertion) - -;;;###autoload -(defcustom message-indent-citation-function 'message-indent-citation - "*Function for modifying a citation just inserted in the mail buffer. -This can also be a list of functions. Each function can find the -citation between (point) and (mark t). And each function should leave -point and mark around the citation text as modified." - :type 'function - :group 'message-insertion) - -(defvar message-abbrevs-loaded nil) - -;;;###autoload -(defcustom message-signature t - "*String to be inserted at the end of the message buffer. -If t, the `message-signature-file' file will be inserted instead. -If a function, the result from the function will be used instead. -If a form, the result from the form will be used instead." - :type 'sexp - :group 'message-insertion) - -;;;###autoload -(defcustom message-signature-file "~/.signature" - "*File containing the text inserted at end of message buffer." - :type 'file - :group 'message-insertion) - -(defcustom message-distribution-function nil - "*Function called to return a Distribution header." - :group 'message-news - :group 'message-headers - :type 'function) - -(defcustom message-expires 14 - "Number of days before your article expires." - :group 'message-news - :group 'message-headers - :link '(custom-manual "(message)News Headers") - :type 'integer) - -(defcustom message-user-path nil - "If nil, use the NNTP server name in the Path header. -If stringp, use this; if non-nil, use no host name (user name only)." - :group 'message-news - :group 'message-headers - :link '(custom-manual "(message)News Headers") - :type '(choice (const :tag "nntp" nil) - (string :tag "name") - (sexp :tag "none" :format "%t" t))) - -(defvar message-reply-buffer nil) -(defvar message-reply-headers nil) -(defvar message-newsreader nil) -(defvar message-mailer nil) -(defvar message-sent-message-via nil) -(defvar message-checksum nil) -(defvar message-send-actions nil - "A list of actions to be performed upon successful sending of a message.") -(defvar message-exit-actions nil - "A list of actions to be performed upon exiting after sending a message.") -(defvar message-kill-actions nil - "A list of actions to be performed before killing a message buffer.") -(defvar message-postpone-actions nil - "A list of actions to be performed after postponing a message.") -(defvar message-original-frame nil) - -(define-widget 'message-header-lines 'text - "All header lines must be LFD terminated." - :format "%t:%n%v" - :valid-regexp "^\\'" - :error "All header lines must be newline terminated") - -(defcustom message-default-headers "" - "*A string containing header lines to be inserted in outgoing messages. -It is inserted before you edit the message, so you can edit or delete -these lines." - :group 'message-headers - :type 'message-header-lines) - -(defcustom message-default-mail-headers "" - "*A string of header lines to be inserted in outgoing mails." - :group 'message-headers - :group 'message-mail - :type 'message-header-lines) - -(defcustom message-default-news-headers "" - "*A string of header lines to be inserted in outgoing news -articles." - :group 'message-headers - :group 'message-news - :type 'message-header-lines) - -;; Note: could use /usr/ucb/mail instead of sendmail; -;; options -t, and -v if not interactive. -(defcustom message-mailer-swallows-blank-line - (if (and (string-match "sparc-sun-sunos\\(\\'\\|[^5]\\)" - system-configuration) - (file-readable-p "/etc/sendmail.cf") - (let ((buffer (get-buffer-create " *temp*"))) - (unwind-protect - (save-excursion - (set-buffer buffer) - (insert-file-contents "/etc/sendmail.cf") - (goto-char (point-min)) - (let ((case-fold-search nil)) - (re-search-forward "^OR\\>" nil t))) - (kill-buffer buffer)))) - ;; According to RFC822, "The field-name must be composed of printable - ;; ASCII characters (i. e., characters that have decimal values between - ;; 33 and 126, except colon)", i. e., any chars except ctl chars, - ;; space, or colon. - '(looking-at "[ \t]\\|[][!\"#$%&'()*+,-./0-9;<=>?@A-Z\\\\^_`a-z{|}~]+:")) - "*Set this non-nil if the system's mailer runs the header and body together. -\(This problem exists on Sunos 4 when sendmail is run in remote mode.) -The value should be an expression to test whether the problem will -actually occur." - :group 'message-sending - :type 'sexp) - -;;; XXX: This symbol is overloaded! See below. -(defvar message-user-agent nil - "String of the form of PRODUCT/VERSION. Used for User-Agent header field.") - -;; Ignore errors in case this is used in Emacs 19. -;; Don't use ignore-errors because this is copied into loaddefs.el. -;;;###autoload -(condition-case nil - (define-mail-user-agent 'message-user-agent - 'message-mail 'message-send-and-exit - 'message-kill-buffer 'message-send-hook) - (error nil)) - -(defvar message-mh-deletable-headers '(Message-ID Date Lines Sender) - "If non-nil, delete the deletable headers before feeding to mh.") - -(defvar message-send-method-alist - '((news message-news-p message-send-via-news) - (mail message-mail-p message-send-via-mail)) - "Alist of ways to send outgoing messages. -Each element has the form - - \(TYPE PREDICATE FUNCTION) - -where TYPE is a symbol that names the method; PREDICATE is a function -called without any parameters to determine whether the message is -a message of type TYPE; and FUNCTION is a function to be called if -PREDICATE returns non-nil. FUNCTION is called with one parameter -- -the prefix.") - -(defvar message-mail-alias-type 'abbrev - "*What alias expansion type to use in Message buffers. -The default is `abbrev', which uses mailabbrev. nil switches -mail aliases off.") - -(defcustom message-autosave-directory - (nnheader-concat message-directory "drafts/") - "*Directory where Message autosaves buffers if Gnus isn't running. -If nil, Message won't autosave." - :group 'message-buffers - :type 'directory) - -;;; Internal variables. -;;; Well, not really internal. - -(defvar message-mode-syntax-table - (let ((table (copy-syntax-table text-mode-syntax-table))) - (modify-syntax-entry ?% ". " table) - table) - "Syntax table used while in Message mode.") - -(defvar message-mode-abbrev-table text-mode-abbrev-table - "Abbrev table used in Message mode buffers. -Defaults to `text-mode-abbrev-table'.") -(defgroup message-headers nil - "Message headers." - :link '(custom-manual "(message)Variables") - :group 'message) - -(defface message-header-to-face - '((((class color) - (background dark)) - (:foreground "green2" :bold t)) - (((class color) - (background light)) - (:foreground "MidnightBlue" :bold t)) - (t - (:bold t :italic t))) - "Face used for displaying From headers." - :group 'message-faces) - -(defface message-header-cc-face - '((((class color) - (background dark)) - (:foreground "green4" :bold t)) - (((class color) - (background light)) - (:foreground "MidnightBlue")) - (t - (:bold t))) - "Face used for displaying Cc headers." - :group 'message-faces) - -(defface message-header-subject-face - '((((class color) - (background dark)) - (:foreground "green3")) - (((class color) - (background light)) - (:foreground "navy blue" :bold t)) - (t - (:bold t))) - "Face used for displaying subject headers." - :group 'message-faces) - -(defface message-header-newsgroups-face - '((((class color) - (background dark)) - (:foreground "yellow" :bold t :italic t)) - (((class color) - (background light)) - (:foreground "blue4" :bold t :italic t)) - (t - (:bold t :italic t))) - "Face used for displaying newsgroups headers." - :group 'message-faces) - -(defface message-header-other-face - '((((class color) - (background dark)) - (:foreground "#b00000")) - (((class color) - (background light)) - (:foreground "steel blue")) - (t - (:bold t :italic t))) - "Face used for displaying newsgroups headers." - :group 'message-faces) - -(defface message-header-name-face - '((((class color) - (background dark)) - (:foreground "DarkGreen")) - (((class color) - (background light)) - (:foreground "cornflower blue")) - (t - (:bold t))) - "Face used for displaying header names." - :group 'message-faces) - -(defface message-header-xheader-face - '((((class color) - (background dark)) - (:foreground "blue")) - (((class color) - (background light)) - (:foreground "blue")) - (t - (:bold t))) - "Face used for displaying X-Header headers." - :group 'message-faces) - -(defface message-separator-face - '((((class color) - (background dark)) - (:foreground "blue3")) - (((class color) - (background light)) - (:foreground "brown")) - (t - (:bold t))) - "Face used for displaying the separator." - :group 'message-faces) - -(defface message-cited-text-face - '((((class color) - (background dark)) - (:foreground "red")) - (((class color) - (background light)) - (:foreground "red")) - (t - (:bold t))) - "Face used for displaying cited text names." - :group 'message-faces) - -(defvar message-font-lock-keywords - (let* ((cite-prefix "A-Za-z") - (cite-suffix (concat cite-prefix "0-9_.@-")) - (content "[ \t]*\\(.+\\(\n[ \t].*\\)*\\)")) - `((,(concat "^\\([Tt]o:\\)" content) - (1 'message-header-name-face) - (2 'message-header-to-face nil t)) - (,(concat "^\\(^[GBF]?[Cc][Cc]:\\|^[Rr]eply-[Tt]o:\\)" content) - (1 'message-header-name-face) - (2 'message-header-cc-face nil t)) - (,(concat "^\\([Ss]ubject:\\)" content) - (1 'message-header-name-face) - (2 'message-header-subject-face nil t)) - (,(concat "^\\([Nn]ewsgroups:\\|Followup-[Tt]o:\\)" content) - (1 'message-header-name-face) - (2 'message-header-newsgroups-face nil t)) - (,(concat "^\\([A-Z][^: \n\t]+:\\)" content) - (1 'message-header-name-face) - (2 'message-header-other-face nil t)) - (,(concat "^\\(X-[A-Za-z0-9-]+\\|In-Reply-To\\):" content) - (1 'message-header-name-face) - (2 'message-header-name-face)) - ,@(if (and mail-header-separator - (not (equal mail-header-separator ""))) - `((,(concat "^\\(" (regexp-quote mail-header-separator) "\\)$") - 1 'message-separator-face)) - nil) - (,(concat "^[ \t]*" - "\\([" cite-prefix "]+[" cite-suffix "]*\\)?" - "[:>|}].*") - (0 'message-cited-text-face)))) - "Additional expressions to highlight in Message mode.") - -;; XEmacs does it like this. For Emacs, we have to set the -;; `font-lock-defaults' buffer-local variable. -(put 'message-mode 'font-lock-defaults '(message-font-lock-keywords t)) - -(defvar message-face-alist - '((bold . bold-region) - (underline . underline-region) - (default . (lambda (b e) - (unbold-region b e) - (ununderline-region b e)))) - "Alist of mail and news faces for facemenu. -The cdr of ech entry is a function for applying the face to a region.") - -(defcustom message-send-hook nil - "Hook run before sending messages." - :group 'message-various - :options '(ispell-message) - :type 'hook) - -(defcustom message-send-mail-hook nil - "Hook run before sending mail messages." - :group 'message-various - :type 'hook) - -(defcustom message-send-news-hook nil - "Hook run before sending news messages." - :group 'message-various - :type 'hook) - -(defcustom message-sent-hook nil - "Hook run after sending messages." - :group 'message-various - :type 'hook) - -(defcustom message-use-multi-frames nil - "Make new frame when sending messages." - :group 'message-frames - :type 'boolean) - -(defcustom message-delete-frame-on-exit nil - "Delete frame after sending messages." - :group 'message-frames - :type '(choice (const :tag "off" nil) - (const :tag "always" t) - (const :tag "ask" ask))) - -(defvar message-send-coding-system 'binary - "Coding system to encode outgoing mail.") - -;;; Internal variables. - -(defvar message-buffer-list nil) -(defvar message-this-is-news nil) -(defvar message-this-is-mail nil) -(defvar message-draft-article nil) - -;; Byte-compiler warning -(defvar gnus-active-hashtb) -(defvar gnus-read-active-file) - -;;; Regexp matching the delimiter of messages in UNIX mail format -;;; (UNIX From lines), minus the initial ^. It should be a copy -;;; of rmail.el's rmail-unix-mail-delimiter. -(defvar message-unix-mail-delimiter - (let ((time-zone-regexp - (concat "\\([A-Z]?[A-Z]?[A-Z][A-Z]\\( DST\\)?" - "\\|[-+]?[0-9][0-9][0-9][0-9]" - "\\|" - "\\) *"))) - (concat - "From " - - ;; Many things can happen to an RFC 822 mailbox before it is put into - ;; a `From' line. The leading phrase can be stripped, e.g. - ;; `Joe <@w.x:joe@y.z>' -> `<@w.x:joe@y.z>'. The <> can be stripped, e.g. - ;; `<@x.y:joe@y.z>' -> `@x.y:joe@y.z'. Everything starting with a CRLF - ;; can be removed, e.g. - ;; From: joe@y.z (Joe K - ;; User) - ;; can yield `From joe@y.z (Joe K Fri Mar 22 08:11:15 1996', and - ;; From: Joe User - ;; - ;; can yield `From Joe User Fri Mar 22 08:11:15 1996'. - ;; The mailbox can be removed or be replaced by white space, e.g. - ;; From: "Joe User"{space}{tab} - ;; - ;; can yield `From {space}{tab} Fri Mar 22 08:11:15 1996', - ;; where {space} and {tab} represent the Ascii space and tab characters. - ;; We want to match the results of any of these manglings. - ;; The following regexp rejects names whose first characters are - ;; obviously bogus, but after that anything goes. - "\\([^\0-\b\n-\r\^?].*\\)? " - - ;; The time the message was sent. - "\\([^\0-\r \^?]+\\) +" ; day of the week - "\\([^\0-\r \^?]+\\) +" ; month - "\\([0-3]?[0-9]\\) +" ; day of month - "\\([0-2][0-9]:[0-5][0-9]\\(:[0-6][0-9]\\)?\\) *" ; time of day - - ;; Perhaps a time zone, specified by an abbreviation, or by a - ;; numeric offset. - time-zone-regexp - - ;; The year. - " \\([0-9][0-9]+\\) *" - - ;; On some systems the time zone can appear after the year, too. - time-zone-regexp - - ;; Old uucp cruft. - "\\(remote from .*\\)?" - - "\n")) - "Regexp matching the delimiter of messages in UNIX mail format.") - -(defvar message-unsent-separator - (concat "^ *---+ +Unsent message follows +---+ *$\\|" - "^ *---+ +Returned message +---+ *$\\|" - "^Start of returned message$\\|" - "^ *---+ +Original message +---+ *$\\|" - "^ *--+ +begin message +--+ *$\\|" - "^ *---+ +Original message follows +---+ *$\\|" - "^|? *---+ +Message text follows: +---+ *|?$") - "A regexp that matches the separator before the text of a failed message.") - -(defvar message-header-format-alist - `((Newsgroups) - (To . message-fill-address) - (Cc . message-fill-address) - (Subject) - (In-Reply-To) - (Fcc) - (Bcc) - (Date) - (Organization) - (Distribution) - (Lines) - (Expires) - (Message-ID) - (References . message-fill-references) - (User-Agent)) - "Alist used for formatting headers.") - -(eval-and-compile - (autoload 'message-setup-toolbar "messagexmas") - (autoload 'mh-new-draft-name "mh-comp") - (autoload 'mh-send-letter "mh-comp") - (autoload 'gnus-point-at-eol "gnus-util") - (autoload 'gnus-point-at-bol "gnus-util") - (autoload 'gnus-output-to-mail "gnus-util") - (autoload 'gnus-output-to-rmail "gnus-util") - (autoload 'mail-abbrev-in-expansion-header-p "mailabbrev") - (autoload 'nndraft-request-associate-buffer "nndraft") - (autoload 'nndraft-request-expire-articles "nndraft") - (autoload 'gnus-open-server "gnus-int") - (autoload 'gnus-request-post "gnus-int") - (autoload 'gnus-copy-article-buffer "gnus-msg") - (autoload 'gnus-alive-p "gnus-util") - (autoload 'rmail-output "rmail")) - - - -;;; -;;; Utility functions. -;;; - -(defmacro message-y-or-n-p (question show &rest text) - "Ask QUESTION, displaying the rest of the arguments in a temp. buffer if SHOW" - `(message-talkative-question 'y-or-n-p ,question ,show ,@text)) - -;; Delete the current line (and the next N lines.); -(defmacro message-delete-line (&optional n) - `(delete-region (progn (beginning-of-line) (point)) - (progn (forward-line ,(or n 1)) (point)))) - -(defun message-tokenize-header (header &optional separator) - "Split HEADER into a list of header elements. -\",\" is used as the separator." - (if (not header) - nil - (let ((regexp (format "[%s]+" (or separator ","))) - (beg 1) - (first t) - quoted elems paren) - (save-excursion - (message-set-work-buffer) - (insert header) - (goto-char (point-min)) - (while (not (eobp)) - (if first - (setq first nil) - (forward-char 1)) - (cond ((and (> (point) beg) - (or (eobp) - (and (looking-at regexp) - (not quoted) - (not paren)))) - (push (buffer-substring beg (point)) elems) - (setq beg (match-end 0))) - ((= (following-char) ?\") - (setq quoted (not quoted))) - ((and (= (following-char) ?\() - (not quoted)) - (setq paren t)) - ((and (= (following-char) ?\)) - (not quoted)) - (setq paren nil)))) - (nreverse elems))))) - -(defun message-mail-file-mbox-p (file) - "Say whether FILE looks like a Unix mbox file." - (when (and (file-exists-p file) - (file-readable-p file) - (file-regular-p file)) - (nnheader-temp-write nil - (nnheader-insert-file-contents file) - (goto-char (point-min)) - (looking-at message-unix-mail-delimiter)))) - -(defun message-fetch-field (header &optional not-all) - "The same as `mail-fetch-field', only remove all newlines." - (let* ((inhibit-point-motion-hooks t) - (value (mail-fetch-field header nil (not not-all)))) - (when value - (nnheader-replace-chars-in-string value ?\n ? )))) - -(defun message-add-header (&rest headers) - "Add the HEADERS to the message header, skipping those already present." - (while headers - (let (hclean) - (unless (string-match "^\\([^:]+\\):[ \t]*[^ \t]" (car headers)) - (error "Invalid header `%s'" (car headers))) - (setq hclean (match-string 1 (car headers))) - (save-restriction - (message-narrow-to-headers) - (unless (re-search-forward (concat "^" (regexp-quote hclean) ":") nil t) - (insert (car headers) ?\n)))) - (setq headers (cdr headers)))) - -(defun message-fetch-reply-field (header) - "Fetch FIELD from the message we're replying to." - (when (and message-reply-buffer - (buffer-name message-reply-buffer)) - (save-excursion - (set-buffer message-reply-buffer) - (message-fetch-field header)))) - -(defun message-set-work-buffer () - (if (get-buffer " *message work*") - (progn - (set-buffer " *message work*") - (erase-buffer)) - (set-buffer (get-buffer-create " *message work*")) - (kill-all-local-variables) - (buffer-disable-undo (current-buffer)))) - -(defun message-functionp (form) - "Return non-nil if FORM is funcallable." - (or (and (symbolp form) (fboundp form)) - (and (listp form) (eq (car form) 'lambda)) - (byte-code-function-p form))) - -(defun message-strip-subject-re (subject) - "Remove \"Re:\" from subject lines." - (if (string-match message-subject-re-regexp subject) - (substring subject (match-end 0)) - subject)) - -(defun message-remove-header (header &optional is-regexp first reverse) - "Remove HEADER in the narrowed buffer. -If REGEXP, HEADER is a regular expression. -If FIRST, only remove the first instance of the header. -Return the number of headers removed." - (goto-char (point-min)) - (let ((regexp (if is-regexp header (concat "^" (regexp-quote header) ":"))) - (number 0) - (case-fold-search t) - last) - (while (and (not (eobp)) - (not last)) - (if (if reverse - (not (looking-at regexp)) - (looking-at regexp)) - (progn - (incf number) - (when first - (setq last t)) - (delete-region - (point) - ;; There might be a continuation header, so we have to search - ;; until we find a new non-continuation line. - (progn - (forward-line 1) - (if (re-search-forward "^[^ \t]" nil t) - (goto-char (match-beginning 0)) - (point-max))))) - (forward-line 1) - (if (re-search-forward "^[^ \t]" nil t) - (goto-char (match-beginning 0)) - (point-max)))) - number)) - -(defun message-narrow-to-headers () - "Narrow the buffer to the head of the message." - (widen) - (narrow-to-region - (goto-char (point-min)) - (if (re-search-forward - (concat "^" (regexp-quote mail-header-separator) "\n") nil t) - (match-beginning 0) - (point-max))) - (goto-char (point-min))) - -(defun message-narrow-to-head () - "Narrow the buffer to the head of the message." - (widen) - (narrow-to-region - (goto-char (point-min)) - (if (search-forward "\n\n" nil 1) - (1- (point)) - (point-max))) - (goto-char (point-min))) - -(defun message-news-p () - "Say whether the current buffer contains a news message." - (and (not message-this-is-mail) - (or message-this-is-news - (save-excursion - (save-restriction - (message-narrow-to-headers) - (and (message-fetch-field "newsgroups") - (not (message-fetch-field "posted-to")))))))) - -(defun message-mail-p () - "Say whether the current buffer contains a mail message." - (and (not message-this-is-news) - (or message-this-is-mail - (save-excursion - (save-restriction - (message-narrow-to-headers) - (or (message-fetch-field "to") - (message-fetch-field "cc") - (message-fetch-field "bcc"))))))) - -(defun message-next-header () - "Go to the beginning of the next header." - (beginning-of-line) - (or (eobp) (forward-char 1)) - (not (if (re-search-forward "^[^ \t]" nil t) - (beginning-of-line) - (goto-char (point-max))))) - -(defun message-sort-headers-1 () - "Sort the buffer as headers using `message-rank' text props." - (goto-char (point-min)) - (sort-subr - nil 'message-next-header - (lambda () - (message-next-header) - (unless (bobp) - (forward-char -1))) - (lambda () - (or (get-text-property (point) 'message-rank) - 10000)))) - -(defun message-sort-headers () - "Sort the headers of the current message according to `message-header-format-alist'." - (interactive) - (save-excursion - (save-restriction - (let ((max (1+ (length message-header-format-alist))) - rank) - (message-narrow-to-headers) - (while (re-search-forward "^[^ \n]+:" nil t) - (put-text-property - (match-beginning 0) (1+ (match-beginning 0)) - 'message-rank - (if (setq rank (length (memq (assq (intern (buffer-substring - (match-beginning 0) - (1- (match-end 0)))) - message-header-format-alist) - message-header-format-alist))) - (- max rank) - (1+ max))))) - (message-sort-headers-1)))) - - - -;;; -;;; Message mode -;;; - -;;; Set up keymap. - -(defvar message-mode-map nil) - -(unless message-mode-map - (setq message-mode-map (copy-keymap text-mode-map)) - (define-key message-mode-map "\C-c?" 'describe-mode) - - (define-key message-mode-map "\C-c\C-f\C-t" 'message-goto-to) - (define-key message-mode-map "\C-c\C-f\C-b" 'message-goto-bcc) - (define-key message-mode-map "\C-c\C-f\C-w" 'message-goto-fcc) - (define-key message-mode-map "\C-c\C-f\C-c" 'message-goto-cc) - (define-key message-mode-map "\C-c\C-f\C-s" 'message-goto-subject) - (define-key message-mode-map "\C-c\C-f\C-r" 'message-goto-reply-to) - (define-key message-mode-map "\C-c\C-f\C-n" 'message-goto-newsgroups) - (define-key message-mode-map "\C-c\C-f\C-d" 'message-goto-distribution) - (define-key message-mode-map "\C-c\C-f\C-f" 'message-goto-followup-to) - (define-key message-mode-map "\C-c\C-f\C-k" 'message-goto-keywords) - (define-key message-mode-map "\C-c\C-f\C-u" 'message-goto-summary) - (define-key message-mode-map "\C-c\C-b" 'message-goto-body) - (define-key message-mode-map "\C-c\C-i" 'message-goto-signature) - - (define-key message-mode-map "\C-c\C-t" 'message-insert-to) - (define-key message-mode-map "\C-c\C-n" 'message-insert-newsgroups) - - (define-key message-mode-map "\C-c\C-y" 'message-yank-original) - (define-key message-mode-map "\C-c\C-q" 'message-fill-yanked-message) - (define-key message-mode-map "\C-c\C-w" 'message-insert-signature) - (define-key message-mode-map "\C-c\C-r" 'message-caesar-buffer-body) - (define-key message-mode-map "\C-c\C-o" 'message-sort-headers) - (define-key message-mode-map "\C-c\M-r" 'message-rename-buffer) - - (define-key message-mode-map "\C-c\C-c" 'message-send-and-exit) - (define-key message-mode-map "\C-c\C-s" 'message-send) - (define-key message-mode-map "\C-c\C-k" 'message-kill-buffer) - (define-key message-mode-map "\C-c\C-d" 'message-dont-send) - - (define-key message-mode-map "\C-c\C-e" 'message-elide-region) - (define-key message-mode-map "\C-c\C-v" 'message-delete-not-region) - (define-key message-mode-map "\C-c\C-z" 'message-kill-to-signature) - (define-key message-mode-map "\M-\r" 'message-newline-and-reformat) - - (define-key message-mode-map "\t" 'message-tab)) - -(easy-menu-define - message-mode-menu message-mode-map "Message Menu." - '("Message" - ["Sort Headers" message-sort-headers t] - ["Yank Original" message-yank-original t] - ["Fill Yanked Message" message-fill-yanked-message t] - ["Insert Signature" message-insert-signature t] - ["Caesar (rot13) Message" message-caesar-buffer-body t] - ["Caesar (rot13) Region" message-caesar-region (mark t)] - ["Elide Region" message-elide-region (mark t)] - ["Delete Outside Region" message-delete-not-region (mark t)] - ["Kill To Signature" message-kill-to-signature t] - ["Newline and Reformat" message-newline-and-reformat t] - ["Rename buffer" message-rename-buffer t] - ["Spellcheck" ispell-message t] - "----" - ["Send Message" message-send-and-exit t] - ["Abort Message" message-dont-send t] - ["Kill Message" message-kill-buffer t])) - -(easy-menu-define - message-mode-field-menu message-mode-map "" - '("Field" - ["Fetch To" message-insert-to t] - ["Fetch Newsgroups" message-insert-newsgroups t] - "----" - ["To" message-goto-to t] - ["Subject" message-goto-subject t] - ["Cc" message-goto-cc t] - ["Reply-To" message-goto-reply-to t] - ["Summary" message-goto-summary t] - ["Keywords" message-goto-keywords t] - ["Newsgroups" message-goto-newsgroups t] - ["Followup-To" message-goto-followup-to t] - ["Distribution" message-goto-distribution t] - ["Body" message-goto-body t] - ["Signature" message-goto-signature t])) - -(defvar facemenu-add-face-function) -(defvar facemenu-remove-face-function) - -;;;###autoload -(defun message-mode () - "Major mode for editing mail and news to be sent. -Like Text Mode but with these additional commands: -C-c C-s message-send (send the message) C-c C-c message-send-and-exit -C-c C-f move to a header field (and create it if there isn't): - C-c C-f C-t move to To C-c C-f C-s move to Subject - C-c C-f C-c move to Cc C-c C-f C-b move to Bcc - C-c C-f C-w move to Fcc C-c C-f C-r move to Reply-To - C-c C-f C-u move to Summary C-c C-f C-n move to Newsgroups - C-c C-f C-k move to Keywords C-c C-f C-d move to Distribution - C-c C-f C-f move to Followup-To -C-c C-t message-insert-to (add a To header to a news followup) -C-c C-n message-insert-newsgroups (add a Newsgroup header to a news reply) -C-c C-b message-goto-body (move to beginning of message text). -C-c C-i message-goto-signature (move to the beginning of the signature). -C-c C-w message-insert-signature (insert `message-signature-file' file). -C-c C-y message-yank-original (insert current message, if any). -C-c C-q message-fill-yanked-message (fill what was yanked). -C-c C-e message-elide-region (elide the text between point and mark). -C-c C-z message-kill-to-signature (kill the text up to the signature). -C-c C-r message-caesar-buffer-body (rot13 the message body)." - (interactive) - (kill-all-local-variables) - (make-local-variable 'message-reply-buffer) - (setq message-reply-buffer nil) - (make-local-variable 'message-send-actions) - (make-local-variable 'message-exit-actions) - (make-local-variable 'message-kill-actions) - (make-local-variable 'message-postpone-actions) - (make-local-variable 'message-draft-article) - (make-local-hook 'kill-buffer-hook) - (set-syntax-table message-mode-syntax-table) - (use-local-map message-mode-map) - (setq local-abbrev-table message-mode-abbrev-table) - (setq major-mode 'message-mode) - (setq mode-name "Message") - (setq buffer-offer-save t) - (make-local-variable 'facemenu-add-face-function) - (make-local-variable 'facemenu-remove-face-function) - (setq facemenu-add-face-function - (lambda (face end) - (let ((face-fun (cdr (assq face message-face-alist)))) - (if face-fun - (funcall face-fun (point) end) - (error "Face %s not configured for %s mode" face mode-name))) - "") - facemenu-remove-face-function t) - (make-local-variable 'paragraph-separate) - (make-local-variable 'paragraph-start) - ;; `-- ' precedes the signature. `-----' appears at the start of the - ;; lines that delimit forwarded messages. - ;; Lines containing just >= 3 dashes, perhaps after whitespace, - ;; are also sometimes used and should be separators. - (setq paragraph-start - (concat (regexp-quote mail-header-separator) - "$\\|[ \t]*[a-z0-9A-Z]*>+[ \t]*$\\|[ \t]*$\\|" - "-- $\\|---+$\\|" - page-delimiter - ;;!!! Uhm... shurely this can't be right? - "[> " (regexp-quote message-yank-prefix) "]+$")) - (setq paragraph-separate paragraph-start) - (make-local-variable 'message-reply-headers) - (setq message-reply-headers nil) - (make-local-variable 'message-user-agent) - (make-local-variable 'message-post-method) - (make-local-variable 'message-sent-message-via) - (setq message-sent-message-via nil) - (make-local-variable 'message-checksum) - (setq message-checksum nil) - ;;(when (fboundp 'mail-hist-define-keys) - ;; (mail-hist-define-keys)) - (when (string-match "XEmacs\\|Lucid" emacs-version) - (message-setup-toolbar)) - (easy-menu-add message-mode-menu message-mode-map) - (easy-menu-add message-mode-field-menu message-mode-map) - ;; Allow mail alias things. - (when (eq message-mail-alias-type 'abbrev) - (if (fboundp 'mail-abbrevs-setup) - (mail-abbrevs-setup) - (mail-aliases-setup))) - (message-set-auto-save-file-name) - (unless (string-match "XEmacs" emacs-version) - (set (make-local-variable 'font-lock-defaults) - '(message-font-lock-keywords t))) - (make-local-variable 'adaptive-fill-regexp) - (setq adaptive-fill-regexp - (concat "[ \t]*[-a-z0-9A-Z]*>+[ \t]*\\|" adaptive-fill-regexp)) - (unless (boundp 'adaptive-fill-first-line-regexp) - (setq adaptive-fill-first-line-regexp nil)) - (make-local-variable 'adaptive-fill-first-line-regexp) - (setq adaptive-fill-first-line-regexp - (concat "[ \t]*[-a-z0-9A-Z]*>+[ \t]*\\|" - adaptive-fill-first-line-regexp)) - (run-hooks 'text-mode-hook 'message-mode-hook)) - - - -;;; -;;; Message mode commands -;;; - -;;; Movement commands - -(defun message-goto-to () - "Move point to the To header." - (interactive) - (message-position-on-field "To")) - -(defun message-goto-subject () - "Move point to the Subject header." - (interactive) - (message-position-on-field "Subject")) - -(defun message-goto-cc () - "Move point to the Cc header." - (interactive) - (message-position-on-field "Cc" "To")) - -(defun message-goto-bcc () - "Move point to the Bcc header." - (interactive) - (message-position-on-field "Bcc" "Cc" "To")) - -(defun message-goto-fcc () - "Move point to the Fcc header." - (interactive) - (message-position-on-field "Fcc" "To" "Newsgroups")) - -(defun message-goto-reply-to () - "Move point to the Reply-To header." - (interactive) - (message-position-on-field "Reply-To" "Subject")) - -(defun message-goto-newsgroups () - "Move point to the Newsgroups header." - (interactive) - (message-position-on-field "Newsgroups")) - -(defun message-goto-distribution () - "Move point to the Distribution header." - (interactive) - (message-position-on-field "Distribution")) - -(defun message-goto-followup-to () - "Move point to the Followup-To header." - (interactive) - (message-position-on-field "Followup-To" "Newsgroups")) - -(defun message-goto-keywords () - "Move point to the Keywords header." - (interactive) - (message-position-on-field "Keywords" "Subject")) - -(defun message-goto-summary () - "Move point to the Summary header." - (interactive) - (message-position-on-field "Summary" "Subject")) - -(defun message-goto-body () - "Move point to the beginning of the message body." - (interactive) - (if (looking-at "[ \t]*\n") (expand-abbrev)) - (goto-char (point-min)) - (search-forward (concat "\n" mail-header-separator "\n") nil t)) - -(defun message-goto-eoh () - "Move point to the end of the headers." - (interactive) - (message-goto-body) - (forward-line -2)) - -(defun message-goto-signature () - "Move point to the beginning of the message signature. -If there is no signature in the article, go to the end and -return nil." - (interactive) - (goto-char (point-min)) - (if (re-search-forward message-signature-separator nil t) - (forward-line 1) - (goto-char (point-max)) - nil)) - - - -(defun message-insert-to (&optional force) - "Insert a To header that points to the author of the article being replied to. -If the original author requested not to be sent mail, the function signals -an error. -With the prefix argument FORCE, insert the header anyway." - (interactive "P") - (let ((co (message-fetch-reply-field "mail-copies-to"))) - (when (and (null force) - co - (equal (downcase co) "never")) - (error "The user has requested not to have copies sent via mail"))) - (when (and (message-position-on-field "To") - (mail-fetch-field "to") - (not (string-match "\\` *\\'" (mail-fetch-field "to")))) - (insert ", ")) - (insert (or (message-fetch-reply-field "reply-to") - (message-fetch-reply-field "from") ""))) - -(defun message-insert-newsgroups () - "Insert the Newsgroups header from the article being replied to." - (interactive) - (when (and (message-position-on-field "Newsgroups") - (mail-fetch-field "newsgroups") - (not (string-match "\\` *\\'" (mail-fetch-field "newsgroups")))) - (insert ",")) - (insert (or (message-fetch-reply-field "newsgroups") ""))) - - - -;;; Various commands - -(defun message-delete-not-region (beg end) - "Delete everything in the body of the current message that is outside of the region." - (interactive "r") - (save-excursion - (goto-char end) - (delete-region (point) (if (not (message-goto-signature)) - (point) - (forward-line -2) - (point))) - (insert "\n") - (goto-char beg) - (delete-region beg (progn (message-goto-body) - (forward-line 2) - (point)))) - (when (message-goto-signature) - (forward-line -2))) - -(defun message-kill-to-signature () - "Deletes all text up to the signature." - (interactive) - (let ((point (point))) - (message-goto-signature) - (unless (eobp) - (forward-line -2)) - (kill-region point (point)) - (unless (bolp) - (insert "\n")))) - -(defun message-newline-and-reformat () - "Insert four newlines, and then reformat if inside quoted text." - (interactive) - (let ((point (point)) - quoted) - (save-excursion - (beginning-of-line) - (setq quoted (looking-at (regexp-quote message-yank-prefix)))) - (insert "\n\n\n\n") - (when quoted - (insert message-yank-prefix)) - (fill-paragraph nil) - (goto-char point) - (forward-line 2))) - -(defun message-insert-signature (&optional force) - "Insert a signature. See documentation for the `message-signature' variable." - (interactive (list 0)) - (let* ((signature - (cond - ((and (null message-signature) - (eq force 0)) - (save-excursion - (goto-char (point-max)) - (not (re-search-backward - message-signature-separator nil t)))) - ((and (null message-signature) - force) - t) - ((message-functionp message-signature) - (funcall message-signature)) - ((listp message-signature) - (eval message-signature)) - (t message-signature))) - (signature - (cond ((stringp signature) - signature) - ((and (eq t signature) - message-signature-file - (file-exists-p message-signature-file)) - signature)))) - (when signature - (goto-char (point-max)) - ;; Insert the signature. - (unless (bolp) - (insert "\n")) - (insert "\n-- \n") - (if (eq signature t) - (insert-file-contents message-signature-file) - (insert signature)) - (goto-char (point-max)) - (or (bolp) (insert "\n"))))) - -(defun message-elide-region (b e) - "Elide the text between point and mark. -An ellipsis (from `message-elide-elipsis') will be inserted where the -text was killed." - (interactive "r") - (kill-region b e) - (unless (bolp) - (insert "\n")) - (insert message-elide-elipsis)) - -(defvar message-caesar-translation-table nil) - -(defun message-caesar-region (b e &optional n) - "Caesar rotation of region by N, default 13, for decrypting netnews." - (interactive - (list - (min (point) (or (mark t) (point))) - (max (point) (or (mark t) (point))) - (when current-prefix-arg - (prefix-numeric-value current-prefix-arg)))) - - (setq n (if (numberp n) (mod n 26) 13)) ;canonize N - (unless (or (zerop n) ; no action needed for a rot of 0 - (= b e)) ; no region to rotate - ;; We build the table, if necessary. - (when (or (not message-caesar-translation-table) - (/= (aref message-caesar-translation-table ?a) (+ ?a n))) - (setq message-caesar-translation-table - (message-make-caesar-translation-table n))) - ;; Then we translate the region. Do it this way to retain - ;; text properties. - (while (< b e) - (subst-char-in-region - b (1+ b) (char-after b) - (aref message-caesar-translation-table (char-after b))) - (incf b)))) - -(defun message-make-caesar-translation-table (n) - "Create a rot table with offset N." - (let ((i -1) - (table (make-string 256 0))) - (while (< (incf i) 256) - (aset table i i)) - (concat - (substring table 0 ?A) - (substring table (+ ?A n) (+ ?A n (- 26 n))) - (substring table ?A (+ ?A n)) - (substring table (+ ?A 26) ?a) - (substring table (+ ?a n) (+ ?a n (- 26 n))) - (substring table ?a (+ ?a n)) - (substring table (+ ?a 26) 255)))) - -(defun message-caesar-buffer-body (&optional rotnum) - "Caesar rotates all letters in the current buffer by 13 places. -Used to encode/decode possiblyun offensive messages (commonly in net.jokes). -With prefix arg, specifies the number of places to rotate each letter forward. -Mail and USENET news headers are not rotated." - (interactive (if current-prefix-arg - (list (prefix-numeric-value current-prefix-arg)) - (list nil))) - (save-excursion - (save-restriction - (when (message-goto-body) - (narrow-to-region (point) (point-max))) - (message-caesar-region (point-min) (point-max) rotnum)))) - -(defun message-pipe-buffer-body (program) - "Pipe the message body in the current buffer through PROGRAM." - (save-excursion - (save-restriction - (when (message-goto-body) - (narrow-to-region (point) (point-max))) - (let ((body (buffer-substring (point-min) (point-max)))) - (unless (equal 0 (call-process-region - (point-min) (point-max) program t t)) - (insert body) - (message "%s failed." program)))))) - -(defun message-rename-buffer (&optional enter-string) - "Rename the *message* buffer to \"*message* RECIPIENT\". -If the function is run with a prefix, it will ask for a new buffer -name, rather than giving an automatic name." - (interactive "Pbuffer name: ") - (save-excursion - (save-restriction - (goto-char (point-min)) - (narrow-to-region (point) - (search-forward mail-header-separator nil 'end)) - (let* ((mail-to (or - (if (message-news-p) (message-fetch-field "Newsgroups") - (message-fetch-field "To")) - "")) - (mail-trimmed-to - (if (string-match "," mail-to) - (concat (substring mail-to 0 (match-beginning 0)) ", ...") - mail-to)) - (name-default (concat "*message* " mail-trimmed-to)) - (name (if enter-string - (read-string "New buffer name: " name-default) - name-default))) - (rename-buffer name t))))) - -(defun message-fill-yanked-message (&optional justifyp) - "Fill the paragraphs of a message yanked into this one. -Numeric argument means justify as well." - (interactive "P") - (save-excursion - (goto-char (point-min)) - (search-forward (concat "\n" mail-header-separator "\n") nil t) - (let ((fill-prefix message-yank-prefix)) - (fill-individual-paragraphs (point) (point-max) justifyp t)))) - -(defun message-indent-citation () - "Modify text just inserted from a message to be cited. -The inserted text should be the region. -When this function returns, the region is again around the modified text. - -Normally, indent each nonblank line `message-indentation-spaces' spaces. -However, if `message-yank-prefix' is non-nil, insert that prefix on each line." - (let ((start (point))) - ;; Remove unwanted headers. - (when message-ignored-cited-headers - (let (all-removed) - (save-restriction - (narrow-to-region - (goto-char start) - (if (search-forward "\n\n" nil t) - (1- (point)) - (point))) - (message-remove-header message-ignored-cited-headers t) - (when (= (point-min) (point-max)) - (setq all-removed t)) - (goto-char (point-max))) - (if all-removed - (goto-char start) - (forward-line 1)))) - ;; Delete blank lines at the start of the buffer. - (while (and (point-min) - (eolp) - (not (eobp))) - (message-delete-line)) - ;; Delete blank lines at the end of the buffer. - (goto-char (point-max)) - (unless (eolp) - (insert "\n")) - (while (and (zerop (forward-line -1)) - (looking-at "$")) - (message-delete-line)) - ;; Do the indentation. - (if (null message-yank-prefix) - (indent-rigidly start (mark t) message-indentation-spaces) - (save-excursion - (goto-char start) - (while (< (point) (mark t)) - (insert message-yank-prefix) - (forward-line 1)))) - (goto-char start))) - -(defvar gnus-article-copy) -(defun message-yank-original (&optional arg) - "Insert the message being replied to, if any. -Puts point before the text and mark after. -Normally indents each nonblank line ARG spaces (default 3). However, -if `message-yank-prefix' is non-nil, insert that prefix on each line. - -This function uses `message-cite-function' to do the actual citing. - -Just \\[universal-argument] as argument means don't indent, insert no -prefix, and don't delete any headers." - (interactive "P") - (let ((modified (buffer-modified-p))) - (when (and message-reply-buffer - message-cite-function) - (gnus-copy-article-buffer) - (setq message-reply-buffer gnus-article-copy) - (delete-windows-on message-reply-buffer t) - (insert-buffer message-reply-buffer) - (funcall message-cite-function) - (message-exchange-point-and-mark) - (unless (bolp) - (insert ?\n)) - (unless modified - (setq message-checksum (message-checksum)))))) - -(defun message-cite-original-without-signature () - "Cite function in the standard Message manner." - (let ((start (point)) - (end (mark t)) - (functions - (when message-indent-citation-function - (if (listp message-indent-citation-function) - message-indent-citation-function - (list message-indent-citation-function))))) - (goto-char end) - (when (re-search-backward "^-- $" start t) - ;; Also peel off any blank lines before the signature. - (forward-line -1) - (while (looking-at "^[ \t]*$") - (forward-line -1)) - (forward-line 1) - (delete-region (point) end)) - (goto-char start) - (while functions - (funcall (pop functions))) - (when message-citation-line-function - (unless (bolp) - (insert "\n")) - (funcall message-citation-line-function)))) - -(defvar mail-citation-hook) ;Compiler directive -(defun message-cite-original () - "Cite function in the standard Message manner." - (if (and (boundp 'mail-citation-hook) - mail-citation-hook) - (run-hooks 'mail-citation-hook) - (let ((start (point)) - (functions - (when message-indent-citation-function - (if (listp message-indent-citation-function) - message-indent-citation-function - (list message-indent-citation-function))))) - (goto-char start) - (while functions - (funcall (pop functions))) - (when message-citation-line-function - (unless (bolp) - (insert "\n")) - (funcall message-citation-line-function))))) - -(defun message-insert-citation-line () - "Function that inserts a simple citation line." - (when message-reply-headers - (insert (mail-header-from message-reply-headers) " writes:\n\n"))) - -(defun message-position-on-field (header &rest afters) - (let ((case-fold-search t)) - (save-restriction - (narrow-to-region - (goto-char (point-min)) - (progn - (re-search-forward - (concat "^" (regexp-quote mail-header-separator) "$")) - (match-beginning 0))) - (goto-char (point-min)) - (if (re-search-forward (concat "^" (regexp-quote header) ":") nil t) - (progn - (re-search-forward "^[^ \t]" nil 'move) - (beginning-of-line) - (skip-chars-backward "\n") - t) - (while (and afters - (not (re-search-forward - (concat "^" (regexp-quote (car afters)) ":") - nil t))) - (pop afters)) - (when afters - (re-search-forward "^[^ \t]" nil 'move) - (beginning-of-line)) - (insert header ": \n") - (forward-char -1) - nil)))) - -(defun message-remove-signature () - "Remove the signature from the text between point and mark. -The text will also be indented the normal way." - (save-excursion - (let ((start (point)) - mark) - (if (not (re-search-forward message-signature-separator (mark t) t)) - ;; No signature here, so we just indent the cited text. - (message-indent-citation) - ;; Find the last non-empty line. - (forward-line -1) - (while (looking-at "[ \t]*$") - (forward-line -1)) - (forward-line 1) - (setq mark (set-marker (make-marker) (point))) - (goto-char start) - (message-indent-citation) - ;; Enable undoing the deletion. - (undo-boundary) - (delete-region mark (mark t)) - (set-marker mark nil))))) - - - -;;; -;;; Sending messages -;;; - -;; Avoid byte-compile warning. -(defvar message-encoding-buffer nil) -(defvar message-edit-buffer nil) -(defvar message-mime-mode nil) - -(defun message-send-and-exit (&optional arg) - "Send message like `message-send', then, if no errors, exit from mail buffer." - (interactive "P") - (let ((buf (current-buffer)) - (actions message-exit-actions) - (frame (selected-frame)) - (org-frame message-original-frame)) - (when (and (message-send arg) - (buffer-name buf)) - (if message-kill-buffer-on-exit - (kill-buffer buf) - (bury-buffer buf) - (when (eq buf (current-buffer)) - (message-bury buf))) - (message-do-actions actions) - (message-delete-frame frame org-frame) - t))) - -(defun message-dont-send () - "Don't send the message you have been editing." - (interactive) - (set-buffer-modified-p t) - (save-buffer) - (let ((actions message-postpone-actions)) - (message-bury (current-buffer)) - (message-do-actions actions))) - -(defun message-kill-buffer () - "Kill the current buffer." - (interactive) - (when (or (not (buffer-modified-p)) - (yes-or-no-p "Message modified; kill anyway? ")) - (let ((actions message-kill-actions) - (frame (selected-frame)) - (org-frame message-original-frame)) - (setq buffer-file-name nil) - (kill-buffer (current-buffer)) - (message-do-actions actions) - (message-delete-frame frame org-frame)))) - -(defun message-delete-frame (frame org-frame) - "Delete frame for editing message." - (when (and (or (and (featurep 'xemacs) - (not (eq 'tty (device-type)))) - window-system - (>= emacs-major-version 20)) - (or (and (eq message-delete-frame-on-exit t) - (select-frame frame) - (or (eq frame org-frame) - (prog1 - (y-or-n-p "Delete this frame?") - (message "")))) - (and (eq message-delete-frame-on-exit 'ask) - (select-frame frame) - (prog1 - (y-or-n-p "Delete this frame?") - (message ""))))) - (delete-frame frame))) - -(defun message-bury (buffer) - "Bury this mail buffer." - (let ((newbuf (other-buffer buffer))) - (bury-buffer buffer) - (if (and (fboundp 'frame-parameters) - (cdr (assq 'dedicated (frame-parameters))) - (not (null (delq (selected-frame) (visible-frame-list))))) - (delete-frame (selected-frame)) - (switch-to-buffer newbuf)))) - -(defun message-send (&optional arg) - "Send the message in the current buffer. -If `message-interactive' is non-nil, wait for success indication -or error messages, and inform user. -Otherwise any failure is reported in a message back to -the user from the mailer." - (interactive "P") - ;; Disabled test. - (when (or (buffer-modified-p) - (message-check-element 'unchanged) - (y-or-n-p "No changes in the buffer; really send? ")) - ;; Make it possible to undo the coming changes. - (undo-boundary) - (let ((inhibit-read-only t)) - (put-text-property (point-min) (point-max) 'read-only nil)) - (run-hooks 'message-send-hook) - (message "Sending...") - (let ((message-encoding-buffer - (message-generate-new-buffer-clone-locals " message encoding")) - (message-edit-buffer (current-buffer)) - (message-mime-mode mime-edit-mode-flag) - (alist message-send-method-alist) - (success t) - elem sent) - (save-excursion - (set-buffer message-encoding-buffer) - (erase-buffer) - (insert-buffer message-edit-buffer) - (funcall message-encode-function) - (message-fix-before-sending) - (while (and success - (setq elem (pop alist))) - (when (and (or (not (funcall (cadr elem))) - (and (or (not (memq (car elem) - message-sent-message-via)) - (y-or-n-p - (format - "Already sent message via %s; resend? " - (car elem)))) - (setq success (funcall (caddr elem) arg))))) - (setq sent t)))) - (when (and success sent) - (message-do-fcc) - ;;(when (fboundp 'mail-hist-put-headers-into-history) - ;; (mail-hist-put-headers-into-history)) - (run-hooks 'message-sent-hook) - (message "Sending...done") - ;; Mark the buffer as unmodified and delete autosave. - (set-buffer-modified-p nil) - (delete-auto-save-file-if-necessary t) - (message-disassociate-draft) - ;; Delete other mail buffers and stuff. - (message-do-send-housekeeping) - (message-do-actions message-send-actions) - ;; Return success. - t)))) - -(defun message-send-via-mail (arg) - "Send the current message via mail." - (message-send-mail arg)) - -(defun message-send-via-news (arg) - "Send the current message via news." - (message-send-news arg)) - -(defun message-fix-before-sending () - "Do various things to make the message nice before sending it." - ;; Make sure there's a newline at the end of the message. - (goto-char (point-max)) - (unless (bolp) - (insert "\n")) - ;; Make all invisible text visible. - ;;(when (text-property-any (point-min) (point-max) 'invisible t) - ;; (put-text-property (point-min) (point-max) 'invisible nil) - ;; (unless (yes-or-no-p "Invisible text found and made visible; continue posting?") - ;; (error "Invisible text found and made visible"))) - ) - -(defun message-add-action (action &rest types) - "Add ACTION to be performed when doing an exit of type TYPES." - (let (var) - (while types - (set (setq var (intern (format "message-%s-actions" (pop types)))) - (nconc (symbol-value var) (list action)))))) - -(defun message-do-actions (actions) - "Perform all actions in ACTIONS." - ;; Now perform actions on successful sending. - (while actions - (ignore-errors - (cond - ;; A simple function. - ((message-functionp (car actions)) - (funcall (car actions))) - ;; Something to be evaled. - (t - (eval (car actions))))) - (pop actions))) - -(defun message-send-mail (&optional arg) - (require 'mail-utils) - (let ((tembuf (message-generate-new-buffer-clone-locals " message temp")) - (case-fold-search nil) - (news (message-news-p))) - (save-restriction - (message-narrow-to-headers) - ;; Insert some headers. - (let ((message-deletable-headers - (if news nil message-deletable-headers))) - (message-generate-headers message-required-mail-headers)) - ;; Let the user do all of the above. - (run-hooks 'message-header-hook)) - (unwind-protect - (save-excursion - (set-buffer tembuf) - (erase-buffer) - (insert-buffer message-encoding-buffer) - ;; Remove some headers. - (save-restriction - (message-narrow-to-headers) - ;; Remove some headers. - (message-remove-header message-ignored-mail-headers t)) - (goto-char (point-max)) - ;; require one newline at the end. - (or (= (preceding-char) ?\n) - (insert ?\n)) - (when (and news - (or (message-fetch-field "cc") - (message-fetch-field "to"))) - (message-insert-courtesy-copy)) - (mime-edit-maybe-split-and-send - (function - (lambda () - (interactive) - (funcall message-send-mail-function) - ))) - (funcall message-send-mail-function)) - (kill-buffer tembuf)) - (set-buffer message-edit-buffer) - (push 'mail message-sent-message-via))) - -(defun message-send-mail-with-sendmail () - "Send off the prepared buffer with sendmail." - (let ((errbuf (if message-interactive - (generate-new-buffer " sendmail errors") - 0)) - resend-to-addresses delimline) - (let ((case-fold-search t)) - (save-restriction - (message-narrow-to-headers) - (setq resend-to-addresses (message-fetch-field "resent-to"))) - ;; Change header-delimiter to be what sendmail expects. - (goto-char (point-min)) - (re-search-forward - (concat "^" (regexp-quote mail-header-separator) "\n")) - (replace-match "\n") - (backward-char 1) - (setq delimline (point-marker)) - (run-hooks 'message-send-mail-hook) - ;; Insert an extra newline if we need it to work around - ;; Sun's bug that swallows newlines. - (goto-char (1+ delimline)) - (when (eval message-mailer-swallows-blank-line) - (newline)) - (when message-interactive - (save-excursion - (set-buffer errbuf) - (erase-buffer)))) - (let ((default-directory "/") - (coding-system-for-write message-send-coding-system)) - (apply 'call-process-region - (append (list (point-min) (point-max) - (if (boundp 'sendmail-program) - sendmail-program - "/usr/lib/sendmail") - nil errbuf nil "-oi") - ;; Always specify who from, - ;; since some systems have broken sendmails. - ;; But some systems are more broken with -f, so - ;; we'll let users override this. - (if (null message-sendmail-f-is-evil) - (list "-f" (user-login-name))) - ;; These mean "report errors by mail" - ;; and "deliver in background". - (if (null message-interactive) '("-oem" "-odb")) - ;; Get the addresses from the message - ;; unless this is a resend. - ;; We must not do that for a resend - ;; because we would find the original addresses. - ;; For a resend, include the specific addresses. - (if resend-to-addresses - (list resend-to-addresses) - '("-t"))))) - (when message-interactive - (save-excursion - (set-buffer errbuf) - (goto-char (point-min)) - (while (re-search-forward "\n\n* *" nil t) - (replace-match "; ")) - (if (not (zerop (buffer-size))) - (error "Sending...failed to %s" - (buffer-substring (point-min) (point-max))))) - (when (bufferp errbuf) - (kill-buffer errbuf))))) - -(defun message-send-mail-with-qmail () - "Pass the prepared message buffer to qmail-inject. -Refer to the documentation for the variable `message-send-mail-function' -to find out how to use this." - ;; replace the header delimiter with a blank line - (goto-char (point-min)) - (re-search-forward - (concat "^" (regexp-quote mail-header-separator) "\n")) - (replace-match "\n") - (run-hooks 'message-send-mail-hook) - ;; send the message - (case - (let ((coding-system-for-write message-send-coding-system)) - (apply - 'call-process-region 1 (point-max) message-qmail-inject-program - nil nil nil - ;; qmail-inject's default behaviour is to look for addresses on the - ;; command line; if there're none, it scans the headers. - ;; yes, it does The Right Thing w.r.t. Resent-To and it's kin. - ;; - ;; in general, ALL of qmail-inject's defaults are perfect for simply - ;; reading a formatted (i. e., at least a To: or Resent-To header) - ;; message from stdin. - ;; - ;; qmail also has the advantage of not having been raped by - ;; various vendors, so we don't have to allow for that, either -- - ;; compare this with message-send-mail-with-sendmail and weep - ;; for sendmail's lost innocence. - ;; - ;; all this is way cool coz it lets us keep the arguments entirely - ;; free for -inject-arguments -- a big win for the user and for us - ;; since we don't have to play that double-guessing game and the user - ;; gets full control (no gestapo'ish -f's, for instance). --sj - message-qmail-inject-args)) - ;; qmail-inject doesn't say anything on it's stdout/stderr, - ;; we have to look at the retval instead - (0 nil) - (1 (error "qmail-inject reported permanent failure")) - (111 (error "qmail-inject reported transient failure")) - ;; should never happen - (t (error "qmail-inject reported unknown failure")))) - -(defun message-send-mail-with-mh () - "Send the prepared message buffer with mh." - (let ((mh-previous-window-config nil) - (name (mh-new-draft-name))) - (setq buffer-file-name name) - ;; MH wants to generate these headers itself. - (when message-mh-deletable-headers - (let ((headers message-mh-deletable-headers)) - (while headers - (goto-char (point-min)) - (and (re-search-forward - (concat "^" (symbol-name (car headers)) ": *") nil t) - (message-delete-line)) - (pop headers)))) - (run-hooks 'message-send-mail-hook) - ;; Pass it on to mh. - (mh-send-letter))) - -(defun message-send-mail-with-smtp () - "Send the prepared message buffer with SMTP." - (require 'smtp) - (let ((errbuf (if mail-interactive - (generate-new-buffer " smtp errors") - 0)) - (case-fold-search nil) - resend-to-addresses - delimline) - (unwind-protect - (save-excursion - (goto-char (point-max)) - ;; require one newline at the end. - (or (= (preceding-char) ?\n) - (insert ?\n)) - ;; Change header-delimiter to be what sendmail expects. - (goto-char (point-min)) - (re-search-forward - (concat "^" (regexp-quote mail-header-separator) "\n")) - (replace-match "\n") - (backward-char 1) - (setq delimline (point-marker)) - (run-hooks 'message-send-mail-hook) - ;; (sendmail-synch-aliases) - ;; (if mail-aliases - ;; (expand-mail-aliases (point-min) delimline)) - (goto-char (point-min)) - ;; ignore any blank lines in the header - (while (and (re-search-forward "\n\n\n*" delimline t) - (< (point) delimline)) - (replace-match "\n")) - (let ((case-fold-search t)) - (goto-char (point-min)) - (goto-char (point-min)) - (while (re-search-forward "^Resent-to:" delimline t) - (setq resend-to-addresses - (save-restriction - (narrow-to-region (point) - (save-excursion - (end-of-line) - (point))) - (append (mail-parse-comma-list) - resend-to-addresses)))) -;;; Apparently this causes a duplicate Sender. -;;; ;; If the From is different than current user, insert Sender. -;;; (goto-char (point-min)) -;;; (and (re-search-forward "^From:" delimline t) -;;; (progn -;;; (require 'mail-utils) -;;; (not (string-equal -;;; (mail-strip-quoted-names -;;; (save-restriction -;;; (narrow-to-region (point-min) delimline) -;;; (mail-fetch-field "From"))) -;;; (user-login-name)))) -;;; (progn -;;; (forward-line 1) -;;; (insert "Sender: " (user-login-name) "\n"))) - ;; Don't send out a blank subject line - (goto-char (point-min)) - (if (re-search-forward "^Subject:[ \t]*\n" delimline t) - (replace-match "")) - ;; Put the "From:" field in unless for some odd reason - ;; they put one in themselves. - (goto-char (point-min)) - (if (not (re-search-forward "^From:" delimline t)) - (let* ((login user-mail-address) - (fullname (user-full-name))) - (cond ((eq mail-from-style 'angles) - (insert "From: " fullname) - (let ((fullname-start (+ (point-min) 6)) - (fullname-end (point-marker))) - (goto-char fullname-start) - ;; Look for a character that cannot appear unquoted - ;; according to RFC 822. - (if (re-search-forward "[^- !#-'*+/-9=?A-Z^-~]" - fullname-end 1) - (progn - ;; Quote fullname, escaping specials. - (goto-char fullname-start) - (insert "\"") - (while (re-search-forward "[\"\\]" - fullname-end 1) - (replace-match "\\\\\\&" t)) - (insert "\"")))) - (insert " <" login ">\n")) - ((eq mail-from-style 'parens) - (insert "From: " login " (") - (let ((fullname-start (point))) - (insert fullname) - (let ((fullname-end (point-marker))) - (goto-char fullname-start) - ;; RFC 822 says \ and nonmatching parentheses - ;; must be escaped in comments. - ;; Escape every instance of ()\ ... - (while (re-search-forward "[()\\]" fullname-end 1) - (replace-match "\\\\\\&" t)) - ;; ... then undo escaping of matching parentheses, - ;; including matching nested parentheses. - (goto-char fullname-start) - (while (re-search-forward - "\\(\\=\\|[^\\]\\(\\\\\\\\\\)*\\)\\\\(\\(\\([^\\]\\|\\\\\\\\\\)*\\)\\\\)" - fullname-end 1) - (replace-match "\\1(\\3)" t) - (goto-char fullname-start)))) - (insert ")\n")) - ((null mail-from-style) - (insert "From: " login "\n"))))) - ;; Insert an extra newline if we need it to work around - ;; Sun's bug that swallows newlines. - (goto-char (1+ delimline)) - (if (eval mail-mailer-swallows-blank-line) - (newline)) - ;; Find and handle any FCC fields. - (goto-char (point-min)) - (if (re-search-forward "^FCC:" delimline t) - (mail-do-fcc delimline)) - (if mail-interactive - (save-excursion - (set-buffer errbuf) - (erase-buffer)))) - ;; - ;; - ;; - (let ((recipient-address-list - (or resend-to-addresses - (smtp-deduce-address-list (current-buffer) - (point-min) delimline)))) - (smtp-do-bcc delimline) - - (if recipient-address-list - (if (not (smtp-via-smtp recipient-address-list - (current-buffer))) - (error "Sending failed; SMTP protocol error")) - (error "Sending failed; no recipients")) - )) - (if (bufferp errbuf) - (kill-buffer errbuf))))) - -(defun message-send-news (&optional arg) - (let ((tembuf (message-generate-new-buffer-clone-locals " *message temp*")) - (case-fold-search nil) - (method (if (message-functionp message-post-method) - (funcall message-post-method arg) - message-post-method)) - (message-syntax-checks - (if arg - (cons '(existing-newsgroups . disabled) - message-syntax-checks) - message-syntax-checks)) - result) - (save-restriction - (message-narrow-to-headers) - ;; Insert some headers. - (message-generate-headers message-required-news-headers) - ;; Let the user do all of the above. - (run-hooks 'message-header-hook)) - (message-cleanup-headers) - (if (not (message-check-news-syntax)) - (progn - ;;(message "Posting not performed") - nil) - (unwind-protect - (save-excursion - (set-buffer tembuf) - (buffer-disable-undo (current-buffer)) - (erase-buffer) - (insert-buffer message-encoding-buffer) - ;; Remove some headers. - (save-restriction - (message-narrow-to-headers) - ;; Remove some headers. - (message-remove-header message-ignored-news-headers t)) - (goto-char (point-max)) - ;; require one newline at the end. - (or (= (preceding-char) ?\n) - (insert ?\n)) - (mime-edit-maybe-split-and-send - (function - (lambda () - (interactive) - (save-restriction - (std11-narrow-to-header mail-header-separator) - (goto-char (point-min)) - (when (re-search-forward "^Message-Id:" nil t) - (delete-region (match-end 0)(std11-field-end)) - (insert (concat " " (message-make-message-id))) - )) - (funcall message-send-news-function method) - ))) - (setq result (funcall message-send-news-function method))) - (kill-buffer tembuf)) - (set-buffer message-edit-buffer) - (if result - (push 'news message-sent-message-via) - (message "Couldn't send message via news: %s" - (nnheader-get-report (car method))) - nil)))) - -;; 1997-09-29 by MORIOKA Tomohiko -(defun message-send-news-with-gnus (method) - (let ((case-fold-search t)) - ;; Remove the delimiter. - (goto-char (point-min)) - (re-search-forward - (concat "^" (regexp-quote mail-header-separator) "\n")) - (replace-match "\n") - (backward-char 1) - (run-hooks 'message-send-news-hook) - ;;(require (car method)) - ;;(funcall (intern (format "%s-open-server" (car method))) - ;;(cadr method) (cddr method)) - ;;(setq result - ;; (funcall (intern (format "%s-request-post" (car method))) - ;; (cadr method))) - (gnus-open-server method) - (gnus-request-post method) - )) - -;;; -;;; Header generation & syntax checking. -;;; - -(defmacro message-check (type &rest forms) - "Eval FORMS if TYPE is to be checked." - `(or (message-check-element ,type) - (save-excursion - ,@forms))) - -(put 'message-check 'lisp-indent-function 1) -(put 'message-check 'edebug-form-spec '(form body)) - -(defun message-check-element (type) - "Returns non-nil if this type is not to be checked." - (if (eq message-syntax-checks 'dont-check-for-anything-just-trust-me) - t - (let ((able (assq type message-syntax-checks))) - (and (consp able) - (eq (cdr able) 'disabled))))) - -(defun message-check-news-syntax () - "Check the syntax of the message." - (save-excursion - (save-restriction - (widen) - (and - ;; We narrow to the headers and check them first. - (save-excursion - (save-restriction - (message-narrow-to-headers) - (message-check-news-header-syntax))) - ;; Check the body. - (save-excursion - (set-buffer message-edit-buffer) - (message-check-news-body-syntax)))))) - -(defun message-check-news-header-syntax () - (and - ;; Check the Subject header. - (message-check 'subject - (let* ((case-fold-search t) - (subject (message-fetch-field "subject"))) - (or - (and subject - (not (string-match "\\`[ \t]*\\'" subject))) - (ignore - (message - "The subject field is empty or missing. Posting is denied."))))) - ;; Check for commands in Subject. - (message-check 'subject-cmsg - (if (string-match "^cmsg " (message-fetch-field "subject")) - (y-or-n-p - "The control code \"cmsg\" is in the subject. Really post? ") - t)) - ;; Check for multiple identical headers. - (message-check 'multiple-headers - (let (found) - (while (and (not found) - (re-search-forward "^[^ \t:]+: " nil t)) - (save-excursion - (or (re-search-forward - (concat "^" - (regexp-quote - (setq found - (buffer-substring - (match-beginning 0) (- (match-end 0) 2)))) - ":") - nil t) - (setq found nil)))) - (if found - (y-or-n-p (format "Multiple %s headers. Really post? " found)) - t))) - ;; Check for Version and Sendsys. - (message-check 'sendsys - (if (re-search-forward "^Sendsys:\\|^Version:" nil t) - (y-or-n-p - (format "The article contains a %s command. Really post? " - (buffer-substring (match-beginning 0) - (1- (match-end 0))))) - t)) - ;; See whether we can shorten Followup-To. - (message-check 'shorten-followup-to - (let ((newsgroups (message-fetch-field "newsgroups")) - (followup-to (message-fetch-field "followup-to")) - to) - (when (and newsgroups - (string-match "," newsgroups) - (not followup-to) - (not - (zerop - (length - (setq to (completing-read - "Followups to: (default all groups) " - (mapcar (lambda (g) (list g)) - (cons "poster" - (message-tokenize-header - newsgroups))))))))) - (goto-char (point-min)) - (insert "Followup-To: " to "\n")) - t)) - ;; Check "Shoot me". - (message-check 'shoot - (if (re-search-forward - "Message-ID.*.i-did-not-set--mail-host-address--so-shoot-me" nil t) - (y-or-n-p "You appear to have a misconfigured system. Really post? ") - t)) - ;; Check for Approved. - (message-check 'approved - (if (re-search-forward "^Approved:" nil t) - (y-or-n-p "The article contains an Approved header. Really post? ") - t)) - ;; Check the Message-ID header. - (message-check 'message-id - (let* ((case-fold-search t) - (message-id (message-fetch-field "message-id" t))) - (or (not message-id) - ;; Is there an @ in the ID? - (and (string-match "@" message-id) - ;; Is there a dot in the ID? - (string-match "@[^.]*\\." message-id) - ;; Does the ID end with a dot? - (not (string-match "\\.>" message-id))) - (y-or-n-p - (format "The Message-ID looks strange: \"%s\". Really post? " - message-id))))) - ;; Check the Newsgroups & Followup-To headers. - (message-check 'existing-newsgroups - (let* ((case-fold-search t) - (newsgroups (message-fetch-field "newsgroups")) - (followup-to (message-fetch-field "followup-to")) - (groups (message-tokenize-header - (if followup-to - (concat newsgroups "," followup-to) - newsgroups))) - (hashtb (and (boundp 'gnus-active-hashtb) - gnus-active-hashtb)) - errors) - (if (or (not hashtb) - (not (boundp 'gnus-read-active-file)) - (not gnus-read-active-file) - (eq gnus-read-active-file 'some)) - t - (while groups - (when (and (not (boundp (intern (car groups) hashtb))) - (not (equal (car groups) "poster"))) - (push (car groups) errors)) - (pop groups)) - (if (not errors) - t - (y-or-n-p - (format - "Really post to %s unknown group%s: %s " - (if (= (length errors) 1) "this" "these") - (if (= (length errors) 1) "" "s") - (mapconcat 'identity errors ", "))))))) - ;; Check the Newsgroups & Followup-To headers for syntax errors. - (message-check 'valid-newsgroups - (let ((case-fold-search t) - (headers '("Newsgroups" "Followup-To")) - header error) - (while (and headers (not error)) - (when (setq header (mail-fetch-field (car headers))) - (if (or - (not - (string-match - "\\`\\([-+_&.a-zA-Z0-9]+\\)?\\(,[-+_&.a-zA-Z0-9]+\\)*\\'" - header)) - (memq - nil (mapcar - (lambda (g) - (not (string-match "\\.\\'\\|\\.\\." g))) - (message-tokenize-header header ",")))) - (setq error t))) - (unless error - (pop headers))) - (if (not error) - t - (y-or-n-p - (format "The %s header looks odd: \"%s\". Really post? " - (car headers) header))))) - (message-check 'repeated-newsgroups - (let ((case-fold-search t) - (headers '("Newsgroups" "Followup-To")) - header error groups group) - (while (and headers - (not error)) - (when (setq header (mail-fetch-field (pop headers))) - (setq groups (message-tokenize-header header ",")) - (while (setq group (pop groups)) - (when (member group groups) - (setq error group - groups nil))))) - (if (not error) - t - (y-or-n-p - (format "Group %s is repeated in headers. Really post? " error))))) - ;; Check the From header. - (message-check 'from - (let* ((case-fold-search t) - (from (message-fetch-field "from")) - (ad (nth 1 (mail-extract-address-components from)))) - (cond - ((not from) - (message "There is no From line. Posting is denied.") - nil) - ((or (not (string-match "@[^\\.]*\\." ad)) ;larsi@ifi - (string-match "\\.\\." ad) ;larsi@ifi..uio - (string-match "@\\." ad) ;larsi@.ifi.uio - (string-match "\\.$" ad) ;larsi@ifi.uio. - (not (string-match "^[^@]+@[^@]+$" ad)) ;larsi.ifi.uio - (string-match "(.*).*(.*)" from)) ;(lars) (lars) - (message - "Denied posting -- the From looks strange: \"%s\"." from) - nil) - (t t)))))) - -(defun message-check-news-body-syntax () - (and - ;; Check for long lines. - (message-check 'long-lines - (goto-char (point-min)) - (re-search-forward - (concat "^" (regexp-quote mail-header-separator) "$")) - (while (and - (progn - (end-of-line) - (< (current-column) 80)) - (zerop (forward-line 1)))) - (or (bolp) - (eobp) - (y-or-n-p - "You have lines longer than 79 characters. Really post? "))) - ;; Check whether the article is empty. - (message-check 'empty - (goto-char (point-min)) - (re-search-forward - (concat "^" (regexp-quote mail-header-separator) "$")) - (forward-line 1) - (let ((b (point))) - (goto-char (point-max)) - (re-search-backward message-signature-separator nil t) - (beginning-of-line) - (or (re-search-backward "[^ \n\t]" b t) - (y-or-n-p "Empty article. Really post? ")))) - ;; Check for control characters. - (message-check 'control-chars - (if (re-search-forward "[\000-\007\013\015-\037\200-\237]" nil t) - (y-or-n-p - "The article contains control characters. Really post? ") - t)) - ;; Check excessive size. - (message-check 'size - (if (> (buffer-size) 60000) - (y-or-n-p - (format "The article is %d octets long. Really post? " - (buffer-size))) - t)) - ;; Check whether any new text has been added. - (message-check 'new-text - (or - (not message-checksum) - (not (eq (message-checksum) message-checksum)) - (y-or-n-p - "It looks like no new text has been added. Really post? "))) - ;; Check the length of the signature. - (message-check 'signature - (goto-char (point-max)) - (if (or (not (re-search-backward message-signature-separator nil t)) - (search-forward message-forward-end-separator nil t)) - t - (if (> (count-lines (point) (point-max)) 5) - (y-or-n-p - (format - "Your .sig is %d lines; it should be max 4. Really post? " - (1- (count-lines (point) (point-max))))) - t))))) - -(defun message-checksum () - "Return a \"checksum\" for the current buffer." - (let ((sum 0)) - (save-excursion - (goto-char (point-min)) - (re-search-forward - (concat "^" (regexp-quote mail-header-separator) "$")) - (while (not (eobp)) - (when (not (looking-at "[ \t\n]")) - (setq sum (logxor (ash sum 1) (if (natnump sum) 0 1) - (following-char)))) - (forward-char 1))) - sum)) - -(defun message-do-fcc () - "Process Fcc headers in the current buffer." - (let ((case-fold-search t) - (coding-system-for-write 'raw-text) - list file) - (save-excursion - (set-buffer (get-buffer-create " *message temp*")) - (buffer-disable-undo (current-buffer)) - (erase-buffer) - (insert-buffer-substring message-encoding-buffer) - (save-restriction - (message-narrow-to-headers) - (while (setq file (message-fetch-field "fcc")) - (push file list) - (message-remove-header "fcc" nil t))) - (run-hooks 'message-header-hook 'message-before-do-fcc-hook) - (goto-char (point-min)) - (re-search-forward (concat "^" (regexp-quote mail-header-separator) "$")) - (replace-match "" t t) - ;; Process FCC operations. - (while list - (setq file (pop list)) - (if (string-match "^[ \t]*|[ \t]*\\(.*\\)[ \t]*$" file) - ;; Pipe the article to the program in question. - (call-process-region (point-min) (point-max) shell-file-name - nil nil nil shell-command-switch - (match-string 1 file)) - ;; Save the article. - (setq file (expand-file-name file)) - (unless (file-exists-p (file-name-directory file)) - (make-directory (file-name-directory file) t)) - (if (and message-fcc-handler-function - (not (eq message-fcc-handler-function 'rmail-output))) - (funcall message-fcc-handler-function file) - (if (and (file-readable-p file) (mail-file-babyl-p file)) - (rmail-output file 1 nil t) - (let ((mail-use-rfc822 t)) - (rmail-output file 1 t t)))))) - - (kill-buffer (current-buffer))))) - -(defun message-output (filename) - "Append this article to Unix/babyl mail file.." - (if (and (file-readable-p filename) - (mail-file-babyl-p filename)) - (gnus-output-to-rmail filename t) - (gnus-output-to-mail filename t))) - -(defun message-cleanup-headers () - "Do various automatic cleanups of the headers." - ;; Remove empty lines in the header. - (save-restriction - (message-narrow-to-headers) - ;; Remove blank lines. - (while (re-search-forward "^[ \t]*\n" nil t) - (replace-match "" t t)) - - ;; Correct Newsgroups and Followup-To headers: Change sequence of - ;; spaces to comma and eliminate spaces around commas. Eliminate - ;; embedded line breaks. - (goto-char (point-min)) - (while (re-search-forward "^\\(Newsgroups\\|Followup-To\\): +" nil t) - (save-restriction - (narrow-to-region - (point) - (if (re-search-forward "^[^ \t]" nil t) - (match-beginning 0) - (forward-line 1) - (point))) - (goto-char (point-min)) - (while (re-search-forward "\n[ \t]+" nil t) - (replace-match " " t t)) ;No line breaks (too confusing) - (goto-char (point-min)) - (while (re-search-forward "[ \t\n]*,[ \t\n]*\\|[ \t]+" nil t) - (replace-match "," t t)) - (goto-char (point-min)) - ;; Remove trailing commas. - (when (re-search-forward ",+$" nil t) - (replace-match "" t t)))))) - -(defun message-make-date () - "Make a valid data header." - (let ((now (current-time))) - (timezone-make-date-arpa-standard - (current-time-string now) (current-time-zone now)))) - -(defun message-make-message-id () - "Make a unique Message-ID." - (concat "<" (message-unique-id) - (let ((psubject (save-excursion (message-fetch-field "subject"))) - (psupersedes - (save-excursion (message-fetch-field "supersedes")))) - (if (or - (and message-reply-headers - (mail-header-references message-reply-headers) - (mail-header-subject message-reply-headers) - psubject - (mail-header-subject message-reply-headers) - (not (string= - (message-strip-subject-re - (mail-header-subject message-reply-headers)) - (message-strip-subject-re psubject)))) - (and psupersedes - (string-match "_-_@" psupersedes))) - "_-_" "")) - "@" (message-make-fqdn) ">")) - -(defvar message-unique-id-char nil) - -;; If you ever change this function, make sure the new version -;; cannot generate IDs that the old version could. -;; You might for example insert a "." somewhere (not next to another dot -;; or string boundary), or modify the "fsf" string. -(defun message-unique-id () - ;; Don't use microseconds from (current-time), they may be unsupported. - ;; Instead we use this randomly inited counter. - (setq message-unique-id-char - (% (1+ (or message-unique-id-char (logand (random t) (1- (lsh 1 20))))) - ;; (current-time) returns 16-bit ints, - ;; and 2^16*25 just fits into 4 digits i base 36. - (* 25 25))) - (let ((tm (current-time))) - (concat - (if (memq system-type '(ms-dos emx vax-vms)) - (let ((user (downcase (user-login-name)))) - (while (string-match "[^a-z0-9_]" user) - (aset user (match-beginning 0) ?_)) - user) - (message-number-base36 (user-uid) -1)) - (message-number-base36 (+ (car tm) - (lsh (% message-unique-id-char 25) 16)) 4) - (message-number-base36 (+ (nth 1 tm) - (lsh (/ message-unique-id-char 25) 16)) 4) - ;; Append the newsreader name, because while the generated - ;; ID is unique to this newsreader, other newsreaders might - ;; otherwise generate the same ID via another algorithm. - ".fsf"))) - -(defun message-number-base36 (num len) - (if (if (< len 0) - (<= num 0) - (= len 0)) - "" - (concat (message-number-base36 (/ num 36) (1- len)) - (char-to-string (aref "zyxwvutsrqponmlkjihgfedcba9876543210" - (% num 36)))))) - -(defun message-make-organization () - "Make an Organization header." - (let* ((organization - (when message-user-organization - (if (message-functionp message-user-organization) - (funcall message-user-organization) - message-user-organization)))) - (save-excursion - (message-set-work-buffer) - (cond ((stringp organization) - (insert organization)) - ((and (eq t organization) - message-user-organization-file - (file-exists-p message-user-organization-file)) - (insert-file-contents message-user-organization-file))) - (goto-char (point-min)) - (while (re-search-forward "[\t\n]+" nil t) - (replace-match "" t t)) - (unless (zerop (buffer-size)) - (buffer-string))))) - -(defun message-make-lines () - "Count the number of lines and return numeric string." - (save-excursion - (save-restriction - (widen) - (goto-char (point-min)) - (re-search-forward - (concat "^" (regexp-quote mail-header-separator) "$")) - (forward-line 1) - (int-to-string (count-lines (point) (point-max)))))) - -(defun message-make-in-reply-to () - "Return the In-Reply-To header for this message." - (when message-reply-headers - (let ((from (mail-header-from message-reply-headers)) - (date (mail-header-date message-reply-headers))) - (when from - (let ((stop-pos - (string-match " *at \\| *@ \\| *(\\| *<" from))) - (concat (if (and stop-pos - (not (zerop stop-pos))) - (substring from 0 stop-pos) from) - "'s message of \"" - (if (or (not date) (string= date "")) - "(unknown date)" date) - "\"")))))) - -(defun message-make-distribution () - "Make a Distribution header." - (let ((orig-distribution (message-fetch-reply-field "distribution"))) - (cond ((message-functionp message-distribution-function) - (funcall message-distribution-function)) - (t orig-distribution)))) - -(defun message-make-expires () - "Return an Expires header based on `message-expires'." - (let ((current (current-time)) - (future (* 1.0 message-expires 60 60 24))) - ;; Add the future to current. - (setcar current (+ (car current) (round (/ future (expt 2 16))))) - (setcar (cdr current) (+ (nth 1 current) (% (round future) (expt 2 16)))) - ;; Return the date in the future in UT. - (timezone-make-date-arpa-standard - (current-time-string current) (current-time-zone current) '(0 "UT")))) - -(defun message-make-path () - "Return uucp path." - (let ((login-name (user-login-name))) - (cond ((null message-user-path) - (concat (system-name) "!" login-name)) - ((stringp message-user-path) - ;; Support GENERICPATH. Suggested by vixie@decwrl.dec.com. - (concat message-user-path "!" login-name)) - (t login-name)))) - -(defun message-make-from () - "Make a From header." - (let* ((style message-from-style) - (login (message-make-address)) - (fullname - (or (and (boundp 'user-full-name) - user-full-name) - (user-full-name)))) - (when (string= fullname "&") - (setq fullname (user-login-name))) - (save-excursion - (message-set-work-buffer) - (cond - ((or (null style) - (equal fullname "")) - (insert login)) - ((or (eq style 'angles) - (and (not (eq style 'parens)) - ;; Use angles if no quoting is needed, or if parens would - ;; need quoting too. - (or (not (string-match "[^- !#-'*+/-9=?A-Z^-~]" fullname)) - (let ((tmp (concat fullname nil))) - (while (string-match "([^()]*)" tmp) - (aset tmp (match-beginning 0) ?-) - (aset tmp (1- (match-end 0)) ?-)) - (string-match "[\\()]" tmp))))) - (insert fullname) - (goto-char (point-min)) - ;; Look for a character that cannot appear unquoted - ;; according to RFC 822. - (when (re-search-forward "[^- !#-'*+/-9=?A-Z^-~]" nil 1) - ;; Quote fullname, escaping specials. - (goto-char (point-min)) - (insert "\"") - (while (re-search-forward "[\"\\]" nil 1) - (replace-match "\\\\\\&" t)) - (insert "\"")) - (insert " <" login ">")) - (t ; 'parens or default - (insert login " (") - (let ((fullname-start (point))) - (insert fullname) - (goto-char fullname-start) - ;; RFC 822 says \ and nonmatching parentheses - ;; must be escaped in comments. - ;; Escape every instance of ()\ ... - (while (re-search-forward "[()\\]" nil 1) - (replace-match "\\\\\\&" t)) - ;; ... then undo escaping of matching parentheses, - ;; including matching nested parentheses. - (goto-char fullname-start) - (while (re-search-forward - "\\(\\=\\|[^\\]\\(\\\\\\\\\\)*\\)\\\\(\\(\\([^\\]\\|\\\\\\\\\\)*\\)\\\\)" - nil 1) - (replace-match "\\1(\\3)" t) - (goto-char fullname-start))) - (insert ")"))) - (buffer-string)))) - -(defun message-make-sender () - "Return the \"real\" user address. -This function tries to ignore all user modifications, and -give as trustworthy answer as possible." - (concat (user-login-name) "@" (system-name))) - -(defun message-make-address () - "Make the address of the user." - (or (message-user-mail-address) - (concat (user-login-name) "@" (message-make-domain)))) - -(defun message-user-mail-address () - "Return the pertinent part of `user-mail-address'." - (when user-mail-address - (if (string-match " " user-mail-address) - (nth 1 (mail-extract-address-components user-mail-address)) - user-mail-address))) - -(defun message-make-fqdn () - "Return user's fully qualified domain name." - (let ((system-name (system-name)) - (user-mail (message-user-mail-address))) - (cond - ((string-match "[^.]\\.[^.]" system-name) - ;; `system-name' returned the right result. - system-name) - ;; Try `mail-host-address'. - ((and (boundp 'mail-host-address) - (stringp mail-host-address) - (string-match "\\." mail-host-address)) - mail-host-address) - ;; We try `user-mail-address' as a backup. - ((and user-mail - (string-match "\\." user-mail) - (string-match "@\\(.*\\)\\'" user-mail)) - (match-string 1 user-mail)) - ;; Default to this bogus thing. - (t - (concat system-name ".i-did-not-set--mail-host-address--so-shoot-me"))))) - -(defun message-make-host-name () - "Return the name of the host." - (let ((fqdn (message-make-fqdn))) - (string-match "^[^.]+\\." fqdn) - (substring fqdn 0 (1- (match-end 0))))) - -(defun message-make-domain () - "Return the domain name." - (or mail-host-address - (message-make-fqdn))) - -(defun message-make-user-agent () - "Return user-agent info." - (if message-user-agent - (save-excursion - (goto-char (point-min)) - (let ((case-fold-search t) - user-agent beg p end) - (if (re-search-forward "^User-Agent:[ \t]*" nil t) - (progn - (setq beg (match-beginning 0) - p (match-end 0) - end (std11-field-end) - user-agent (buffer-substring p end)) - (delete-region beg (1+ end)) - (concat message-user-agent " " user-agent) - ) - message-user-agent))))) - -(defun message-generate-headers (headers) - "Prepare article HEADERS. -Headers already prepared in the buffer are not modified." - (save-restriction - (message-narrow-to-headers) - (let* ((Date (message-make-date)) - (Message-ID (message-make-message-id)) - (Organization (message-make-organization)) - (From (message-make-from)) - (Path (message-make-path)) - (Subject nil) - (Newsgroups nil) - (In-Reply-To (message-make-in-reply-to)) - (To nil) - (Distribution (message-make-distribution)) - (Lines (message-make-lines)) - (User-Agent (message-make-user-agent)) - (Expires (message-make-expires)) - (case-fold-search t) - header value elem) - ;; First we remove any old generated headers. - (let ((headers message-deletable-headers)) - (unless (buffer-modified-p) - (setq headers (delq 'Message-ID (copy-sequence headers)))) - (while headers - (goto-char (point-min)) - (and (re-search-forward - (concat "^" (symbol-name (car headers)) ": *") nil t) - (get-text-property (1+ (match-beginning 0)) 'message-deletable) - (message-delete-line)) - (pop headers))) - ;; Go through all the required headers and see if they are in the - ;; articles already. If they are not, or are empty, they are - ;; inserted automatically - except for Subject, Newsgroups and - ;; Distribution. - (while headers - (goto-char (point-min)) - (setq elem (pop headers)) - (if (consp elem) - (if (eq (car elem) 'optional) - (setq header (cdr elem)) - (setq header (car elem))) - (setq header elem)) - (when (or (not (re-search-forward - (concat "^" - (regexp-quote - (downcase - (if (stringp header) - header - (symbol-name header)))) - ":") - nil t)) - (progn - ;; The header was found. We insert a space after the - ;; colon, if there is none. - (if (/= (following-char) ? ) (insert " ") (forward-char 1)) - ;; Find out whether the header is empty... - (looking-at "[ \t]*$"))) - ;; So we find out what value we should insert. - (setq value - (cond - ((and (consp elem) (eq (car elem) 'optional)) - ;; This is an optional header. If the cdr of this - ;; is something that is nil, then we do not insert - ;; this header. - (setq header (cdr elem)) - (or (and (fboundp (cdr elem)) (funcall (cdr elem))) - (and (boundp (cdr elem)) (symbol-value (cdr elem))))) - ((consp elem) - ;; The element is a cons. Either the cdr is a - ;; string to be inserted verbatim, or it is a - ;; function, and we insert the value returned from - ;; this function. - (or (and (stringp (cdr elem)) (cdr elem)) - (and (fboundp (cdr elem)) (funcall (cdr elem))))) - ((and (boundp header) (symbol-value header)) - ;; The element is a symbol. We insert the value - ;; of this symbol, if any. - (symbol-value header)) - (t - ;; We couldn't generate a value for this header, - ;; so we just ask the user. - (read-from-minibuffer - (format "Empty header for %s; enter value: " header))))) - ;; Finally insert the header. - (when (and value - (not (equal value ""))) - (save-excursion - (if (bolp) - (progn - ;; This header didn't exist, so we insert it. - (goto-char (point-max)) - (insert (if (stringp header) header (symbol-name header)) - ": " value "\n") - (forward-line -1)) - ;; The value of this header was empty, so we clear - ;; totally and insert the new value. - (delete-region (point) (gnus-point-at-eol)) - (insert value)) - ;; Add the deletable property to the headers that require it. - (and (memq header message-deletable-headers) - (progn (beginning-of-line) (looking-at "[^:]+: ")) - (add-text-properties - (point) (match-end 0) - '(message-deletable t face italic) (current-buffer))))))) - ;; Insert new Sender if the From is strange. - (let ((from (message-fetch-field "from")) - (sender (message-fetch-field "sender")) - (secure-sender (message-make-sender))) - (when (and from - (not (message-check-element 'sender)) - (not (string= - (downcase - (cadr (mail-extract-address-components from))) - (downcase secure-sender))) - (or (null sender) - (not - (string= - (downcase - (cadr (mail-extract-address-components sender))) - (downcase secure-sender))))) - (goto-char (point-min)) - ;; Rename any old Sender headers to Original-Sender. - (when (re-search-forward "^\\(Original-\\)*Sender:" nil t) - (beginning-of-line) - (insert "Original-") - (beginning-of-line)) - (when (or (message-news-p) - (string-match "@.+\\.." secure-sender)) - (insert "Sender: " secure-sender "\n"))))))) - -(defun message-insert-courtesy-copy () - "Insert a courtesy message in mail copies of combined messages." - (let (newsgroups) - (save-excursion - (save-restriction - (message-narrow-to-headers) - (when (setq newsgroups (message-fetch-field "newsgroups")) - (goto-char (point-max)) - (insert "Posted-To: " newsgroups "\n"))) - (forward-line 1) - (when message-courtesy-message - (cond - ((string-match "%s" message-courtesy-message) - (insert (format message-courtesy-message newsgroups))) - (t - (insert message-courtesy-message))))))) - -;;; -;;; Setting up a message buffer -;;; - -(defun message-fill-address (header value) - (save-restriction - (narrow-to-region (point) (point)) - (insert (capitalize (symbol-name header)) - ": " - (if (consp value) (car value) value) - "\n") - (narrow-to-region (point-min) (1- (point-max))) - (let (quoted last) - (goto-char (point-min)) - (while (not (eobp)) - (skip-chars-forward "^,\"" (point-max)) - (if (or (= (following-char) ?,) - (eobp)) - (when (not quoted) - (if (and (> (current-column) 78) - last) - (progn - (save-excursion - (goto-char last) - (insert "\n\t")) - (setq last (1+ (point)))) - (setq last (1+ (point))))) - (setq quoted (not quoted))) - (unless (eobp) - (forward-char 1)))) - (goto-char (point-max)) - (widen) - (forward-line 1))) - -(defun message-fill-references (header value) - (insert (capitalize (symbol-name header)) - ": " - (std11-fill-msg-id-list-string - (if (consp value) (car value) value)) - "\n")) - -(defun message-fill-header (header value) - (let ((begin (point)) - (fill-column 990) - (fill-prefix "\t")) - (insert (capitalize (symbol-name header)) - ": " - (if (consp value) (car value) value) - "\n") - (save-restriction - (narrow-to-region begin (point)) - (fill-region-as-paragraph begin (point)) - ;; Tapdance around looong Message-IDs. - (forward-line -1) - (when (looking-at "[ \t]*$") - (message-delete-line)) - (goto-char begin) - (re-search-forward ":" nil t) - (when (looking-at "\n[ \t]+") - (replace-match " " t t)) - (goto-char (point-max))))) - -(defun message-shorten-references (header references) - "Limit REFERENCES to be shorter than 988 characters." - (let ((max 988) - (cut 4) - refs) - (nnheader-temp-write nil - (insert references) - (goto-char (point-min)) - (while (re-search-forward "<[^>]+>" nil t) - (push (match-string 0) refs)) - (setq refs (nreverse refs)) - (while (> (length (mapconcat 'identity refs " ")) max) - (when (< (length refs) (1+ cut)) - (decf cut)) - (setcdr (nthcdr cut refs) (cddr (nthcdr cut refs))))) - (insert (capitalize (symbol-name header)) ": " - (mapconcat 'identity refs " ") "\n"))) - -(defun message-position-point () - "Move point to where the user probably wants to find it." - (message-narrow-to-headers) - (cond - ((re-search-forward "^[^:]+:[ \t]*$" nil t) - (search-backward ":" ) - (widen) - (forward-char 1) - (if (= (following-char) ? ) - (forward-char 1) - (insert " "))) - (t - (goto-char (point-max)) - (widen) - (forward-line 1) - (unless (looking-at "$") - (forward-line 2))) - (sit-for 0))) - -(defun message-buffer-name (type &optional to group) - "Return a new (unique) buffer name based on TYPE and TO." - (cond - ;; Check whether `message-generate-new-buffers' is a function, - ;; and if so, call it. - ((message-functionp message-generate-new-buffers) - (funcall message-generate-new-buffers type to group)) - ;; Generate a new buffer name The Message Way. - (message-generate-new-buffers - (generate-new-buffer-name - (concat "*" type - (if to - (concat " to " - (or (car (mail-extract-address-components to)) - to) "") - "") - (if (and group (not (string= group ""))) (concat " on " group) "") - "*"))) - ;; Use standard name. - (t - (format "*%s message*" type)))) - -(defun message-pop-to-buffer (name) - "Pop to buffer NAME, and warn if it already exists and is modified." - (let ((pop-up-frames pop-up-frames) - (special-display-buffer-names special-display-buffer-names) - (special-display-regexps special-display-regexps) - (same-window-buffer-names same-window-buffer-names) - (same-window-regexps same-window-regexps) - (buffer (get-buffer name)) - (cur (current-buffer))) - (if (or (and (featurep 'xemacs) - (not (eq 'tty (device-type)))) - window-system - (>= emacs-major-version 20)) - (when message-use-multi-frames - (setq pop-up-frames t - special-display-buffer-names nil - special-display-regexps nil - same-window-buffer-names nil - same-window-regexps nil)) - (setq pop-up-frames nil)) - (if (and buffer - (buffer-name buffer)) - (progn - (set-buffer (pop-to-buffer buffer)) - (when (and (buffer-modified-p) - (not (y-or-n-p - "Message already being composed; erase? "))) - (error "Message being composed"))) - (set-buffer (pop-to-buffer name))) - (erase-buffer) - (message-mode) - (when pop-up-frames - (make-local-variable 'message-original-frame) - (setq message-original-frame (selected-frame))))) - -(defun message-do-send-housekeeping () - "Kill old message buffers." - ;; We might have sent this buffer already. Delete it from the - ;; list of buffers. - (setq message-buffer-list (delq (current-buffer) message-buffer-list)) - (while (and message-max-buffers - message-buffer-list - (>= (length message-buffer-list) message-max-buffers)) - ;; Kill the oldest buffer -- unless it has been changed. - (let ((buffer (pop message-buffer-list))) - (when (and (buffer-name buffer) - (not (buffer-modified-p buffer))) - (kill-buffer buffer)))) - ;; Rename the buffer. - (if message-send-rename-function - (funcall message-send-rename-function) - (when (string-match "\\`\\*" (buffer-name)) - (rename-buffer - (concat "*sent " (substring (buffer-name) (match-end 0))) t))) - ;; Push the current buffer onto the list. - (when message-max-buffers - (setq message-buffer-list - (nconc message-buffer-list (list (current-buffer)))))) - -(defvar mc-modes-alist) -(defun message-setup (headers &optional replybuffer actions) - (when (and (boundp 'mc-modes-alist) - (not (assq 'message-mode mc-modes-alist))) - (push '(message-mode (encrypt . mc-encrypt-message) - (sign . mc-sign-message)) - mc-modes-alist)) - (when actions - (setq message-send-actions actions)) - (setq message-reply-buffer replybuffer) - (goto-char (point-min)) - ;; Insert all the headers. - (mail-header-format - (let ((h headers) - (alist message-header-format-alist)) - (while h - (unless (assq (caar h) message-header-format-alist) - (push (list (caar h)) alist)) - (pop h)) - alist) - headers) - (delete-region (point) (progn (forward-line -1) (point))) - (when message-default-headers - (insert message-default-headers) - (or (bolp) (insert ?\n))) - (put-text-property - (point) - (progn - (insert mail-header-separator "\n") - (1- (point))) - 'read-only nil) - (forward-line -1) - (when (message-news-p) - (when message-default-news-headers - (insert message-default-news-headers) - (or (bolp) (insert ?\n))) - (when message-generate-headers-first - (message-generate-headers - (delq 'Lines - (delq 'Subject - (copy-sequence message-required-news-headers)))))) - (when (message-mail-p) - (when message-default-mail-headers - (insert message-default-mail-headers) - (or (bolp) (insert ?\n))) - (when message-generate-headers-first - (message-generate-headers - (delq 'Lines - (delq 'Subject - (copy-sequence message-required-mail-headers)))))) - (run-hooks 'message-signature-setup-hook) - (message-insert-signature) - (save-restriction - (message-narrow-to-headers) - (run-hooks 'message-header-setup-hook)) - (set-buffer-modified-p nil) - (setq buffer-undo-list nil) - (run-hooks 'message-setup-hook) - (message-position-point) - (undo-boundary)) - -(defun message-set-auto-save-file-name () - "Associate the message buffer with a file in the drafts directory." - (when message-autosave-directory - (if (gnus-alive-p) - (setq message-draft-article - (nndraft-request-associate-buffer "drafts")) - (setq buffer-file-name (expand-file-name "*message*" - message-autosave-directory)) - (setq buffer-auto-save-file-name (make-auto-save-file-name))) - (clear-visited-file-modtime))) - -(defun message-disassociate-draft () - "Disassociate the message buffer from the drafts directory." - (when message-draft-article - (nndraft-request-expire-articles - (list message-draft-article) "drafts" nil t))) - - - -;;; -;;; Commands for interfacing with message -;;; - -;;;###autoload -(defun message-mail (&optional to subject - other-headers continue switch-function - yank-action send-actions) - "Start editing a mail message to be sent. -OTHER-HEADERS is an alist of header/value pairs." - (interactive) - (let ((message-this-is-mail t)) - (message-pop-to-buffer (message-buffer-name "mail" to)) - (message-setup - (nconc - `((To . ,(or to "")) (Subject . ,(or subject ""))) - (when other-headers other-headers))))) - -;;;###autoload -(defun message-news (&optional newsgroups subject) - "Start editing a news article to be sent." - (interactive) - (let ((message-this-is-news t)) - (message-pop-to-buffer (message-buffer-name "news" nil newsgroups)) - (message-setup `((Newsgroups . ,(or newsgroups "")) - (Subject . ,(or subject "")))))) - -;;;###autoload -(defun message-reply (&optional to-address wide) - "Start editing a reply to the article in the current buffer." - (interactive) - (let ((cur (current-buffer)) - from subject date reply-to to cc - references message-id follow-to - (inhibit-point-motion-hooks t) - mct never-mct gnus-warning) - (save-restriction - (message-narrow-to-head) - ;; Allow customizations to have their say. - (if (not wide) - ;; This is a regular reply. - (if (message-functionp message-reply-to-function) - (setq follow-to (funcall message-reply-to-function))) - ;; This is a followup. - (if (message-functionp message-wide-reply-to-function) - (save-excursion - (setq follow-to - (funcall message-wide-reply-to-function))))) - ;; Find all relevant headers we need. - (setq from (message-fetch-field "from") - date (message-fetch-field "date") - subject (or (message-fetch-field "subject") "none") - to (message-fetch-field "to") - cc (message-fetch-field "cc") - mct (message-fetch-field "mail-copies-to") - reply-to (message-fetch-field "reply-to") - references (message-fetch-field "references") - message-id (message-fetch-field "message-id" t)) - ;; Remove any (buggy) Re:'s that are present and make a - ;; proper one. - (when (string-match message-subject-re-regexp subject) - (setq subject (substring subject (match-end 0)))) - (setq subject (concat "Re: " subject)) - - (when (and (setq gnus-warning (message-fetch-field "gnus-warning")) - (string-match "<[^>]+>" gnus-warning)) - (setq message-id (match-string 0 gnus-warning))) - - ;; Handle special values of Mail-Copies-To. - (when mct - (cond ((equal (downcase mct) "never") - (setq never-mct t) - (setq mct nil)) - ((equal (downcase mct) "always") - (setq mct (or reply-to from))))) - - (unless follow-to - (if (or (not wide) - to-address) - (progn - (setq follow-to (list (cons 'To (or to-address reply-to from)))) - (when (and wide mct) - (push (cons 'Cc mct) follow-to))) - (let (ccalist) - (save-excursion - (message-set-work-buffer) - (unless never-mct - (insert (or reply-to from ""))) - (insert (if to (concat (if (bolp) "" ", ") to "") "")) - (insert (if mct (concat (if (bolp) "" ", ") mct) "")) - (insert (if cc (concat (if (bolp) "" ", ") cc) "")) - (goto-char (point-min)) - (while (re-search-forward "[ \t]+" nil t) - (replace-match " " t t)) - ;; Remove addresses that match `rmail-dont-reply-to-names'. - (insert (prog1 (rmail-dont-reply-to (buffer-string)) - (erase-buffer))) - (goto-char (point-min)) - ;; Perhaps Mail-Copies-To: never removed the only address? - (when (eobp) - (insert (or reply-to from ""))) - (setq ccalist - (mapcar - (lambda (addr) - (cons (mail-strip-quoted-names addr) addr)) - (message-tokenize-header (buffer-string)))) - (let ((s ccalist)) - (while s - (setq ccalist (delq (assoc (car (pop s)) s) ccalist))))) - (setq follow-to (list (cons 'To (cdr (pop ccalist))))) - (when ccalist - (let ((ccs (cons 'Cc (mapconcat - (lambda (addr) (cdr addr)) ccalist ", ")))) - (when (string-match "^ +" (cdr ccs)) - (setcdr ccs (substring (cdr ccs) (match-end 0)))) - (push ccs follow-to)))))) - (widen)) - - (message-pop-to-buffer (message-buffer-name - (if wide "wide reply" "reply") from - (if wide to-address nil))) - - (setq message-reply-headers - (make-full-mail-header - 0 subject from date message-id references 0 0 "")) - - (message-setup - `((Subject . ,subject) - ,@follow-to - ,@(if (or references message-id) - `((References . ,(concat (or references "") (and references " ") - (or message-id "")))) - nil)) - cur))) - -;;;###autoload -(defun message-wide-reply (&optional to-address) - "Make a \"wide\" reply to the message in the current buffer." - (interactive) - (message-reply to-address t)) - -;;;###autoload -(defun message-followup (&optional to-newsgroups) - "Follow up to the message in the current buffer. -If TO-NEWSGROUPS, use that as the new Newsgroups line." - (interactive) - (let ((cur (current-buffer)) - from subject date reply-to mct - references message-id follow-to - (inhibit-point-motion-hooks t) - (message-this-is-news t) - followup-to distribution newsgroups gnus-warning posted-to) - (save-restriction - (narrow-to-region - (goto-char (point-min)) - (if (search-forward "\n\n" nil t) - (1- (point)) - (point-max))) - (when (message-functionp message-followup-to-function) - (setq follow-to - (funcall message-followup-to-function))) - (setq from (message-fetch-field "from") - date (message-fetch-field "date") - subject (or (message-fetch-field "subject") "none") - references (message-fetch-field "references") - message-id (message-fetch-field "message-id" t) - followup-to (message-fetch-field "followup-to") - newsgroups (message-fetch-field "newsgroups") - posted-to (message-fetch-field "posted-to") - reply-to (message-fetch-field "reply-to") - distribution (message-fetch-field "distribution") - mct (message-fetch-field "mail-copies-to")) - (when (and (setq gnus-warning (message-fetch-field "gnus-warning")) - (string-match "<[^>]+>" gnus-warning)) - (setq message-id (match-string 0 gnus-warning))) - ;; Remove bogus distribution. - (when (and (stringp distribution) - (let ((case-fold-search t)) - (string-match "world" distribution))) - (setq distribution nil)) - ;; Remove any (buggy) Re:'s that are present and make a - ;; proper one. - (when (string-match message-subject-re-regexp subject) - (setq subject (substring subject (match-end 0)))) - (setq subject (concat "Re: " subject)) - (widen)) - - (message-pop-to-buffer (message-buffer-name "followup" from newsgroups)) - - (message-setup - `((Subject . ,subject) - ,@(cond - (to-newsgroups - (list (cons 'Newsgroups to-newsgroups))) - (follow-to follow-to) - ((and followup-to message-use-followup-to) - (list - (cond - ((equal (downcase followup-to) "poster") - (if (or (eq message-use-followup-to 'use) - (message-y-or-n-p "Obey Followup-To: poster? " t "\ -You should normally obey the Followup-To: header. - -`Followup-To: poster' sends your response via e-mail instead of news. - -A typical situation where `Followup-To: poster' is used is when the poster -does not read the newsgroup, so he wouldn't see any replies sent to it.")) - (progn - (setq message-this-is-news nil) - (cons 'To (or reply-to from ""))) - (cons 'Newsgroups newsgroups))) - (t - (if (or (equal followup-to newsgroups) - (not (eq message-use-followup-to 'ask)) - (message-y-or-n-p - (concat "Obey Followup-To: " followup-to "? ") t "\ -You should normally obey the Followup-To: header. - - `Followup-To: " followup-to "' -directs your response to " (if (string-match "," followup-to) - "the specified newsgroups" - "that newsgroup only") ". - -If a message is posted to several newsgroups, Followup-To is often -used to direct the following discussion to one newsgroup only, -because discussions that are spread over several newsgroup tend to -be fragmented and very difficult to follow. - -Also, some source/announcement newsgroups are not indented for discussion; -responses here are directed to other newsgroups.")) - (cons 'Newsgroups followup-to) - (cons 'Newsgroups newsgroups)))))) - (posted-to - `((Newsgroups . ,posted-to))) - (t - `((Newsgroups . ,newsgroups)))) - ,@(and distribution (list (cons 'Distribution distribution))) - ,@(if (or references message-id) - `((References . ,(concat (or references "") (and references " ") - (or message-id ""))))) - ,@(when (and mct - (not (equal (downcase mct) "never"))) - (list (cons 'Cc (if (equal (downcase mct) "always") - (or reply-to from "") - mct))))) - - cur) - - (setq message-reply-headers - (make-full-mail-header - 0 subject from date message-id references 0 0 "")))) - - -;;;###autoload -(defun message-cancel-news () - "Cancel an article you posted." - (interactive) - (unless (message-news-p) - (error "This is not a news article; canceling is impossible")) - (when (yes-or-no-p "Do you really want to cancel this article? ") - (let (from newsgroups message-id distribution buf sender) - (save-excursion - ;; Get header info. from original article. - (save-restriction - (message-narrow-to-head) - (setq from (message-fetch-field "from") - sender (message-fetch-field "sender") - newsgroups (message-fetch-field "newsgroups") - message-id (message-fetch-field "message-id" t) - distribution (message-fetch-field "distribution"))) - ;; Make sure that this article was written by the user. - (unless (or (and sender - (string-equal - (downcase sender) - (downcase (message-make-sender)))) - (string-equal - (downcase (cadr (mail-extract-address-components from))) - (downcase (cadr (mail-extract-address-components - (message-make-from)))))) - (error "This article is not yours")) - ;; Make control message. - (setq buf (set-buffer (get-buffer-create " *message cancel*"))) - (buffer-disable-undo (current-buffer)) - (erase-buffer) - (insert "Newsgroups: " newsgroups "\n" - "From: " (message-make-from) "\n" - "Subject: cmsg cancel " message-id "\n" - "Control: cancel " message-id "\n" - (if distribution - (concat "Distribution: " distribution "\n") - "") - mail-header-separator "\n" - message-cancel-message) - (message "Canceling your article...") - (if (let ((message-syntax-checks - 'dont-check-for-anything-just-trust-me) - (message-encoding-buffer (current-buffer)) - (message-edit-buffer (current-buffer))) - (message-send-news)) - (message "Canceling your article...done")) - (kill-buffer buf))))) - -;;;###autoload -(defun message-supersede () - "Start composing a message to supersede the current message. -This is done simply by taking the old article and adding a Supersedes -header line with the old Message-ID." - (interactive) - (let ((cur (current-buffer)) - (sender (message-fetch-field "sender")) - (from (message-fetch-field "from"))) - ;; Check whether the user owns the article that is to be superseded. - (unless (or (and sender - (string-equal - (downcase sender) - (downcase (message-make-sender)))) - (string-equal - (downcase (cadr (mail-extract-address-components from))) - (downcase (cadr (mail-extract-address-components - (message-make-from)))))) - (error "This article is not yours")) - ;; Get a normal message buffer. - (message-pop-to-buffer (message-buffer-name "supersede")) - (insert-buffer-substring cur) - (message-narrow-to-head) - ;; Remove unwanted headers. - (when message-ignored-supersedes-headers - (message-remove-header message-ignored-supersedes-headers t)) - (goto-char (point-min)) - (if (not (re-search-forward "^Message-ID: " nil t)) - (error "No Message-ID in this article") - (replace-match "Supersedes: " t t)) - (goto-char (point-max)) - (insert mail-header-separator) - (widen) - (forward-line 1))) - -;;;###autoload -(defun message-recover () - "Reread contents of current buffer from its last auto-save file." - (interactive) - (let ((file-name (make-auto-save-file-name))) - (cond ((save-window-excursion - (if (not (eq system-type 'vax-vms)) - (with-output-to-temp-buffer "*Directory*" - (buffer-disable-undo standard-output) - (let ((default-directory "/")) - (call-process - "ls" nil standard-output nil "-l" file-name)))) - (yes-or-no-p (format "Recover auto save file %s? " file-name))) - (let ((buffer-read-only nil)) - (erase-buffer) - (insert-file-contents file-name nil))) - (t (error "message-recover cancelled"))))) - -;;; Washing Subject: - -(defun message-wash-subject (subject) - "Remove junk like \"Re:\", \"(fwd)\", etc. that was added to the subject by previous forwarders, replyers, etc." - (nnheader-temp-write nil - (insert-string subject) - (goto-char (point-min)) - ;; strip Re/Fwd stuff off the beginning - (while (re-search-forward - "\\([Rr][Ee]:\\|[Ff][Ww][Dd]\\(\\[[0-9]*\\]\\)?:\\|[Ff][Ww]:\\)" nil t) - (replace-match "")) - - ;; and gnus-style forwards [foo@bar.com] subject - (goto-char (point-min)) - (while (re-search-forward "\\[[^ \t]*\\(@\\|\\.\\)[^ \t]*\\]" nil t) - (replace-match "")) - - ;; and off the end - (goto-char (point-max)) - (while (re-search-backward "([Ff][Ww][Dd])" nil t) - (replace-match "")) - - ;; and finally, any whitespace that was left-over - (goto-char (point-min)) - (while (re-search-forward "^[ \t]+" nil t) - (replace-match "")) - (goto-char (point-max)) - (while (re-search-backward "[ \t]+$" nil t) - (replace-match "")) - - (buffer-string))) - -;;; Forwarding messages. - -(defun message-forward-subject-author-subject (subject) - "Generate a subject for a forwarded message. -The form is: [Source] Subject, where if the original message was mail, -Source is the sender, and if the original message was news, Source is -the list of newsgroups is was posted to." - (concat "[" - (or (message-fetch-field - (if (message-news-p) "newsgroups" "from")) - "(nowhere)") - "] " subject)) - -(defun message-forward-subject-fwd (subject) - "Generate a subject for a forwarded message. -The form is: Fwd: Subject, where Subject is the original subject of -the message." - (concat "Fwd: " subject)) - -(defun message-make-forward-subject () - "Return a Subject header suitable for the message in the current buffer." - (save-excursion - (save-restriction - (current-buffer) - (message-narrow-to-head) - (let ((funcs message-make-forward-subject-function) - (subject (if message-wash-forwarded-subjects - (message-wash-subject - (or (eword-decode-unstructured-field-body - (message-fetch-field "Subject")) "")) - (or (eword-decode-unstructured-field-body - (message-fetch-field "Subject")) "")))) - ;; Make sure funcs is a list. - (and funcs - (not (listp funcs)) - (setq funcs (list funcs))) - ;; Apply funcs in order, passing subject generated by previous - ;; func to the next one. - (while funcs - (when (message-functionp (car funcs)) - (setq subject (funcall (car funcs) subject))) - (setq funcs (cdr funcs))) - subject)))) - -;;;###autoload -(defun message-forward (&optional news) - "Forward the current message via mail. -Optional NEWS will use news to forward instead of mail." - (interactive "P") - (let ((cur (current-buffer)) - (subject (message-make-forward-subject)) - art-beg) - (if news (message-news nil subject) (message-mail nil subject)) - ;; Put point where we want it before inserting the forwarded - ;; message. - (if message-signature-before-forwarded-message - (goto-char (point-max)) - (message-goto-body)) - ;; Make sure we're at the start of the line. - (unless (eolp) - (insert "\n")) - ;; Narrow to the area we are to insert. - (narrow-to-region (point) (point)) - ;; Insert the separators and the forwarded buffer. - (insert message-forward-start-separator) - (setq art-beg (point)) - (insert-buffer-substring cur) - (goto-char (point-max)) - (insert message-forward-end-separator) - (set-text-properties (point-min) (point-max) nil) - ;; Remove all unwanted headers. - (goto-char art-beg) - (narrow-to-region (point) (if (search-forward "\n\n" nil t) - (1- (point)) - (point))) - (goto-char (point-min)) - (message-remove-header message-included-forward-headers t nil t) - (widen) - (message-position-point))) - -;;;###autoload -(defun message-resend (address) - "Resend the current article to ADDRESS." - (interactive "sResend message to: ") - (message "Resending message to %s..." address) - (save-excursion - (let ((cur (current-buffer)) - beg) - ;; We first set up a normal mail buffer. - (set-buffer (get-buffer-create " *message resend*")) - (buffer-disable-undo (current-buffer)) - (erase-buffer) - ;; avoid to turn-on-mime-edit - (let (message-setup-hook) - (message-setup `((To . ,address))) - ) - ;; Insert our usual headers. - (message-generate-headers '(From Date To)) - (message-narrow-to-headers) - ;; Rename them all to "Resent-*". - (while (re-search-forward "^[A-Za-z]" nil t) - (forward-char -1) - (insert "Resent-")) - (widen) - (forward-line) - (delete-region (point) (point-max)) - (setq beg (point)) - ;; Insert the message to be resent. - (insert-buffer-substring cur) - (goto-char (point-min)) - (search-forward "\n\n") - (forward-char -1) - (save-restriction - (narrow-to-region beg (point)) - (message-remove-header message-ignored-resent-headers t) - (goto-char (point-max))) - (insert mail-header-separator) - ;; Rename all old ("Also-")Resent headers. - (while (re-search-backward "^\\(Also-\\)*Resent-" beg t) - (beginning-of-line) - (insert "Also-")) - ;; Quote any "From " lines at the beginning. - (goto-char beg) - (when (looking-at "From ") - (replace-match "X-From-Line: ")) - ;; Send it. - (let ((message-encoding-buffer (current-buffer)) - (message-edit-buffer (current-buffer))) - (message-send-mail)) - (kill-buffer (current-buffer))) - (message "Resending message to %s...done" address))) - -;;;###autoload -(defun message-bounce () - "Re-mail the current message. -This only makes sense if the current message is a bounce message than -contains some mail you have written which has been bounced back to -you." - (interactive) - (let ((cur (current-buffer)) - boundary) - (message-pop-to-buffer (message-buffer-name "bounce")) - (insert-buffer-substring cur) - (undo-boundary) - (message-narrow-to-head) - (if (and (message-fetch-field "MIME-Version") - (setq boundary (message-fetch-field "Content-Type"))) - (if (string-match "boundary=\"\\([^\"]+\\)\"" boundary) - (setq boundary (concat (match-string 1 boundary) " *\n" - "Content-Type: message/rfc822")) - (setq boundary nil))) - (widen) - (goto-char (point-min)) - (search-forward "\n\n" nil t) - (or (and boundary - (re-search-forward boundary nil t) - (forward-line 2)) - (and (re-search-forward message-unsent-separator nil t) - (forward-line 1)) - (re-search-forward "^Return-Path:.*\n" nil t)) - ;; We remove everything before the bounced mail. - (delete-region - (point-min) - (if (re-search-forward "^[^ \n\t]+:" nil t) - (match-beginning 0) - (point))) - (save-restriction - (message-narrow-to-head) - (message-remove-header message-ignored-bounced-headers t) - (goto-char (point-max)) - (insert mail-header-separator)) - (message-position-point))) - -;;; -;;; Interactive entry points for new message buffers. -;;; - -;;;###autoload -(defun message-mail-other-window (&optional to subject) - "Like `message-mail' command, but display mail buffer in another window." - (interactive) - (let ((pop-up-windows t) - (special-display-buffer-names nil) - (special-display-regexps nil) - (same-window-buffer-names nil) - (same-window-regexps nil)) - (message-pop-to-buffer (message-buffer-name "mail" to))) - (let ((message-this-is-mail t)) - (message-setup `((To . ,(or to "")) (Subject . ,(or subject "")))))) - -;;;###autoload -(defun message-mail-other-frame (&optional to subject) - "Like `message-mail' command, but display mail buffer in another frame." - (interactive) - (let ((pop-up-frames t) - (special-display-buffer-names nil) - (special-display-regexps nil) - (same-window-buffer-names nil) - (same-window-regexps nil)) - (message-pop-to-buffer (message-buffer-name "mail" to))) - (let ((message-this-is-mail t)) - (message-setup `((To . ,(or to "")) (Subject . ,(or subject "")))))) - -;;;###autoload -(defun message-news-other-window (&optional newsgroups subject) - "Start editing a news article to be sent." - (interactive) - (let ((pop-up-windows t) - (special-display-buffer-names nil) - (special-display-regexps nil) - (same-window-buffer-names nil) - (same-window-regexps nil)) - (message-pop-to-buffer (message-buffer-name "news" nil newsgroups))) - (let ((message-this-is-news t)) - (message-setup `((Newsgroups . ,(or newsgroups "")) - (Subject . ,(or subject "")))))) - -;;;###autoload -(defun message-news-other-frame (&optional newsgroups subject) - "Start editing a news article to be sent." - (interactive) - (let ((pop-up-frames t) - (special-display-buffer-names nil) - (special-display-regexps nil) - (same-window-buffer-names nil) - (same-window-regexps nil)) - (message-pop-to-buffer (message-buffer-name "news" nil newsgroups))) - (let ((message-this-is-news t)) - (message-setup `((Newsgroups . ,(or newsgroups "")) - (Subject . ,(or subject "")))))) - -;;; underline.el - -;; This code should be moved to underline.el (from which it is stolen). - -;;;###autoload -(defun bold-region (start end) - "Bold all nonblank characters in the region. -Works by overstriking characters. -Called from program, takes two arguments START and END -which specify the range to operate on." - (interactive "r") - (save-excursion - (let ((end1 (make-marker))) - (move-marker end1 (max start end)) - (goto-char (min start end)) - (while (< (point) end1) - (or (looking-at "[_\^@- ]") - (insert (following-char) "\b")) - (forward-char 1))))) - -;;;###autoload -(defun unbold-region (start end) - "Remove all boldness (overstruck characters) in the region. -Called from program, takes two arguments START and END -which specify the range to operate on." - (interactive "r") - (save-excursion - (let ((end1 (make-marker))) - (move-marker end1 (max start end)) - (goto-char (min start end)) - (while (re-search-forward "\b" end1 t) - (if (eq (following-char) (char-after (- (point) 2))) - (delete-char -2)))))) - -(defalias 'message-exchange-point-and-mark 'exchange-point-and-mark) - -;; Support for toolbar -(when (string-match "XEmacs\\|Lucid" emacs-version) - (require 'messagexmas)) - -;;; Group name completion. - -(defvar message-newgroups-header-regexp - "^\\(Newsgroups\\|Followup-To\\|Posted-To\\|Gcc\\):" - "Regexp that match headers that lists groups.") - -(defun message-tab () - "Expand group names in Newsgroups and Followup-To headers. -Do a `tab-to-tab-stop' if not in those headers." - (interactive) - (if (let ((mail-abbrev-mode-regexp message-newgroups-header-regexp)) - (mail-abbrev-in-expansion-header-p)) - (message-expand-group) - (tab-to-tab-stop))) - -(defvar gnus-active-hashtb) -(defun message-expand-group () - "Expand the group name under point." - (let* ((b (save-excursion - (save-restriction - (narrow-to-region - (save-excursion - (beginning-of-line) - (skip-chars-forward "^:") - (1+ (point))) - (point)) - (skip-chars-backward "^, \t\n") (point)))) - (completion-ignore-case t) - (string (buffer-substring b (progn (skip-chars-forward "^,\t\n ") - (point)))) - (hashtb (and (boundp 'gnus-active-hashtb) gnus-active-hashtb)) - (completions (all-completions string hashtb)) - comp) - (delete-region b (point)) - (cond - ((= (length completions) 1) - (if (string= (car completions) string) - (progn - (insert string) - (message "Only matching group")) - (insert (car completions)))) - ((and (setq comp (try-completion string hashtb)) - (not (string= comp string))) - (insert comp)) - (t - (insert string) - (if (not comp) - (message "No matching groups") - (save-selected-window - (pop-to-buffer "*Completions*") - (buffer-disable-undo (current-buffer)) - (let ((buffer-read-only nil)) - (erase-buffer) - (let ((standard-output (current-buffer))) - (display-completion-list (sort completions 'string<))) - (goto-char (point-min)) - (delete-region (point) (progn (forward-line 3) (point)))))))))) - -;;; Help stuff. - -(defun message-talkative-question (ask question show &rest text) - "Call FUNCTION with argument QUESTION; optionally display TEXT... args. -If SHOW is non-nil, the arguments TEXT... are displayed in a temp buffer. -The following arguments may contain lists of values." - (if (and show - (setq text (message-flatten-list text))) - (save-window-excursion - (save-excursion - (with-output-to-temp-buffer " *MESSAGE information message*" - (set-buffer " *MESSAGE information message*") - (mapcar 'princ text) - (goto-char (point-min)))) - (funcall ask question)) - (funcall ask question))) - -(defun message-flatten-list (list) - "Return a new, flat list that contains all elements of LIST. - -\(message-flatten-list '(1 (2 3 (4 5 (6))) 7)) -=> (1 2 3 4 5 6 7)" - (cond ((consp list) - (apply 'append (mapcar 'message-flatten-list list))) - (list - (list list)))) - -(defun message-generate-new-buffer-clone-locals (name &optional varstr) - "Create and return a buffer with a name based on NAME using generate-new-buffer. -Then clone the local variables and values from the old buffer to the -new one, cloning only the locals having a substring matching the -regexp varstr." - (let ((oldbuf (current-buffer))) - (save-excursion - (set-buffer (generate-new-buffer name)) - (message-clone-locals oldbuf) - (current-buffer)))) - -(defun message-clone-locals (buffer) - "Clone the local variables from BUFFER to the current buffer." - (let ((locals (save-excursion - (set-buffer buffer) - (buffer-local-variables))) - (regexp "^\\(gnus\\|nn\\|message\\|user-\\(mail-address\\|full-name\\)\\)")) - (mapcar - (lambda (local) - (when (and (consp local) - (car local) - (string-match regexp (symbol-name (car local)))) - (ignore-errors - (set (make-local-variable (car local)) - (cdr local))))) - locals))) - - -;;; @ for MIME Edit mode -;;; - -(defun message-maybe-setup-default-charset () - (let ((charset - (and (boundp 'gnus-summary-buffer) - (buffer-live-p gnus-summary-buffer) - (save-excursion - (set-buffer gnus-summary-buffer) - default-mime-charset)))) - (if charset - (progn - (make-local-variable 'default-mime-charset) - (setq default-mime-charset charset) - )))) - -(defun message-maybe-encode () - (when message-mime-mode - (run-hooks 'mime-edit-translate-hook) - (if (catch 'mime-edit-error - (save-excursion - (mime-edit-translate-body) - )) - (error "Translation error!") - ) - (end-of-invisible) - (run-hooks 'mime-edit-exit-hook) - )) - -(defun message-mime-insert-article (&optional message) - (interactive) - (let ((message-cite-function 'mime-edit-inserted-message-filter) - (message-reply-buffer gnus-original-article-buffer) - ) - (message-yank-original nil) - )) - -(set-alist 'mime-edit-message-inserter-alist - 'message-mode (function message-mime-insert-article)) - -;;; Miscellaneous functions - -;; stolen (and renamed) from nnheader.el -(defun message-replace-chars-in-string (string from to) - "Replace characters in STRING from FROM to TO." - (let ((string (substring string 0)) ;Copy string. - (len (length string)) - (idx 0)) - ;; Replace all occurrences of FROM with TO. - (while (< idx len) - (when (= (aref string idx) from) - (aset string idx to)) - (setq idx (1+ idx))) - string)) - -(run-hooks 'message-load-hook) - -(provide 'message) - -;;; message.el ends here diff --git a/lisp/messagexmas.el b/lisp/messagexmas.el deleted file mode 100644 index 7e3edd3..0000000 --- a/lisp/messagexmas.el +++ /dev/null @@ -1,124 +0,0 @@ -;;; messagexmas.el --- XEmacs extensions to message -;; Copyright (C) 1996,97,98 Free Software Foundation, Inc. - -;; Author: Lars Magne Ingebrigtsen -;; Keywords: mail, news - -;; This file is part of GNU Emacs. - -;; GNU Emacs is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 2, or (at your option) -;; any later version. - -;; GNU Emacs is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs; see the file COPYING. If not, write to the -;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. - -;;; Commentary: - -;;; Code: - -(require 'nnheader) - -(defvar message-xmas-dont-activate-region t - "If t, don't activate region after yanking.") - -(defvar message-xmas-glyph-directory nil - "*Directory where Message logos and icons are located. -If this variable is nil, Message will try to locate the directory -automatically.") - -(defvar message-use-toolbar (if (featurep 'toolbar) - 'default-toolbar - nil) - "*If nil, do not use a toolbar. -If it is non-nil, it must be a toolbar. The five legal values are -`default-toolbar', `top-toolbar', `bottom-toolbar', -`right-toolbar', and `left-toolbar'.") - -(defvar message-toolbar - '([message-spell ispell-message t "Spell"] - [message-help (Info-goto-node "(Message)Top") t "Message help"]) - "The message buffer toolbar.") - -(defun message-xmas-find-glyph-directory (&optional package) - (setq package (or package "message")) - (let ((dir (symbol-value - (intern-soft (concat package "-xmas-glyph-directory"))))) - (if (and (stringp dir) (file-directory-p dir)) - dir - (nnheader-find-etc-directory package)))) - -(defun message-xmas-setup-toolbar (bar &optional force package) - (let ((dir (message-xmas-find-glyph-directory package)) - (xpm (if (featurep 'xpm) "xpm" "xbm")) - icon up down disabled name) - (unless package - (setq message-xmas-glyph-directory dir)) - (when dir - (while bar - (setq icon (aref (car bar) 0) - name (symbol-name icon) - bar (cdr bar)) - (when (or force - (not (boundp icon))) - (setq up (concat dir name "-up." xpm)) - (setq down (concat dir name "-down." xpm)) - (setq disabled (concat dir name "-disabled." xpm)) - (if (not (file-exists-p up)) - (setq bar nil - dir nil) - (set icon (toolbar-make-button-list - up (and (file-exists-p down) down) - (and (file-exists-p disabled) disabled))))))) - dir)) - -(defun message-setup-toolbar () - (and message-use-toolbar - (message-xmas-setup-toolbar message-toolbar) - (set-specifier (symbol-value message-use-toolbar) - (cons (current-buffer) message-toolbar)))) - -(defun message-xmas-exchange-point-and-mark () - "Exchange point and mark, but allow for XEmacs' optional argument." - (exchange-point-and-mark message-xmas-dont-activate-region)) - -(fset 'message-exchange-point-and-mark 'message-xmas-exchange-point-and-mark) - -(defun message-xmas-maybe-fontify () - (when (featurep 'font-lock) - (font-lock-set-defaults))) - -(defun message-xmas-make-caesar-translation-table (n) - "Create a rot table with offset N." - (let ((i -1) - (table (make-string 256 0)) - (a (char-int ?a)) - (A (char-int ?A))) - (while (< (incf i) 256) - (aset table i i)) - (concat - (substring table 0 A) - (substring table (+ A n) (+ A n (- 26 n))) - (substring table A (+ A n)) - (substring table (+ A 26) a) - (substring table (+ a n) (+ a n (- 26 n))) - (substring table a (+ a n)) - (substring table (+ a 26) 255)))) - -(when (>= emacs-major-version 20) - (fset 'message-make-caesar-translation-table - 'message-xmas-make-caesar-translation-table)) - -(add-hook 'message-mode-hook 'message-xmas-maybe-fontify) - -(provide 'messagexmas) - -;;; messagexmas.el ends here diff --git a/lisp/messcompat.el b/lisp/messcompat.el deleted file mode 100644 index 153f76d..0000000 --- a/lisp/messcompat.el +++ /dev/null @@ -1,92 +0,0 @@ -;;; messcompat.el --- making message mode compatible with mail mode -;; Copyright (C) 1996,97,98 Free Software Foundation, Inc. - -;; Author: Lars Magne Ingebrigtsen -;; Keywords: mail, news - -;; This file is part of GNU Emacs. - -;; GNU Emacs is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 2, or (at your option) -;; any later version. - -;; GNU Emacs is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs; see the file COPYING. If not, write to the -;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. - -;;; Commentary: - -;; This file tries to provide backward compatability with sendmail.el -;; for Message mode. It should be used by simply adding -;; -;; (require 'messcompat) -;; -;; to the .emacs file. Loading it after Message mode has been -;; loaded will have no effect. - -;;; Code: - -(require 'sendmail) - -(defvar message-from-style mail-from-style - "*Specifies how \"From\" headers look. - -If `nil', they contain just the return address like: - king@grassland.com -If `parens', they look like: - king@grassland.com (Elvis Parsley) -If `angles', they look like: - Elvis Parsley - -Otherwise, most addresses look like `angles', but they look like -`parens' if `angles' would need quoting and `parens' would not.") - -(defvar message-interactive mail-interactive - "Non-nil means when sending a message wait for and display errors. -nil means let mailer mail back a message to report errors.") - -(defvar message-setup-hook mail-setup-hook - "Normal hook, run each time a new outgoing message is initialized. -The function `message-setup' runs this hook.") - -(if (boundp 'mail-mode-hook) - (defvar message-mode-hook mail-mode-hook - "Hook run in message mode buffers.")) - -(defvar message-indentation-spaces mail-indentation-spaces - "*Number of spaces to insert at the beginning of each cited line. -Used by `message-yank-original' via `message-yank-cite'.") - -(defvar message-signature mail-signature - "*String to be inserted at the end of the message buffer. -If t, the `message-signature-file' file will be inserted instead. -If a function, the result from the function will be used instead. -If a form, the result from the form will be used instead.") - -;; Deleted the autoload cookie because this crashes in loaddefs.el. -(defvar message-signature-file mail-signature-file - "*File containing the text inserted at end of message. buffer.") - -(defvar message-default-headers mail-default-headers - "*A string containing header lines to be inserted in outgoing messages. -It is inserted before you edit the message, so you can edit or delete -these lines.") - -(defvar message-send-hook mail-send-hook - "Hook run before sending messages.") - -(defvar message-send-mail-function send-mail-function - "Function to call to send the current buffer as mail. -The headers should be delimited by a line whose contents match the -variable `mail-header-separator'.") - -(provide 'messcompat) - -;;; messcompat.el ends here diff --git a/lisp/mmgnus.el b/lisp/mmgnus.el deleted file mode 100644 index 0ecc7f9..0000000 --- a/lisp/mmgnus.el +++ /dev/null @@ -1,77 +0,0 @@ -;;; mmgnus.el --- MIME entity implementation for gnus-article - -;; Copyright (C) 1998 Free Software Foundation, Inc. - -;; Author: MORIOKA Tomohiko -;; Keywords: MIME, multimedia, mail, news - -;; This file is part of Chao-gnus. - -;; This program is free software; you can redistribute it and/or -;; modify it under the terms of the GNU General Public License as -;; published by the Free Software Foundation; either version 2, or (at -;; your option) any later version. - -;; This program is distributed in the hope that it will be useful, but -;; WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -;; General Public License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs; see the file COPYING. If not, write to the -;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. - -;;; Code: - -(require 'mmbuffer) - -(mm-define-backend gnus (buffer)) - -(mm-define-method entity-header-start ((entity gnus)) - (save-excursion - (set-buffer (mime-entity-buffer-internal entity)) - (goto-char (point-min)) - )) - -(mm-define-method entity-header-end ((entity gnus)) - (save-excursion - (set-buffer (mime-entity-buffer-internal entity)) - (goto-char (point-min)) - (if (re-search-forward "^$" nil t) - (match-end 0) - ))) - -(mm-define-method fetch-field ((entity gnus) field-name) - (save-excursion - (set-buffer (mime-entity-buffer-internal entity)) - (unless (mime-entity-header-start-internal entity) - (mime-entity-set-header-start-internal entity (point-min)) - (mime-entity-set-body-end-internal entity (point-max)) - (if (re-search-forward "^$" nil t) - (progn - (mime-entity-set-header-end-internal entity (match-end 0)) - (mime-entity-set-body-start-internal - entity - (if (= (mime-entity-header-end-internal entity) - (mime-entity-body-end-internal entity)) - (mime-entity-body-end-internal entity) - (1+ (mime-entity-header-end-internal entity)) - )) - ) - (mime-entity-set-header-end-internal entity (point-min)) - (mime-entity-set-body-start-internal entity (point-min)) - )) - (save-restriction - (narrow-to-region (mime-entity-header-start-internal entity) - (mime-entity-header-end-internal entity)) - (std11-fetch-field field-name) - ))) - - -;;; @ end -;;; - -(provide 'mmgnus) - -;;; mmgnus.el ends here diff --git a/lisp/nnagent.el b/lisp/nnagent.el deleted file mode 100644 index 714a07a..0000000 --- a/lisp/nnagent.el +++ /dev/null @@ -1,124 +0,0 @@ -;;; nnagent.el --- offline backend for Gnus -;; Copyright (C) 1997,98 Free Software Foundation, Inc. - -;; Author: Lars Magne Ingebrigtsen -;; Keywords: news, mail - -;; This file is part of GNU Emacs. - -;; GNU Emacs is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 2, or (at your option) -;; any later version. - -;; GNU Emacs is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs; see the file COPYING. If not, write to the -;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. - -;;; Commentary: - -;;; Code: - -(require 'nnheader) -(require 'nnoo) -(eval-when-compile (require 'cl)) -(require 'gnus-agent) -(require 'nnml) - -(nnoo-declare nnagent - nnml) - - - -(defconst nnagent-version "nnagent 1.0") - -(defvoo nnagent-directory nil - "Internal variable." - nnml-directory) - -(defvoo nnagent-active-file nil - "Internal variable." - nnml-active-file) - -(defvoo nnagent-newsgroups-file nil - "Internal variable." - nnml-newsgroups-file) - -(defvoo nnagent-get-new-mail nil - "Internal variable." - nnml-get-new-mail) - -;;; Interface functions. - -(nnoo-define-basics nnagent) - -(deffoo nnagent-open-server (server &optional defs) - (setq defs - `((nnagent-directory ,(gnus-agent-directory)) - (nnagent-active-file ,(gnus-agent-lib-file "active")) - (nnagent-newsgroups-file ,(gnus-agent-lib-file "newsgroups")) - (nnagent-get-new-mail nil))) - (nnoo-change-server 'nnagent server defs) - (let ((dir (gnus-agent-directory)) - err) - (cond - ((not (condition-case arg - (file-exists-p dir) - (ftp-error (setq err (format "%s" arg))))) - (nnagent-close-server) - (nnheader-report - 'nnagent (or err "No such file or directory: %s" dir))) - ((not (file-directory-p (file-truename dir))) - (nnagent-close-server) - (nnheader-report 'nnagent "Not a directory: %s" dir)) - (t - (nnheader-report 'nnagent "Opened server %s using directory %s" - server dir) - t)))) - -(deffoo nnagent-retrieve-groups (groups &optional server) - (save-excursion - (cond - ((file-exists-p (gnus-agent-lib-file "groups")) - (nnmail-find-file (gnus-agent-lib-file "groups")) - 'groups) - ((file-exists-p (gnus-agent-lib-file "active")) - (nnmail-find-file (gnus-agent-lib-file "active")) - 'active) - (t nil)))) - -(defun nnagent-request-type (group article) - (unless (stringp article) - (let ((gnus-plugged t)) - (if (not (gnus-check-backend-function - 'request-type (car gnus-command-method))) - 'unknown - (funcall (gnus-get-function gnus-command-method 'request-type) - (gnus-group-real-name group) article))))) - -(deffoo nnagent-request-newgroups (date server) - nil) - -(deffoo nnagent-request-update-info (group info &optional server) - nil) - -(deffoo nnagent-request-post (&optional server) - (gnus-agent-insert-meta-information 'news gnus-command-method) - (gnus-request-accept-article "nndraft:queue")) - -;; Use nnml functions for just about everything. -(nnoo-import nnagent - (nnml)) - - -;;; Internal functions. - -(provide 'nnagent) - -;;; nnagent.el ends here diff --git a/lisp/nnbabyl.el b/lisp/nnbabyl.el deleted file mode 100644 index def1e0c..0000000 --- a/lisp/nnbabyl.el +++ /dev/null @@ -1,652 +0,0 @@ -;;; nnbabyl.el --- rmail mbox access for Gnus -;; Copyright (C) 1995,96,97,98 Free Software Foundation, Inc. - -;; Author: Lars Magne Ingebrigtsen -;; Masanobu UMEDA -;; Keywords: news, mail - -;; This file is part of GNU Emacs. - -;; GNU Emacs is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 2, or (at your option) -;; any later version. - -;; GNU Emacs is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs; see the file COPYING. If not, write to the -;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. - -;;; Commentary: - -;; For an overview of what the interface functions do, please see the -;; Gnus sources. - -;;; Code: - -(require 'nnheader) -(condition-case nil - (require 'rmail) - (t (nnheader-message 5 "Ignore rmail errors from this file, you don't have rmail"))) -(require 'nnmail) -(require 'nnoo) -(eval-when-compile (require 'cl)) - -(nnoo-declare nnbabyl) - -(defvoo nnbabyl-mbox-file (expand-file-name "~/RMAIL") - "The name of the rmail box file in the users home directory.") - -(defvoo nnbabyl-active-file (expand-file-name "~/.rmail-active") - "The name of the active file for the rmail box.") - -(defvoo nnbabyl-get-new-mail t - "If non-nil, nnbabyl will check the incoming mail file and split the mail.") - -(defvoo nnbabyl-prepare-save-mail-hook nil - "Hook run narrowed to an article before saving.") - - - -(defvar nnbabyl-mail-delimiter "\^_") - -(defconst nnbabyl-version "nnbabyl 1.0" - "nnbabyl version.") - -(defvoo nnbabyl-mbox-buffer nil) -(defvoo nnbabyl-current-group nil) -(defvoo nnbabyl-status-string "") -(defvoo nnbabyl-group-alist nil) -(defvoo nnbabyl-active-timestamp nil) - -(defvoo nnbabyl-previous-buffer-mode nil) - -(eval-and-compile - (autoload 'gnus-set-text-properties "gnus-ems")) - - - -;;; Interface functions - -(nnoo-define-basics nnbabyl) - -(deffoo nnbabyl-retrieve-headers (articles &optional group server fetch-old) - (save-excursion - (set-buffer nntp-server-buffer) - (erase-buffer) - (let ((number (length articles)) - (count 0) - (delim (concat "^" nnbabyl-mail-delimiter)) - article art-string start stop) - (nnbabyl-possibly-change-newsgroup group server) - (while (setq article (pop articles)) - (setq art-string (nnbabyl-article-string article)) - (set-buffer nnbabyl-mbox-buffer) - (end-of-line) - (when (or (search-forward art-string nil t) - (search-backward art-string nil t)) - (unless (re-search-backward delim nil t) - (goto-char (point-min))) - (while (and (not (looking-at ".+:")) - (zerop (forward-line 1)))) - (setq start (point)) - (search-forward "\n\n" nil t) - (setq stop (1- (point))) - (set-buffer nntp-server-buffer) - (insert "221 ") - (princ article (current-buffer)) - (insert " Article retrieved.\n") - (insert-buffer-substring nnbabyl-mbox-buffer start stop) - (goto-char (point-max)) - (insert ".\n")) - (and (numberp nnmail-large-newsgroup) - (> number nnmail-large-newsgroup) - (zerop (% (incf count) 20)) - (nnheader-message 5 "nnbabyl: Receiving headers... %d%%" - (/ (* count 100) number)))) - - (and (numberp nnmail-large-newsgroup) - (> number nnmail-large-newsgroup) - (nnheader-message 5 "nnbabyl: Receiving headers...done")) - - (set-buffer nntp-server-buffer) - (nnheader-fold-continuation-lines) - 'headers))) - -(deffoo nnbabyl-open-server (server &optional defs) - (nnoo-change-server 'nnbabyl server defs) - (nnbabyl-create-mbox) - (cond - ((not (file-exists-p nnbabyl-mbox-file)) - (nnbabyl-close-server) - (nnheader-report 'nnbabyl "No such file: %s" nnbabyl-mbox-file)) - ((file-directory-p nnbabyl-mbox-file) - (nnbabyl-close-server) - (nnheader-report 'nnbabyl "Not a regular file: %s" nnbabyl-mbox-file)) - (t - (nnheader-report 'nnbabyl "Opened server %s using mbox %s" server - nnbabyl-mbox-file) - t))) - -(deffoo nnbabyl-close-server (&optional server) - ;; Restore buffer mode. - (when (and (nnbabyl-server-opened) - nnbabyl-previous-buffer-mode) - (save-excursion - (set-buffer nnbabyl-mbox-buffer) - (narrow-to-region - (caar nnbabyl-previous-buffer-mode) - (cdar nnbabyl-previous-buffer-mode)) - (funcall (cdr nnbabyl-previous-buffer-mode)))) - (nnoo-close-server 'nnbabyl server) - (setq nnbabyl-mbox-buffer nil) - t) - -(deffoo nnbabyl-server-opened (&optional server) - (and (nnoo-current-server-p 'nnbabyl server) - nnbabyl-mbox-buffer - (buffer-name nnbabyl-mbox-buffer) - nntp-server-buffer - (buffer-name nntp-server-buffer))) - -(deffoo nnbabyl-request-article (article &optional newsgroup server buffer) - (nnbabyl-possibly-change-newsgroup newsgroup server) - (save-excursion - (set-buffer nnbabyl-mbox-buffer) - (goto-char (point-min)) - (when (search-forward (nnbabyl-article-string article) nil t) - (let (start stop summary-line) - (unless (re-search-backward (concat "^" nnbabyl-mail-delimiter) nil t) - (goto-char (point-min)) - (end-of-line)) - (while (and (not (looking-at ".+:")) - (zerop (forward-line 1)))) - (setq start (point)) - (or (when (re-search-forward - (concat "^" nnbabyl-mail-delimiter) nil t) - (beginning-of-line) - t) - (goto-char (point-max))) - (setq stop (point)) - (let ((nntp-server-buffer (or buffer nntp-server-buffer))) - (set-buffer nntp-server-buffer) - (erase-buffer) - (insert-buffer-substring nnbabyl-mbox-buffer start stop) - (goto-char (point-min)) - ;; If there is an EOOH header, then we have to remove some - ;; duplicated headers. - (setq summary-line (looking-at "Summary-line:")) - (when (search-forward "\n*** EOOH ***" nil t) - (if summary-line - ;; The headers to be deleted are located before the - ;; EOOH line... - (delete-region (point-min) (progn (forward-line 1) - (point))) - ;; ...or after. - (delete-region (progn (beginning-of-line) (point)) - (or (search-forward "\n\n" nil t) - (point))))) - (if (numberp article) - (cons nnbabyl-current-group article) - (nnbabyl-article-group-number))))))) - -(deffoo nnbabyl-request-group (group &optional server dont-check) - (let ((active (cadr (assoc group nnbabyl-group-alist)))) - (save-excursion - (cond - ((or (null active) - (null (nnbabyl-possibly-change-newsgroup group server))) - (nnheader-report 'nnbabyl "No such group: %s" group)) - (dont-check - (nnheader-report 'nnbabyl "Selected group %s" group) - (nnheader-insert "")) - (t - (nnheader-report 'nnbabyl "Selected group %s" group) - (nnheader-insert "211 %d %d %d %s\n" - (1+ (- (cdr active) (car active))) - (car active) (cdr active) group)))))) - -(deffoo nnbabyl-request-scan (&optional group server) - (nnbabyl-possibly-change-newsgroup group server) - (nnbabyl-read-mbox) - (nnmail-get-new-mail - 'nnbabyl - (lambda () - (save-excursion - (set-buffer nnbabyl-mbox-buffer) - (save-buffer))) - (file-name-directory nnbabyl-mbox-file) - group - (lambda () - (save-excursion - (let ((in-buf (current-buffer))) - (goto-char (point-min)) - (while (search-forward "\n\^_\n" nil t) - (delete-char -1)) - (set-buffer nnbabyl-mbox-buffer) - (goto-char (point-max)) - (search-backward "\n\^_" nil t) - (goto-char (match-end 0)) - (insert-buffer-substring in-buf))) - (nnmail-save-active nnbabyl-group-alist nnbabyl-active-file)))) - -(deffoo nnbabyl-close-group (group &optional server) - t) - -(deffoo nnbabyl-request-create-group (group &optional server args) - (nnmail-activate 'nnbabyl) - (unless (assoc group nnbabyl-group-alist) - (push (list group (cons 1 0)) - nnbabyl-group-alist) - (nnmail-save-active nnbabyl-group-alist nnbabyl-active-file)) - t) - -(deffoo nnbabyl-request-list (&optional server) - (save-excursion - (nnmail-find-file nnbabyl-active-file) - (setq nnbabyl-group-alist (nnmail-get-active)) - t)) - -(deffoo nnbabyl-request-newgroups (date &optional server) - (nnbabyl-request-list server)) - -(deffoo nnbabyl-request-list-newsgroups (&optional server) - (nnheader-report 'nnbabyl "nnbabyl: LIST NEWSGROUPS is not implemented.")) - -(deffoo nnbabyl-request-expire-articles - (articles newsgroup &optional server force) - (nnbabyl-possibly-change-newsgroup newsgroup server) - (let* ((is-old t) - rest) - (nnmail-activate 'nnbabyl) - - (save-excursion - (set-buffer nnbabyl-mbox-buffer) - (gnus-set-text-properties (point-min) (point-max) nil) - (while (and articles is-old) - (goto-char (point-min)) - (when (search-forward (nnbabyl-article-string (car articles)) nil t) - (if (setq is-old - (nnmail-expired-article-p - newsgroup - (buffer-substring - (point) (progn (end-of-line) (point))) force)) - (progn - (nnheader-message 5 "Deleting article %d in %s..." - (car articles) newsgroup) - (nnbabyl-delete-mail)) - (push (car articles) rest))) - (setq articles (cdr articles))) - (save-buffer) - ;; Find the lowest active article in this group. - (let ((active (nth 1 (assoc newsgroup nnbabyl-group-alist)))) - (goto-char (point-min)) - (while (and (not (search-forward - (nnbabyl-article-string (car active)) nil t)) - (<= (car active) (cdr active))) - (setcar active (1+ (car active))) - (goto-char (point-min)))) - (nnmail-save-active nnbabyl-group-alist nnbabyl-active-file) - (nconc rest articles)))) - -(deffoo nnbabyl-request-move-article - (article group server accept-form &optional last) - (let ((buf (get-buffer-create " *nnbabyl move*")) - result) - (and - (nnbabyl-request-article article group server) - (save-excursion - (set-buffer buf) - (insert-buffer-substring nntp-server-buffer) - (goto-char (point-min)) - (while (re-search-forward - "^X-Gnus-Newsgroup:" - (save-excursion (search-forward "\n\n" nil t) (point)) t) - (delete-region (progn (beginning-of-line) (point)) - (progn (forward-line 1) (point)))) - (setq result (eval accept-form)) - (kill-buffer (current-buffer)) - result) - (save-excursion - (nnbabyl-possibly-change-newsgroup group server) - (set-buffer nnbabyl-mbox-buffer) - (goto-char (point-min)) - (if (search-forward (nnbabyl-article-string article) nil t) - (nnbabyl-delete-mail)) - (and last (save-buffer)))) - result)) - -(deffoo nnbabyl-request-accept-article (group &optional server last) - (nnbabyl-possibly-change-newsgroup group server) - (nnmail-check-syntax) - (let ((buf (current-buffer)) - result beg) - (and - (nnmail-activate 'nnbabyl) - (save-excursion - (goto-char (point-min)) - (search-forward "\n\n" nil t) - (forward-line -1) - (save-excursion - (while (re-search-backward "^X-Gnus-Newsgroup: " beg t) - (delete-region (point) (progn (forward-line 1) (point))))) - (when nnmail-cache-accepted-message-ids - (nnmail-cache-insert (nnmail-fetch-field "message-id"))) - (setq result - (if (stringp group) - (list (cons group (nnbabyl-active-number group))) - (nnmail-article-group 'nnbabyl-active-number))) - (if (and (null result) - (yes-or-no-p "Moved to `junk' group; delete article? ")) - (setq result 'junk) - (setq result (car (nnbabyl-save-mail result)))) - (set-buffer nnbabyl-mbox-buffer) - (goto-char (point-max)) - (search-backward "\n\^_") - (goto-char (match-end 0)) - (insert-buffer-substring buf) - (when last - (when nnmail-cache-accepted-message-ids - (nnmail-cache-insert (nnmail-fetch-field "message-id"))) - (save-buffer) - (nnmail-save-active nnbabyl-group-alist nnbabyl-active-file)) - result)))) - -(deffoo nnbabyl-request-replace-article (article group buffer) - (nnbabyl-possibly-change-newsgroup group) - (save-excursion - (set-buffer nnbabyl-mbox-buffer) - (goto-char (point-min)) - (if (not (search-forward (nnbabyl-article-string article) nil t)) - nil - (nnbabyl-delete-mail t t) - (insert-buffer-substring buffer) - (save-buffer) - t))) - -(deffoo nnbabyl-request-delete-group (group &optional force server) - (nnbabyl-possibly-change-newsgroup group server) - ;; Delete all articles in GROUP. - (if (not force) - () ; Don't delete the articles. - (save-excursion - (set-buffer nnbabyl-mbox-buffer) - (goto-char (point-min)) - ;; Delete all articles in this group. - (let ((ident (concat "\nX-Gnus-Newsgroup: " nnbabyl-current-group ":")) - found) - (while (search-forward ident nil t) - (setq found t) - (nnbabyl-delete-mail)) - (when found - (save-buffer))))) - ;; Remove the group from all structures. - (setq nnbabyl-group-alist - (delq (assoc group nnbabyl-group-alist) nnbabyl-group-alist) - nnbabyl-current-group nil) - ;; Save the active file. - (nnmail-save-active nnbabyl-group-alist nnbabyl-active-file) - t) - -(deffoo nnbabyl-request-rename-group (group new-name &optional server) - (nnbabyl-possibly-change-newsgroup group server) - (save-excursion - (set-buffer nnbabyl-mbox-buffer) - (goto-char (point-min)) - (let ((ident (concat "\nX-Gnus-Newsgroup: " nnbabyl-current-group ":")) - (new-ident (concat "\nX-Gnus-Newsgroup: " new-name ":")) - found) - (while (search-forward ident nil t) - (replace-match new-ident t t) - (setq found t)) - (when found - (save-buffer)))) - (let ((entry (assoc group nnbabyl-group-alist))) - (and entry (setcar entry new-name)) - (setq nnbabyl-current-group nil) - ;; Save the new group alist. - (nnmail-save-active nnbabyl-group-alist nnbabyl-active-file) - t)) - - -;;; Internal functions. - -;; If FORCE, delete article no matter how many X-Gnus-Newsgroup -;; headers there are. If LEAVE-DELIM, don't delete the Unix mbox -;; delimiter line. -(defun nnbabyl-delete-mail (&optional force leave-delim) - ;; Delete the current X-Gnus-Newsgroup line. - (unless force - (delete-region - (progn (beginning-of-line) (point)) - (progn (forward-line 1) (point)))) - ;; Beginning of the article. - (save-excursion - (save-restriction - (widen) - (narrow-to-region - (save-excursion - (unless (re-search-backward (concat "^" nnbabyl-mail-delimiter) nil t) - (goto-char (point-min)) - (end-of-line)) - (if leave-delim (progn (forward-line 1) (point)) - (match-beginning 0))) - (progn - (forward-line 1) - (or (and (re-search-forward (concat "^" nnbabyl-mail-delimiter) - nil t) - (match-beginning 0)) - (point-max)))) - (goto-char (point-min)) - ;; Only delete the article if no other groups owns it as well. - (when (or force (not (re-search-forward "^X-Gnus-Newsgroup: " nil t))) - (delete-region (point-min) (point-max)))))) - -(defun nnbabyl-possibly-change-newsgroup (newsgroup &optional server) - (when (and server - (not (nnbabyl-server-opened server))) - (nnbabyl-open-server server)) - (when (or (not nnbabyl-mbox-buffer) - (not (buffer-name nnbabyl-mbox-buffer))) - (save-excursion (nnbabyl-read-mbox))) - (unless nnbabyl-group-alist - (nnmail-activate 'nnbabyl)) - (if newsgroup - (if (assoc newsgroup nnbabyl-group-alist) - (setq nnbabyl-current-group newsgroup) - (nnheader-report 'nnbabyl "No such group in file")) - t)) - -(defun nnbabyl-article-string (article) - (if (numberp article) - (concat "\nX-Gnus-Newsgroup: " nnbabyl-current-group ":" - (int-to-string article) " ") - (concat "\nMessage-ID: " article))) - -(defun nnbabyl-article-group-number () - (save-excursion - (goto-char (point-min)) - (when (re-search-forward "^X-Gnus-Newsgroup: +\\([^:]+\\):\\([0-9]+\\) " - nil t) - (cons (buffer-substring (match-beginning 1) (match-end 1)) - (string-to-int - (buffer-substring (match-beginning 2) (match-end 2))))))) - -(defun nnbabyl-insert-lines () - "Insert how many lines and chars there are in the body of the mail." - (let (lines chars) - (save-excursion - (goto-char (point-min)) - (when (search-forward "\n\n" nil t) - ;; There may be an EOOH line here... - (when (looking-at "\\*\\*\\* EOOH \\*\\*\\*") - (search-forward "\n\n" nil t)) - (setq chars (- (point-max) (point)) - lines (max (- (count-lines (point) (point-max)) 1) 0)) - ;; Move back to the end of the headers. - (goto-char (point-min)) - (search-forward "\n\n" nil t) - (forward-char -1) - (save-excursion - (when (re-search-backward "^Lines: " nil t) - (delete-region (point) (progn (forward-line 1) (point))))) - (insert (format "Lines: %d\n" lines)) - chars)))) - -(defun nnbabyl-save-mail (group-art) - ;; Called narrowed to an article. - (nnbabyl-insert-lines) - (nnmail-insert-xref group-art) - (nnbabyl-insert-newsgroup-line group-art) - (run-hooks 'nnbabyl-prepare-save-mail-hook) - group-art) - -(defun nnbabyl-insert-newsgroup-line (group-art) - (save-excursion - (goto-char (point-min)) - (while (looking-at "From ") - (replace-match "Mail-from: From " t t) - (forward-line 1)) - ;; If there is a C-l at the beginning of the narrowed region, this - ;; isn't really a "save", but rather a "scan". - (goto-char (point-min)) - (unless (looking-at "\^L") - (save-excursion - (insert "\^L\n0, unseen,,\n*** EOOH ***\n") - (goto-char (point-max)) - (insert "\^_\n"))) - (when (search-forward "\n\n" nil t) - (forward-char -1) - (while group-art - (insert (format "X-Gnus-Newsgroup: %s:%d %s\n" - (caar group-art) (cdar group-art) - (current-time-string))) - (setq group-art (cdr group-art)))) - t)) - -(defun nnbabyl-active-number (group) - ;; Find the next article number in GROUP. - (let ((active (cadr (assoc group nnbabyl-group-alist)))) - (if active - (setcdr active (1+ (cdr active))) - ;; This group is new, so we create a new entry for it. - ;; This might be a bit naughty... creating groups on the drop of - ;; a hat, but I don't know... - (push (list group (setq active (cons 1 1))) - nnbabyl-group-alist)) - (cdr active))) - -(defun nnbabyl-create-mbox () - (unless (file-exists-p nnbabyl-mbox-file) - ;; Create a new, empty RMAIL mbox file. - (save-excursion - (set-buffer (setq nnbabyl-mbox-buffer - (create-file-buffer nnbabyl-mbox-file))) - (setq buffer-file-name nnbabyl-mbox-file) - (insert "BABYL OPTIONS:\n\n\^_") - (nnmail-write-region - (point-min) (point-max) nnbabyl-mbox-file t 'nomesg)))) - -(defun nnbabyl-read-mbox () - (nnmail-activate 'nnbabyl) - (nnbabyl-create-mbox) - - (unless (and nnbabyl-mbox-buffer - (buffer-name nnbabyl-mbox-buffer) - (save-excursion - (set-buffer nnbabyl-mbox-buffer) - (= (buffer-size) (nnheader-file-size nnbabyl-mbox-file)))) - ;; This buffer has changed since we read it last. Possibly. - (save-excursion - (let ((delim (concat "^" nnbabyl-mail-delimiter)) - (alist nnbabyl-group-alist) - start end number) - (set-buffer (setq nnbabyl-mbox-buffer - (nnheader-find-file-noselect - nnbabyl-mbox-file nil 'raw))) - ;; Save previous buffer mode. - (setq nnbabyl-previous-buffer-mode - (cons (cons (point-min) (point-max)) - major-mode)) - - (buffer-disable-undo (current-buffer)) - (widen) - (setq buffer-read-only nil) - (fundamental-mode) - - ;; Go through the group alist and compare against - ;; the rmail file. - (while alist - (goto-char (point-max)) - (when (and (re-search-backward - (format "^X-Gnus-Newsgroup: %s:\\([0-9]+\\) " - (caar alist)) - nil t) - (> (setq number - (string-to-number - (buffer-substring - (match-beginning 1) (match-end 1)))) - (cdadar alist))) - (setcdr (cadar alist) number)) - (setq alist (cdr alist))) - - ;; We go through the mbox and make sure that each and - ;; every mail belongs to some group or other. - (goto-char (point-min)) - (if (looking-at "\^L") - (setq start (point)) - (re-search-forward delim nil t) - (setq start (match-end 0))) - (while (re-search-forward delim nil t) - (setq end (match-end 0)) - (unless (search-backward "\nX-Gnus-Newsgroup: " start t) - (goto-char end) - (save-excursion - (save-restriction - (narrow-to-region (goto-char start) end) - (nnbabyl-save-mail - (nnmail-article-group 'nnbabyl-active-number)) - (setq end (point-max))))) - (goto-char (setq start end))) - (when (buffer-modified-p (current-buffer)) - (save-buffer)) - (nnmail-save-active nnbabyl-group-alist nnbabyl-active-file))))) - -(defun nnbabyl-remove-incoming-delims () - (goto-char (point-min)) - (while (search-forward "\^_" nil t) - (replace-match "?" t t))) - -(defun nnbabyl-check-mbox () - "Go through the nnbabyl mbox and make sure that no article numbers are reused." - (interactive) - (let ((idents (make-vector 1000 0)) - id) - (save-excursion - (when (or (not nnbabyl-mbox-buffer) - (not (buffer-name nnbabyl-mbox-buffer))) - (nnbabyl-read-mbox)) - (set-buffer nnbabyl-mbox-buffer) - (goto-char (point-min)) - (while (re-search-forward "^X-Gnus-Newsgroup: \\([^ ]+\\) " nil t) - (if (intern-soft (setq id (match-string 1)) idents) - (progn - (delete-region (progn (beginning-of-line) (point)) - (progn (forward-line 1) (point))) - (nnheader-message 7 "Moving %s..." id) - (nnbabyl-save-mail - (nnmail-article-group 'nnbabyl-active-number))) - (intern id idents))) - (when (buffer-modified-p (current-buffer)) - (save-buffer)) - (nnmail-save-active nnbabyl-group-alist nnbabyl-active-file) - (nnheader-message 5 "")))) - -(provide 'nnbabyl) - -;;; nnbabyl.el ends here diff --git a/lisp/nndb.el b/lisp/nndb.el deleted file mode 100644 index 0a0f3ef..0000000 --- a/lisp/nndb.el +++ /dev/null @@ -1,333 +0,0 @@ -;;; nndb.el --- nndb access for Gnus -;; Copyright (C) 1997,98 Free Software Foundation, Inc. - -;; Author: Masanobu UMEDA -;; Kai Grossjohann -;; Joe Hildebrand -;; David Blacka -;; Keywords: news - -;; This file is NOT part of GNU Emacs. - -;; GNU Emacs is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 2, or (at your option) -;; any later version. - -;; GNU Emacs is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs; see the file COPYING. If not, write to the -;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. - -;;; Commentary: - -;;; This was based upon Kai Grossjohan's shamessly snarfed code and -;;; further modified by Joe Hildebrand. It has been updated for Red -;;; Gnus. - -;; TODO: -;; -;; * Fix bug where server connection can be lost and impossible to regain -;; This hasn't happened to me in a while; think it was fixed in Rgnus -;; -;; * make it handle different nndb servers seemlessly -;; -;; * Optimize expire if FORCE -;; -;; * Optimize move (only expire once) -;; -;; * Deal with add/deletion of groups -;; -;; * make the backend TOUCH an article when marked as expireable (will -;; make article expire 'expiry' days after that moment). - -;;- -;; Register nndb with known select methods. - -(gnus-declare-backend "nndb" 'mail 'respool 'address 'prompt-address) - -;;; Code: - -(require 'nnmail) -(require 'nnheader) -(require 'nntp) -(eval-when-compile (require 'cl)) - -(eval-and-compile - (unless (fboundp 'open-network-stream) - (require 'tcp))) - -(eval-when-compile (require 'cl)) - -(eval-and-compile - (autoload 'news-setup "rnewspost") - (autoload 'news-reply-mode "rnewspost") - (autoload 'cancel-timer "timer") - (autoload 'telnet "telnet" nil t) - (autoload 'telnet-send-input "telnet" nil t) - (autoload 'timezone-parse-date "timezone") - (autoload 'gnus-declare-backend "gnus-start")) - -;; Declare nndb as derived from nntp - -(nnoo-declare nndb nntp) - -;; Variables specific to nndb - -;;- currently not used but just in case... -(defvoo nndb-deliver-program "nndel" - "*The program used to put a message in an NNDB group.") - -(defvoo nndb-server-side-expiry nil - "If t, expiry calculation will occur on the server side") - -(defvoo nndb-set-expire-date-on-mark nil - "If t, the expiry date for a given article will be set to the time -it was marked as expireable; otherwise the date will be the time the -article was posted to nndb") - -;; Variables copied from nntp - -(defvoo nndb-server-opened-hook '(nntp-send-authinfo-from-file) - "Like nntp-server-opened-hook." - nntp-server-opened-hook) - -(defvoo nndb-address "localhost" - "*The name of the NNDB server." - nntp-address) - -(defvoo nndb-port-number 9000 - "*Port number to connect to." - nntp-port-number) - -;; change to 'news if you are actually using nndb for news -(defvoo nndb-article-type 'mail) - -(defvoo nndb-status-string nil "" nntp-status-string) - - - -(defconst nndb-version "nndb 0.7" - "Version numbers of this version of NNDB.") - - -;;; Interface functions. - -(nnoo-define-basics nndb) - -;;------------------------------------------------------------------ - -;; this function turns the lisp list into a string list. There is -;; probably a more efficient way to do this. -(defun nndb-build-article-string (articles) - (let (art-string art) - (while articles - (setq art (pop articles)) - (setq art-string (concat art-string art " "))) - art-string)) - -(defun nndb-build-expire-rest-list (total expire) - (let (art rest) - (while total - (setq art (pop total)) - (if (memq art expire) - () - (push art rest))) - rest)) - - -;; -(deffoo nndb-request-type (group &optional article) - nndb-article-type) - -;; nndb-request-update-info does not exist and is not needed - -;; nndb-request-update-mark does not exist; it should be used to TOUCH -;; articles as they are marked exipirable -(defun nndb-touch-article (group article) - (nntp-send-command nil "X-TOUCH" article)) - -(deffoo nndb-request-update-mark - (group article mark) - "Sets the expiry date for ARTICLE in GROUP to now, if the mark is 'E'" - (if (and nndb-set-expire-date-on-mark (string-equal mark "E")) - (nndb-touch-article group article)) - mark) - -;; nndb-request-create-group -- currently this isn't necessary; nndb -;; creates groups on demand. - -;; todo -- use some other time than the creation time of the article -;; best is time since article has been marked as expirable - -(defun nndb-request-expire-articles-local - (articles &optional group server force) - "Let gnus do the date check and issue the delete commands." - (let (msg art delete-list (num-delete 0) rest) - (nntp-possibly-change-group group server) - (while articles - (setq art (pop articles)) - (nntp-send-command "^\\([23]\\|^423\\).*\n" "X-DATE" art) - (setq msg (nndb-status-message)) - (if (string-match "^423" msg) - () - (or (string-match "'\\(.+\\)'" msg) - (error "Not a valid response for X-DATE command: %s" - msg)) - (if (nnmail-expired-article-p - group - (gnus-encode-date - (substring msg (match-beginning 1) (match-end 1))) - force) - (progn - (setq delete-list (concat delete-list " " (int-to-string art))) - (setq num-delete (1+ num-delete))) - (push art rest)))) - (if (> (length delete-list) 0) - (progn - (nnheader-message 5 "Deleting %s article(s) from %s" - (int-to-string num-delete) group) - (nntp-send-command "^[23].*\n" "X-DELETE" delete-list)) - ) - - (nnheader-message 5 "") - (nconc rest articles))) - -(defun nndb-get-remote-expire-response () - (let (list) - (set-buffer nntp-server-buffer) - (goto-char (point-min)) - (if (looking-at "^[34]") - ;; x-expire returned error--presume no articles were expirable) - (setq list nil) - ;; otherwise, pull all of the following numbers into the list - (re-search-forward "follows\r?\n?" nil t) - (while (re-search-forward "^[0-9]+$" nil t) - (push (string-to-int (match-string 0)) list))) - list)) - -(defun nndb-request-expire-articles-remote - (articles &optional group server force) - "Let the nndb backend expire articles" - (let (days art-string delete-list (num-delete 0)) - (nntp-possibly-change-group group server) - - ;; first calculate the wait period in days - (setq days (or (and nnmail-expiry-wait-function - (funcall nnmail-expiry-wait-function group)) - nnmail-expiry-wait)) - ;; now handle the special cases - (cond (force - (setq days 0)) - ((eq days 'never) - ;; This isn't an expirable group. - (setq days -1)) - ((eq days 'immediate) - (setq days 0))) - - - ;; build article string - (setq art-string (concat days " " (nndb-build-article-string articles))) - (nntp-send-command "^\.\r?\n\\|^[345].*\n" "X-EXPIRE" art-string) - - (setq delete-list (nndb-get-remote-expire-response)) - (setq num-delete (length delete-list)) - (if (> num-delete 0) - (nnheader-message 5 "Deleting %s article(s) from %s" - (int-to-string num-delete) group)) - - (nndb-build-expire-rest-list articles delete-list))) - -(deffoo nndb-request-expire-articles - (articles &optional group server force) - "Expires ARTICLES from GROUP on SERVER. -If FORCE, delete regardless of exiration date, otherwise use normal -expiry mechanism." - (if nndb-server-side-expiry - (nndb-request-expire-articles-remote articles group server force) - (nndb-request-expire-articles-local articles group server force))) - -(deffoo nndb-request-move-article - (article group server accept-form &optional last) - "Move ARTICLE (a number) from GROUP on SERVER. -Evals ACCEPT-FORM in current buffer, where the article is. -Optional LAST is ignored." - ;; we guess that the second arg in accept-form is the new group, - ;; which it will be for nndb, which is all that matters anyway - (let ((new-group (nth 1 accept-form)) result) - (nntp-possibly-change-group group server) - - ;; use the move command for nndb-to-nndb moves - (if (string-match "^nndb" new-group) - (let ((new-group-name (gnus-group-real-name new-group))) - (nntp-send-command "^[23].*\n" "X-MOVE" article new-group-name) - (cons new-group article)) - ;; else move normally - (let ((artbuf (get-buffer-create " *nndb move*"))) - (and - (nndb-request-article article group server artbuf) - (save-excursion - (set-buffer artbuf) - (insert-buffer-substring nntp-server-buffer) - (setq result (eval accept-form)) - (kill-buffer (current-buffer)) - result) - (nndb-request-expire-articles (list article) - group - server - t)) - result) - ))) - -(deffoo nndb-request-accept-article (group server &optional last) - "The article in the current buffer is put into GROUP." - (nntp-possibly-change-group group server) - (let (art msg) - (when (nntp-send-command "^[23].*\r?\n" "ACCEPT" group) - (nnheader-insert "") - (nntp-send-buffer "^[23].*\n")) - - (set-buffer nntp-server-buffer) - (setq msg (buffer-string (point-min) (point-max))) - (or (string-match "^\\([0-9]+\\)" msg) - (error "nndb: %s" msg)) - (setq art (substring msg (match-beginning 1) (match-end 1))) - (nnheader-message 5 "nndb: accepted %s" art) - (list art))) - -(deffoo nndb-request-replace-article (article group buffer) - "ARTICLE is the number of the article in GROUP to be replaced -with the contents of the BUFFER." - (set-buffer buffer) - (when (nntp-send-command "^[23].*\r?\n" "X-REPLACE" (int-to-string article)) - (nnheader-insert "") - (nntp-send-buffer "^[23.*\n") - (list (int-to-string article)))) - -; nndb-request-delete-group does not exist -; todo -- maybe later - -; nndb-request-rename-group does not exist -; todo -- maybe later - -;; -- standard compatability functions - -(deffoo nndb-status-message (&optional server) - "Return server status as a string." - (set-buffer nntp-server-buffer) - (buffer-string (point-min) (point-max))) - -;; Import stuff from nntp - -(nnoo-import nndb - (nntp)) - -(provide 'nndb) - - - diff --git a/lisp/nndir.el b/lisp/nndir.el deleted file mode 100644 index a3b5eae..0000000 --- a/lisp/nndir.el +++ /dev/null @@ -1,99 +0,0 @@ -;;; nndir.el --- single directory newsgroup access for Gnus -;; Copyright (C) 1995,96,97,98 Free Software Foundation, Inc. - -;; Author: Lars Magne Ingebrigtsen -;; Keywords: news - -;; This file is part of GNU Emacs. - -;; GNU Emacs is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 2, or (at your option) -;; any later version. - -;; GNU Emacs is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs; see the file COPYING. If not, write to the -;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. - -;;; Commentary: - -;;; Code: - -(require 'nnheader) -(require 'nnmh) -(require 'nnml) -(require 'nnoo) -(eval-when-compile (require 'cl)) - -(nnoo-declare nndir - nnml nnmh) - -(defvoo nndir-directory nil - "Where nndir will look for groups." - nnml-current-directory nnmh-current-directory) - -(defvoo nndir-nov-is-evil nil - "*Non-nil means that nndir will never retrieve NOV headers." - nnml-nov-is-evil) - - - -(defvoo nndir-current-group "" nil nnml-current-group nnmh-current-group) -(defvoo nndir-top-directory nil nil nnml-directory nnmh-directory) -(defvoo nndir-get-new-mail nil nil nnml-get-new-mail nnmh-get-new-mail) - -(defvoo nndir-status-string "" nil nnmh-status-string) -(defconst nndir-version "nndir 1.0") - - - -;;; Interface functions. - -(nnoo-define-basics nndir) - -(deffoo nndir-open-server (server &optional defs) - (setq nndir-directory - (or (cadr (assq 'nndir-directory defs)) - server)) - (unless (assq 'nndir-directory defs) - (push `(nndir-directory ,server) defs)) - (push `(nndir-current-group - ,(file-name-nondirectory (directory-file-name nndir-directory))) - defs) - (push `(nndir-top-directory - ,(file-name-directory (directory-file-name nndir-directory))) - defs) - (nnoo-change-server 'nndir server defs) - (let (err) - (cond - ((not (condition-case arg - (file-exists-p nndir-directory) - (ftp-error (setq err (format "%s" arg))))) - (nndir-close-server) - (nnheader-report - 'nndir (or err "No such file or directory: %s" nndir-directory))) - ((not (file-directory-p (file-truename nndir-directory))) - (nndir-close-server) - (nnheader-report 'nndir "Not a directory: %s" nndir-directory)) - (t - (nnheader-report 'nndir "Opened server %s using directory %s" - server nndir-directory) - t)))) - -(nnoo-map-functions nndir - (nnml-retrieve-headers 0 nndir-current-group 0 0) - (nnml-request-article 0 nndir-current-group 0 0) - (nnmh-request-group nndir-current-group 0 0) - (nnml-close-group nndir-current-group 0) - (nnml-request-list (nnoo-current-server 'nndir) nndir-directory) - (nnml-request-newsgroups (nnoo-current-server 'nndir) nndir-directory)) - -(provide 'nndir) - -;;; nndir.el ends here diff --git a/lisp/nndoc.el b/lisp/nndoc.el deleted file mode 100644 index 0da245a..0000000 --- a/lisp/nndoc.el +++ /dev/null @@ -1,783 +0,0 @@ -;;; nndoc.el --- single file access for Gnus -;; Copyright (C) 1995,96,97,98 Free Software Foundation, Inc. - -;; Author: Lars Magne Ingebrigtsen -;; Masanobu UMEDA -;; Keywords: news - -;; This file is part of GNU Emacs. - -;; GNU Emacs is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 2, or (at your option) -;; any later version. - -;; GNU Emacs is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs; see the file COPYING. If not, write to the -;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. - -;;; Commentary: - -;;; Code: - -(require 'nnheader) -(require 'message) -(require 'nnmail) -(require 'nnoo) -(require 'gnus-util) -(eval-when-compile (require 'cl)) - -(nnoo-declare nndoc) - -(defvoo nndoc-article-type 'guess - "*Type of the file. -One of `mbox', `babyl', `digest', `news', `rnews', `mmdf', `forward', -`rfc934', `rfc822-forward', `mime-digest', `mime-parts', `standard-digest', -`slack-digest', `clari-briefs' or `guess'.") - -(defvoo nndoc-post-type 'mail - "*Whether the nndoc group is `mail' or `post'.") - -(defvoo nndoc-open-document-hook 'nnheader-ms-strip-cr - "Hook run after opening a document. -The default function removes all trailing carriage returns -from the document.") - -(defvar nndoc-type-alist - `((mmdf - (article-begin . "^\^A\^A\^A\^A\n") - (body-end . "^\^A\^A\^A\^A\n")) - (news - (article-begin . "^Path:")) - (rnews - (article-begin . "^#! *rnews +\\([0-9]+\\) *\n") - (body-end-function . nndoc-rnews-body-end)) - (mbox - (article-begin-function . nndoc-mbox-article-begin) - (body-end-function . nndoc-mbox-body-end)) - (babyl - (article-begin . "\^_\^L *\n") - (body-end . "\^_") - (body-begin-function . nndoc-babyl-body-begin) - (head-begin-function . nndoc-babyl-head-begin)) - (forward - (article-begin . "^-+ Start of forwarded message -+\n+") - (body-end . "^-+ End of forwarded message -+$") - (prepare-body-function . nndoc-unquote-dashes)) - (rfc934 - (article-begin . "^--.*\n+") - (body-end . "^--.*$") - (prepare-body-function . nndoc-unquote-dashes)) - (clari-briefs - (article-begin . "^ \\*") - (body-end . "^\t------*[ \t]^*\n^ \\*") - (body-begin . "^\t") - (head-end . "^\t") - (generate-head-function . nndoc-generate-clari-briefs-head) - (article-transform-function . nndoc-transform-clari-briefs)) - (mime-digest - (article-begin . "") - (head-end . "^ ?$") - (body-end . "") - (file-end . "") - (subtype digest guess)) - (mime-parts - (generate-head-function . nndoc-generate-mime-parts-head) - (article-transform-function . nndoc-transform-mime-parts)) - (standard-digest - (first-article . ,(concat "^" (make-string 70 ?-) "\n *\n+")) - (article-begin . ,(concat "^\n" (make-string 30 ?-) "\n *\n+")) - (prepare-body-function . nndoc-unquote-dashes) - (body-end-function . nndoc-digest-body-end) - (head-end . "^ *$") - (body-begin . "^ *\n") - (file-end . "^End of .*digest.*[0-9].*\n\\*\\*\\|^End of.*Digest *$") - (subtype digest guess)) - (slack-digest - (article-begin . "^------------------------------*[\n \t]+") - (head-end . "^ ?$") - (body-end-function . nndoc-digest-body-end) - (body-begin . "^ ?$") - (file-end . "^End of") - (prepare-body-function . nndoc-unquote-dashes) - (subtype digest guess)) - (lanl-gov-announce - (article-begin . "^\\\\\\\\\n") - (head-begin . "^Paper.*:") - (head-end . "\\(^\\\\\\\\.*\n\\|-----------------\\)") - (body-begin . "") - (body-end . "-------------------------------------------------") - (file-end . "^Title: Recent Seminal") - (generate-head-function . nndoc-generate-lanl-gov-head) - (article-transform-function . nndoc-transform-lanl-gov-announce) - (subtype preprints guess)) - (rfc822-forward - (article-begin . "^\n") - (body-end-function . nndoc-rfc822-forward-body-end-function)) - (guess - (guess . t) - (subtype nil)) - (digest - (guess . t) - (subtype nil)) - (preprints - (guess . t) - (subtype nil)))) - - -(defvoo nndoc-file-begin nil) -(defvoo nndoc-first-article nil) -(defvoo nndoc-article-begin nil) -(defvoo nndoc-head-begin nil) -(defvoo nndoc-head-end nil) -(defvoo nndoc-file-end nil) -(defvoo nndoc-body-begin nil) -(defvoo nndoc-body-end-function nil) -(defvoo nndoc-body-begin-function nil) -(defvoo nndoc-head-begin-function nil) -(defvoo nndoc-body-end nil) -;; nndoc-dissection-alist is a list of sublists. Each sublist holds the -;; following items. ARTICLE is an ordinal starting at 1. HEAD-BEGIN, -;; HEAD-END, BODY-BEGIN and BODY-END are positions in the `nndoc' buffer. -;; LINE-COUNT is a count of lines in the body. SUBJECT, MESSAGE-ID and -;; REFERENCES, only present for MIME dissections, are field values. -(defvoo nndoc-dissection-alist nil) -(defvoo nndoc-prepare-body-function nil) -(defvoo nndoc-generate-head-function nil) -(defvoo nndoc-article-transform-function nil) -(defvoo nndoc-article-begin-function nil) - -(defvoo nndoc-status-string "") -(defvoo nndoc-group-alist nil) -(defvoo nndoc-current-buffer nil - "Current nndoc news buffer.") -(defvoo nndoc-address nil) -(defvoo nndoc-mime-header nil) -(defvoo nndoc-mime-subject nil) - -(defconst nndoc-version "nndoc 1.0" - "nndoc version.") - - - -;;; Interface functions - -(nnoo-define-basics nndoc) - -(deffoo nndoc-retrieve-headers (articles &optional newsgroup server fetch-old) - (when (nndoc-possibly-change-buffer newsgroup server) - (save-excursion - (set-buffer nntp-server-buffer) - (erase-buffer) - (let (article entry) - (if (stringp (car articles)) - 'headers - (while articles - (when (setq entry (cdr (assq (setq article (pop articles)) - nndoc-dissection-alist))) - (insert (format "221 %d Article retrieved.\n" article)) - (if nndoc-generate-head-function - (funcall nndoc-generate-head-function article) - (insert-buffer-substring - nndoc-current-buffer (car entry) (nth 1 entry))) - (goto-char (point-max)) - (unless (= (char-after (1- (point))) ?\n) - (insert "\n")) - (insert (format "Lines: %d\n" (nth 4 entry))) - (insert ".\n"))) - - (nnheader-fold-continuation-lines) - 'headers))))) - -(deffoo nndoc-request-article (article &optional newsgroup server buffer) - (nndoc-possibly-change-buffer newsgroup server) - (save-excursion - (let ((buffer (or buffer nntp-server-buffer)) - (entry (cdr (assq article nndoc-dissection-alist))) - beg) - (set-buffer buffer) - (erase-buffer) - (when entry - (if (stringp article) - nil - (insert-buffer-substring - nndoc-current-buffer (car entry) (nth 1 entry)) - (insert "\n") - (setq beg (point)) - (insert-buffer-substring - nndoc-current-buffer (nth 2 entry) (nth 3 entry)) - (goto-char beg) - (when nndoc-prepare-body-function - (funcall nndoc-prepare-body-function)) - (when nndoc-article-transform-function - (funcall nndoc-article-transform-function article)) - t))))) - -(deffoo nndoc-request-group (group &optional server dont-check) - "Select news GROUP." - (let (number) - (cond - ((not (nndoc-possibly-change-buffer group server)) - (nnheader-report 'nndoc "No such file or buffer: %s" - nndoc-address)) - (dont-check - (nnheader-report 'nndoc "Selected group %s" group) - t) - ((zerop (setq number (length nndoc-dissection-alist))) - (nndoc-close-group group) - (nnheader-report 'nndoc "No articles in group %s" group)) - (t - (nnheader-insert "211 %d %d %d %s\n" number 1 number group))))) - -(deffoo nndoc-request-type (group &optional article) - (cond ((not article) 'unknown) - (nndoc-post-type nndoc-post-type) - (t 'unknown))) - -(deffoo nndoc-close-group (group &optional server) - (nndoc-possibly-change-buffer group server) - (and nndoc-current-buffer - (buffer-name nndoc-current-buffer) - (kill-buffer nndoc-current-buffer)) - (setq nndoc-group-alist (delq (assoc group nndoc-group-alist) - nndoc-group-alist)) - (setq nndoc-current-buffer nil) - (nnoo-close-server 'nndoc server) - (setq nndoc-dissection-alist nil) - t) - -(deffoo nndoc-request-list (&optional server) - nil) - -(deffoo nndoc-request-newgroups (date &optional server) - nil) - -(deffoo nndoc-request-list-newsgroups (&optional server) - nil) - - -;;; Internal functions. - -(defun nndoc-possibly-change-buffer (group source) - (let (buf) - (cond - ;; The current buffer is this group's buffer. - ((and nndoc-current-buffer - (buffer-name nndoc-current-buffer) - (eq nndoc-current-buffer - (setq buf (cdr (assoc group nndoc-group-alist)))))) - ;; We change buffers by taking an old from the group alist. - ;; `source' is either a string (a file name) or a buffer object. - (buf - (setq nndoc-current-buffer buf)) - ;; It's a totally new group. - ((or (and (bufferp nndoc-address) - (buffer-name nndoc-address)) - (and (stringp nndoc-address) - (file-exists-p nndoc-address) - (not (file-directory-p nndoc-address)))) - (push (cons group (setq nndoc-current-buffer - (get-buffer-create - (concat " *nndoc " group "*")))) - nndoc-group-alist) - (setq nndoc-dissection-alist nil) - (save-excursion - (set-buffer nndoc-current-buffer) - (buffer-disable-undo (current-buffer)) - (erase-buffer) - (if (stringp nndoc-address) - (nnheader-insert-file-contents nndoc-address) - (insert-buffer-substring nndoc-address)) - (run-hooks 'nndoc-open-document-hook)))) - ;; Initialize the nndoc structures according to this new document. - (when (and nndoc-current-buffer - (not nndoc-dissection-alist)) - (save-excursion - (set-buffer nndoc-current-buffer) - (nndoc-set-delims) - (if (eq nndoc-article-type 'mime-parts) - (nndoc-dissect-mime-parts) - (nndoc-dissect-buffer)))) - (unless nndoc-current-buffer - (nndoc-close-server)) - ;; Return whether we managed to select a file. - nndoc-current-buffer)) - -;;; -;;; Deciding what document type we have -;;; - -(defun nndoc-set-delims () - "Set the nndoc delimiter variables according to the type of the document." - (let ((vars '(nndoc-file-begin - nndoc-first-article - nndoc-article-begin-function - nndoc-head-begin nndoc-head-end - nndoc-file-end nndoc-article-begin - nndoc-body-begin nndoc-body-end-function nndoc-body-end - nndoc-prepare-body-function nndoc-article-transform-function - nndoc-generate-head-function nndoc-body-begin-function - nndoc-head-begin-function))) - (while vars - (set (pop vars) nil))) - (let (defs) - ;; Guess away until we find the real file type. - (while (assq 'guess (setq defs (cdr (assq nndoc-article-type - nndoc-type-alist)))) - (setq nndoc-article-type (nndoc-guess-type nndoc-article-type))) - ;; Set the nndoc variables. - (while defs - (set (intern (format "nndoc-%s" (caar defs))) - (cdr (pop defs)))))) - -(defun nndoc-guess-type (subtype) - (let ((alist nndoc-type-alist) - results result entry) - (while (and (not result) - (setq entry (pop alist))) - (when (memq subtype (or (cdr (assq 'subtype entry)) '(guess))) - (goto-char (point-min)) - (when (numberp (setq result (funcall (intern - (format "nndoc-%s-type-p" - (car entry)))))) - (push (cons result entry) results) - (setq result nil)))) - (unless (or result results) - (error "Document is not of any recognized type")) - (if result - (car entry) - (cadar (sort results 'car-less-than-car))))) - -;;; -;;; Built-in type predicates and functions -;;; - -(defun nndoc-mbox-type-p () - (when (looking-at message-unix-mail-delimiter) - t)) - -(defun nndoc-mbox-article-begin () - (when (re-search-forward (concat "^" message-unix-mail-delimiter) nil t) - (goto-char (match-beginning 0)))) - -(defun nndoc-mbox-body-end () - (let ((beg (point)) - len end) - (when - (save-excursion - (and (re-search-backward - (concat "^" message-unix-mail-delimiter) nil t) - (setq end (point)) - (search-forward "\n\n" beg t) - (re-search-backward - "^Content-Length:[ \t]*\\([0-9]+\\) *$" end t) - (setq len (string-to-int (match-string 1))) - (search-forward "\n\n" beg t) - (unless (= (setq len (+ (point) len)) (point-max)) - (and (< len (point-max)) - (goto-char len) - (looking-at message-unix-mail-delimiter))))) - (goto-char len)))) - -(defun nndoc-mmdf-type-p () - (when (looking-at "\^A\^A\^A\^A$") - t)) - -(defun nndoc-news-type-p () - (when (looking-at "^Path:.*\n") - t)) - -(defun nndoc-rnews-type-p () - (when (looking-at "#! *rnews") - t)) - -(defun nndoc-rnews-body-end () - (and (re-search-backward nndoc-article-begin nil t) - (forward-line 1) - (goto-char (+ (point) (string-to-int (match-string 1)))))) - -(defun nndoc-babyl-type-p () - (when (re-search-forward "\^_\^L *\n" nil t) - t)) - -(defun nndoc-babyl-body-begin () - (re-search-forward "^\n" nil t) - (when (looking-at "\\*\\*\\* EOOH \\*\\*\\*") - (let ((next (or (save-excursion - (re-search-forward nndoc-article-begin nil t)) - (point-max)))) - (unless (re-search-forward "^\n" next t) - (goto-char next) - (forward-line -1) - (insert "\n") - (forward-line -1))))) - -(defun nndoc-babyl-head-begin () - (when (re-search-forward "^[0-9].*\n" nil t) - (when (looking-at "\\*\\*\\* EOOH \\*\\*\\*") - (forward-line 1)) - t)) - -(defun nndoc-forward-type-p () - (when (and (re-search-forward "^-+ Start of forwarded message -+\n+" nil t) - (not (re-search-forward "^Subject:.*digest" nil t)) - (not (re-search-backward "^From:" nil t 2)) - (not (re-search-forward "^From:" nil t 2))) - t)) - -(defun nndoc-rfc934-type-p () - (when (and (re-search-forward "^-+ Start of forwarded.*\n+" nil t) - (not (re-search-forward "^Subject:.*digest" nil t)) - (not (re-search-backward "^From:" nil t 2)) - (not (re-search-forward "^From:" nil t 2))) - t)) - -(defun nndoc-rfc822-forward-type-p () - (save-restriction - (message-narrow-to-head) - (when (re-search-forward "^Content-Type: *message/rfc822" nil t) - t))) - -(defun nndoc-rfc822-forward-body-end-function () - (goto-char (point-max))) - -(defun nndoc-mime-parts-type-p () - (let ((case-fold-search t) - (limit (search-forward "\n\n" nil t))) - (goto-char (point-min)) - (when (and limit - (re-search-forward - (concat "\ -^Content-Type:[ \t]*multipart/[a-z]+;\\(.*;\\)*" - "[ \t\n]*[ \t]boundary=\"?[^\"\n]*[^\" \t\n]") - limit t)) - t))) - -(defun nndoc-transform-mime-parts (article) - (unless (= article 1) - ;; Ensure some MIME-Version. - (goto-char (point-min)) - (search-forward "\n\n") - (let ((case-fold-search nil) - (limit (point))) - (goto-char (point-min)) - (or (save-excursion (re-search-forward "^MIME-Version:" limit t)) - (insert "Mime-Version: 1.0\n"))) - ;; Generate default header before entity fields. - (goto-char (point-min)) - (nndoc-generate-mime-parts-head article t))) - -(defun nndoc-generate-mime-parts-head (article &optional body-present) - (let ((entry (cdr (assq (if body-present 1 article) nndoc-dissection-alist)))) - (let ((subject (if body-present - nndoc-mime-subject - (concat "<" (nth 5 entry) ">"))) - (message-id (nth 6 entry)) - (references (nth 7 entry))) - (insert nndoc-mime-header) - (and subject (insert "Subject: " subject "\n")) - (and message-id (insert "Message-ID: " message-id "\n")) - (and references (insert "References: " references "\n"))))) - -(defun nndoc-clari-briefs-type-p () - (when (let ((case-fold-search nil)) - (re-search-forward "^\t[^a-z]+ ([^a-z]+) --" nil t)) - t)) - -(defun nndoc-transform-clari-briefs (article) - (goto-char (point-min)) - (when (looking-at " *\\*\\(.*\\)\n") - (replace-match "" t t)) - (nndoc-generate-clari-briefs-head article)) - -(defun nndoc-generate-clari-briefs-head (article) - (let ((entry (cdr (assq article nndoc-dissection-alist))) - subject from) - (save-excursion - (set-buffer nndoc-current-buffer) - (save-restriction - (narrow-to-region (car entry) (nth 3 entry)) - (goto-char (point-min)) - (when (looking-at " *\\*\\(.*\\)$") - (setq subject (match-string 1)) - (when (string-match "[ \t]+$" subject) - (setq subject (substring subject 0 (match-beginning 0))))) - (when - (let ((case-fold-search nil)) - (re-search-forward - "^\t\\([^a-z]+\\(,[^(]+\\)? ([^a-z]+)\\) --" nil t)) - (setq from (match-string 1))))) - (insert "From: " "clari@clari.net (" (or from "unknown") ")" - "\nSubject: " (or subject "(no subject)") "\n"))) - -(defun nndoc-mime-digest-type-p () - (let ((case-fold-search t) - boundary-id b-delimiter entry) - (when (and - (re-search-forward - (concat "^Content-Type: *multipart/digest;[ \t\n]*[ \t]" - "boundary=\"?\\([^\"\n]*[^\" \t\n]\\)") - nil t) - (match-beginning 1)) - (setq boundary-id (match-string 1) - b-delimiter (concat "\n--" boundary-id "[\n \t]+")) - (setq entry (assq 'mime-digest nndoc-type-alist)) - (setcdr entry - (list - (cons 'head-end "^ ?$") - (cons 'body-begin "^ ?\n") - (cons 'article-begin b-delimiter) - (cons 'body-end-function 'nndoc-digest-body-end) - (cons 'file-end (concat "\n--" boundary-id "--[ \t]*$")))) - t))) - -(defun nndoc-standard-digest-type-p () - (when (and (re-search-forward (concat "^" (make-string 70 ?-) "\n\n") nil t) - (re-search-forward - (concat "\n\n" (make-string 30 ?-) "\n\n") nil t)) - t)) - -(defun nndoc-digest-body-end () - (and (re-search-forward nndoc-article-begin nil t) - (goto-char (match-beginning 0)))) - -(defun nndoc-slack-digest-type-p () - 0) - -(defun nndoc-lanl-gov-announce-type-p () - (when (let ((case-fold-search nil)) - (re-search-forward "^\\\\\\\\\nPaper: [a-z-]+/[0-9]+" nil t)) - t)) - -(defun nndoc-transform-lanl-gov-announce (article) - (goto-char (point-max)) - (when (re-search-backward "^\\\\\\\\ +(\\([^ ]*\\) , *\\([^ ]*\\))" nil t) - (replace-match "\n\nGet it at \\1 (\\2)" t nil)) - ;; (when (re-search-backward "^\\\\\\\\$" nil t) - ;; (replace-match "" t t)) - ) - -(defun nndoc-generate-lanl-gov-head (article) - (let ((entry (cdr (assq article nndoc-dissection-alist))) - (e-mail "no address given") - subject from) - (save-excursion - (set-buffer nndoc-current-buffer) - (save-restriction - (narrow-to-region (car entry) (nth 1 entry)) - (goto-char (point-min)) - (when (looking-at "^Paper.*: \\([a-z-]+/[0-9]+\\)") - (setq subject (concat " (" (match-string 1) ")")) - (when (re-search-forward "^From: \\([^ ]+\\)" nil t) - (setq e-mail (match-string 1))) - (when (re-search-forward "^Title: \\([^\f]*\\)\nAuthors?: \\(.*\\)" - nil t) - (setq subject (concat (match-string 1) subject)) - (setq from (concat (match-string 2) " <" e-mail ">")))) - )) - (while (and from (string-match "(\[^)\]*)" from)) - (setq from (replace-match "" t t from))) - (insert "From: " (or from "unknown") - "\nSubject: " (or subject "(no subject)") "\n"))) - -(deffoo nndoc-request-accept-article (group &optional server last) - nil) - - - -;;; -;;; Functions for dissecting the documents -;;; - -(defun nndoc-search (regexp) - (prog1 - (re-search-forward regexp nil t) - (beginning-of-line))) - -(defun nndoc-dissect-buffer () - "Go through the document and partition it into heads/bodies/articles." - (let ((i 0) - (first t) - head-begin head-end body-begin body-end) - (setq nndoc-dissection-alist nil) - (save-excursion - (set-buffer nndoc-current-buffer) - (goto-char (point-min)) - ;; Find the beginning of the file. - (when nndoc-file-begin - (nndoc-search nndoc-file-begin)) - ;; Go through the file. - (while (if (and first nndoc-first-article) - (nndoc-search nndoc-first-article) - (nndoc-article-begin)) - (setq first nil) - (cond (nndoc-head-begin-function - (funcall nndoc-head-begin-function)) - (nndoc-head-begin - (nndoc-search nndoc-head-begin))) - (if (or (eobp) - (and nndoc-file-end - (looking-at nndoc-file-end))) - (goto-char (point-max)) - (setq head-begin (point)) - (nndoc-search (or nndoc-head-end "^$")) - (setq head-end (point)) - (if nndoc-body-begin-function - (funcall nndoc-body-begin-function) - (nndoc-search (or nndoc-body-begin "^\n"))) - (setq body-begin (point)) - (or (and nndoc-body-end-function - (funcall nndoc-body-end-function)) - (and nndoc-body-end - (nndoc-search nndoc-body-end)) - (nndoc-article-begin) - (progn - (goto-char (point-max)) - (when nndoc-file-end - (and (re-search-backward nndoc-file-end nil t) - (beginning-of-line))))) - (setq body-end (point)) - (push (list (incf i) head-begin head-end body-begin body-end - (count-lines body-begin body-end)) - nndoc-dissection-alist)))))) - -(defun nndoc-article-begin () - (if nndoc-article-begin-function - (funcall nndoc-article-begin-function) - (ignore-errors - (nndoc-search nndoc-article-begin)))) - -(defun nndoc-unquote-dashes () - "Unquote quoted non-separators in digests." - (while (re-search-forward "^- -"nil t) - (replace-match "-" t t))) - -;; Against compiler warnings. -(defvar nndoc-mime-split-ordinal) - -(defun nndoc-dissect-mime-parts () - "Go through a MIME composite article and partition it into sub-articles. -When a MIME entity contains sub-entities, dissection produces one article for -the header of this entity, and one article per sub-entity." - (setq nndoc-dissection-alist nil - nndoc-mime-split-ordinal 0) - (save-excursion - (set-buffer nndoc-current-buffer) - (message-narrow-to-head) - (let ((case-fold-search t) - (message-id (message-fetch-field "Message-ID")) - (references (message-fetch-field "References"))) - (setq nndoc-mime-header (buffer-substring (point-min) (point-max)) - nndoc-mime-subject (message-fetch-field "Subject")) - (while (string-match "\ -^\\(Subject\\|Message-ID\\|References\\|Lines\\|\ -MIME-Version\\|Content-Type\\|Content-Transfer-Encoding\\|\ -\\):.*\n\\([ \t].*\n\\)*" - nndoc-mime-header) - (setq nndoc-mime-header (replace-match "" t t nndoc-mime-header))) - (widen) - (nndoc-dissect-mime-parts-sub (point-min) (point-max) - nil message-id references)))) - -(defun nndoc-dissect-mime-parts-sub (begin end position message-id references) - "Dissect an entity within a composite MIME message. -The article, which corresponds to a MIME entity, extends from BEGIN to END. -The string POSITION holds a dotted decimal representation of the article -position in the hierarchical structure, it is nil for the outer entity. -The generated article should use MESSAGE-ID and REFERENCES field values." - ;; Note: `case-fold-search' is already `t' from the calling function. - (let ((head-begin begin) - (body-end end) - head-end body-begin type subtype composite comment) - (save-excursion - ;; Gracefully handle a missing body. - (goto-char head-begin) - (if (search-forward "\n\n" body-end t) - (setq head-end (1- (point)) - body-begin (point)) - (setq head-end end - body-begin end)) - ;; Save MIME attributes. - (goto-char head-begin) - (if (re-search-forward "\ -^Content-Type: *\\([^ \t\n/;]+\\)/\\([^ \t\n/;]+\\)" - head-end t) - (setq type (downcase (match-string 1)) - subtype (downcase (match-string 2))) - (setq type "text" - subtype "plain")) - (setq composite (string= type "multipart") - comment (concat position - (when (and position composite) ".") - (when composite "*") - (when (or position composite) " ") - (cond ((string= subtype "plain") type) - ((string= subtype "basic") type) - (t subtype)))) - ;; Generate dissection information for this entity. - (push (list (incf nndoc-mime-split-ordinal) - head-begin head-end body-begin body-end - (count-lines body-begin body-end) - comment message-id references) - nndoc-dissection-alist) - ;; Recurse for all sub-entities, if any. - (goto-char head-begin) - (when (re-search-forward - (concat "\ -^Content-Type: *multipart/\\([a-z]+\\);\\(.*;\\)*" - "[ \t\n]*[ \t]boundary=\"?\\([^\"\n]*[^\" \t\n]\\)") - head-end t) - (let ((boundary (concat "\n--" (match-string 3) "\\(--\\)?[ \t]*\n")) - (part-counter 0) - begin end eof-flag) - (goto-char head-end) - (setq eof-flag (not (re-search-forward boundary body-end t))) - (while (not eof-flag) - (setq begin (point)) - (cond ((re-search-forward boundary body-end t) - (or (not (match-string 1)) - (string= (match-string 1) "") - (setq eof-flag t)) - (forward-line -1) - (setq end (point)) - (forward-line 1)) - (t (setq end body-end - eof-flag t))) - (nndoc-dissect-mime-parts-sub begin end - (concat position (when position ".") - (format "%d" - (incf part-counter))) - (nnmail-message-id) - message-id))))))) - -;;;###autoload -(defun nndoc-add-type (definition &optional position) - "Add document DEFINITION to the list of nndoc document definitions. -If POSITION is nil or `last', the definition will be added -as the last checked definition, if t or `first', add as the -first definition, and if any other symbol, add after that -symbol in the alist." - ;; First remove any old instances. - (gnus-pull (car definition) nndoc-type-alist) - ;; Then enter the new definition in the proper place. - (cond - ((or (null position) (eq position 'last)) - (setq nndoc-type-alist (nconc nndoc-type-alist (list definition)))) - ((or (eq position t) (eq position 'first)) - (push definition nndoc-type-alist)) - (t - (let ((list (memq (assq position nndoc-type-alist) - nndoc-type-alist))) - (unless list - (error "No such position: %s" position)) - (setcdr list (cons definition (cdr list))))))) - -(provide 'nndoc) - -;;; nndoc.el ends here diff --git a/lisp/nndraft.el b/lisp/nndraft.el deleted file mode 100644 index c6f23c4..0000000 --- a/lisp/nndraft.el +++ /dev/null @@ -1,247 +0,0 @@ -;;; nndraft.el --- draft article access for Gnus -;; Copyright (C) 1995,96,97,98 Free Software Foundation, Inc. - -;; Author: Lars Magne Ingebrigtsen -;; Keywords: news - -;; This file is part of GNU Emacs. - -;; GNU Emacs is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 2, or (at your option) -;; any later version. - -;; GNU Emacs is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs; see the file COPYING. If not, write to the -;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. - -;;; Commentary: - -;;; Code: - -(require 'nnheader) -(require 'nnmail) -(require 'gnus-start) -(require 'nnmh) -(require 'nnoo) -(eval-when-compile - (require 'cl) - ;; This is just to shut up the byte-compiler. - (fset 'nndraft-request-group 'ignore)) - -(nnoo-declare nndraft - nnmh) - -(defvoo nndraft-directory (nnheader-concat gnus-directory "drafts/") - "Where nndraft will store its files." - nnmh-directory) - - - -(defvoo nndraft-current-group "" nil nnmh-current-group) -(defvoo nndraft-get-new-mail nil nil nnmh-get-new-mail) -(defvoo nndraft-current-directory nil nil nnmh-current-directory) - -(defconst nndraft-version "nndraft 1.0") -(defvoo nndraft-status-string "" nil nnmh-status-string) - - - -;;; Interface functions. - -(nnoo-define-basics nndraft) - -(deffoo nndraft-open-server (server &optional defs) - (nnoo-change-server 'nndraft server defs) - (cond - ((not (file-exists-p nndraft-directory)) - (nndraft-close-server) - (nnheader-report 'nndraft "No such file or directory: %s" - nndraft-directory)) - ((not (file-directory-p (file-truename nndraft-directory))) - (nndraft-close-server) - (nnheader-report 'nndraft "Not a directory: %s" nndraft-directory)) - (t - (nnheader-report 'nndraft "Opened server %s using directory %s" - server nndraft-directory) - t))) - -(deffoo nndraft-retrieve-headers (articles &optional group server fetch-old) - (nndraft-possibly-change-group group) - (save-excursion - (set-buffer nntp-server-buffer) - (erase-buffer) - (let* ((buf (get-buffer-create " *draft headers*")) - article) - (set-buffer buf) - (buffer-disable-undo (current-buffer)) - (erase-buffer) - ;; We don't support fetching by Message-ID. - (if (stringp (car articles)) - 'headers - (while articles - (set-buffer buf) - (when (nndraft-request-article - (setq article (pop articles)) group server (current-buffer)) - (goto-char (point-min)) - (if (search-forward "\n\n" nil t) - (forward-line -1) - (goto-char (point-max))) - (delete-region (point) (point-max)) - (set-buffer nntp-server-buffer) - (goto-char (point-max)) - (insert (format "221 %d Article retrieved.\n" article)) - (insert-buffer-substring buf) - (insert ".\n"))) - - (nnheader-fold-continuation-lines) - 'headers)))) - -(deffoo nndraft-request-article (id &optional group server buffer) - (nndraft-possibly-change-group group) - (when (numberp id) - ;; We get the newest file of the auto-saved file and the - ;; "real" file. - (let* ((file (nndraft-article-filename id)) - (auto (nndraft-auto-save-file-name file)) - (newest (if (file-newer-than-file-p file auto) file auto)) - (nntp-server-buffer (or buffer nntp-server-buffer))) - (when (and (file-exists-p newest) - (nnmail-find-file newest)) - (save-excursion - (set-buffer nntp-server-buffer) - (goto-char (point-min)) - ;; If there's a mail header separator in this file, - ;; we remove it. - (when (re-search-forward - (concat "^" mail-header-separator "$") nil t) - (replace-match "" t t))) - t)))) - -(deffoo nndraft-request-restore-buffer (article &optional group server) - "Request a new buffer that is restored to the state of ARTICLE." - (nndraft-possibly-change-group group) - (when (nndraft-request-article article group server (current-buffer)) - (message-remove-header "xref") - (message-remove-header "lines") - t)) - -(deffoo nndraft-request-update-info (group info &optional server) - (nndraft-possibly-change-group group) - (gnus-info-set-read - info - (gnus-update-read-articles (gnus-group-prefixed-name group '(nndraft "")) - (nndraft-articles) t)) - (let (marks) - (when (setq marks (nth 3 info)) - (setcar (nthcdr 3 info) - (if (assq 'unsend marks) - (list (assq 'unsend marks)) - nil)))) - t) - -(deffoo nndraft-request-associate-buffer (group) - "Associate the current buffer with some article in the draft group." - (nndraft-open-server "") - (nndraft-request-group group) - (nndraft-possibly-change-group group) - (let ((gnus-verbose-backends nil) - (buf (current-buffer)) - article file) - (nnheader-temp-write nil - (insert-buffer buf) - (setq article (nndraft-request-accept-article - group (nnoo-current-server 'nndraft) t 'noinsert)) - (setq file (nndraft-article-filename article))) - (setq buffer-file-name (expand-file-name file)) - (setq buffer-auto-save-file-name (make-auto-save-file-name)) - (clear-visited-file-modtime) - article)) - -(deffoo nndraft-request-expire-articles (articles group &optional server force) - (nndraft-possibly-change-group group) - (let* ((nnmh-allow-delete-final t) - (res (nnoo-parent-function 'nndraft - 'nnmh-request-expire-articles - (list articles group server force))) - article) - ;; Delete all the "state" files of articles that have been expired. - (while articles - (unless (memq (setq article (pop articles)) res) - (let ((auto (nndraft-auto-save-file-name - (nndraft-article-filename article)))) - (when (file-exists-p auto) - (funcall nnmail-delete-file-function auto))))) - res)) - -(deffoo nndraft-request-accept-article (group &optional server last noinsert) - (nndraft-possibly-change-group group) - (let ((gnus-verbose-backends nil)) - (nnoo-parent-function 'nndraft 'nnmh-request-accept-article - (list group server last noinsert)))) - -(deffoo nndraft-request-create-group (group &optional server args) - (nndraft-possibly-change-group group) - (if (file-exists-p nndraft-current-directory) - (if (file-directory-p nndraft-current-directory) - t - nil) - (condition-case () - (progn - (gnus-make-directory nndraft-current-directory) - t) - (file-error nil)))) - - -;;; Low-Level Interface - -(defun nndraft-possibly-change-group (group) - (when (and group - (not (equal group nndraft-current-group))) - (nndraft-open-server "") - (setq nndraft-current-group group) - (setq nndraft-current-directory - (nnheader-concat nndraft-directory group)))) - -(defun nndraft-article-filename (article &rest args) - (apply 'concat - (file-name-as-directory nndraft-current-directory) - (int-to-string article) - args)) - -(defun nndraft-auto-save-file-name (file) - (save-excursion - (prog1 - (progn - (set-buffer (get-buffer-create " *draft tmp*")) - (setq buffer-file-name file) - (make-auto-save-file-name)) - (kill-buffer (current-buffer))))) - -(defun nndraft-articles () - "Return the list of messages in the group." - (gnus-make-directory nndraft-current-directory) - (sort - (mapcar 'string-to-int - (directory-files nndraft-current-directory nil "\\`[0-9]+\\'" t)) - '<)) - -(nnoo-import nndraft - (nnmh - nnmh-retrieve-headers - nnmh-request-group - nnmh-close-group - nnmh-request-list - nnmh-request-newsgroups - nnmh-request-move-article - nnmh-request-replace-article)) - -(provide 'nndraft) - -;;; nndraft.el ends here diff --git a/lisp/nneething.el b/lisp/nneething.el deleted file mode 100644 index 7da5466..0000000 --- a/lisp/nneething.el +++ /dev/null @@ -1,354 +0,0 @@ -;;; nneething.el --- arbitrary file access for Gnus -;; Copyright (C) 1995,96,97,98 Free Software Foundation, Inc. - -;; Author: Lars Magne Ingebrigtsen -;; Masanobu UMEDA -;; Keywords: news, mail - -;; This file is part of GNU Emacs. - -;; GNU Emacs is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 2, or (at your option) -;; any later version. - -;; GNU Emacs is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs; see the file COPYING. If not, write to the -;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. - -;;; Commentary: - -;;; Code: - -(eval-when-compile (require 'cl)) - -(require 'nnheader) -(require 'nnmail) -(require 'nnoo) -(require 'gnus-util) - -(nnoo-declare nneething) - -(defvoo nneething-map-file-directory "~/.nneething/" - "Where nneething stores the map files.") - -(defvoo nneething-map-file ".nneething" - "Name of the map files.") - -(defvoo nneething-exclude-files nil - "Regexp saying what files to exclude from the group. -If this variable is nil, no files will be excluded.") - - - -;;; Internal variables. - -(defconst nneething-version "nneething 1.0" - "nneething version.") - -(defvoo nneething-current-directory nil - "Current news group directory.") - -(defvoo nneething-status-string "") - -(defvoo nneething-message-id-number 0) -(defvoo nneething-work-buffer " *nneething work*") - -(defvoo nneething-group nil) -(defvoo nneething-map nil) -(defvoo nneething-read-only nil) -(defvoo nneething-active nil) -(defvoo nneething-address nil) - - - -(autoload 'gnus-encode-coding-string "gnus-ems") - -;;; Interface functions. - -(nnoo-define-basics nneething) - -(deffoo nneething-retrieve-headers (articles &optional group server fetch-old) - (nneething-possibly-change-directory group) - - (save-excursion - (set-buffer nntp-server-buffer) - (erase-buffer) - (let* ((number (length articles)) - (count 0) - (large (and (numberp nnmail-large-newsgroup) - (> number nnmail-large-newsgroup))) - article file) - - (if (stringp (car articles)) - 'headers - - (while (setq article (pop articles)) - (setq file (nneething-file-name article)) - - (when (and (file-exists-p file) - (or (file-directory-p file) - (not (zerop (nnheader-file-size file))))) - (insert (format "221 %d Article retrieved.\n" article)) - (nneething-insert-head file) - (insert ".\n")) - - (incf count) - - (and large - (zerop (% count 20)) - (nnheader-message 5 "nneething: Receiving headers... %d%%" - (/ (* count 100) number)))) - - (when large - (nnheader-message 5 "nneething: Receiving headers...done")) - - (nnheader-fold-continuation-lines) - 'headers)))) - -(deffoo nneething-request-article (id &optional group server buffer) - (nneething-possibly-change-directory group) - (let ((file (unless (stringp id) - (nneething-file-name id))) - (nntp-server-buffer (or buffer nntp-server-buffer))) - (and (stringp file) ; We did not request by Message-ID. - (file-exists-p file) ; The file exists. - (not (file-directory-p file)) ; It's not a dir. - (save-excursion - (nnmail-find-file file) ; Insert the file in the nntp buf. - (unless (nnheader-article-p) ; Either it's a real article... - (goto-char (point-min)) - (nneething-make-head file (current-buffer)) ; ... or we fake some headers. - (insert "\n")) - t)))) - -(deffoo nneething-request-group (group &optional server dont-check) - (nneething-possibly-change-directory group server) - (unless dont-check - (nneething-create-mapping) - (if (> (car nneething-active) (cdr nneething-active)) - (nnheader-insert "211 0 1 0 %s\n" group) - (nnheader-insert - "211 %d %d %d %s\n" - (- (1+ (cdr nneething-active)) (car nneething-active)) - (car nneething-active) (cdr nneething-active) - group))) - t) - -(deffoo nneething-request-list (&optional server dir) - (nnheader-report 'nneething "LIST is not implemented.")) - -(deffoo nneething-request-newgroups (date &optional server) - (nnheader-report 'nneething "NEWSGROUPS is not implemented.")) - -(deffoo nneething-request-type (group &optional article) - 'unknown) - -(deffoo nneething-close-group (group &optional server) - (setq nneething-current-directory nil) - t) - -(deffoo nneething-open-server (server &optional defs) - (nnheader-init-server-buffer) - (if (nneething-server-opened server) - t - (unless (assq 'nneething-address defs) - (setq defs (append defs (list (list 'nneething-address server))))) - (nnoo-change-server 'nneething server defs))) - - -;;; Internal functions. - -(defun nneething-possibly-change-directory (group &optional server) - (when (and server - (not (nneething-server-opened server))) - (nneething-open-server server)) - (when (and group - (not (equal nneething-group group))) - (setq nneething-group group) - (setq nneething-map nil) - (setq nneething-active (cons 1 0)) - (nneething-create-mapping))) - -(defun nneething-map-file () - ;; We make sure that the .nneething directory exists. - (gnus-make-directory nneething-map-file-directory) - ;; We store it in a special directory under the user's home dir. - (concat (file-name-as-directory nneething-map-file-directory) - nneething-group nneething-map-file)) - -(defun nneething-create-mapping () - ;; Read nneething-active and nneething-map. - (when (file-exists-p nneething-address) - (let ((map-file (nneething-map-file)) - (files (directory-files nneething-address)) - touched map-files) - (when (file-exists-p map-file) - (ignore-errors - (load map-file nil t t))) - (unless nneething-active - (setq nneething-active (cons 1 0))) - ;; Old nneething had a different map format. - (when (and (cdar nneething-map) - (atom (cdar nneething-map))) - (setq nneething-map - (mapcar (lambda (n) - (list (cdr n) (car n) - (nth 5 (file-attributes - (nneething-file-name (car n)))))) - nneething-map))) - ;; Remove files matching the exclusion regexp. - (when nneething-exclude-files - (let ((f files) - prev) - (while f - (if (string-match nneething-exclude-files (car f)) - (if prev (setcdr prev (cdr f)) - (setq files (cdr files))) - (setq prev f)) - (setq f (cdr f))))) - ;; Remove deleted files from the map. - (let ((map nneething-map) - prev) - (while map - (if (and (member (cadar map) files) - ;; We also remove files that have changed mod times. - (equal (nth 5 (file-attributes - (nneething-file-name (cadar map)))) - (caddar map))) - (progn - (push (cadar map) map-files) - (setq prev map)) - (setq touched t) - (if prev - (setcdr prev (cdr map)) - (setq nneething-map (cdr nneething-map)))) - (setq map (cdr map)))) - ;; Find all new files and enter them into the map. - (while files - (unless (member (car files) map-files) - ;; This file is not in the map, so we enter it. - (setq touched t) - (setcdr nneething-active (1+ (cdr nneething-active))) - (push (list (cdr nneething-active) (car files) - (nth 5 (file-attributes - (nneething-file-name (car files))))) - nneething-map)) - (setq files (cdr files))) - (when (and touched - (not nneething-read-only)) - (nnheader-temp-write map-file - (insert "(setq nneething-map '") - (gnus-prin1 nneething-map) - (insert ")\n(setq nneething-active '") - (gnus-prin1 nneething-active) - (insert ")\n")))))) - -(defun nneething-insert-head (file) - "Insert the head of FILE." - (when (nneething-get-head file) - (insert-buffer-substring nneething-work-buffer) - (goto-char (point-max)))) - -(defun nneething-make-head (file &optional buffer) - "Create a head by looking at the file attributes of FILE." - (let ((atts (file-attributes file))) - (insert - "Subject: " (file-name-nondirectory file) "\n" - "Message-ID: \n" - (if (equal '(0 0) (nth 5 atts)) "" - (concat "Date: " (current-time-string (nth 5 atts)) "\n")) - (or (when buffer - (save-excursion - (set-buffer buffer) - (when (re-search-forward "<[a-zA-Z0-9_]@[-a-zA-Z0-9_]>" 1000 t) - (concat "From: " (match-string 0) "\n")))) - (nneething-from-line (nth 2 atts) file)) - (if (> (string-to-int (int-to-string (nth 7 atts))) 0) - (concat "Chars: " (int-to-string (nth 7 atts)) "\n") - "") - (if buffer - (save-excursion - (set-buffer buffer) - (concat "Lines: " (int-to-string - (count-lines (point-min) (point-max))) - "\n")) - "") - ))) - -(defun nneething-from-line (uid &optional file) - "Return a From header based of UID." - (let* ((login (condition-case nil - (user-login-name uid) - (error - (cond ((= uid (user-uid)) (user-login-name)) - ((zerop uid) "root") - (t (int-to-string uid)))))) - (name (condition-case nil - (user-full-name uid) - (error - (cond ((= uid (user-uid)) (user-full-name)) - ((zerop uid) "Ms. Root"))))) - (host (if (string-match "\\`/[^/@]*@\\([^:/]+\\):" file) - (prog1 - (substring file - (match-beginning 1) - (match-end 1)) - (when (string-match "/\\(users\\|home\\)/\\([^/]+\\)/" file) - (setq login (substring file - (match-beginning 2) - (match-end 2)) - name nil))) - (system-name)))) - (concat "From: " login "@" host - (if name (concat " (" name ")") "") "\n"))) - -(defun nneething-get-head (file) - "Either find the head in FILE or make a head for FILE." - (save-excursion - (set-buffer (get-buffer-create nneething-work-buffer)) - (setq case-fold-search nil) - (buffer-disable-undo (current-buffer)) - (erase-buffer) - (cond - ((not (file-exists-p file)) - ;; The file do not exist. - nil) - ((or (file-directory-p file) - (file-symlink-p file)) - ;; It's a dir, so we fudge a head. - (nneething-make-head file) t) - (t - ;; We examine the file. - (nnheader-insert-head file) - (if (nnheader-article-p) - (delete-region - (progn - (goto-char (point-min)) - (or (and (search-forward "\n\n" nil t) - (1- (point))) - (point-max))) - (point-max)) - (goto-char (point-min)) - (nneething-make-head file (current-buffer)) - (delete-region (point) (point-max))) - t)))) - -(defun nneething-file-name (article) - "Return the file name of ARTICLE." - (concat (file-name-as-directory nneething-address) - (if (numberp article) - (cadr (assq article nneething-map)) - article))) - -(provide 'nneething) - -;;; nneething.el ends here diff --git a/lisp/nnfolder.el b/lisp/nnfolder.el deleted file mode 100644 index db9666b..0000000 --- a/lisp/nnfolder.el +++ /dev/null @@ -1,818 +0,0 @@ -;;; nnfolder.el --- mail folder access for Gnus -;; Copyright (C) 1995,96,97,98 Free Software Foundation, Inc. - -;; Author: Scott Byer -;; Lars Magne Ingebrigtsen -;; Masanobu UMEDA -;; Keywords: mail - -;; This file is part of GNU Emacs. - -;; GNU Emacs is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 2, or (at your option) -;; any later version. - -;; GNU Emacs is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs; see the file COPYING. If not, write to the -;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. - -;;; Commentary: - -;;; Code: - -(require 'nnheader) -(require 'message) -(require 'nnmail) -(require 'nnoo) -(eval-when-compile (require 'cl)) -(require 'gnus-util) - -(nnoo-declare nnfolder) - -(defvoo nnfolder-directory (expand-file-name message-directory) - "The name of the nnfolder directory.") - -(defvoo nnfolder-active-file - (nnheader-concat nnfolder-directory "active") - "The name of the active file.") - -;; I renamed this variable to something more in keeping with the general GNU -;; style. -SLB - -(defvoo nnfolder-ignore-active-file nil - "If non-nil, causes nnfolder to do some extra work in order to determine -the true active ranges of an mbox file. Note that the active file is still -saved, but it's values are not used. This costs some extra time when -scanning an mbox when opening it.") - -(defvoo nnfolder-distrust-mbox nil - "If non-nil, causes nnfolder to not trust the user with respect to -inserting unaccounted for mail in the middle of an mbox file. This can greatly -slow down scans, which now must scan the entire file for unmarked messages. -When nil, scans occur forward from the last marked message, a huge -time saver for large mailboxes.") - -(defvoo nnfolder-newsgroups-file - (concat (file-name-as-directory nnfolder-directory) "newsgroups") - "Mail newsgroups description file.") - -(defvoo nnfolder-get-new-mail t - "If non-nil, nnfolder will check the incoming mail file and split the mail.") - -(defvoo nnfolder-prepare-save-mail-hook nil - "Hook run narrowed to an article before saving.") - -(defvoo nnfolder-save-buffer-hook nil - "Hook run before saving the nnfolder mbox buffer.") - -(defvoo nnfolder-inhibit-expiry nil - "If non-nil, inhibit expiry.") - - - -(defconst nnfolder-version "nnfolder 1.0" - "nnfolder version.") - -(defconst nnfolder-article-marker "X-Gnus-Article-Number: " - "String used to demarcate what the article number for a message is.") - -(defvoo nnfolder-current-group nil) -(defvoo nnfolder-current-buffer nil) -(defvoo nnfolder-status-string "") -(defvoo nnfolder-group-alist nil) -(defvoo nnfolder-buffer-alist nil) -(defvoo nnfolder-scantime-alist nil) -(defvoo nnfolder-active-timestamp nil) - - - -;;; Interface functions - -(nnoo-define-basics nnfolder) - -(deffoo nnfolder-retrieve-headers (articles &optional group server fetch-old) - (save-excursion - (set-buffer nntp-server-buffer) - (erase-buffer) - (let (article start stop) - (nnfolder-possibly-change-group group server) - (when nnfolder-current-buffer - (set-buffer nnfolder-current-buffer) - (goto-char (point-min)) - (if (stringp (car articles)) - 'headers - (while (setq article (pop articles)) - (set-buffer nnfolder-current-buffer) - (when (nnfolder-goto-article article) - (setq start (point)) - (search-forward "\n\n" nil t) - (setq stop (1- (point))) - (set-buffer nntp-server-buffer) - (insert (format "221 %d Article retrieved.\n" article)) - (insert-buffer-substring nnfolder-current-buffer start stop) - (goto-char (point-max)) - (insert ".\n"))) - - (set-buffer nntp-server-buffer) - (nnheader-fold-continuation-lines) - 'headers))))) - -(deffoo nnfolder-open-server (server &optional defs) - (nnoo-change-server 'nnfolder server defs) - (nnmail-activate 'nnfolder t) - (gnus-make-directory nnfolder-directory) - (cond - ((not (file-exists-p nnfolder-directory)) - (nnfolder-close-server) - (nnheader-report 'nnfolder "Couldn't create directory: %s" - nnfolder-directory)) - ((not (file-directory-p (file-truename nnfolder-directory))) - (nnfolder-close-server) - (nnheader-report 'nnfolder "Not a directory: %s" nnfolder-directory)) - (t - (nnmail-activate 'nnfolder) - (nnheader-report 'nnfolder "Opened server %s using directory %s" - server nnfolder-directory) - t))) - -(deffoo nnfolder-request-close () - (let ((alist nnfolder-buffer-alist)) - (while alist - (nnfolder-close-group (caar alist) nil t) - (setq alist (cdr alist)))) - (nnoo-close-server 'nnfolder) - (setq nnfolder-buffer-alist nil - nnfolder-group-alist nil)) - -(deffoo nnfolder-request-article (article &optional group server buffer) - (nnfolder-possibly-change-group group server) - (save-excursion - (set-buffer nnfolder-current-buffer) - (goto-char (point-min)) - (when (nnfolder-goto-article article) - (let (start stop) - (setq start (point)) - (forward-line 1) - (unless (and (nnmail-search-unix-mail-delim) - (forward-line -1)) - (goto-char (point-max))) - (setq stop (point)) - (let ((nntp-server-buffer (or buffer nntp-server-buffer))) - (set-buffer nntp-server-buffer) - (erase-buffer) - (insert-buffer-substring nnfolder-current-buffer start stop) - (goto-char (point-min)) - (while (looking-at "From ") - (delete-char 5) - (insert "X-From-Line: ") - (forward-line 1)) - (if (numberp article) - (cons nnfolder-current-group article) - (goto-char (point-min)) - (search-forward (concat "\n" nnfolder-article-marker)) - (cons nnfolder-current-group - (string-to-int - (buffer-substring - (point) (progn (end-of-line) (point))))))))))) - -(deffoo nnfolder-request-group (group &optional server dont-check) - (nnfolder-possibly-change-group group server t) - (save-excursion - (if (not (assoc group nnfolder-group-alist)) - (nnheader-report 'nnfolder "No such group: %s" group) - (if dont-check - (progn - (nnheader-report 'nnfolder "Selected group %s" group) - t) - (let* ((active (assoc group nnfolder-group-alist)) - (group (car active)) - (range (cadr active))) - (cond - ((null active) - (nnheader-report 'nnfolder "No such group: %s" group)) - ((null nnfolder-current-group) - (nnheader-report 'nnfolder "Empty group: %s" group)) - (t - (nnheader-report 'nnfolder "Selected group %s" group) - (nnheader-insert "211 %d %d %d %s\n" - (1+ (- (cdr range) (car range))) - (car range) (cdr range) group)))))))) - -(deffoo nnfolder-request-scan (&optional group server) - (nnfolder-possibly-change-group nil server) - (when nnfolder-get-new-mail - (nnfolder-possibly-change-group group server) - (nnmail-get-new-mail - 'nnfolder - (lambda () - (let ((bufs nnfolder-buffer-alist)) - (save-excursion - (while bufs - (if (not (gnus-buffer-live-p (nth 1 (car bufs)))) - (setq nnfolder-buffer-alist - (delq (car bufs) nnfolder-buffer-alist)) - (set-buffer (nth 1 (car bufs))) - (nnfolder-save-buffer) - (kill-buffer (current-buffer))) - (setq bufs (cdr bufs)))))) - nnfolder-directory - group))) - -;; Don't close the buffer if we're not shutting down the server. This way, -;; we can keep the buffer in the group buffer cache, and not have to grovel -;; over the buffer again unless we add new mail to it or modify it in some -;; way. - -(deffoo nnfolder-close-group (group &optional server force) - ;; Make sure we _had_ the group open. - (when (or (assoc group nnfolder-buffer-alist) - (equal group nnfolder-current-group)) - (let ((inf (assoc group nnfolder-buffer-alist))) - (when inf - (when (and nnfolder-current-group - nnfolder-current-buffer) - (push (list nnfolder-current-group nnfolder-current-buffer) - nnfolder-buffer-alist)) - (setq nnfolder-buffer-alist - (delq inf nnfolder-buffer-alist)) - (setq nnfolder-current-buffer (cadr inf) - nnfolder-current-group (car inf)))) - (when (and nnfolder-current-buffer - (buffer-name nnfolder-current-buffer)) - (save-excursion - (set-buffer nnfolder-current-buffer) - ;; If the buffer was modified, write the file out now. - (nnfolder-save-buffer) - ;; If we're shutting the server down, we need to kill the - ;; buffer and remove it from the open buffer list. Or, of - ;; course, if we're trying to minimize our space impact. - (kill-buffer (current-buffer)) - (setq nnfolder-buffer-alist (delq (assoc group nnfolder-buffer-alist) - nnfolder-buffer-alist))))) - (setq nnfolder-current-group nil - nnfolder-current-buffer nil) - t) - -(deffoo nnfolder-request-create-group (group &optional server args) - (nnfolder-possibly-change-group nil server) - (nnmail-activate 'nnfolder) - (when group - (unless (assoc group nnfolder-group-alist) - (push (list group (cons 1 0)) nnfolder-group-alist) - (nnmail-save-active nnfolder-group-alist nnfolder-active-file) - (nnfolder-read-folder group))) - t) - -(deffoo nnfolder-request-list (&optional server) - (nnfolder-possibly-change-group nil server) - (save-excursion - (let ((nnmail-file-coding-system nnmail-active-file-coding-system) - (pathname-coding-system 'binary)) - (nnmail-find-file nnfolder-active-file) - (setq nnfolder-group-alist (nnmail-get-active))) - t)) - -(deffoo nnfolder-request-newgroups (date &optional server) - (nnfolder-possibly-change-group nil server) - (nnfolder-request-list server)) - -(deffoo nnfolder-request-list-newsgroups (&optional server) - (nnfolder-possibly-change-group nil server) - (save-excursion - (nnmail-find-file nnfolder-newsgroups-file))) - -(deffoo nnfolder-request-expire-articles - (articles newsgroup &optional server force) - (nnfolder-possibly-change-group newsgroup server) - (let* ((is-old t) - rest) - (nnmail-activate 'nnfolder) - - (save-excursion - (set-buffer nnfolder-current-buffer) - (while (and articles is-old) - (goto-char (point-min)) - (when (nnfolder-goto-article (car articles)) - (if (setq is-old - (nnmail-expired-article-p - newsgroup - (buffer-substring - (point) (progn (end-of-line) (point))) - force nnfolder-inhibit-expiry)) - (progn - (nnheader-message 5 "Deleting article %d..." - (car articles) newsgroup) - (nnfolder-delete-mail)) - (push (car articles) rest))) - (setq articles (cdr articles))) - (unless nnfolder-inhibit-expiry - (nnheader-message 5 "Deleting articles...done")) - (nnfolder-save-buffer) - (nnfolder-adjust-min-active newsgroup) - (nnmail-save-active nnfolder-group-alist nnfolder-active-file) - (nconc rest articles)))) - -(deffoo nnfolder-request-move-article (article group server - accept-form &optional last) - (save-excursion - (let ((buf (get-buffer-create " *nnfolder move*")) - result) - (and - (nnfolder-request-article article group server) - (save-excursion - (set-buffer buf) - (buffer-disable-undo (current-buffer)) - (erase-buffer) - (insert-buffer-substring nntp-server-buffer) - (goto-char (point-min)) - (while (re-search-forward - (concat "^" nnfolder-article-marker) - (save-excursion (search-forward "\n\n" nil t) (point)) t) - (delete-region (progn (beginning-of-line) (point)) - (progn (forward-line 1) (point)))) - (setq result (eval accept-form)) - (kill-buffer buf) - result) - (save-excursion - (nnfolder-possibly-change-group group server) - (set-buffer nnfolder-current-buffer) - (goto-char (point-min)) - (when (nnfolder-goto-article article) - (nnfolder-delete-mail)) - (when last - (nnfolder-save-buffer) - (nnfolder-adjust-min-active group) - (nnmail-save-active nnfolder-group-alist nnfolder-active-file)))) - result))) - -(deffoo nnfolder-request-accept-article (group &optional server last) - (save-excursion - (nnfolder-possibly-change-group group server) - (nnmail-check-syntax) - (let ((buf (current-buffer)) - result art-group) - (goto-char (point-min)) - (when (looking-at "X-From-Line: ") - (replace-match "From ")) - (and - (nnfolder-request-list) - (save-excursion - (set-buffer buf) - (goto-char (point-min)) - (search-forward "\n\n" nil t) - (forward-line -1) - (while (re-search-backward (concat "^" nnfolder-article-marker) nil t) - (delete-region (point) (progn (forward-line 1) (point)))) - (when nnmail-cache-accepted-message-ids - (nnmail-cache-insert (nnmail-fetch-field "message-id"))) - (setq result (if (stringp group) - (list (cons group (nnfolder-active-number group))) - (setq art-group - (nnmail-article-group 'nnfolder-active-number)))) - (if (and (null result) - (yes-or-no-p "Moved to `junk' group; delete article? ")) - (setq result 'junk) - (setq result - (car (nnfolder-save-mail result))))) - (when last - (save-excursion - (nnfolder-possibly-change-folder (or (caar art-group) group)) - (nnfolder-save-buffer) - (when nnmail-cache-accepted-message-ids - (nnmail-cache-close))))) - (nnmail-save-active nnfolder-group-alist nnfolder-active-file) - (unless result - (nnheader-report 'nnfolder "Couldn't store article")) - result))) - -(deffoo nnfolder-request-replace-article (article group buffer) - (nnfolder-possibly-change-group group) - (save-excursion - (set-buffer buffer) - (goto-char (point-min)) - (let (xfrom) - (while (re-search-forward "^X-From-Line: \\(.*\\)$" nil t) - (setq xfrom (match-string 1)) - (gnus-delete-line)) - (goto-char (point-min)) - (if xfrom - (insert "From " xfrom "\n") - (unless (looking-at message-unix-mail-delimiter) - (insert "From nobody " (current-time-string) "\n")))) - (nnfolder-normalize-buffer) - (set-buffer nnfolder-current-buffer) - (goto-char (point-min)) - (if (not (nnfolder-goto-article article)) - nil - (nnfolder-delete-mail) - (insert-buffer-substring buffer) - (nnfolder-save-buffer) - t))) - -(deffoo nnfolder-request-delete-group (group &optional force server) - (nnfolder-close-group group server t) - ;; Delete all articles in GROUP. - (if (not force) - () ; Don't delete the articles. - ;; Delete the file that holds the group. - (ignore-errors - (delete-file (nnfolder-group-pathname group)))) - ;; Remove the group from all structures. - (setq nnfolder-group-alist - (delq (assoc group nnfolder-group-alist) nnfolder-group-alist) - nnfolder-current-group nil - nnfolder-current-buffer nil) - ;; Save the active file. - (nnmail-save-active nnfolder-group-alist nnfolder-active-file) - t) - -(deffoo nnfolder-request-rename-group (group new-name &optional server) - (nnfolder-possibly-change-group group server) - (save-excursion - (set-buffer nnfolder-current-buffer) - (and (file-writable-p buffer-file-name) - (ignore-errors - (rename-file - buffer-file-name - (nnfolder-group-pathname new-name)) - t) - ;; That went ok, so we change the internal structures. - (let ((entry (assoc group nnfolder-group-alist))) - (and entry (setcar entry new-name)) - (setq nnfolder-current-buffer nil - nnfolder-current-group nil) - ;; Save the new group alist. - (nnmail-save-active nnfolder-group-alist nnfolder-active-file) - ;; We kill the buffer instead of renaming it and stuff. - (kill-buffer (current-buffer)) - t)))) - -(defun nnfolder-request-regenerate (server) - (nnfolder-possibly-change-group nil server) - (nnfolder-generate-active-file) - t) - - -;;; Internal functions. - -(defun nnfolder-adjust-min-active (group) - ;; Find the lowest active article in this group. - (let* ((active (cadr (assoc group nnfolder-group-alist))) - (marker (concat "\n" nnfolder-article-marker)) - (number "[0-9]+") - (activemin (cdr active))) - (save-excursion - (set-buffer nnfolder-current-buffer) - (goto-char (point-min)) - (while (and (search-forward marker nil t) - (re-search-forward number nil t)) - (let ((newnum (string-to-number (match-string 0)))) - (if (nnmail-within-headers-p) - (setq activemin (min activemin newnum))))) - (setcar active activemin)))) - -(defun nnfolder-article-string (article) - (if (numberp article) - (concat "\n" nnfolder-article-marker (int-to-string article) " ") - (concat "\nMessage-ID: " article))) - -(defun nnfolder-goto-article (article) - "Place point at the start of the headers of ARTICLE. -ARTICLE can be an article number or a Message-ID. -Returns t if successful, nil otherwise." - (let ((art-string (nnfolder-article-string article)) - start found) - ;; It is likely that we are at or before the delimiter line. - ;; We therefore go to the end of the previous line, and start - ;; searching from there. - (beginning-of-line) - (unless (bobp) - (forward-char -1)) - (setq start (point)) - ;; First search forward. - (while (and (setq found (search-forward art-string nil t)) - (not (nnmail-within-headers-p)))) - ;; If unsuccessful, search backward from where we started, - (unless found - (goto-char start) - (while (and (setq found (search-backward art-string nil t)) - (not (nnmail-within-headers-p))))) - (when found - (nnmail-search-unix-mail-delim-backward)))) - -(defun nnfolder-delete-mail (&optional leave-delim) - "Delete the message that point is in. -If optional argument LEAVE-DELIM is t, then mailbox delimiter is not -deleted. Point is left where the deleted region was." - (delete-region - (save-excursion - (forward-line 1) ; in case point is at beginning of message already - (nnmail-search-unix-mail-delim-backward) - (if leave-delim (progn (forward-line 1) (point)) - (point))) - (progn - (forward-line 1) - (if (nnmail-search-unix-mail-delim) - (point) - (point-max))))) - -(defun nnfolder-possibly-change-group (group &optional server dont-check) - ;; Change servers. - (when (and server - (not (nnfolder-server-opened server))) - (nnfolder-open-server server)) - (unless (gnus-buffer-live-p nnfolder-current-buffer) - (setq nnfolder-current-buffer nil - nnfolder-current-group nil)) - ;; Change group. - (when (and group - (not (equal group nnfolder-current-group))) - (let ((pathname-coding-system 'binary)) - (nnmail-activate 'nnfolder) - (when (and (not (assoc group nnfolder-group-alist)) - (not (file-exists-p - (nnfolder-group-pathname group)))) - ;; The group doesn't exist, so we create a new entry for it. - (push (list group (cons 1 0)) nnfolder-group-alist) - (nnmail-save-active nnfolder-group-alist nnfolder-active-file)) - - (if dont-check - (setq nnfolder-current-group group - nnfolder-current-buffer nil) - (let (inf file) - ;; If we have to change groups, see if we don't already have the - ;; folder in memory. If we do, verify the modtime and destroy - ;; the folder if needed so we can rescan it. - (setq nnfolder-current-buffer - (nth 1 (assoc group nnfolder-buffer-alist))) - - ;; If the buffer is not live, make sure it isn't in the alist. If it - ;; is live, verify that nobody else has touched the file since last - ;; time. - (when (and nnfolder-current-buffer - (not (gnus-buffer-live-p nnfolder-current-buffer))) - (setq nnfolder-buffer-alist (delq inf nnfolder-buffer-alist) - nnfolder-current-buffer nil)) - - (setq nnfolder-current-group group) - - (when (or (not nnfolder-current-buffer) - (not (verify-visited-file-modtime - nnfolder-current-buffer))) - (save-excursion - (setq file (nnfolder-group-pathname group)) - ;; See whether we need to create the new file. - (unless (file-exists-p file) - (gnus-make-directory (file-name-directory file)) - (nnmail-write-region 1 1 file t 'nomesg)) - (when (setq nnfolder-current-buffer (nnfolder-read-folder group)) - (set-buffer nnfolder-current-buffer) - (push (list group nnfolder-current-buffer) - nnfolder-buffer-alist))))))))) - -(defun nnfolder-save-mail (group-art-list) - "Called narrowed to an article." - (let* (save-list group-art) - (goto-char (point-min)) - ;; The From line may have been quoted by movemail. - (when (looking-at (concat ">" message-unix-mail-delimiter)) - (delete-char 1)) - ;; This might come from somewhere else. - (unless (looking-at message-unix-mail-delimiter) - (insert "From nobody " (current-time-string) "\n") - (goto-char (point-min))) - ;; Quote all "From " lines in the article. - (forward-line 1) - (let (case-fold-search) - (while (re-search-forward "^From " nil t) - (beginning-of-line) - (insert "> "))) - (setq save-list group-art-list) - (nnmail-insert-lines) - (nnmail-insert-xref group-art-list) - (run-hooks 'nnmail-prepare-save-mail-hook) - (run-hooks 'nnfolder-prepare-save-mail-hook) - - ;; Insert the mail into each of the destination groups. - (while (setq group-art (pop group-art-list)) - ;; Kill any previous newsgroup markers. - (goto-char (point-min)) - (search-forward "\n\n" nil t) - (forward-line -1) - (while (search-backward (concat "\n" nnfolder-article-marker) nil t) - (delete-region (1+ (point)) (progn (forward-line 2) (point)))) - - ;; Insert the new newsgroup marker. - (nnfolder-insert-newsgroup-line group-art) - - (save-excursion - (let ((beg (point-min)) - (end (point-max)) - (obuf (current-buffer))) - (nnfolder-possibly-change-folder (car group-art)) - (let ((buffer-read-only nil)) - (nnfolder-normalize-buffer) - (insert-buffer-substring obuf beg end))))) - - ;; Did we save it anywhere? - save-list)) - -(defun nnfolder-normalize-buffer () - "Make sure there are two newlines at the end of the buffer." - (goto-char (point-max)) - (skip-chars-backward "\n") - (delete-region (point) (point-max)) - (insert "\n\n")) - -(defun nnfolder-insert-newsgroup-line (group-art) - (save-excursion - (goto-char (point-min)) - (when (search-forward "\n\n" nil t) - (forward-char -1) - (insert (format (concat nnfolder-article-marker "%d %s\n") - (cdr group-art) (current-time-string)))))) - -(defun nnfolder-active-number (group) - ;; Find the next article number in GROUP. - (let ((active (cadr (assoc group nnfolder-group-alist)))) - (if active - (setcdr active (1+ (cdr active))) - ;; This group is new, so we create a new entry for it. - ;; This might be a bit naughty... creating groups on the drop of - ;; a hat, but I don't know... - (push (list group (setq active (cons 1 1))) - nnfolder-group-alist)) - (cdr active))) - -(defun nnfolder-possibly-change-folder (group) - (let ((inf (assoc group nnfolder-buffer-alist))) - (if (and inf - (gnus-buffer-live-p (cadr inf))) - (set-buffer (cadr inf)) - (when inf - (setq nnfolder-buffer-alist (delq inf nnfolder-buffer-alist))) - (when nnfolder-group-alist - (nnmail-save-active nnfolder-group-alist nnfolder-active-file)) - (push (list group (nnfolder-read-folder group)) - nnfolder-buffer-alist)))) - -;; This method has a problem if you've accidentally let the active list get -;; out of sync with the files. This could happen, say, if you've -;; accidentally gotten new mail with something other than Gnus (but why -;; would _that_ ever happen? :-). In that case, we will be in the middle of -;; processing the file, ready to add new X-Gnus article number markers, and -;; we'll run across a message with no ID yet - the active list _may_not_ be -;; ready for us yet. - -;; To handle this, I'm modifying this routine to maintain the maximum ID seen -;; so far, and when we hit a message with no ID, we will _manually_ scan the -;; rest of the message looking for any more, possibly higher IDs. We'll -;; assume the maximum that we find is the highest active. Note that this -;; shouldn't cost us much extra time at all, but will be a lot less -;; vulnerable to glitches between the mbox and the active file. - -(defun nnfolder-read-folder (group) - (let* ((file (nnfolder-group-pathname group)) - (buffer (set-buffer (nnheader-find-file-noselect file)))) - (if (equal (cadr (assoc group nnfolder-scantime-alist)) - (nth 5 (file-attributes file))) - ;; This looks up-to-date, so we don't do any scanning. - (if (file-exists-p file) - buffer - (push (list group buffer) nnfolder-buffer-alist) - (set-buffer-modified-p t) - (save-buffer)) - ;; Parse the damn thing. - (save-excursion - (nnmail-activate 'nnfolder) - ;; Read in the file. - (let ((delim (concat "^" message-unix-mail-delimiter)) - (marker (concat "\n" nnfolder-article-marker)) - (number "[0-9]+") - (active (or (cadr (assoc group nnfolder-group-alist)) - (cons 1 0))) - (scantime (assoc group nnfolder-scantime-alist)) - (minid (lsh -1 -1)) - maxid start end newscantime - buffer-read-only) - (buffer-disable-undo (current-buffer)) - (setq maxid (cdr active)) - (goto-char (point-min)) - - ;; Anytime the active number is 1 or 0, it is suspect. In that - ;; case, search the file manually to find the active number. Or, - ;; of course, if we're being paranoid. (This would also be the - ;; place to build other lists from the header markers, such as - ;; expunge lists, etc., if we ever desired to abandon the active - ;; file entirely for mboxes.) - (when (or nnfolder-ignore-active-file - (< maxid 2)) - (while (and (search-forward marker nil t) - (re-search-forward number nil t)) - (let ((newnum (string-to-number (match-string 0)))) - (if (nnmail-within-headers-p) - (setq maxid (max maxid newnum) - minid (min minid newnum))))) - (setcar active (max 1 (min minid maxid))) - (setcdr active (max maxid (cdr active))) - (goto-char (point-min))) - - ;; As long as we trust that the user will only insert unmarked mail - ;; at the end, go to the end and search backwards for the last - ;; marker. Find the start of that message, and begin to search for - ;; unmarked messages from there. - (when (not (or nnfolder-distrust-mbox - (< maxid 2))) - (goto-char (point-max)) - (unless (re-search-backward marker nil t) - (goto-char (point-min))) - (when (nnmail-search-unix-mail-delim) - (goto-char (point-min)))) - - ;; Keep track of the active number on our own, and insert it back - ;; into the active list when we're done. Also, prime the pump to - ;; cut down on the number of searches we do. - (unless (nnmail-search-unix-mail-delim) - (goto-char (point-max))) - (setq end (point-marker)) - (while (not (= end (point-max))) - (setq start (marker-position end)) - (goto-char end) - ;; There may be more than one "From " line, so we skip past - ;; them. - (while (looking-at delim) - (forward-line 1)) - (set-marker end (if (nnmail-search-unix-mail-delim) - (point) - (point-max))) - (goto-char start) - (when (not (search-forward marker end t)) - (narrow-to-region start end) - (nnmail-insert-lines) - (nnfolder-insert-newsgroup-line - (cons nil (nnfolder-active-number nnfolder-current-group))) - (widen))) - - (set-marker end nil) - ;; Make absolutely sure that the active list reflects reality! - (nnmail-save-active nnfolder-group-alist nnfolder-active-file) - ;; Set the scantime for this group. - (setq newscantime (visited-file-modtime)) - (if scantime - (setcdr scantime (list newscantime)) - (push (list nnfolder-current-group newscantime) - nnfolder-scantime-alist)) - (current-buffer)))))) - -;;;###autoload -(defun nnfolder-generate-active-file () - "Look for mbox folders in the nnfolder directory and make them into groups." - (interactive) - (nnmail-activate 'nnfolder) - (let ((files (directory-files nnfolder-directory)) - file) - (while (setq file (pop files)) - (when (and (not (backup-file-name-p file)) - (message-mail-file-mbox-p - (nnheader-concat nnfolder-directory file))) - (let ((oldgroup (assoc file nnfolder-group-alist))) - (if oldgroup - (nnheader-message 5 "Refreshing group %s..." file) - (nnheader-message 5 "Adding group %s..." file)) - (if oldgroup - (setq nnfolder-group-alist - (delq oldgroup (copy-sequence nnfolder-group-alist)))) - (push (list file (cons 1 0)) nnfolder-group-alist) - (nnfolder-possibly-change-folder file) - (nnfolder-possibly-change-group file) - (nnfolder-close-group file)))) - (nnheader-message 5 ""))) - -(defun nnfolder-group-pathname (group) - "Make pathname for GROUP." - (setq group (gnus-encode-coding-string group nnmail-pathname-coding-system)) - (let ((dir (file-name-as-directory (expand-file-name nnfolder-directory)))) - ;; If this file exists, we use it directly. - (if (or nnmail-use-long-file-names - (file-exists-p (concat dir group))) - (concat dir group) - ;; If not, we translate dots into slashes. - (concat dir (nnheader-replace-chars-in-string group ?. ?/))))) - -(defun nnfolder-save-buffer () - "Save the buffer." - (when (buffer-modified-p) - (run-hooks 'nnfolder-save-buffer-hook) - (gnus-make-directory (file-name-directory (buffer-file-name))) - (save-buffer))) - -(provide 'nnfolder) - -;;; nnfolder.el ends here diff --git a/lisp/nngateway.el b/lisp/nngateway.el deleted file mode 100644 index 2139885..0000000 --- a/lisp/nngateway.el +++ /dev/null @@ -1,90 +0,0 @@ -;;; nngateway.el --- posting news via mail gateways -;; Copyright (C) 1996,97,98 Free Software Foundation, Inc. - -;; Author: Lars Magne Ingebrigtsen -;; Keywords: news, mail - -;; This file is part of GNU Emacs. - -;; GNU Emacs is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 2, or (at your option) -;; any later version. - -;; GNU Emacs is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs; see the file COPYING. If not, write to the -;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. - -;;; Commentary: - -;;; Code: - -(require 'nnoo) -(require 'message) - -(nnoo-declare nngateway) - -(defvoo nngateway-address nil - "Address of the mail-to-news gateway.") - -(defvoo nngateway-header-transformation 'nngateway-simple-header-transformation - "Function to be called to rewrite the news headers into mail headers. -It is called narrowed to the headers to be transformed with one -parameter -- the gateway address.") - -;;; Interface functions - -(nnoo-define-basics nngateway) - -(deffoo nngateway-open-server (server &optional defs) - (if (nngateway-server-opened server) - t - (unless (assq 'nngateway-address defs) - (setq defs (append defs (list (list 'nngateway-address server))))) - (nnoo-change-server 'nngateway server defs))) - -(deffoo nngateway-request-post (&optional server) - (when (or (nngateway-server-opened server) - (nngateway-open-server server)) - ;; Rewrite the header. - (let ((buf (current-buffer))) - (nnheader-temp-write nil - (insert-buffer-substring buf) - (message-narrow-to-head) - (funcall nngateway-header-transformation nngateway-address) - (goto-char (point-max)) - (insert mail-header-separator "\n") - (widen) - (let (message-required-mail-headers) - (funcall message-send-mail-function)) - t)))) - -;;; Internal functions - -(defun nngateway-simple-header-transformation (gateway) - "Transform the headers to use GATEWAY." - (let ((newsgroups (mail-fetch-field "newsgroups"))) - (message-remove-header "to") - (message-remove-header "cc") - (goto-char (point-min)) - (insert "To: " (nnheader-replace-chars-in-string newsgroups ?. ?-) - "@" gateway "\n"))) - -(defun nngateway-mail2news-header-transformation (gateway) - "Transform the headers for sending to a mail2news gateway." - (message-remove-header "to") - (message-remove-header "cc") - (goto-char (point-min)) - (insert "To: " gateway "\n")) - -(nnoo-define-skeleton nngateway) - -(provide 'nngateway) - -;;; nngateway.el ends here diff --git a/lisp/nnheaderxm.el b/lisp/nnheaderxm.el deleted file mode 100644 index f788042..0000000 --- a/lisp/nnheaderxm.el +++ /dev/null @@ -1,41 +0,0 @@ -;;; nnheaderxm.el --- making Gnus backends work under XEmacs -;; Copyright (C) 1996,97,98 Free Software Foundation, Inc. - -;; Author: Lars Magne Ingebrigtsen -;; Keywords: news - -;; This file is part of GNU Emacs. - -;; GNU Emacs is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 2, or (at your option) -;; any later version. - -;; GNU Emacs is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs; see the file COPYING. If not, write to the -;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. - -;;; Commentary: - -;;; Code: - -(defun nnheader-xmas-run-at-time (time repeat function &rest args) - (start-itimer - "nnheader-run-at-time" - `(lambda () - (,function ,@args)) - time repeat)) - -(fset 'nnheader-run-at-time 'nnheader-xmas-run-at-time) -(fset 'nnheader-cancel-timer 'delete-itimer) -(fset 'nnheader-cancel-function-timers 'ignore) - -(provide 'nnheaderxm) - -;;; nnheaderxm.el ends here. diff --git a/lisp/nnkiboze.el b/lisp/nnkiboze.el deleted file mode 100644 index 38a0244..0000000 --- a/lisp/nnkiboze.el +++ /dev/null @@ -1,365 +0,0 @@ -;;; nnkiboze.el --- select virtual news access for Gnus -;; Copyright (C) 1995,96,97,98 Free Software Foundation, Inc. - -;; Author: Lars Magne Ingebrigtsen -;; Keywords: news - -;; This file is part of GNU Emacs. - -;; GNU Emacs is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 2, or (at your option) -;; any later version. - -;; GNU Emacs is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs; see the file COPYING. If not, write to the -;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. - -;;; Commentary: - -;; The other access methods (nntp, nnspool, etc) are general news -;; access methods. This module relies on Gnus and can't be used -;; separately. - -;;; Code: - -(require 'nntp) -(require 'nnheader) -(require 'gnus) -(require 'gnus-score) -(require 'nnoo) -(eval-when-compile (require 'cl)) - -(nnoo-declare nnkiboze) -(defvoo nnkiboze-directory (nnheader-concat gnus-directory "kiboze/") - "nnkiboze will put its files in this directory.") - -(defvoo nnkiboze-level 9 - "The maximum level to be searched for articles.") - -(defvoo nnkiboze-remove-read-articles t - "If non-nil, nnkiboze will remove read articles from the kiboze group.") - -(defvoo nnkiboze-ephemeral nil - "If non-nil, don't store any data anywhere.") - -(defvoo nnkiboze-scores nil - "Score rules for generating the nnkiboze group.") - -(defvoo nnkiboze-regexp nil - "Regexp for matching component groups.") - - - -(defconst nnkiboze-version "nnkiboze 1.0") - -(defvoo nnkiboze-current-group nil) -(defvoo nnkiboze-status-string "") - -(defvoo nnkiboze-headers nil) - - - -;;; Interface functions. - -(nnoo-define-basics nnkiboze) - -(deffoo nnkiboze-retrieve-headers (articles &optional group server fetch-old) - (nnkiboze-possibly-change-group group) - (unless gnus-nov-is-evil - (if (stringp (car articles)) - 'headers - (let ((nov (nnkiboze-nov-file-name))) - (when (file-exists-p nov) - (save-excursion - (set-buffer nntp-server-buffer) - (erase-buffer) - (nnheader-insert-file-contents nov) - (nnheader-nov-delete-outside-range - (car articles) (car (last articles))) - 'nov)))))) - -(deffoo nnkiboze-request-article (article &optional newsgroup server buffer) - (nnkiboze-possibly-change-group newsgroup) - (if (not (numberp article)) - ;; This is a real kludge. It might not work at times, but it - ;; does no harm I think. The only alternative is to offer no - ;; article fetching by message-id at all. - (nntp-request-article article newsgroup gnus-nntp-server buffer) - (let* ((header (gnus-summary-article-header article)) - (xref (mail-header-xref header))) - (unless xref - (error "nnkiboze: No xref")) - (unless (string-match " \\([^ ]+\\):\\([0-9]+\\)" xref) - (error "nnkiboze: Malformed xref")) - (gnus-request-article (string-to-int (match-string 2 xref)) - (match-string 1 xref) - buffer)))) - -(deffoo nnkiboze-request-scan (&optional group server) - (nnkiboze-generate-group (concat "nnkiboze:" group))) - -(deffoo nnkiboze-request-group (group &optional server dont-check) - "Make GROUP the current newsgroup." - (nnkiboze-possibly-change-group group) - (if dont-check - t - (let ((nov-file (nnkiboze-nov-file-name)) - beg end total) - (save-excursion - (set-buffer nntp-server-buffer) - (erase-buffer) - (unless (file-exists-p nov-file) - (nnkiboze-request-scan group)) - (if (not (file-exists-p nov-file)) - (nnheader-report 'nnkiboze "Can't select group %s" group) - (nnheader-insert-file-contents nov-file) - (if (zerop (buffer-size)) - (nnheader-insert "211 0 0 0 %s\n" group) - (goto-char (point-min)) - (when (looking-at "[0-9]+") - (setq beg (read (current-buffer)))) - (goto-char (point-max)) - (when (re-search-backward "^[0-9]" nil t) - (setq end (read (current-buffer)))) - (setq total (count-lines (point-min) (point-max))) - (nnheader-insert "211 %d %d %d %s\n" total beg end group))))))) - -(deffoo nnkiboze-close-group (group &optional server) - (nnkiboze-possibly-change-group group) - ;; Remove NOV lines of articles that are marked as read. - (when (and (file-exists-p (nnkiboze-nov-file-name)) - nnkiboze-remove-read-articles) - (nnheader-temp-write (nnkiboze-nov-file-name) - (let ((cur (current-buffer))) - (nnheader-insert-file-contents (nnkiboze-nov-file-name)) - (goto-char (point-min)) - (while (not (eobp)) - (if (not (gnus-article-read-p (read cur))) - (forward-line 1) - (gnus-delete-line)))))) - (setq nnkiboze-current-group nil)) - -(deffoo nnkiboze-open-server (server &optional defs) - (unless (assq 'nnkiboze-regexp defs) - (push `(nnkiboze-regexp ,server) - defs)) - (nnoo-change-server 'nnkiboze server defs)) - -(deffoo nnkiboze-request-delete-group (group &optional force server) - (nnkiboze-possibly-change-group group) - (when force - (let ((files (nconc - (nnkiboze-score-file group) - (list (nnkiboze-nov-file-name) - (nnkiboze-nov-file-name ".newsrc"))))) - (while files - (and (file-exists-p (car files)) - (file-writable-p (car files)) - (delete-file (car files))) - (setq files (cdr files))))) - (setq nnkiboze-current-group nil) - t) - -(nnoo-define-skeleton nnkiboze) - - -;;; Internal functions. - -(defun nnkiboze-possibly-change-group (group) - (setq nnkiboze-current-group group)) - -(defun nnkiboze-prefixed-name (group) - (gnus-group-prefixed-name group '(nnkiboze ""))) - -;;;###autoload -(defun nnkiboze-generate-groups () - "\"Usage: emacs -batch -l nnkiboze -f nnkiboze-generate-groups\". -Finds out what articles are to be part of the nnkiboze groups." - (interactive) - (let ((nnmail-spool-file nil) - (gnus-use-dribble-file nil) - (gnus-read-active-file t) - (gnus-expert-user t)) - (gnus)) - (let* ((gnus-newsrc-alist (gnus-copy-sequence gnus-newsrc-alist)) - (newsrc (cdr gnus-newsrc-alist)) - gnus-newsrc-hashtb info) - (gnus-make-hashtable-from-newsrc-alist) - ;; We have copied all the newsrc alist info over to local copies - ;; so that we can mess all we want with these lists. - (while (setq info (pop newsrc)) - (when (string-match "nnkiboze" (gnus-info-group info)) - ;; For each kiboze group, we call this function to generate - ;; it. - (nnkiboze-generate-group (gnus-info-group info)))))) - -(defun nnkiboze-score-file (group) - (list (expand-file-name - (concat (file-name-as-directory gnus-kill-files-directory) - (nnheader-translate-file-chars - (concat (nnkiboze-prefixed-name nnkiboze-current-group) - "." gnus-score-file-suffix)))))) - -(defun nnkiboze-generate-group (group) - (let* ((info (nth 2 (gnus-gethash group gnus-newsrc-hashtb))) - (newsrc-file (concat nnkiboze-directory - (nnheader-translate-file-chars - (concat group ".newsrc")))) - (nov-file (concat nnkiboze-directory - (nnheader-translate-file-chars - (concat group ".nov")))) - method nnkiboze-newsrc gname newsrc active - ginfo lowest glevel orig-info nov-buffer - ;; Bind various things to nil to make group entry faster. - (gnus-expert-user t) - (gnus-large-newsgroup nil) - (gnus-score-find-score-files-function 'nnkiboze-score-file) - (gnus-verbose (min gnus-verbose 3)) - gnus-select-group-hook gnus-summary-prepare-hook - gnus-thread-sort-functions gnus-show-threads - gnus-visual gnus-suppress-duplicates num-unread) - (unless info - (error "No such group: %s" group)) - ;; Load the kiboze newsrc file for this group. - (when (file-exists-p newsrc-file) - (load newsrc-file)) - (nnheader-temp-write nov-file - (when (file-exists-p nov-file) - (nnheader-insert-file-contents nov-file)) - (setq nov-buffer (current-buffer)) - ;; Go through the active hashtb and add new all groups that match the - ;; kiboze regexp. - (mapatoms - (lambda (group) - (and (string-match nnkiboze-regexp - (setq gname (symbol-name group))) ; Match - (not (assoc gname nnkiboze-newsrc)) ; It isn't registered - (numberp (car (symbol-value group))) ; It is active - (or (> nnkiboze-level 7) - (and (setq glevel (nth 1 (nth 2 (gnus-gethash - gname gnus-newsrc-hashtb)))) - (>= nnkiboze-level glevel))) - (not (string-match "^nnkiboze:" gname)) ; Exclude kibozes - (push (cons gname (1- (car (symbol-value group)))) - nnkiboze-newsrc))) - gnus-active-hashtb) - ;; `newsrc' is set to the list of groups that possibly are - ;; component groups to this kiboze group. This list has elements - ;; on the form `(GROUP . NUMBER)', where NUMBER is the highest - ;; number that has been kibozed in GROUP in this kiboze group. - (setq newsrc nnkiboze-newsrc) - (while newsrc - (if (not (setq active (gnus-gethash - (caar newsrc) gnus-active-hashtb))) - ;; This group isn't active after all, so we remove it from - ;; the list of component groups. - (setq nnkiboze-newsrc (delq (car newsrc) nnkiboze-newsrc)) - (setq lowest (cdar newsrc)) - ;; Ok, we have a valid component group, so we jump to it. - (switch-to-buffer gnus-group-buffer) - (gnus-group-jump-to-group (caar newsrc)) - (gnus-message 3 "nnkiboze: Checking %s..." (caar newsrc)) - (setq ginfo (gnus-get-info (gnus-group-group-name)) - orig-info (gnus-copy-sequence ginfo) - num-unread (car (gnus-gethash (caar newsrc) - gnus-newsrc-hashtb))) - (unwind-protect - (progn - ;; We set all list of article marks to nil. Since we operate - ;; on copies of the real lists, we can destroy anything we - ;; want here. - (when (nth 3 ginfo) - (setcar (nthcdr 3 ginfo) nil)) - ;; We set the list of read articles to be what we expect for - ;; this kiboze group -- either nil or `(1 . LOWEST)'. - (when ginfo - (setcar (nthcdr 2 ginfo) - (and (not (= lowest 1)) (cons 1 lowest)))) - (when (and (or (not ginfo) - (> (length (gnus-list-of-unread-articles - (car ginfo))) - 0)) - (progn - (ignore-errors - (gnus-group-select-group nil)) - (eq major-mode 'gnus-summary-mode))) - ;; We are now in the group where we want to be. - (setq method (gnus-find-method-for-group - gnus-newsgroup-name)) - (when (eq method gnus-select-method) - (setq method nil)) - ;; We go through the list of scored articles. - (while gnus-newsgroup-scored - (when (> (caar gnus-newsgroup-scored) lowest) - ;; If it has a good score, then we enter this article - ;; into the kiboze group. - (nnkiboze-enter-nov - nov-buffer - (gnus-summary-article-header - (caar gnus-newsgroup-scored)) - gnus-newsgroup-name)) - (setq gnus-newsgroup-scored (cdr gnus-newsgroup-scored))) - ;; That's it. We exit this group. - (when (eq major-mode 'gnus-summary-mode) - (kill-buffer (current-buffer))))) - ;; Restore the proper info. - (when ginfo - (setcdr ginfo (cdr orig-info))) - (setcar (gnus-gethash (caar newsrc) gnus-newsrc-hashtb) - num-unread))) - (setcdr (car newsrc) (car active)) - (gnus-message 3 "nnkiboze: Checking %s...done" (caar newsrc)) - (setq newsrc (cdr newsrc)))) - ;; We save the kiboze newsrc for this group. - (nnheader-temp-write newsrc-file - (insert "(setq nnkiboze-newsrc '") - (gnus-prin1 nnkiboze-newsrc) - (insert ")\n"))) - (save-excursion - (set-buffer gnus-group-buffer) - (gnus-group-list-groups)) - t) - -(defun nnkiboze-enter-nov (buffer header group) - (save-excursion - (set-buffer buffer) - (goto-char (point-max)) - (let ((prefix (gnus-group-real-prefix group)) - (oheader (copy-sequence header)) - article) - (if (zerop (forward-line -1)) - (progn - (setq article (1+ (read (current-buffer)))) - (forward-line 1)) - (setq article 1)) - (mail-header-set-number oheader article) - (nnheader-insert-nov oheader) - (search-backward "\t" nil t 2) - (if (re-search-forward " [^ ]+:[0-9]+" nil t) - (goto-char (match-beginning 0)) - (forward-char 1)) - ;; The first Xref has to be the group this article - ;; really came for - this is the article nnkiboze - ;; will request when it is asked for the article. - (insert " " group ":" - (int-to-string (mail-header-number header)) " ") - (while (re-search-forward " [^ ]+:[0-9]+" nil t) - (goto-char (1+ (match-beginning 0))) - (insert prefix))))) - -(defun nnkiboze-nov-file-name (&optional suffix) - (concat (file-name-as-directory nnkiboze-directory) - (nnheader-translate-file-chars - (concat (nnkiboze-prefixed-name nnkiboze-current-group) - (or suffix ".nov"))))) - -(provide 'nnkiboze) - -;;; nnkiboze.el ends here diff --git a/lisp/nnlistserv.el b/lisp/nnlistserv.el deleted file mode 100644 index bb2b4a9..0000000 --- a/lisp/nnlistserv.el +++ /dev/null @@ -1,154 +0,0 @@ -;;; nnlistserv.el --- retrieving articles via web mailing list archives -;; Copyright (C) 1997,98 Free Software Foundation, Inc. - -;; Author: Lars Magne Ingebrigtsen -;; Keywords: news, mail - -;; This file is part of GNU Emacs. - -;; GNU Emacs is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 2, or (at your option) -;; any later version. - -;; GNU Emacs is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs; see the file COPYING. If not, write to the -;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. - -;;; Commentary: - -;; Note: You need to have `url' and `w3' installed for this -;; backend to work. - -;;; Code: - -(eval-when-compile (require 'cl)) - -(require 'nnoo) -(require 'nnweb) - -(nnoo-declare nnlistserv - nnweb) - -(defvoo nnlistserv-directory (nnheader-concat gnus-directory "nnlistserv/") - "Where nnlistserv will save its files." - nnweb-directory) - -(defvoo nnlistserv-name 'kk - "What search engine type is being used." - nnweb-type) - -(defvoo nnlistserv-type-definition - '((kk - (article . nnlistserv-kk-wash-article) - (map . nnlistserv-kk-create-mapping) - (search . nnlistserv-kk-search) - (address . "http://www.itk.ntnu.no/ansatte/Andresen_Trond/kk-f/%s/") - (pages "fra160396" "fra160796" "fra061196" "fra160197" - "fra090997" "fra040797" "fra130397" "nye") - (index . "date.html") - (identifier . nnlistserv-kk-identity))) - "Type-definition alist." - nnweb-type-definition) - -(defvoo nnlistserv-search nil - "Search string to feed to DejaNews." - nnweb-search) - -(defvoo nnlistserv-ephemeral-p nil - "Whether this nnlistserv server is ephemeral." - nnweb-ephemeral-p) - -;;; Internal variables - -;;; Interface functions - -(nnoo-define-basics nnlistserv) - -(nnoo-import nnlistserv - (nnweb)) - -;;; Internal functions - -;;; -;;; KK functions. -;;; - -(defun nnlistserv-kk-create-mapping () - "Perform the search and create an number-to-url alist." - (save-excursion - (set-buffer nnweb-buffer) - (let ((case-fold-search t) - (active (or (cadr (assoc nnweb-group nnweb-group-alist)) - (cons 1 0))) - (pages (nnweb-definition 'pages)) - map url page subject from ) - (while (setq page (pop pages)) - (erase-buffer) - (when (funcall (nnweb-definition 'search) page) - ;; Go through all the article hits on this page. - (goto-char (point-min)) - (nnweb-decode-entities) - (goto-char (point-min)) - (while (re-search-forward "^
  • *\\([^\\>]+\\) *<[^>]+>\\([^>]+\\)<" nil t) - (setq url (match-string 1) - subject (match-string 2) - from (match-string 3)) - (setq url (concat (format (nnweb-definition 'address) page) url)) - (unless (nnweb-get-hashtb url) - (push - (list - (incf (cdr active)) - (make-full-mail-header - (cdr active) subject from "" - (concat "<" (nnweb-identifier url) "@kk>") - nil 0 0 url)) - map) - (nnweb-set-hashtb (cadar map) (car map)) - (nnheader-message 5 "%s %s %s" (cdr active) (point) pages) - )))) - ;; Return the articles in the right order. - (setq nnweb-articles - (sort (nconc nnweb-articles map) 'car-less-than-car))))) - -(defun nnlistserv-kk-wash-article () - (let ((case-fold-search t) - (headers '(sent name email subject id)) - sent name email subject id) - (nnweb-decode-entities) - (while headers - (goto-char (point-min)) - (re-search-forward (format "" nil t) - (point-max)))) - (goto-char (point-min)) - (while (re-search-forward "<[^>]+>" nil t) - (replace-match "" t t))) - -;;; -;;; DejaNews functions. -;;; - -(defun nnweb-dejanews-create-mapping () - "Perform the search and create an number-to-url alist." - (save-excursion - (set-buffer nnweb-buffer) - (erase-buffer) - (when (funcall (nnweb-definition 'search) nnweb-search) - (let ((i 0) - (more t) - (case-fold-search t) - (active (or (cadr (assoc nnweb-group nnweb-group-alist)) - (cons 1 0))) - Subject (Score "0") Date Newsgroup Author - map url) - (while more - ;; Go through all the article hits on this page. - (goto-char (point-min)) - (nnweb-decode-entities) - (goto-char (point-min)) - (while (re-search-forward "^

    \n" nil t) - (narrow-to-region - (point) - (cond ((re-search-forward "^

    \n" nil t) - (match-beginning 0)) - ((search-forward "\n\n" nil t) - (point)) - (t - (point-max)))) - (goto-char (point-min)) - (looking-at ".*HREF=\"\\([^\"]+\\)\"\\(.*\\)") - (setq url (match-string 1)) - (let ((begin (point))) - (nnweb-remove-markup) - (goto-char begin) - (while (search-forward "\t" nil t) - (replace-match " ")) - (goto-char begin) - (end-of-line) - (setq Subject (buffer-substring begin (point))) - (if (re-search-forward - "^ Newsgroup: \\(.*\\)\n Posted on \\([0-9/]+\\) by \\(.*\\)$" nil t) - (setq Newsgroup (match-string 1) - Date (match-string 2) - Author (match-string 3)))) - (widen) - (incf i) - (unless (nnweb-get-hashtb url) - (push - (list - (incf (cdr active)) - (make-full-mail-header - (cdr active) Subject Author Date - (concat "<" (nnweb-identifier url) "@dejanews>") - nil 0 (string-to-int Score) url)) - map) - (nnweb-set-hashtb (cadar map) (car map)))) - ;; See whether there is a "Get next 20 hits" button here. - (if (or (not (re-search-forward - "HREF=\"\\([^\"]+\\)\"[<>b]+Next result" nil t)) - (>= i nnweb-max-hits)) - (setq more nil) - ;; Yup -- fetch it. - (setq more (match-string 1)) - (erase-buffer) - (url-insert-file-contents more))) - ;; Return the articles in the right order. - (setq nnweb-articles - (sort (nconc nnweb-articles map) 'car-less-than-car)))))) - -(defun nnweb-dejanews-wash-article () - (let ((case-fold-search t)) - (goto-char (point-min)) - (re-search-forward "

    " nil t)
    -    (delete-region (point-min) (point))
    -    (re-search-forward "
    " nil t) - (delete-region (point) (point-max)) - (nnweb-remove-markup) - (goto-char (point-min)) - (while (and (looking-at " *$") - (not (eobp))) - (gnus-delete-line)) - (while (looking-at "\\(^[^ ]+:\\) *") - (replace-match "\\1 " t) - (forward-line 1)) - (when (re-search-forward "\n\n+" nil t) - (replace-match "\n" t t)) - (goto-char (point-min)) - (when (search-forward "[More Headers]" nil t) - (replace-match "" t t)))) - -(defun nnweb-dejanews-search (search) - (nnweb-fetch-form - (nnweb-definition 'address) - `(("query" . ,search) - ("defaultOp" . "AND") - ("svcclass" . "dncurrent") - ("maxhits" . "100") - ("format" . "verbose2") - ("threaded" . "0") - ("showsort" . "date") - ("agesign" . "1") - ("ageweight" . "1"))) - t) - -(defun nnweb-dejanewsold-search (search) - (nnweb-fetch-form - (nnweb-definition 'address) - `(("query" . ,search) - ("defaultOp" . "AND") - ("svcclass" . "dnold") - ("maxhits" . "100") - ("format" . "verbose2") - ("threaded" . "0") - ("showsort" . "date") - ("agesign" . "1") - ("ageweight" . "1"))) - t) - -(defun nnweb-dejanews-identity (url) - "Return an unique identifier based on URL." - (if (string-match "recnum=\\([0-9]+\\)" url) - (match-string 1 url) - url)) - -;;; -;;; InReference -;;; - -(defun nnweb-reference-create-mapping () - "Perform the search and create an number-to-url alist." - (save-excursion - (set-buffer nnweb-buffer) - (erase-buffer) - (when (funcall (nnweb-definition 'search) nnweb-search) - (let ((i 0) - (more t) - (case-fold-search t) - (active (or (cadr (assoc nnweb-group nnweb-group-alist)) - (cons 1 0))) - Subject Score Date Newsgroups From Message-ID - map url) - (while more - ;; Go through all the article hits on this page. - (goto-char (point-min)) - (search-forward "
    " nil t) - (delete-region (point-min) (point)) - ;(nnweb-decode-entities) - (goto-char (point-min)) - (while (re-search-forward "^ +[0-9]+\\." nil t) - (narrow-to-region - (point) - (if (re-search-forward "^$" nil t) - (match-beginning 0) - (point-max))) - (goto-char (point-min)) - (when (looking-at ".*href=\"\\([^\"]+\\)\"") - (setq url (match-string 1))) - (nnweb-remove-markup) - (goto-char (point-min)) - (while (search-forward "\t" nil t) - (replace-match " ")) - (goto-char (point-min)) - (while (re-search-forward "^\\([^:]+\\): \\(.*\\)$" nil t) - (set (intern (match-string 1)) (match-string 2))) - (widen) - (search-forward "" nil t) - (incf i) - (unless (nnweb-get-hashtb url) - (push - (list - (incf (cdr active)) - (make-full-mail-header - (cdr active) (concat "(" Newsgroups ") " Subject) From Date - Message-ID - nil 0 (string-to-int Score) url)) - map) - (nnweb-set-hashtb (cadar map) (car map)))) - (setq more nil)) - ;; Return the articles in the right order. - (setq nnweb-articles - (sort (nconc nnweb-articles map) 'car-less-than-car)))))) - -(defun nnweb-reference-wash-article () - (let ((case-fold-search t)) - (goto-char (point-min)) - (re-search-forward "^
    " nil t) - (delete-region (point-min) (point)) - (search-forward "
    " nil t)
    -    (forward-line -1)
    -    (let ((body (point-marker)))
    -      (search-forward "
    " nil t) - (delete-region (point) (point-max)) - (nnweb-remove-markup) - (goto-char (point-min)) - (while (looking-at " *$") - (gnus-delete-line)) - (narrow-to-region (point-min) body) - (while (and (re-search-forward "^$" nil t) - (not (eobp))) - (gnus-delete-line)) - (goto-char (point-min)) - (while (looking-at "\\(^[^ ]+:\\) *") - (replace-match "\\1 " t) - (forward-line 1)) - (goto-char (point-min)) - (when (re-search-forward "^References:" nil t) - (narrow-to-region - (point) (if (re-search-forward "^$\\|^[^:]+:" nil t) - (match-beginning 0) - (point-max))) - (goto-char (point-min)) - (while (not (eobp)) - (unless (looking-at "References") - (insert "\t") - (forward-line 1))) - (goto-char (point-min)) - (while (search-forward "," nil t) - (replace-match " " t t))) - (widen) - (set-marker body nil)))) - -(defun nnweb-reference-search (search) - (url-insert-file-contents - (concat - (nnweb-definition 'address) - "?" - (nnweb-encode-www-form-urlencoded - `(("search" . "advanced") - ("querytext" . ,search) - ("subj" . "") - ("name" . "") - ("login" . "") - ("host" . "") - ("organization" . "") - ("groups" . "") - ("keywords" . "") - ("choice" . "Search") - ("startmonth" . "Jul") - ("startday" . "25") - ("startyear" . "1996") - ("endmonth" . "Aug") - ("endday" . "24") - ("endyear" . "1996") - ("mode" . "Quick") - ("verbosity" . "Verbose") - ("ranking" . "Relevance") - ("first" . "1") - ("last" . "25") - ("score" . "50"))))) - (setq buffer-file-name nil) - t) - -;;; -;;; Alta Vista -;;; - -(defun nnweb-altavista-create-mapping () - "Perform the search and create an number-to-url alist." - (save-excursion - (set-buffer nnweb-buffer) - (erase-buffer) - (let ((part 0)) - (when (funcall (nnweb-definition 'search) nnweb-search part) - (let ((i 0) - (more t) - (case-fold-search t) - (active (or (cadr (assoc nnweb-group nnweb-group-alist)) - (cons 1 0))) - subject date from id group - map url) - (while more - ;; Go through all the article hits on this page. - (goto-char (point-min)) - (search-forward "
    " nil t) - (delete-region (point-min) (match-beginning 0)) - (goto-char (point-min)) - (while (search-forward "
    " nil t) - (replace-match "\n")) - (nnweb-decode-entities) - (goto-char (point-min)) - (while (re-search-forward ".*href=\"\\([^\"]+\\)\">\\([^>]*\\)
    \\([^-]+\\)- \\([^<]+\\)<.*href=\"news:\\([^\"]+\\)\">.*\">\\(.+\\)

    " - nil t) - (setq url (match-string 1) - subject (match-string 2) - date (match-string 3) - group (match-string 4) - id (concat "<" (match-string 5) ">") - from (match-string 6)) - (incf i) - (unless (nnweb-get-hashtb url) - (push - (list - (incf (cdr active)) - (make-full-mail-header - (cdr active) (concat "(" group ") " subject) from date - id nil 0 0 url)) - map) - (nnweb-set-hashtb (cadar map) (car map)))) - ;; See if we want more. - (when (or (not nnweb-articles) - (>= i nnweb-max-hits) - (not (funcall (nnweb-definition 'search) - nnweb-search (incf part)))) - (setq more nil))) - ;; Return the articles in the right order. - (setq nnweb-articles - (sort (nconc nnweb-articles map) 'car-less-than-car))))))) - -(defun nnweb-altavista-wash-article () - (goto-char (point-min)) - (let ((case-fold-search t)) - (when (re-search-forward "^" nil t) - (delete-region (point-min) (match-beginning 0))) - (goto-char (point-min)) - (while (looking-at "\\([^ ]+\\) + +\\(.*\\)$") - (replace-match "\\1: \\2" t) - (forward-line 1)) - (when (re-search-backward "^References:" nil t) - (narrow-to-region (point) (progn (forward-line 1) (point))) - (goto-char (point-min)) - (while (re-search-forward "[0-9]+" nil t) - (replace-match "<\\1> " t))) - (widen) - (nnweb-remove-markup))) - -(defun nnweb-altavista-search (search &optional part) - (url-insert-file-contents - (concat - (nnweb-definition 'address) - "?" - (nnweb-encode-www-form-urlencoded - `(("pg" . "aq") - ("what" . "news") - ,@(when part `(("stq" . ,(int-to-string (* part 30))))) - ("fmt" . "d") - ("q" . ,search) - ("r" . "") - ("d0" . "") - ("d1" . ""))))) - (setq buffer-file-name nil) - t) - -(provide 'nnweb) - -;;; nnweb.el ends here diff --git a/lisp/parse-time.el b/lisp/parse-time.el deleted file mode 100644 index e25abbb..0000000 --- a/lisp/parse-time.el +++ /dev/null @@ -1,199 +0,0 @@ -;;; parse-time.el --- Parsing time strings - -;; Copyright (C) 1996 by Free Software Foundation, Inc. - -;; Author: Erik Naggum -;; Keywords: util - -;; This file is part of GNU Emacs. - -;; GNU Emacs is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 2, or (at your option) -;; any later version. - -;; GNU Emacs is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs; see the file COPYING. If not, write to -;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. - -;;; Commentary: - -;; With the introduction of the `encode-time', `decode-time', and -;; `format-time-string' functions, dealing with time became simpler in -;; Emacs. However, parsing time strings is still largely a matter of -;; heuristics and no common interface has been designed. - -;; `parse-time-string' parses a time in a string and returns a list of 9 -;; values, just like `decode-time', where unspecified elements in the -;; string are returned as nil. `encode-time' may be applied on these -;; valuse to obtain an internal time value. - -;;; Code: - -(eval-when-compile (require 'cl)) ;and ah ain't kiddin' 'bout it - -(put 'parse-time-syntax 'char-table-extra-slots 0) - -(defvar parse-time-syntax (make-char-table 'parse-time-syntax)) -(defvar parse-time-digits (make-char-table 'parse-time-syntax)) - -;; Byte-compiler warnings -(defvar elt) -(defvar val) - -(unless (aref parse-time-digits ?0) - (loop for i from ?0 to ?9 - do (set-char-table-range parse-time-digits i (- i ?0)))) - -(unless (aref parse-time-syntax ?0) - (loop for i from ?0 to ?9 - do (set-char-table-range parse-time-syntax i ?0)) - (loop for i from ?A to ?Z - do (set-char-table-range parse-time-syntax i ?A)) - (loop for i from ?a to ?z - do (set-char-table-range parse-time-syntax i ?a)) - (set-char-table-range parse-time-syntax ?+ 1) - (set-char-table-range parse-time-syntax ?- -1) - (set-char-table-range parse-time-syntax ?: ?d) - ) - -(defsubst digit-char-p (char) - (aref parse-time-digits char)) - -(defsubst parse-time-string-chars (char) - (aref parse-time-syntax char)) - -(put 'parse-error 'error-conditions '(parse-error error)) -(put 'parse-error 'error-message "Parsing error") - -(defsubst parse-integer (string &optional start end) - "[CL] Parse and return the integer in STRING, or nil if none." - (let ((integer 0) - (digit 0) - (index (or start 0)) - (end (or end (length string)))) - (when (< index end) - (let ((sign (aref string index))) - (if (or (eq sign ?+) (eq sign ?-)) - (setq sign (parse-time-string-chars sign) - index (1+ index)) - (setq sign 1)) - (while (and (< index end) - (setq digit (digit-char-p (aref string index)))) - (setq integer (+ (* integer 10) digit) - index (1+ index))) - (if (/= index end) - (signal 'parse-error `("not an integer" ,(substring string (or start 0) end))) - (* sign integer)))))) - -(defun parse-time-tokenize (string) - "Tokenize STRING into substrings." - (let ((start nil) - (end (length string)) - (all-digits nil) - (list ()) - (index 0) - (c nil)) - (while (< index end) - (while (and (< index end) ;skip invalid characters - (not (setq c (parse-time-string-chars (aref string index))))) - (incf index)) - (setq start index all-digits (eq c ?0)) - (while (and (< (incf index) end) ;scan valid characters - (setq c (parse-time-string-chars (aref string index)))) - (setq all-digits (and all-digits (eq c ?0)))) - (if (<= index end) - (push (if all-digits (parse-integer string start index) - (substring string start index)) - list))) - (nreverse list))) - -(defvar parse-time-months '(("Jan" . 1) ("Feb" . 2) ("Mar" . 3) - ("Apr" . 4) ("May" . 5) ("Jun" . 6) - ("Jul" . 7) ("Aug" . 8) ("Sep" . 9) - ("Oct" . 10) ("Nov" . 11) ("Dec" . 12))) -(defvar parse-time-weekdays '(("Sun" . 0) ("Mon" . 1) ("Tue" . 2) - ("Wed" . 3) ("Thu" . 4) ("Fri" . 5) ("Sat" . 6))) -(defvar parse-time-zoneinfo `(("Z" 0) ("UT" 0) ("GMT" 0) - ("PST" ,(* -8 3600)) ("PDT" ,(* -7 3600) t) - ("MST" ,(* -7 3600)) ("MDT" ,(* -6 3600) t) - ("CST" ,(* -6 3600)) ("CDT" ,(* -5 3600) t) - ("EST" ,(* -5 3600)) ("EDT" ,(* -4 3600) t)) - "(zoneinfo seconds-off daylight-savings-time-p)") - -(defvar parse-time-rules - `(((6) parse-time-weekdays) - ((3) (1 31)) - ((4) parse-time-months) - ((5) (1970 2038)) - ((2 1 0) - ,#'(lambda () (and (stringp elt) - (= (length elt) 8) - (= (aref elt 2) ?:) - (= (aref elt 5) ?:))) - [0 2] [3 5] [6 8]) - ((8 7) parse-time-zoneinfo - ,#'(lambda () (car val)) - ,#'(lambda () (cadr val))) - ((8) - ,#'(lambda () - (and (stringp elt) - (= 5 (length elt)) - (or (= (aref elt 0) ?+) (= (aref elt 0) ?-)))) - ,#'(lambda () (* 60 (+ (parse-integer elt 3 5) - (* 60 (parse-integer elt 1 3))) - (if (= (aref elt 0) ?-) -1 1)))) - ((5 4 3) - ,#'(lambda () (and (stringp elt) (= (length elt) 10) (= (aref elt 4) ?-) (= (aref elt 7) ?-))) - [0 4] [5 7] [8 10]) - ((2 1) - ,#'(lambda () (and (stringp elt) (= (length elt) 5) (= (aref elt 2) ?:))) - [0 2] [3 5]) - ((5) (70 99) ,#'(lambda () (+ 1900 elt)))) - "(slots predicate extractor...)") - -(defun parse-time-string (string) - "Parse the time-string STRING into (SEC MIN HOUR DAY MON YEAR DOW DST TZ). -The values are identical to those of `decode-time', but any values that are -unknown are returned as nil." - (let ((time (list nil nil nil nil nil nil nil nil nil nil)) - (temp (parse-time-tokenize string))) - (while temp - (let ((elt (pop temp)) - (rules parse-time-rules) - (exit nil)) - (while (and (not (null rules)) (not exit)) - (let* ((rule (pop rules)) - (slots (pop rule)) - (predicate (pop rule)) - (val)) - (if (and (not (nth (car slots) time)) ;not already set - (setq val (cond ((and (consp predicate) - (not (eq (car predicate) 'lambda))) - (and (numberp elt) - (<= (car predicate) elt) - (<= elt (cadr predicate)) - elt)) - ((symbolp predicate) - (cdr (assoc elt (symbol-value predicate)))) - ((funcall predicate))))) - (progn - (setq exit t) - (while slots - (let ((new-val (and rule - (let ((this (pop rule))) - (if (vectorp this) - (parse-integer elt (aref this 0) (aref this 1)) - (funcall this)))))) - (rplaca (nthcdr (pop slots) time) (or new-val val)))))))))) - time)) - -(provide 'parse-time) - -;;; parse-time.el ends here diff --git a/lisp/pop3-fma.el b/lisp/pop3-fma.el deleted file mode 100644 index e95c147..0000000 --- a/lisp/pop3-fma.el +++ /dev/null @@ -1,346 +0,0 @@ -;; pop3-fma.el.el --- POP3 for Multiple Account for Gnus. -;; Copyright (C) 1996,97,98 Free Software Foundation, Inc. , Tatsuya Ichikawa -;; Yasuo Okabe -;; Author: Tatsuya Ichikawa -;; Yasuo OKABE -;; Version: 1.11 -;; Keywords: mail , gnus , pop3 -;; -;; SPECIAL THANKS -;; Keiichi Suzuki -;; Katsumi Yamaoka -;; -;; This file is not part of GNU Emacs. - -;; GNU Emacs is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 2, or (at your option) -;; any later version. - -;; GNU Emacs is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs; see the file COPYING. If not, write to the -;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. - -;;; Commentary: -;; -;; Note. -;; -;; This file store pop3 password in variable "pop3-fma-password". -;; Please take care by yourself to treat pop3 password. -;; -;; How to use. -;; -;; add your .emacs following codes. -;; -;; (require 'pop3-fma) -;; (setq pop3-fma-spool-file-alist -;; '( -;; ("po:username0@mailhost0.your.domain0" pass) -;; ("po:username1@mailhost1.your.domain1" apop) -;; : -;; : -;; )) -;; -;; pass means normal authentication USER/PASS. -;; apop means authentication using APOP. -;; -;; When using apop , Please set pop3-fma-movemail-type 'lisp. -;; movemail.exe does not work on APOP protocol. -;; -;; Variables -;; -;; pop3-fma-spool-file-alist ... Spool file alist of POP3 protocol -;; pop3-fma-movemail-type ... Type of movemail program. -;; 'lisp or 'exe -;; 'lisp use pop3.el -;; 'exe use movemail -;; pop3-fma-movemail-arguments ... List of options of movemail program. -;; -;;; Code: - -(require 'cl) -(require 'custom) - -(unless (and (condition-case () - (require 'custom) - (file-error nil)) - (fboundp 'defgroup) - (fboundp 'defcustom)) - (require 'backquote) - (defmacro defgroup (&rest args)) - (defmacro defcustom (symbol value &optional doc &rest args) - (` (defvar (, symbol) (, value) (, doc)))) - ) - -(unless (and (fboundp 'pop3-fma-encode-string) - (fboundp 'pop3-fma-decode-string)) - (require 'mel-b) - (fset 'pop3-fma-encode-string 'base64-encode-string) - (fset 'pop3-fma-decode-string 'base64-decode-string)) - -(defgroup pop3-fma nil - "Multile POP3 account utility for Gnus." - :prefix "pop3-fma-" - :group 'mail - :group 'news) - -(defconst pop3-fma-version-number "1.11") -(defconst pop3-fma-codename -;; "Feel the wind" ; 0.10 -;; "My home town" ; 0.11 -;; "On the road" ; 0.12 -;; "Rock'n Roll city" ; 0.13 -;; "Money" ; 0.20 -;; "Still 19" ; 0.21 -;; "J boy" ; 1.00 -;; "Blood line" ; 1.10 - "Star ring" ; 0.xx -;; "Goodbye Game" ; 0.xx - ) -(defconst pop3-fma-version (format "Multiple POP3 account utiliy for Gnus v%s - \"%s\"" - pop3-fma-version-number - pop3-fma-codename)) - -(defcustom pop3-fma-spool-file-alist nil - "*Spool file to get mail using pop3 protocol. -You should specify this variable like - '( - (\"po:user1@mailhost1\" type) - (\"po:user2@mailhost2\" type) - ) -Type must be pass or apop." - :group 'pop3-fma - :type 'alist) - -(defcustom pop3-fma-local-spool-file-alist nil - "*List of Local spool file to get mail." - :group 'pop3-fma - :type 'alist) - -(defcustom pop3-fma-movemail-type 'lisp - "*Type of movemail program. -Lisp means `nnmail-movemail-program' is lisp function. - Exe means `nnmail-movemail-program' is external program. - Please do not use exe if you do not use Meadow." - :group 'pop3-fma - :type '(choice (const lisp) - (const exe))) - -(defcustom pop3-fma-movemail-arguments '("-pf") - "*Options for movemail." - :group 'pop3-fma - :type '(repeat (string :tag "Argument"))) - -;;; Internal variables. -(defvar pop3-fma-password nil - "*POP3 password , user , mailhost information for Gnus.") - -(defvar pop3-fma-movemail-program "movemail.exe" - "*External program name your movemail. -Please do not set this valiable non-nil if you do not use Meadow.") - -;; Temporary variable -(defvar hdr nil) -(defvar passwd nil) -(defvar str nil) -(defvar pop3-fma-movemail-options pop3-fma-movemail-arguments) -(defvar spool nil) -(defvar movemail-output-buffer " *movemail-out*") - -(defun pop3-fma-init-message-hook () - (add-hook 'message-send-hook 'pop3-fma-message-add-header)) - -(eval-after-load "message" - '(pop3-fma-init-message-hook)) - -(add-hook 'gnus-after-exiting-gnus-hook - '(lambda () (setq pop3-fma-password nil))) -(add-hook 'gnus-before-startup-hook 'pop3-fma-set-pop3-password) - -;; -;; -;; Gnus POP3 additional utility... -;; -(defun pop3-fma-movemail (inbox crashbox) - "Function to move mail from INBOX on a pop3 server to file CRASHBOX." - (if (string-match "^po:" inbox) - (progn - (let ((pop3-maildrop - (substring inbox (match-end (string-match "^po:" inbox)) - (- (match-end (string-match "^.*@" inbox)) 1))) - (pop3-mailhost - (substring inbox (match-end (string-match "^.*@" inbox)))) - (pop3-password - (pop3-fma-read-passwd (substring inbox (match-end (string-match "^.*@" inbox))))) - (pop3-authentication-scheme - (nth 1 (assoc inbox pop3-fma-spool-file-alist))) - (pop3-fma-movemail-type (pop3-fma-get-movemail-type inbox))) - (if (eq pop3-authentication-scheme 'pass) - (message "Checking new mail user %s at %s using USER/PASS ..." pop3-maildrop pop3-mailhost) - (message "Checking new mail user %s at %s using APOP ..." pop3-maildrop pop3-mailhost)) - (if (and (eq system-type 'windows-nt) - (eq pop3-fma-movemail-type 'exe)) - (progn - (setenv "MAILHOST" pop3-mailhost) - (if (and (not (memq pop3-password pop3-fma-movemail-arguments)) - (not (memq (concat "po:" pop3-maildrop) pop3-fma-movemail-arguments))) - (progn - (setq pop3-fma-movemail-arguments nil) - (setq pop3-fma-movemail-arguments - (append pop3-fma-movemail-options - (list - (concat "po:" pop3-maildrop) - crashbox - pop3-password))))) - (if (not (get-buffer movemail-output-buffer)) - (get-buffer-create movemail-output-buffer)) - (set-buffer movemail-output-buffer) - (erase-buffer) - (apply 'call-process (concat - exec-directory - pop3-fma-movemail-program) - nil movemail-output-buffer nil - pop3-fma-movemail-arguments) - (let ((string (buffer-string))) - (if (> (length string) 0) - (progn - (if (y-or-n-p - (concat (substring string 0 - (- (length string) 1)) - " continue ??")) - nil - nil))))) - (pop3-movemail crashbox)))) - (message "Checking new mail at %s ... " inbox) - (call-process (concat exec-directory pop3-fma-movemail-program) - nil - nil - nil - inbox - crashbox) - (message "Checking new mail at %s ... done." inbox))) -;; -;; -(defun pop3-fma-read-passwd (mailhost) - (setq passwd (nth 2 (assoc mailhost pop3-fma-password))) - (pop3-fma-decode-string passwd)) - -(setq pop3-read-passwd 'pop3-fma-read-passwd) -;; -;; Set multiple pop3 server's password -(defun pop3-fma-store-password (passwd) - (interactive - (list (pop3-fma-read-noecho - (format "POP Password for %s at %s: " pop3-maildrop pop3-mailhost) t))) - (if (not (assoc pop3-mailhost pop3-fma-password)) - (setq pop3-fma-password - (append pop3-fma-password - (list - (list - pop3-mailhost - pop3-maildrop - (pop3-fma-encode-string passwd))))) - (setcar (cdr (cdr (assoc pop3-mailhost pop3-fma-password))) - (pop3-fma-encode-string passwd))) - (message "POP password registered.") - (pop3-fma-encode-string passwd)) -;; -;;;###autoload -(defun pop3-fma-set-pop3-password() - (interactive) - (mapcar - (lambda (x) - (let ((pop3-maildrop - (substring (car x) (match-end (string-match "^po:" (car x))) - (- (match-end (string-match "^.*@" (car x))) 1))) - (pop3-mailhost - (substring (car x) (match-end (string-match "^.*@" (car x)))))) - (call-interactively 'pop3-fma-store-password))) - pop3-fma-spool-file-alist) - (setq nnmail-movemail-program 'pop3-fma-movemail) -;; (setq nnmail-spool-file pop3-fma-spool-file-alist)) - (setq nnmail-spool-file (append - pop3-fma-local-spool-file-alist - (mapcar - (lambda (spool) - (car spool)) - pop3-fma-spool-file-alist)))) -;; -(defun pop3-fma-read-noecho (prompt &optional stars) - "Read a single line of text from user without echoing, and return it. -Argument PROMPT ." - (let ((ans "") - (c 0) - (echo-keystrokes 0) - (cursor-in-echo-area t) - (log-message-max-size 0) - message-log-max done msg truncate) - (while (not done) - (if (or (not stars) (string-equal "" ans)) - (setq msg prompt) - (setq msg (concat prompt (make-string (length ans) ?*))) - (setq truncate - (1+ (- (length msg) (window-width (minibuffer-window))))) - (and (> truncate 0) - (setq msg (concat "$" (substring msg (1+ truncate)))))) - (message msg) - (setq c (read-char-exclusive)) - (cond ((= c ?\C-g) - (setq quit-flag t - done t)) - ((or (= c ?\r) (= c ?\n) (= c ?\e)) - (setq done t)) - ((= c ?\C-u) - (setq ans "")) - ((and (/= c ?\b) (/= c ?\177)) - (setq ans (concat ans (char-to-string c)))) - ((> (length ans) 0) - (setq ans (substring ans 0 -1))))) - (if quit-flag - (prog1 - (setq quit-flag nil) - (message "Quit") - (beep t)) - (message "") - ans))) -;; -;; -(defun pop3-fma-message-add-header () - (if (message-mail-p) - (pop3-fma-add-custom-header "X-Ya-Pop3:" pop3-fma-version))) - -;; -;; Add your custom header. -(defun pop3-fma-add-custom-header (header string) - (let ((delimline - (progn (goto-char (point-min)) - (re-search-forward - (concat "^" (regexp-quote mail-header-separator) "\n")) - (point-marker)))) - (goto-char (point-min)) - (or (re-search-forward (concat "^" header) delimline t) - (progn - (goto-char delimline) - (forward-line -1) - (beginning-of-line) - (setq hdr (concat header " ")) - (setq str (concat hdr string)) - (setq hdr (concat str "\n")) - (insert-string hdr))))) -;; -;; -(defun pop3-fma-get-movemail-type (inbox) - (if (eq (nth 1 (assoc inbox pop3-fma-spool-file-alist)) 'apop) - 'lisp - pop3-fma-movemail-type)) -;; -(provide 'pop3-fma) -;; -;; pop3-fma.el ends here. - diff --git a/lisp/pop3.el b/lisp/pop3.el deleted file mode 100644 index 1bfd8ec..0000000 --- a/lisp/pop3.el +++ /dev/null @@ -1,448 +0,0 @@ -;;; pop3.el --- Post Office Protocol (RFC 1460) interface - -;; Copyright (C) 1996,97,98 Free Software Foundation, Inc. - -;; Author: Richard L. Pieri -;; Keywords: mail, pop3 -;; Version: 1.3l+ - -;; This file is part of GNU Emacs. - -;; GNU Emacs is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 2, or (at your option) -;; any later version. - -;; GNU Emacs is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs; see the file COPYING. If not, write to the -;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. - -;;; Commentary: - -;; Most of the standard Post Office Protocol version 3 (RFC 1460) commands -;; are implemented. The LIST command has not been implemented due to lack -;; of actual usefulness. -;; The optional POP3 command TOP has not been implemented. - -;; This program was inspired by Kyle E. Jones's vm-pop program. - -;;; Code: - -(require 'mail-utils) -(provide 'pop3) - -(defconst pop3-version "1.3l+") - -(defvar pop3-maildrop (or (user-login-name) (getenv "LOGNAME") (getenv "USER") nil) - "*POP3 maildrop.") -(defvar pop3-mailhost (or (getenv "MAILHOST") nil) - "*POP3 mailhost.") -(defvar pop3-port 110 - "*POP3 port.") - -(defvar pop3-password-required t - "*Non-nil if a password is required when connecting to POP server.") -(defvar pop3-password nil - "*Password to use when connecting to POP server.") - -(defvar pop3-authentication-scheme 'pass - "*POP3 authentication scheme. -Defaults to 'pass, for the standard USER/PASS authentication. Other valid -values are 'apop.") - -(defvar pop3-timestamp nil - "Timestamp returned when initially connected to the POP server. -Used for APOP authentication.") - -(defvar pop3-movemail-file-coding-system 'binary - "Crashbox made by pop3-movemail with this coding system.") - -(defvar pop3-read-point nil) -(defvar pop3-debug nil) - -(defun pop3-movemail (&optional crashbox) - "Transfer contents of a maildrop to the specified CRASHBOX." - (or crashbox (setq crashbox (expand-file-name "~/.crashbox"))) - (let* ((process (pop3-open-server pop3-mailhost pop3-port)) - (crashbuf (get-buffer-create " *pop3-retr*")) - (n 1) - message-count - (pop3-password pop3-password) - ) - ;; for debugging only - (if pop3-debug (switch-to-buffer (process-buffer process))) - ;; query for password - (if (and pop3-password-required (not pop3-password)) - (setq pop3-password - (pop3-read-passwd (format "Password for %s: " pop3-maildrop)))) - (cond ((equal 'apop pop3-authentication-scheme) - (pop3-apop process pop3-maildrop)) - ((equal 'pass pop3-authentication-scheme) - (pop3-user process pop3-maildrop) - (pop3-pass process)) - (t (error "Invalid POP3 authentication scheme."))) - (setq message-count (car (pop3-stat process))) - (while (<= n message-count) - (message (format "Retrieving message %d of %d from %s..." - n message-count pop3-mailhost)) - (pop3-retr process n crashbuf) - (save-excursion - (set-buffer crashbuf) - (let ((coding-system-for-write pop3-movemail-file-coding-system)) - (append-to-file (point-min) (point-max) crashbox)) - (set-buffer (process-buffer process)) - (while (> (buffer-size) 5000) - (goto-char (point-min)) - (forward-line 50) - (delete-region (point-min) (point)))) - (pop3-dele process n) - (setq n (+ 1 n)) - (if pop3-debug (sit-for 1) (sit-for 0.1)) - ) - (pop3-quit process) - (kill-buffer crashbuf) - ) - ) - -(defun pop3-open-server (mailhost port) - "Open TCP connection to MAILHOST. -Returns the process associated with the connection." - (let ((process-buffer - (get-buffer-create (format "trace of POP session to %s" mailhost))) - (process) - (coding-system-for-read 'binary)) - (save-excursion - (set-buffer process-buffer) - (erase-buffer) - (setq pop3-read-point (point-min)) - ) - (setq process - (open-network-stream "POP" process-buffer mailhost port)) - (let ((response (pop3-read-response process t))) - (setq pop3-timestamp - (substring response (or (string-match "<" response) 0) - (+ 1 (or (string-match ">" response) -1))))) - process)) - -;; Support functions - -(defun pop3-process-filter (process output) - (save-excursion - (set-buffer (process-buffer process)) - (goto-char (point-max)) - (insert output))) - -(defun pop3-send-command (process command) - (set-buffer (process-buffer process)) - (goto-char (point-max)) -;; (if (= (aref command 0) ?P) -;; (insert "PASS \r\n") -;; (insert command "\r\n")) - (setq pop3-read-point (point)) - (goto-char (point-max)) - (process-send-string process command) - (process-send-string process "\r\n") - ) - -(defun pop3-read-response (process &optional return) - "Read the response from the server. -Return the response string if optional second argument is non-nil." - (let ((case-fold-search nil) - match-end) - (save-excursion - (set-buffer (process-buffer process)) - (goto-char pop3-read-point) - (while (not (search-forward "\r\n" nil t)) - (accept-process-output process 3) - (goto-char pop3-read-point)) - (setq match-end (point)) - (goto-char pop3-read-point) - (if (looking-at "-ERR") - (error (buffer-substring (point) (- match-end 2))) - (if (not (looking-at "+OK")) - (progn (setq pop3-read-point match-end) nil) - (setq pop3-read-point match-end) - (if return - (buffer-substring (point) match-end) - t) - ))))) - -(defun pop3-string-to-list (string &optional regexp) - "Chop up a string into a list." - (let ((list) - (regexp (or regexp " ")) - (string (if (string-match "\r" string) - (substring string 0 (match-beginning 0)) - string))) - (store-match-data nil) - (while string - (if (string-match regexp string) - (setq list (cons (substring string 0 (- (match-end 0) 1)) list) - string (substring string (match-end 0))) - (setq list (cons string list) - string nil))) - (nreverse list))) - -(defvar pop3-read-passwd nil) -(defun pop3-read-passwd (prompt) - (if (not pop3-read-passwd) - (if (load "passwd" t) - (setq pop3-read-passwd 'read-passwd) - (autoload 'ange-ftp-read-passwd "ange-ftp") - (setq pop3-read-passwd 'ange-ftp-read-passwd))) - (funcall pop3-read-passwd prompt)) - -(defun pop3-clean-region (start end) - (setq end (set-marker (make-marker) end)) - (save-excursion - (goto-char start) - (while (and (< (point) end) (search-forward "\r\n" end t)) - (replace-match "\n" t t)) - (goto-char start) - (while (and (< (point) end) (re-search-forward "^\\." end t)) - (replace-match "" t t) - (forward-char))) - (set-marker end nil)) - -(defun pop3-munge-message-separator (start end) - "Check to see if a message separator exists. If not, generate one." - (if (not (fboundp 'message-make-date)) (autoload 'message-make-date "message")) - (save-excursion - (save-restriction - (narrow-to-region start end) - (goto-char (point-min)) - (if (not (or (looking-at "From .?") ; Unix mail - (looking-at "\001\001\001\001\n") ; MMDF - (looking-at "BABYL OPTIONS:") ; Babyl - )) - (let ((from (mail-strip-quoted-names (mail-fetch-field "From"))) - (date (pop3-string-to-list (or (mail-fetch-field "Date") - (message-make-date)))) - (From_)) - ;; sample date formats I have seen - ;; Date: Tue, 9 Jul 1996 09:04:21 -0400 (EDT) - ;; Date: 08 Jul 1996 23:22:24 -0400 - ;; should be - ;; Tue Jul 9 09:04:21 1996 - (setq date - (cond ((string-match "[A-Z]" (nth 0 date)) - (format "%s %s %s %s %s" - (nth 0 date) (nth 2 date) (nth 1 date) - (nth 4 date) (nth 3 date))) - (t - ;; this really needs to be better but I don't feel - ;; like writing a date to day converter. - (format "Sun %s %s %s %s" - (nth 1 date) (nth 0 date) - (nth 3 date) (nth 2 date))) - )) - (setq From_ (format "\nFrom %s %s\n" from date)) - (while (string-match "," From_) - (setq From_ (concat (substring From_ 0 (match-beginning 0)) - (substring From_ (match-end 0))))) - (goto-char (point-min)) - (insert From_)))))) - -;; The Command Set - -;; AUTHORIZATION STATE - -(defun pop3-user (process user) - "Send USER information to POP3 server." - (pop3-send-command process (format "USER %s" user)) - (let ((response (pop3-read-response process t))) - (if (not (and response (string-match "+OK" response))) - (error (format "USER %s not valid." user))))) - -(defun pop3-pass (process) - "Send authentication information to the server." - (pop3-send-command process (format "PASS %s" pop3-password)) - (let ((response (pop3-read-response process t))) - (if (not (and response (string-match "+OK" response))) - (pop3-quit process)))) - -(defun pop3-apop (process user) - "Send alternate authentication information to the server." - (if (not (fboundp 'md5)) (autoload 'md5 "md5")) - (let ((hash (md5 (concat pop3-timestamp pop3-password)))) - (pop3-send-command process (format "APOP %s %s" user hash)) - (let ((response (pop3-read-response process t))) - (if (not (and response (string-match "+OK" response))) - (pop3-quit process))))) - -;; TRANSACTION STATE - -(defun pop3-stat (process) - "Return the number of messages in the maildrop and the maildrop's size." - (pop3-send-command process "STAT") - (let ((response (pop3-read-response process t))) - (list (string-to-int (nth 1 (pop3-string-to-list response))) - (string-to-int (nth 2 (pop3-string-to-list response)))) - )) - -(defun pop3-list (process &optional msg) - "Scan listing of available messages. -This function currently does nothing.") - -(defun pop3-retr (process msg crashbuf) - "Retrieve message-id MSG to buffer CRASHBUF." - (pop3-send-command process (format "RETR %s" msg)) - (pop3-read-response process) - (let ((start pop3-read-point) end) - (save-excursion - (set-buffer (process-buffer process)) - (while (not (re-search-forward "^\\.\r\n" nil t)) - (accept-process-output process 3) - ;; bill@att.com ... to save wear and tear on the heap - ;; uncommented because the condensed version below is a problem for - ;; some. - (if (> (buffer-size) 20000) (sleep-for 1)) - (if (> (buffer-size) 50000) (sleep-for 1)) - (if (> (buffer-size) 100000) (sleep-for 1)) - (if (> (buffer-size) 200000) (sleep-for 1)) - (if (> (buffer-size) 500000) (sleep-for 1)) - ;; bill@att.com - ;; condensed into: - ;; (sometimes causes problems for really large messages.) -; (if (> (buffer-size) 20000) (sleep-for (/ (buffer-size) 20000))) - (goto-char start)) - (setq pop3-read-point (point-marker)) -;; this code does not seem to work for some POP servers... -;; and I cannot figure out why not. -; (goto-char (match-beginning 0)) -; (backward-char 2) -; (if (not (looking-at "\r\n")) -; (insert "\r\n")) -; (re-search-forward "\\.\r\n") - (goto-char (match-beginning 0)) - (setq end (point-marker)) - (pop3-clean-region start end) - (pop3-munge-message-separator start end) - (save-excursion - (set-buffer crashbuf) - (erase-buffer)) - (copy-to-buffer crashbuf start end) - (delete-region start end) - ))) - -(defun pop3-dele (process msg) - "Mark message-id MSG as deleted." - (pop3-send-command process (format "DELE %s" msg)) - (pop3-read-response process)) - -(defun pop3-noop (process msg) - "No-operation." - (pop3-send-command process "NOOP") - (pop3-read-response process)) - -(defun pop3-last (process) - "Return highest accessed message-id number for the session." - (pop3-send-command process "LAST") - (let ((response (pop3-read-response process t))) - (string-to-int (nth 1 (pop3-string-to-list response))) - )) - -(defun pop3-rset (process) - "Remove all delete marks from current maildrop." - (pop3-send-command process "RSET") - (pop3-read-response process)) - -;; UPDATE - -(defun pop3-quit (process) - "Close connection to POP3 server. -Tell server to remove all messages marked as deleted, unlock the maildrop, -and close the connection." - (pop3-send-command process "QUIT") - (pop3-read-response process t) - (if process - (save-excursion - (set-buffer (process-buffer process)) - (goto-char (point-max)) - (delete-process process)))) - -;; Summary of POP3 (Post Office Protocol version 3) commands and responses - -;;; AUTHORIZATION STATE - -;; Initial TCP connection -;; Arguments: none -;; Restrictions: none -;; Possible responses: -;; +OK [POP3 server ready] - -;; USER name -;; Arguments: a server specific user-id (required) -;; Restrictions: authorization state [after unsuccessful USER or PASS -;; Possible responses: -;; +OK [valid user-id] -;; -ERR [invalid user-id] - -;; PASS string -;; Arguments: a server/user-id specific password (required) -;; Restrictions: authorization state, after successful USER -;; Possible responses: -;; +OK [maildrop locked and ready] -;; -ERR [invalid password] -;; -ERR [unable to lock maildrop] - -;;; TRANSACTION STATE - -;; STAT -;; Arguments: none -;; Restrictions: transaction state -;; Possible responses: -;; +OK nn mm [# of messages, size of maildrop] - -;; LIST [msg] -;; Arguments: a message-id (optional) -;; Restrictions: transaction state; msg must not be deleted -;; Possible responses: -;; +OK [scan listing follows] -;; -ERR [no such message] - -;; RETR msg -;; Arguments: a message-id (required) -;; Restrictions: transaction state; msg must not be deleted -;; Possible responses: -;; +OK [message contents follow] -;; -ERR [no such message] - -;; DELE msg -;; Arguments: a message-id (required) -;; Restrictions: transaction state; msg must not be deleted -;; Possible responses: -;; +OK [message deleted] -;; -ERR [no such message] - -;; NOOP -;; Arguments: none -;; Restrictions: transaction state -;; Possible responses: -;; +OK - -;; LAST -;; Arguments: none -;; Restrictions: transaction state -;; Possible responses: -;; +OK nn [highest numbered message accessed] - -;; RSET -;; Arguments: none -;; Restrictions: transaction state -;; Possible responses: -;; +OK [all delete marks removed] - -;;; UPDATE STATE - -;; QUIT -;; Arguments: none -;; Restrictions: none -;; Possible responses: -;; +OK [TCP connection closed] diff --git a/lisp/score-mode.el b/lisp/score-mode.el deleted file mode 100644 index 24c31f6..0000000 --- a/lisp/score-mode.el +++ /dev/null @@ -1,116 +0,0 @@ -;;; score-mode.el --- mode for editing Gnus score files -;; Copyright (C) 1996 Free Software Foundation, Inc. - -;; Author: Lars Magne Ingebrigtsen -;; Keywords: news, mail - -;; This file is part of GNU Emacs. - -;; GNU Emacs is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 2, or (at your option) -;; any later version. - -;; GNU Emacs is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs; see the file COPYING. If not, write to the -;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. - -;;; Commentary: - -;;; Code: - -(require 'easymenu) -(require 'timezone) -(eval-when-compile (require 'cl)) - -(defvar gnus-score-mode-hook nil - "*Hook run in score mode buffers.") - -(defvar gnus-score-menu-hook nil - "*Hook run after creating the score mode menu.") - -(defvar gnus-score-edit-exit-function nil - "Function run on exit from the score buffer.") - -(defvar gnus-score-mode-map nil) -(unless gnus-score-mode-map - (setq gnus-score-mode-map (copy-keymap emacs-lisp-mode-map)) - (define-key gnus-score-mode-map "\C-c\C-c" 'gnus-score-edit-exit) - (define-key gnus-score-mode-map "\C-c\C-d" 'gnus-score-edit-insert-date) - (define-key gnus-score-mode-map "\C-c\C-p" 'gnus-score-pretty-print)) - -(defvar score-mode-syntax-table - (let ((table (copy-syntax-table lisp-mode-syntax-table))) - (modify-syntax-entry ?| "w" table) - table) - "Syntax table used in score-mode buffers.") - -;;;###autoload -(defun gnus-score-mode () - "Mode for editing Gnus score files. -This mode is an extended emacs-lisp mode. - -\\{gnus-score-mode-map}" - (interactive) - (kill-all-local-variables) - (use-local-map gnus-score-mode-map) - (gnus-score-make-menu-bar) - (set-syntax-table score-mode-syntax-table) - (setq major-mode 'gnus-score-mode) - (setq mode-name "Score") - (lisp-mode-variables nil) - (make-local-variable 'gnus-score-edit-exit-function) - (run-hooks 'emacs-lisp-mode-hook 'gnus-score-mode-hook)) - -(defun gnus-score-make-menu-bar () - (unless (boundp 'gnus-score-menu) - (easy-menu-define - gnus-score-menu gnus-score-mode-map "" - '("Score" - ["Exit" gnus-score-edit-exit t] - ["Insert date" gnus-score-edit-insert-date t] - ["Format" gnus-score-pretty-print t])) - (run-hooks 'gnus-score-menu-hook))) - -(defun gnus-score-edit-insert-date () - "Insert date in numerical format." - (interactive) - (princ (gnus-score-day-number (current-time)) (current-buffer))) - -(defun gnus-score-pretty-print () - "Format the current score file." - (interactive) - (goto-char (point-min)) - (let ((form (read (current-buffer)))) - (erase-buffer) - (let ((emacs-lisp-mode-syntax-table score-mode-syntax-table)) - (pp form (current-buffer)))) - (goto-char (point-min))) - -(defun gnus-score-edit-exit () - "Stop editing the score file." - (interactive) - (unless (file-exists-p (file-name-directory (buffer-file-name))) - (make-directory (file-name-directory (buffer-file-name)) t)) - (save-buffer) - (bury-buffer (current-buffer)) - (let ((buf (current-buffer))) - (when gnus-score-edit-exit-function - (funcall gnus-score-edit-exit-function)) - (when (eq buf (current-buffer)) - (switch-to-buffer (other-buffer (current-buffer)))))) - -(defun gnus-score-day-number (time) - (let ((dat (decode-time time))) - (timezone-absolute-from-gregorian - (nth 4 dat) (nth 3 dat) (nth 5 dat)))) - -(provide 'score-mode) - -;;; score-mode.el ends here diff --git a/lisp/smiley.el b/lisp/smiley.el deleted file mode 100644 index e6c13f7..0000000 --- a/lisp/smiley.el +++ /dev/null @@ -1,318 +0,0 @@ -;;; smiley.el --- displaying smiley faces -;; Copyright (C) 1996,97,98 Free Software Foundation, Inc. - -;; Author: Wes Hardaker -;; Keywords: fun - -;; This file is part of GNU Emacs. - -;; GNU Emacs is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 2, or (at your option) -;; any later version. - -;; GNU Emacs is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs; see the file COPYING. If not, write to the -;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. - -;;; Commentary: - -;; -;; comments go here. -;; - -;;; Test smileys: :-] :-o :-) ;-) :-\ :-| :-d :-P 8-| :-( - -;; To use: -;; (require 'smiley) -;; (add-hook 'gnus-article-display-hook 'gnus-smiley-display t) - -;; The smilies were drawn by Joe Reiss . - -(require 'annotations) -(require 'messagexmas) -(require 'cl) -(require 'custom) - -(defgroup smiley nil - "Turn :-)'s into real images (XEmacs)." - :group 'gnus-visual) - -(defcustom smiley-data-directory (message-xmas-find-glyph-directory "smilies") - "*Location of the smiley faces files." - :type 'directory - :group 'smiley) - -;; Notice the subtle differences in the regular expressions in the -;; two alists below. - -(defcustom smiley-deformed-regexp-alist - '(("\\(\\^_?\\^;;;\\)\\W" 1 "WideFaceAse3.xbm") - ("\\(\\^_?\\^;;\\)\\W" 1 "WideFaceAse2.xbm") - ("\\(\\^_?\\^;\\)\\W" 1 "WideFaceAse1.xbm") - ("\\(\\^_?\\^\\)\\W" 1 "WideFaceSmile.xbm") - ("\\(;_;\\)\\W" 1 "WideFaceWeep.xbm") - ("\\(T_T\\)\\W" 1 "WideFaceWeep.xbm") - ("\\(:-*[<«]+\\)\\W" 1 "FaceAngry.xpm") - ("\\(:-+\\]+\\)\\W" 1 "FaceGoofy.xpm") - ("\\(:-*D\\)\\W" 1 "FaceGrinning.xpm") - ("\\(:-*[)>}»]+\\)\\W" 1 "FaceHappy.xpm") - ("\\(=[)>»]+\\)\\W" 1 "FaceHappy.xpm") - ("\\(:-*[/\\\"]\\)[^/]\\W" 1 "FaceIronic.xpm") - ("\\([8|]-*[|Oo%]\\)\\W" 1 "FaceKOed.xpm") - ("\\([:|]-*#+\\)\\W" 1 "FaceNyah.xpm") - ("\\(:-*[({]+\\)\\W" 1 "FaceSad.xpm") - ("\\(=[({]+\\)\\W" 1 "FaceSad.xpm") - ("\\(:-*[Oo\*]\\)\\W" 1 "FaceStartled.xpm") - ("\\(:-*|\\)\\W" 1 "FaceStraight.xpm") - ("\\(:-*p\\)\\W" 1 "FaceTalking.xpm") - ("\\(:-*d\\)\\W" 1 "FaceTasty.xpm") - ("\\(;-*[>)}»]+\\)\\W" 1 "FaceWinking.xpm") - ("\\(:-*[Vvµ]\\)\\W" 1 "FaceWry.xpm") - ("\\([:|]-*P\\)\\W" 1 "FaceYukky.xpm")) - "*Normal and deformed faces for smilies." - :type '(repeat (list regexp - (integer :tag "Match") - (string :tag "Image"))) - :group 'smiley) - -(defcustom smiley-nosey-regexp-alist - '(("\\(:-+[<«]+\\)\\W" 1 "FaceAngry.xpm") - ("\\(:-+\\]+\\)\\W" 1 "FaceGoofy.xpm") - ("\\(:-+D\\)\\W" 1 "FaceGrinning.xpm") - ("\\(:-+[}»]+\\)\\W" 1 "FaceHappy.xpm") - ("\\(:-*)+\\)\\W" 1 "FaceHappy.xpm") - ("\\(=[)>]+\\)\\W" 1 "FaceHappy.xpm") - ("\\(:-+[/\\\"]+\\)\\W" 1 "FaceIronic.xpm") - ("\\([8|]-+[|Oo%]\\)\\W" 1 "FaceKOed.xpm") - ("\\([:|]-+#+\\)\\W" 1 "FaceNyah.xpm") - ("\\(:-+[({]+\\)\\W" 1 "FaceSad.xpm") - ("\\(=[({]+\\)\\W" 1 "FaceSad.xpm") - ("\\(:-+[Oo\*]\\)\\W" 1 "FaceStartled.xpm") - ("\\(:-+|\\)\\W" 1 "FaceStraight.xpm") - ("\\(:-+p\\)\\W" 1 "FaceTalking.xpm") - ("\\(:-+d\\)\\W" 1 "FaceTasty.xpm") - ("\\(;-+[>)}»]+\\)\\W" 1 "FaceWinking.xpm") - ("\\(:-+[Vvµ]\\)\\W" 1 "FaceWry.xpm") - ("\\(][:8B]-[)>]\\)\\W" 1 "FaceDevilish.xpm") - ("\\([:|]-+P\\)\\W" 1 "FaceYukky.xpm")) - "*Smileys with noses. These get less false matches." - :type '(repeat (list regexp - (integer :tag "Match") - (string :tag "Image"))) - :group 'smiley) - -(defcustom smiley-regexp-alist smiley-deformed-regexp-alist - "*A list of regexps to map smilies to real images. -Defaults to the contents of `smiley-deformed-regexp-alist'. -An alternative is `smiley-nosey-regexp-alist' that matches less -aggressively. -If this is a symbol, take its value." - :type '(radio (variable-item smiley-deformed-regexp-alist) - (variable-item smiley-nosey-regexp-alist) - symbol - (repeat (list regexp - (integer :tag "Match") - (string :tag "Image")))) - :group 'smiley) - -(defcustom smiley-flesh-color "yellow" - "*Flesh color." - :type 'string - :group 'smiley) - -(defcustom smiley-features-color "black" - "*Features color." - :type 'string - :group 'smiley) - -(defcustom smiley-tongue-color "red" - "*Tongue color." - :type 'string - :group 'smiley) - -(defcustom smiley-circle-color "black" - "*Circle color." - :type 'string - :group 'smiley) - -(defcustom smiley-mouse-face 'highlight - "*Face used for mouse highlighting in the smiley buffer. - -Smiley buttons will be displayed in this face when the cursor is -above them." - :type 'face - :group 'smiley) - -(defvar smiley-glyph-cache nil) -(defvar smiley-running-xemacs (string-match "XEmacs" emacs-version)) - -(defvar smiley-map (make-sparse-keymap "smiley-keys") - "Keymap to toggle smiley states.") - -(define-key smiley-map [(button2)] 'smiley-toggle-extent) -(define-key smiley-map [(button3)] 'smiley-popup-menu) - -(defun smiley-popup-menu (e) - (interactive "e") - (popup-menu - `("Smilies" - ["Toggle This Smiley" (smiley-toggle-extent ,e) t] - ["Toggle All Smilies" (smiley-toggle-extents ,e) t]))) - -(defun smiley-create-glyph (smiley pixmap) - (and - smiley-running-xemacs - (or - (cdr-safe (assoc pixmap smiley-glyph-cache)) - (let* ((xpm-color-symbols - (and (featurep 'xpm) - (append `(("flesh" ,smiley-flesh-color) - ("features" ,smiley-features-color) - ("tongue" ,smiley-tongue-color)) - xpm-color-symbols))) - (glyph (make-glyph - (list - (cons 'x (expand-file-name pixmap smiley-data-directory)) - (cons 'tty smiley))))) - (setq smiley-glyph-cache (cons (cons pixmap glyph) smiley-glyph-cache)) - (set-glyph-face glyph 'default) - glyph)))) - -;;;###autoload -(defun smiley-region (beg end) - "Smilify the region between point and mark." - (interactive "r") - (smiley-buffer (current-buffer) beg end)) - -(defun smiley-toggle-extent (event) - "Toggle smiley at given point." - (interactive "e") - (let* ((ant (event-glyph-extent event)) - (pt (event-closest-point event)) - ext) - (if (annotationp ant) - (when (extentp (setq ext (extent-property ant 'smiley-extent))) - (set-extent-property ext 'invisible nil) - (hide-annotation ant)) - (when pt - (while (setq ext (extent-at pt (event-buffer event) nil ext 'at)) - (when (annotationp (setq ant - (extent-property ext 'smiley-annotation))) - (reveal-annotation ant) - (set-extent-property ext 'invisible t))))))) - -(defun smiley-toggle-extents (e) - (interactive "e") - (map-extents - '(lambda (e void) - (let (ant) - (if (annotationp (setq ant (extent-property e 'smiley-annotation))) - (progn - (if (eq (extent-property e 'invisible) nil) - (progn - (reveal-annotation ant) - (set-extent-property e 'invisible t) - ) - (hide-annotation ant) - (set-extent-property e 'invisible nil)))) - nil)) - (event-buffer e))) - -;;;###autoload -(defun smiley-buffer (&optional buffer st nd) - (interactive) - (when (featurep 'x) - (save-excursion - (when buffer - (set-buffer buffer)) - (let ((buffer-read-only nil) - (alist (if (symbolp smiley-regexp-alist) - (symbol-value smiley-regexp-alist) - smiley-regexp-alist)) - (case-fold-search nil) - entry regexp beg group file) - (map-extents - '(lambda (e void) - (when (or (extent-property e 'smiley-extent) - (extent-property e 'smiley-annotation)) - (delete-extent e))) - buffer st nd) - (goto-char (or st (point-min))) - (setq beg (point)) - ;; loop through alist - (while (setq entry (pop alist)) - (setq regexp (car entry) - group (cadr entry) - file (caddr entry)) - (goto-char beg) - (while (re-search-forward regexp nd t) - (let* ((start (match-beginning group)) - (end (match-end group)) - (glyph (smiley-create-glyph (buffer-substring start end) - file))) - (when glyph - (mapcar 'delete-annotation (annotations-at end)) - (let ((ext (make-extent start end)) - (ant (make-annotation glyph end 'text))) - ;; set text extent params - (set-extent-property ext 'end-open t) - (set-extent-property ext 'start-open t) - (set-extent-property ext 'invisible t) - (set-extent-property ext 'keymap smiley-map) - (set-extent-property ext 'mouse-face smiley-mouse-face) - (set-extent-property ext 'intangible t) - ;; set annotation params - (set-extent-property ant 'mouse-face smiley-mouse-face) - (set-extent-property ant 'keymap smiley-map) - ;; remember each other - (set-extent-property ant 'smiley-extent ext) - (set-extent-property ext 'smiley-annotation ant) - ;; Help - (set-extent-property ext 'help-echo - "button2 toggles smiley, button3 pops up menu") - (set-extent-property ant 'help-echo - "button2 toggles smiley, button3 pops up menu") - (set-extent-property ext 'balloon-help - "Mouse button2 - toggle smiley -Mouse button3 - menu") - (set-extent-property ant 'balloon-help - "Mouse button2 - toggle smiley -Mouse button3 - menu")) - (when (smiley-end-paren-p start end) - (make-annotation ")" end 'text)) - (goto-char end))))))))) - -(defun smiley-end-paren-p (start end) - "Try to guess whether the current smiley is an end-paren smiley." - (save-excursion - (goto-char start) - (when (and (re-search-backward "[()]" nil t) - (= (following-char) ?\() - (goto-char end) - (or (not (re-search-forward "[()]" nil t)) - (= (char-after (1- (point))) ?\())) - t))) - -(defvar gnus-article-buffer) -;;;###autoload -(defun gnus-smiley-display () - "Display \"smileys\" as small graphical icons." - (interactive) - (save-excursion - (set-buffer gnus-article-buffer) - (goto-char (point-min)) - ;; We skip the headers. - (unless (search-forward "\n\n" nil t) - (goto-char (point-max))) - (smiley-buffer (current-buffer) (point)))) - -(provide 'smiley) - -;;; smiley.el ends here diff --git a/lisp/smtp.el b/lisp/smtp.el deleted file mode 100644 index 3d2e113..0000000 --- a/lisp/smtp.el +++ /dev/null @@ -1,457 +0,0 @@ -;;; smtp.el --- basic functions to send mail with SMTP server - -;; Copyright (C) 1995, 1996, 1998 Free Software Foundation, Inc. - -;; Author: Tomoji Kagatani -;; ESMTP support: Simon Leinen -;; Keywords: SMTP, mail - -;; This file is part of GNU Emacs. - -;; GNU Emacs is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 2, or (at your option) -;; any later version. - -;; GNU Emacs is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs; see the file COPYING. If not, write to the -;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. - -;;; Code: - -(defgroup smtp nil - "SMTP protocol for sending mail." - :group 'mail) - -(defcustom smtp-default-server nil - "*Specify default SMTP server." - :type '(choice (const nil) string) - :group 'smtp) - -(defcustom smtp-server - (or (getenv "SMTPSERVER") smtp-default-server) - "*The name of the host running SMTP server." - :type '(choice (const nil) string) - :group 'smtp) - -(defcustom smtp-service 25 - "*SMTP service port number. smtp or 25 ." - :type 'integer - :group 'smtp) - -(defcustom smtp-local-domain nil - "*Local domain name without a host name. -If the function (system-name) returns the full internet address, -don't define this value." - :type '(choice (const nil) string) - :group 'smtp) - -(defcustom smtp-debug-info nil - "*smtp debug info printout. messages and process buffer." - :type 'boolean - :group 'smtp) - -(defcustom smtp-coding-system 'binary - "*Coding-system for SMTP output." - :type 'coding-system - :group 'smtp) - - -(defun smtp-fqdn () - (if smtp-local-domain - (concat (system-name) "." smtp-local-domain) - (system-name))) - -(defun smtp-via-smtp (recipient smtp-text-buffer) - (let ((process nil) - (host smtp-server) - (port smtp-service) - response-code - greeting - process-buffer - (supported-extensions '()) - (coding-system-for-read smtp-coding-system) - (coding-system-for-write smtp-coding-system)) - (unwind-protect - (catch 'done - ;; get or create the trace buffer - (setq process-buffer - (get-buffer-create - (format "*trace of SMTP session to %s*" host))) - - ;; clear the trace buffer of old output - (save-excursion - (set-buffer process-buffer) - (erase-buffer)) - - ;; open the connection to the server - (setq process (open-network-stream "SMTP" process-buffer host port)) - (and (null process) (throw 'done nil)) - - ;; set the send-filter - (set-process-filter process 'smtp-process-filter) - - (save-excursion - (set-buffer process-buffer) - (make-local-variable 'smtp-read-point) - (setq smtp-read-point (point-min)) - - (if (or (null (car (setq greeting (smtp-read-response process)))) - (not (integerp (car greeting))) - (>= (car greeting) 400)) - (throw 'done nil) - ) - - ;; EHLO - (smtp-send-command process (format "EHLO %s" (smtp-fqdn))) - - (if (or (null (car (setq response-code (smtp-read-response process)))) - (not (integerp (car response-code))) - (>= (car response-code) 400)) - (progn - ;; HELO - (smtp-send-command process (format "HELO %s" (smtp-fqdn))) - - (if (or (null (car (setq response-code (smtp-read-response process)))) - (not (integerp (car response-code))) - (>= (car response-code) 400)) - (throw 'done nil))) - (let ((extension-lines (cdr (cdr response-code)))) - (while extension-lines - (let ((name (intern (downcase (substring (car extension-lines) 4))))) - (and name - (cond ((memq name '(verb xvrb 8bitmime onex xone - expn size dsn etrn - help xusr)) - (setq supported-extensions - (cons name supported-extensions))) - (t (message "unknown extension %s" - name))))) - (setq extension-lines (cdr extension-lines))))) - - (if (or (member 'onex supported-extensions) - (member 'xone supported-extensions)) - (progn - (smtp-send-command process (format "ONEX")) - (if (or (null (car (setq response-code (smtp-read-response process)))) - (not (integerp (car response-code))) - (>= (car response-code) 400)) - (throw 'done nil)))) - - (if (and smtp-debug-info - (or (member 'verb supported-extensions) - (member 'xvrb supported-extensions))) - (progn - (smtp-send-command process (format "VERB")) - (if (or (null (car (setq response-code (smtp-read-response process)))) - (not (integerp (car response-code))) - (>= (car response-code) 400)) - (throw 'done nil)))) - - (if (member 'xusr supported-extensions) - (progn - (smtp-send-command process (format "XUSR")) - (if (or (null (car (setq response-code (smtp-read-response process)))) - (not (integerp (car response-code))) - (>= (car response-code) 400)) - (throw 'done nil)))) - - ;; MAIL FROM: - (let ((size-part - (if (member 'size supported-extensions) - (format " SIZE=%d" - (save-excursion - (set-buffer smtp-text-buffer) - ;; size estimate: - (+ (- (point-max) (point-min)) - ;; Add one byte for each change-of-line - ;; because or CR-LF representation: - (count-lines (point-min) (point-max)) - ;; For some reason, an empty line is - ;; added to the message. Maybe this - ;; is a bug, but it can't hurt to add - ;; those two bytes anyway: - 2))) - "")) - (body-part - (if (member '8bitmime supported-extensions) - ;; FIXME: - ;; Code should be added here that transforms - ;; the contents of the message buffer into - ;; something the receiving SMTP can handle. - ;; For a receiver that supports 8BITMIME, this - ;; may mean converting BINARY to BASE64, or - ;; adding Content-Transfer-Encoding and the - ;; other MIME headers. The code should also - ;; return an indication of what encoding the - ;; message buffer is now, i.e. ASCII or - ;; 8BITMIME. - (if nil - " BODY=8BITMIME" - "") - ""))) -; (smtp-send-command process (format "MAIL FROM:%s@%s" (user-login-name) (smtp-fqdn))) - (smtp-send-command process (format "MAIL FROM: <%s>%s%s" - user-mail-address - size-part - body-part)) - - (if (or (null (car (setq response-code (smtp-read-response process)))) - (not (integerp (car response-code))) - (>= (car response-code) 400)) - (throw 'done nil) - )) - - ;; RCPT TO: - (let ((n 0)) - (while (not (null (nth n recipient))) - (smtp-send-command process (format "RCPT TO: <%s>" (nth n recipient))) - (setq n (1+ n)) - - (setq response-code (smtp-read-response process)) - (if (or (null (car response-code)) - (not (integerp (car response-code))) - (>= (car response-code) 400)) - (throw 'done nil) - ) - )) - - ;; DATA - (smtp-send-command process "DATA") - - (if (or (null (car (setq response-code (smtp-read-response process)))) - (not (integerp (car response-code))) - (>= (car response-code) 400)) - (throw 'done nil) - ) - - ;; Mail contents - (smtp-send-data process smtp-text-buffer) - - ;;DATA end "." - (smtp-send-command process ".") - - (if (or (null (car (setq response-code (smtp-read-response process)))) - (not (integerp (car response-code))) - (>= (car response-code) 400)) - (throw 'done nil) - ) - - ;;QUIT -; (smtp-send-command process "QUIT") -; (and (null (car (smtp-read-response process))) -; (throw 'done nil)) - t )) - (if process - (save-excursion - (set-buffer (process-buffer process)) - (smtp-send-command process "QUIT") - (smtp-read-response process) - -; (if (or (null (car (setq response-code (smtp-read-response process)))) -; (not (integerp (car response-code))) -; (>= (car response-code) 400)) -; (throw 'done nil) -; ) - (delete-process process)))))) - -(defun smtp-process-filter (process output) - (save-excursion - (set-buffer (process-buffer process)) - (goto-char (point-max)) - (insert output))) - -(defun smtp-read-response (process) - (let ((case-fold-search nil) - (response-strings nil) - (response-continue t) - (return-value '(nil ())) - match-end) - - (while response-continue - (goto-char smtp-read-point) - (while (not (search-forward "\r\n" nil t)) - (accept-process-output process) - (goto-char smtp-read-point)) - - (setq match-end (point)) - (setq response-strings - (cons (buffer-substring smtp-read-point (- match-end 2)) - response-strings)) - - (goto-char smtp-read-point) - (if (looking-at "[0-9]+ ") - (let ((begin (match-beginning 0)) - (end (match-end 0))) - (if smtp-debug-info - (message "%s" (car response-strings))) - - (setq smtp-read-point match-end) - - ;; ignore lines that start with "0" - (if (looking-at "0[0-9]+ ") - nil - (setq response-continue nil) - (setq return-value - (cons (string-to-int - (buffer-substring begin end)) - (nreverse response-strings))))) - - (if (looking-at "[0-9]+-") - (progn (if smtp-debug-info - (message "%s" (car response-strings))) - (setq smtp-read-point match-end) - (setq response-continue t)) - (progn - (setq smtp-read-point match-end) - (setq response-continue nil) - (setq return-value - (cons nil (nreverse response-strings))) - ) - ))) - (setq smtp-read-point match-end) - return-value)) - -(defun smtp-send-command (process command) - (goto-char (point-max)) - (if (= (aref command 0) ?P) - (insert "PASS \r\n") - (insert command "\r\n")) - (setq smtp-read-point (point)) - (process-send-string process command) - (process-send-string process "\r\n")) - -(defun smtp-send-data-1 (process data) - (goto-char (point-max)) - - (if smtp-debug-info - (insert data "\r\n")) - - (setq smtp-read-point (point)) - ;; Escape "." at start of a line - (if (eq (string-to-char data) ?.) - (process-send-string process ".")) - (process-send-string process data) - (process-send-string process "\r\n") - ) - -(defun smtp-send-data (process buffer) - (let - ((data-continue t) - (sending-data nil) - this-line - this-line-end) - - (save-excursion - (set-buffer buffer) - (goto-char (point-min))) - - (while data-continue - (save-excursion - (set-buffer buffer) - (beginning-of-line) - (setq this-line (point)) - (end-of-line) - (setq this-line-end (point)) - (setq sending-data nil) - (setq sending-data (buffer-substring this-line this-line-end)) - (if (or (/= (forward-line 1) 0) (eobp)) - (setq data-continue nil))) - - (smtp-send-data-1 process sending-data) - ) - ) - ) - -(defun smtp-deduce-address-list (smtp-text-buffer header-start header-end) - "Get address list suitable for smtp RCPT TO:

    ." - (require 'mail-utils) ;; pick up mail-strip-quoted-names - (let ((case-fold-search t) - (simple-address-list "") - this-line - this-line-end - addr-regexp - (smtp-address-buffer (generate-new-buffer " *smtp-mail*"))) - (unwind-protect - (save-excursion - ;; - (set-buffer smtp-address-buffer) - (erase-buffer) - (insert-buffer-substring smtp-text-buffer - header-start header-end) - (goto-char (point-min)) - ;; RESENT-* fields should stop processing of regular fields. - (save-excursion - (if (re-search-forward "^RESENT-TO:" header-end t) - (setq addr-regexp - "^\\(RESENT-TO:\\|RESENT-CC:\\|RESENT-BCC:\\)") - (setq addr-regexp "^\\(TO:\\|CC:\\|BCC:\\)"))) - - (while (re-search-forward addr-regexp header-end t) - (replace-match "") - (setq this-line (match-beginning 0)) - (forward-line 1) - ;; get any continuation lines - (while (and (looking-at "^[ \t]+") (< (point) header-end)) - (forward-line 1)) - (setq this-line-end (point-marker)) - (setq simple-address-list - (concat simple-address-list " " - (mail-strip-quoted-names - (buffer-substring this-line this-line-end)))) - ) - (erase-buffer) - (insert-string " ") - (insert-string simple-address-list) - (insert-string "\n") - ;; newline --> blank - (subst-char-in-region (point-min) (point-max) 10 ? t) - ;; comma --> blank - (subst-char-in-region (point-min) (point-max) ?, ? t) - ;; tab --> blank - (subst-char-in-region (point-min) (point-max) 9 ? t) - - (goto-char (point-min)) - ;; tidyness in case hook is not robust when it looks at this - (while (re-search-forward "[ \t]+" header-end t) (replace-match " ")) - - (goto-char (point-min)) - (let (recipient-address-list) - (while (re-search-forward " \\([^ ]+\\) " (point-max) t) - (backward-char 1) - (setq recipient-address-list - (cons (buffer-substring (match-beginning 1) (match-end 1)) - recipient-address-list)) - ) - recipient-address-list) - ) - (kill-buffer smtp-address-buffer)) - )) - -(defun smtp-do-bcc (header-end) - "Delete BCC: and their continuation lines from the header area. -There may be multiple BCC: lines, and each may have arbitrarily -many continuation lines." - (let ((case-fold-search t)) - (save-excursion - (goto-char (point-min)) - ;; iterate over all BCC: lines - (while (re-search-forward "^BCC:" header-end t) - (delete-region (match-beginning 0) (progn (forward-line 1) (point))) - ;; get rid of any continuation lines - (while (and (looking-at "^[ \t].*\n") (< (point) header-end)) - (replace-match "")) - ) - ) ;; save-excursion - ) ;; let - ) - -(provide 'smtp) - -;;; smtp.el ends here diff --git a/lisp/smtpmail.el b/lisp/smtpmail.el deleted file mode 100644 index 77a5947..0000000 --- a/lisp/smtpmail.el +++ /dev/null @@ -1,285 +0,0 @@ -;;; smtpmail.el --- simple SMTP protocol (RFC 821) for sending mail - -;; Copyright (C) 1995, 1996 Free Software Foundation, Inc. - -;; Author: Tomoji Kagatani -;; Maintainer: Brian D. Carlstrom -;; ESMTP support: Simon Leinen -;; Keywords: mail - -;; This file is part of GNU Emacs. - -;; GNU Emacs is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 2, or (at your option) -;; any later version. - -;; GNU Emacs is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs; see the file COPYING. If not, write to the -;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. - -;;; Commentary: - -;; Send Mail to smtp host from smtpmail temp buffer. - -;; Please add these lines in your .emacs(_emacs). -;; -;;(setq send-mail-function 'smtpmail-send-it) -;;(setq smtp-default-server "YOUR SMTP HOST") -;;(setq smtp-service "smtp") -;;(setq smtp-local-domain "YOUR DOMAIN NAME") -;;(setq smtp-debug-info t) -;;(autoload 'smtpmail-send-it "smtpmail") -;;(setq user-full-name "YOUR NAME HERE") - -;; To queue mail, set smtpmail-queue-mail to t and use -;; smtpmail-send-queued-mail to send. - - -;;; Code: - -(require 'smtp) -(require 'sendmail) -(require 'time-stamp) - -;;; - -(defcustom smtpmail-queue-mail nil - "*Specify if mail is queued (if t) or sent immediately (if nil). -If queued, it is stored in the directory `smtpmail-queue-dir' -and sent with `smtpmail-send-queued-mail'." - :type 'boolean - :group 'smtp) - -(defcustom smtpmail-queue-dir "~/Mail/queued-mail/" - "*Directory where `smtpmail.el' stores queued mail." - :type 'directory - :group 'smtp) - -(defvar smtpmail-queue-index-file "index" - "File name of queued mail index, -This is relative to `smtpmail-queue-dir'.") - -(defvar smtpmail-queue-index (concat smtpmail-queue-dir - smtpmail-queue-index-file)) - -(defvar smtpmail-recipient-address-list nil) - - -;;; -;;; -;;; - -(defun smtpmail-send-it () - (require 'mail-utils) - (let ((errbuf (if mail-interactive - (generate-new-buffer " smtpmail errors") - 0)) - (tembuf (generate-new-buffer " smtpmail temp")) - (case-fold-search nil) - resend-to-addresses - delimline - (mailbuf (current-buffer))) - (unwind-protect - (save-excursion - (set-buffer tembuf) - (erase-buffer) - (insert-buffer-substring mailbuf) - (goto-char (point-max)) - ;; require one newline at the end. - (or (= (preceding-char) ?\n) - (insert ?\n)) - ;; Change header-delimiter to be what sendmail expects. - (goto-char (point-min)) - (re-search-forward - (concat "^" (regexp-quote mail-header-separator) "\n")) - (replace-match "\n") - (backward-char 1) - (setq delimline (point-marker)) -;; (sendmail-synch-aliases) - (if mail-aliases - (expand-mail-aliases (point-min) delimline)) - (goto-char (point-min)) - ;; ignore any blank lines in the header - (while (and (re-search-forward "\n\n\n*" delimline t) - (< (point) delimline)) - (replace-match "\n")) - (let ((case-fold-search t)) - (goto-char (point-min)) - (goto-char (point-min)) - (while (re-search-forward "^Resent-to:" delimline t) - (setq resend-to-addresses - (save-restriction - (narrow-to-region (point) - (save-excursion - (end-of-line) - (point))) - (append (mail-parse-comma-list) - resend-to-addresses)))) -;;; Apparently this causes a duplicate Sender. -;;; ;; If the From is different than current user, insert Sender. -;;; (goto-char (point-min)) -;;; (and (re-search-forward "^From:" delimline t) -;;; (progn -;;; (require 'mail-utils) -;;; (not (string-equal -;;; (mail-strip-quoted-names -;;; (save-restriction -;;; (narrow-to-region (point-min) delimline) -;;; (mail-fetch-field "From"))) -;;; (user-login-name)))) -;;; (progn -;;; (forward-line 1) -;;; (insert "Sender: " (user-login-name) "\n"))) - ;; Don't send out a blank subject line - (goto-char (point-min)) - (if (re-search-forward "^Subject:[ \t]*\n" delimline t) - (replace-match "")) - ;; Put the "From:" field in unless for some odd reason - ;; they put one in themselves. - (goto-char (point-min)) - (if (not (re-search-forward "^From:" delimline t)) - (let* ((login user-mail-address) - (fullname (user-full-name))) - (cond ((eq mail-from-style 'angles) - (insert "From: " fullname) - (let ((fullname-start (+ (point-min) 6)) - (fullname-end (point-marker))) - (goto-char fullname-start) - ;; Look for a character that cannot appear unquoted - ;; according to RFC 822. - (if (re-search-forward "[^- !#-'*+/-9=?A-Z^-~]" - fullname-end 1) - (progn - ;; Quote fullname, escaping specials. - (goto-char fullname-start) - (insert "\"") - (while (re-search-forward "[\"\\]" - fullname-end 1) - (replace-match "\\\\\\&" t)) - (insert "\"")))) - (insert " <" login ">\n")) - ((eq mail-from-style 'parens) - (insert "From: " login " (") - (let ((fullname-start (point))) - (insert fullname) - (let ((fullname-end (point-marker))) - (goto-char fullname-start) - ;; RFC 822 says \ and nonmatching parentheses - ;; must be escaped in comments. - ;; Escape every instance of ()\ ... - (while (re-search-forward "[()\\]" fullname-end 1) - (replace-match "\\\\\\&" t)) - ;; ... then undo escaping of matching parentheses, - ;; including matching nested parentheses. - (goto-char fullname-start) - (while (re-search-forward - "\\(\\=\\|[^\\]\\(\\\\\\\\\\)*\\)\\\\(\\(\\([^\\]\\|\\\\\\\\\\)*\\)\\\\)" - fullname-end 1) - (replace-match "\\1(\\3)" t) - (goto-char fullname-start)))) - (insert ")\n")) - ((null mail-from-style) - (insert "From: " login "\n"))))) - ;; Insert an extra newline if we need it to work around - ;; Sun's bug that swallows newlines. - (goto-char (1+ delimline)) - (if (eval mail-mailer-swallows-blank-line) - (newline)) - ;; Find and handle any FCC fields. - (goto-char (point-min)) - (if (re-search-forward "^FCC:" delimline t) - (mail-do-fcc delimline)) - (if mail-interactive - (save-excursion - (set-buffer errbuf) - (erase-buffer)))) - ;; - ;; - ;; - (setq smtpmail-recipient-address-list - (or resend-to-addresses - (smtp-deduce-address-list tembuf (point-min) delimline))) - - (smtp-do-bcc delimline) - ; Send or queue - (if (not smtpmail-queue-mail) - (if smtpmail-recipient-address-list - (if (not (smtp-via-smtp - smtpmail-recipient-address-list tembuf)) - (error "Sending failed; SMTP protocol error")) - (error "Sending failed; no recipients")) - (let* ((file-data (concat - smtpmail-queue-dir - (time-stamp-strftime - "%02y%02m%02d-%02H%02M%02S"))) - (file-elisp (concat file-data ".el")) - (buffer-data (create-file-buffer file-data)) - (buffer-elisp (create-file-buffer file-elisp)) - (buffer-scratch "*queue-mail*")) - (save-excursion - (set-buffer buffer-data) - (erase-buffer) - (insert-buffer tembuf) - (write-file file-data) - (set-buffer buffer-elisp) - (erase-buffer) - (insert (concat - "(setq smtpmail-recipient-address-list '" - (prin1-to-string smtpmail-recipient-address-list) - ")\n")) - (write-file file-elisp) - (set-buffer (generate-new-buffer buffer-scratch)) - (insert (concat file-data "\n")) - (append-to-file (point-min) - (point-max) - smtpmail-queue-index) - ) - (kill-buffer buffer-scratch) - (kill-buffer buffer-data) - (kill-buffer buffer-elisp)))) - (kill-buffer tembuf) - (if (bufferp errbuf) - (kill-buffer errbuf))))) - -(defun smtpmail-send-queued-mail () - "Send mail that was queued as a result of setting `smtpmail-queue-mail'." - (interactive) - ;;; Get index, get first mail, send it, get second mail, etc... - (let ((buffer-index (find-file-noselect smtpmail-queue-index)) - (file-msg "") - (tembuf nil)) - (save-excursion - (set-buffer buffer-index) - (beginning-of-buffer) - (while (not (eobp)) - (setq file-msg (buffer-substring (point) (save-excursion - (end-of-line) - (point)))) - (load file-msg) - (setq tembuf (find-file-noselect file-msg)) - (if smtpmail-recipient-address-list - (if (not (smtp-via-smtp smtpmail-recipient-address-list tembuf)) - (error "Sending failed; SMTP protocol error")) - (error "Sending failed; no recipients")) - (delete-file file-msg) - (delete-file (concat file-msg ".el")) - (kill-buffer tembuf) - (kill-line 1)) - (set-buffer buffer-index) - (save-buffer smtpmail-queue-index) - (kill-buffer buffer-index) - ))) - - -;;; - -(provide 'smtpmail) - -;;; smtpmail.el ends here diff --git a/make.bat b/make.bat deleted file mode 100755 index d183af9..0000000 --- a/make.bat +++ /dev/null @@ -1,57 +0,0 @@ -@echo off - -rem Written by David Charlap - -rem There are two catches, however. The emacs.bat batch file may not exist -rem in all distributions. It is part of the Voelker build of Emacs 19.34 -rem (http://www.cs.washington.edu/homes/voelker/ntemacs.html). If the user -rem installs Gnus with some other build, he may have to replace calls to -rem %1\emacs.bat with something else. -rem -rem Also, the emacs.bat file that Voelker ships does not accept more than 9 -rem parameters, so the attempts to compile the .texi files will fail. To -rem fix that (at least on NT. I don't know about Win95), the following -rem change should be made to emacs.bat: -rem -rem %emacs_dir%\bin\emacs.exe %1 %2 %3 %4 %5 %6 %7 %8 %9 -rem -rem should become -rem -rem %emacs_dir%\bin\emacs.exe %* -rem -rem which will allow the batch file to accept an unlimited number of -rem parameters. - -if "%1" == "" goto usage - -cd lisp -call %1\bin\emacs.bat -batch -q -no-site-file -l ./dgnushack.el -f dgnushack-compile -if not "%2" == "copy" goto info -copy *.el* %1\lisp - -:info -cd ..\texi -call %1\bin\emacs.bat -batch -q -no-site-file gnus.texi -l texinfmt -f texinfo-every-node-update -f texinfo-format-buffer -f save-buffer -call %1\bin\emacs.bat -batch -q -no-site-file message.texi -l texinfmt -f texinfo-every-node-update -f texinfo-format-buffer -f save-buffer -if not "%2" == "copy" goto done -copy gnus %1\info -copy gnus-?? %1\info -copy message %1\info - -:etc -cd ..\etc -copy gnus-tut.txt %1\etc - -:done -cd .. -goto end - -:usage -echo Usage: make ^ [copy] -echo. -echo where: ^ is the directory you installed emacs in -echo eg. d:\emacs\19.34 -echo copy indicates that the compiled files should be copied to your -echo emacs lisp, info, and etc directories - -:end diff --git a/mkinstalldirs b/mkinstalldirs deleted file mode 100644 index 31f90a0..0000000 --- a/mkinstalldirs +++ /dev/null @@ -1,40 +0,0 @@ -#! /bin/sh -# mkinstalldirs --- make directory hierarchy -# Author: Noah Friedman -# Created: 1993-05-16 -# Public domain - -# $Id: mkinstalldirs,v 1.8 1997/06/25 17:03:22 meyering Exp $ - -errstatus=0 - -for file -do - set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` - shift - - pathcomp= - for d - do - pathcomp="$pathcomp$d" - case "$pathcomp" in - -* ) pathcomp=./$pathcomp ;; - esac - - if test ! -d "$pathcomp"; then - echo "mkdir $pathcomp" 1>&2 - - mkdir "$pathcomp" || lasterr=$? - - if test ! -d "$pathcomp"; then - errstatus=$lasterr - fi - fi - - pathcomp="$pathcomp/" - done -done - -exit $errstatus - -# mkinstalldirs ends here diff --git a/texi/ChangeLog b/texi/ChangeLog deleted file mode 100644 index fd2879c..0000000 --- a/texi/ChangeLog +++ /dev/null @@ -1,1004 +0,0 @@ -1998-08-27 07:29:17 Lars Magne Ingebrigtsen - - * gnus.texi (Mail Folders): Addition. - -1998-08-25 08:06:28 Lars Magne Ingebrigtsen - - * gnus.texi (Posting Styles): Document this-is. - (Virtual Groups): Addition. - -1998-08-18 00:30:05 Lars Magne Ingebrigtsen - - * gnus.texi (Article Hiding): Addition. - -1998-08-16 14:53:45 Lars Magne Ingebrigtsen - - * gnus.texi (NNTP): Reinstated. - (Asynchronous Fetching): No header prefetch. - -1998-08-15 13:01:41 Lars Magne Ingebrigtsen - - * gnus.texi (Summary Score Commands): Change. - -1998-08-14 01:31:36 Simon Josefsson - - * gnus.texi (Posting Styles): New 'body style. - -1998-08-13 21:17:00 Lars Magne Ingebrigtsen - - * gnus.texi (Paging the Article): Addition. - -1998-08-13 00:13:47 Simon Josefsson - - * gnus.texi (Mail Group Commands): Typo. - -1998-08-12 21:28:09 Simon Josefsson - - * gnus.texi (Article Caching): gnus-cacheable-groups. - (Newest Features): remove gnus-cacheable-groups. - -1998-08-12 22:01:12 Lars Magne Ingebrigtsen - - * message.texi (Forwarding): Addition. - -1998-08-11 20:33:53 Justin Zaglio - - * gnus.texi (Group Maintenance): Fix. - -1998-08-11 11:44:20 Lars Magne Ingebrigtsen - - * gnus.texi (Group Maintenance): Fix. - -1998-08-10 08:59:25 Lars Magne Ingebrigtsen - - * gnus.texi (Article Highlighting): Addition. - (Article Fontisizing): Fix. - (Article Hiding): Change. - (Article Hiding): Fix. - -1998-08-09 15:32:24 Lars Magne Ingebrigtsen - - * gnus.texi (Hiding Headers): Fix. - (Article Hiding): Addition. - (Document Groups): Addition. - -1998-08-08 06:06:37 Lars Magne Ingebrigtsen - - * gnus.texi (Fancy Mail Splitting): Change. - -1998-08-06 02:12:04 Lars Magne Ingebrigtsen - - * gnus.texi: De-legalize. - - * message.texi: De-legalize. - - * gnus.texi (Summary Maneuvering): Fix. - -1998-07-21 17:51 Simon Josefsson - - * gnus.texi (Splitting Mail): junk is fancy splitting only - - * gnus.texi (Fancy Mail Splitting): warn about junk - -1998-07-27 02:28:33 Lars Magne Ingebrigtsen - - * gnus.texi (Topic Commands): Fix. - -1998-07-27 02:23:17 Robert Bihlmeyer - - * gnus.texi (Score Decays): Fix. - -Sun Jul 12 04:03:27 1998 Lars Magne Ingebrigtsen - - * gnus.texi (Home Score File): Addition. - -Fri Jul 10 04:26:23 1998 Lars Magne Ingebrigtsen - - * gnus.texi (NNTP): Addition. - -Sat Jul 4 14:24:29 1998 Lars Magne Ingebrigtsen - - * gnus.texi (Gnus Utility Functions): Addition. - -Thu Jul 2 11:37:51 1998 Lars Magne Ingebrigtsen - - * gnus.texi (Posting Styles): Ununcommented. - -Wed Jul 1 17:57:54 1998 Lars Magne Ingebrigtsen - - * gnus.texi (Topic Commands): Addition. - -Tue Jun 30 16:11:27 1998 Lars Magne Ingebrigtsen - - * gnus.texi (Topic Commands): Addition. - -Mon Jun 29 21:46:13 1998 Lars Magne Ingebrigtsen - - * gnus.texi (Article Keymap): Typo. - -Sun Jun 28 17:41:10 1998 Lars Magne Ingebrigtsen - - * gnus.texi (Formatting Fonts): Typo fix. - -Sat Jun 27 04:37:14 1998 Lars Magne Ingebrigtsen - - * gnus.texi (Mail-To-News Gateways): Addition. - (Mail-To-News Gateways): Typo. - -Fri Jun 26 13:33:00 1998 Yoshiki Hayashi - - * gnus.texi (Summary Buffer Lines): Typo fix. - -Fri Jun 26 05:53:22 1998 Lars Magne Ingebrigtsen - - * gnus.texi (Score File Format): Addition. - (Mode Line Formatting): New. - (Summary Buffer Mode Line): Addition. - -Thu Jun 25 11:24:14 1998 Lars Magne Ingebrigtsen - - * gnus.texi (Summary Score Commands): Deletia. - -Wed Jun 24 00:37:32 1998 Lars Magne Ingebrigtsen - - * gnus.texi (Auto Save): Addition. - (Mail-To-News Gateways): Addition. - (NNTP): Addition. - -Wed Jun 3 03:30:47 1998 Lars Magne Ingebrigtsen - - * message.texi (Message Headers): Addition. - - * gnus.texi (Compatibility): Addition. - -Tue May 19 02:44:31 1998 Mike Pullen - - * gnus.texi.orig: Typo fixes. - -Wed Apr 29 21:52:28 1998 Lars Magne Ingebrigtsen - - * gnus.texi (Key Index): Untabified. - (Group Parameters): Fix. - -Sun Apr 26 15:32:45 1998 Lars Magne Ingebrigtsen - - * gnus.texi (Summary Post Commands): Ref to Message. - - * message.texi (Various Message Variables): Deletia. - -Fri Apr 24 16:00:40 1998 Lars Magne Ingebrigtsen - - * gnus.texi (Unread Articles): Typo. - (Summary Buffer Lines): Fix. - (Foreign Groups): Addition. - (Posting Server): Addition. - -Sat Mar 28 08:57:46 1998 Lars Magne Ingebrigtsen - - * gnus.texi (Example Methods): Addition. - -Thu Mar 26 15:47:54 1998 Lars Magne Ingebrigtsen - - * gnus.texi (Limiting): Mention `/ *'. - -Thu Mar 19 13:02:20 1998 Lars Magne Ingebrigtsen - - * gnus.texi (NNTP): Addition. - Removed spurious white space. - -Fri Mar 13 21:05:47 1998 Lars Magne Ingebrigtsen - - * gnus.texi (Quassia Gnus): Fix. - (Agent Expiry): Addition. - -Sun Mar 8 13:56:37 1998 James Troup - - * gnus.texi (Group Highlighting): Removed old example. - -Sun Mar 8 00:19:24 1998 Lars Magne Ingebrigtsen - - * gnus.texi (Group Info): Fix ".". - -Sat Mar 7 17:09:49 1998 Lars Magne Ingebrigtsen - - * gnus.texi: Took direntries out again, since makeinfo doesn't - understand them. - (Agent Expiry): New. - (Quassia Gnus): New. - -Sat Mar 7 16:14:10 1998 Dan Christensen - - * gnus.texi (Group Parameters): Mention add-to-list. - -Sat Feb 28 14:21:12 1998 Lars Magne Ingebrigtsen - - * gnus.texi (NNTP): Addition. - -1998-03-01 Kim-Minh Kaplan - - * gnus.texi (Easy Picons): Removed references to - `gnus-group-display-picons'. - (Hard Picons): Ditto. - -1998-03-01 Kim-Minh Kaplan - - * gnus.texi (Easy Picons): Removed references to - `gnus-group-display-picons'. - (Hard Picons): Ditto. - -Mon Feb 23 18:05:09 1998 Lars Magne Ingebrigtsen - - * gnus.texi: Direntry not handled by Emacs 19.34. - -1998-02-21 SL Baur - - * gnus.texi: Add a direntry field. - * message.texi: Ditto. (Data taken from Emacs 20.2 info/dir). - -Sun Feb 22 03:24:43 1998 Lars Magne Ingebrigtsen - - * gnus.texi (Score File Format): Addition. - -1998-02-18 Jason R Mastaler - - * gnus.texi: Corrected typo. - -Thu Feb 19 02:20:29 1998 Francois Felix Ingrand - - * gnus.texi (Sorting): Fix order of args. - -Sun Feb 15 23:04:02 1998 Lars Magne Ingebrigtsen - - * gnus.texi (NNTP): Change. - -Sat Feb 14 17:46:33 1998 Lars Magne Ingebrigtsen - - * gnus.texi (Virtual Groups): Fix. - (NNTP): Addition. - (Really Various Summary Commands): Addition. - -Fri Feb 13 18:23:19 1998 Lars Magne Ingebrigtsen - - * gnus.texi (Mail Group Commands): Typo. - (NNTP): Addition. - (Mail and Procmail): Addition. - -Mon Feb 9 16:30:30 1998 Lars Magne Ingebrigtsen - - * gnus.texi (Article Date): Addition. - -Sun Feb 8 16:28:35 1998 Lars Magne Ingebrigtsen - - * gnus.texi (Newest Features): Addition. - -Mon Feb 2 19:21:43 1998 Lars Magne Ingebrigtsen - - * gnus.texi (Agent Variables): Addition. - -Sun Feb 1 18:08:45 1998 Lars Magne Ingebrigtsen - - * gnus.texi (Using MIME): Addition. - -Tue Jan 6 07:22:41 1998 Lars Magne Ingebrigtsen - - * gnus.texi (Batching Agents): New. - -1998-01-04 Christoph Wedler - - * gnus.texi (Newest Features): Delete spaces after @end example. - In XEmacs, `texinfo-format-buffer' would bug out. - -Sun Jan 4 12:04:45 1998 Lars Magne Ingebrigtsen - - * gnus.texi (Conformity): Removed GNKSA. - -Sun Dec 14 11:06:23 1997 Lars Magne Ingebrigtsen - - * gnus.texi (Adaptive Scoring): Addition. - -1997-11-26 SL Baur - - * message.texi (Insertion): Fix typo. - (Responses): Ditto. - (Reply): Ditto. - -Wed Nov 26 12:57:00 1997 Lars Magne Ingebrigtsen - - * message.texi (Insertion): Addition. - -Wed Nov 26 12:55:15 1997 Hallvard B. Furuseth - - * message.texi (Insertion): Addition. - -Wed Nov 26 12:36:08 1997 Lars Magne Ingebrigtsen - - * message.texi (Responses): New. - (Appendices): New. - - * gnus.texi (Group Info): Fix. - -Tue Nov 25 17:53:55 1997 Lars Magne Ingebrigtsen - - * gnus.texi (Article Date): Addition. - -Mon Nov 24 16:01:20 1997 Lars Magne Ingebrigtsen - - * gnus.texi (Faces & Fonts): New. - -Mon Oct 13 00:08:06 1997 Lars Magne Ingebrigtsen - - * gnus.texi (Agent Commands): Addition. - -Sun Oct 12 16:50:23 1997 Lars Magne Ingebrigtsen - - * gnus.texi (Article Washing): Addition. - (Group Highlighting): New. - (Canceling and Superseding): Addition. - -Wed Oct 1 18:37:55 1997 Lars Magne Ingebrigtsen - - * gnus.texi (Startup Files): Addition. - -Sat Sep 27 09:37:17 1997 Lars Magne Ingebrigtsen - - * message.texi (Sending Variables): Fix. - - * gnus.texi (Choosing Commands): Addition. - -Sat Sep 27 05:56:44 1997 Hallvard B. Furuseth - - * gnus.texi: Various fixes. - -Sat Sep 27 04:24:41 1997 Lars Magne Ingebrigtsen - - * message.texi (Various Commands): Addition. - -Wed Sep 24 02:38:21 1997 Lars Magne Ingebrigtsen - - * gnus.texi (Example Setup): Wrong info. - (SOUP Groups): Addition. - (Contributors): Addition. - -1997-09-22 SL Baur - - * gnus.texi (Finding the Parent): Fix typo. - (NoCeM): Fix typos. - -Tue Sep 23 07:05:48 1997 Lars Magne Ingebrigtsen - - * gnus.texi (NoCeM): Addition. - (Finding the Parent): Addition. - -Mon Sep 22 06:13:00 1997 Lars Magne Ingebrigtsen - - * gnus.texi (Filling In Threads): Addition. - (Finding the Parent): Addition. - -Sun Sep 21 04:35:56 1997 Lars Magne Ingebrigtsen - - * gnus.texi (NNTP): Addition. - (Hiding Headers): Addition. - (Symbolic Prefixes): New. - (Extended Interactive): New. - (Summary Score Commands): Addition. - -Sat Sep 20 20:53:43 1997 Lars Magne Ingebrigtsen - - * gnus.texi (Startup Variables): Addition. - -1997-09-16 SL Baur - - * gnus.texi: Correct typo. - -Wed Sep 17 02:32:56 1997 Lars Magne Ingebrigtsen - - * gnus.texi (Customizing Threading): Broken up into five nodes. - (Article Washing): Addition. - - * message.texi (Various Commands): Add. - -Tue Sep 16 04:04:03 1997 Lars Magne Ingebrigtsen - - * gnus.texi (Example Setup): New. - -Mon Sep 15 23:10:05 1997 Lars Magne Ingebrigtsen - - * gnus.texi (Customizing Threading): Addition. - -Sun Sep 14 21:59:07 1997 Lars Magne Ingebrigtsen - - * gnus.texi (Outgoing Messages): New. - (Score File Format): Note. - (Subscription Methods): Fix. - (Starting Up): Fix. - (Threading): Add. - -Sat Jul 19 23:02:03 1997 Lars Magne Ingebrigtsen - - * gnus.texi (Followups To Yourself): \\(_-_\\)? - -Sat Jul 12 16:29:35 1997 Lars Magne Ingebrigtsen - - * gnus.texi (Picon Configuration): Moved Picons to under XEmacs. - (Smileys): New section. - -Fri Jul 11 11:58:20 1997 Lars Magne Ingebrigtsen - - * gnus.texi (NNTP): Addition. - -Tue Jun 17 23:52:17 1997 Justin Sheehy - - * gnus.texi (Group Parameters): Addition. - -Sun May 25 14:40:17 1997 Lars Magne Ingebrigtsen - - * gnus.texi (Expiring Mail): Addition. - -Sat May 24 05:26:17 1997 Lars Magne Ingebrigtsen - - * gnus.texi (Score File Format): Update. - -Tue May 20 21:56:03 1997 Lars Magne Ingebrigtsen - - * gnus.texi (Document Server Internals): Typo. - -Sun May 18 05:59:24 1997 Lars Magne Ingebrigtsen - - * gnus.texi (Topic Commands): Addition. - -Sun May 11 20:09:24 1997 Lars Magne Ingebrigtsen - - * gnus.texi (Article Hiding): Change. - -Thu May 8 23:48:36 1997 James Troup - - * gnus.texi (Saving Articles): Typo. - -Wed May 7 19:00:48 1997 Lars Magne Ingebrigtsen - - * gnus.texi (Saving Articles): Addition. - -Wed May 7 19:00:43 1997 Mark Boyns - - * gnus.texi (Saving Articles): Addition. - -Thu May 1 14:06:57 1997 Lars Magne Ingebrigtsen - - * gnus.texi (Score File Format): Fix. - -Sun Apr 27 11:11:43 1997 Lars Magne Ingebrigtsen - - * gnus.texi (NNTP): Addition. - -Sat Apr 12 16:51:32 1997 Robert Bihlmeyer - - * gnus.texi (Thwarting Email Spam): Addition. - -Tue Apr 15 16:11:38 1997 Lars Magne Ingebrigtsen - - * message.texi (Various Message Variables): Addition. - - * gnus.texi (Thwarting Email Spam): Addition. - -Sat Apr 12 00:26:47 1997 Francois Felix Ingrand - - * gnus.texi (NoCeM): Addition. - -Thu Apr 10 21:25:14 1997 Hrvoje Niksic - - * gnus.texi (Emacs/XEmacs Code): Addition. - -Thu Apr 10 20:45:47 1997 Lars Magne Ingebrigtsen - - * gnus.texi (Group Information): Fix. - -Wed Apr 2 11:48:44 1997 Lars Magne Ingebrigtsen - - * gnus.texi (Sorting): Use total score. - -Tue Apr 1 11:44:57 1997 Lars Magne Ingebrigtsen - - * gnus.texi (Subscription Methods): Addition. - (Group Info): Addition. - (Gnus Utility Functions): New. - (Thwarting Email Spam): Addition. - -Mon Mar 31 16:15:54 1997 Lars Magne Ingebrigtsen - - * message.texi (Various Message Variables): Addition. - -Sun Mar 23 02:16:19 1997 Lars Magne Ingebrigtsen - - * gnus.texi (Thwarting Email Spam): New. - (Unavailable Servers): Fix. - -Wed Mar 19 15:45:17 1997 Lars Magne Ingebrigtsen - - * gnus.texi (Various Summary Stuff): Addition. - (Mail Backend Variables): Addition. - -Tue Mar 18 14:43:32 1997 Lars Magne Ingebrigtsen - - * gnus.texi (Article Washing): Not addition. - -Mon Mar 17 16:15:54 1997 Philippe Schnoebelen - - * Makefile (install): Install properly. - -Fri Mar 14 21:00:33 1997 Lars Magne Ingebrigtsen - - * gnus.texi (Group Parameters): Addition. - (Expiring Mail): Addition. - -Wed Mar 12 06:57:14 1997 Lars Magne Ingebrigtsen - - * gnus.texi (Various Various): Addition. - -Sat Mar 8 03:41:47 1997 Lars Magne Ingebrigtsen - - * gnus.texi (Group Parameters): Added example. - (Duplicates): Fix. - -Fri Mar 7 10:49:43 1997 Lars Magne Ingebrigtsen - - * Makefile: New "install" target. - -Thu Mar 6 08:01:37 1997 Lars Magne Ingebrigtsen - - * gnus.texi (Mail and Procmail): Fix. - -Sun Mar 2 02:08:40 1997 Lars Magne Ingebrigtsen - - * gnus.texi (Startup Files): Addition. - (Score File Format): Fix. - -Fri Feb 28 23:23:31 1997 Lars Magne Ingebrigtsen - - * gnus.texi (Archived Messages): Clarify. - (Fuzzy Matching): New. - -Mon Feb 24 23:41:57 1997 Lars Magne Ingebrigtsen - - * message.texi (Compatibility): New. - -Thu Feb 20 03:29:17 1997 Lars Magne Ingebrigtsen - - * gnus.texi (Foreign Groups): Addition. - -Wed Feb 19 02:57:51 1997 Lars Magne Ingebrigtsen - - * gnus.texi (Server Variables): New. - -Sun Feb 16 15:43:34 1997 Lars Magne Ingebrigtsen - - * gnus.texi (Mail Backend Variables): Fix. - - * message.texi (Various Message Variables): Addition. - -Mon Feb 10 07:18:16 1997 Lars Magne Ingebrigtsen - - * gnus.texi (Article Commands): Addition. - -Mon Feb 3 19:59:10 1997 Paul Franklin - - * gnus-group.el (gnus-group-edit-group): Allow editing of bad - groups. - -Wed Feb 5 02:00:46 1997 Lars Magne Ingebrigtsen - - * message.texi (Mail Variables): Change. - -Tue Feb 4 02:33:31 1997 Lars Magne Ingebrigtsen - - * message.texi (Mail Aliases): New. - - * gnus.texi (Splitting Mail): Addition. - -Mon Feb 3 07:31:47 1997 Lars Magne Ingebrigtsen - - * gnus.texi (Mode Lines): Addition. - -Mon Jan 27 17:51:29 1997 Lars Magne Ingebrigtsen - - * gnus.texi (Highlighting and Menus): Removed - `gnus-display-type'. - -Sat Jan 25 08:09:30 1997 Lars Magne Ingebrigtsen - - * gnus.texi (The Active File): Addition. - -Fri Jan 24 05:07:28 1997 Lars Magne Ingebrigtsen - - * gnus.texi (Summary Mail Commands): Addition. - (Required Backend Functions): Deletia. - (Article Washing): Addition. - (Summary Mail Commands): Addition. - -Mon Jan 20 22:19:40 1997 Lars Magne Ingebrigtsen - - * gnus.texi (Followups To Yourself): Fix. - -Fri Jan 17 00:55:51 1997 Lars Magne Ingebrigtsen - - * gnus.texi (NoCeM): Update. - -Wed Jan 15 02:23:03 1997 Lars Magne Ingebrigtsen - - * gnus.texi (Mail Group Commands): Fix. - -Tue Jan 7 09:36:36 1997 Lars Magne Ingebrigtsen - - * gnus.texi (Summary Buffer Lines): Correction. - -Mon Jan 6 22:49:12 1997 Lars Magne Ingebrigtsen - - * gnus.texi (NoCeM): Addition. - -Fri Jan 3 18:13:02 1997 Lars Magne Ingebrigtsen - - * message.texi (Various Commands): Addition. - -Thu Jan 2 16:12:27 1997 Lars Magne Ingebrigtsen - - * gnus.texi (Optional Backend Functions): Fix. - -Mon Dec 16 13:53:28 1996 Lars Magne Ingebrigtsen - - * gnus.texi (Exiting the Summary Buffer): Update. - -Fri Dec 13 01:04:41 1996 Lars Magne Ingebrigtsen - - * gnus.texi (Limiting): Addition. - -Sat Dec 7 21:10:23 1996 Lars Magne Ingebrigtsen - - * gnus.texi (Example Methods): Addition. - -Fri Dec 6 12:38:14 1996 Lars Magne Ingebrigtsen - - * gnus.texi (Group Parameters): Update. - -1996-11-30 Lars Magne Ingebrigtsen - - * gnus.texi (Terminology): Addition. - -Wed Nov 27 03:13:05 1996 Lars Magne Ingebrigtsen - - * gnus.texi (Selecting a Group): Addition. - -Tue Nov 26 12:42:47 1996 Martin Buchholz - - * message.texi: Typo fixes and stuff. - -Thu Nov 21 17:45:57 1996 Lars Magne Ingebrigtsen - - * gnus.texi (Canceling and Superseding): Fix. - -Wed Nov 20 15:42:36 1996 Lars Magne Ingebrigtsen - - * gnus.texi (New Groups): Addition. - (Summary Sorting): Addition. - -Tue Nov 19 20:54:16 1996 Lars Magne Ingebrigtsen - - * gnus.texi (Scanning New Messages): Addition. - -Sat Nov 9 06:04:22 1996 Lars Magne Ingebrigtsen - - * gnus.texi (Group Parameters): Addition. - -Fri Nov 8 04:01:06 1996 Lars Magne Ingebrigtsen - - * gnus.texi (Article Fontisizing): New. - (Fancy Mail Splitting): Addition. - (Summary Post Commands): Addition. - (Mail Spool): Addition. - (Server Commands): Addition. - (Fancy Mail Splitting): Addition. - -Wed Nov 6 06:39:44 1996 Lars Magne Ingebrigtsen - - * gnus.texi (Misc Article): Addition. - (Emacsen): Updated. - -Wed Nov 6 03:52:05 1996 C. R. Oldham - - * Makefile (.texi.dvi): Fix rule. - -Tue Nov 5 10:45:39 1996 Lars Magne Ingebrigtsen - - * gnus.texi (Other Decode Variables): Addition. - (Mail-like Backends): New. - -Tue Nov 5 06:41:46 1996 Hrvoje Niksic - - * gnus.texi (Score File Format): Added warning. - -Mon Oct 28 15:50:08 1996 Lars Magne Ingebrigtsen - - * gnus.texi (Startup Variables): Addition. - -Fri Oct 25 09:04:59 1996 Lars Magne Ingebrigtsen - - * gnus.texi (Summary Mail Commands): Addition. - -Wed Oct 23 08:28:29 1996 Hrvoje Niksic - - * gnus.texi (Fancy Mail Splitting): Removed trailing garbage. - -Tue Oct 22 07:36:02 1996 Lars Magne Ingebrigtsen - - * gnus.texi (Converting Kill Files): New. - -Sat Oct 19 07:17:28 1996 Lars Magne Ingebrigtsen - - * gnus.texi (Saving Articles): Addition. - - * message.texi (Various Message Variables): Addition. - -Thu Oct 17 06:53:04 1996 Lars Magne Ingebrigtsen - - * gnus.texi (Contributors): Added names. - -Fri Oct 11 12:38:59 1996 Lars Magne Ingebrigtsen - - * gnus.texi (Adaptive Scoring): Addition. - -Tue Oct 8 13:16:41 1996 Lars Magne Ingebrigtsen - - * Makefile (all): Make custom. - -Wed Oct 2 01:32:49 1996 Lars Magne Ingebrigtsen - - * gnus.texi (Group Timestamps): New. - -Tue Oct 1 01:34:45 1996 Lars Magne Ingebrigtsen - - * gnus.texi (Expiring Mail): Addition. - (Group Line Specification): Addition. - -Sat Sep 28 21:36:40 1996 Lars Magne Ingebrigtsen - - * gnus.texi (Foreign Groups): Addition. - -Mon Sep 23 22:17:44 1996 Lars Magne Ingebrigtsen - - * gnus.texi (The Summary Buffer): Addition. - -Mon Sep 23 18:25:38 1996 Lars Magne Ingebrigtsen - - * gnus.texi (Thread Commands): Correction. - (Group Information): Correction. - -Sat Sep 21 08:11:43 1996 Lars Magne Ingebrigtsen - - * gnus.texi (New Groups): Split into three nodes. - (Group Parameters): Shortened. - (Browse Foreign Server): Corrected. - -Thu Sep 19 18:45:15 1996 Lars Magne Ingebrigtsen - - * gnus.texi (Mail and Procmail): Addition. - -Wed Sep 18 07:33:11 1996 Lars Magne Ingebrigtsen - - * gnus.texi (Other Marks): Edited. - (The Manual): New. - (Contributors): Updated. - (Asynchronous Fetching): Addition. - (New Features): Split. - ((ding) Gnus): Renamed. - (September Gnus): New. - (Red Gnus): New, - (Undo): New. - -Thu Sep 12 23:55:53 1996 Lars Magne Ingebrigtsen - - * gnus.texi (Archived Messages): Fix. - -Sat Sep 7 12:14:23 1996 Lars Magne Ingebrigtsen - - * gnus.texi (Various Various): Addition. - -Fri Sep 6 07:57:26 1996 Lars Magne Ingebrigtsen - - * gnus.texi (Startup Files): Addition. - (Splitting Mail): Addition. - (Sorting Groups): Addition. - (Topic Sorting): New. - (Really Various Summary Commands): Deletia. - (Summary Generation Commands): New. - (Setting Process Marks): Addition. - -Thu Sep 5 07:34:27 1996 Lars Magne Ingebrigtsen - - * gnus.texi (Terminology): Addition. - (Web Searches): Fix. - (Windows Configuration): Addition. - -Sun Sep 1 11:07:09 1996 Lars Magne Ingebrigtsen - - * gnus.texi (XEmacs Enhancements): New. - -Sat Aug 31 02:55:50 1996 Lars Magne Ingebrigtsen - - * gnus.texi (Washing Mail): Addition. - -Fri Aug 30 09:10:17 1996 Lars Magne Ingebrigtsen - - * gnus.texi (Washing Mail): New. - (Fancy Mail Splitting): Change. - -Fri Aug 30 00:21:59 1996 Lars Magne Ingebrigtsen - - * gnus.texi (Foreign Groups): Change. - -Thu Aug 29 23:51:45 1996 Lars Magne Ingebrigtsen - - * gnus.texi (Daemons): Addition. - -Thu Aug 29 02:09:24 1996 François Pinard - - * gnus.texi (Web Searches): Typo. - -Wed Aug 28 08:21:36 1996 Lars Magne Ingebrigtsen - - * gnus.texi (Server Commands): Addition. - (Really Various Summary Commands): Addition. - -Mon Aug 26 18:29:23 1996 Lars Magne Ingebrigtsen - - * gnus.texi (Optional Backend Functions): Deletia. - (Asynchronous Fetching): Deletia and addition. - -Sun Aug 25 23:39:03 1996 Lars Magne Ingebrigtsen - - * gnus.texi: Include the version number. - -Sun Aug 25 21:31:33 1996 Lars Magne Ingebrigtsen - - * gnus.texi (Really Various Summary Commands): Addition. - -Sat Aug 17 22:24:34 1996 Lars Magne Ingebrigtsen - - * gnus.texi (Startup Files): Addition. - (Anything Groups): Addition. - -Thu Aug 22 17:27:31 1996 Lars Magne Ingebrigtsen - - * gnus.texi (Adaptive Scoring): Addition. - (Adaptive Scoring): Addition. - -Mon Aug 19 00:30:07 1996 Lars Magne Ingebrigtsen - - * gnus.texi (Fancy Mail Splitting): Addition. - (Splitting Mail): Addition. - (Group Parameters): Addition. - (Topic Variables): Addition. - (Mail Group Commands): Addition. - (Group Information): Addition. - (Article Washing): Addition. - -Sun Aug 18 18:06:49 1996 Lars Magne Ingebrigtsen - - * gnus.texi (Web Searches): Change and addition. - -Sat Aug 17 22:24:34 1996 Lars Magne Ingebrigtsen - - * gnus.texi (Startup Files): Addition. - (Anything Groups): Addition. - -Thu Aug 15 17:59:12 1996 Lars Magne Ingebrigtsen - - * gnus.texi (Followups To Yourself): Addition. - (Setting Process Marks): Addition. - (Process/Prefix): Addition. - (Startup Files): Addition. - (Mail-To-News Gateways): New. - -Wed Aug 14 15:02:14 1996 Lars Magne Ingebrigtsen - - * gnus.texi (Home Score File): Fix. - (Various Various): New. - -Tue Aug 13 10:38:47 1996 Lars Magne Ingebrigtsen - - * gnus.texi (Error Messaging): New. - (Mail Backend Variables): Fix. - (Foreign Groups): Added references. - (Sorting Groups): Addition. - -Sun Aug 11 02:52:37 1996 Lars Magne Ingebrigtsen - - * gnus.texi (User-Defined Specs): Correction. - (Unavailable Servers): Addition. - (Moderation): New. - (Summary Mail Commands): Addition. - (Crosspost Handling): Addition. - -Sat Aug 10 00:13:39 1996 Lars Magne Ingebrigtsen - - * gnus.texi (Summary Buffer Lines): Correction. - (Top): Name fix. - (Compilation ): Addition. - (Group Parameters): Addition. - (Troubleshooting): Addition. - -Fri Aug 9 07:17:59 1996 Lars Magne Ingebrigtsen - - * gnus.texi (Selecting a Group): Addition. - (Score Decays): New. - (Score File Format): Addition. - (Changing Servers): Addition. - (Selecting a Group): Addition. - (Really Various Summary Commands): Addition. - -Thu Aug 8 05:39:31 1996 Lars Magne Ingebrigtsen - - * gnus.texi (Read Articles): Addition. - (Foreign Groups): Addition. - (User-Defined Specs): Separated. - (Formatting Fonts): Ditto. - (Advanced Formatting): New. - (Formatting Basics): Addition. - (Formatting Variables): Split. - -Wed Aug 7 22:00:56 1996 Lars Magne Ingebrigtsen - - * gnus.texi (Hooking New Backends Into Gnus): New node. - -Wed Aug 7 01:02:08 1996 Lars Magne Ingebrigtsen - - * gnus.texi (Setting Marks): Addition. - (Formatting Variables): Addition. - -Mon Aug 5 20:20:42 1996 Lars Magne Ingebrigtsen - - * gnus.texi (Formatting Variables): Addition. - -Sun Aug 4 07:15:28 1996 Lars Magne Ingebrigtsen - - * gnus.texi (Score File Format): Addition. - (Adaptive Scoring): Addition. - -Sat Aug 3 17:35:36 1996 Lars Magne Ingebrigtsen - - * gnus.texi (Group Parameters): Addition. - (Home Score File): New. - (Topic Parameters): New. - -Wed Jul 31 15:34:12 1996 Lars Magne Ingebrigtsen - - * gnus.texi (are): Fix. - -Wed Jul 31 15:32:57 1996 David S. Goldberg - - * gnus.texi (buffer-name): Addition. - -Fri Aug 2 00:32:39 1996 Lars Magne Ingebrigtsen - - * gnus.texi (Pick and Read): Addition. - (Article Hiding): Addition. - (Article Signature): Made into own node. - -Thu Aug 1 00:25:41 1996 Lars Magne Ingebrigtsen - - * message.texi (Wide Reply): Addition. - (Bouncing): Addition. - - * gnus.texi (Crosspost Handling): Made into own node. - (Duplicate Suppression): New. - (Document Server Internals): New. - (Changing Servers): New. - -Wed Jul 31 15:37:44 1996 Lars Magne Ingebrigtsen - - * gnus.texi: Fix - -Mon Jul 29 10:12:24 1996 Lars Magne Ingebrigtsen - - * gnus.texi (Misc Article): Addition. - (Advanced Scoring Tips): New. - (Advanced Scoring Example): New. - (Advanced Scoring Syntax): New. - (Advanced Scoring): New. diff --git a/texi/Makefile.in b/texi/Makefile.in deleted file mode 100644 index 77db83e..0000000 --- a/texi/Makefile.in +++ /dev/null @@ -1,191 +0,0 @@ -infodir = @infodir@ -prefix = @prefix@ -srcdir = @srcdir@ -subdir = texi -top_srcdir = @top_srcdir@ - -TEXI2DVI=texi2dvi -EMACS=emacs -MAKEINFO=@MAKEINFO@ -EMACSINFO=$(EMACS) -batch -q -no-site-file -INFOSWI=-l texinfmt -f texinfo-every-node-update -f texinfo-format-buffer -f save-buffer -XINFOSWI=-l texinfmt -f texinfo-every-node-update -f texinfo-format-buffer -f save-buffer -LATEX=latex -DVIPS=dvips -PERL=perl -INSTALL = @INSTALL@ -INSTALL_DATA = @INSTALL_DATA@ -SHELL = /bin/sh -PAPERTYPE=a4 - -all: gnus message - -ja: gnus-ja message-ja - -most: texi2latex.elc latex latexps - -.SUFFIXES: .texi .dvi .ps - -.texi: - if test $(MAKEINFO) = no; then \ - $(EMACSINFO) -eval '(find-file "$<")' $(XINFOSWI); \ - else \ - makeinfo -o $* $<; \ - fi - -dvi: gnus.dvi message.dvi refcard.dvi - -.texi.dvi : - $(PERL) -n -e 'print unless (/\@iflatex/ .. /\@end iflatex/)' $< > gnustmp.texi - $(TEXI2DVI) gnustmp.texi - cp gnustmp.dvi $*.dvi - rm gnustmp.* - -refcard.dvi: refcard.tex gnuslogo.refcard gnusref.tex - $(LATEX) refcard.tex - -clean: - rm -f gnus.*.bak *.ky *.cp *.fn *.cps *.kys *.log *.aux *.dvi *.vr \ - *.tp *.toc *.pg gnus.latexi *.aux *.[cgk]idx \ - gnus.ilg gnus.ind gnus.[cgk]ind gnus.idx \ - gnus.tmptexi *.tmplatexi gnus.tmplatexi1 texput.log *.orig *.rej \ - gnus.latexi*~* tmp/*.ps xface.tex picons.tex smiley.tex *.latexi - -makeinfo: - makeinfo -o gnus gnus.texi - makeinfo -o message message.texi - -texi2latex.elc: texi2latex.el - $(EMACS) -batch -l bytecomp --eval '(byte-compile-file "texi2latex.el")' - -latex: gnus.texi texi2latex.elc - $(EMACS) -batch -q -no-site-file gnus.texi -l ./texi2latex.elc -f latexi-translate - -latexps: - make texi2latex.elc - rm -f gnus.aux - egrep -v "label.*Index|chapter.*Index" gnus.latexi > gnus.tmplatexi1 - $(LATEX) gnus.tmplatexi1 - ./splitindex - makeindex -o gnus.kind gnus.kidx - makeindex -o gnus.cind gnus.cidx - makeindex -o gnus.gind gnus.gidx - sed 's/\\char 5E\\relax {}/\\symbol{"5E}/' < gnus.kind > gnus.tmpkind - mv gnus.tmpkind gnus.kind - egrep -v "end{document}" gnus.tmplatexi1 > gnus.tmplatexi - cat postamble.tex >> gnus.tmplatexi - $(LATEX) gnus.tmplatexi - $(LATEX) gnus.tmplatexi - $(DVIPS) -t $(PAPERTYPE) -f gnus.dvi > gnus.ps - -pss: - make latex - make latexps - -psout: - make latex - make latexboth - make out - -latexboth: - rm -f gnus-manual-a4.ps.gz gnus-manual-standard.ps.gz - make latexps - mv gnus.ps gnus-manual-a4.ps - gzip gnus-manual-a4.ps - sed 's/,a4paper/,letterpaper/' gnus.latexi > gnus-standard.latexi - mv gnus-standard.latexi gnus.latexi - make latexps PAPERTYPE=letter - mv gnus.ps gnus-manual-standard.ps - gzip gnus-manual-standard.ps - -out: - cp gnus-manual-standard.ps.gz \ - gnus-manual-a4.ps.gz \ - /local/ftp/pub/emacs/gnus/manual - mv gnus-manual-standard.ps.gz \ - gnus-manual-a4.ps.gz \ - /hom/larsi/www_docs/www.gnus.org/documents - -veryclean: - make clean - rm -f gnus.dvi gnus.ps texi2latex.elc - -distclean: - make clean - rm -f *.orig *.rej *.elc *~ gnus gnus-[0-9] gnus-[0-9][0-9] Makefile - rm -f message message-[0-9] - -install: - $(SHELL) $(top_srcdir)/mkinstalldirs $(infodir) - @for file in gnus message gnus-ja message-ja; do \ - for ifile in `echo $$file $$file-[0-9] $$file-[0-9][0-9]`; do \ - if test -f $$ifile; then \ - echo " $(INSTALL_DATA) $$ifile $(infodir)/$$ifile"; \ - $(INSTALL_DATA) $$ifile $(infodir)/$$ifile; \ - else : ; fi; \ - done; \ - done - -tmps: - if [ ! -e tmp ]; then mkdir tmp; fi - make screens - make herdss - make etcs - make piconss - make xfaces - make smiley - make miscs - -herdss: - cd herds ; for i in new-herd-[0-9]*.gif; do echo $$i; giftopnm $$i | pnmcrop -white | pnmmargin -white 9 | pnmscale 2 | pnmconvol convol5.pnm | ppmtopgm | pnmdepth 255 | pnmtops -width 100 -height 100 -noturn > ../tmp/`basename $$i .gif`.ps; done - cd herds ; giftopnm new-herd-section.gif | pnmscale 4 | pnmconvol convol11.pnm | ppmtopgm | pnmdepth 255 | pnmtops -noturn -width 100 -height 100 > ../tmp/new-herd-section.ps - - -screens: - cd screen ; for i in *.gif; do echo $$i; giftopnm $$i | pnmmargin -black 1 | ppmtopgm | pnmtops -width 100 -height 100 -noturn > ../tmp/`basename $$i .gif`.ps; done - -miscs: - giftopnm misc/larsi.gif | ppmtopgm | pnmtops -noturn > tmp/larsi.ps - tifftopnm misc/eseptember.tif | pnmscale 4 | ppmtopgm | pnmtops -noturn -width 100 -height 100 > tmp/september.ps - tifftopnm misc/fseptember.tif | pnmscale 2 | ppmtopgm | pnmtops -noturn -width 100 -height 100 > tmp/fseptember.ps - tifftopnm misc/fred.tif | pnmscale 2 | ppmtopgm | pnmtops -noturn -width 100 -height 100 > tmp/fred.ps - tifftopnm misc/ered.tif | pnmscale 2 | ppmtopgm | pnmtops -noturn -width 100 -height 100 > tmp/red.ps - -etcs: - cd etc; for i in gnus-*.xpm; do echo $$i; xpmtoppm $$i | ppmtopgm | pnmdepth 255 | pnmtops -noturn > ../tmp/`basename $$i .xpm`.ps; done - -piconss: - cd picons; for i in *.xbm; do echo $$i; xbmtopbm $$i | pnmtops -noturn > ../tmp/picons-`basename $$i .xbm`.ps; done - cd picons; for i in *.gif; do echo $$i; giftopnm $$i | ppmtopgm | pnmtops -noturn > ../tmp/picons-`basename $$i .gif`.ps; done - for i in tmp/picons-*.ps; do echo "\\gnuspicon{$$i}"; done > picons.tex - -xfaces: - cd xface; for i in *.gif; do echo $$i; giftopnm $$i | ppmtopgm | pnmtops -noturn > ../tmp/xface-`basename $$i .gif`.ps; done - for i in tmp/xface-*.ps; do \ - if [ -n "$$a" ]; then a=""; echo "{$$i}"; else \ - a="h"; echo -n "\\gnusxface{$$i}"; fi done > xface.tex; \ - if [ -n "$$a" ]; then echo "{$$i}" >> xface.tex; fi - -smiley: - cd smilies; tifftopnm BigFace.tif | ppmtopgm | pnmtops > ../tmp/BigFace.ps - cd smilies; for i in *.xpm; do echo $$i; sed "s/none/#FFFFFF/" $$i | xpmtoppm | ppmtopgm | pnmdepth 255 | pnmtops > ../tmp/smiley-`basename $$i .xpm`.ps; done - for i in tmp/smiley-*.ps; do \ - if [ -n "$$a" ]; then a=""; echo "{$$i}"; else \ - a="h"; echo -n "\\gnussmiley{$$i}"; fi done > smiley.tex; \ - if [ -n "$$a" ]; then echo "{$$i}" >> smiley.tex; fi - -pspackage: - tar czvf pspackage.tar.gz gnus-faq.texi gnus.texi herds misc pagestyle.sty picons pixidx.sty postamble.tex ps screen smilies splitindex texi2latex.el xface Makefile README etc - -complete: - make texi2latex.elc - make tmps - make pss - -Makefile: $(srcdir)/Makefile.in ../config.status - cd .. \ - && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/texi/TRANSLATION.ja b/texi/TRANSLATION.ja deleted file mode 100644 index 1538b5f..0000000 --- a/texi/TRANSLATION.ja +++ /dev/null @@ -1,27 +0,0 @@ -This file documents about translation policy. -There is an ongoing project to make gnus-ja.texi. -Any volunteers are welcomed. - -$BF|K\8lLu$K4X$9$kN.57$r@bL@$9$k%U%!%$%k$G$9!#(B -gnus-ja.texi $B$r:n@.$9$k%W%m%8%'%/%H$,?J9TCf$G$9!#(B -$B%W%m%8%'%/%H;22C $B$NK]Lu$K4X$9$k5,B'(B -$B$G$9!#$3$N5,B'$O$h$jNI$$$H;W$o$l$k$b$N$,8+$D$+$C$?>l9g$K$OJQ99$5$l$k2D(B -$BG=@-$,$"$j$^$9!#$^$?!"$h$jNI$$0F$d!"B>$N5,B'$rIU$12C$($?$$>l9g$O!"(B -semi-gnus-ja $B%a!<%j%s%0%j%9%H$K$=$N0F$r=q$/$+!"(Bjaist $B$N(B Open CVS $B$K=q(B -$B$-9~$_8"8B$r;}$C$F$$$kJ}$OD>@\=q$-9~$_$r$7$F$/$@$5$$!#(B(CVS $B$N>l9g$G$b!"(B -semi-gnus-ja $B$GJQ99$N9pCN$r$9$k;v$,K>$^$7$$$G$9!#(B) semi-gnus-ja $B%a!<%j(B -$B%s%0%j%9%H$N2CF~$N;EJ}$KIU$$$F$b!">e5-$N(B URI $B$r;2>H$7$F$/$@$5$$!#(B - -1. $B$J$k$Y$/%+%?%+%J$O;H$o$J$$$h$&$K$9$k!#(B - ($BF|K\8l$K$G$-$k$H$3$m$O$J$k$Y$/F|K\8l$K$9$k!#(B - $B>l9g$K$h$C$F$O?7$7$$8l$rDj5A$9$k;v$b$"$k!#(B) - -2. $B1Q8l$rIU2C$7$?J}$,J,$+$j$d$9$$$H;W$o$l$k8l6g$O!"(B - $BF|K\8l$ND>8e$K3g8L$NCf$KF~$l$k!#(B - diff --git a/texi/dir b/texi/dir deleted file mode 100644 index a169da0..0000000 --- a/texi/dir +++ /dev/null @@ -1,9 +0,0 @@ --*- Text -*- -The Gnus-related top node. - -File: dir Node: Top This is the Gnus Info tree - -* Menu: - -* Gnus: (gnus). The news reader Gnus. -* Message: (message). The Message sending thingamabob. diff --git a/texi/gnus-faq-ja.texi b/texi/gnus-faq-ja.texi deleted file mode 100644 index 31e588e..0000000 --- a/texi/gnus-faq-ja.texi +++ /dev/null @@ -1,468 +0,0 @@ -@c Insert "\input texinfo" at 1st line before texing this file alone. -@c -*-texinfo-*- -@c Copyright (C) 1998 Keiichi Suzuki -@setfilename gnus-faq-ja.info - -@node Frequently Asked Questions -@section $BIQHK$K?R$M$i$l$kR2p!#(B -* Installation FAQ:: Gnus $B$NF3F~!#(B -* Customization FAQ:: Gnus $B$N%+%9%?%^%$%:!#(B -* Reading News FAQ:: $B%K%e!<%9$rFI$`;v$K4X$9$kR2p(B -$B$3$NJ8=q$O!"(B Semi-gnus $B$KBP$9$k$h$/$"$ke$GF0:n$9$k%M%C%H%K%e!<%9!&%j!<%@!<(B / $BEE;R%a!<%k!&%f!<(B -$B%6!$=$&$H7h0U$7$^$7$?!#(B - -$B$7$+$7!"(B Gnus $BC1FH$G$O(B MIME $B2=$5$l$?5-;v!&%a!<%k$rFI$`$3$H$O$G$-$^$;$s!#(B -$B$=$3$G!"(B Emacs $B>e$G(B MIME $B%5%]!<%H$r$9$k$?$a$N%Q%C%1!<%8$G$"$k(B SEMI $B$r;H(B -$BMQ$7$F0lIt$N?M$?$A$,(B Gnus $B$r;HMQ$9$k$h$&$K$J$j$^$7$?!#$7$+$7!"$3$l$K$O(B -Gnus $B$K(B patch $B$r$"$F$kI,MW$,$"$k>e$K%*%j%8%J%k$N(B Gnus ($B$3$A$i$b(B -Quassia-Gnus $B$H8F$P$l3+H/ESCf$G$7$?(B)$B$NJQ99FbMF$K$h$C$F$O$=$N(B patch $B<+BN(B -$B$b:n$jD>$5$J$1$l$P$J$j$^$;$s$G$7$?!#$=$s$J(B 1997$BG/$N(B11$B7n!" $B$O<~0O(B($B9%$-/62I]$r46$8$k$+$bCN$l$^$;$s!"$7$+$7!"(B -$B$"$J$?$,$=$N5!G=$rI,MW$K$J$k$^$G$OJ#;($J5!G=$N$[$H$s$I$rL5;k$9$k$3$H$,$G(B -$B$-$^$9!#(B $B$b$7!"$"$J$?$,$^$"$^$"$NNL$N%a%$%k$ro$KN.NL$NB?$$%a!<%j%s%0%j%9%H$K;22C(B -$B$7$F$$$k$N$G$"$l$P!"$"$J$?$O(B Semi-gnus $B$G%a%$%k$rFI$`$?$a$ND4::$r$O$8$a(B -$B$?$/$J$k$G$7$g$&!#(B - -$B$3$N(B FAQ $B$O!"NkLZ7=0l$K$h$C$FJ]$NJ}K!(B($B%a%$%k!"%M%C%H%K%e!<%9Ey(B)$B$G>pJs$rF@$h$&$H$9$kA0$K!"$^$:$3$N(B FAQ -$B$r8+$F$_$F$/$@$5$$!#(B - -$B$3$N>pJs$O(B Semi-gnus (Ja) $B%a%$%j%s%0!&%j%9%H$N1g=u$r!"(B APEL $B$,I,MW$K$J$j$^$9$,!"I,MW$J%P!<%8%g(B -$B%s$O(B FLIM / SEMI (WEMI) $B%Q%C%1!<%8Fb$N(B README $B$r;2>H$7$F$/$@$5$$!#(B - -Semi-gnus $B$N%P!<%8%g%s$O!"I,MW$J(B SEMI (WEMI) $B$*$h$S(B FLIM $B$N%P!<%8%g%s$K(B -$B?<$/4X78$7$F$$$^$9!#(B $BI,$:!"(B Semi-gnus $B$N%P!<%8%g%s$K$"$C$?(B SEMI (WEMI) -$B$*$h$S(B FLIM $B$r;HMQ$7$F$/$@$5$$!#(B - -$B8=:_!"$+$J$j$N%O%$%Z!<%9$G%P!<%8%g%s$,>e$,$C$F$$$^$9!#(B CVS $B$N(B main trunk -(tag $BL5$7(B) $B$,0BDj%P!<%8%g%s$G$9!#(B - -@item -Q1.2: $BF~l=j$+$il=j$+$ie!#(B - -@item -XEmacs - -$B%P!<%8%g%s(B 20.2 $B0J>e$N(BMule $B5!G=IU$-(B - -@item -Meadow - -$B%P!<%8%g%s(B 1.00 $B0J>e!#(B(Mule for Windows $B$G$OF0$-$^$;$s!#(B) -@end itemize - -$B;32,9nH~$5$s(B $B:n$NHs8x<0$N(B -@file{semi-mule23@@1934-YYMMDD.tar.gz} $B$r;HMQ$9$l$P(B Mule 2.3 / Emacs -19.34 $B$G$OF0:n$9$k$G$7$g$&!#(B - -$B$3$l$O!"J}$GF0$+$9$3$H$O$G$-$^$9$+(B? - -$B%=!<%9!&%l%Y%k(B( *.el )$B$G$O2DG=$G$9!#(B - -$B$7$+$7!"%P%$%H!&%3%s%Q%$%k$7$?%U%!%$%k(B ( *.elc ) $B$O6&M-$G$-$^$;$s$N$G!"(B -$B$=$l$>$l;HMQ$9$k(B emacs $B$G%P%$%H%3%s%Q%$%k$9$kI,MW$,$"$j$^$9!#(B - -@item -Q1.5: Semi-gnus $B$K$D$$$F$N>pJs8;$O(B? - -@table @var - -@item $B%K%e!<%9%0%k!<%W(B - -fj.news.reader.gnus $B$,$"$j$^$9$,!"(B Semi-gnus $B$K4X$7$F$N\$7$/$O!"(B@xref{Mailing list FAQ, $B%a!<%j%s%0%j%9%H(B}, $B$r;2>H$7$F$/$@$5$$!#(B - -$B8=:_!"$3$l$,$b$C$H$b3NpJs8;$G$7$g$&!#(B Semi-gnus $B$r;H$&$N$G$"$l$P!"(B -$B@'Hs;22C$9$k$3$H$r$*$9$9$a$7$^$9!#(B - -$B%@%$%8%'%9%HHG%5!<%S%9$O$"$j$^$;$s!#(B - -@item WWW - -$B8x<0$N(B Semi-gnus $B%[!<%`%Z!<%8$,$G$-$kM=Dj$G$9!#<9I.$J(B Jamie Zawinski $B$N:n$G!"(BGNU -Emacs $BMQ$N(Brolodex-like $B$J%G!<%?%Y!<%9%W%m%0%i%`$G$9!#(B Jamie $B$O(B BBDB $B$N(B -Web $B%Z!<%8$r;}$C$F$$$^$9!#(B @file{http://people.netscape.com/jwz/bbdb/}$B$3(B -$B$l$O!"l=j$K$"$j$^$9!#(B -@file{http://www.netcom.com/%7Esimmonmt/index.html} - -Semi-gnus $B$G;HMQ$9$k>l9g$K$O!"I,$:(B Q2.1 $B$r;2>H$7$F$/$@$5$$!#(B - -@item gnus-offline -gnus-offline $B$O!";T@nC#:H(B $B$N:n$G!"(B Semi-gnus -$B$r$$$o$f$k!V%*%U%i%$%s;HMQ!W(B($B%K%e!<%95-;v!"%a%$%k$NAwuBV$G9T$&(B)$B$9$k$3$H$rMF(B -$B0W$K$9$k$?$a$N%Q%C%1!<%8$G$9!#(B - -$BF~H$7$F2<$5$$!#(B - -@item -Q1.8: Semi-gnus $B$N5/F0$rAa$/$9$k$K$O(B? - -$B9XFI$7$F$$$J$$%0%k!<%W$r(B ``kill'' (*Group* $B%P%C%U%!!<$G(B C-k) $B$7$F$"$k$3(B -$B$H$r3NG'$7$F$/$@$5$$!#$=$7$F!">o$K(B ``.newsrc'' $B$r>.$5$/J]$D$h$&$K$7$F$/(B -$B$@$5$$!#(B - -@end itemize - -@node Customization FAQ -@subsection $B%+%9%?%^%$%:$K4X$9$k(B FAQ - -@itemize @bullet -@item -Q2.1: Semi-gnus $B$N%P!<%8%g%s$r$"$2$?$i(B BBDB $B$,F0$+$J$/$J$C$F$7$^$$$^$7$?!#(B - -Semi-gnus 6.8 $B0J9_$N%P!<%8%g%s$G$O!"%*%j%8%J%k$N(B bbdb-gnus.el $B$OF0:n$7$^(B -$B$;$s!#(B $BH$9$k$h$&$K$9$k!#(B - -$B$b$7!"%*%j%8%J%k$N(B Gnus (September $B0J9_(B) $B$r;H$C$F$$$k$N$G$"$l$P!"$3$NJ}(B -$BK!$,NI$$$G$7$g$&!#(B - -@item -bbdb/gnus-update-record $B$r(B gnus-article-prepare-hook $B$NBe$j$K(B -gnus-article-display-hook $B$KDI2C$9$k!#(B - -@end enumerate - -a $B$NJ}K!!"$*$h$S(B bbdb-user-mail-names $B$KBP1~$7$?(B BBDB 2.00.01 $B$KBP$9$k(B -patch $B!"4pK\E*$J@_DjNc$,!"(B -@file{http://www.mdcnet.co.jp/~keiichi/bbdb.shtml} $B$K$"$j$^$9!#(B - -@item -Q2.2: hook $B$r@_Dj$7$?$i(B Semi-gnus $B$NF0:n$,$*$+$7$/$J$C$?(B - -$BDL>o$NJQ?t$G$bF1MM$G$9$,!"(B Semi-gnus $B$G$OB?$/$N(B hook $B$K=i4|CM$,@_Dj$5$l(B -$B$F$$$^$9!#(B - -$B$3$NCM$rJQ99$7$h$&$H$7$F!"JQ?t$,Dj5A$5$l$F$$$k%U%!%$%k$r%m!<%I$9$kA0$K(B -setq / add-hook $BEy$r9T$&$H!"$3$l$i$N=i4|CM$,@_Dj$5$l$:!"(B Semi-gnus $B$,@5(B -$B>o$KF0:n$7$J$/$J$k>l9g$,$"$j$^$9!#(B($BFC$K(B Semi-gnus $B$N%P!<%8%g%s$,JQ$C$?>l(B -$B9g(B) - -$B$3$l$rKI$0$?$a$K$b!"(B Semi-gnus $B$K4X$9$k@_Dj$O$G$-$k$@$1(B ~/.gnus.el $BFb$G(B -$B9T$&$h$&$K$7$F$/$@$5$$!#(B - -@item -Q2.3: $B08@h$K$h$C$F(B Signature $B$rJQ99$9$k$K$O(B? - -SEMI $B$K$O(B signature.el $B$H$$$&$3$N$?$a$N%D!<%k$,IUB0$7$F$$$^$9!#;HMQJ}K!$O0J2<$N$H$*$j$G$9!#(B - -tm $B$N(B info $B$NFbMF$r(B SEMI $B$K9g$o$;$FJQ99$7$?$b$N$G$9!#(B - -SEMI $B$K$O(B *signature* $B$H$$$&(B signature $B$N<+F0@ZBX$((B tool $B$,ImB0$7$F$*$j!"(B -`semi-setup.el' $B$O$3$N@_Dj$b9T$J$$$^$9!#(Bmessage header $B$N(B field $B$K9g$o$;(B -$B$F(B signature $B$N<+F0@ZBX$r9T$J$$$?$$>l9g$O(B `~/.emacs' $B$K0J2<$N$h$&$J$b$N(B -$B$rF~$l$F2<$5$$!#!J>\$7$/$O(B signature.el $B$N@bL@=q$r;2>H$7$F2<$5$$!K(B - -@lisp -(setq signature-file-alist - '((("Newsgroups" . "jokes") . "~/.signature-jokes") - (("Newsgroups" . ("zxr" "nzr")) . "~/.signature-sun") - (("To" . ("ishimaru" "z-suzuki")) . "~/.signature-sun") - (("To" . "tea") . "~/.signature-jokes") - (("To" . ("sim" "oku" "takuo")) . "~/.signature-formal") - )) -@end lisp - -@defvar mime-setup-use-signature - -$B$3$NJQ?t$,(B @code{nil} $B0J30$N;~!"(B@file{signature.el} $B$r;H$$$^$9!#=i4|CM$O(B -@code{t} $B$G$9!#(B -@end defvar - -@defvar mime-setup-signature-key-alist - -$B3F(B major-mode $B$K$*$$$F(B signature $BA^F~L?Na$r@_Dj$9$Y$-(B key $B$r;XDj$7$^$9!#(B -$B=i4|CM$O(B - -@lisp - ((mail-mode . "\C-c\C-w")) -@end lisp - -$B$G$9!#(B - -$B$3$l$rJQ99$7$?$$>l9g$O!"4X?t(B set-alist $B$J$I$r;H$C$F$3$NJQ?t$r=q$-49$((B -$B$F2<$5$$!#(B - -@lisp -(set-alist 'mime-setup-signature-key-alist - 'news-reply-mode "\C-c\C-w") -@end lisp - -@end defvar - -@defvar mime-setup-default-signature-key - -$B$"$k(B major-mode $B$K$*$$$F(B signature $BA^F~L?Na$r@_Dj$9$Y$-(B key $B$,8+$D$+$i$J(B -$B$$>l9g!"$3$NJQ?t$K@_Dj$5$l$?(B key $B$,MQ$$$i$l$^$9!#=i4|CM$O!"(B -@code{"\C-c\C-s"} $B$G$9!#(B -@end defvar - -gnus-posting-style $B$r;HMQ$9$k;v$b$G$-$^$9!#(B - -@end itemize - -@node Reading News FAQ -@subsection $B%K%e!<%9$rFI$`(B - -@node Reading Mail FAQ -@subsection $B%a!<%k$rFI$`(B - -@node Mailing list FAQ -@subsection $B%a!<%j%s%0%j%9%H(B - -@itemize bullet -@item -Q5.1: $B%a%$%j%s%0!&%j%9%H$+$iC&B`$9$k$K$O(B? - -@table @var -@item $BF|K\8lMQ(B -@file{semi-gnus-ja-unsubscribe@@meadow.scphys.kyoto-u.ac.jp} $B$K6u$N%a%$(B -$B%k$rAw$C$F2<$5$$!#(B(Subject $B$bITMW$G$9!#(B) - -@item $B1Q8lMQ(B -@file{semi-gnus-en-unsubscribe@@meadow.scphys.kyoto-u.ac.jp} $B$K6u$N%a%$(B -$B%k$rAw$C$F2<$5$$!#(B(Subject $B$bITMW$G$9!#(B) - -@end table - -@item -Q5.2: $B%a%$%j%s%0!&%j%9%H$K;22C$9$k$K$O(B? - -Semi-gnus $B$G$O!"MxMQMh$NB?$/$N%Q%C%1!<%8$G:NMQ$5$l$F$$(B -$B$k3+H/BN@)$O$C$F$/$/$@$5$$!#(B(Subject $B$bITMW$G$9!#(B) - -@item $B1Q8lMQ(B -@file{semi-gnus-en-help@@meadow.scphys.kyoto-u.ac.jp} $B$K6u$N%a!<%k$rAw$C(B -$B$F!"Aw$i$l$F$/$k%a!<%k$N;X<($K=>$C$F$/$@$5$$!#(B(Subject $B$bITMW$G$9!#(B) - -@end table - -@item -Q5.3: Semi-gnus $B$K4X$9$kJ}?K7hDj$O(B? - -Semi-gnus $B$N3+H/Ey$K4X$9$kJ}?K$N7hDj$OA4$F(B Semi-gnus-ja/en $B%a!<%j%s%0%j(B -$B%9%HFb$G9T$o$l$^$9!#(B $B3F%a%s%P!<$+$i$NDs0F$O%"%s%1!<%H$N7A$GDs0F$5$l7h5D(B -$B$5$l$^$9$,!"$=$NJ}K!$Ol9g$KE,MQ$5$l$k!#(B $B;dE*$J;^$dHG$K4X(B -$B$7$F$OE,MQ$5$l$J$$!#(B - -@item -$B8xE*$J0F7o$NDs0F$*$h$S5DO@$O(B semi-gnus-ja@@meadow.scphys.kyoto-u.ac.jp $B$b(B -$B$7$/$O(Bsemi-gnus-en@@meadow.scphys.kyoto-u.ac.jp $B$G9T$&!#(B - -@item -$B:G=*E*$JJ}?K$O%"%s%1!<%H7k2L$NB??t0U8+$r:NMQ$9$k!#(B - -@item -$BDs0Fe$G$J$1$l(B -$B$P$J$i$J$$!#(B - -@item -$BDs0Fl9g!"Ds0FF|$h$j#1=54V8e$r2s(B -$BEz4|8B$H$9$k!#(B - -@item -$BDs0F0J>e$N2sEz$,$"$C(B -$B$?;~E@$G%"%s%1!<%H$N=*N;$r@k8@$G$-$k!#(B $B$3$N>l9g!"%"%s%1!<%H$NB??t0U8+$r(B -$B7kO@$H$9$k!#(B - -@item -$B2sEz4|8B$,2a$.$F$b!"#5L>0J>e$N2sEz$,$J$$>l9g$O!"Ds0Fe$N;22Cl9g!"2sEz4|8B$O1dD9(B -$B$5$l$k!#(B -@end enumerate - -@end itemize diff --git a/texi/gnus-faq.texi b/texi/gnus-faq.texi deleted file mode 100644 index abc9054..0000000 --- a/texi/gnus-faq.texi +++ /dev/null @@ -1,659 +0,0 @@ -@c Insert "\input texinfo" at 1st line before texing this file alone. -@c -*-texinfo-*- -@c Copyright (C) 1995 Free Software Foundation, Inc. -@setfilename gnus-faq.info - -@node Frequently Asked Questions -@section Frequently Asked Questions - -This is the Gnus Frequently Asked Questions list. -If you have a Web browser, the official hypertext version is at -@file{http://www.ccs.neu.edu/software/gnus/}, and has -probably been updated since you got this manual. - -@menu -* Installation FAQ:: Installation of Gnus. -* Customization FAQ:: Customizing Gnus. -* Reading News FAQ:: News Reading Questions. -* Reading Mail FAQ:: Mail Reading Questions. -@end menu - - -@node Installation FAQ -@subsection Installation - -@itemize @bullet -@item -Q1.1 What is the latest version of Gnus? - -The latest (and greatest) version is 5.0.10. You might also run -across something called @emph{September Gnus}. September Gnus -is the alpha version of the next major release of Gnus. It is currently -not stable enough to run unless you are prepared to debug lisp. - -@item -Q1.2 Where do I get Gnus? - -Any of the following locations: - -@itemize @minus -@item -@file{ftp://ftp.ifi.uio.no/pub/emacs/gnus/gnus.tar.gz} - -@item -@file{ftp://ftp.pilgrim.umass.edu/pub/misc/ding/} - -@item -@file{gopher://gopher.pilgrim.umass.edu/11/pub/misc/ding/} - -@item -@file{ftp://aphrodite.nectar.cs.cmu.edu/pub/ding-gnus/} - -@item -@file{ftp://ftp.solace.mh.se:/pub/gnu/elisp/} - -@end itemize - -@item -Q1.3 Which version of Emacs do I need? - -At least GNU Emacs 19.28, or XEmacs 19.12 is recommended. GNU Emacs -19.25 has been reported to work under certain circumstances, but it -doesn't @emph{officially} work on it. 19.27 has also been reported to -work. Gnus has been reported to work under OS/2 as well as Unix. - - -@item -Q1.4 Where is timezone.el? - -Upgrade to XEmacs 19.13. In earlier versions of XEmacs this file was -placed with Gnus 4.1.3, but that has been corrected. - - -@item -Q1.5 When I run Gnus on XEmacs 19.13 I get weird error messages. - -You're running an old version of Gnus. Upgrade to at least version -5.0.4. - - -@item -Q1.6 How do I unsubscribe from the Mailing List? - -Send an e-mail message to @file{ding-request@@ifi.uio.no} with the magic word -@emph{unsubscribe} somewhere in it, and you will be removed. - -If you are reading the digest version of the list, send an e-mail message -to @* -@file{ding-rn-digests-d-request@@moe.shore.net} -with @emph{unsubscribe} as the subject and you will be removed. - - -@item -Q1.7 How do I run Gnus on both Emacs and XEmacs? - -The basic answer is to byte-compile under XEmacs, and then you can -run under either Emacsen. There is, however, a potential version -problem with easymenu.el with Gnu Emacs prior to 19.29. - -Per Abrahamsen writes :@* -The internal easymenu.el interface changed between 19.28 and 19.29 in -order to make it possible to create byte compiled files that can be -shared between Gnu Emacs and XEmacs. The change is upward -compatible, but not downward compatible. -This gives the following compatibility table: - -@example -Compiled with: | Can be used with: -----------------+-------------------------------------- -19.28 | 19.28 19.29 -19.29 | 19.29 XEmacs -XEmacs | 19.29 XEmacs -@end example - -If you have Gnu Emacs 19.28 or earlier, or XEmacs 19.12 or earlier, get -a recent version of auc-menu.el from -@file{ftp://ftp.iesd.auc.dk/pub/emacs-lisp/auc-menu.el}, and install it -under the name easymenu.el somewhere early in your load path. - - -@item -Q1.8 What resources are available? - -There is the newsgroup Gnu.emacs.gnus. Discussion of Gnus 5.x is now -taking place there. There is also a mailing list, send mail to -@file{ding-request@@ifi.uio.no} with the magic word @emph{subscribe} -somewhere in it. - -@emph{NOTE:} the traffic on this list is heavy so you may not want to be -on it (unless you use Gnus as your mailer reader, that is). The mailing -list is mainly for developers and testers. - -Gnus has a home World Wide Web page at@* -@file{http://www.ifi.uio.no/~larsi/ding.html}. - -Gnus has a write up in the X Windows Applications FAQ at@* -@file{http://www.ee.ryerson.ca:8080/~elf/xapps/Q-III.html}. - -The Gnus manual is also available on the World Wide Web. The canonical -source is in Norway at@* -@file{http://www.ifi.uio.no/~larsi/ding-manual/gnus_toc.html}. - -There are three mirrors in the United States: -@enumerate -@item -@file{http://www.miranova.com/gnus-man/} - -@item -@file{http://www.pilgrim.umass.edu/pub/misc/ding/manual/gnus_toc.html} - -@item -@file{http://www.rtd.com/~woo/gnus/} - -@end enumerate - -PostScript copies of the Gnus Reference card are available from@* -@file{ftp://ftp.cs.ualberta.ca/pub/oolog/gnus/}. They are mirrored at@* -@file{ftp://ftp.pilgrim.umass.edu/pub/misc/ding/refcard/} in the -United States. And@* -@file{ftp://marvin.fkphy.uni-duesseldorf.de/pub/gnus/} -in Germany. - -An online version of the Gnus FAQ is available at@* -@file{http://www.miranova.com/~steve/gnus-faq.html}. Off-line formats -are also available:@* -ASCII: @file{ftp://ftp.miranova.com/pub/gnus/gnus-faq}@* -PostScript: @file{ftp://ftp.miranova.com/pub/gnus/gnus-faq.ps}. - - -@item -Q1.9 Gnus hangs on connecting to NNTP server - -I am running XEmacs on SunOS and Gnus prints a message about Connecting -to NNTP server and then just hangs. - -Ben Wing writes :@* -I wonder if you're hitting the infamous @emph{libresolv} problem. -The basic problem is that under SunOS you can compile either -with DNS or NIS name lookup libraries but not both. Try -substituting the IP address and see if that works; if so, you -need to download the sources and recompile. - - -@item -Q1.10 Mailcrypt 3.4 doesn't work - -This problem is verified to still exist in Gnus 5.0.9 and Mailcrypt 3.4. -The answer comes from Peter Arius -. - -I found out that mailcrypt uses -@code{gnus-eval-in-buffer-window}, which is a macro. -It seems as if you have -compiled mailcrypt with plain old GNUS in load path, and the XEmacs byte -compiler has inserted that macro definition into -@file{mc-toplev.elc}. -The solution is to recompile @file{mc-toplev.el} with Gnus 5 in -load-path, and it works fine. - -Steve Baur adds :@* -The problem also manifests itself if neither GNUS 4 nor Gnus 5 is in the -load-path. - - -@item -Q1.11 What other packages work with Gnus? - -@itemize @minus -@item -Mailcrypt. - -Mailcrypt is an Emacs interface to PGP. It works, it installs -without hassle, and integrates very easily. Mailcrypt can be -obtained from@* -@file{ftp://cag.lcs.mit.edu/pub/patl/mailcrypt-3.4.tar.gz}. - -@item -Tools for Mime. - -Tools for Mime is an Emacs MUA interface to MIME. Installation is -a two-step process unlike most other packages, so you should -be prepared to move the byte-compiled code somewhere. There -are currently two versions of this package available. It can -be obtained from@* -@file{ftp://ftp.jaist.ac.jp/pub/GNU/elisp/}. -Be sure to apply the supplied patch. It works with Gnus through -version 5.0.9. In order for all dependencies to work correctly -the load sequence is as follows: -@lisp - (load "tm-setup") - (load "gnus") - (load "mime-compose") -@end lisp - -@emph{NOTE:} Loading the package disables citation highlighting by -default. To get the old behavior back, use the @kbd{M-t} command. - -@end itemize - -@end itemize - - -@node Customization FAQ -@subsection Customization - -@itemize @bullet -@item -Q2.1 Custom Edit does not work under XEmacs - -The custom package has not been ported to XEmacs. - - -@item -Q2.2 How do I quote messages? - -I see lots of messages with quoted material in them. I am wondering -how to have Gnus do it for me. - -This is Gnus, so there are a number of ways of doing this. You can use -the built-in commands to do this. There are the @kbd{F} and @kbd{R} -keys from the summary buffer which automatically include the article -being responded to. These commands are also selectable as @i{Followup -and Yank} and @i{Reply and Yank} in the Post menu. - -@kbd{C-c C-y} grabs the previous message and prefixes each line with -@code{ail-indentation-spaces} spaces or @code{mail-yank-prefix} if that is -non-nil, unless you have set your own @code{mail-citation-hook}, which will -be called to do the job. - -You might also consider the Supercite package, which allows for pretty -arbitrarily complex quoting styles. Some people love it, some people -hate it. - - -@item -Q2.3 How can I keep my nnvirtual:* groups sorted? - -How can I most efficiently arrange matters so as to keep my nnvirtual:* -(etc) groups at the top of my group selection buffer, whilst keeping -everything sorted in alphabetical order. - -If you don't subscribe often to new groups then the easiest way is to -first sort the groups and then manually kill and yank the virtuals -wherever you want them. - - -@item -Q2.4 Any good suggestions on stuff for an all.SCORE file? - -Here is a collection of suggestions from the Gnus mailing list. - -@enumerate -@item -From ``Dave Disser'' @* -I like blasting anything without lowercase letters. Weeds out most of -the make $$ fast, as well as the lame titles like ``IBM'' and ``HP-UX'' -with no further description. -@lisp - (("Subject" - ("^\\(Re: \\)?[^a-z]*$" -200 nil R))) -@end lisp - -@item -From ``Peter Arius'' @* -The most vital entries in my (still young) all.SCORE: -@lisp -(("xref" - ("alt.fan.oj-simpson" -1000 nil s)) - ("subject" - ("\\<\\(make\\|fast\\|big\\)\\s-*\\(money\\|cash\\|bucks?\\)\\>" -1000 nil r) - ("$$$$" -1000 nil s))) -@end lisp - -@item -From ``Per Abrahamsen'' @* -@lisp -(("subject" - ;; CAPS OF THE WORLD, UNITE - ("^..[^a-z]+$" -1 nil R) - ;; $$$ Make Money $$$ (Try work) - ("$" -1 nil s) - ;; I'm important! And I have exclamation marks to prove it! - ("!" -1 nil s))) -@end lisp - -@item -From ``heddy boubaker'' @* -I would like to contribute with mine. -@lisp -( - (read-only t) - ("subject" - ;; ALL CAPS SUBJECTS - ("^\\([Rr][Ee]: +\\)?[^a-z]+$" -1 nil R) - ;; $$$ Make Money $$$ - ("$$" -10 nil s) - ;; Empty subjects are worthless! - ("^ *\\([(<]none[>)]\\|(no subject\\( given\\)?)\\)? *$" -10 nil r) - ;; Sometimes interesting announces occur! - ("ANN?OU?NC\\(E\\|ING\\)" +10 nil r) - ;; Some people think they're on mailing lists - ("\\(un\\)?sub?scribe" -100 nil r) - ;; Stop Micro$oft NOW!! - ("\\(m\\(icro\\)?[s$]\\(oft\\|lot\\)?-?\\)?wind?\\(ows\\|aube\\|oze\\)?[- ]*\\('?95\\|NT\\|3[.]1\\|32\\)" -1001 nil r) - ;; I've nothing to buy - ("\\(for\\|4\\)[- ]*sale" -100 nil r) - ;; SELF-DISCIPLINED people - ("\\[[^a-z0-9 \t\n][^a-z0-9 \t\n]\\]" +100 nil r) - ) - ("from" - ;; To keep track of posters from my site - (".dgac.fr" +1000 nil s)) - ("followup" - ;; Keep track of answers to my posts - ("boubaker" +1000 nil s)) - ("lines" - ;; Some people have really nothing to say!! - (1 -10 nil <=)) - (mark -100) - (expunge -1000) - ) -@end lisp - -@item -From ``Christopher Jones'' @* -The sample @file{all.SCORE} files from Per and boubaker could be -augmented with: -@lisp - (("subject" - ;; No junk mail please! - ("please ignore" -500 nil s) - ("test" -500 nil e)) - ) -@end lisp - -@item -From ``Brian Edmonds'' @* -Augment any of the above with a fast method of scoring down -excessively cross posted articles. -@lisp - ("xref" - ;; the more cross posting, the exponentially worse the article - ("^xref: \\S-+ \\S-+ \\S-+ \\S-+" -1 nil r) - ("^xref: \\S-+ \\S-+ \\S-+ \\S-+ \\S-+" -2 nil r) - ("^xref: \\S-+ \\S-+ \\S-+ \\S-+ \\S-+ \\S-+" -4 nil r) - ("^xref: \\S-+ \\S-+ \\S-+ \\S-+ \\S-+ \\S-+ \\S-+" -8 nil r) - ("^xref: \\S-+ \\S-+ \\S-+ \\S-+ \\S-+ \\S-+ \\S-+ \\S-+" -16 nil r) - ("^xref: \\S-+ \\S-+ \\S-+ \\S-+ \\S-+ \\S-+ \\S-+ \\S-+ \\S-+" -32 nil r) - ("^xref: \\S-+ \\S-+ \\S-+ \\S-+ \\S-+ \\S-+ \\S-+ \\S-+ \\S-+ \\S-+" -64 nil r) - ("^xref: \\S-+ \\S-+ \\S-+ \\S-+ \\S-+ \\S-+ \\S-+ \\S-+ \\S-+ \\S-+ \\S-+" -128 nil r) - ("^xref: \\S-+ \\S-+ \\S-+ \\S-+ \\S-+ \\S-+ \\S-+ \\S-+ \\S-+ \\S-+ \\S-+ \\S-+" -256 nil r) - ("^xref: \\S-+ \\S-+ \\S-+ \\S-+ \\S-+ \\S-+ \\S-+ \\S-+ \\S-+ \\S-+ \\S-+ \\S-+ \\S-+" -512 nil r)) -@end lisp - -@end enumerate - - -@item -Q2.5 What do I use to yank-through when replying? - -You should probably reply and followup with @kbd{R} and @kbd{F}, instead -of @kbd{r} and @kbd{f}, which solves your problem. But you could try -something like: - -@example -(defconst mail-yank-ignored-headers - "^.*:" - "Delete these headers from old message when it's inserted in a reply.") -@end example - - -@item -Q2.6 I don't like the default WWW browser - -Now when choosing an URL Gnus starts up a W3 buffer, I would like it -to always use Netscape (I don't browse in text-mode ;-). - -@enumerate -@item -Activate `Customize...' from the `Help' menu. - -@item -Scroll down to the `WWW Browser' field. - -@item -Click `mouse-2' on `WWW Browser'. - -@item -Select `Netscape' from the pop up menu. - -@item -Press `C-c C-c' - -@end enumerate - -If you are using XEmacs then to specify Netscape do -@lisp - (setq gnus-button-url 'gnus-netscape-open-url) -@end lisp - - -@item -Q2.7 What, if any, relation is between ``ask-server'' and ``(setq -gnus-read-active-file 'some)''? - -In order for Gnus to show you the complete list of newsgroups, it will -either have to either store the list locally, or ask the server to -transmit the list. You enable the first with - -@lisp - (setq gnus-save-killed-list t) -@end lisp - -and the second with - -@lisp - (setq gnus-read-active-file t) -@end lisp - -If both are disabled, Gnus will not know what newsgroups exists. There -is no option to get the list by casting a spell. - - -@item -Q2.8 Moving between groups is slow. - -Per Abrahamsen writes:@* - -Do you call @code{define-key} or something like that in one of the -summary mode hooks? This would force Emacs to recalculate the keyboard -shortcuts. Removing the call should speed up @kbd{M-x gnus-summary-mode -RET} by a couple of orders of magnitude. You can use - -@lisp -(define-key gnus-summary-mode-map KEY COMMAND) -@end lisp - -in your @file{.gnus} instead. - -@end itemize - - -@node Reading News FAQ -@subsection Reading News - -@itemize @bullet -@item -Q3.1 How do I convert my kill files to score files? - -A kill-to-score translator was written by Ethan Bradford -. It is available from@* -@file{http://baugi.ifi.uio.no/~larsi/ding-various/gnus-kill-to-score.el}. - - -@item -Q3.2 My news server has a lot of groups, and killing groups is painfully -slow. - -Don't do that then. The best way to get rid of groups that should be -dead is to edit your newsrc directly. This problem will be addressed -in the near future. - - -@item -Q3.3 How do I use an NNTP server with authentication? - -Put the following into your .gnus: -@lisp - (add-hook 'nntp-server-opened-hook 'nntp-send-authinfo) -@end lisp - - -@item -Q3.4 Not reading the first article. - -How do I avoid reading the first article when a group is selected? - -@enumerate -@item -Use @kbd{RET} to select the group instead of @kbd{SPC}. - -@item -@code{(setq gnus-auto-select first nil)} - -@item -Luis Fernandes writes:@* -This is what I use...customize as necessary... - -@lisp -;;; Don't auto-select first article if reading sources, or archives or -;;; jobs postings, etc. and just display the summary buffer -(add-hook 'gnus-select-group-hook - (function - (lambda () - (cond ((string-match "sources" gnus-newsgroup-name) - (setq gnus-auto-select-first nil)) - ((string-match "jobs" gnus-newsgroup-name) - (setq gnus-auto-select-first nil)) - ((string-match "comp\\.archives" gnus-newsgroup-name) - (setq gnus-auto-select-first nil)) - ((string-match "reviews" gnus-newsgroup-name) - (setq gnus-auto-select-first nil)) - ((string-match "announce" gnus-newsgroup-name) - (setq gnus-auto-select-first nil)) - ((string-match "binaries" gnus-newsgroup-name) - (setq gnus-auto-select-first nil)) - (t - (setq gnus-auto-select-first t)))))) -@end lisp - -@item -Per Abrahamsen writes:@* -Another possibility is to create an @file{all.binaries.all.SCORE} file -like this: - -@lisp -((local - (gnus-auto-select-first nil))) -@end lisp - -and insert -@lisp - (setq gnus-auto-select-first t) -@end lisp - -in your @file{.gnus}. - -@end enumerate - -@item -Q3.5 Why aren't BBDB known posters marked in the summary buffer? - -Brian Edmonds writes:@* -Due to changes in Gnus 5.0, @file{bbdb-gnus.el} no longer marks known -posters in the summary buffer. An updated version, @file{gnus-bbdb.el} -is available at the locations listed below. This package also supports -autofiling of incoming mail to folders specified in the BBDB. Extensive -instructions are included as comments in the file. - -Send mail to @file{majordomo@@edmonds.home.cs.ubc.ca} with the following -line in the body of the message: @emph{get misc gnus-bbdb.el}. - -Or get it from the World Wide Web:@* -@file{http://www.cs.ubc.ca/spider/edmonds/gnus-bbdb.el}. - -@end itemize - - -@node Reading Mail FAQ -@subsection Reading Mail - -@itemize @bullet -@item -Q4.1 What does the message ``Buffer has changed on disk'' mean in a mail -group? - -Your filter program should not deliver mail directly to your folders, -instead it should put the mail into spool files. Gnus will then move -the mail safely from the spool files into the folders. This will -eliminate the problem. Look it up in the manual, in the section -entitled ``Mail & Procmail''. - - -@item -Q4.2 How do you make articles un-expirable? - -I am using nnml to read news and have used -@code{gnus-auto-expirable-newsgroups} to automagically expire articles -in some groups (Gnus being one of them). Sometimes there are -interesting articles in these groups that I want to keep. Is there any -way of explicitly marking an article as un-expirable - that is mark it -as read but not expirable? - -Use @kbd{u}, @kbd{!}, @kbd{d} or @kbd{M-u} in the summary buffer. You -just remove the @kbd{E} mark by setting some other mark. It's not -necessary to tick the articles. - - -@item -Q4.3 How do I delete bogus nnml: groups? - -My problem is that I have various mail (nnml) groups generated while -experimenting with Gnus. How do I remove them now? Setting the level to -9 does not help. Also @code{gnus-group-check-bogus-groups} does not -recognize them. - -Removing mail groups is tricky at the moment. (It's on the to-do list, -though.) You basically have to kill the groups in Gnus, shut down Gnus, -edit the active file to exclude these groups, and probably remove the -nnml directories that contained these groups as well. Then start Gnus -back up again. - - -@item -Q4.4 What happened to my new mail groups? - -I got new mail, but I have -never seen the groups they should have been placed in. - -They are probably there, but as zombies. Press @kbd{A z} to list -zombie groups, and then subscribe to the groups you want with @kbd{u}. -This is all documented quite nicely in the user's manual. - - -@item -Q4.5 Not scoring mail groups - -How do you @emph{totally} turn off scoring in mail groups? - -Use an nnbabyl:all.SCORE (or nnmh, or nnml, or whatever) file containing: - -@example -((adapt ignore) - (local (gnus-use-scoring nil)) - (exclude-files "all.SCORE")) -@end example - -@end itemize - - diff --git a/texi/gnus-ja.texi b/texi/gnus-ja.texi deleted file mode 100644 index 8d32fd1..0000000 --- a/texi/gnus-ja.texi +++ /dev/null @@ -1,19702 +0,0 @@ -\input texinfo @c -*-texinfo-*- - -@setfilename gnus-ja -@settitle Semi-gnus 6.8.19 Manual -@synindex fn cp -@synindex vr cp -@synindex pg cp -@c @direntry -@c * Gnus-ja: (gnus-ja). The news reader gnus ($BF|K\8lHG(B). -@c @end direntry -@iftex -@finalout -@end iftex -@setchapternewpage odd - -@iftex -@iflatex -\documentclass[twoside,a4paper,openright,11pt]{book} -\usepackage[latin1]{inputenc} -\usepackage{pagestyle} -\usepackage{epsfig} -\usepackage{bembo} -\usepackage{pixidx} - -\makeindex -\begin{document} - -\newcommand{\gnuschaptername}{} -\newcommand{\gnussectionname}{} - -\newcommand{\gnusbackslash}{/} - -\newcommand{\gnusxref}[1]{See ``#1'' on page \pageref{#1}} -\newcommand{\gnuspxref}[1]{see ``#1'' on page \pageref{#1}} - -\newcommand{\gnuskindex}[1]{\index{#1}} -\newcommand{\gnusindex}[1]{\index{#1}} - -\newcommand{\gnustt}[1]{{\fontfamily{pfu}\fontsize{10pt}{10}\selectfont #1}} -\newcommand{\gnuscode}[1]{\gnustt{#1}} -\newcommand{\gnussamp}[1]{``{\fontencoding{OT1}\fontfamily{pfu}\fontsize{10pt}{10}\selectfont #1}''} -\newcommand{\gnuslisp}[1]{\gnustt{#1}} -\newcommand{\gnuskbd}[1]{`\gnustt{#1}'} -\newcommand{\gnusfile}[1]{`\gnustt{#1}'} -\newcommand{\gnusdfn}[1]{\textit{#1}} -\newcommand{\gnusi}[1]{\textit{#1}} -\newcommand{\gnusstrong}[1]{\textbf{#1}} -\newcommand{\gnusemph}[1]{\textit{#1}} -\newcommand{\gnusvar}[1]{{\fontsize{10pt}{10}\selectfont\textsl{\textsf{#1}}}} -\newcommand{\gnussc}[1]{\textsc{#1}} -\newcommand{\gnustitle}[1]{{\huge\textbf{#1}}} -\newcommand{\gnusauthor}[1]{{\large\textbf{#1}}} - -\newcommand{\gnusbullet}{{${\bullet}$}} -\newcommand{\gnusdollar}{\$} -\newcommand{\gnusampersand}{\&} -\newcommand{\gnuspercent}{\%} -\newcommand{\gnushash}{\#} -\newcommand{\gnushat}{\symbol{"5E}} -\newcommand{\gnusunderline}{\symbol{"5F}} -\newcommand{\gnusnot}{$\neg$} -\newcommand{\gnustilde}{\symbol{"7E}} -\newcommand{\gnusless}{{$<$}} -\newcommand{\gnusgreater}{{$>$}} -\newcommand{\gnusbraceleft}{{$>$}} -\newcommand{\gnusbraceright}{{$>$}} - -\newcommand{\gnushead}{\raisebox{-1cm}{\epsfig{figure=ps/gnus-head.eps,height=1cm}}} -\newcommand{\gnusinteresting}{ -\marginpar[\mbox{}\hfill\gnushead]{\gnushead} -} - -\newcommand{\gnuscleardoublepage}{\ifodd\count0\mbox{}\clearpage\thispagestyle{empty}\mbox{}\clearpage\else\clearpage\fi} - -\newcommand{\gnuspagechapter}[1]{ -{\mbox{}} -} - -\newdimen{\gnusdimen} -\gnusdimen 0pt - -\newcommand{\gnuschapter}[2]{ -\gnuscleardoublepage -\ifdim \gnusdimen = 0pt\setcounter{page}{1}\pagestyle{gnus}\pagenumbering{arabic} \gnusdimen 1pt\fi -\chapter{#2} -\renewcommand{\gnussectionname}{} -\renewcommand{\gnuschaptername}{#2} -\thispagestyle{empty} -\hspace*{-2cm} -\begin{picture}(500,500)(0,0) -\put(480,350){\makebox(0,0)[tr]{#1}} -\put(40,300){\makebox(500,50)[bl]{{\Huge\bf{#2}}}} -\end{picture} -\clearpage -} - -\newcommand{\gnusfigure}[3]{ -\begin{figure} -\mbox{}\ifodd\count0\hspace*{-0.8cm}\else\hspace*{-3cm}\fi\begin{picture}(440,#2) -#3 -\end{picture} -\caption{#1} -\end{figure} -} - -\newcommand{\gnusicon}[1]{ -\marginpar[\mbox{}\hfill\raisebox{-1.5cm}{\epsfig{figure=tmp/#1-up.ps,height=1.5cm}}]{\raisebox{-1cm}{\epsfig{figure=tmp/#1-up.ps,height=1cm}}} -} - -\newcommand{\gnuspicon}[1]{ -\margindex{\epsfig{figure=#1,width=2cm}} -} - -\newcommand{\gnusxface}[2]{ -\margindex{\epsfig{figure=#1,width=1cm}\epsfig{figure=#2,width=1cm}} -} - -\newcommand{\gnussmiley}[2]{ -\margindex{\makebox[2cm]{\hfill\epsfig{figure=#1,width=0.5cm}\hfill\epsfig{figure=#2,width=0.5cm}\hfill}} -} - -\newcommand{\gnusitemx}[1]{\mbox{}\vspace*{-\itemsep}\vspace*{-\parsep}\item#1} - -\newcommand{\gnussection}[1]{ -\renewcommand{\gnussectionname}{#1} -\section{#1} -} - -\newenvironment{codelist}% -{\begin{list}{}{ -} -}{\end{list}} - -\newenvironment{kbdlist}% -{\begin{list}{}{ -\labelwidth=0cm -} -}{\end{list}} - -\newenvironment{dfnlist}% -{\begin{list}{}{ -} -}{\end{list}} - -\newenvironment{stronglist}% -{\begin{list}{}{ -} -}{\end{list}} - -\newenvironment{samplist}% -{\begin{list}{}{ -} -}{\end{list}} - -\newenvironment{varlist}% -{\begin{list}{}{ -} -}{\end{list}} - -\newenvironment{emphlist}% -{\begin{list}{}{ -} -}{\end{list}} - -\newlength\gnusheadtextwidth -\setlength{\gnusheadtextwidth}{\headtextwidth} -\addtolength{\gnusheadtextwidth}{1cm} - -\newpagestyle{gnuspreamble}% -{ -{ -\ifodd\count0 -{ -\hspace*{-0.23cm}\underline{\makebox[\gnusheadtextwidth]{\mbox{}}\textbf{\hfill\roman{page}}} -} -\else -{ -\hspace*{-3.25cm}\underline{\makebox[\gnusheadtextwidth]{\textbf{\roman{page}\hfill\mbox{}}} -} -} -\fi -} -} -{ -\ifodd\count0 -\mbox{} \hfill -\raisebox{-0.5cm}{\epsfig{figure=ps/gnus-big-logo.eps,height=1cm}} -\else -\raisebox{-0.5cm}{\epsfig{figure=ps/gnus-big-logo.eps,height=1cm}} -\hfill \mbox{} -\fi -} - -\newpagestyle{gnusindex}% -{ -{ -\ifodd\count0 -{ -\hspace*{-0.23cm}\underline{\makebox[\gnusheadtextwidth]{\textbf{\gnuschaptername\hfill\arabic{page}}}} -} -\else -{ -\hspace*{-3.25cm}\underline{\makebox[\gnusheadtextwidth]{\textbf{\arabic{page}\hfill\gnuschaptername}}} -} -\fi -} -} -{ -\ifodd\count0 -\mbox{} \hfill -\raisebox{-0.5cm}{\epsfig{figure=ps/gnus-big-logo.eps,height=1cm}} -\else -\raisebox{-0.5cm}{\epsfig{figure=ps/gnus-big-logo.eps,height=1cm}} -\hfill \mbox{} -\fi -} - -\newpagestyle{gnus}% -{ -{ -\ifodd\count0 -{ -\makebox[12cm]{\hspace*{3.1cm}\underline{\makebox[\gnusheadtextwidth]{\textbf{\arabic{chapter}.\arabic{section}} \textbf{\gnussectionname\hfill\arabic{page}}}}} -} -\else -{ -\makebox[12cm]{\hspace*{-2.95cm}\underline{\makebox[\gnusheadtextwidth]{\textbf{\arabic{page}\hfill\gnuschaptername}}}} -} -\fi -} -} -{ -\ifodd\count0 -\mbox{} \hfill -\raisebox{-0.5cm}{\epsfig{figure=ps/gnus-big-logo.eps,height=1cm}} -\else -\raisebox{-0.5cm}{\epsfig{figure=ps/gnus-big-logo.eps,height=1cm}} -\hfill \mbox{} -\fi -} - -\pagenumbering{roman} -\pagestyle{gnuspreamble} - -@end iflatex -@end iftex - -@iftex -@iflatex -\begin{titlepage} -{ - -%\addtolength{\oddsidemargin}{-5cm} -%\addtolength{\evensidemargin}{-5cm} -\parindent=0cm -\addtolength{\textheight}{2cm} - -\gnustitle{\gnustitlename}\\ -\rule{15cm}{1mm}\\ -\vfill -\hspace*{0cm}\epsfig{figure=ps/gnus-big-logo.eps,height=15cm} -\vfill -\rule{15cm}{1mm}\\ -\gnusauthor{by Lars Magne Ingebrigtsen} -\newpage -} - -\mbox{} -\vfill - -\thispagestyle{empty} - -Copyright \copyright{} 1995,96,97 Free Software Foundation, Inc. - -Permission is granted to make and distribute verbatim copies of -this manual provided the copyright notice and this permission notice -are preserved on all copies. - -$BCx:n8"I=<($H$3$N5v2DJ8$,$9$Y$F$NJ#@=$KB8:_$9$k8B$j!"$3$N@bL@=q$N$^$C$?$/(B -$BF10l$NJ#@=$r:n$j!"G[I[$9$k$3$H$r5v2D$9$k!#(B - -Permission is granted to copy and distribute modified versions of this -manual under the conditions for verbatim copying, provided that the -entire resulting derived work is distributed under the terms of a -permission notice identical to this one. - -$BF10lJ#@=$N>r7o$N2<$G!"$=$l$K$h$C$FF@$i$l$?7k2L$r$3$N5v2DJ8$NI=<($HF10l$N(B -$B>r7o$N$b$H$GG[I[$9$k8B$j!"$3$N@bL@=q$N=$@5HG$NJ#@=$r$7!"G[I[$9$k$3$H$r5v(B -$B2D$9$k!#(B - -Permission is granted to copy and distribute translations of this manual -into another language, under the above conditions for modified versions. - -$B>e5-$N=$@5HG$K4X$9$k>r7o$N2<$G!"$3$N@bL@=q$NK]Lu$NJ#@=$r:n$j!"G[I[$9$k$3(B -$B$H$r5v2D$9$k!#(B - -\newpage -\end{titlepage} -@end iflatex -@end iftex - -@ifinfo - -This file documents gnus, the GNU Emacs newsreader. - -$B$3$N%U%!%$%k$O(B GNU Emacs $B$N%K%e!<%9%j!<%@$G$"$k(B gnus $B$K4X$9$k@bL@=q$G$9!#(B - -Copyright (C) 1995,96 Free Software Foundation, Inc. - -Permission is granted to make and distribute verbatim copies of -this manual provided the copyright notice and this permission notice -are preserved on all copies. - -$BCx:n8"I=<($H$3$N5v2DJ8$,$9$Y$F$NJ#@=$KB8:_$9$k8B$j!"$3$N@bL@=q$N$^$C$?$/(B -$BF10l$NJ#@=$r:n$j!"G[I[$9$k$3$H$r5v2D$9$k!#(B - -@ignore -Permission is granted to process this file through Tex and print the -results, provided the printed document carries copying permission -notice identical to this one except for the removal of this paragraph -(this paragraph not being relevant to the printed manual). - -$B$3$NCJMn$,H$5$l$^$;$s(B)$B!#(B - -@end ignore -Permission is granted to copy and distribute modified versions of this -manual under the conditions for verbatim copying, provided also that the -entire resulting derived work is distributed under the terms of a -permission notice identical to this one. - -$BF10lJ#@=$N>r7o$N2<$G!"$=$l$K$h$C$FF@$i$l$?7k2L$b$3$N5v2DJ8$NI=<($HF10l$N(B -$B>r7o$N$b$H$GG[I[$9$k8B$j!"$3$N@bL@=q$N=$@5HG$NJ#@=$r$7!"G[I[$9$k$3$H$r5v(B -$B2D$9$k!#(B - -Permission is granted to copy and distribute translations of this manual -into another language, under the above conditions for modified versions. - -$B>e5-$N=$@5HG$K4X$9$k>r7o$N2<$G!"$3$N@bL@=q$NK]Lu$NJ#@=$r:n$j!"G[I[$9$k$3(B -$B$H$r5v2D$9$k!#(B - -@end ifinfo - -@tex - -@titlepage -@title Semi-gnus 6.8.19 Manual - -@author by Lars Magne Ingebrigtsen -@author by members of Semi-gnus mailing-list -@page - -@vskip 0pt plus 1filll -Copyright @copyright{} 1995,96,97 Free Software Foundation, Inc. - -Permission is granted to make and distribute verbatim copies of -this manual provided the copyright notice and this permission notice -are preserved on all copies. - -$BCx:n8"I=<($H$3$N5v2DJ8$,$9$Y$F$NJ#@=$KB8:_$9$k8B$j!"$3$N@bL@=q$N$^$C$?$/(B -$BF10l$NJ#@=$r:n$j!"G[I[$9$k$3$H$r5v2D$9$k!#(B - -Permission is granted to copy and distribute modified versions of this -manual under the conditions for verbatim copying, provided that the -entire resulting derived work is distributed under the terms of a -permission notice identical to this one. - -$BF10lJ#@=$N>r7o$N2<$G!"$=$l$K$h$C$FF@$i$l$?7k2L$r$3$N5v2DJ8$NI=<($HF10l$N(B -$B>r7o$N$b$H$GG[I[$9$k8B$j!"$3$N@bL@=q$N=$@5HG$NJ#@=$r$7!"G[I[$9$k$3$H$r5v(B -$B2D$9$k!#(B - -Permission is granted to copy and distribute translations of this manual -into another language, under the above conditions for modified versions. - -$B>e5-$N=$@5HG$K4X$9$k>r7o$N2<$G!"$3$N@bL@=q$NK]Lu$NJ#@=$r:n$j!"G[I[$9$k$3(B -$B$H$r5v2D$9$k!#(B - -@end titlepage -@page - -@end tex - - -@node Top -@top The gnus Newsreader - -@ifinfo - -Gnus $B$r;H$&$3$H$K$h$C$F(B Emacs $B$G%K%e!<%9(B (news) $B$r!J$=$l$K%a!<%k(B (mail) -$B$b!KFI$`$3$H$,$G$-$^$9!#%K%e!<%9$O(B @sc{nntp}$B!"%m!<%+%k%9%W!<%k!"(Bmbox $B%U%!(B -$B%$%k$J$I$N$"$i$f$k6K0-$Jl$G$9!#(BGnus $B$O$9$Y$F$r%K%e!<%9%0(B -$B%k!<%W$N$h$&$KI=<($7$^$9!#(BGnus $B$G%a!<%k$rFI$_!"%G%#%l%/%H%j!<$r%V%i%&%:(B -$B$7!"(B@code{ftp} $B$r$9$k$3$H$,$G$-$^$9!#$"$"!"$=$l$K!"%K%e!<%9$rFI$`$3$H$5(B -$B$($G$-$^$9!*(B - -Emacs $B$,J8>O$rJT=8$9$k?M$KNO$rM?$($k$h$&$K!"(Bgnus $B$O%K%e!<%9$rFI$`?M$KNO(B -$B$rM?$($h$&$H$7$F$$$^$9!#(BGnus $B$OMxMQ$`F0:n$r$9$k$h$&$K(B gnus $B$r3HD%$9$k$3$H$r>)Ne$7$F$$$^$9!#(B -$B%W%m%0%i%`$,?M$rA`:n$9$k$Y$-$G$O$"$j$^$;$s!#?M$,%W%m%0%i%`$r;H$&!J$b$7$/(B -$B$OMtMQ$9$k!K$3$H$K$h$C$F!"$d$j$?$$$3$H$r$G$-$k$h$&$K$J$C$F$$$k$Y$-$G$9!#(B - -@end iftex - - -@menu -* Starting Up:: $B%K%e!<%9$r8+$D$1$k$N$K$O6lO+$,H<$&$+$bCN$l$J$$(B -* The Group Buffer:: $B%0%k!<%W$rA*Br$7!"9VFI$7!":o=|$9$k(B -* The Summary Buffer:: $B5-;v$rFI$_!"J]B8$7!"Ej9F$9$k(B -* The Article Buffer:: $B5-;v$rI=<($7!"07$&(B -* Composing Messages:: $B%a!<%k$H%K%e!<%9$rAw$k$?$a$N>pJs(B -* Select Methods:: Gnus $B$OA4$F$N%a%C%;!<%8$r$$$m$$$m$JA*BrJ}K!$GFI$`(B -* Scoring:: $B5-;v$KCM$r$D$1$k(B -* Various:: $B0lHLE*$J@_Dj(B -* The End:: $B$5$i$P!"$=$7$F$5$h$&$J$i(B -* Appendices:: $BMQ8l!"(BEmacs $BF~Lg!"(BFAQ$B!"Nr;K!"FbIt9=B$(B -* Index:: $BJQ?t!"4X?t!"35G0$N:w0z(B -* Key Index:: $B%-!<:w0z(B -@end menu - -@node Starting Up -@chapter gnus $B$N5/F0(B -@cindex starting up - -@kindex M-x gnus -@findex gnus -$B%7%9%F%`4IM}o$K4JC1$G$9!#$=$&!"(BEmacs $B$G(B @kbd{M-x gnus} $B$HBG$D$@$1$G$9!#(B - -@findex gnus-other-frame -@kindex M-x gnus-other-frame -$BJL$N%U%l!<%`(B (frame) $B$G(B gnus $B$r5/F0$7$?$$$H$-$O!"L?Na(B @kbd{M-x -gnus-other-frame} $B$r;H$&$3$H$,$G$-$^$9!#(B - -$B3+;O;~$K2?$+$,$&$^$/$$$+$J$$$H$-$O(B @file{~/.gnus} $B%U%!%$%k$NCf$GJQ?t$r$$(B -$B$/$D$+$$$8$/$j$^$o$5$J$1$l$P$J$i$J$$$G$7$g$&!#$3$N%U%!%$%k$O(B -@file{~/.emacs} $B$H;w$F$$$^$9$,!"$3$A$i$O(B gnus $B$,5/F0$9$k$H$-$KFI$_9~$^$l(B -$B$^$9!#(B - -$B$3$N@bL@=q$G$h$/$o$+$i$J$$MQ8l$,$G$F$-$?$H$-$O!"MQ8l$N9`(B -(@pxref{Terminology}) $B$r;2>H$7$F$/$@$5$$!#(B - -@menu -* Finding the News:: $B%K%e!<%9$re$N(B gnus $B$r:nF0$5$;$k$3$H$,$G$-$k(B -* Fetching a Group:: $B%0%k!<%W$rFI$`$?$a$@$1$K(B gnus $B$r5/F0$9$k(B -* New Groups:: Gnus $B$,?7$7$$%0%k!<%W$KBP$7$F2?$r$9$k$+(B -* Startup Files:: $B$d$C$+$$$J%9%?!<%H%"%C%W%U%!%$%k(B--@file{.newsrc} -* Auto Save:: $B%/%i%C%7%e$+$i$N2sI|(B -* The Active File:: $BCY$$2s@~$+$i$N%U%!%$%k$Nl9g$O!"(B - -@lisp -(setq gnus-select-method '(nnspool "")) -@end lisp - -$B$N$h$&$K$G$-$^$9!#(B - -$B%m!<%+%k$N%9%W!<%k$r;H$($k$N$G$"$l$P!"$+$J$j$N3NN($G$=$NJ}$,$:$C$HB.$$$G(B -$B$7$g$&$7!"$=$l$r;H$&$Y$-$G$7$g$&!#(B - -@vindex gnus-nntpserver-file -@cindex NNTPSERVER -@cindex @sc{nntp} server -$B$b$7$3$NJQ?t$,@_Dj$5$l$F$$$J$1$l$P!"(Bgnus $B$O(B @code{NNTPSERVER} $B4D6-JQ?t$r(B -$BFI$_$K$$$-$^$9!#$b$7$=$NJQ?t$,@_Dj$5$l$F$$$J$1$l$P!"(Bgnus $B$O(B -@code{gnus-nntpserver-file}$B!J@_Dj$5$l$F$$$J$$>l9g$O(B -@file{/etc/nntpserver}$B!K$,$3$N7o$K4X$7$F2?$+$r8@$C$F$$$J$$$+$rD4$Y$^$9!#(B -$B$b$7$=$l$b<:GT$7$?$J$i!"(Bgnus$B$O(B Emacs $B$,F0:n$7$F$$$k%5!<%P!<$r(B @sc{nntp} -$B%5!<%P!<$H$7$F;H$*$&$H$7$^$9!#?oJ,$JEv$F?dNL$G$9$1$I$M!#(B - -@vindex gnus-nntp-server -@code{gnus-nntp-server} $B$,@_Dj$5$l$F$$$k$H!"$3$NJQ?t$O(B -@code{gnus-select-method} $B$r>e=q$-$7$^$9!#$G$9$+$i!"(B -@code{gnus-nntp-server} $B$O(B @code{nil} $B$K@_Dj$9$k$Y$-$G!"I8=`@_Dj$G$b$=$N(B -$B$h$&$K$J$C$F$$$^$9!#(B - -@vindex gnus-secondary-servers -Gnus $B$K(B @sc{nntp} $B%5!<%P!<$NL>A0$NF~NO$rBPOCE*$K;XDj$9$k$3$H$b$G$-$^$9!#(B -@code{gnus} $B$K?tCM$G$J$$@\F,0z?t$rEO$9$H!JNc!'(B@kbd{C-u M-x gnus}$B!K!"(Bgnus -$B$O(B @code{gnus-secondary-servers} $B%j%9%H!J$b$7B8:_$9$k$J$i$P!K$+$i%5!<%P!<(B -$B$rA*$V$3$H$,$G$-$k$h$&$K$7$^$9!#$?$@C1$K@\B3$7$?$$$H;W$C$?%5!<%P!<$NL>A0(B -$B$rBG$D$3$H$b$G$-$^$9!#(B - -@findex gnus-group-browse-foreign-server -@kindex B (Group) -$B$7$+$7!"IaCJF|>oE*$K$O0l$D$N(B @sc{nntp} $B%5!<%P$r;H$$!"0c$C$?%5!<%P!<$K$O6=(B -$BL#$N$"$k%0%k!<%W$,>/$7$7$+$J$$>l9g!"%0%k!<%W%P%C%U%!$G(B @kbd{B} $BL?Na$r;H$&(B -$B$3$H$NJ}$,NI$$$G$7$g$&!#$=$l$O!"A*Br2DG=$J%0%k!<%W$rI=<($7!"$=$NCf$+$i$I$l(B -$B$G$b9%$-$J$b$N$r9XFI$9$k$3$H$,$G$-$^$9!#$3$l$O!"(B@file{.newsrc} $B$NJ];}$r$:$C(B -$B$H$d$j$d$9$/$7$^$9!#(B@xref{Foreign Groups}. - -@vindex gnus-secondary-select-methods -@c @head -$B30$N%0%k!<%W$KBP$9$k>/$70c$C$?$d$jJ}$O!"JQ?t(B -@code{gnus-secondary-select-methods} $B$r@_Dj$9$k$3$H$G$9!#$3$NJQ?t$KI=$5(B -$B$l$F$$$kA*BrJ}K!$O!"B?$/$NE@$G(B @code{gnus-select-method} $B%5!<%P!<$H$NA*(B -$BBrJ}K!$HF1$8$h$&$K07$o$l$^$9!#5/F0Cf$K%"%/%F%#%V%U%!%$%k$rC5$7$K$$$-$^$9$7(B -$B!J$b$7MW5a$5$l$F$$$l$P!K!"$3$l$i$N%5!<%P!<>e$K$G$-$??7$7$$%K%e!<%9%0%k!<(B -$B%W$O85!9$N%0%k!<%W$HF1$8$h$&$K9XFI!J$b$7$/$OIT9XFI!K$5$l$^$9!#(B - -$B$?$H$($P!"%a!<%k$rFI$`$?$a$K(B @code{nnmbox} $B%P%C%/%(%s%I(B (backend) $B$r;H$$(B -$B$?$$$H$-$O!"IaDL!"$3$NJQ?t$r!"(B - -@lisp -(setq gnus-secondary-select-methods '((nnmbox ""))) -@end lisp - -$B$H@_Dj$7$^$9!#(B - -@node The First Time -@section $B0lHV=i$a(B -@cindex first time usage - -$B5/F0MQ%U%!%$%k$,B8:_$7$J$$$H$-$O!"(Bgnus $B$O%G%#%U%)%k%H$G$I$N%0%k!<%W$,9X(B -$BFI$5$l$F$$$k$Y$-$+$r7hDj$7$h$&$H$7$^$9!#(B - -@vindex gnus-default-subscribed-newsgroups -$BJQ?t(B @code{gnus-default-sebscribed-newsgroups} $B$,@_Dj$5$l$F$$$k$H!"(Bgnus -$B$O$=$N%j%9%H$NCf$N%0%k!<%W$r9XFI$7!";D$j$r:o=|$7$^$9!#%7%9%F%`4IM}/$7$NG$0U$N%0%k!<%W$r9XFI$7$^$9!JNc!'(B -@samp{*.newusers}$B!K!#!J(B@dfn{$BG$0U(B}$B$O$3$3$G$O!"(B@dfn{Lars $B$5$s$,FI$`$Y$-$G(B -$B$"$k$H9M$($k$b$N(B}$B$H$$$&$h$&$KDj5A$5$l$F$$$^$9!K(B - -$B$^$?!"$?$$$F$$$N6&DL$NLdBj$N2r7h$N$K$$$/$D$+%a!<%k$N%0(B -$B%k!<%W$,$"$l$P!"$=$l$K$b$+$+$o$i$:(B gnus $B$r5/F0$7$?$$$H;W$&$+$b$7$l$^$;$s!#(B - -Gnus $B$O!"?.Mj$G$-$k%W%m%0%i%`$N0l$D$H$7$F!"%5!<%P!<$H@\B3$G$-$J$$$H$-$O(B -$B4pK\A*BrJ}K!$J$7$GB3$1$k$+$I$&$+$r?R$M$^$9!#$3$l$Ol9g!K$d%5!<%P!<$,2?$i$+$NM}M3$G0l(B -$B;~E*$KD4;R$,$*$+$7$/$J$C$F$$$k$H$-$K5/$3$j$^$9!#$b$7$=$N$^$^B39T$9$k$3$H(B -$B$K$7$F!"30$N%0%k!<%W$,0l$D$bL5$$>l9g!"uBV$K$7$^$9!J4pK\%0%k!<%W$G$J$$%0%k!<%W$O$=$N(B 2 $B$D$N%l%Y(B -$B%k$K$7$F$*$/$N$,K>$^$7$$$G$7$g$&!K!#(B - - -@node Slave Gnusae -@section gnus $B$r%9%l!<%V$K$9$k(B -@cindex slave - -$B$"$J$?$O(B 2 $B$D0J>e$N(B Emacs $B$H!"(B2 $B$D0J>e$N(B gnus $B$rF1;~$KF0$+$7$?$$$H;W$&$+(B -$B$b$7$l$^$;$s!#0c$C$?(B @file{.newsrc} $B%U%!%$%k$r;H$C$F$$$k$J$i!JNc$($P!"(B2 -$B$D$N0c$C$?%5!<%P!<$+$iFI$_9~$`$?$a$K!"(B2 $B$D$N0c$C$?(B gnus $B$rF0:n$5$;$F$$$k(B -$B>l9g!K!"$^$C$?$/LdBj$O$"$j$^$;$s!#$=$l$r9T$($PNI$$$@$1$G$9!#(B - -$BLdBj$O!"F1$8(B @code{.newsrc} $B%U%!%$%k$r;H$$D$N(B gnus $B$rF0$+$=$&$H$7$?$H(B -$B$-$K5/$3$j$^$9!#(B - -$B$3$NLdBj$KBP=h$9$k$?$a$K!"(Bgnus $B%?%o!<$N%7%s%/%?%s%/$K$$$k2f!9$O?7$7$$35(B -$BG0$K$?$I$j$D$-$^$7$?!#(B@dfn{$B%^%9%?!<(B} $B$H(B @dfn{$B%9%l!<%V(B} $B$G$9!#!J2f!9$O$3(B -$B$N35G0$KFC5v$r?=@A$7$^$7$?!#$=$7$F!"$=$N8@MU$NCx:n8"$rF@$^$7$?!#$*8_$$$K(B -$B4XO"$7$F$3$l$i$N8@MU$r;H$$$?$$$J$i!"#12s;H$&Kh$K!";d$K(B $1 $B$rAw$i$J$1$l$P(B -$B$J$j$^$;$s!#$b$A$m$s!"(B@dfn{$B%3%s%T%e!<%?!<%"%W%j%1!<%7%g%s$N%^%9%?!$l(B @kbd{M-x gnus-slave} $B$G5/F0(B -$B$7$^$9!#%9%l!<%V$OIaDL$N(B @file{.newsrc} $B$OJ]B8$7$^$;$s$,!"Be$o$j$K(B -@dfn{$B%9%l!<%V%U%!%$%k(B} $B$K%9%l!<%V$N5/F0Cf$K$I$N$h$&$J%0%k!<%W$,FI$^$l$?(B -$B$+$H$$$&>pJs$@$1$rJ]B8$7$^$9!#%^%9%?!<(B gnus $B$,5/F0$9$k$H$-!"$=$l$O$=$l$i(B -$B$N%9%l!<%V%U%!%$%k$rFI$_9~$_!J$=$7$F>C$7!K!"$=$l$i$+$i$9$Y$F$N>pJs$rpJs$OIaDL$N!JNc$($P!"%^%9%?!<$N!K%U%!%$(B -$B%k$h$j$bM%@h$5$l$^$9!#(B - - -@node Fetching a Group -@section $B%0%k!<%W$rA0$r0z?t$H$7$F$H$j$^$9!#(B - - -@node New Groups -@section $B?7$7$$%0%k!<%W(B -@cindex new groups -@cindex subscription - -@vindex gnus-check-new-newsgroups -$B?7$7$$%K%e!<%9%0%k!<%W$rA4$/8+$J$$$GK~B-$G$"$k$J$i$P!"(B -@code{gnus-check-new-newsgroups} $B$r(B @code{nil} $B$K@_Dj$9$k$3$H$,$G$-$^$9!#(B -$B$3$l$r@_Dj$7$?>l9g!"5/F0$K$+$+$k;~4V$,C;$/$J$j$^$9!#$3$NJQ?t$,(B nil $B$K@_(B -$BDj$5$l$F$$$F$b!"%0%k!<%W%P%C%U%!$G(B @kbd{U} $B$r2!$;$P$$$D$G$b?7$7$$%0%k!<(B -$B%W$r9XFI$9$k$3$H$,$G$-$^$9(B (@pxref{Group Maintenance})$B!#@_Dj$5$l$F$$$J$$(B -$B>l9g(B (default) $B$G$O$3$NJQ?t$O(B @code{ask-server} $B$G$9!#$3$NJQ?t$,(B -@code{always} $B$K@_Dj$5$l$F$$$k$H!"L?Na(B @kbd{g} $B$ru%U%!%$%k(B (active file) $B$rHf3S$9$k$3$H$K$h(B -$B$j7hDj$7$F$$$^$9!#$3$NJ}K!$OFC$KB.$$$H$$$&$o$1$G$O$"$j$^$;$s!#(B -@code{gnus-check-new-newsgroups} $B$,(B @code{ask-server} $B$G$"$k$H!"(Bgnus $B$O(B -$B%5!<%P!<$K!":G8e$K@\B3$7$F$+$i?7$7$$%0%k!<%W$,$G$-$F$$$k$+$I$&$+$r?R$M$^(B -$B$9!#$3$NJ}K!$OB.$$$7!"0B>e$,$j$G$9!#$3$l$K$h$j!":o=|$5$l$?%0%k!<%W$N%j%9(B -$B%H$rJ];}$7$F$*$/$3$H$+$i$+$i40A4$K3+J|$5$l$^$9!#$G$9$+$i!"(B -@code{gnus-save-killed-list} $B$r(B @code{nil} $B$K$9$k$3$H$,$G$-$k$G$7$g$&!#(B -$B$=$&$9$l$P!"5/F0!"=*N;$NN>J}!"$=$7$FA4BN$K$o$?$C$F;~4V$r@aLs$G$-$^$9!#%G%#(B -$B%9%/>CHqNL$b>/$J$/$J$j$^$9!#$=$l$J$i!"$I$&$7$F$3$l$,=i4|@_Dj(B (default) -$B$G$O$J$$$N$G$7$g$&!);DG0$J$,$i!"$9$Y$F$N%5!<%P!<$,$3$NL?Na$rM}2r$9$k$o$1(B -$B$G$O$J$$$N$G$9!#(B - -$B;d$O:#$"$J$?$,2?$r9M$($F$$$k$+$rEv$F$i$l$^$9!#$I$&$9$l$P%5!<%P!<$,(B -@code{ask-server} $B$rM}2r$9$k$+$,$o$+$k$N$G$7$g$&!)$(!"0c$&$N$G$9$+!)$"$!!"(B -$BNI$+$C$?!#$H$$$&$N$O!"3N$NJ}K!$H$7$F$O!"%5!<%P!<$K(B @code{telnet} $B$r$7$F!"(B -@code{HELP} $B$HBG$A!"%5!<%P!<$,M}2r$9$k%3%^%s%I$NCf$K(B @samp{NEWGROUPS} $B$,$"(B -$B$k$+$I$&$+$rD4$Y$k$3$H$b$G$-$^$9!#$b$7$"$l$P!"$*$=$i$/F0:n$9$k$G$7$g$&!J$7(B -$B$+$7!"E,@Z$K5!G=$rDs6!$9$k$3$H$J$/(B @samp{NEGROUPS} $B$r%j%9%H$K4^$a$k%5!<%P!<(B -$B$b$"$j$^$9!K!#(B - -$B$3$NJQ?t$O!"A*BrJ}K!$N%j%9%H$G$"$k$3$H$b$G$-$^$9!#$=$N$H$-$O!"(Bgnus $B$OL?(B -$BNa(B @code{ask-server} $B$r$=$l$>$l$NA*BrJ}K!$KBP$7$FA0(B -$B$rM#0l$N0z?t$H$7$F8F$P$l$^$9!#(B - -$B$$$/$D$+$N%s%S(B (zombie) $B$K$7$^$9!#$3$l$,=i4|@_Dj(B -(default) $B$K$J$C$F$$$^$9!#8e$G%>%s%S$r(B (@kbd{A z} $B$K$h$C$F(B) $B354Q$7$?$j!"(B -$B!J(B@kbd{S z} $B$K$h$C$F!KE,@Z$KA4$F$r:o=|$7$?$j!"!J(B@kbd{u} $B$K$h$C$F!K9XFI$7(B -$B$?$j$G$-$^$9!#(B - -@item gnus-subscribe-randomly -@vindex gnus-subscribe-randomly -$BG$0U$N=gHV$G$9$Y$F$N?7$7$$%0%k!<%W$r9XFI$7$^$9!#e!Y$K2C$($i$l$^$9!#(B - -@item gnus-subscribe-alphabetically -@vindex gnus-subscribe-alphabetically -$B$9$Y$F$N?7$7$$%0%k!<%W$r%"%k%U%!%Y%C%H=g$K9XFI$7$^$9!#(B - -@item gnus-subscribe-hierarchically -@vindex gnus-subscribe-hierarchically -$B$9$Y$F$N?7$7$$%0%k!<%W$r3,AXE*$K9XFI$7$^$9!#$3$N4X?t$H(B -@code{gnus-subscribe-alphabetically} $B$N0c$$$O>/$7$7$+$"$j$^$;$s!#(B -@code{gnus-subscribe-alphabetically} $B$O?7$7$$%0%k!<%W$r87L)$K%"%k%U%!%Y%C(B -$B%H=g$K$J$i$Y$^$9$,!"$3$N4X?t$O%0%k!<%W$r$=$N3,AX$NCf$KF~$l$^$9!#$G$9$+$i!"(B -@samp{rec} $B$N3,AX$r(B @samp{comp} $B$N3,AX$NA0$K;}$C$F$-$?$$>l9g!"$3$N4X?t$O(B -$B$=$NG[CV$r$0$A$c$0$A$c$K$O$7$^$;$s!#$b$7$/$O!"$=$N$h$&$J$b$N$G$9!#(B - -@item gnus-subscribe-interactively -@vindex gnus-subscribe-interactively -$B?7$7$$%0%k!<%W$rBPOCE*$K9XFI$7$^$9!#$3$l$O(B gnus $B$,(B @strong{$BA4$F(B} $B$N%0%k!<(B -$B%W$KBP$7$F?R$M$k$3$H$r0UL#$7$F$$$^$9!#9XFI$9$k%0%k!<%W$O3,AXE*$K9XFI$5$l(B -$B$^$9!#(B - -@item gnus-subscribe-killed -@vindex gnus-subscribe-killed -$B$9$Y$F$N?7$7$$%0%k!<%W$r:o=|$7$^$9!#(B - -@end table - -@vindex gnus-subscribe-hierarchical-interactive -$B>e$NJQ?t$HNI$/4X78$7$?JQ?t$O!"(B -@code{gnus-subscribe-hierarchical-interactive} $B$G$9!#$3$NJQ?t$,(B -@code{nil} $B$G$J$$$H!"(Bgnus $B$O3,AXE*$JJ}K!$G?7$7$$%0%k!<%W$r9XFI$9$k$+$I$&$+(B -$B$r?R$M$^$9!#(Bgnus $B$O$=$l$>$l$N3,AX$G!"$=$l$r2<$K9_$j$k$+$I$&$+$r?R$M$^$9!#(B - -$BNI$/$"$k4V0c$$$O!"?tCJMnA0$NJQ?t(B (@code{gnus-subscribe-newsgroup-method} -) $B$r(B @code{gnus-subscribe-herarchical-interactive} $B$K@_Dj$9$k$3$H$G$9!#(B -$B$3$l$O8m$j$G$9!#$3$l$OF0:n$7$^$;$s!#$3$l$O$*$a$G$?$$?M$N$9$k$3$H$G$9!#$G(B -$B$9$+$i!"@dBP$K$7$J$$$G$/$@$5$$!#(B - - -@node Filtering New Groups -@subsection $B?7$7$$%0%k!<%W$rA*JL$9$k(B - -$B$I$N?7$7$$%0%k!<%W$,9XFI!J$b$7$/$O!"L5;k!K$5$l$k$Y$-$+$r4IM}$9$k2wE,$GA0$r;}$D%0%k!<%W$OA4$FL5;k$5$l!"(B@samp{sci} $B$G;O$^$kL>A0$r;}$D%0%k!<(B -$B%W$OA4$F9XFI$9$k!"$H$$$&$3$H$rI=$7$F$$$k$+$i$G$9!#(BGnus $B$O$3$l$i$N%0%k!<(B -$B%W$r9XFI$9$k$N$K!"IaDL$N9XFIJ}K!$rMQ$$$^$;$s!#Be$o$j$K!"(B -@code{gnus-subscribe-options-newsgroup-method} $B$,MQ$$$i$l$^$9!#$3$NJQ?t(B -$B$OI8=`(B (default) $B$G$O(B @code{gnus-subscribe-alphabetically} $B$G$9!#(B - -@vindex gnus-options-not-subscribe -@vindex gnus-options-subscribe -$B%U%!%$%k(B @file{.newrc} $B$r$$$8$j$?$/$J$$>l9g$O!"(B -@code{gnus-options-subscribe} $B$H(B @code{gnus-options-not-subscribe} $B$N#2(B -$B$D$NJQ?t$@$1$r@_Dj$9$k$3$H$b$G$-$^$9!#$3$N#2$D$NJQ?t$O%U%!%$%k(B -@file{.newrc} $B$N(B @samp{optinos -n} $B9T$HA4$/F1$8$3$H$r$7$^$9!#$I$A$i$NJQ(B -$B?t$b@55,I=8=$G!"?7$7$$%0%k!<%W$OA0r7o$K9XFI$5$l!"8eJ,$J$b$N$G$9!#$7$+$7!";d$O$3$NFs$D$,$"$C$?J}$,NI$$$H;W$$$^$7(B -$B$?!#$b$&0lJ}$NJQ?t$O%f!<%6$,$$$8$/$k$N$K;H$o$l$k$N$KBP$7$F!"$3$NJQ?t$O$$(B -$B$/$D$+$N4pK\E*$J5,B'$r@_Dj$9$k$?$a$N$b$N$G$9!#%G%#%U%)%k%H$G$O$3$NJQ?t$O(B -$B%a!<%k%P%C%/%(%s%I(B (@code{nnml} $B!"(B@code{nnbabyl} $B!"(B@code{nnfolder} $B!"(B -@code{nnmbox} $B$H(B@code{nnmh}) $B$+$i$G$-$kA4$F$N?7$7$$%0%k!<%W$r9XFI$9$k$h(B -$B$&$K$J$C$F$$$^$9!#$=$l$,7y$G$"$l$P!"$3$NJQ?t$r(B @code{nil} $B$K@_Dj$7$F$/$@(B -$B$5$$!#(B - -$B$3$N@55,I=8=$K9gCW$9$k?7$7$$%0%k!<%W$O(B -@code{gnus-subscribe-options-newsgroup-method} $B$r;H$C$F9XFI$5$l$^$9!#(B - - -@node Changing Servers -@section $B%5!<%P!<$r49$($k(B -@cindex changing servers - -$B$H$-$I$-!"$"$k(B @sc{nntp} $B%5!<%P!<$+$iJL$N%5!<%P!<$X0\F0$7$J$1$l$P$J$i$J(B -$B$$$3$H$,$"$j$^$9!#$3$N$h$&$J$3$H$O$a$C$?$K$*$-$^$;$s$,!"$*$=$i$/$"$J$?$,(B -$B;E;v$rJQ$($?$j!";H$C$F$$$k%5!<%P!<$,$H$F$bIT0BDj$G!"JL$N$b$N$K>h$j49$($?(B -$B$$$H$$$&$H$-$KI,MW$K$J$k$G$7$g$&!#(B - -$B%5!<%P!<$rJQ99$9$k$N$O$H$F$b4JC1$G$9$h$M!)(B -@code{gnus-select-method} $B$r?7$7$$%5!<%P!<$r;X$7<($9$h$&$KJQ99$9$l$P$$$$(B -$B$@$1$G$9$M!)(B - -@emph{$B0c$$$^$9!*(B} - -$B5-;v$NHV9f$O0c$C$?(B @sc{nntp} $B%5!<%P!<$G$b(B ($B$I$&$K$+$7$F(B) $BF1$8$K$7$F$"$k!"(B -$B$H$$$&$3$H$O$"$j$^$;$s!#$=$7$F!"(B guns $B$,$I$N5-;v$rFI$s$@$+$r5-O?$9$kM#0l(B -$B$NJ}K!$O!"5-;vHV9f$r5-O?$9$k$3$H$G$9!#$G$9$+$i!"(B -@code{gnus-select-method} $B$rJQ99$7$?$H$-$O!"%U%!%$%k(B @file{.newsrc} $B$O0U(B -$BL#$,$J$/$J$j$^$9!#(B - -Gnus$B$O%U%!%$%k(B @file{.newsrc} $B$r$"$k%5!<%P!J}$N%5!<%P!<$K@\B3$G$-$k$J$i!"(Bgnus$B$O$"$J$?$,FI$s$@5-;vA4$F$KBP$7$F(B -$B%X%C%@!<(B (headers) $B$rMW5a$7$F!"(B@code{Message-ID} $B$rHf3S$7!"FI$s$@5-;v$H(B -$B5-;v$N0u$r?7$7$/5-O?$7$^$9!#%3%^%s%I(B @kbd{M-x gnus-change-server} $B$O$3$l(B -$B$r$9$Y$F$N4pK\%0%k!<%W$KBP$7$F9T$$$^$9!#$=$N%3%^%s%I$O0\F0@h$NJ}K!$NF~NO(B -$B$rB%$7$^$9!#(B - -@kindex M-x gnus-group-move-group-to-server -@findex gnus-group-move-group-to-server -$B8D!9$N%0%k!<%W$rL?Na(B @kbd{M-x gnus-group-move-group-to-server} $B$G0\(B -$BF0$9$k$3$H$b$G$-$^$9!#$3$l$O$"$k%5!<%P!<$+$iJL$N%5!<%P!<$X0l$D$N(B ($B30$N(B) -$B%0%k!<%W$r0\F0$7$?$$$H$-$KLr$KN)$A$^$9!#(B - -@kindex M-x gnus-group-clear-data-on-native-groups -@findex gnus-group-clear-data-on-native-groups -$B8E$$%5!<%P!<$H?7$7$$%5!<%P!<$NN>J}$K@\B3$9$k$3$H$,$G$-$J$$$H$-!"0u$HFI$s(B -$B$@HO0O$O$9$Y$F0UL#$,L5$/$J$j$^$9!#$=$N$h$&$J$H$-$O!"%3%^%s%I(B @kbd{M-x -gnus-group-clear-data-on-native-groups} $B$r;H$C$F!"4pK\%0%k!<%W$K4X$9$k%G!<(B -$B%?$r$9$Y$F>C5n$9$k$3$H$,$G$-$^$9!#$3$N%3%^%s%I$OCm0U$7$F;H$C$F$/$@$5$$!#(B - - -@node Startup Files -@section $B5/F0%U%!%$%k(B -@cindex startup files -@cindex .newsrc -@cindex .newsrc.el -@cindex .newsrc.eld - -$B:#$d!"$"$J$?$O%U%!%$%k(B @file{.newrc} $B$K$D$$$F$9$Y$FCN$C$F$$$^$9!#$9$Y$F(B -$B$N9XFI>pJs$OEAE}E*$K$3$N%U%!%$%k$KC_@Q$5$l$^$9!#(B - -@sc{GNUS} $B$G$OJ*;v$,>/!9J#;($K$J$C$F$$$^$9!#%U%!%$%k(B @file{.newsrc} $B$r:G(B -$B?7$N$b$N$K$9$k$@$1$G$O$J$/!"%U%!%$%k(B @file{.newsrc} $B$K$O9g$o$J$$>pJs$rJ](B -$BB8$7$F$*$/$?$a$K(B @file{.newsrc.el} $B$H8F$P$l$k%U%!%$%k$r;H$$$^$9!#(B ($BpJs$rJ#@=$7$FJ];}$7$F$$$^$9!#(B) -@sc{gnus}$B$O$3$l$i$NCf$G0lHV:G8e$KJ]B8$5$l$?$b$N$r;H$$$^$9!#$3$l$r$9$k$3(B -$B$H$K$h$j!"(B@sc{GNUS} $B$HB>$N%K%e!<%9%j!<%@!<$r@Z$jBX$($F;H$&$3$H$,$G$-$^$9!#(B - -$B$3$l$O$A$g$C$H$P$+$JJ}K!$J$N$G!"(BGnus $B$O$b$C$HNI$$J}K!$rJT$_=P$7$^$7$?!#(B -@file{.newsrc} $B$H(B @file{.newsrc.el} $B%U%!%$%k$K2C$($F!"(B Gnus $B$O(B -@file{.newsrc.eld} $B$H8F$P$l$k%U%!%$%k$b;}$C$F$$$^$9!#(BGnus $B$O$3$l$i$NCf$G(B -$B0lHV?7$7$$%U%!%$%k$rFI$_$^$9$,!"%U%!%$%k(B @file{.newsrc.el} $B$K=q$-9~$`$3(B -$B$H$O$"$j$^$;$s!#%U%!%$%k(B @file{.newsrc.eld} $B$O@dBP$K>C$9$Y$-$G$O$"$j$^$;(B -$B$s!#(B---$B$=$l$O%U%!%$%k(B @file{.newsrc} $B$K$O$J$$$?$/$5$s$N>pJs$rJ];}$7$F$$(B -$B$^$9!#(B - -$B$A$J$_$K!"(Bgnus $B$O2?$bJQ$($F$^$;$s!#(BLars $BF1;V!"K|:P!*(B - - -@vindex gnus-save-newsrc-file -@code{gnus-save-newsrc-file} $B$r(B @code{nil} $B$K$9$k$3$H$K$h$C$F%U%!%$%k(B -@file{.newsrc} $B$K=q$-9~$`$N$r;_$a$k$3$H$,$G$-$^$9!#$=$&$9$l$P!"$=$N%U%!(B -$B%$%k$r:o=|$9$k$3$H$,$G$-!"%G%#%9%/MFNL$r@aLs$9$k$3$H$,$G$-!"(Bgnus $B$N=*N;(B -$B$,B.$/$J$j$^$9!#$7$+$7!"$=$&$9$k$HB>$N%K%e!<%9%j!<%@!<$r;H$($J$/$J$j$^$9!#(B -$B$G$b!"$A$g$C$H!"C/$+$=$&$7$?$$?M$,$$$k$G$7$g$&$+!#(B - -@vindex gnus-save-killed-list -@code{gnus-save-killed-list} ($B%G%#%U%)%k%H(B $B$G$O(B @code{t}) $B$,(B @code{nil} -$B$G$"$k$H!"(Bgnus $B$O:o=|$5$l$?%0%k!<%W$r5/F0%U%!%$%k$KJ]B8$7$^$;$s!#$3$l$O!"(B -($B5/F0;~$H=*N;;~$N(B) $B;~4V$H!"(B($B%G%#%9%/$N(B) $BMFNL$r@aLs$7$^$9!#$3$&$9$k$H!"(B -gnus$B$,$I$N%0%k!<%W$,?7$7$$$+$N5-O?$r;}$C$F$$$J$$$3$H$K$J$j$^$9$N$G!"?7$7(B -$B$$%0%k!<%W$N<+F09XFIJ}K!$O0UL#$,L5$/$J$j$^$9!#$3$NJQ?t$r(B @code{nil} $B$K$7(B -$B$?$H$-$O!"(B@code{gnus-check-new-newsgroups} $B$r>o$K(B @code{nil} $B$+(B -@code{ask-server} $B$K$7$F$*$/$Y$-$G$7$g$&(B (@pxref{New Groups})$B!#$3$NJQ?t(B -$B$O@55,I=8=$G$"$k$3$H$b$G$-$^$9!#$=$N$h$&$J>l9g$O!"%U%!%$%k$rJ]B8$9$kD>A0(B -$B$K$=$N@55,I=8=$K9gCW$7$J$$$9$Y$F$N%0%k!<%W$r>C5n$7$^$9!#$3$l$O!"$9$Y$F$N(B -$B%5!<%P!<$,(B @code{ask-server} $B$rM}2r$9$k$o$1$G$O$J$$!"$H$$$C$?$h$&$J!"FC(B -$BDj$N$"$$$^$$$J>u67$N$H$-$KLr$KN)$D$G$7$g$&!#(B - -@vindex gnus-startup-file -$BJQ?t(B @code{gnus-startup-file} $B$O5/F0%U%!%$%k$,$I$3$K$"$k$+$r;XDj$7$^$9!#(B -$B%G%#%U%)%k%H$NCM$O(B @file{~/.newsrc} $B$G!"$=$l$,$I$N$h$&$J$b$N$G$"$l!"(B -$BKvHx$K(B @samp{.eld} $B$r$D$1$?$b$N$,(B gnus (El Dingo) $B$N5/F0%U%!%$%k$K$J$j$^(B -$B$9!#(B - -@vindex gnus-save-newsrc-hook -@vindex gnus-save-quick-newsrc-hook -@vindex gnus-save-standard-newsrc-hook -@code{gnus-save-newsrc-hook} $B$O(B newsrc $B%U%!%$%k$NCf$N$I$l$+$rJ]B8$9$kA0$KA0(B -$B$N%U%!%$%k$rD4$Y$^$9$,!"@\Hx8l(B @file{.elc} $B$H(B @file{.el} $B$,$D$$$F$$$k$b(B -$B$N$bD4$Y$^$9!#8@$$49$($l$P!"(B@code{gnus-init-file} $B$r(B @file{~/.gnus} $B$K@_(B -$BDj$9$k$H!"(Bgnus $B$O(B ($B$3$N=gHV$K(B) @file{~/.gnus.elc} $B!"(B@file{~/.gnus.el} $B$r(B -$BC5$7!":G8e$K(B @file{~/.gnus} $B$rC5$7$^$9!#(B - - - -@node Auto Save -@section $B<+F0J]B8(B -@cindex dribble file -@cindex auto-save - -$B2?$+(B gnus $B$N%G!<%?$rJQ99$9$k$3$H(B ($B5-;v$rFI$`!"0u$rIU$1$k!"%0%k!<%W$r:o=|(B -$B$^$?$O9XFI$9$k(B) $B$r$7$?$H$-!"JQ99$OFCJL$J(B@dfn{$B%I%j%V%k%P%C%U%!(B (dribble -buffer)} $B$K=q$-9~$^$l$^$9!#$3$N%P%C%U%!$O(BEmacs $B$,IaDL$9$k$h$&$K<+F0J]B8(B -$B$5$l$^$9!#%U%!%$%k(B @file{.newsrc} $B$rJ]B8$9$kA0$K(B Emacs$B$,Mn$A$?$H$-$O!"$9(B -$B$Y$F$NJQ99$r$3$N%U%!%$%k$+$i2sI|$9$k$3$H$,$G$-$k$G$7$g$&!#(B - -$B5/F0;~$K(B gnus $B$,$3$N%U%!%$%k$NB8:_$rH/8+$9$k$H!"(Bgnus $B$O$=$l$rFI$_9~$`$+(B -$B$I$&$+$rMxMQu%U%!%$%k(B -@cindex active file -@cindex ignored groups - -Gnus $B$O5/F0$7$?$H$-$d!"u%U%!%$%k$rFI$_9~$_$^$9!#$3$l$O$H$F$bBg$-$J%U%!%$%k$G!"$=$N(B -$B%5!<%P!<$N3hF0Cf$N%0%k!<%W$H5-;v$N$9$Y$F$N%j%9%H$,F~$C$F$$$^$9!#(B - -@vindex gnus-ignored-newsgroups -$B8=>u%U%!%$%k$r8!::$9$kA0$K!"(Bgnus $B$O@55,I=8=(B -@code{gnus-ignored-newsgroups} $B$K9g$&$9$Y$F$N9T$r:o=|$7$^$9!#$3$l$OA0$r;}$D%0%k!<%W$rGS=|$9$k$?$a$K;H$o$l$F$-$^$7$?$,!"6=L#$NL5$$%0%k!<(B -$B%W$N3,AX$rL5;k$9$k$?$a$K;H$&$3$H$b$G$-$^$9!#$7$+$7!"$3$l$O$*4+$a$G$-$^$;(B -$B$s!#K\Ev$N$3$H$r8@$&$H!"A4$/;?@.$G$-$^$;$s!#Be$o$j$K!"$=$N$h$&$JMQES$KMQ(B -$B$$$i$l$kJQ?t$N35N,$rCN$k$?$a$K!"(B@pxref{New Groups} $B$r;2>H$7$F$/$@$5$$!#(B - -@c This variable is -@c @code{nil} by default, and will slow down active file handling somewhat -@c if you set it to anything else. - -@vindex gnus-read-active-file -@c @head -$B8=>u%U%!%$%k$OHf3SE*Bg$-$/$J$k798~$,$"$k$N$G!"CY$$2s@~$r;H$C$F$$$k$H$-$O!"(B -$B8=>u%U%!%$%k$rFI$_9~$^$J$$$h$&$K(B @code{gnus-read-active-file} $B$r(B -@code{nil} $B$K@_Dj$9$k$3$H$,$G$-$^$9!#$3$NJQ?t$O%G%#%U%)%k%H$G$O(B -@code{some} $B$G$9!#(B - -$B$=$N$h$&$J;~$O!"(Bgnus $B$OpJs$@$1$rF@(B -$B$F$d$C$F$$$3$&$H$7$^$9!#(B - -$B5$$rIU$1$F$[$7$$$N$O!"$"$J$?$,;3$[$I$N$?$/$5$s$N%0%k!<%W$r9XFI$7$F$$$k$H(B -$B$-$K$3$NJQ?t$r(B @code{nil} $B@_Dj$9$k$H!"(Bgnus $B$OB.$/$J$k$I$3$m$+!"CY$/$J$C(B -$B$F$7$^$&$H$$$&$3$H$G$9!#8=>u$G$O!"%K%e!<%9$r(B 2400bps $B0J>e$N%b%G%`$rDL$7(B -$B$FFI$s$G$$$k$N$G$J$$8B$j!"(Bgnus $B$NB.EY$O$+$J$jCY$/$J$k$G$7$g$&!#(B - -$B$3$NJQ?t$O(B @code{some} $B$H$$$&CM$bu$N>pJs$r9XFI$5$l$F$$$k%0%k!<%W$N$b$N$@$1$rF@$h$&$H$7$^$9!#$$$/$D$+$N%5!<(B -$B%P!<(B ($BL?Na(B@code{LIST ACTIVE group} $B$r;H$&$3$H$N$G$-$k!":G?71T$N(B INN $B%5!<(B -$B%P!<(B) $B$G$O!"Hs>o$KAa$/$J$k$G$7$g$&$,!"B>$N%5!<%P!<$G$OB.$/$O$"$j$^$;$s!#(B -$B$I$N$h$&$K$;$h!"CY$$2s@~$G$O(B @code{some} $B$O(B @code{nil} $B$h$j$bB.$/!"$=$l(B -$B$O$b$A$m$s(B@code{t} $B$h$j$bB.$/$J$j$^$9!#(B - -$B$b$7$3$NJQ?t$,(B @code{nil} $B$G$"$k$H!"(Bgnus $B$O40A4$K$,$s$8$,$i$a$NJ}K!$G%0(B -$B%k!<%W$N>pJs$rF@$h$&$H$7$^$9!#$=$7$F!"$3$l$O$"$^$jB.$/$"$j$^$;$s!#$b$7$=(B -$B$l$,(B @code{some} $B$G(B @sc{nntp} $B%5!<%P!<$r;H$C$F$$$k$H$-$O!"(Bgnus $B$O$G$-$k(B -$B$@$1B.$/L?Na$r=P$7!"0l7b$G$9$Y$F$NJVEz$rFI$_9~$_$^$9!#$3$NJ}$,IaDL$O$h$j(B -$BNI$$7k2L$r$b$?$i$7$^$9$,!"%5!<%P!<$,L?Na(B @code{LIST ACTIVE group} $B$rM}2r(B -$B$7$J$$$J$i!"%5!<%P!<$K$H$C$F$O$"$^$jNI$$$H$O8@$($^$;$s!#(B - -@code{some} $B$+(B @code{nil} $B$r;H$&$N$G$"$l$P!"$I$A$i$K$7$mB.EY$r>e$2$k$?$a(B -$B$K$9$Y$F$N6=L#$NL5$$%0%k!<%W$rI,$::o=|$9$k$Y$-$G$7$g$&!#(B - -$B$3$NJQ?t$O#2HVL\$N(B (secondary) $BJ}K!$N8=>u%U%!%$%kH$7$F$/$@$5$$(B)$B!#(B - -@item gnus-inhibit-startup-message -@vindex gnus-inhibit-startup-message -$B$b$7(B @code{nil} $B$G$J$$$H!"5/F0;~$N%a%C%;!<%8$OI=<($5$l$^$;$s!#$=$N$h$&$K(B -$B$9$l$P!";E;v$NBe$o$j$K%K%e!<%9$rFI$s$G$$$k$N$r>e;J$K5$IU$+$l$K$/$/$J$k$G(B -$B$7$g$&!#$3$NJQ?t$O(B @file{.gnus.el} $B$,%m!<%I$5$l$kA0$K;H$o$l$^$9$N$G!"(B -@code{.emacs} $B$K@_Dj$9$k$Y$-$G$"$kE@$rCm0U$7$F$/$@$5$$!#(B - -@item gnus-no-groups-message -@vindex gnus-no-groups-message -$B%0%k!<%W$,0l$D$bB8:_$7$J$$$H$-$K(B gnus $B$,I=<($9$k%a%C%;!<%8$G$9!#(B - -@item gnus-play-startup-jingle -@vindex gnus-play-startup-jingle -$B$b$7(B @code{nil} $B$G$J$$$H!"5/F0;~$K(B gnus $B$NC;$$6J$r1iAU$7$^$9!#(B - -@item gnus-startup-jingle -@vindex gnus-startup-jingle -$B>e$NJQ?t$,(B @code{nil} $B$G$J$$$H$-$K1iAU$5$l$kC;$$6J$G$9!#%G%#%U%)%k%H$O(B -@samp{Tuxdemoon.Jingle4.au} $B$G$9!#(B - -@end table - - -@node The Group Buffer -@chapter $B%0%k!<%W%P%C%U%!(B -@cindex group buffer - -$B%0%k!<%W%P%C%U%!(B @dfn{group buffer} $B$OM-8z$J%0%k!<%W$rA4It!J$"$k$$$O0lIt$r!K(B -$B0lMwI=<($7$^$9!#$3$l$O(B gnus $B$r5/F0$7$?$H$-$K:G=i$KI=<($5$l$k%P%C%U%!$G!"(B -gnus $B$,@8$-$F$$$k8B$j7h$7$F>C$5$l$k$3$H$O$"$j$^$;$s!#(B - - -@iftex -@iflatex -\gnusfigure{The Group Buffer}{320}{ -\put(75,50){\epsfig{figure=tmp/group.ps,height=9cm}} -\put(120,37){\makebox(0,0)[t]{Buffer name}} -\put(120,38){\vector(1,2){10}} -\put(40,60){\makebox(0,0)[r]{Mode line}} -\put(40,58){\vector(1,0){30}} -\put(200,28){\makebox(0,0)[t]{Native select method}} -\put(200,26){\vector(-1,2){15}} -} -@end iflatex -@end iftex - -@menu -* Group Buffer Format:: $BI=<($5$l$F$$$k>pJs$HJQ99$NJ}K!!#(B -* Group Maneuvering:: $B%0%k!<%W%P%C%U%!$r0\F0$9$k%3%^%s%I!#(B -* Selecting a Group:: $BpJs$rJQ99$9$k!#(B -* Subscription Commands:: $B9XFI!"9XFICf;_!">C5n!#(B -* Group Levels:: $B%l%Y%k!)$=$l$C$F2?!)(B -* Group Score:: $B$"$J$?$N9%$-$J%0%k!<%W$r8+$D$1=P$9J}K!!#(B -* Marking Groups:: $B%0%k!<%W$K0u$r$D$1$F$*$$$F!"8e$G=hM}$G$-$^$9!#(B -* Foreign Groups:: $B%0%k!<%W$N:n@.$H=$@5!#(B -* Group Parameters:: $B%0%k!<%WKh$K0c$C$?%Q%i%a!<%?$r;}$?$;$i$l$^$9!#(B -* Listing Groups:: Gnus $B$O%0%k!<%W$r$$$m$$$m$JJ,$1J}$GI=<($G$-$^$9!#(B -* Sorting Groups:: $B%0%k!<%W$N=gHV$NG[CVBX$(!#(B -* Group Maintenance:: $B$-$l$$$J(B @file{.newsrc} $B$NJ]$AJ}!#(B -* Browse Foreign Server:: $B%5!<%P$r354Q$G$-$k!#2?$,FI$a$k$N$+8+$F$_$h$&!#(B -* Exiting Gnus:: $B%K%e!<%9FI$`$N$r$d$a$F!";E;v$r$7$h$&!#(B -* Group Topics:: $B%0%k!<%W$r@Z$j:.$<$F!"%H%T%C%/$4$H$KJ,3d$9$k!#(B -* Misc Group Stuff:: $BB>$K$G$-$k$3$H!#(B -@end menu - - -@node Group Buffer Format -@section $B%0%k!<%W%P%C%U%!$N7A<0(B - -@menu -* Group Line Specification:: $B%0%k!<%W%P%C%U%!$N8+$(J}$r7h$a$k!#(B -* Group Modeline Specification:: $B%0%k!<%W%P%C%U%!$N%b!<%I9T!#(B -* Group Highlighting:: $B%0%k!<%W%P%C%U%!$K$-$l$$$K?'$r$D$1$k!#(B -@end menu - - -@node Group Line Specification -@subsection $B%0%k!<%W9T$N;EMM(B -@cindex group buffer format - -$B%0%k!<%W%P%C%U%!$N%G%U%)%k%H$G$N7A<0$O$-$l$$$G$D$^$s$J$$$1$I!"$3(B -$B$l$O7/$N9%$-$J$h$&$K!"%5%$%3!<$K%@%5$/$9$k$3$H$b$G$-$^$9!#(B - -$B$3$l$,%0%k!<%W9T$NNc$G$9!#(B - -@example - 25: news.announce.newusers - * 0: alt.fan.andrea-dworkin -@end example - -$B$H$C$F$b4JC1$G$7$g!)(B - -@samp{news.announce.newusers} $B$K$O(B 25 $B$NL$FI5-;v$,$"$k$N$,$o$+$j$^$9!#(B -@samp{alt.fan.andrea-dworkin} $B$K$OL$FI5-;v$O$J$$$1$l$I$b!"0u$r$D$1$?5-;v$,(B -$B$$$/$D$+$"$j$^$9!J9TF,$N$A$C$A$c$J%"%9%?%j%9%/$,8+$($k!)!K!#(B - -@vindex gnus-group-line-format -$B$3$N7A<0$O(B @code{gnus-group-line-format} $BJQ?t$r$$$8$k$3$H$G!"$I$s$JIw$K$G(B -$B$bJQ$($i$l$^$9!#$3$NJQ?t$O(B @code{format} $B$N;EMMIw$KF0:n$7$^$9!#$D$^$j!J$"(B -$B$N%/%=!K(BC $B8@8l$r;H$&?M$?$A$N$?$a!"(Bprintf $B$N;EMM$H$[$\F1$8$G$9!#(B -@xref{Formatting Variables} - -@samp{%M%S%5y: %(%g%)\n} $B$H$$$&CM$G>e5-$N9T$r@8@.$7$^$9!#(B - -$B%3%m%s$O!"$3$N9T$NCf$KI,$:L5$/$F$O$$$1$^$;$s!#%+!<%=%k$O!"2?$+$NA`:n$r$7$?(B -$B8e$O>o$K%3%m%s$N$H$3$m$K0\F0$9$k$+$i$G$9!#B>$K$O2?$bI,MW$G$O$"$j$^$;$s!=!=(B -$B%0%k!<%WL>$5$($b$G$9!#I=<($5$l$F$$$kJ8;z$OA4$F$?$@$N2hLL$N>~$j$G$"$j!"(B -gnus $B$,$=$l$rD4$Y$k$3$H$O$"$j$^$;$s!#(BGnus $B$OI,MW$H$9$kA4$F$NpJs$r!"%F%-(B -$B%9%HB0@-$r;H$C$F21$($F$$$^$9!#(B - - -$B!J$b$77/$,!"$9$4$/%X%s$J!"AG@2$i$7$$!"I=7W;;Iw$N%l%$%"%&%H$r:n$C$?$H$7$?$i!"(B -$B$_$s$J!"7/$O2q7W$N;E;v$,K;$7$/$C$F!"%K%e!<%9$rFI$s$G;~4V$rL5BL;H$$$7$?$j$J(B -$B$s$+$7$F$J$$!"$C$F?.$8$F$/$l$k$h!#!K(B - -$B0J2<$,;HMQ$G$-$k%U%)!<%^%C%HJ8;z$N%j%9%H$G$9!#(B - -@table @samp - -@item M -$B$=$N%0%k!<%W$,0u$N$D$$$?5-;v$@$1$N$H$-$O!"%"%9%?%j%9%/J8;z!#(B - -@item S -$B$=$N%0%k!<%W$,9XFI$5$l$F$$$k$+$I$&$+!#(B - -@item L -$B9XFIEY$N%l%Y%k!#(B - -@item N -$BL$FI5-;v$N?t!#(B - -@item I -$BJ]N15-;v$N?t!#(B - -@item T -$B0uIU$-5-;v$N?t!#(B - -@item R -$B4{FI5-;v$N?t!#(B - -@item t -$B?dDjA45-;v?t!J$3$l$O$N%U%k%M!<%`!#(B - -@item G -$B%0%k!<%WL>!#(B - -@item D -$B%K%e!<%9%0%k!<%W$N@bL@!#(B - -@item o -$B%b%G%l!<%F%C%I$N>l9g(B @samp{m}. - -@item O -$B%b%G%l!<%F%C%I$N>l9g(B @samp{(m)}. - -@item s -$BA*Br%a%=%C%I!#(B - -@item n -$B$I$3$+$i$NA*Br$+!#(B - -@item z -$B30ItA*Br%a%=%C%I$,;H$o$l$F$$$k>l9g!"(B@samp{<%s:%n>} $B$HF1$8J8;zNs!#(B - -@item P -$B%H%T%C%/(B (@pxref{Group Topics}) $B$N%l%Y%k$K1~$8$?;z2<$2!#(B - -@item c -@vindex gnus-group-uncollapsed-levels -$BC;$$!J>JN,$7$?!K%0%k!<%WL>!#(B@code{gnus-group-uncollapsed-levels} $BJQ?t$O!"(B -$B$I$N%l%Y%k$^$G%0%k!<%WL>$rA4It;D$9$+$r<($7$^$9!#%G%U%)%k%H$O(B 1 $B$G$9!=!=$3(B -$B$N0UL#$O!"(B@samp{gnu.emacs.gnus} $B$N$h$&$J%0%k!<%WL>$r(B @samp{g.emacs.gnus} -$B$KC;=L$9$k$H$$$&$3$H$G$9!#(B - -@item m -@vindex gnus-new-mail-mark -@cindex % -$B$=$N%0%k!<%W$K:G6a?7Ce%a!<%k$,FO$$$F$$$k>l9g$O(B @samp{%} -(@code{gnus-new-mail-mark})$B!#(B - -@item d -$B:G8e$K$$$D$3$N%0%k!<%W$rFI$s$@$+$r<($9J8;zNs(B (@pxref{Group Timestamp})$B!#(B - -@item u -$BMxMQ$N3F;XDjJ8;z(B -$B$N>pJs$HF1MM$K!"%P%C%U%!$KA^F~$5$l$kJ8;zNs$rJV$5$J$1$l$P$J$j$^$;$s!#(B -@end table - -@cindex * -$BA4$F$N!V!A$N?t!W$N;XDj$G!"$b$7$=$N>pJs$,MxMQ$G$-$J$$>l9g$K$O%"%9%?%j%9%/(B -(@samp{*}) $B$,Kd$a$i$l$^$9!=!=Nc$($P!"5/F0$5$l$F$$$J$$30It%0%k!<%W$d!"IT@5(B -$B$J%M%$%F%#%V%0%k!<%W$N>l9g$G$9!#(B - - -@node Group Modeline Specification -@subsection $B%0%k!<%W%b!<%I9T$N;EMM(B -@cindex group modeline - -@vindex gnus-group-mode-line-format -$B%b!<%I9T$O(B @code{gnus-group-mode-line-format} (@pxref{Mode Line -Formatting}) $B$r@_Dj$9$k$3$H$GJQ99$G$-$^$9!#$3$$$D$O;XDjJ8;z$r$"$s$^$j$?(B -$B$/$5$sCN$C$F$^$;$s!#(B - -@table @samp -@item S -$B4pK\%K%e!<%9%5!<%P!2A$5$l$k$b$N$J$i!"$=$N9T$KBP$7$F(B @var{face} $B$,;HMQ$5$l$^$9!#(B - -$B0J2<$,$3$NJQ?t$NCM$NNc$G$9!#$3$l$OGX7J$,0E$$@_Dj$G$O$-$l$$$K8+$((B -$B$k$+$bCN$l$^$;$s!#(B - -@lisp -(face-spec-set 'my-group-face-1 - '((t (:foreground "Red" :bold t)))) -(face-spec-set 'my-group-face-2 - '((t (:foreground "SeaGreen" :bold t)))) -(face-spec-set 'my-group-face-3 - '((t (:foreground "SpringGreen" :bold t)))) -(face-spec-set 'my-group-face-4 - '((t (:foreground "SteelBlue" :bold t)))) -(face-spec-set 'my-group-face-5 - '((t (:foreground "SkyBlue" :bold t)))) - -(setq gnus-group-highlight - '(((> unread 200) . my-group-face-1) - ((and (< level 3) (zerop unread)) . my-group-face-2) - ((< level 3) . my-group-face-3) - ((zerop unread) . my-group-face-4) - (t . my-group-face-5))) -@end lisp - -@pxref{Faces and Fonts} $B$b;2>H$7$F$/$@$5$$!#(B - -$B$3$N(B form $B$,I>2A$5$l$k$H$-$KF0E*$KB+G{$5$l$F$$$kJQ?t$K$O0J2<$N$b(B -$B$N$,$"$j$^$9!#(B - - -@table @code -@item group -$B%0%k!<%WL>!#(B -@item unread -$B$=$N%0%k!<%W$NL$FI5-;v$N?t!#(B -@item method -$BA*Br%a%=%C%I!#(B -@item mailp -$B$=$N%0%k!<%W$,%a!<%k$N%0%k!<%W$+$I$&$+!#(B -@item level -$B$=$N%0%k!<%W$N%l%Y%k!#(B -@item score -$B$=$N%0%k!<%W$N%9%3%"!#(B -@item ticked -$B$=$N%0%k!<%WCf$N0u$NIU$$$?5-;v$N?t!#(B -@item total -$B$=$N%0%k!<%WCf$NA45-;v?t!#$b$C$H@53N$K8@$&$H!"(BMAX-NUMBER - MIN_NUMBER + -1. -@item topic -$B%H%T%C%/%^%$%J!<%b!<%I$r;HMQ$7$F$$$k;~!"$3$NJQ?t$OA^F~$5$l$F$$(B -$B$k8=:_$N%H%T%C%/$KB+G{$5$l$^$9!#(B -@end table - -$B$3$N(B form $B$,I>2A(B (@code{eval}) $B$5$l$k$H$-$O!"%]%$%s%H$OLdBj$N%0%k!<%W$N9T(B -$BF,$K$"$j$^$9!#=>$C$F!"DL>o$N(B gnus $B$N4X?t$N$[$H$s$I$r;H$C$F$=$N%0%k!<%W$N>p(B -$BJs$r.$5$$%l%Y%k!K$NL$FI%0%k!<%W$K0\F0$7$^(B -$B$9(B(@code{gnus-group-prev-unread-group-same-level})$B!#(B - -@item M-p -@kindex M-p (Group) -@findex gnus-group-next-unread-group-same-level -$B.$5$$%l%Y%k(B)$B$NL$FI%0%k!<%W$K0\F0$7$^$9(B -(@code{gnus-group-next-unread-group-same-level})$B!#(B -@end table - -$B.$5$$%l%Y%k$NL$FI%0%k!<%W$K%8%c%s%W$7$^$9(B -(@code{gnus-group-best-unread-group})$B!#(B - -@item . -@kindex . (Group) -@findex gnus-group-first-unread-group -$B:G=i$NL$FI5-;v$N$"$k%0%k!<%W$K%8%c%s%W$7$^$9(B -(@code{gnus-group-first-unread-group})$B!#(B -@end table - -@vindex gnus-group-goto-unread -@code{gnus-group-goto-unread} $B$,(B @code{nil} $B$K$9$k$H!"A4$F$N0\F0(B -$B%3%^%s%I$O!"e5-$N%3%^%s%I$HF1$8F0:n$r$7$^$9$,!"!V%4%?%4%?!W$O:GDc8B$K$7$h$&$H$7(B -$B$^$9(B (@code{gnus-group-quick-select-group})$B!#%9%3%"!&(Bkill $B$N=hM}$O9T$o$l$:!"(B -$B%O%$%i%$%H$b5-;v>C5n$b$7$^$;$s!#$3$l$O!"$"$J$?$,K\Ev$K5^$$$G$$$F!"$I$C$+$N(B -$B$d$?$i$G$C$+$$%0%k!<%W$KF~$i$J$1$l$P$$$1$J$$$H$-$KLr$KN)$D$+$b$7$l$^$;$s!#(B -$B$^$?!"%W%l%U%#%C%/%9$K(B 0 $B$rM?$($l$P!J$9$J$o$A(B @kbd{0 M-RET}$B!K!"(Bgnus $B$O%5%^(B -$B%j%P%C%U%!$r:n$m$&$H$5$($7$^$;$s!#$3$l$O%5%^%j%P%C%U%!$r:n$kA0$K%9%l%C%II=(B -$B<($r@Z$jBX$($?$$$H$-Lr$KN)$A$^$9(B (@pxref{Summary Generation Commands})$B!#(B - -@item M-SPACE -@kindex M-SPACE (Group) -@findex gnus-group-visible-select-group -$B$3$l$O(B @kbd{RET} $B%3%^%s%I$HF1$8F0:n$r$9$k$5$i$K$b$&0l$D$N%3%^%s(B -$B%I$G$9$,!"$3$N%3%^%s%I$O5-;v>C5n$HJ]N15-;v$r1#$9=hM}$r9T$$$^$;$s(B -(@code{gnus-group-visible-select-group})$B!#(B - -@item M-C-RET -@kindex M-C-RET (Group) -@findex gnus-group-select-group-ephemerally -$B:G8e$K$3$N%3%^%s%I$O!"8=:_$N%0%k!<%W$r0lEY8B$j!"$=$NFbMF$K0l@Z$N(B -$B=hM}$r$9$k$3$H$N$J$$$h$&$KA*Br$7$^$9(B -(@code{gnus-group-select-group-ephemerally})$B!#(B $B%9%l%C%II=<($5(B -$B$($b9T$o$l$^$;$s!#$3$NJ}K!$GA*Br$7$?8e$K$3$N%0%k!<%W$KBP$7$F9T$C(B -$B$?$3$H$OA4$F!"$=$N8e$K1F6A$rM?$($k$3$H$O$"$j$^$;$s!#(B - -@end table - -@vindex gnus-large-newsgroup -@code{gnus-large-newsgroup} $BJQ?t$O!"2?$rBg$-$J%0%k!<%W$H9M$($k$Y$-$+!"$r(B -gnus $B$KM?$($^$9!#$3$l$O(B $B%G%U%)%k%H$G$O(B 200 $B$G$9!#%0%k!<%W$K!JL$FI$H0uIU$-(B -$B$N!K5-;v$,$3$N?t0J>e$"$l$P!"(Bgnus $B$O$=$N%0%k!<%W$KF~$kA0$KMxMQl9g$K$O!"9XFI$r;_$a$^$9(B -(@code{gnus-group-unsubscribe-group})$B!#(B - -@item S k -@itemx C-k -@kindex S k (Group) -@kindex C-k (Group) -@findex gnus-group-kill-group -@c @icon{gnus-group-kill-group} -$B8=:_$N%0%k!<%W$r(B kill $B$7$^$9(B (@code{gnus-group-kill-group})$B!#(B - -@item S y -@itemx C-y -@kindex S y (Group) -@kindex C-y (Group) -@findex gnus-group-yank-group -$B:G8e$K(B kill $B$7$?%0%k!<%W$r(B yank $B$7$^$9(B -(@code{gnus-group-yank-group})$B!#(B - -@item C-x C-t -@kindex C-x C-t (Group) -@findex gnus-group-transpose-groups -$BFs$D$N%0%k!<%W$N=g=x$rCV$-49$($^$9(B -(@code{gnus-group-transpose-groups})$B!#(B $B$3$l$O%[%s%H$O9XFI%3%^%s(B -$B%I$G$O$"$j$^$;$s$,!"(Bkill $B$H(B yank $B$r2?EY$+B3$1$kBe$o$j$K$3$N%3%^(B -$B%s%I$,;H$($^$9!#(B - -@item S w -@itemx C-w -@kindex S w (Group) -@kindex C-w (Group) -@findex gnus-group-kill-region -$B%j!<%8%g%sFb$NA4$F$N%0%k!<%W$r(B kill $B$7$^$9(B -(@code{gnus-group-kill-region})$B!#(B - -@item S z -@kindex S z (Group) -@findex gnus-group-kill-all-zombies -$BA4$F$N%>%s%S%0%k!<%W$r(B kill $B$7$^$9(B -(@code{gnus-group-kill-all-zombies})$B!#(B - -@item S C-k -@kindex S C-k (Group) -@findex gnus-group-kill-level -$B$"$k%l%Y%k$N%0%k!<%W$rA4$F(B kill $B$7$^$9(B -(@code{gnus-group-kill-level})$B!#(B kill $B$7$?8e!"$3$l$i$N%0%k!<%W$r(B -yank $B$GLa$9$3$H$O$G$-$J$$$N$G!"$3$N%3%^%s%I$O$$$/$i$+Cm0U$7$F;H$C(B -$B$F$/$@$5$$!#$3$N%3%^%s%I$,K\Ev$KJXMx$K$J$k$N$O!"(B@file{.newsrc} -$B$KH$7$F$/$/$@$5$$!#(B - - -@node Group Data -@section $B%0%k!<%W%G!<%?(B - -@table @kbd - -@item c -@kindex c (Group) -@findex gnus-group-catchup-current -@vindex gnus-group-catchup-group-hook -@c @icon{gnus-group-catchup-current} -$B$=$N%0%k!<%WFb$NA4$F$NL50u$N5-;v$r4{FI$K$9$k(B -(@code{gnus-group-catchup-current})$B!#%0%k!<%W%P%C%U%!$+$i4{FI$K$7$?>l9g$O(B -@code{gnus-group-catchup-group-hook} $B$,8F$S=P$5$l$^$9!#(B - -@item C -@kindex C (Group) -@findex gnus-group-catchup-current-all -$B$=$N%0%k!<%W$NA45-;v$r!"0uIU$-$N5-;v$b4^$a$F4{FI$K$7$^$9(B -(@code{gnus-group-catchup-current-all})$B!#(B - -@item M-c -@kindex M-c (Group) -@findex gnus-group-clear-data -$B8=:_$N%0%k!<%W$NA4$F$N%G!<%?$r%/%j%"$7$^$9!=!=%^!<%/$H4{FI5-;v$N%j%9%H$r>C(B -$B$75n$j$^$9(B (@code{gnus-group-clear-data})$B!#(B - -@item M-x gnus-group-clear-data-on-native-groups -@kindex M-x gnus-group-clear-data-on-native-groups -@findex gnus-group-clear-data-on-native-groups -$B$b$7(B @sc{nntp} $B%5!<%P$rJL$N$b$N$K@Z$jBX$($?$H$9$k$H!"A4$F$N%^!<%/$H4{FI>p(B -$BJs$O$b$&Lr$K$ON)$A$^$;$s!#$3$N%3%^%s%I$r;H$C$F%M%$%F%#%V%0%k!<%W$NA4$F$N%G!<(B -$B%?$r%/%j%"$9$k$3$H$,$G$-$^$9!#Cm0U$7$F;H$C$F$M!#(B - -@end table - - -@node Group Levels -@section $B%0%k!<%W%l%Y%k(B -@cindex group level -@cindex level - -$BA4$F$N%0%k!<%W$O9XFIEY(B @dfn{subscribedness} $B$N%l%Y%k$r;}$A$^$9!#(B -$BNc$($P!"$"$k%0%k!<%W$,%l%Y%k(B 2 $B$@$H$9$l$P!"$=$l$O%l%Y%k(B 5 $B$N%0%k!<(B -$B%W$h$j$b!V$h$j9XFI$7$F$$$k!W$H$$$&$3$H$G$9!#(BGnus $B$KBP$7$F!"$"$k(B -$B%l%Y%k$+$=$l$h$j>.$5$$%l%Y%k$N%0%k!<%W$N$_0lMwI=<($9$k$h$&$KMj$`(B -$B$3$H$b$G$-$k$7(B (@pxref{Listing Groups})$B!"$"$k%l%Y%k$+$=$l$h$j>.(B -$B$5$$%l%Y%k$N%0%k!<%W$N?7Ce5-;v$N$_$r3NG'$9$k$3$H$b$G$-$^$9(B -(@pxref{Scanning New Messages})$B!#(B - -$BK:$l$J$$$G(B: $B%0%k!<%W$N%l%Y%k$,Bg$-$$$[$I!"=EMWEY$ODc$/$J$k$H$$$&$3$H!#(B - -@table @kbd - -@item S l -@kindex S l (Group) -@findex gnus-group-set-current-level -$B8=:_$N%0%k!<%W$N%l%Y%k$r@_Dj$9$k!#?t;z%W%l%U%#%C%/%9$,M?$($i$l$k(B -$B$H!"$=$3$+$i(B @var{n} $B8D$N%0%k!<%W$N%l%Y%k$,@_Dj$5$l$^$9!#%l%Y%k(B -$B$rF~NO$9$k$?$a$N%W%m%s%W%H$,=P$^$9!#(B - -@end table - -@vindex gnus-level-killed -@vindex gnus-level-zombie -@vindex gnus-level-unsubscribed -@vindex gnus-level-subscribed -Gnus $B$O%l%Y%k(B 1 $B$+$i(B @code{gnus-level-subscribed}$B!J$3$NCM$r4^$`!K!J%G%U%)(B -$B%k%H$O(B 5$B!K$^$G$N%0%k!<%W$r9XFI!"(B@code{gnus-level-subscribed}$B!J$3$NCM$r4^$^(B -$B$J$$!K$+$i(B@code{gnus-level-unsubscribed}$B!J$3$NCM$r4^$`!K!J%G%U%)%k%H$O(B 7$B!K(B -$B$^$G$N%0%k!<%W$rHs9XFI!"(B@code{gnus-level-zombie} $B$r%>%s%S!JJb$/;S!K!J%G%U%)(B -$B%k%H$O(B 8$B!K!"(B@code{gnus-level-killed} $B$r(B kill $B$5$l$F$$$k!J40A4$K;`$s$G$k!K(B -$B!J%G%U%)%k%H$O(B 9$B!K$HH=CG$7$^$9!#(BGnus $B$O9XFI$HHs9XFI$N%0%k!<%W$OA4$/F1MM$K(B -$B07$$$^$9$,!"%>%s%S$H(B kill $B%0%k!<%W$O!"$I$N5-;v$rFI$s$@$+!"B8:_$9$k$+$J$I$N(B -$B>pJs$r0l@Z;}$A$^$;$s!#$3$N;`$s$G$k%0%k!<%W$H@8$-$F$k%0%k!<%W$N6hJL$O!"JL$K(B -$B$=$l$,$-$l$$$@$+$i$H$+8-$$$+$i$H$$$&$o$1$G$O$J$/!"=c?h$K8zN(E*$JM}M3$N$?$a(B -$B$G$9!#(B - -$B%a!<%kMQ$N%0%k!<%W$O!J$b$7$"$l$P!KHs>o$K>.$5$$%l%Y%k!JNc$($P(B 1 $B$+(B 2$B!K$K$7(B -$B$F$*$/$3$H$r$*4+$a$7$^$9!#(B - -$B$b$7%l%Y%kJQ?t$GM7$S$?$$$N$G$"$l$P!"B?>/Cm0U$r$7$F$^$o$kI,MW$,$"(B -$B$j$^$9!#0lC6$=$l$r@_Dj$7$?$i!"FsEY$H$=$l$K?($i$J$$$G$/$@$5$$!#$5(B -$B$i$K8@$($P!"<+J,$G2?$r$d$C$F$$$k$+$r@53N$KM}2r$7$F$$$J$$8B$j!"0l(B -$B@Z?($i$J$$$G$/$@$5$$!#(B - -@vindex gnus-level-default-unsubscribed -@vindex gnus-level-default-subscribed -$B?H6a$K4X78$9$k(B2$B$D$NJQ?t$O(B @code{gnus-level-default-subscribed}$B!J%G%U%)%k%H(B -$B$O(B 3$B!K$H(B @code{gnus-level-default-unsubscribed}$B!J%G%U%)%k%H$O(B 6$B!K$G$9!#$3(B -$B$l$i$O?7$7$$%0%k!<%W$,!JHs!K9XFI$5$l$?$H$-$N%l%Y%k$G$9!#$b$A$m(B -$B$s!"$3$l$i#2$D$NJQ?t$NCM$O!"0UL#$N$"$k@5$7$$HO0O$G$J$/$F$O$J$j$^$;$s!#(B - -@vindex gnus-keep-same-level -@code{gnus-keep-same-level} $B$,(B @code{nil} $B0J30$G$"$l$P!"0\F0%3%^%s%I$N$$$/(B -$B$D$+$OF10l!J$"$k$$$O$=$l$h$j>.$5$$!K%l%Y%k$N%0%k!<%W$N$_$N0\F0$K$J$j$^$9!#(B -$BFC$K!"$"$k%0%k!<%W$N:G8e$N5-;v$+$i.$5$$!K%l%Y%k$N%0%k!<%W$K0\F0$7$^$9!#$3$l$O;D$j$N%0%k!<%W$rFI$`(B -$B$h$j@h$K!"$h$j=EMW$J%0%k!<%W$rFI$s$G$*$-$?$$$H$-$K$OJXMx$+$b$7$l$^$;$s!#(B - -@vindex gnus-group-default-list-level -$B%G%U%)%k%H$G$O(B @code{gnus-group-default-list-level} $B$HF1$8$+$=$l(B -$B$h$j>.$5$$%l%Y%k$N%0%k!<%W$,!"%0%k!<%W%P%C%U%!$K0lMwI=<($5$l$^$9!#(B - -@vindex gnus-group-list-inactive-groups -@code{gnus-group-list-inactive-groups} $B$,(B @code{nil} $B0J30$G$"$l(B -$B$P!"L$FI$N%0%k!<%W$K0l=o$K%"%/%F%#%V$G$J$$%0%k!<%W$bI=<($7$^$9!#(B -$B$3$NJQ?t$O%G%U%)%k%H$G(B @code{t} $B$G$9!#$b$7$3$l$,(B @code{nil} $B$G$"(B -$B$l$P!"%"%/%F%#%V$G$J$$%0%k!<%W$OI=<($5$l$^$;$s!#(B - -@vindex gnus-group-use-permanent-levels -@code{gnus-group-use-permanent-levels} $B$,(B @code{nil} $B0J30$G$"$l(B -$B$P!"0lC6%l%Y%k$r(B @kbd{g} $B$d(B @kbd{l} $B$N%W%l%U%#%C%/%9$KM?$($k$H!"(B -$B$=$N8e$NA4$F$N%3%^%s%I$K$*$$$F$=$N%l%Y%k$,!V:nMQ$9$k!W%l%Y%k$K$J(B -$B$j$^$9!#(B - - -@vindex gnus-activate-level -Gnus $B$ODL>o!"(B@code{gnus-activate-level} $B$+$=$l$h$j>.$5$$%l%Y%k$N%0%k!<%W$N(B -$B$_$r5/F0$7$^$9!J$D$^$j%5!<%P$KLd$$9g$o$;$r$9$k!K!#9XFI$7$F$$$J$$%0%k!<%W$r(B -$B5/F0$7$?$/$J$1$l$P!"$3$NJQ?t$rNc$($P(B 5 $B$K@_Dj$9$k$H$h$$$+$b$7$l$^$;$s!#%G(B -$B%U%)%k%H$O(B 6 $B$G$9!#(B - -@node Group Score -@section $B%0%k!<%W$N%9%3%"(B -@cindex group score -@cindex group rank -@cindex rank - -$BIaDL$O=EMW$J%0%k!<%W$O9b%l%Y%k$K$7$F$*$/$G$7$g$&$1$l$I$b!"$3$NJ}(B -$BK!$G$O>/!9@)8B$,$-$D$$$G$9$h$M!#$R$g$C$H$7$?$i!"%0%k!<%W$r$I$l$/(B -$B$i$$IQHK$KFI$`$+$K$h$C$F%0%k!<%W%P%C%U%!$r%=!<%H$7$?$$$J$"!"$J$s(B -$B$F;W$o$J$$!)M}$K$+$J$C$F$k$G$7$g!)(B - -$B%0%k!<%W%9%3%"(B @dfn{group score} $B$O$=$N$?$a$N$b$N$G$9!#$=$l$>$l$N%0%k!<%W(B -$B$KBP$7$F%9%3%"$r;XDj$9$k$3$H$,$G$-$^$9!#$=$7$F%0%k!<%W%P%C%U%!$r$3$N%9%3%"(B -$B$r4p$K%=!<%H$9$k$3$H$,$G$-$^$9!#$"$k$$$O!"%9%3%"=g$G%=!<%H$7$F$=$N8e%l%Y%k(B -$B$G%=!<%H$9$k$3$H$b$G$-$^$9!#!J%l%Y%k$H%9%3%"$r$R$H$^$H$a$K$7$F!"%0%k!<%W$N(B -$B%i%s%/(B @dfn{rank} $B$H8F$S$^$9!#%l%Y%k$,(B 4 $B$G%9%3%"$,(B 1 $B$N%0%k!<%W$O!"%l%Y%k(B -$B$,(B 5 $B$G%9%3%"$,(B 300 $B$N%0%k!<%W$h$j$b9b$$%i%s%/$H$J$j$^$9!#!J%l%Y%k$NJ}$,=E(B -$BMWEY$,9b$/!"%9%3%"$NJ}$O=EMWEY$,Dc$/$J$j$^$9!#!K!K(B - -@findex gnus-summary-bubble-group -$BIQHK$KFI$`%0%k!<%W$K!"$a$C$?$KFI$^$J$$%0%k!<%W$h$j$b9b$$%9%3%"$rM?$($?$$$H(B -$B$-$O!"(B@code{gnus-summary-exit-hook} $B%U%C%/$K(B -@code{gnus-summary-bubble-group} $B4X?t$rDI2C$9$k$3$H$,$G$-$^$9!#$3$l$G%P%V(B -$B%k%=!<%H$Nl9g$G!"$=$l$i$,%0%k!<(B -$B%W%P%C%U%!$KO"B3$7$F$"$k>l9g$K$O!"DL>oDL$jL?Na$KBP$7$F?t;z%W%l%U%#%C%/%9$r(B -$BM?$($k$@$1$G$9!#$=$&$9$l$P$[$H$s$I$N%0%k!<%W%3%^%s%I$O!"$3$l$i$N%0%k!<%W$K(B -$BBP$7$F$"$J$?$NL?Na$K=>$$$^$9!#(B - -$B$7$+$7$=$l$i$N%0%k!<%W$,=gHV$KJB$s$G$$$J$$>l9g$K$*$$$F$b!"$$$/$D$+$N%0%k!<(B -$B%W$KBP$7$FL?Na$rH$7$F$/$@$5$$!#(B - -@findex gnus-group-universal-argument -$B%W%m%;%9%^!<%/$,IU$1$i$l$F$$$kA4$F$N%0%k!<%W$KBP$7$F2?$+$NL?Na$rR2p$7$^$9!#$3$l$i$N(B -$BL?Na$OA4$F!"?75,$K:n@.$7$?%0%k!<%W$r%]%$%s%H0LCV$KA^F~$7$^$9!=!=(B -@code{gnus-subscribe-newsgroup-method} $B$O;2>H$5$l$^$;$s!#(B - -@table @kbd - -@item G m -@kindex G m (Group) -@findex gnus-group-make-group -@cindex making groups -$B?7$7$$%0%k!<%W$r:n@.$7$^$9(B (@code{gnus-group-make-group})$B!#(BGnus $B$O%W%m%s(B -$B%W%H$rI=<($7$F!"L>A0$H%a%=%C%I$H!">l9g$K$h$C$F$O(B @dfn{address} $B$NF~NO$r(B -$B5a$a$F$-$^$9!#$h$j4JC1$K(B @sc{nntp} $B%0%k!<%W$r9XFI$9$kJ}K!$O!"(B -@pxref{Browse Foreign Server} $B$r;2>H$7$F$/$@$5$$!#(B - -@item G r -@kindex G r (Group) -@findex gnus-group-rename-group -@cindex renaming groups -$B8=:_$N%0%k!<%W$NL>A0$r!"2?$+JL$N$b$N$KJQ99$7$^$9(B -(@code{gnus-group-rename-group})$B!#$3$l$O$"$ko$KCY$$$3$H(B -$B$bM-$jF@$^$9!#(B - -@item G c -@kindex G c (Group) -@cindex customizing -@findex gnus-group-customize -$B%0%k!<%W%Q%i%a!<%?$r%+%9%?%^%$%:$9$k(B (@code{gnus-group-customize})$B!#(B - -@item G e -@kindex G e (Group) -@findex gnus-group-edit-group-method -@cindex renaming groups -$B8=:_$N%0%k!<%W$NA*Br%a%=%C%I$r=$@5$9$k$?$a$N%P%C%U%!$K0\F0$7$^$9(B -(@code{gnus-group-edit-group-method})$B!#(B - -@item G p -@kindex G p (Group) -@findex gnus-group-edit-group-parameters -$B%0%k!<%W%Q%i%a!<%?$r=$@5$9$k$?$a$N%P%C%U%!$K0\F0$7$^$9(B -(@code{gnus-group-edit-group-parameters})$B!#(B - -@item G E -@kindex G E (Group) -@findex gnus-group-edit-group -$B%0%k!<%W>pJs$r=$@5$9$k$?$a$N%P%C%U%!$K0\F0$7$^$9(B -(@code{gnus-group-edit-group})$B!#(B - -@item G d -@kindex G d (Group) -@findex gnus-group-make-directory-group -@cindex nndir -$B%G%#%l%/%H%j%0%k!<%W$r:n@.$7$^$9(B (@pxref{Directory Groups})$B!#%G%#%l%/%H%j(B -$BL>$r%W%m%s%W%HF~NO$7$^$9(B (@code{gnus-group-make-directory-group})$B!#(B - -@item G h -@kindex G h (Group) -@cindex help group -@findex gnus-group-make-help-group - -Gnus $B%X%k%W%0%k!<%W$r:n@.$7$^$9(B (@code{gnus-group-make-help-group})$B!#(B - -@item G a -@kindex G a (Group) -@cindex (ding) archive -@cindex archive group -@findex gnus-group-make-archive-group -@vindex gnus-group-archive-directory -@vindex gnus-group-recent-archive-directory -Gnus $B%"!<%+%$%V%0%k!<%W$r:n@.$7$^$9(B -(@code{gnus-group-make-archive-group})$B!#%G%U%)%k%H$G$O:G$b:G6a$N5-;v$r;X(B -$B$7$F$$$k%0%k!<%W$,:n@.$5$l$^$9$,(B -(@code{gnus-group-recent-archive-directory})$B!"%W%l%U%#%C%/%9$rM?$($k$HA4(B -$B$F$N5-;v$r4^$`%0%k!<%W$,(B @code{gnus-group-archive-directory} $B$r4p$K:n@.(B -$B$5$l$^$9!#(B - -@item G k -@kindex G k (Group) -@findex gnus-group-make-kiboze-group -@cindex nnkiboze -kiboze $B%0%k!<%W$r:n@.$7$^$9!#%W%m%s%W%H$GL>A0$H!"(Bkiboze $B%0%k!<%W$K!V4^$a$?(B -$B$$!W%0%k!<%W$K%^%C%A$9$k@55,I=8=$H!"%X%C%@$H%^%C%A$9$kJ8;zNs$NAH$rF~NO$7(B -$B$^$9(B (@code{gnus-group-make-kiboze-group})$B!#(B@xref{Kibozed Groups}$B!#(B - -@item G D -@kindex G D (Group) -@findex gnus-group-enter-directory -@cindex nneething -$BG$0U$N%G%#%l%/%H%j$r(B @code{nneething} $B%P%C%/%(%s%I%K%e!<%9%0%k!<%W$G$"$k(B -$B$+$N$h$&$KFI$_9~$_$^$9(B (@code{gnus-group-enter-directory})$B!#(B -@xref{Anything Groups}. - -@item G f -@kindex G f (Group) -@findex gnus-group-make-doc-group -@cindex ClariNet Briefs -@cindex nndoc -$B%U%!%$%k$J$I$r$b$H$K%0%k!<%W$r:n@.$7$^$9(B -(@code{gnus-group-make-doc-group})$B!#$3$N%3%^%s%I$K%W%l%U%#%C%/%9$rM?$($?>l(B -$B9g!"%U%!%$%kL>$H%U%!%$%k%?%$%W$r%W%m%s%W%H$GF~NO$7$^$9!#8=:_%5%]!<%H$5$l$F(B -$B$$$k%U%!%$%k%?%$%W$O!"(B@code{babyl}, @code{mbox}, @code{digest}, -@code{mmdf}, @code{news}, @code{rnews}, @code{clari-briefs}, -@code{rfc934}, @code{rfc822-forward}, @code{forward} $B$G$9!#%W%l%U%#%C%/%9(B -$B$J$7$G$3$N%3%^%s%I$rl9g$K$O!"(B@samp{~g -alt.sysadmin.recovery shaving} $B$N$h$&$J%^%C%A$9$kJ8;zNs$rMQ$$$k$3$H$K$h$C(B -$B$F!"8!:wBP>]$rFCDj$N%0%k!<%W$K8BDj$9$k$3$H$,2DG=$G$9!#(B - -@item G DEL -@kindex G DEL (Group) -@findex gnus-group-delete-group -$B$3$N4X?t$O8=:_$N%0%k!<%W$r:o=|$7$^$9(B (@code{gnus-group-delete-group})$B!#%W(B -$B%l%U%#%C%/%9$,M?$($i$l$k$H!"$3$N4X?t$O$=$N%0%k!<%WFb$NA45-;v$rK\Ev$K:o=|$7!"(B -$B%0%k!<%W<+?H$r$3$N@$$+$i6/@)E*$KKu;&$7$F$7$^$$$^$9!#%W%l%U%#%C%/%9$O!"$"$J(B -$B$?$,2?$r$d$m$&$H$7$F$$$k$+!"K\Ev$K<+?.$,$"$k$H$-$K$N$_;H$C$F$/$@$5$$!#$^$"!"(B -$B$3$N%3%^%s%I$O!J(B@code{nntp} $B%0%k!<%W$N$h$&$J!KFI$_=P$7@lMQ%0%k!<%W$K$O;H$((B -$B$^$;$s$1$I!#(B - -@item G V -@kindex G V (Group) -@findex gnus-group-make-empty-virtual -$B?7$7$$!"?7A/$J!"6u$N(B @code{nnvirtual} $B%0%k!<%W$r:n@.$7$^$9(B -(@code{gnus-group-make-empty-virtual})$B!#(B@xref{Virtual Groups}. - -@item G v -@kindex G v (Group) -@findex gnus-group-add-to-virtual -$B8=:_$N%0%k!<%W$r(B @code{nnvirtual} $B%0%k!<%W$KDI2C$7$^$9(B -(@code{gnus-group-add-to-virtual})$B!#$3$l$O%W%m%;%9%^!<%/!&%W%l%U%#%C%/%9%k!<(B -$B%k$K=>$$$^$9!#(B - -@end table - -$B$5$^$6$^$JA*Br%a%=%C%I$K4X$9$k$5$i$J$k>pJs$O(B @xref{Select Methods} $B$r;2(B -$B>H$7$F$/$@$5$$!#(B - -@vindex gnus-activate-foreign-newsgroups -$B$b$7(B @code{gnus-activate-foreign-newsgroups} $B$,@5$N?t$G$"$l$P!"(Bgnus $B$O5/(B -$BF0;~$K!"$3$N?t$+$=$l$h$j$b>.$5$$%l%Y%k$N30It%0%k!<%W$rA4$F%A%'%C%/$7$^$9!#(B -$B$3$l$OFC$K0c$C$?(B @sc{nntp} $B%5!<%P$+$i$?$/$5$s$N%0%k!<%W$r9XFI$7$F$$$k>l(B -$B9g$J$I!"$7$P$i$/;~4V$,$+$+$k$+$b$7$l$^$;$s!#(B@pxref{Group Levels} $B$b;2>H(B -$B$7$F2<$5$$!#(B@code{gnus-activate-level} $B$b30It%K%e!<%9%0%k!<%W$N3hF02=$K(B -$B1F6A$r5Z$\$7$^$9!#(B - - -@node Group Parameters -@section $B%0%k!<%W%Q%i%a!<%?(B -@cindex group parameters - -$B%0%k!<%W%Q%i%a!<%?$O!"$"$kFCDj$N%0%k!<%W%m!<%+%k$J>pJs$r3JG<$7$^$9!#0J2<$O(B -$B%0%k!<%W%Q%i%a!<%?%j%9%H$NNc$G$9!'(B - -@example -((to-address . "ding@@gnus.org") - (auto-expire . t)) -@end example - -$B$=$l$>$l$NMWAG$O!XE@BP!Y(B(dotted pair)$B!=!=$D$^$jE@(B (dot) $B$NA0$K80!"E@$N8e$m(B -$B$KCM$,$"$k$b$N!"$G9=@.$5$l$^$9!#A4$F$N%Q%i%a!<%?$O$3$N7A<0$ro$N%j%9%H$K$J$j$^$9!#(B - -$B0J2<$OMxMQ2DG=$J%0%k!<%W%Q%i%a!<%?$G$9!'(B - -@table @code -@item to-address -@cindex to-address -$B%U%)%m!<%"%C%W$H%K%e!<%9$X$NEj9F$r$9$k$H$-$K;HMQ$5$l$k%"%I%l%9!#(B - -@example -(to-address . "some@@where.com") -@end example - -$B$3$l$OZ$5$l$k$N$G!";22Ce$K$"$C$?$H$7$^$7$g$&!#$3$l$OK\Ev$N%K%e!<%9%0%k!<%W$G$9$,!"%5!<%P$O%a!<(B -$B%k%K%e!<%9%2!<%H%&%'%$$rDL$7$F5-;v$r@\Ej9F$9$k$3$H$OIT2DG=$G!"Be$o$j$K$=$N%a!<%j%s%0%j%9%H$K%a!<%k$rAw(B -$B?.$7$J$1$l$P$J$j$^$;$s!#(B - -@item to-list -@cindex to-list -$B$=$N%0%k!<%W$G(B @kbd{a} $B$r2!$7$?$H$-$K;HMQ$5$l$k%"%I%l%9!#(B - -@example -(to-list . "some@@where.com") -@end example - -$B$3$l$O%U%)%m!<%"%C%W$r$7$?$H$-$O40A4$KL5;k$5$l$^$9!=!=Nc30$O$=$l$,%K%e!<%9(B -$B%0%k!<%W$rI=$o$7$F$$$k$H$-$O!"(B@kbd{f} $B$r2!$7$?$H$-$K%a!<%k%0%k!<%W$N%k!<%k(B -$B$,E,MQ$5$l$k$H$$$&$3$H$G$9!#(B - -$B$b$7(B @kbd{a} $B%3%^%s%I$r%a!<%k%0%k!<%W$Go$KI=<($5$l$^$9!#(B - -@item broken-reply-to -@cindex broken-reply-to -@code{(broken-reply-to . t)} $B$H$$$&MWAG$,$"$l$P!"$=$N%0%k!<%W$G$O(B -@code{Reply-To} $B$OL5;k$5$l$k!"$H$$$&0UL#$G$9!#$3$l$O$"$k(B listserv $B$K$h$k%a!<(B -$B%j%s%0%j%9%H$r9XFI$7$F$$$F!"$=$l$,(B @code{Reply-To} $BMs$r(B listserv $B<+?H$KJV(B -$B$9$h$&$K$D$1$i$l$F$$$k>l9g$KM-8z$G$7$g$&!#$3$l$O$*$+$7$J?6$kIq$$$G$9!#$@$+(B -$B$i$3$l$,MW$k$s$G$9!*(B - -@item to-group -@cindex to-group -@code{(to-group . "some.group.name")} $B$H$$$&MWAG$O!"$=$N%0%k!<%W$X$NEj9F(B -$B$OA4$F(B @code{some.group.name} $B$KAw$i$l$k!"$H$$$&0UL#$G$9!#(B - -@item newsgroup -@cindex newsgroup -$B%0%k!<%W%Q%i%a!<%?%j%9%H$K(B @code{(newsgroup . t)} $B$,$"$l$P!"(Bgnus $B$OA4$F$N(B -$B%l%9%]%s%9$r%K%e!<%95-;v$KBP$9$k%l%9%]%s%9$G$"$k$+$N$h$&$K07$$$^$9!#$3$l$O(B -$B$NJ}K!$K$D$$$F$O(B -@pxref{Expiring Mail} $B$r;2>H$7$F$/$@$5$$!#(B - -@item total-expire -@cindex total-expire -$B%0%k!<%W%Q%i%a!<%?$K(B @code{(total-expire . t)} $B$N$h$&$JMWAG$,$"$l$P!"4{(B -$BFI5-;v$O!"%(%/%9%Q%$%"$N%^!<%/$,$D$$$F$$$J$/$H$bA4$F%(%/%9%Q%$%"=hM}$r;\(B -$B$5$l$^$9!#Cm0U$7$F;HMQ$7$F$/$@$5$$!#L$FI5-;v!"0uIU$-5-;v!"J]N15-;v$O%(%/(B -$B%9%Q%$%"$5$l$^$;$s!#(B - -@item expiry-wait -@cindex expiry-wait -@vindex nnmail-expiry-wait-function -$B%0%k!<%W%Q%i%a!<%?$K(B @code{(expiry-wait . 10)} $B$N$h$&$JMWAG$,$"$l$P!"$3$N(B -$BCM$O5-;v$r%(%/%9%Q%$%"$9$k$H$-$K(B @code{nnmail-expiry-wait} $B$H(B -@code{nnmail-expiry-wait-function} $B$N@_Dj$h$j$bM%@h$5$l$^$9!#$3$NCM$O%(%/(B -$B%9%Q%$%"$NF|?t!J@0?t$G$"$kI,MW$O$J$$!K$+$b$7$/$O(B @code{never} $B$+(B -@code{immediate} $B$N%7%s%\%k$r;XDj$G$-$^$9!#(B - -@item score-file -@cindex score file group parameter -@code{(score-file . "file")} $B$N$h$&$JMWAG$O!"(B@file{file} $B$r8=:_$N%0%k!<%W(B -$B$KE,MQ$5$l$k%9%3%"%U%!%$%k$K$7$^$9!#E,MQ$5$l$k%9%3%"%(%s%H%j$OA4$F$3$N%U%!(B -$B%$%k$KF~$j$^$9!#(B - -@item adapt-file -@cindex adapt file group parameter -@code{(adapt-file . "file")} $B$N$h$&$JMWAG$O!"(B@file{file} $B$r8=:_$N%0%k!<%W(B -$B$NE,MQ%U%!%$%k$K$7$^$9!#A4$F$NE,MQ%9%3%"%(%s%H%j$O$3$N%U%!%$%k$KF~$j$^$9!#(B - -@item admin-address -$B%a!<%j%s%0%j%9%H$+$iC&2q$9$k$H$-$O!"C&2qDLCN%a!<%k$r$=$N%a!<%j%s%0%j%9%H(B -$B<+?H$KAw?.$7$F$O$$$1$^$;$s!#Be$o$j$K4IM}MQ%"%I%l%9$K%a%C%;!<%8$rAw?.$7$^(B -$B$9!#$3$N%Q%i%a!<%?$K$O$I$3$+JXMx$J4IM}MQ%"%I%l%9$r=q$$$F$*$/$3$H$,$G$-$^$9!#(B - -@item display - @code{(display . MODE)} $B$N$h$&$JMWAG$O!"%0%k!<%W$KF~$k$H$-$K$I$N5-;v$r(B -$BI=<($9$k$+$r;XDj$7$^$9!#M-8z$JCM$O!"(B - -@table @code -@item all -$BL$FI!"4{FI5-;v$NN>J}$rA4$FI=<($7$^$9!#(B - -@item default -$B%G%U%)%k%H$NI=<(5-;v$rI=<($7$^$9!#$3$l$ODL>o$OL$FI5-;v$H0uIU$-5-;v$G$9!#(B -@end table - -@item comment -@code{(comment . "This is a comment")} $B$N$h$&$JMWAG$O!"$=$N%0%k!<%W$KBP$9(B -$B$kG$0U$N%3%a%s%H$G$9!#$3$l$O8=:_$N(B gnus $B$G$OL5;k$5$l$^$9$,!"FCDj$N%0%k!<%W(B -$B$KBP$9$k>pJs$r3JG<$9$k>l=j$rDs6!$7$^$9!#(B - -@item @var{(variable form)} -$B%0%k!<%W$KF~$k$H$-$K!"$=$N%0%k!<%W%m!<%+%k$NJQ?t$r@_Dj$9$k%0%k!<%W%Q%i%a!<(B -$B%?$r;HMQ$9$k$3$H$,$G$-$^$9!#(B@samp{news.answers} $B$K$*$$$F%9%l%C%II=<($r9T(B -$B$$$?$/$J$$$H$-$O!"$=$N%0%k!<%W$K%0%k!<%W%Q%i%a!<%?$K(B -@code{(gnus-show-threads nil)} $B$H=q$1$^$9!#(B @code{gnus-show-threads} $B$O!"(B -$B$=$N%5%^%j%P%C%U%!$NCf$N%m!<%+%kJQ?t$K$J$j!"(Bform $B$N(B @code{nil} $B$O$=$3$G(B -$BI>2A$5$l$^$9!#(B - -$B$3$l$O$b$7I,MW$G$"$l$P!"%0%k!<%WKh$N%U%C%/4X?t$H$7$F$b;HMQ$G$-$^$9!#$b$7$"(B -$B$k%0%k!<%W$KF~$C$?$H$-$K%S!<%W2;$rLD$i$7$?$1$l$P!"$=$N%0%k!<%W$N%Q%i%a!<%?(B -$B$K(B @code{(dummy-variable (ding))} $B$_$?$$$J$b$N$r=q$$$F$*$/$3$H$b$G$-$^$9!#(B -@code{dummy-variable} $B$H$$$&JQ?t$K(B @code{(ding)} $B$NI>2A7k2L$,@_Dj$5$l$^$9(B -$B$,!"$^$"!"C/$b5$$K$7$J$$$G$7$g!)(B - -@end table - -$B%0%k!<%W%Q%i%a!<%?$N=$@5$K$O(B @kbd{G p} $BL?Na$r;H$C$F$/$@$5$$!#%H%T%C%/%Q%i(B -$B%a!<%?$K$D$$$FFI$s$G$_$k$3$H$bLLGr$$$G$7$g$&(B (@pxref{Topic Parameters})$B!#(B - - -@node Listing Groups -@section $B%0%k!<%W$N0lMwI=<((B -@cindex group listing - -$B$3$l$i$N%3%^%s%I$O!"MxMQ$G$-$k%0%k!<%W$r$$$m$$$m$K@Z$jJ,$1$FI=<($7$^$9!#(B - -@table @kbd - -@item l -@itemx A s -@kindex A s (Group) -@kindex l (Group) -@findex gnus-group-list-groups -$BL$FI5-;v$r;}$DA4$F$N%0%k!<%W$rI=<($7$^$9(B (@code{gnus-group-list-groups})$B!#(B -$B?t;z%W%l%U%#%C%/%9$r;H$&$H!"$3$N%3%^%s%I$O0z?t$N?t$+$=$l$h$j$b>.$5$$%l%Y%k(B -$B$N%0%k!<%W$N$_$rI=<($7$^$9!#%G%U%)%k%H$G$O!"$3$l$O%l%Y%k(B 5$B!J$D$^$j(B -@code{gnus-group-default-list-level}$B!K$+$=$l$h$j>.$5$$%l%Y%k!J$9$J$o$A9XFI(B -$B$7$F$$$k%0%k!<%W$N$_!K$rI=<($7$^$9!#(B - -@item L -@itemx A u -@kindex A u (Group) -@kindex L (Group) -@findex gnus-group-list-all-groups -$BL$FI5-;v$N$"$k$J$7$K4X$o$i$:!"A4$F$N%0%k!<%W$rI=<($7$^$9(B -(@code{gnus-group-list-all-groups})$B!#?t;z%W%l%U%#%C%/%9$r;HMQ$9$k$H!"$3$N(B -$B%3%^%s%I$O0z?t$N?t$+$=$l$h$j$b>.$5$$%l%Y%k$N%0%k!<%W$N$_$rI=<($7$^$9!#%G%U%)(B -$B%k%H$G$O(B 7 $B$+$=$l$h$j$b>.$5$$%l%Y%k$N%0%k!<%W!J$9$J$o$A9XFI!"Hs9XFI$N%0%k!<(B -$B%W$N$_!K$,I=<($5$l$^$9!#(B - -@item A l -@kindex A l (Group) -@findex gnus-group-list-level -$B$"$kFCDj$N%l%Y%k$NL$FI5-;v$N$"$k%0%k!<%W$rI=<($7$^$9(B -(@code{gnus-group-list-level})$B!#%W%l%U%#%C%/%9$rM?$($k$H!"L$FI5-;v$N$J$$(B -$B%0%k!<%W$b4^$a$FI=<($7$^$9!#(B - -@item A k -@kindex A k (Group) -@findex gnus-group-list-killed -kill $B$5$l$?%0%k!<%W$rA4$FI=<($7$^$9(B (@code{gnus-group-list-killed})$B!#%W(B -$B%l%U%#%C%/%90z?t$rM?$($k$H!"8=:_9XFI!"Hs9XFI$H$J$C$F$$$J$$A4$F$NMxMQ2DG=(B -$B$J%0%k!<%W$rI=<($7$^$9!#$3$l$O%5!<%P$+$i%"%/%F%#%V%U%!%$%k$rFI$`$3$H$K$J(B -$B$k$G$7$g$&!#(B - -@item A z -@kindex A z (Group) -@findex gnus-group-list-zombies -$BA4$F$N%>%s%S%0%k!<%W$rI=<($7$^$9(B (@code{gnus-group-list-zombies})$B!#(B - -@item A m -@kindex A m (Group) -@findex gnus-group-list-matching -$B@55,I=8=$K%^%C%A$9$kL>A0$r;}$D%0%k!<%W$G!"L$FI5-;v$N$"$k9XFI%0%k!<%W$rA4(B -$B$FI=<($7$^$9(B (@code{gnus-group-list-matching})$B!#(B - -@item A M -@kindex A M (Group) -@findex gnus-group-list-all-matching -$B@55,I=8=$K%^%C%A$9$k%0%k!<%W$rI=<($9$k(B -(@code{gnus-group-list-all-matching})$B!#(B - -@item A A -@kindex A A (Group) -@findex gnus-group-list-active -$B:#@\B3$7$F$$$k%5!<%P$N%"%/%F%#%V%U%!%$%k$K$"$k%0%k!<%W$r!"K\Ev$KA4ItI=<($7(B -$B$^$9(B (@code{gnus-group-list-active})$B!#$3$l$O$7$P$i$/;~4V$,$+$+$k$3$H$bM-$j(B -$BF@$^$9!#$?$V$s(B @kbd{A M} $B$r/3d$j0z$$$FA0$r;}$D%0%k!<%W$rA4$FI=<($9$k(B -(@code{gnus-group-apropos})$B!#(B - -@item A d -@kindex A d (Group) -@findex gnus-group-description-apropos -$B@55,I=8=$K%^%C%A$9$kL>A0$+@bL@J8$r;}$D%0%k!<%W$rA4$FI=<($9$k(B -(@code{gnus-group-description-apropos})$B!#(B - -@end table - -@vindex gnus-permanently-visible-groups -@cindex visible group parameter -@code{gnus-permanently-visible-groups} $B@55,I=8=$K%^%C%A$9$k%0%k!<%W$O!"(B -$BL$FI5-;v$,$"$k$+$J$$$+$K4X$o$i$:>o$KI=<($5$l$^$9!#$"$k$$$O%0%k!<%W%Q%i%a!<(B -$B%?$K$*$$$F(B @code{visible} $BMWAG$rDI2C$9$k$3$H$G$bF1MM$N8z2L$rF@$k$3$H$,$G(B -$B$-$^$9!#(B - -@vindex gnus-list-groups-with-ticked-articles -$B0uIU$-$N5-;v$N$_$r;}$D%0%k!<%W$ODL>o%0%k!<%W%P%C%U%!$KI=<($5$l$^$9!#$b$7(B -@code{gnus-list-groups-with-ticked-articles} $B$,(B @code{nil} $B$G$"$l$P!"$=(B -$B$N%0%k!<%W$O40A4$K6u$N%0%k!<%W$G$"$k$+$N$h$&$K07$o$l$^$9!#%G%U%)%k%H$O(B -@code{t} $B$G$9!#(B - - -@node Sorting Groups -@section $B%0%k!<%W$N%=!<%H(B -@cindex sorting groups - -@kindex C-c C-s (Group) -@findex gnus-group-sort-groups -@vindex gnus-group-sort-function -@kbd{C-c C-s} (@code{gnus-group-sort-groups}) $BL?Na$O!"%0%k!<%W%P%C%U%!$r(B -@code{gnus-group-sort-function} $BJQ?t$GM?$($i$l$k4X?t$K=>$C$FJB$YBX$($^$9!#(B -$BMxMQ2DG=$JJB$YBX$(4X?t(B (sorting function) $B$K$O0J2<$N$b$N$,$"$j$^$9!'(B - -@table @code - -@item gnus-group-sort-by-alphabet -@findex gnus-group-sort-by-alphabet -$B%0%k!<%WL>$G%"%k%U%!%Y%C%H=g$KJB$YBX$($^$9!#$3$l$,=i4|@_Dj$G$9!#(B - -@item gnus-group-sort-by-real-name -@findex gnus-group-sort-by-real-name -$B%0%k!<%W$rK\Ev$N!JA0$K2?$b$D$$$F$$$J$$!K%0%k!<%WL>$G%"%k%U%!%Y%C%H=g$KJB$Y(B -$BJQ$($^$9!#(B - -@item gnus-group-sort-by-level -@findex gnus-group-sort-by-level -$B%0%k!<%W%l%Y%k$GJB$YBX$($^$9!#(B - -@item gnus-group-sort-by-score -@findex gnus-group-sort-by-score -$B%0%k!<%W$N%9%3%"$GJB$YBX$($^$9!#(B@xref{Group Score}. - -@item gnus-group-sort-by-rank -@findex gnus-group-sort-by-rank -$B%0%k!<%W$N%9%3%"$GJB$YBX$(!"l9g!"$b$C$H$b=EMW$JJB$YBX$($N80$r;}$D4X?t$O:G8e$G$J$/$F$O$J$j$^$;$s!#(B - - -$B$"$k@\JB$YBX$($kL?Na$b$$$/$D$+$"$j$^$9!#(B - -@table @kbd -@item G S a -@kindex G S a (Group) -@findex gnus-group-sort-groups-by-alphabet -$B%0%k!<%W%P%C%U%!$r%0%k!<%WL>$N%"%k%U%!%Y%C%H=g$GJB$YBX$($^$9(B -(@code{gnus-group-sort-groups-by-alphabet})$B!#(B - -@item G S u -@kindex G S u (Group) -@findex gnus-group-sort-groups-by-unread -$B%0%k!<%W%P%C%U%!$rL$FI5-;v$N?t$GJB$YBX$($^$9(B -(@code{gnus-group-sort-groups-by-unread})$B!#(B - -@item G S l -@kindex G S l (Group) -@findex gnus-group-sort-groups-by-level -$B%0%k!<%W%P%C%U%!$r%0%k!<%W%l%Y%k$GJB$YBX$($^$9(B -(@code{gnus-group-sort-groups-by-level})$B!#(B - -@item G S v -@kindex G S v (Group) -@findex gnus-group-sort-groups-by-score -$B%0%k!<%W%P%C%U%!$r%0%k!<%W$N%9%3%"$GJB$YBX$($^$9(B -(@code{gnus-group-sort-groups-by-score})$B!#(B@xref{Group Score}. - -@item G S r -@kindex G S r (Group) -@findex gnus-group-sort-groups-by-rank -$B%0%k!<%W%P%C%U%!$r%0%k!<%W$N%i%s%/$GJB$YBX$($^$9(B -(@code{gnus-group-sort-groups-by-rank})$B!#(B@xref{Group Score}. - -@item G S m -@kindex G S m (Group) -@findex gnus-group-sort-groups-by-method -$B%0%k!<%W%P%C%U%!$r%P%C%/%(%s%I$NL>A0$G%"%k%U%!%Y%C%H=g$KJB$YBX$($^$9(B -(@code{gnus-group-sort-groups-by-method})$B!#(B - -@end table - -$B%W%l%U%#%C%/%9$rM?$($?$H$-$O!"$3$l$i$NL?Na$OA4$F5U=g$KJB$YBX$($^$9!#(B - -$B$^$?!"%0%k!<%W$N0lIt$rJB$YBX$($k$3$H$b$G$-$^$9!#(B - -@table @kbd -@item G P a -@kindex G P a (Group) -@findex gnus-group-sort-selected-groups-by-alphabet -$B%0%k!<%W%P%C%U%!Fb$N%W%m%;%9%^!<%/!&%W%l%U%#%C%/%9;XDj$5$l$?%0%k!<%W$r!"%0(B -$B%k!<%WL>$N%"%k%U%!%Y%C%H=g$GJB$YBX$($^$9(B -(@code{gnus-group-sort-selected-groups-by-alphabet})$B!#(B - -@item G P u -@kindex G P u (Group) -@findex gnus-group-sort-selected-groups-by-unread -$B%0%k!<%W%P%C%U%!Fb$N%W%m%;%9%^!<%/!&%W%l%U%#%C%/%9;XDj$5$l$?%0%k!<%W$r!"L$(B -$BFI5-;v$N?t$GJB$YBX$($^$9(B -(@code{gnus-group-sort-selected-groups-by-unread})$B!#(B - -@item G P l -@kindex G P l (Group) -@findex gnus-group-sort-selected-groups-by-level -$B%0%k!<%W%P%C%U%!Fb$N%W%m%;%9%^!<%/!&%W%l%U%#%C%/%9;XDj$5$l$?%0%k!<%W$r!"%0(B -$B%k!<%W%l%Y%k$GJB$YBX$($^$9(B -(@code{gnus-group-sort-selected-groups-by-level})$B!#(B - -@item G P v -@kindex G P v (Group) -@findex gnus-group-sort-selected-groups-by-score -$B%0%k!<%W%P%C%U%!Fb$N%W%m%;%9%^!<%/!&%W%l%U%#%C%/%9;XDj$5$l$?%0%k!<%W$r!"%0(B -$B%k!<%W$N%9%3%"$GJB$YBX$($^$9(B -(@code{gnus-group-sort-selected-groups-by-score})$B!#(B@xref{Group Score}. - -@item G P r -@kindex G P r (Group) -@findex gnus-group-sort-selected-groups-by-rank -$B%0%k!<%W%P%C%U%!Fb$N%W%m%;%9%^!<%/!&%W%l%U%#%C%/%9;XDj$5$l$?%0%k!<%W$r!"%0(B -$B%k!<%W$N%i%s%/$GJB$YBX$($^$9(B -(@code{gnus-group-sort-selected-groups-by-rank})$B!#(B@xref{Group Score}. - -@item G P m -@kindex G P m (Group) -@findex gnus-group-sort-selected-groups-by-method -$B%0%k!<%W%P%C%U%!Fb$N%W%m%;%9%^!<%/!&%W%l%U%#%C%/%9;XDj$5$l$?%0%k!<%W$r!"%P%C(B -$B%/%(%s%I$NL>A0$G%"%k%U%!%Y%C%H=g$KJB$YBX$($^$9(B -(@code{gnus-group-sort-selected-groups-by-method})$B!#(B - -@end table - - - -@node Group Maintenance -@section $B%0%k!<%W$N4IM}(B -@cindex bogus groups - -@table @kbd -@item b -@kindex b (Group) -@findex gnus-group-check-bogus-groups -$BIT@5$J%0%k!<%W$r8+$D$1$F!":o=|$7$^$9(B -(@code{gnus-group-check-bogus-groups})$B!#(B - -@item F -@kindex F (Group) -@findex gnus-group-find-new-groups -$B?7$7$$%0%k!<%W$r8+$D$1$F!"$=$l$i$r=hM}$7$^$9(B -(@code{gnus-group-find-new-groups})$B!#(B1$B2s$N(B @kbd{C-u} $B$N8e$G2!$5$l$k$H!"(B -$B%5!<%P!<$K?7$7$$%0%k!<%W$r?R$M$k$?$a$KJ}K!(B @code{ask-server} $B$r;H$$$^$9!#(B -2$B2s$N(B @kbd{C-u} $B$N8e$G2!$5$l$k$H!"%5!<%P!<$K?7$7$$%0%k!<%W$r?R$M$k$?$a$K(B -$B:G$b40A4$G$"$k$H;W$o$l$kJ}K!$rMQ$$!"?7$7$$%0%k!<%W$r%>%s%S$H$7$F9XFI$7$^(B -$B$9!#(B - -@item C-c C-x -@kindex C-c C-x (Group) -@findex gnus-group-expire-articles -$B8=:_$N%0%k!<%W$N%(%/%9%Q%$%"5-;v$KBP$7$F!J$b$7$"$l$P!KA4$F%(%/%9%Q%$%"=hM}(B -$B$r9T$$$^$9(B (@code{gnus-group-expire-articles})$B!#(B - -@item C-c M-C-x -@kindex C-c M-C-x (Group) -@findex gnus-group-expire-all-groups -$BA4$F$N%0%k!<%W$NA4$F$N5-;v$KBP$7$F!"%(%/%9%Q%$%"=hM}$r9T$$$^$9(B -(@code{gnus-group-expire-all-groups})$B!#(B - -@end table - - -@node Browse Foreign Server -@section $B30It%5!<%P$N1\Mw(B -@cindex foreign servers -@cindex browsing servers - -@table @kbd -@item B -@kindex B (Group) -@findex gnus-group-browse-foreign-server -$BA*Br%a%=%C%I$H%5!<%PL>$rJ9$+$l$^$9!#(BGnus $B$O$3$N%5!<%P$K@\B3$7!"$=$3$K$"$k(B -$B%0%k!<%W$r1\Mw$7$h$&$H$7$^$9(B (@code{gnus-group-browse-foreign-server})$B!#(B -@end table - -@findex gnus-browse-mode -$BMxMQ2DG=$J%0%k!<%W$N%j%9%H$r;}$C$??7$7$$%P%C%U%!$,8=$l$^$9!#$3$N%P%C%U%!(B -$B$O(B @code{gnus-browse-mode} $B$r;HMQ$7$^$9!#$3$N%P%C%U%!$ODL>o$N%0%k!<%W%P%C(B -$B%U%!$K$A$g$C$H!J$H$$$&$+!"$H$C$F$b!K;w$F$$$^$9!#(B - -$B0J2<$,1\Mw%b!<%I(B (browse mode) $B$G;HMQ$G$-$k%-!l9g$O9XFI$9$k$3$H$K$J$k$N$@$1$l(B -$B$I(B (@code{gnus-browse-unsubscribe-current-group})$B!#(B - -@item l -@itemx q -@kindex q (Browse) -@kindex l (Browse) -@findex gnus-browse-exit -$B1\Mw%b!<%I(B (browse mode) $B$r=*N;$7$^$9(B (@code{gnus-browse-exit})$B!#(B - -@item ? -@kindex ? (Browse) -@findex gnus-browse-describe-briefly -$B1\Mw%b!<%I(B (browse mode) $B$r4JC1$K@bL@$7$^$9!J$^$"!"Bg$7$F@bL@$9$k$3$H$b$J(B -$B$$$s$@$1$I$5!K(B(@code{gnus-browse-describe-briefly})$B!#(B -@end table - - -@node Exiting gnus -@section Gnus $B$N=*N;(B -@cindex exiting gnus - -$B$=$&!"(Bgnus $B$O:G8e!J%5%$%3!C$9$@$1$G$9!#KM$O$3$l$N$&$l(B -$B$7$5$,$h$/$o$+$s$J$$$s$@$1$I!"C/$+J,$+$k?M$$$k!)(B - -@item q -@kindex q (Group) -@findex gnus-group-exit -@c @icon{gnus-group-exit} -Gnus $B$r=*N;$7$^$9(B(@code{gnus-group-exit})$B!#(B - -@item Q -@kindex Q (Group) -@findex gnus-group-quit -@file{.newsrc} $B%U%!%$%k$r%;!<%V$;$:$K(B gnus $B$r=*N;$7$^$9(B -(@code{gnus-group-quit})$B!#%I%j%V%k%U%!%$%k$O%;!<%V$5$l$^$9$1$I(B -(@pxref{Auto Save})$B!#(B -@end table - -@vindex gnus-exit-gnus-hook -@vindex gnus-suspend-gnus-hook -Gnus $B$rCfCG$9$k$H$-$O(B @code{gnus-suspend-gnus-hook} $B$,8F$S=P$5$l$^$9!#(B -Gnus$B$r=*N;$9$k$H$-$O(B @code{gnus-exit-gnus-hook} $B$,8F$S=P$5$l!"$5$i$K(B -gnus $B$r=*N;$9$k$H$-$N:G8e$H$7$F(B @code{gnus-after-exiting-gnus-hook} $B$,8F$S(B -$B=P$5$l$^$9!#(B - -@findex gnus-unload -@cindex unloading -$B$b$7(B gnus $B$H$=$l$K4XO"$9$k$b$N$r40A4$K=hJ,$7$?$$$N$G$"$l$P!"(B -@code{gnus-unload} $B%3%^%s%I$,;H$($^$9!#$3$N%3%^%s%I$O!"%a%?JQ?t$r%+%9%?%^(B -$B%$%:$7$h$&$H$7$F$$$k$H$-$K$bJXMx$G$9!#(B - -Note: - -@quotation -$B%_%9(B Lisa Cannifax $B$O1Q8l$N/G/$,H`=w$N(B -$B%W%i%9%F%#%C%/$N0X;R$NGX1[$7$K!"1tI.$G7+$jJV$7@~$rIA$/$N$K$D$i$l(B -$B$F!"B-$,$7$S$l$F=E$/$J$j!"0U<1$,[/[0$H$7$F$-$^$7$?!#(B -@end quotation - - -@node Group Topics -@section Group Topics -@cindex topics - -$B$b$7$"$J$?$,$?!<$/$5$s$N%0%k!<%W$rFI$s$G$$$k$N$G$"$l$P!"%0%k!<%W$r%H%T%C%/(B -$BKh$K3,AXJ,$1$G$-$k$HJXMx$G$7$g$&!#(BEmacs $B$N%0%k!<%W$r$3$C$A$X!"%;%C%/%9$N%0(B -$B%k!<%W$r$"$C$A$X!"$G!";D$j$r!J$(!)%0%k!<%W$,#2$D$/$i$$$7$+$J$$$N!)!K$N%;%/%7%g%s$KF~$l$^$7$g$&!#$"$k$$$O(B Emacs $B%;%C%/%9$N(B -$B%0%k!<%W$r(B Emacs $B%0%k!<%W!"%;%C%/%9%0%k!<%W$N$I$A$i$+$NI{%H%T%C%/$H$9$k$3(B -$B$H$5$($b$G$-$^$9!=!=$"$k$$$ON>J}$K!*$9$s$4$$$G$7$g$&!*(B - -@iftex -@iflatex -\gnusfigure{Group Topics}{400}{ -\put(75,50){\epsfig{figure=tmp/group-topic.ps,height=9cm}} -} -@end iflatex -@end iftex - -$B$3$l$,Nc$G$9!'(B - -@example -Gnus - Emacs -- $B$3$$$D$O$9$2!<$<(B! - 3: comp.emacs - 2: alt.religion.emacs - $B$($C$A$J(B Emacs - 452: alt.sex.emacs - 0: comp.talk.emacs.recovery - $B$=$NB>(B - 8: comp.binaries.fractals - 13: comp.sources.unix -@end example - -@findex gnus-topic-mode -@kindex t (Group) -$B$3$N(B@emph{$BAG@2$i$7$$(B}$B5!G=$r;H$&$K$O!"(B@code{gnus-topic} $B%^%$%J!<%b!<%I$r(B -$B!J2?$H!*!KC1$K%9%$%C%A%*%s$9$k$@$1!=!=%0%k!<%W%P%C%U%!$G!"(B@kbd{t} $B$r2!$7$F(B -$B$/$@$5$$!J$3$l$O%H%0%k%3%^%s%I$G$9!K!#(B - -$B$5$"$d$C$F$_$h$&!#$H$K$+$/;n$7$F$_$F!#7/$,La$C$F$/$k$^$G!"KM$O$3$3$GBT$C$F(B -$B$k$+$i$5!#%i%i!"%?%i%i%s!D$s!"$$$$6J$@$M!"$3$l!D%i!"%i!"%i!D$((B? $BLa$C$F$-$?!)(B -$B$h$7!"$8$cv$^$l$^$9!#$3$l!"$H$C$F$b(B -$B%9%F%-$@$H;W$&$s$@$1$I!#(B - -@vindex gnus-topic-line-format -$B%H%T%C%/9T$O!"(B@code{gnus-topic-line-format} $BJQ?t$NCM$K=>$C$F:n@.$5$l$^$9(B -(@pxref{Formatting Variables})$B!#M-8z$JMWAG$O!"(B - -@table @samp -@item i -$B;z2<$2!#(B -@item n -$B%H%T%C%/L>!#(B -@item v -$B8+$($k$+$I$&$+!#(B -@item l -$B%l%Y%k!#(B -@item g -$B%H%T%C%/Cf$N%0%k!<%W$N?t!#(B -@item a -$B%H%T%C%/Cf$NL$FI5-;v$N?t!#(B -@item A -$B%H%T%C%/$HA4$F$NI{%H%T%C%/$NL$FI5-;v$N?t!#(B -@end table - -@vindex gnus-topic-indent-level -$B3FI{%H%T%C%/!J$HI{%H%T%C%/Fb$N%0%k!<%W!K$O!"%H%T%C%/%l%Y%k?t$N(B -@code{gnus-topic-indent-level} $BG\$N6uGrJ,$N;z2<$2$,9T$o$l$^$9!#%G%U%)%k%H(B -$B$O(B 2 $B$G$9!#(B - -@vindex gnus-topic-mode-hook -@code{gnus-topic-mode-hook} $B$O%H%T%C%/%^%$%J!<%b!<%I%P%C%U%!$G8F$S=P$5$l(B -$B$^$9!#(B - -@vindex gnus-topic-display-empty-topics -@code{gnus-topic-display-empty-topics} $B$O%H%T%C%/$NCf$KL$FI5-;v(B -$B$,L5$$>l9g$G$b$=$N%H%T%C%/$rI=<($9$k$h$&$K$7$^$9!#%G%U%)%k%H$O(B -@code{t} $B$G$9!#(B - -@node Topic Commands -@subsection $B%H%T%C%/L?Na(B -@cindex topic commands - -$B%H%T%C%/%^%$%J!<%b!<%I$,M-8z$G$"$k$H$-$O!"(B@kbd{T} $B%5%V%^%C%W$,?7(B -$B$7$/MxMQ$G$-$k$h$&$K$J$j$^$9!#$5$i$KI8=`%-!<$NCf$G$b!"Dj5A$,$A$g$C(B -$B$HJQ$o$k$b$N$,>/$7$"$j$^$9!#(B - -@table @kbd - -@item T n -@kindex T n (Topic) -@findex gnus-topic-create-topic -$B?7$7$$%H%T%C%/$NL>A0$r%W%m%s%W%HF~NO$7!"$=$l$r:n@.$7$^$9(B -(@code{gnus-topic-create-topic})$B!#(B - -@item T m -@kindex T m (Topic) -@findex gnus-topic-move-group -$B8=:_$N%0%k!<%W$r!"$I$3$+B>$N%H%T%C%/$K0\F0$5$;$^$9(B -(@code{gnus-topic-move-group})$B!#$3$N%3%^%s%I$O%W%m%;%9%^!<%/!&%W(B -$B%l%U%#%C%/%9%k!<%k$K=>$$$^$9(B (@pxref{Process/Prefix})$B!#(B - -@item T c -@kindex T c (Topic) -@findex gnus-topic-copy-group -$B8=:_$N%0%k!<%W$r!"$I$3$+B>$N%H%T%C%/$K%3%T!<$7$^$9(B -(@code{gnus-topic-copy-group})$B!#$3$N%3%^%s%I$O%W%m%;%9%^!<%/!&%W(B -$B%l%U%#%C%/%9%k!<%k$K=>$$$^$9(B (@pxref{Process/Prefix})$B!#(B - -@item T D -@kindex T D (Topic) -@findex gnus-topic-remove-group -$B%0%k!<%W$r8=:_$N%H%T%C%/$+$i:o=|$7$^$9(B(@code{gnus-topic-remove-group})$B!#(B -$B$3$NL?Na$Ol9g$O!"(Bgnus $B$O$"$J$?$,$$$^$9(B (@pxref{Process/Prefix})$B!#(B - -@item T M -@kindex T M (Topic) -@findex gnus-topic-move-matching -$B@55,I=8=$K%^%C%A$9$kA4$F$N%0%k!<%W$r!"$"$k%H%T%C%/$K0\F0$5$;$^$9(B -(@code{gnus-topic-move-matching})$B!#(B - -@item T C -@kindex T C (Topic) -@findex gnus-topic-copy-matching -$B@55,I=8=$K%^%C%A$9$kA4$F$N%0%k!<%W$r!"$"$k%H%T%C%/$K%3%T!<$7$^$9(B -(@code{gnus-topic-copy-matching})$B!#(B - -@item T h -@kindex T h (Topic) -@findex gnus-topic-toggle-display-empty-topics -$B6u$N%H%T%C%/$NI=<(!&HsI=<($r@Z$jBX$($^$9(B -(@code{gnus-topic-toggle-display-empty-topics})$B!#(B - -@item T # -@kindex T # (Topic) -@findex gnus-topic-mark-topic -$B8=:_$N%H%T%C%/$K$"$k%0%k!<%WA4$F$K%W%m%;%9%^!<%/$r$D$1$^$9(B -(@code{gnus-topic-mark-topic})$B!#(B - -@item T M-# -@kindex T M-# (Topic) -@findex gnus-topic-unmark-topic -$B8=:_$N%H%T%C%/$K$"$kA4$F$N%0%k!<%W$+$i%W%m%;%9%^!<%/$r>C$7$^$9(B -(@code{gnus-topic-unmark-topic})$B!#(B - -@item RET -@kindex RET (Topic) -@findex gnus-topic-select-group -@itemx SPACE -$B%0%k!<%W$rA*Br$9$k$+!"$"$k$$$O%H%T%C%/$r@^$j$?$?$_$^$9(B -(@code{gnus-topic-select-group})$B!#%0%k!<%W$N>e$G$3$N%3%^%s%I$roDL$j$=$N%0%k!<%W$KF~$j$^$9!#%H%T%C%/9T$N>e$G9T$&$H!"$=$N%H%T%C%/$O!J4{(B -$B$KI=<($5$l$F$$$k$H$-$O!K@^$j$?$?$^$l$k$+!"!J4{$K@^$j$?$?$^$l$F$$$k$H$-$O!K(B -$BE83+$5$l$^$9!#$D$^$j%H%T%C%/$KBP$7$F$O$3$l$O%H%0%k%3%^%s%I$G$9!#$5$i$K!"?t(B -$B;z%W%l%U%#%C%/%9$rM?$($k$H!"$=$N%l%Y%k!J$H$=$l$h$j$b>.$5$$%l%Y%k!K$N%0%k!<(B -$B%W$,I=<($5$l$^$9!#(B - -@item T TAB -@itemx TAB -@kindex T TAB (Topic) -@kindex TAB (Topic) -@findex gnus-topic-indent -$B8=:_$N%H%T%C%/$N(B ``$B;z2<$2(B'' $B$r9T$$!"$=$NA0$N%H%T%C%/$NI{%H%T%C%/$K$7$^$9(B -(@code{gnus-topic-indent})$B!#@\F,0z?t$rM?$($k$H!"H?BP$K$=$N%H%T%C%/(B -$B$N;z2<$2$rLa$7$^$9!#(B - -@item M-TAB -@kindex M-TAB (Topic) -@findex gnus-topic-unindent -$B8=:_$N%H%T%C%/$N(B ``$B;z2<$22sI|(B'' (un-indent) $B$r9T$$!"$=$l$,8=:_$N?F$N?F$N(B -$BI{%H%T%C%/$K$J$k$h$&$K$7$^$9(B (@code{gnus-topic-unindent})$B!#(B - -@item C-k -@kindex C-k (Topic) -@findex gnus-topic-kill-group -$B%0%k!<%W$"$k$$$O%H%T%C%/$r(B kill $B$7$^$9(B(@code{gnus-topic-kill-group})$B!#%H(B -$B%T%C%/Fb$K$"$C$?%0%k!<%W$bA4$F!"%H%T%C%/$H0l=o$K:o=|$5$l$^$9!#(B - -@item C-y -@kindex C-y (Topic) -@findex gnus-topic-yank-group -$BD>A0$N(B kill $B$5$l$?%0%k!<%W$"$k$$$O%H%T%C%/$r(B yank $B$7$^$9(B -(@code{gnus-topic-yank-group})$B!#A4$F$N%H%T%C%/$O!"A4$F$N%0%k!<%W(B -$B$NA0$K(B yank $B$5$l$k$3$H$K5$$r$D$1$F$/$@$5$$!#(B - -@item T r -@kindex T r (Topic) -@findex gnus-topic-rename -$B%H%T%C%/$NL>A0$rJQ99$9$k(B (@code{gnus-topic-rename})$B!#(B - -@item T DEL -@kindex T DEL (Topic) -@findex gnus-topic-delete -$B6u$N%H%T%C%/$r:o=|$9$k(B (@code{gnus-topic-delete})$B!#(B - -@item A T -@kindex A T (Topic) -@findex gnus-topic-list-active -Gnus $B$,CN$C$F$$$k%H%T%C%/2=$5$l$?%0%k!<%W$rA4$FI=<($7$^$9(B -(@code{gnus-topic-list-active})$B!#(B - -@item G p -@kindex G p (Topic) -@findex gnus-topic-edit-parameters -@cindex group parameters -@cindex topic parameters -@cindex parameters -$B%H%T%C%/%Q%i%a!<%?$r=$@5$7$^$9(B (@code{gnus-topic-edit-parameters})$B!#(B -@xref{Topic Parameters}. - -@end table - - -@node Topic Sorting -@subsection $B%H%T%C%/$NJB$YBX$((B -@cindex topic sorting - -$B0J2<$K<($9L?Na$G!"3F%H%T%C%/Kh$KJL!9$K%0%k!<%W$rJB$YBX$($k$3$H$,$G$-$^$9!'(B - - -@table @kbd -@item T S a -@kindex T S a (Topic) -@findex gnus-topic-sort-groups-by-alphabet -$B8=:_$N%H%T%C%/$r%0%k!<%WL>$N%"%k%U%!%Y%C%H=g$KJB$YBX$($^$9(B -(@code{gnus-topic-sort-groups-by-alphabet})$B!#(B - -@item T S u -@kindex T S u (Topic) -@findex gnus-topic-sort-groups-by-unread -$B8=:_$N%H%T%C%/$rL$FI5-;v$N?t$GJB$YBX$($^$9(B -(@code{gnus-topic-sort-groups-by-unread})$B!#(B - -@item T S l -@kindex T S l (Topic) -@findex gnus-topic-sort-groups-by-level -$B8=:_$N%H%T%C%/$r%0%k!<%W$N%l%Y%k$GJB$YBX$($^$9(B -(@code{gnus-topic-sort-groups-by-level})$B!#(B - -@item T S v -@kindex T S v (Topic) -@findex gnus-topic-sort-groups-by-score -$B8=:_$N%H%T%C%/$r%0%k!<%W$N%9%3%"$GJB$YBX$($^$9(B -(@code{gnus-topic-sort-groups-by-score})$B!#(B@xref{Group Score}. - -@item T S r -@kindex T S r (Topic) -@findex gnus-topic-sort-groups-by-rank -$B8=:_$N%H%T%C%/$r%0%k!<%W$N%i%s%/$GJB$YBX$($^$9(B -(@code{gnus-topic-sort-groups-by-rank})$B!#(B@xref{Group Score}. - -@item T S m -@kindex T S m (Topic) -@findex gnus-topic-sort-groups-by-method -$B8=:_$N%H%T%C%/$r%P%C%/%(%s%I$NL>A0$G%"%k%U%!%Y%C%H=g$KJB$YBX$($^$9(B -(@code{gnus-topic-sort-groups-by-method})$B!#(B - -@end table - -$B%0%k!<%W$N%=!<%H$K$D$$$F$N$5$i$J$k>pJs$O(B @xref{Sorting Groups} $B$r;2>H$7$F(B -$B$/$@$5$$!#(B - - -@node Topic Topology -@subsection $B%H%T%C%/$N0LAj9=B$(B -@cindex topic topology -@cindex topology - -$B$=$l$G$O!"%0%k!<%W%P%C%U%!$NNc$r8+$F$$$-$^$7$g$&!#(B - -@example -Gnus - Emacs -- $B$3$$$D$O$9$2!<$<(B! - 3: comp.emacs - 2: alt.religion.emacs - $B$($C$A$J(B Emacs - 452: alt.sex.emacs - 0: comp.talk.emacs.recovery - $B$=$NB>(B - 8: comp.binaries.fractals - 13: comp.sources.unix -@end example - -$B$D$^$j!"$3$3$G$O0l$D$N%H%C%W%l%Y%k$N%H%T%C%/(B (@samp{Gnus}) $B$,$"$j!"$=$N2<(B -$B$K#2$D$N%H%T%C%/$,$"$j!"$=$N$&$A$N0lJ}$NI{%H%T%C%/Cf$K0l$DI{%H%T%C%/$,$"$j(B -$B$^$9!J%H%C%W%l%Y%k%H%T%C%/$O>o$K0l$D$7$+$"$j$^$;$s!K!#$3$N9=B$$O!"0J2<$N$h(B -$B$&$KI=8=$G$-$^$9!'(B - -@lisp -(("Gnus" visible) - (("Emacs -- $B$3$$$D$O$9$2!<$<(B!" visible) - (("$B$($C$A$J(B Emacs" visible))) - (("$B$=$NB>(B" visible))) -@end lisp - -@vindex gnus-topic-topology -$B$3$l$Oe5-$NI=<($r9T$&$?$a$N!"JQ?t(B @code{gnus-topic-topology} $B$NCM$=(B -$B$N$b$N$J$N$G$9!#$3$NJQ?t$O(B@file{.newsrc.eld} $B%U%!%$%k$KJ]B8$5$l!"$N%9%?!<%H%"%C%W%U%!(B -$B%$%k$N@_Dj$K$OA4$/1F6A$rM?$($^$;$s!#(B - -$B$3$N9=B$$O!"$I$N%H%T%C%/$,$I$N%H%T%C%/$NI{%H%T%C%/$G$"$k$+$H!"$I$N%H%T%C%/(B -$B$,I=<($5$l$F$$$k$+$r<($7$F$$$^$9!#8=:_$OFs$D$N@_DjCM!=!=(B@code{visible} $B$H(B -@code{invisible} $B$,5v$5$l$F$$$^$9!#(B - - -@node Topic Parameters -@subsection $B%H%T%C%/%Q%i%a!<%?(B -@cindex topic parameters - -$B%H%T%C%/Fb$NA4$F$N%0%k!<%W$O%0%k!<%W%Q%i%a!<%?$r!"$=$N?F!J$H@hAD!K$N%H%T%C(B -$B%/%Q%i%a!<%?$+$i7Q>5$7$^$9!#%0%k!<%W%Q%i%a!<%?$H$7$F@5$7$$$b$N$OA4$F!"%H%T%C(B -$B%/%Q%i%a!<%?$H$7$F$b@5$7$$$b$N$G$9(B(@pxref{Group Parameters})$B!#(B - -$B%0%k!<%W%Q%i%a!<%?$O!J$b$A$m$s!K%H%T%C%/%Q%i%a!<%?$h$j$bM%@h$5$l!"I{%H%T%C(B -$B%/$N%H%T%C%/%Q%i%a!<%?$O?F%H%T%C%/$N%H%T%C%/%Q%i%a!<%?$h$j$bM%@h$5$l$^$9!#(B -$BJ,$+$k$h$M!#$4$/IaDL$N7Q>5%k!<%k$G$9!J%k!<%k(B (@dfn{Rules}) $B$O$3$3$G$OL>;l(B -$B$G$"$C$F!"F0;l$N!V@~$r0z$/!W$G$O$"$j$^$;$s!#$3$N%k!<%k$K$OH?BP$7$?$/$J$k$+(B -$B$bCN$l$J$$$1$I!"$=$l$O$4<+M3$K!K!#(B - -@example -Gnus - Emacs - 3: comp.emacs - 2: alt.religion.emacs - 452: alt.sex.emacs - $BB)H4$-(B - 452: alt.sex.emacs - 0: comp.talk.emacs.recovery - $B$=$NB>(B - 8: comp.binaries.fractals - 13: comp.sources.unix - 452: alt.sex.emacs -@end example - -@samp{Emacs} $B%H%T%C%/$O%H%T%C%/%Q%i%a!<%?(B @code{(score-file -. "emacs.SCORE")} $B$r;}$C$F$$$^$9!#(B@samp{$BB)H4$-(B} $B%H%T%C%/$O%H%T%C(B -$B%/%Q%i%a!<%?(B @code{(score-file . "relief.SCORE")} $B$r;}$A!"(B -@samp{$B$=$NB>(B} $B%H%T%C%/$O%H%T%C%/%Q%i%a!<%?(B @code{(score-file -. "emacs.SCORE")} $B$r;}$C$F$$$^$9!#$5$i$K!"(B -@samp{alt.religion.emacs} $B$O%0%k!<%W%Q%i%a!<%?(B @code{(score-file -. "religion.SCORE")} $B$r;}$C$F$$$^$9!#(B - -$B$5$F!"$3$3$G(B @samp{$BB)H4$-(B} $B%H%T%C%/$N(B @samp{alt.sex.emacs} $B%0%k!<(B -$B%W$KF~$C$?$H$-!"(B@file{relief.SCORE} $B$,4pK\%9%3%"%U%!%$%k$H$J$j$^(B -$B$9!#$b$7(B @samp{Emacs} $B%H%T%C%/$NF1$8%0%k!<%W$KF~$k$H!"(B -@file{emacs.SCORE} $B$,4pK\%9%3%"%U%!%$%k$K$J$k$G$7$g$&!#(B -@* @samp{alt.religion.emacs} $B%0%k!<%W$KF~$l$P!"(B -@file{religion.SCORE} $B$,4pK\%9%3%"%U%!%$%k$K$J$k$G$7$g$&!#(B - -$B$3$l$C$F$H$C$F$b4JC1$G<+L@$N$3$H$N$h$&$K8+$($k$G$7$g!)$^$"!"$=$NDL$j$G$9!#(B -$B$G$9$,LdBj$,$"$k>l9g$b$"$j$^$9!#FC$K(B@code{total-expiry} $B%Q%i%a!<%?$K4X$7$F(B -$B$G$9!#Nc$($P$"$k%a!<%k%0%k!<%W$rFs$D$N%H%T%C%/$NCf$K!"0lJ}$O(B -@code{total-expiry} $B$"$j$G!"$b$&0lJ}$O$=$l$J$7$G;}$C$F$$$k$H$7$^$7$g$&!#$3(B -$B$3$G(B @kbd{M-x gnus-expire-all-expirable-groups} $B$rl9g$K$O==J,Cm0U$7$J$1$l$P$J$j$^$;$s!#(B - - -@node Misc Group Stuff -@section $B$=$NB>$N%0%k!<%W4XO"(B - -@menu -* Scanning New Messages:: Gnus $B$K?7$7$$%a%C%;!<%8$,E~Ce$7$?$+$I$&$+$rJ9$/!#(B -* Group Information:: $B%0%k!<%W$H(B gnus $B$K4X$9$k>pJs$H%X%k%W!#(B -* Group Timestamp:: Gnus $B$K:G8e$K$$$D%0%k!<%W$rFI$s$@$+$r5-O?$5$;$k!#(B -* File Commands:: Gnus $B$N%U%!%$%k$NFI$_=q$-!#(B -@end menu - -@table @kbd - -@item ^ -@kindex ^ (Group) -@findex gnus-group-enter-server-mode -$B%5!<%P%P%C%U%!%b!<%I$KF~$k(B (@code{gnus-group-enter-server-mode})$B!#(B -@xref{The Server Buffer}$B!#(B - -@item a -@kindex a (Group) -@findex gnus-group-post-news -$B$"$k%0%k!<%W$K5-;v$rEj9F$9$k(B (@code{gnus-group-post-news})$B!#%W%l(B -$B%U%#%C%/%9$rM?$($k$H!"8=:_$N%0%k!<%WL>$,%G%U%)%k%H$H$7$F;HMQ$5$l$^$9!#(B - -@item m -@kindex m (Group) -@findex gnus-group-mail -$B%a!<%k$r$I$3$+$KAw$k(B (@code{gnus-group-mail})$B!#(B - -@end table - -$B0J2<$O%0%k!<%W%P%C%U%!$N$?$a$NJQ?t$G$9!'(B - -@table @code - -@item gnus-group-mode-hook -@vindex gnus-group-mode-hook -$B%0%k!<%W%P%C%U%!$,:n@.$5$l$?;~$K8F$S=P$5$l$^$9!#(B - -@item gnus-group-prepare-hook -@vindex gnus-group-prepare-hook -$B%0%k!<%W%P%C%U%!$,@8@.$5$l$?$"$H$K8F$S=P$5$l$^$9!#$3$l$O%P%C%U%!$r2?$+JQ$J!"(B -$B<+A3$8$c$J$$J}K!$G=$@5$7$?$$$H$-$K;H$o$l$k$+$b$7$l$^$;$s!#(B - -@item gnus-group-prepared-hook -@vindex gnus-group-prepare-hook -$B%0%k!<%W%P%C%U%!$,@8@.$5$l$?8e$N0lHV:G8e$K8F$S=P$5$l$^$9!#Nc$($P(B -$B%]%$%s%H$r$I$3$+$K0\F0$5$;$?$$$H$-$J$I$K;H$($^$9!#(B - -@item gnus-permanently-visible-groups -@vindex gnus-permanently-visible-groups -$B$3$N@55,I=8=$K%^%C%A$9$k%0%k!<%W$O!"$=$l$,6u$G$"$k$+$I$&$+$K4X$o(B -$B$i$:!">o$K%0%k!<%W%P%C%U%!$KI=<($5$l$^$9!#(B - -@end table - - -@node Scanning New Messages -@subsection $B?7Ce%a%C%;!<%8$rC5$9(B -@cindex new messages -@cindex scanning new news - -@table @kbd - -@item g -@kindex g (Group) -@findex gnus-group-get-new-news -@c @icon{gnus-group-get-new-news} -$B%5!<%P$N?7Ce5-;v$r%A%'%C%/$7$^$9!#?t;z%W%l%U%#%C%/%9$r;HMQ$9$k$H!"$3$NL?Na(B -$B$O0z?t(B @var{arg} $B$+$=$l$h$j>.$5$$%l%Y%k$N%0%k!<%W$N$_$r%A%'%C%/$7$^$9(B -(@code{gnus-group-get-new-news})$B!#?t;z0J30$N%W%l%U%#%C%/%9$rM?$($k$H!"$3$N(B -$BL?Na$O$=$N%P%C%/%(%s%I$+$i%"%/%F%#%V%U%!%$%k$r6/@)E*$KA4ItFI$_D>$7$^$9!#(B - -@item M-g -@kindex M-g (Group) -@findex gnus-group-get-new-news-this-group -@vindex gnus-goto-next-group-when-activating -@c @icon{gnus-group-get-new-news-this-group} -$B8=:_$N%0%k!<%W$K?7Ce5-;v$,$"$k$+$I$&$+$r%A%'%C%/$7$^$9(B -(@code{gnus-group-get-new-news-this-group})$B!#(B -@code{gnus-goto-next-group-when-activating} $B$O$3$NL?Na$,r7o$KA4$F$N%0%k!<%W$r5/F0$7$^$9(B (@code{gnus-activate-all-groups})$B!#(B - -@item R -@kindex R (Group) -@cindex restarting -@findex gnus-group-restart -Gnus $B$r%j%9%?!<%H$7$^$9(B (@code{gnus-group-restart})$B!#$3$l$O(B -@file{.newsrc} $B%U%!%$%k$r%;!<%V$7!"A4$F$N%5!<%P$N@\B3$rJD$8!"A4$F$N(B gnus -$B%i%s%?%$%`JQ?t$r%/%j%"$7$?8e!"(Bgnus $B$r$b$&0lEY:G=i$+$i3+;O$7$^$9!#(B - -@end table - -@vindex gnus-get-new-news-hook -@code{gnus-get-new-news-hook} $B$O?7Ce%K%e!<%9$r%A%'%C%/$9$kD>A0$K(B -$BpJs(B -@cindex group information -@cindex information on groups - -@table @kbd - - -@item H f -@kindex H f (Group) -@findex gnus-group-fetch-faq -@vindex gnus-group-faq-directory -@cindex FAQ -@cindex ange-ftp -$B8=:_$N%0%k!<%W$N(B FAQ $B$ro%j%b!<%H%^%7%s>e$N%G%#%l%/%H%j$G$9!#$3$NJQ?t$O%G%#%l%/%H%j$N%j%9%H$G(B -$B$"$C$F$b9=$$$^$;$s!#$3$N>l9g!"$3$N%3%^%s%I$K%W%l%U%#%C%/%9$rM?$($k$3$H$G$$(B -$B$/$D$+$N%5%$%H$NCf$+$iA*$V$3$H$,$G$-$^$9!#%U%!%$%k$Nl9g!"(Bgnus $B$O(B -@code{gnus-group-faq-directory} $B$NCM$rA4$F!"0l$D0l$D%*!<%W%s$7$F$_$h$&$H$7(B -$B$^$9!#(B - -@item H d -@itemx C-c C-d -@c @icon{gnus-group-describe-group} -@kindex H d (Group) -@kindex C-c C-d (Group) -@cindex describing groups -@cindex group description -@findex gnus-group-describe-group -$B8=:_$N%0%k!<%W$N@bL@$rI=<($9$k(B -(@code{gnus-group-describe-group})$B!#%W%l%U%#%C%/%9$rM?$($k$H!"@b(B -$BL@J8$r%5!<%P$+$i6/@)E*$K:FFI$_9~$_$7$^$9!#(B - -@item M-d -@kindex M-d (Group) -@findex gnus-group-describe-all-groups -$BA4$F$N%0%k!<%W$N@bL@$rI=<($7$^$9(B -(@code{gnus-group-describe-all-groups})$B!#%W%l%U%#%C%/%9$rM?$($k(B -$B$H!"@bL@J8%U%!%$%k$r%5!<%P$+$i6/@)E*$K:FFI$_9~$_$7$^$9!#(B - -@item H v -@itemx V -@kindex V (Group) -@kindex H v (Group) -@cindex version -@findex gnus-version -$B8=:_$N(B gnus $B$N%P!<%8%g%sHV9f$rI=<($7$^$9(B (@code{gnus-version})$B!#(B - -@item ? -@kindex ? (Group) -@findex gnus-group-describe-briefly -$B$H$F$bC;$$%X%k%W%a%C%;!<%8$rM?$($^$9(B (@code{gnus-group-describe-briefly})$B!#(B - -@item C-c C-i -@kindex C-c C-i (Group) -@cindex info -@cindex manual -@findex gnus-info-find-node -Gnus $B$N(B info $B%N!<%I$K0\F0$7$^$9(B (@code{gnus-info-find-node}).$B!#(B - -@end table - - -@node Group Timestamp -@subsection $B%0%k!<%W$NF|IU(B -@cindex timestamps -@cindex group timestamps - -Gnus $B$K!"$"$J$?$,:G8e$K$$$D%0%k!<%W$rFI$s$@$+$r5-O?$5$;$k$HJXMx(B -$B$+$b$7$l$^$;$s!#$3$N3hF0$r;O$a$5$;$k$K$O!"(B -@code{gnus-group-set-timestamp}$B$r(B @code{gnus-select-group-hook} -$B$KDI2C$7$F$/$@$5$$!#(B - -@lisp -(add-hook 'gnus-select-group-hook 'gnus-group-set-timestamp) -@end lisp - -$B$3$l$r9T$C$?8e!"$"$J$?$,%0%k!<%W$KF~$k$?$S$K$=$l$,5-O?$5$l$^$9!#(B - -$B$3$N>pJs$O$5$^$6$^$JJ}K!$GI=<($G$-$^$9!=!=$b$C$H$b4JC1$J$N$O!"%0%k!<%W9T%U%)!<(B -$B%^%C%H$G(B @samp{%d} $B;XDj$r;H$&J}K!$G$9!'(B - -@lisp -(setq gnus-group-line-format - "%M\%S\%p\%P\%5y: %(%-40,40g%) %d\n") -@end lisp - -$B$3$N7k2L$H$7$F!"3F9T$O0J2<$N$h$&$KI=<($5$l$^$9!'(B - -@example -* 0: mail.ding 19961002T012943 - 0: custom 19961002T012713 -@end example - -$B8+$FJ,$+$k$H$*$j!"F|IU$O%3%s%Q%/%H$J(B ISO 8601 $B7A<0$GI=<($5$l$^$9!#(B -$B$3$l$G$O$A$g$C$H$"$s$^$j$J$N$G!"0J2<$N$h$&$J46$8$K$9$k$HF|IU$@$1(B -$B$rI=<($G$-$^$9!#(B - -@lisp -(setq gnus-group-line-format - "%M\%S\%p\%P\%5y: %(%-40,40g%) %6,6~(cut 2)d\n") -@end lisp - - -@node File Commands -@subsection $B%U%!%$%kL?Na(B -@cindex file commands - -@table @kbd - -@item r -@kindex r (Group) -@findex gnus-group-read-init-file -@vindex gnus-init-file -@cindex reading init file -$B=i4|2=%U%!%$%k$N:FFI$_9~$_$r9T$&(B (@code{gnus-init-file}$B!"$3$N%G(B -$B%U%)%k%H$O(B @file{~/.gnus}) (@code{gnus-group-read-init-file})$B!#(B - -@item s -@kindex s (Group) -@findex gnus-group-save-newsrc -@cindex saving .newsrc -@file{.newsrc.eld}$B%U%!%$%k!J$H!"$b$7$=$&$7$?$1$l$P(B@file{.newsrc} $B%U%!%$%k!K(B -$B$r%;!<%V$9$k(B(@code{gnus-group-save-newsrc})$B!#(B - -@c @item Z -@c @kindex Z (Group) -@c @findex gnus-group-clear-dribble -@c $B%I%j%V%k%U%!%$%k$r%/%j%"$9$k(B -@c (@code{gnus-group-clear-dribble})$B!#(B - -@end table - - -@node The Summary Buffer -@chapter $B35N,%P%C%U%!(B -@cindex summary buffer - -$B35N,%P%C%U%!(B (summary buffer) $B$G$O$=$l$>$l$N5-;v$,0l9T$GI=<($5$l$^$9!#$=(B -$B$NCf$rF0$-2s$j!"5-;v$rFI$_!"Ej9F$7!"JVEz$r$9$k$3$H$,$G$-$^$9!#(B - -$B35N,%P%C%U%!$K0\$k0lHVIaDL$NJ}K!$O!"%0%k!<%W%P%C%U%!$G%0%k!<%W$rA*Br$9$k(B -$B$3$H$G$9(B (@pxref{Selecting a Group})$B!#(B - -$B35N,%P%C%U%!$OK>$`$@$1$?$/$5$s3+$$$?>uBV$K$7$F$*$/$3$H$,$G$-$^$9!#(B - -@menu -* Summary Buffer Format:: $B35N,%P%C%U%!$N304Q$r7hDj$9$k!#(B -* Summary Maneuvering:: $B35N,%P%C%U%!$rF0$-2s$k!#(B -* Choosing Articles:: $B5-;v$rFI$`!#(B -* Paging the Article:: $BFI$s$G$$$k5-;v$r%9%/%m!<%k$9$k!#(B -* Reply Followup and Post:: $B5-;v$rEj9F$9$k!#(B -* Canceling and Superseding:: $B!X$"$!!"$"$s$J$U$&$K8@$&$s$8$c$J$+$C$?!#!Y(B -* Marking Articles:: $B5-;v$K4{FI$d4|8B@Z$l:o=|2DG=Ey$N0u$rIU$1$k!#(B -* Limiting:: $B35N,%P%C%U%!$K@)8B$r2C$($k$3$H$,$G$-$k!#(B -* Threading:: $B%9%l%C%I$,$I$N$h$&$K:n$i$l$k$+!#(B -* Sorting:: $B%9%l%C%I$H5-;v$,$I$N$h$&$KJB$S$+$($i$l$k$+!#(B -* Asynchronous Fetching:: Gnus $B$O5-;v$r@h$KC5n$7$J$/$5$;$k!#(B -* Article Backlog:: $B4{$KFI$s$@5-;v$r;D$7$F$*$/!#(B -* Saving Articles:: $B5-;v$NJ]B8$r%+%9%?%^%$%:$9$kJ}K!!#(B -* Decoding Articles:: Gnus $B$O0lO"$N(B (uu)encode $B$5$l$?5-;v$r07$($k!#(B -* Article Treatment:: $B5-;v%P%C%U%!$O$*K>$_$I$*$j$KL\Cc6lCc$K$G$-$k!#(B -* Article Commands:: $B5-;v%P%C%U%!$G$$$m$$$m$J$3$H$r$9$k!#(B -* Summary Sorting:: $B$$$m$$$m$JJ}K!$G35N,%P%C%U%!$rJB$YBX$($k!#(B -* Finding the Parent:: $B;R5-;v$K1g=u$,L5$$$C$F(B? $B?F5-;v$r$N$I$N>l=j$K$b9g$o$J$+$C$?$b$N!#(B -* Exiting the Summary Buffer:: $B%0%k!<%W%P%C%U%!$KLa$k!#(B -* Crosspost Handling:: $B%/%m%9%]%9%H$5$l$?5-;v$,$I$N$h$&$K07$o$l$k$+!#(B -* Duplicate Suppression:: $B%/%m%9%]%9%H$N07$$$K<:GT$7$?$H$-$NBeBXA0$H%"%I%l%9$NItJ,$ro$KB.$/F0:n$7$^$9!#(B -@code{mail-extract-address-components} $B$ONI$/F0:n$7$^$9$,!"$d$dCY$/$J$j$^(B -$B$9!#$=$7$F!"(B@code{std11-extract-address-components} $B$O$H$F$bNI$/F0:n$7$^$9(B -$B$,!"CY$/$J$j$^$9!#%G%#%U%)%k%H$N4X?t$O(B 5% $B$N3d9g$G4V0c$C$FEz$($^$9!#$b$7$3(B -$B$l$K2fK}$J$i$J$$$N$G$"$l$P!"B>$N4X?t$rBe$o$j$K;H$&$3$H$,$G$-$^$9!#(B - -@vindex gnus-summary-same-subject -@code{gnus-summary-same-subject} $B$O:#FI$s$G$$$k5-;v$,!"$=$NA0$N5-;v$HF1(B -$B$8I=Bj(B (subject) $B$G$"$k$3$H$r<($9J8;zNs$G$9!#$3$NJ8;zNs$O;EMM$,$3$l$rMW(B -$B5a$9$k$H$-$K;H$o$l$^$9!#%G%#%U%)%k%H$G$O(B @code{""} $B$G$9!#(B - - -@node Summary Buffer Lines -@subsection $B35N,%P%C%U%!$N9T(B - -@vindex gnus-summary-line-format -$BJQ?t(B @code{gnus-summary-line-format} $B$NCM$rJQ$($k$3$H$K$h$C$F!"35N,%P%C(B -$B%U%!$G$N9T$NMM<0(B (format) $B$rJQ99$9$k$3$H$,$G$-$^$9!#$$$/$D$+$N3HD%(B -(@pxref{Formatting Variables}) $B$r=|$$$F!"IaDL$N(B @code{format} $BJ8;zNs$HF1(B -$B$8$h$&$KF0:n$7$^$9!#(B - -$B%G%#%U%)%k%H$NJ8;zNs$O(B @samp{%U%R%z%I%(%[%4L: %-20,20n%]%) %s\n} $B$G$9!#(B - -$B0J2<$NMM<0;X<(J8;z$r;H$&$3$H$,$G$-$^$9(B: - -@table @samp -@item N -$B5-;v?t!#(B -@item S -$BI=Bj$NJ8;zNs!#(B -@item s -$B%9%l%C%I(B (thread) $B$N4p5-;v$G$"$k$H$-$+D>A0$N5-;v$,0c$&I=Bj$N$H$-$O$=$NBj(B -$BL>$G!"$=$l0J30$O(B @code{gnus-summary-same-subject}$B!#(B -(@code{gnus-summary-same-subject} $B$N%G%#%U%)%k%H$NCM$O(B @code{""}$B!#(B) -@item F -$B40A4$J(B @code{From} $BMs!#(B -@item n -$BL>A0!J(B@code{From} $BMs$h$j!K!#(B -@item a -$BL>A0!J(B@code{From} $BMs$h$j!K!#$3$l$H(B @code{n} $B$H$N0c$$$O!"$3$l$OJQ?t(B -@code{gnus-extract-address-components} $B$G;XDj$5$l$F$$$k4X?t$r;H$C$FL>A0$r(B -$BA0!J(B@code{From} $BMs$h$j!K!#$3$l$O(B @code{a} $B$HF1$8$h$&$KF0:n$7$^$9!#(B -@item L -$B5-;v$N9T?t!#(B -@item c -$B5-;v$NJ8;z?t!#(B -@item I -$B%9%l%C%I$N%l%Y%k$K$h$k;z2<$2(B (@pxref{Customizing Threading})$B!#(B -@item T -$B5-;v$,K\5-;v$G$"$l$P2?$bI=<($;$:!"$=$&$G$J$$>l9g$O$?$/$5$s$N6uGr$G$9!J8e$N(B -$B$b$N$r$9$Y$F2hLL$N30$KDI$$=P$7$F$7$^$$$^$9!K!#(B -@item [ -$B3+$-3g8L!#IaDL$O(B @samp{[} $B$G$9$,!"M\;R5-;v$K$O(B @samp{<} $B$K$9$k$3$H$,$G$-(B -$B$^$9(B (@pxref{Customizing Threading})$B!#(B -@item ] -$BJD$83g8L!#IaDL$O(B @samp{[} $B$G$9$,!"M\;R5-;v$K$O(B @samp{<} $B$K$9$k$3$H$,$G$-(B -$B$^$9!#(B -@item > -$B$=$l$>$l$N%9%l%C%I$N%l%Y%k$KBP$7$F0l$D$N6uGr!#(B -@item < -$BFs==0z$/%9%l%C%I%l%Y%k$N6uGr!#(B -@item U -$BL$FI!#(B - -@item R -$B$3$NJ6$i$o$7$$L>A0;XDj;R$O(B @dfn{secondary mark} $B$K$h$C$FDj5A$5$l$^$9!#$3$N(B -$B%^!<%/$O5-;v$,4{$KJVEz:Q$_$N$b$N$+!"%-%c%C%7%e$5$l$?$b$N$+!"$"$k$$$OJ]B8$5(B -$B$l$?$b$N$+$rI=$7$^$9!#(B - -@item i -$B?t;z$H$7$F$N%9%3%"(B (@pxref{Scoring})$B!#(B -@item z -@vindex gnus-summary-zcore-fuzz -$B$3$l$O!"(Bzcore $B$G%G%#%U%)%k%H$N%l%Y%k$h$j$b>e$G$"$l$P(B @samp{+} $B$G!"%G%#%U%)(B -$B%k%H$N%l%Y%k$h$j$b2<$G$"$l$P(B @samp{-} $B$G$9!#(B -@code{gnus-summary-default-score} $B$H$N:9$,(B @code{gnus-summary-zcore-fuzz} -$B$h$j$b>.$5$$$H!"$3$N;EMM$O;H$o$l$^$;$s!#(B -@item V -$B%9%l%C%IA4BN$N%9%3%"!#(B -@item x -@code{Xref}. -@item D -@code{$BF|IU(B} (@code{Date})$B!#(B -@item d -@code{DD-MM}$BMM<0$K$h$k(B@code{$BF|IU(B}$B!#(B -@item o -@var{YYYYMMDD}@code{T}@var{HHMMSS}$BMM<0$K$h$k(B@code{$BF|IU(B}$B!#(B -@item M -@code{Message-ID}. -@item r -@code{References}. -@item t -$B8=:_$NI{%9%l%C%I$N5-;v$N?t!#$3$N;EMM$r;H$&$H35N,%P%C%U%!$N@8@.$,4vJ,CY$/(B -$B$J$j$^$9!#(B -@item e -$B5-;v$K;R5-;v$,$"$k$H!"(B@samp{=} (@code{gnus-not-empty-thread-mark}) $B$,I=(B -$B<($5$l$^$9!#(B -@item P -$B9T?t!#(B -@item O -$B%@%&%s%m!<%I$N0u!#(B -@item u -$BMxMQ$N35N,;XDj$HF1(B -$BMM$K35N,$KA^F~$5$l$^$9!#(B -@end table - -@samp{%U}$B!J>uBV!K!"(B@samp{%R}$B!JJVEz:Q$_!K!"(B@samp{%z} (zcore) $B$N07$$$K$O5$$r(B -$BIU$1$kI,MW$,$"$j$^$9!#8zN($N$?$a$K!"(Bgnus $B$O$3$l$i$NJ8;z$,$I$N7e$K8=$l$k$+(B -$B$r7W;;$7!"!X%O!<%I!&%3!<%I!Y$7$^$9!#$3$l$O!"2DJQD9$N;EMM$N8e$G$O!"$3$l$i$O(B -$B0UL#$r;}$?$J$$$H$$$&$3$H$G$9!#$^$!!"$5$9$,$KBaJa$O$5$l$J$$$G$7$g$&$,!"35N,(B -$B%P%C%U%!$OJQ$K$J$j$^$9!#$=$l$G$b==J,Ha$7$$$G$7$g$&$1$I!#(B - -$B8-$$A*Br$O$3$l$i$N;XDj$r$G$-$k$@$1:8$K;}$C$F$/$k$3$H$G$9!#!J$G$b!"$=$&$$(B -$B$&$3$H$O$9$Y$F$KEv$F$O$^$k$N$G$O$J$$$G$7$g$&$+!#4WOC5YBj!#!K(B - -$B$3$N@)8B$O>-Mh$NHG$G$OL5$/$J$k$+$bCN$l$^$;$s!#(B - - -@node Summary Buffer Mode Line -@subsection $B35N,%P%C%U%!$N%b!<%I9T(B - -@vindex gnus-summary-mode-line-format -$B35N,$N%b!<%I9T$NMM<0$bJQ99$9$k$3$H$,$G$-$^$9(B (@pxref{Mode Line -Formatting})$B!#(B@code{gnus-summary-mode-line-format} $B$r2?$G$b9%$-$J$b$N$K(B -$BJQ99$7$F$/$@$5$$!#%G%#%U%)%k%H$O(B @samp{Gnus: %%b [%A] %Z} $B$G$9!#(B - -$B0J2<$,$"$J$?$,M7$V$3$H$N$G$-$k$=$l$>$l$NMWAG$G$9!'(B - -@table @samp -@item G -$B%0%k!<%WL>!#(B -@item p -$B@\F,8l$rA0!#(B -@item A -$B8=:_$N5-;vHV9f!#(B -@item z -$B8=:_$N5-;v%9%3%"!#(B -@item V -Gnus $B%P!<%8%g%s!#(B -@item U -$B$=$N%0%k!<%W$G$NL$FI5-;v$N?t!#(B -@item e -$B35N,%P%C%U%!$KI=<($5$l$F$$$J$$L$FI5-;v$N?t!#(B -@item Z -$BL$FI$HL$A*Br$N5-;v$N?t$H$H$b$KI=$5$l$kJ8;zNs$G!"L$FI$+$DL$A*Br$N5-;v$,$"(B -$B$k>l9g$O(B @samp{<%U(+%e) more>} $B$G!"L$FI5-;v$N$_$N>l9g$O(B @samp{<%U more>} -$B$G$9!#(B -@item g -$BC;=L%0%k!<%WL>!#Nc$($P!"(B@samp{rec.arts.anime} $B$O(B @samp{r.a.anime} $B$KC;=L(B -$B$5$l$^$9!#(B -@item S -$B8=:_$N5-;v$NI=Bj!#(B -@item u -$BMxMQA0(B (@pxref{Scoring})$B!#(B -@item d -$BJ]N15-;v$N?t(B (@pxref{Unread Articles})$B!#(B -@item t -$B2D;k0uIU$-5-;v$N?t(B (@pxref{Unread Articles})$B!#(B -@item r -$B$=$N0lO"$NF0:n$N4V$K4{FI$H$7$F0u$,$D$$$?5-;v$N?t!#(B -@item E -$B%9%3%"%U%!%$%k$K$h$C$FKu>C$5$l$?5-;v$N?t!#(B -@end table - - -@node Summary Highlighting -@subsection $B35N,$N%O%$%i%$%H(B - -@table @code - -@item gnus-visual-mark-article-hook -@vindex gnus-visual-mark-article-hook -$B$3$N%U%C%/$O5-;v$rA*Br$7$?8e$Kl9g$Ol9g$O score default) . bold)) -@end lisp -$B$4A[A|$N$H$*$j!"$b$7(B @var{FORM} $B$,(B @code{nil} $B$G$J$$CM$rJV$9$H!"(B -@var{FACE} $B$,$=$N9T$KE,MQ$5$l$^$9!#(B -@end table - - -@node Summary Maneuvering -@section $B35N,4V$N0\F0(B -@cindex summary movement - -$B$9$Y$F$ND>@\0\F0L?Na$O?tCM@\F,0z?t$r)$a$^$9!#$3$NJQ?t$,(B @code{t}$B$Gl9g$H$7$F!"$3$NJQ?t$,(B -@code{quietly} $B$G$"$k$H!"(Bgnus $B$O3NG'$r$;$:$K!"H$7$F$/$@$5$$!#(B - -@item gnus-auto-select-same -@vindex gnus-auto-select-same -@code{nil} $B$G$J$$$H!"$9$Y$F$N0\F0L?Na$O8=:_$N5-;v$HF1$8I=Bj$N5-;v$K0\F0(B -$B$7$h$&$H$7$^$9!#(B(@dfn{$BF1$8(B} $B$O$3$3$G$O(B @dfn{$BBgBNF1$8(B} $B$H$$$&0UL#$+$bCN$l(B -$B$^$;$s!#>\:Y$O(B @code{gnus-summary-gather-subject-limit} $B$r8+$F$/$@$5$$(B -(@pxref{Customizing Threading} $B$b;2>H$7$F$/$@$5$$(B)$B!#(B) $BF1$8I=Bj$N5-;v$,L5(B -$B$$$H$-$O:G=i$NL$FI5-;v$K0\F0$7$^$9!#(B - -$B$3$NJQ?t$O!"%9%l%C%II=<($r9T$C$F$$$k$H$-$O$"$^$jLr$KN)$?$J$$$G$7$g$&!#(B - -@item gnus-summary-check-current -@vindex gnus-summary-check-current -@code{nil} $B$G$J$$$H!"$9$Y$F$N!XL$FI!Y0\F0L?Na$O!"o$K??Cf$KJ]$A$^$9!#(B -$B$3$l$r$9$k$H!"$H$F$b$3$.$l$$$K$J$j$^$9$,!"CY$$%M%C%H%o!<%/@\B3$G$"$C$?$j!"(B -$BC1$K$3$N(B Emacsism $B$G$J$$9T0Y$r9%$-$K$J$l$J$$$N$G$"$l$P!"IaDL$N(B Emacs $B$N(B -$B%9%/%m!<%k$K$9$k$?$a$K!"$3$NJQ?t$r(B @code{nil} $B$K$9$k$3$H$,$G$-$^$9!#$3$l(B -$B$O35N,%P%C%U%!$N?eJ?J}8~$N??Cf$X$N:F0\F0$b6X;_$7$^$9$N$G!"Hs>o$KD9$$%9%l%C(B -$B%I$rFI$`$H$-$OITJX$+$b$7$l$^$;$s!#(B - -@end table - - -@node Choosing Articles -@section $B5-;v$NA*Br(B -@cindex selecting articles - -@menu -* Choosing Commands:: $B5-;v$rA*Br$9$k$?$a$NL?Na!#(B -* Choosing Variables:: $B$3$l$i$NL?Na$K1F6A$r5Z$\$9JQ?t!#(B -@end menu - - -@node Choosing Commands -@subsection $BL?Na$NA*Br(B - -$B0J2<$N0\F0%3%^%s%I$O$I$l$b?tCM@\F,0z?t$rl9g$OA0$N5-;v$K0\F0$7$^$9(B (@code{gnus-summary-goto-last-article})$B!#(B - -@item G o -@kindex G o$B!J35N,!K(B -@findex gnus-summary-pop-article -$B35N,$NMzNr(B (history) $B$+$i:G8e$N5-;v$r0l$De$NL?Na$H0c$&$N$O!"(B@kbd{l} -$B$,:G=*(B2$B$D$N5-;v$N4V$r0\F0$9$k$N$KBP$7$F!"$3$l$O9%$-$J$@$1A0$N5-;v$rMzNr$+(B -$B$iA*$S=P$9$3$H$,$G$-$kE@$G$9!#2?$i$+$N$3$l$K4X78$7$?$3$H$O!J$b$7$3$l$i$NL?(B -$BNa$r$?$/$5$s;H$&$N$G$"$l$P!K!"(B@pxref{Article Backlog} $B$r;2>H$7$F$/$@$5$$!#(B -@end table - - -@node Choosing Variables -@subsection $BA*$V$?$a$NJQ?t(B - -$B5-;v$r0\F0$7!"A*Br$9$k$N$K4XO"$7$?$$$/$D$+$NJQ?t(B: - -@table @code -@item gnus-auto-extended-newsgroup -@vindex gnus-auto-extend-newsgroup -$B$3$NJQ?t$,(B @code{nil} $B$G$J$$$H!"$9$Y$F$N0\F0L?Na$O!"$b$7$=$N5-;v$,35N,%P%C(B -$B%U%!$KI=<($5$l$F$$$J$$>l9g$G$b!"A0!J$b$7$/$Oo$K8F$P$l$^$9!#%G%#%U%)%k%H$G$O!"A*Br(B -$B$5$l$?5-;v$N2<$K1#$l$F$$$k%9%l%C%I$r8+$;$k$h$&$K$J$C$F$$$^$9!#(B - -@item gnus-mark-article-hook -@vindex gnus-mark-article-hook -@findex gnus-summary-mark-unread-as-read -@findex gnus-summary-mark-read-and-unread-as-read -@findex gnus-unread-mark -$B$3$N%U%C%/$O5-;v$,A*Br$5$l$?$H$-$K>o$K8F$P$l$^$9!#$=$l$O5-;v$K4{FI$N0u$rIU(B -$B$1$k$?$a$K$"$j$^$9!#%G%#%U%)%k%H$NCM$O(B -@code{gnus-summary-mark-read-and-unread-as-read} $B$G!"$[$H$s$I$9$Y$F$NFI$s(B -$B$@5-;v$N0u$r(B @code{gnus-read-mark} $B$KJQ99$7$^$9!#$3$N4X?t$K1F6A$5$l$J$$5-(B -$B;v$O!"2D;k!"J]N1!"4|8B@Z$l:o=|2DG=5-;v$@$1$G$9!#$b$7!"L$FI$K4{FI$N0u$rIU$1(B -$B$?$$$@$1$G$"$l$P!"Be$o$j$K(B @code{gnus-summary-mark-unread-as-read} $B$r;H$&(B -$B$3$H$,$G$-$^$9!#$=$l$O!"(B@code{gnus-low-score-mark} $B$d(B -@code{gnus-del-mark}$B!J$J$I$J$I!K$N0u$r$=$N$^$^;D$7$^$9!#(B - -@end table - - -@node Paging the Article -@section $B5-;v$N%9%/%m!<%k(B -@cindex article scrolling - -@table @kbd - -@item SPACE -@kindex SPACE $B!J35N,!K(B -@findex gnus-summary-next-page -@kbd{SPACE} $B$O5-;v$r0l%Z!<%8@h$K%9%/%m!<%k$7$^$9!#5-;v$N:G8e$K$$$k>l9g$O(B -$B -@itemx > -@kindex > $B!J35N,!K(B -@kindex A > $B!J35N,!K(B -@findex gnus-summary-end-of-article -$B5-;v$N:G8e$^$G%9%/%m!<%k$7$^$9(B (@code{gnus-summary-end-of-article})$B!#(B - -@item A s -@itemx s -@kindex A s $B!J35N,!K(B -@kindex s $B!J35N,!K(B -@findex gnus-summary-isearch-article -$B5-;v%P%C%U%!$G%$%s%/%j%a%s%?%k%5!<%A(B (isearch) $B$r9T$$$^$9(B -(@code{gnus-summary-isearch-article})$B!#(B - -@item h -@kindex h $B!J35N,!K(B -@findex gnus-summary-select-article-buffer -$B5-;v%P%C%U%!$rA*Br$7$^$9(B (@code{gnus-summary-select-article-buffer})$B!#(B - -@end table - - -@node Reply Followup and Post -@section $BJVEz!"%U%)%m!<%"%C%W!"Ej9F(B - -@menu -* Summary Mail Commands:: $B%a!<%k$rAw$k!#(B -* Summary Post Commands:: $B%K%e!<%9$rAw$k!#(B -@end menu - - -@node Summary Mail Commands -@subsection $B35N,$G$N%a!<%k$NL?Na(B -@cindex mail -@cindex composing mail - -$B%a!<%k%a%C%;!<%8$r:n@.$9$k$?$a$NL?Na(B: - -@table @kbd - -@item S r -@item r -@kindex S r $B!J35N,!K(B -@kindex r $B!J35N,!K(B -@findex gnus-summary-reply -@c @icon{gnus-summary-mail-reply} -@c @icon{gnus-summary-reply} -$B8=:_$N5-;v$r=q$$$??M$KJVEz$N%a!<%k$rAw$j$^$9(B (@code{gnus-summary-reply})$B!#(B - -@item S R -@itemx R -@kindex R $B!J35N,!K(B -@kindex S R $B!J35N,!K(B -@findex gnus-summary-reply-with-original -@c @icon{gnus-summary-reply-with-original} -$B8=:_$N5-;v$r=q$$$??M$K!"K\5-;v$r4^$s$@JVEz$N%a!<%k$r=P$7$^$9(B -(@code{gnus-summary-reply-with-original})$B!#$3$NL?Na$O%W%m%;%9(B/$B@\F,0z?t$N=,(B -$B47$r;H$$$^$9!#(B - -@item S w -@kindex S w $B!J35N,!K(B -@findex gnus-summary-wide-reply -$B8=:_$N5-;v$r=q$$$??M$KBP$7$F!"9-$$JVEz(B (wide reply) $B$r$7$^$9(B -(@code{gnus-summary-wide-reply})$B!#(B@dfn{$B9-$$JVEz(B} $B$H$O%X%C%@!<$N(B -@code{To}, @code{From},$B!J$b$7$/$O(B @code{Reply-to}) $B$H(B @code{Cc}$B!K$N$9$Y$F(B -$B$N?M$KJVEz$r$9$k$3$H$G$9!#(B - -@item S W -@kindex S W $B!J35N,!K(B -@findex gnus-summary-wide-reply-with-original -$B8=:_$N5-;v$KK\5-;v$r4^$s$@9-$$JVEz$N%a!<%k$rAw$j$^$9(B -(@code{gnus-summary-reply-with-original})$B!#$3$NL?Na$O%W%m%;%9(B/$B@\F,0z?t$N(B -$B=,47$r;H$$$^$9!#(B - -@item S o m -@kindex S o m $B!J35N,!K(B -@findex gnus-summary-mail-forward -@c @icon{gnus-summary-mail-forward} -$BC/$+B>$N?M$K8=:_$N5-;v$rE>Aw$7$^$9(B (@code{gnus-summary-mail-forward})$B!#(B -$B@\F,0z?t$,$"$k$H!"E>Aw5-;v$N40A4$J%X%C%@!<$r$N?M$K%a!<%k$rAw$j$^$9(B (@code{gnus-summary-mail-other-window})$B!#(B - -@item S D b -@kindex S D b $B!J35N,!K(B -@findex gnus-summary-resend-bounced-mail -@cindex bouncing mail -$B%a!<%k$rAw$C$?$N$K!"2?$i$+$NM}M3!J%"%I%l%9$N4V0c$$!"E>Aw$NITD4!K$GLa$C$F$-(B -$B$?$H$-$K!"$3$NL?Na$r;H$C$FLa$C$F$-$?%a!<%k$r$b$&0l2sAw$k$3$H$,$G$-$^$9(B -(@code{gnus-summary-resend-bonced-mail})$B!#$b$&0lEY%a!<%k$rAw$kA0$K%X%C%@!<(B -$B$rJT=8$G$-$k$h$&$K!"%a!<%k%P%C%U%!$K$=$N%a!<%k$,8=$l$k$G$7$g$&!#$3$NL?Na$K(B -$B@\F,0z?t$rM?$($F!"La$C$F$-$?%a!<%k$,C/$+$X$NJVEz$G$"$C$?>l9g!"(Bgnus $B$O$=$N(B -$B%a!<%k$re$NL?Na$H:.F1$7$J$$$h$&$K!"(B@code{gnus-summary-resend-message} $B$O8=:_$N%a%C(B -$B%;!<%8$rAw$k@h$N%"%I%l%9$NF~NO$rB%$7!"$=$l$+$i$=$N>l=j$K%a!<%k$rAw$j$^$9!#(B -$B%a%C%;!<%8$N%X%C%@!<$OJQ99$5$l$^$;$s!=!=$7$+$7!"(B@code{Resent-To}, -@code{Resent-From} $BEy$N%X%C%@!<$,IU$12C$($i$l$^$9!#$3$l$O!"!J$*$=$i$/!K$"(B -$B$J$?<+?H$r(B @code{To} $BMs$K=q$$$?K\?M$K$b%a!<%k$rAw$C$F$7$^$&$H$$$&$3$H$G$9!#(B -$B$3$l$O:.Mp$r>7$/$G$7$g$&!#$G$9$+$i!"$b$A$m$s!"K\Ev$K(B $BAw$7$?$$$H$-$KMQ$$$i$l$^$9!#(B -($B$b$7$"$J$?$,!"(B@code{$B%k!<%H(B} (root) $B$G$"$j!"(B@code{$B%]%9%H%^%9%?!<(B} -(postmaster) $B$G$b$"$j!"(B@code{$B%k!<%H(B} $B$K(B @code{$B%]%9%H%^%9%?!<(B} $B$X$N%a!<%k(B -$B$rl9g$O!"$=$l$r(B @code{$B%]%9%H%^%9%?!<(B} $B$K$b:FAw$7$?$$$H;W$&$G(B -$B$7$g$&!#(BOrdnung mu,A_(B sein!) - -$B$3$NL?Na$O%W%m%;%9(B/$B@\F,0z?t$N=,47$K=>$$$^$9(B (@pxref{Process/Prefix})$B!#(B - -@item S O m -@kindex S O m $B!J35N,!K(B -@findex gnus-uu-digest-mail-forward -$B8=:_$N0lO"$N5-;v(B (@pxref{Decoding Articles}) $B$NMWLs$r:n$j!"%a!<%k$G$=$N7k(B -$B2L$rAw$j$^$9(B (@code{gnus-uu-digest-mail-forward})$B!#$3$NL?Na$O%W%m%;%9(B/$B@\F,(B -$B0z?t$N=,47$K=>$$$^$9(B (@pxref{Process/Prefix})$B!#(B - -@item S M-c -@kindex S M-c $B!J35N,!K(B -@findex gnus-summary-mail-crosspost-complaint -@cindex crossposting -@cindex excessive crossposting -$B8=:_$N5-;v$N=q$-j%/%m%9%]%9%H$X$N6l>p$N%a!<%k$rAw$j$^$9(B -(@code{gnus-summary-mail-crosspost-complaint})$B!#(B - -@findex gnus-crosspost-complaint -$B$3$NL?Na$O!"8=:_(B Usenet $B$K2#9T$7$F$$$k!"%/%m%9%]%9%H$N@$3&E*N.9T$KBP$7$F(B -$BH?7b$r9T$&$$!"$=$l$>$l$N%a!<(B -$B%k$rAw$kA0$KAw?.$9$k$+$I$&$+$N3NG'$r$7$^$9!#(B - -@end table - -$B$^$?(B @pxref{(message)Header Commands} $B$K$5$i$J$k>pJs$,$"$j$^$9!#(B - - -@node Summary Post Commands -@subsection $B35N,$NEj9FL?Na(B -@cindex post -@cindex composing news - -$B%K%e!<%9$N5-;v$rEj9F$9$k$?$a$NL?Na!'(B - -@table @kbd -@item S p -@itemx a -@kindex a $B!J35N,!K(B -@kindex S p $B!J35N,!K(B -@findex gnus-summary-post-news -@c @icon{gnus-summary-post-news} -$B8=:_$N%0%k!<%W$K5-;v$rEj9F$7$^$9(B (@code{gnus-summary-post-news})$B!#(B - -@item S f -@itemx f -@kindex f $B!J35N,!K(B -@kindex S f $B!J35N,!K(B -@findex gnus-summary-followup -@c @icon{gnus-summary-followup} -$B8=:_$N5-;v$N%U%)%m!<%"%C%W$rEj9F$7$^$9(B (@code{gnus-summary-followup})$B!#(B - -@item S F -@itemx F -@kindex S F $B!J35N,!K(B -@kindex F $B!J35N,!K(B -@c @icon{gnus-summary-followup-with-original} -@findex gnus-summary-followup-with-original -$BK\5-;v$rAw$7$^$9(B -(@code{gnus-summary-post-forward})$B!#@\F,0z?t$,M?$($i$l$?$H$-$O!"E>Aw5-;v(B -$B$N%X%C%@!<$r40A4$KpJs$,$"$j$^$9!#(B - - -@node Canceling and Superseding -@section $B5-;v$rC$9(B -@cindex canceling articles -@cindex superseding articles - -$B2?$+$r=q$$$?8e$G!"K\Ev$K!"K\Ev$K!"$[(B $B$s(B $B$H(B $B$&(B $B$K$=$l$rEj9F$7$F$$$J$1$l$P(B -$B$J$!$H;W$C$?$3$H$O$"$j$^$;$s$+!#(B - -$B$(!<$H!"%a!<%k$OC$9$3$H$O$G$-$J$$$N$G$9$,!"%K%e!<%9$NEj9F$OC$9(B -$B$3$H$,$G$-$^$9!#(B - -@findex gnus-summary-cancel-article -@kindex C $B!J35N,!K(B -@c @icon{gnus-summary-cancel-article} -$BC$7$?$$5-;v$r8+$D$1$F$/$@$5$$!JC$9$3$H$,$G$-$k$N$O<+J,$N5-;v$@$1(B -$B$G$9!#JQ$J$3$H$O;n$5$J$$$G$/$@$5$$!K!#$=$l$+$i!"(B @kbd{C} $B$+(B @kbd{S c}$B$r2!(B -$B$7$F$/$@$5$$(B (@code{gnus-summary-cancel-article})$B!#$"$J$?$N5-;v$,C$5(B -$B$l$^$9!=!=@$3&Cf$N5!3#$,$"$J$?$N5-;v$rC$7$^$9!#$3$NL?Na$O%W%m%;%9(B/$B@\(B -$BF,0z?t$N=,47$rMQ$$$^$9(B (@pxref{Process/Prefix})$B!#(B - -$B$7$+$7!"Cm0U$7$F$[$7$$$N$O$9$Y$F$N%5%$%H(B (site) $B$,C$7$r07$C$F$$$k$o(B -$B$1$G$O$J$$$3$H$G$9!#$G$9$+$i!"$?$$$F$$$N%5%$%H$,LdBj$N5-;v$rC$7$F$b!"(B -$B$"$A$3$A$G$"$J$?$N5-;v$O@8$-;D$k$+$b$7$l$^$;$s!#(B - -Gnus $B$O!"C$9$H$-$K!X8=:_!Y$NA*BrJ}K!$r;H$$$^$9!#I8=`$NEj9FJ}K!$r;H$$(B -$B$?$$$N$G$"$l$P!"J8;z@\F,0z?t(B @samp{a} $B$r;H$C$F$/$@$5$$(B(@pxref{Symbolic -Prefixes})$B!#(B - -$B$b$72?$+4V0c$$$r$7$?$N$K5$IU$$$F!"D{@5$r$7$?$$$N$G$"$l$P!"(B@dfn{$BBeBX(B} -(@dfn{superseding}) $B5-;v$rEj9F$7$FK\5-;v$rCV$-49$($k$3$H$,$G$-$^$9!#(B - -@findex gnus-summary-supersede-article -@kindex S $B!J35N,!K(B -$BK\5-;v$N$H$3$m$X0\F0$7$F!"(B@kbd{S s} $B$r2!$7$F$/$@$5$$(B -(@code{gnus-summary-supersede-article})$B!#IaDL$NJ}K!$G$=$l$rAw$kA0$K!"5-;v(B -$B$r9%$-$J$h$&$KJT=8$9$k$3$H$,$G$-$^$9!#BeBX$K4X$7$F$b!"C$7$HF1$8$3$H$,(B -$BEv$F$O$^$j$^$9!#$3$A$i$NJ}$,$b$C$H$h$/Ev$F$O$^$k$+$b$7$l$^$;$s!'$$$/$D$+$N(B -$B%5%$%H$OBeBX$rl9g!"5-;v$,:G=i$K$"(B -$B$J$?$N%5%$%H$K8=$l$kA0$KC$7(B/$BBeBX$r$9$k$?$a$N9*L/$Jj$J$/$i$$$NL?Na$,$"$j$^$9!'(B -@end ifinfo - -@menu -* Setting Marks:: $B0u$NIU$1J}$H>C$7J}(B -* Setting Process Marks:: $B8e$No$K2D;k>uBV$G$"$k5-;v$N$3$H$G$9!#$*$b$7$m$$$H;W$&5-;v(B -$B$,$"$C$?>l9g$d!"C1$KFI$`$N$r@h$K1d$P$7$?$$$H$-$d!"8e$GJVEz$r$7$?$$$H$-$K!"(B -$BIaDL$O2D;k0u$rIU$1$^$9!#$7$+$7!"5-;v$O4|8B@Z$l>C5n$5$l$k$3$H$b$"$j$^$9$N$G!"(B -$B1J1s$K5-;v$rJ]B8$7$F$*$-$?$$>l9g$O!"$=$N5-;v$r1JB3$K$9$kI,MW$,$"$j$^$9(B -(@pxref{Persistent Articles})$B!#(B - -@item ? -@vindex gnus-dormant-mark -$BJ]N1$H$7$F0u$rIU$1$^$9(B (@code{gnus-dormant-mark})$B!#(B - -@dfn{$BJ]N15-;v(B}$B$O%U%)%m!<%"%C%W$,$"$C$?$H$-$K$@$135N,%P%C%U%!$K8=$l$^$9!#%U%)(B -$B%m!<%"%C%W$,L5$$$H$-$bI=<($5$;$?$$$H$-$O!"L?Na(B @kbd{/ D} $B$r;H$&$3$H$,$G$-(B -$B$^$9!#(B - -@item SPACE -@vindex gnus-unread-mark -$BL$FI$H$7$F0u$rIU$1$^$9(B (@code{gnus-unread-mark})$B!#(B - -@dfn{$BL$FI5-;v(B}$B$O:#$^$GA4$/FI$^$l$F$$$J$$5-;v$N$3$H$G$9!#(B -@end table - - -@node Read Articles -@subsection $B4{FI5-;v(B -@cindex expirable mark - -$B0J2<$N$9$Y$F$N0u$O5-;v$K4{FI$N0u$rIU$1$^$9!#(B - -@table @samp - -@item r -@vindex gnus-del-mark -$BMxMQC$5$l$?5-;v(B (@code{gnus-canceled-mark})$B!#(B - -@item F -@vindex gnus-souped-mark -@sc{SOUP} $B$5$l$F$$$k5-;v(B (@code{gnus-souped-mark})$B!#(B @xref{SOUP}. - -@item Q -@vindex gnus-sparse-mark -$B$^$P$i$K;2>H$5$l$?5-;v(B (@code{gnus-sparse-mark})$B!#(B -@xref{Customizing Threading}. - -@item M -@vindex gnus-duplicate-mark -$B=EJ#M^@)$K$h$j4{FI$N0u$N$D$$$?5-;v(B (@code{gnus-duplicated-mark})$B!#(B -@xref{Duplicate Suppression}. - -@end table - -$B$3$l$i$N$9$Y$F$N0u$O!"K\Ev$O$?$@5-;v$,4{FI$H$7$F0u$,$D$$$F$$$k$3$H$r0UL#(B -$B$9$k$@$1$G$9!#E,1~%9%3%"%j%s%0$r$7$?$H$-$K$O0c$C$?$h$&$K2r$N0u(B -@cindex process mark -@cindex bookmarks - -$B5-;v$,FI$^$l$?$+$I$&$+$K$O4X78$7$J$$0u$,$$$/$D$+$"$j$^$9!#(B - -@itemize @bullet - -@item -$B8=:_$N5-;v$K$7$*$j$r64$`$3$H$,$G$-$^$9!#$"$J$?$OG-$NG"$N=,47$K4X$9$kD9$$(B -$BO@J8$rFI$s$G$$$F!"$=$l$rFI$_=*$o$kA0$KM$l$K$h$C$F0u$,$D$-$^$9!#(B - -@item -@vindex gnus-process-mark -$B:G8e$K(B @dfn{$B%W%m%;%90u(B} $B$,$"$j$^$9(B(@code{gnus-process-mark})$B!#$$$m$$$m$Jl9g!"$I$N$h$&$K$J$k$N$G$7$g$&!)(B - -$B$?$$$7$?$3$H$O$"$j$^$;$s!#M%@h=g0L$Ol9g!"%-%c%C%7%e0u$,$"$k$@$1$G!"JVEz:Q$_0u$O$"$j$^$;$s!#(B - - -@node Setting Marks -@subsection $B0u$rIU$1$k(B -@cindex setting marks - -$B$9$Y$F$N0u$D$1L?Na$O?tCM@\F,0z?t$rC5n$7$^$9(B -(@code{gnus-summary-clear-mark-forward})$B!#MW$9$k$K!"5-;v$KL$FI$N0u$rIU$1(B -$B$^$9!#(B - -@item M t -@itemx ! -@kindex ! $B!J35N,!K(B -@kindex M t $B!J35N,!K(B -@findex gnus-summary-tick-article-forward -$B8=:_$N5-;v$K2D;k5-;v0u$rIU$1$^$9(B -(@code{gnus-summary-tick-article-forward})$B!#(B @xref{Article Caching} - -@item M ? -@itemx ? -@kindex ? $B!J35N,!K(B -@kindex M ? $B!J35N,!K(B -@findex gnus-summary-mark-as-dormant -$B8=:_$N5-;v$KJ]N15-;v0u$rIU$1$^$9(B -(@code{gnus-summary-mark-as-read-forward})$B!#(B - -@item D -@kindex D $B!J35N,!K(B -@findex gnus-summary-mark-as-read-backward -$B8=:_$N5-;v$K4{FI$N0u$rIU$1!"A0$N9T$K%]%$%s%H$r0\F0$7$^$9(B -(@code{gnus-summary-mark-as-read-backward})$B!#(B - -@item M k -@itemx k -@kindex k $B!J35N,!K(B -@kindex M k $B!J35N,!K(B -@findex gnus-summary-kill-same-subject-and-select -$B8=:_$N5-;v$HF1$8I=Bj$r;}$D$9$Y$F$N5-;v$r4{FI$H$7$F0u$rIU$1!"C5n$7$^$9(B (@code{gnus-summary-clar-above})$B!#(B - -@item M V u -@kindex M V u $B!J35N,!K(B -@findex gnus-summary-tick-above -$B%G%#%U%)%k%H$N%9%3%"!J$b$7$/$O?tCM@\F,0z?t!K$h$j$bBg$-$$%9%3%"$r;}$D$9$Y$F(B -$B$N5-;v$K2D;k0u$rIU$1$^$9(B (@code{gnus-summary-tick-above})$B!#(B - -@item M V m -@kindex M V m $B!J35N,!K(B -@findex gnus-summary-mark-above -$B0u$NF~NO$rB%$7!"%G%#%U%)%k%H$N%9%3%"!J$b$7$/$O?tCM@\F,0z?t!K$h$j$bBg$-$J%9(B -$B%3%"$r;}$D$9$Y$F$N5-;v$K$=$N0u$rIU$1$^$9(B(@code{gnus-summary-mark-above})$B!#(B -@end table - -@vindex gnus-summary-goto-unread -$BJQ?t(B @code{gnus-summary-goto-unread} $B$O0u$,IU$1$i$l$?8e$K$I$N$h$&$JF0:n$,(B -$B$J$5$l$k$+$r7hDj$7$^$9!#$b$7(B @code{nil} $B$G$J$$$H!"%]%$%s%H$Oe$+2<$K9T$/$@$1$G(B -$B$9!#FCJL$J>l9g$H$7$F!"$3$NJQ?t$,(B @code{never} $B$G$"$k$H!"$9$Y$F$N0u$rIU$1$k(B -$BL?Na$H!J(B@kbd{SPACE} $B$N$h$&$J!KB>$NL?Na$Ol9g$O!"$=$N(B -$B5-;v$@$1$rL$A*Br$K$7$^$9!#$=$N9T$N%9%l%C%I$+5-;v$rL$A*Br$K$9$k$?$a$K$3$N(B -$B%-!<$K?tCM@\F,0z?t$rM?$($k;v$,$G$-$^$9!#(B - -@item M P u -@itemx M-# -@kindex M P u $B!J35N,!K(B -@kindex M-# $B!J35N,!K(B -$B$b$78=:_$N5-;v$K%W%m%;%90u$,$"$l$P/$7!J$b$7(B -$B$/$OB?$/!K$N5-;v$r35N,%P%C%U%!$+$i:o=|$9$k$3$H$G$9!#(B - -$B$9$Y$F$N@)8BL?Na$O%5!<%P!<$+$i4{$KC5n$5$l$?5-;v$rI=<($7$^$9(B -(@code{gnus-summary-limit-include-expunged})$B!#(B - -@item / D -@kindex / D $B!J35N,!K(B -@findex gnus-summary-limit-include-dormant -$B$9$Y$F$NJ]N15-;v$rI=<($7$^$9(B (@code{gnus-summary-limit-include-dormant})$B!#(B - -@item / * -@kindex / * $B!J35N,!K(B -@findex gnus-summary-limit-include-cached -$B$9$Y$F$N%-%c%C%7%e$KF~$C$F$$$k5-;v$rI=<($7$^$9(B -(@code{gnus-summary-limit-include-cached})$B!#(B - -@item / d -@kindex / d $B!J35N,!K(B -@findex gnus-summary-limit-exclude-dormant -$B$9$Y$F$NJ]N15-;v$r1#$7$^$9(B (@code{gnus-summary-limit-exclude-dormant})$B!#(B - -@item / T -@kindex / T $B!J35N,!K(B -@findex gnus-summary-limit-include-thread -$B8=:_$N%9%l%C%I$N$9$Y$F$N5-;v$rI=<($7$^$9(B -(@code{gnus-summary-limit-include-thread})$B!#(B - -@item / c -@kindex / c $B!J35N,!K(B -@findex gnus-summary-limit-exclude-childless-dormant -$B;R5-;v$NL5$$$9$Y$F$NJ]N15-;v$r1#$7$^$9(B -(@code{gnus-summary-limit-exclude-childless-dormant})$B!#(B - - -@item / C -@kindex / C $B!J35N,!K(B -@findex gnus-summary-limit-mark-excluded-as-read -$B$9$Y$F$NL$FI$N$_$N0u$N5-;v$r4{FI$H$7$F0u$rIU$1$^$9(B -(@code{gnus-summary-limit-mark-excluded-as-read})$B!#$b$7@\F,0z?t$,M?$($i(B -$B$l$l$P!"2D;k$HJ]N1$N$_$N0u$N5-;v$b4{FI$H$7$F0u$rIU$1$^$9!#(B - -@end table - - -@node Threading -@section $B%9%l%C%I(B -@cindex threading -@cindex article threading - -Gnus $B$O%G%#%U%)%k%H$G5-;v$r%9%l%C%I$K$7$^$9!#(B@dfn{$B%9%l%C%I$K$9$k(B} $B$H$O!"$"(B -$B$k5-;v$X$N1~Ez$r1~Ez$7$?5-;v$ND>8e$KCV$/!=!=3,AXE*N.57$G(B $B$H$$$&$3$H$G$9!#(B - -$B%9%l%C%I$O5-;v$N(B @code{References} $BMs$rD4$Y$k$3$H$K$h$C$F9T$o$l$^$9!#40A4(B -$B$J@$3&$G$O!"$3$l$@$1$GNI$$LZ$r:n$j>e$2$k$N$K==J,$J$N$G$9$,!"IT1?$J$3$H$K!"(B -@code{References} $BMs$O$7$P$7$P2u$l$F$$$k$+!";~$K$OC1$K$J$$$H$$$&$3$H$,$"$j(B -$B$^$9!#IT;W5D$J%K%e!<%9$NA}?#$,LdBj$rA}$d$7$^$9$N$G!"4n$P$7$$7k2L$rF@$k$?$a(B -$B$K$OB>$NH/8+K!$r:NMQ$7$J$1$l$P$J$j$^$;$s!#2a>j$JBP:vK!$OB8:_$7$F$$$F!"$=$N(B -$B62$k$Y$->\:Y$O(B @pxref{Customizing Threading} $B$K>\$7$/=q$$$F$"$j$^$9!#(B - -$B$^$:!"35G0$N354Q$G$9!'(B - -@table @dfn -@item $B:,K\(B (root) -$B%9%l%C%I$G0lHVD:E@$K$"$k5-;v$G$9!(%9%l%C%I$N:G=i$N5-;v$G$9!#(B - -@item $B%9%l%C%I(B (thread) -$BLZ$N$h$&$J5-;v$N9=@.$G$9!#(B - -@item $BItJ,%9%l%C%I(B (sub-thread) -$BLZ$N$h$&$J9=B$$N!J$h$j!K>.$5$JItJ,$G$9!#(B - -@item $BL5B+G{%9%l%C%I(B (loose threads) -$B5-;v$N4|8B@Z$l:o=|$d!":,K\$,4{$KA02s$N%;%C%7%g%s$GFI$^$l$?$3$H$K$h$j35N,%P%C(B -$B%U%!$KI=<($5$l$J$$!"Ey$NM}M3$K$h$j!"%9%l%C%I$O$7$P$7$P:,K\$r<:$$$^$9!#$=$N(B -$B$h$&$J$H$-$K$O!"IaDL$OB?$/$NItJ,%9%l%C%I$,$"$C$F!"K\Ev$O#1$D$N%9%l%C%I$KB0(B -$B$7$F$$$k$N$G$9$,!":,K\$K$O$D$J$,$C$F$$$J$$!"$H$$$&$3$H$K$J$j$^$9!#$3$&$$$&(B -$B%9%l%C%I$,L5B+G{%9%l%C%I$H8F$P$l$F$$$^$9!#(B - -@item $B%9%l%C%I=8$a(B (thread gathering) -$B$^$P$i%9%l%C%I$rBg$-$J%9%l%C%I$K=8$a$h$&$H$9$k;n$_$G$9!#(B - -@item $B$^$P$i%9%l%C%I(B (sparse threads) -$BL5$$5-;v$,!X?dB,$5$l$?!Y%9%l%C%I$G!"35N,%P%C%U%!$K6u9T$GI=<($5$l$^$9!#(B - -@end table - - -@menu -* Customizing Threading:: $BJQ992DG=$J%9%l%C%I$K1F6A$9$kJQ?t(B -* Thread Commands:: $B35N,%P%C%U%!$G$N%9%l%C%I$K4p$E$$$?L?Na(B -@end menu - - -@node Customizing Threading -@subsection $B%9%l%C%I$r%+%9%?%^%$%:$9$k(B -@cindex customizing threading - -@menu -* Loose Threads:: Gnus $B$,L5B+G{%9%l%C%I$r=8$a$FBg$-$J%9%l%C%I$K$9$kJ}K!(B -* Filling In Threads:: $B%9%l%C%I$rKd$a$k(B -* More Threading:: $B%9%l%C%I$r$$$8$/$k$5$i$KB?$/$NJQ?t(B -* Low-Level Threading:: $B$3$l$G=*$o$C$?$H;W$C$?$G$7$g$&(B... $B$G$b$"$J$?$O4V0c$C$F$$$?!*(B -@end menu - - -@node Loose Threads -@subsubsection $BL5B+G{%9%l%C%I(B -@cindex < -@cindex > -@cindex loose threads - -@table @code -@item gnus-summary-make-false-root -@vindex gnus-summary-make-false-root -$B$b$7(B @code{nil} $B$G$J$$$H!"(Bgnus $B$OA4$F$N$D$J$,$C$F$$$J$$ItJ,LZ$r#1$D$NBg$-(B -$B$JLZ$K$7$F!"D:>e$K$_$;$+$1$N:,K\$r:n$j$^$9!#!J$A$g$C$HBT$C$F$/$@$5$$!#D:(B -$B>e$K:,85(B (root) $B$G$9$C$F!)$($(!"$=$&$J$N$G$9!#!K$D$J$,$C$F$$$J$$ItJ,LZ$OK\(B -$BEv$N:,K\$,4|8B@Z$l:o=|$5$l$?$+!"A02s$N%;%C%7%g%s$G:,K\$rFI$s$@$j:o=|$7(B -$B$?$H$-$K$G$-$^$9!#(B - -$BK\Ev$N%9%l%C%I$,L5$$$H$-$O!"(Bgnus $B$O2?$+$G$C$A>e$2$r$9$kI,MW$,$"$j$^$9!#$3(B -$B$NJQ?t$O(B gnus $B$,;H$&$Y$-$4$^$+$7$NJ}K!$r<($7$F$$$^$9!#CM$H$7$F$H$k$3$H$,$G(B -$B$-$k#4$D$N8uJd$,$"$j$^$9!#(B - -@iftex -@iflatex -\gnusfigure{The Summary Buffer}{390}{ -\put(0,0){\epsfig{figure=tmp/summary-adopt.ps,width=7.5cm}} -\put(445,0){\makebox(0,0)[br]{\epsfig{figure=tmp/summary-empty.ps,width=7.5cm}}} -\put(0,400){\makebox(0,0)[tl]{\epsfig{figure=tmp/summary-none.ps,width=7.5cm}}} -\put(445,400){\makebox(0,0)[tr]{\epsfig{figure=tmp/summary-dummy.ps,width=7.5cm}}} -} -@end iflatex -@end iftex - -@cindex adopting articles - -@table @code - -@item $BM\;R(B (adopt) -Gnus $B$O:G=i$N8I;y$r?F$K$7$^$9!#$3$N?F$O$9$Y$F$NB>$N5-;v$rM\;R$K$7$^$9!#(B -$B$3$NM\;R5-;v$O!"I8=`$N3Q3g8L(B (@samp{[]}) $B$NBe$o$j$K!"@h$N@m$C$?3g8L(B -(@samp{<>}) $B$G0uIU$1$i$l$^$9!#$3$l$,%G%#%U%)%k%H$NJ}K!$G$9!#(B - -@item $B$_$;$+$1(B (dummy) -@vindex gnus-summary-dummy-line-format -Gnus $B$O?F$N$U$j$r$9$k$_$;$+$1$N35N,9T$r$D$/$j$^$9!#$_$;$+$1$N9T$O$I$NK\(B -$BEv$N5-;v$K$bBP1~$7$^$;$s$N$G!"$=$l$rA*Br$9$k$3$H$O!"$_$;$+$1$N5-;v$N8e$N(B -$B:G=i$NK\Ev$N5-;v$rA*Br$r$9$k$@$1$K$J$j$^$9!#$_$;$+$1$N:,K\$NMM<0$r;XDj(B -$B$9$k$?$a$K!"(B @code{gnus-summary-dummy-line-format} $B$,;H$o$l$^$9!#$3$l$O(B -$B$?$C$?0l$D$@$1$N%U%)!<%^%C%H$N;EMM$r$N5-;v$r(B -$BI=<($9$k$@$1$G$9!#(B - -@item nil -$BL5B+G{%9%l%C%I$r=8$a$^$;$s!#(B -@end table - -@item gnus-summary-gather-subject-limit -@vindex gnus-summary-gather-subject-limit -$BL5B+G{%9%l%C%I$O5-;v$NI=Bj$rHf3S$9$k$3$H$K$h$C$F=8$a$i$l$^$9!#$b$7$3$NJQ?t(B -$B$,(B @code{nil} $B$G$"$k$H!"(Bgnus $B$OL5B+G{%9%l%C%I$r0l$D$NBg$-$JD6%9%l%C%I$K=8(B -$B$a$kA0$K!"L5B+G{%9%l%C%I$NI=Bj$,40A4$K0lCW$9$k$3$H$rMW5a$7$^$9!#$3$l$O!"D9(B -$B$$I=Bj$N9T$r@Z$jMn$H$7$F$7$^$&4VH4$1$J%K%e!<%9%j!<%@!<$,B8:_$9$k8=:_$G$O!"(B -$B$"$^$j$K87$7$$MW5a$+$bCN$l$^$;$s!#$b$7$=$&;W$&$N$J$i!"$3$NJQ?t$rNc$($P(B -20 $B$K@_Dj$7$F!"I=Bj$N:G=i$N(B 20 $BJ8;z$@$1$,0lCW$9$k$3$H$rMW5a$9$k$h$&$K$9$k(B -$B$3$H$,$G$-$^$9!#$3$NJQ?t$rK\Ev$KDc$$?t;z$K@_Dj$9$k$H!"(Bgnus $B$,L\$KF~$kA4$F(B -$B$r0l$D$N%9%l%C%I$K=8$a$k$N$r8+$k$3$H$,$G$-$k$G$7$g$&!#$=$7$F!"$=$l$O$"$^$j(B -$BM-MQ$G$O$"$j$^$;$s!#(B - -@cindex fuzzy article gathering -$B$3$NJQ?t$rFCJL$JCM(B @code{fuzzy} $B$K@_Dj$9$l$P!"(Bgnus $B$OI=Bj$K$"$$$^$$$JJ8(B -$B;zNsHf3S%"%k%4%j%:%`$r;H$$$^$9(B (@pxref{Fuzzy Matching})$B!#(B - -@item gnus-sumplify-subject-fuzzy-regexp -@vindex gnus-simplify-subject-fuzzy-regexp -$B$3$l$O@55,I=8=$+!"$"$$$^$$I=Bj;XDj$,;H$o$l$F$$$k$H$-$KI=Bj$+$i9gCW$7$?$b(B -$B$N$, -@lisp -(setq gnus-simplify-ignored-prefixes - (concat - "\\`\\[?\\(" - (mapconcat - 'identity - '("looking" - "wanted" "followup" "summary\\( of\\)?" - "help" "query" "problem" "question" - "answer" "reference" "announce" - "How can I" "How to" "Comparison of" - ;; ... - ) - "\\|") - "\\)\\s *\\(" - (mapconcat 'identity - '("for" "for reference" "with" "about") - "\\|") - "\\)?\\]?:?[ \t]*")) -@end lisp - -$B$3$N@55,I=8=$K9gCW$9$k$9$Y$F$N8l$O!"#2$D$NI=Bj$rHf3S$9$kA0$Ke=q$-$7$^$9!#$3$NJQ?t$OJ8;zNs(B @code{Subject} $B$rH?I|$7$F4JC1$J7A$K$?$I(B -$B$jCe$/$?$a$KE,MQ$9$k4X?t$N%j%9%H$G$"$kI,MW$,$"$j$^$9!#(B - -$B$3$N%j%9%H$KF~$l$FLr$KN)$D$h$&$J4X?t$OJ,$J6uGr(B (whitespace) $B$ru67$r>/$7$h$/$9$k$?$a$K!"$I$NI=Bj$,=8$a$k2aDx$+$i=|$+$l$k(B -$B$+$r7h$a$k@55,I=8=(B @code{gnus-summary-gather-exclude-subject} $B$r;H$&$3$H(B -$B$,$G$-$^$9!#%G%#%U%)%k%H$O(B @samp{^ *$\\|^(none)$} $B$G$9!#(B - -@item gnus-summary-thread-gathering-function -@vindex gnus-summmary-thread-gathering-function -Gnus $B$O(B @code{Subject} $BMs$r8+$k$3$H$K$h$C$F%9%l%C%I$r=8$a$^$9!#$3$l$O!"7k(B -$B2LE*$KA4$/4X78$NL5$$5-;v$,F1$8!X%9%l%C%I!Y$K4^$^$l$k$3$H$,$"$k$H$$$&$3$H$G!"(B -$B$3$l$O:.Mp$N85$G$9!#BeBXZ$7$^$9(B -$B$,!"$3$o$l$?%K%e!<%9%j!<%@!<$GEj9F$7$?5-;v$OE,@Z$K=8$a$i$l$J$$$H$$$&$3$H$G(B -$B$b$"$j$^$9!#A*Br8"$O$"$J$?$K$"$j$^$9!=!=1VIB$+%3%l%i$+!#(B - -@table @code -@item gnus-gather-threads-by-subject -@findex gnus-gather-threads-by-subject -$B$3$N4X?t$O%G%#%U%)%k%H$N<}=84X?t$G!"GSB>E*$K(B @code{Subject} $B$r8+$^$9!#(B - -@item gnus-gather-threads-by-references -$B$3$N4X?t$OGSB>E*$K(B @code{References} $BMs$r8+$^$9!#(B -@end table - -@code{References} $B$K$h$C$F=8$a$k$3$H$r;n$7$F$_$?$$$N$G$"$l$P!"/$J$$35N,9T$rI=<($7$?$$$1$l$I!"$G$-$k$@$1$?$/$5$s$NHsL)%9%l%C%I$K(B -$B@\B3$7$F$*$-$?$$$H$-$O!"$3$NJQ?t$r(B @code{some} $B$+?t;z$K@_Dj$9$k$3$H$,$G$-(B -$B$^$9!#$b$7?t;z$K@_Dj$7$?$H$-$O!"$=$l$h$jB?$$DI2C$N%X%C%@!<$Ol9g$G$b!"8E$$%X%C%@!<$N/$7B.$/$J$j$^$9$,!"5-;v$rFI$`$N$,$b$C$HCY$/!"ITJX$K$J$k$3$H$O3N/$J$$Am9gE*%9%3%"(B (@code{gnus-thread-score-function}) $B$r;}(B -$B$D$9$Y$F$N%9%l%C%I$O>C5n$5$l$^$9!#$3$NJQ?t$O%G%#%U%)%k%H$G$O(B @code{nil} -$B$G!"$3$l$O$I$N%9%l%C%I$b>C5n$5$l$J$$$H$$$&$3$H$G$9!#(B - -@item gnus-thread-hide-killed -@vindex gnus-thread-hide-killed -$B$b$7%9%l%C%I$r:o=|$7$F!"$3$NJQ?t$,(B @code{nil} $B$G$J$$$H!"ItJ,LZ$O1#$5$l$^$9!#(B - -@item gnus-thread-ignore-subject -@vindex gnus-thread-ignore-subject -$B;~!9!"C/$+$,%9%l%C%I$N??Cf$GI=Bj$rJQ99$9$k$3$H$,$"$j$^$9!#$b$7$3$NJQ?t$,(B -@code{nil} $B$G$J$$$H!"I=Bj$NJQ99$OL5;k$5$l$^$9!#$b$7(B @code{nil} $B$@$H!"$3(B -$B$l$,%G%#%U%)%k%H$G$9$,!"I=Bj$NJQ99$r$9$k$HJL$N%9%l%C%I$K$J$j$^$9!#(B - -@item gnus-thread-indent-level -@vindex gnus-thread-indent-level -$B$3$N?t;z$OItJ,%9%l%C%I$,$I$l$/$i$$;z2<$2(B (indent) $B$5$l$k$Y$-$+$r7h$a$^$9!#(B -$B%G%#%U%)%k%H$O(B 4 $B$G$9!#(B - -@end table - - -@node Low-Level Threading -@subsubsection $BDc%l%Y%k$K$*$1$k%9%l%C%I:n@.(B - -@table @code - -@item gnus-parse-headers-hook -@vindex gnus-parse-headers-hook -$B$9$Y$F$N%X%C%@!<$r2r@O$9$kA0$K$N$b$N$rIU$12C$($k$3(B -$B$H$K$h$k!KBN7OE*$JJ}K!$G(B @code{Message-ID} $B$r8r49$9$k%a!<%k$+$i%K%e!<%9$X(B -$B$N%2!<%H%&%'%$$,$"$k>l9g!"(B@code{Message-ID} $B$,$b$C$H0UL#$N$"$k$b$N$K$9$k$?(B -$B$a$K!"$3$NJQ?t$r@_Dj$7$F85$KLa$9$3$H$,$G$-$^$9!#$3$l$O0l$D$NNc$G$9!'(B - -@lisp -(setq gnus-alter-header-function 'my-alter-message-id) - -(defun my-alter-message-id (header) - (let ((id (mail-header-id header))) - (when (string-match - "\\(<[^<>@@]*\\)\\.?cygnus\\..*@@\\([^<>@@]*>\\)" id) - (mail-header-set-id - (concat (match-string 1 id) "@@" (match-string 2 id)) - header)))) -@end lisp - -@end table - - -@node Thread Commands -@subsection $B%9%l%C%I$NL?Na(B -@cindex thread commands - -@table @kbd - -@item T k -@itemx M-C-k -@kindex T k $B!J35N,!K(B -@kindex M-C-k $B!J35N,!K(B -@findex gnus-summary-kill-thread -$B8=:_$N!JItJ,!K%9%l%C%I$K4{FI$N0u$rIU$1$^$9(B -(@code{gnus-summary-kill-thread})$B!#$b$7@\F,0z?t$,@5$G$"$k$H!"Be$o$j$K$9$Y(B -$B$F$N0u$re$2$^$9(B -(@code{gnus-summary-raise-thread})$B!#(B - -@item T # -@kindex T # $B!J35N,!K(B -@findex gnus-uu-mark-thread -$B%W%m%;%90u$r8=:_$N!JItJ,!K%9%l%C%I$KIU$1$^$9(B -(@code{gnus-uu-mark-thread})$B!#(B - -@item T M-# -@kindex T M-# $B!J35N,!K(B -@findex gnus-uu-unmark-thread -$B8=:_$N!JItJ,!K%9%l%C%I$+$i%W%m%;%90u$r$7$^$9(B -(@code{gnus-summary-rethread-current})$B!#$3$l$O35N,%P%C%U%!$,%9%l%C%II=<($5(B -$B$l$F$$$J$$$H$-$G$bF0:n$7$^$9!#(B - -@item T ^ -@kindex T ^ $B!J35N,!K(B -@findex gnus-summary-reparent-thread -$B8=:_$N5-;v$r0uIU$-!J$b$7$/$OA0$N!K5-;v$N;R5-;v$K$7$^$9(B -(@code{gnus-summary-reparent-thread})$B!#(B - -@end table - -$B0J2<$NL?Na$O%9%l%C%I0\F0L?Na$G$9!#$3$l$i$O$9$Y$F?tCM@\F,0z?t$re>:$7$^$9(B (@code{gnus-summary-up-thread})$B!#(B - -@item T o -@kindex T o $B!J35N,!K(B -@findex gnus-summary-top-thread -$B%9%l%C%I$ND:>e$K0\F0$7$^$9(B (@code{gnus-summary-top-thread})$B!#(B -@end table - -@vindex gnus-thread-operation-ignore-subject -$B%9%l%C%I$r:n@.$9$k$H$-$KI=Bj$rL5;k$9$k$H!"<+A3$K%9%l%C%I$K$O$$$/$D$+$N0c$C(B -$B$?I=Bj$,$"$k$3$H$K$J$j$^$9!#$=$l$+$i(B `T k' -(@code{gnus-summary-kill-thread}) $B$N$h$&$JL?Na$rH/$9$k$H$-$K!"A4BN$N%9%l%C(B -$B%I$r:o=|$9$k$N$G$O$J$/!"8=:_$N5-;v$HF1$8I=Bj$r;}$DItJ,$@$1$r:o=|$7$?$$$H$-(B -$B$,$"$k$+$b$7$l$^$;$s!#$b$7$3$NH/A[$,NI$$$H;W$&$N$G$"$l$P!"(B -@code{gnus-thread-operation-ignore-subject} $B$r$$$8$/$k$3$H$,$G$-$^$9!#$3$l(B -$B$,(B @code{nil} $B$G$J$$$H!J$3$l$,%G%#%U%)%k%H$G$9$,!K!"%9%l%C%I$NL?Na$r$N%9%l%C%I$h$j@h$KJB$SBX$((B -$B$i$l$k$Y$-$G$"$l$P!"(B@code{nil} $B$G$J$$CM$r$+$($7$^$9!#IaDL!"JB$SBX$($OK\Ev(B -$B$O$=$l$>$l$N%9%l%C%I$N:,K\$r8+$k$@$1$K$h$j$J$5$l$k$3$H$K5$$rIU$1$F$/$@$5$$!#(B -$B$b$7#2$D0J>e$N4X?t$r;H$&>l9g!"M%@hE*JB$SBX$(%-!<$O%j%9%H$N:G8e$N4X?t$G$9!#(B -$B$*$=$i$/$$$D$b(B @code{gnus-thread-sort-by-number} $B$rJB$SBX$(4X?t$N%j%9%H!=!=(B -$B:G=i$,9%$^$7$$(B $B$KF~$l$F$*$/$Y$-$G$7$g$&!#$3$l$OB>$NJB$SBX$(4p=`$K4X$7$FEy(B -$B$7$$%9%l%C%I$O5-;v$,>e$,$C$F$$$/=gHV$KI=<($5$l$k$3$H$rJ]>Z$7$^$9!#(B - -$B%9%3%"!"I=Bj!"$=$7$F:G8e$KHV9f!"$N=g$KJB$SBX$($?$$$N$G$"$l$P!"l9g$O!"1Q;z=g$KJB$S$+$($i$l$^$9!#%9%3%"$HI=Bj$,F1$8%9%l%C%I$OHV9f(B -$B$GJB$SBX$($i$l!"!JIaDL$O!K5-;v$,E~Ce$7$?=gHV$K$J$j$^$9!#(B - -$B%9%3%"!"E~Ce$N5U=g$KJB$SBX$($?$$$N$G$"$l$P!"h!"$b$7$/$O$"$J$?$N9%4q?4$r$/$9$0$k(B -$B$h$&$J2?$+$G$7$g$&!#(B - -@findex gnus-article-sort-functions -@findex gnus-article-sort-by-date -@findex gnus-article-sort-by-score -@findex gnus-article-sort-by-subject -@findex gnus-article-sort-by-author -@findex gnus-article-sort-by-number -$B2?$+4qL/$JM}M3$J$I$G%9%l%C%II=<($r;H$C$F$$$J$$$N$J$i!"JQ?t(B -@code{gnus-article-sort-functions} $B$r$$$8$/$kI,MW$,$"$j$^$9!#$3$l$O(B -@code{gnus-thread-sort-functions} $B$HHs>o$K;w$F$$$^$9$,!"5-;v$NHf3S$K$O>/!9(B -$B0c$C$?4X?t$r;H$$$^$9!#;HMQ2DG=$JJB$SBX$(=R8l4X?t$O(B -@code{gnus-article-sort-by-number}, @code{gnus-article-sort-by-author}, -@code{gnus-article-sort-by-subject}, @code{gnus-article-sort-by-date} $B$*$h(B -$B$S(B @code{gnus-article-sort-by-score} $B$G$9!#(B - -$B%9%l%C%I$r;H$C$F$$$J$$I=Bj$N35N,I=<($rJB$SBX$($?$$$N$G$"$l$P!"u67$rHr$1$k$?$a$K!"(Bgnus $B$O%5!<%P!<$K#2$D$N!J$=$l$O#2$H?t$($F$/$@$5$$!K(B -$B@\B3$rD%$k$3$H$,$G$-$^$9!#$3$l$O$"$^$j$7$FNI$$$3$H$G$O$J$$$H9M$($k?M$b$$$k(B -$B$G$7$g$&$,!";d$K$OJ,$J@\B3$r$9$k$?$a(B -$B$K$O2?$i$+$N;~4V$,$+$+$j$^$9$N$G!"(Bgnus $B$N5/F0$OCY$/$J$j$^$9!#(B - -Gnus $B$O$"$J$?$,FI$`$G$"$m$&5-;v$h$j$b$?$/$5$s$N5-;v$rJ,$J5-;v$NMW5a$H!"M>J,$J@\B3$G!#(B - -$B$O$$!"$3$l$GK\Ev$O$3$N$h$&$J$3$H$r$9$Y$-$GL5$$;v$,J,$+$C$?$G$7$g$&(B... $BK\(B -$BEv$K$=$&$7$?$$$H;W$o$J$$8B$j$O!#(B - -@vindex gnus-asynchronous -$B$3$l$,J}K!$G$9!'(B @code{gnus-asynchronous} $B$r(B @code{t} $B$K@_Dj$7$F$/$@$5$$!#(B -$B;D$j$N$3$H$O<+F0E*$K5/$3$j$^$9!#(B - -@vindex gnus-use-article-prefetch -@code{gnus-use-article-prefetch} $B$r@_Dj$9$k$3$H$K$h$j!"$I$l$/$i$$$N5-;v$,(B -$B@h$Ko$K(B}$BCY$$(B @sc{nntp} $B@\B3$G$"$k$J$i$P!"5-;v%-%c%C%7%e$r$9$k$3$H(B -$B$r9M$($k$+$b$7$l$^$;$s!#$=$&$9$k$H!"$=$l$>$l$N5-;v$O$"$J$?$N%[!<%`%G%#%l%/(B -$B%H%j$N2<$K%m!<%+%k$KN/$a$i$^$9!#4{$K?dB,$5$l$F$$$k$+$bCN$l$^$;$s$,!"$3$l$O(B -@emph{$B5pBg$J(B}$B%G%#%9%/%9%Z!<%9$r?)$$!"(Bi$B%N!<%I$bHs>o$KB.$/?)$$$D$V$92DG=@-$,(B -$B$"$k$?$a!"$=$l$O$"$J$?$NF,$r1K$,$;$k;v$K$J$k$+$b$7$l$^$;$s!#%&%)%C%+$NCf$G!#(B - -$B$G$bCm0U?<$/;H$o$l$l$P!"$=$l$O5-;v$rJ]B8$9$k4JC1$JJ}K!$K$J$jF@$^$9!#(B - -@vindex gnus-use-long-file-name -@vindex gnus-cache-directory -@vindex gnus-use-cache -$B%-%c%C%7%e$rl9g$O!"%5!<%P!<$NBe$o$j$K%-%c%C%7%e$+$iJ}$H$b%7(B -$B%s%\%k$N%j%9%H$G$9!#A0/$J$/$9$k0l$D$NJ}(B -$BK!$O!"M_$7$/$J$$5-;v$N%9%3%"$rDc$/$7!"4{FI$N0u$rIU$1$k;v$G$9!#$=$&$7$?>l9g!"(B -$B$=$l$i$O$3$NL?Na$G$O%@%&%s%m!<%I$5$l$^$;$s!#(B - -@vindex gnus-uncacheable-groups -@vindex gnus-cacheable-groups -$B$$$/$D$+$N%0%k!<%W$G$O%-%c%C%7%e$r$7$?$/$J$$$H$$$&$N$ONI$/$"$k;v$G$9!#Nc$((B -$B$P!"(B@code{nnml} $B%a!<%k%G%#%l%/%H%j!<$,%[!<%`%G%#%l%/%H%j!<$N2<$K$"$l$P!"$=(B -$B$l$r$"$J$?$N%[!<%`%G%#%l%/%H%j!<$N2<$NJL$N>l=j$K%-%c%C%7%e$9$k$N$O0UL#$NL5(B -$B$$;v$G$9!#$"$J$?$,#2G\$NMFNL$r;H$&;v$,NI$$$H46$8$J$$8B$j$O!#(B - -$B%-%c%C%7%e$r@)8B$9$k$?$a$K!"(B@code{gnus-uncacheable-groups} $B$r(B $B$r%-%c%C%7%e(B -$B$9$k%0%k!<%W$NO"A[%j%9%H!"Nc$($P(B @samp{^nntp}$B!"$H$9$k$+!"@55,I=8=(B -@code{gnus-uncacheable-group} $B$rNc$($P!"(B@samp{^nnml} $B$K@_Dj$7$F2<$5$$!#(B -$BN>J}$NJQ?t$N=i4|CM$O(B @code{nil} $B$G$9!#$b$7%0%k!<%W$,N>J}$N@55,I=8=$K9gCW(B -$B$9$k$H!"$=$N%0%k!<%W$O%-%c%C%7%e$5$l$^$;$s!#(B - -@findex gnus-cache-generate-nov-databases -@findex gnus-cache-generate-active -@vindex gnus-cache-active-file -$B%-%c%C%7%e$O$I$N5-;v$,4^$^$l$F$$$k$+$N>pJs$r8=>u%U%!%$%k(B (active file) -(@code{gnus-cache-active-file}) $B$KN/$a$^$9!#$3$N%U%!%$%k!J$b$7$/$O%-%c%C%7%e(B -$B$NB>$NItJ,!K$,2?$i$+$NM}M3$G$0$A$c$0$A$c$K$J$C$F$7$^$C$?>l9g!"(Bgnus $B$OJ*;v(B -$B$r@5$7$/$9$k$?$a$K#2$D$N4X?t$r$*4+$a$7$^$9!#(B@kbd{M-x -gnus-cache-generate-nov-databases} $B$O$9$Y$F$N(B @sc{nov} $B%U%!%$%k$r!J:F!K:n(B -$B@.$7!"(B@kbd{gnus-cache-generate-active} $B$O(B $B8=>u%U%!%$%k$r!J:F!K:n@.$7$^$9!#(B - - -@node Persistent Articles -@section $B1JB35-;v(B -@cindex persistent articles -$B5-;v$N%-%c%C%7%e$H6a$$4X78$K$"$k$b$K!"(B@dfn{$B1JB35-;v(B}$B$,$"$j$^$9!#l=j$K1J1s$K;D$C$F$$$k$Y$-$G$7$g(B -$B$&!#%K%e!<%9%5!<%P!<$K$*$1$k4|8B:o=|$K$O1F6A$5$l$J$$$G!#(B - -$B$3$l$,(B@dfn{$B1JB35-;v(B}$B$G$9!=!=5-;v$O:o=|$5$l$^$;$s!#$=$l$OIaDL$N%-%c%C%7%eL?(B -$BNa$r;H$C$FJ}$H$b%W%m%;%9(B/$B@\F,0z?t$N=,47$rM}2r$7$^$9!#(B - -$B$b$71JB35-;v$K$@$16=L#$,$"$k$N$G$7$?$i!"2D;k5-;v!J$d$=$NB>$N$b$N!K$,%-%c%C(B -$B%7%e$KF~$k$N$rHr$1$k$?$a$K!"(B@code{gnus-use-cache} $B$r(B @code{passive} $B$K@_Dj(B -$B$9$k$N$,NI$$$G$7$g$&!'(B - -@lisp -(setq gnus-use-cache 'passive) -@end lisp - - -@node Article Backlog -@section $B5-;v$N%P%C%/%m%0(B -@cindex backlog -@cindex article backlog -$B$b$7CY$$@\B3$7$+$J$$>l9g$G!"%-%c%C%7%e$r;H$&$H$$$&H/A[$O$"$^$jL%NOE*$G$O$J(B -$B$$$H$-!Ju67$r(B -$B2?$H$+$9$k$3$H$,$G$-$^$9!#$3$l$O4{$KFI$s$@5-;v$r:F/$7CY$/$7!"%a%b%j!<$N;H(B -$BMQNL$r$$$/$i$+A}$d$7$^$9!#(B - -@vindex gnus-keep-backlog -$B$b$7(B @code{gnus-keep-backlog} $B$r?t;z(B @var{n} $B$K@_Dj$9$k$H!"(Bgnus $B$O:GBg$G(B -@var{n} $B$N8E$$5-;v$r8e$N:Fl9g!"(Bgnus $B$O(B@emph{$BA4$F(B}$B$N4{FI5-;v$r$?$/(B -$B$o$($^$9!#$3$l$O$"$J$?$N(B Emacs $B$,!"K=H/$7$F$"$J$?$N%^%7%s$,Mn$A$k$^$G@)8B(B -$B$J$/KD$l>e$,$k$H$$$&$3$H$G$9!#;d$O$"$J$?J}A4$F$,855$$G$$$i$l$k$h$&$K$3$3$K(B -$B=q$-2C$($^$7$?!#(B - -$B$3$NJQ?t$O%G%#%U%)%k%H$G$O(B @code{nil} $B$G$9!#(B - - -@node Saving Articles -@section $B5-;v$NJ]B8(B -@cindex saving articles - -Gnus $B$O$?$/$5$s$NJ}K!$G5-;v$rJ]B8$9$k;v$,$G$-$^$9!#0J2<$N$b$N$OHs>o$KN(D>(B -$B$JJ}K!!JNc$($P!"5-;v$,J]B8$9$kA0$K$[$H$s$I2?$b$J$5$l$J$$!K$G5-;v$rJ]B8$9$k(B -$B$?$a$N@bL@$G$9!#0c$C$?$^$7$/$J$$%X%C%@!<$r>C5n$7$^$;$s!#(B - -@vindex gnus-saved-headers -$B$b$7>e$NJQ?t$,(B @code{nil} $B$G$"$k$H!"@55,I=8=(B @code{gnus-saved-headers} -$B$K9gCW$9$k$9$Y$F$N%X%C%@!<$O;D$5$l!";D$j$N$b$N$OJ]B8$9$kA0$K:o=|$5$l$^$9!#(B - -@table @kbd - -@item O o -@itemx o -@kindex O o $B!J35N,!K(B -@kindex o $B!J35N,!K(B -@findex gnus-summary-save-article -@c @icon{gnus-summary-save-article} -$B%G%#%U%)%k%H$N5-;vJ]B8$rMQ$$$F8=:_$N5-;v$rJ]B8$7$^$9(B -(@code{gnus-summary-save-article})$B!#(B - -@item O m -@kindex O m $B!J35N,!K(B -@findex gnus-summary-save-article-mail -$B8=:_$N5-;v$r%a!<%k$NMM<0$GJ]B8$7$^$9(B -(@code{gnus-summary-save-article-mail})$B!#(B - -@item O r -@kindex O r $B!J35N,!K(B -@findex gnus-summary-save-article-rmail -$B8=:_$N5-;v$r(B rmail $B$NMM<0$GJ]B8$7$^$9(B -(@code{gnus-summary-save-article-rmail})$B!#(B - -@item O f -@kindex O f $B!J35N,!K(B -@findex gnus-summary-save-article-file -@c @icon{gnus-summary-save-article-file} -$B8=:_$N5-;v$rIaDL$N%U%!%$%k(B (plain file) $BMM<0$GJ]B8$7$^$9(B -(@code{gnus-summary-save-article-file})$B!#(B - -@item O F -@kindex O F $B!J35N,!K(B -@findex gnus-summary-write-article-file -$B8=:_$N5-;v$rIaDL$N%U%!%$%kMM<0$GJ]B8$7!"0JA0$N%U%!%$%k$NFbMF$r>e=q$-$7$^(B -$B$9(B (@code{gnus-summary-write-article-file})$B!#(B - -@item O b -@kindex O b $B!J35N,!K(B -@findex gnus-summary-save-article-body-file -$B8=:_$N5-;v$NK\J8(B (body) $B$rIaDL$N%U%!%$%kMM<0$GJ]B8$7$^$9(B -(@code{gnus-summary-save-article-body-file})$B!#(B - -@item O h -@kindex O h $B!J35N,!K(B -@findex gnus-summary-save-article-folder -$B8=:_$N5-;v$r(B mh $B$N%U%)%k%@!<$NMM<0$GJ]B8$7$^$9(B -(@code{gnus-summary-save-article-folder})$B!#(B - -@item O v -@kindex O v $B!J35N,!K(B -@findex gnus-summary-save-article-vm -$B8=:_$N5-;v$r(B VM $B%U%)%k%@!<$KJ]B8$7$^$9(B -(@code{gnus-summary-save-article-vm})$B!#(B - -@item O p -@kindex O p $B!J35N,!K(B -@findex gnus-summary-pipe-output -$B8=:_$N5-;v$r%Q%$%W$KJ]B8$7$^$9!#$&!<$s$H!"$"$N$)!";d$,8@$*$&$H$7$F$$$k;v$O!=!=(B -$B8=:_$N5-;v$r%W%m%;%9$K%Q%$%W$9$k$H$$$&$3$H$G$9(B -(@code{gnus-summary-pipe-output})$B!#(B -@end table - -@vindex gnus-prompt-before-saving -$B$9$Y$F$N$3$l$i$NL?Na$O%W%m%;%9(B/$B@\F,0z?t$N=,47$r;H$$$^$9(B -(@pxref{Process/Prefix})$B!#$b$7$3$l$i$N4X?t$r;H$C$F$?$/$5$s$N5-;v$rJ]B8$7(B -$B$?>l9g!"$=$l$>$l$N$9$Y$F$N5-;v$KBP$7$F%U%!%$%kL>$NF~NO$rMW5a$5$l$k;v$KK0(B -$B$-K0$-$9$k$G$7$g$&!#F~NOB%?JF0:n$OJQ?t(B @code{gnus-prompt-before-saving} -$B$K$h$C$F@)8f$5$l$^$9!#$3$l$O%G%#%U%)%k%H$G$O(B @code{always} $B$G!"$"$J$?$,(B -$BCN$C$F$$$F7y$,$C$F$$$k!"2a>j$JB%?JF0:n$r$7$^$9!#Be$o$j$K$3$NJQ?t$r(B -@code{t} $B$K@_Dj$9$k$H!"$"$J$?$,J]B8$9$k$=$l$>$l$N0lO"$N5-;v$KBP$7$F0l2s(B -$B$@$1B%$5$l$^$9!#K\Ev$K(B gnus $B$K$9$Y$F$N;W9M$r$5$;$?$$$N$G$"$l$P!"$3$NJQ?t(B -$B$r(B@code{nil} $B$K$9$k$3$H$5$($G$-$^$9!#$=$7$F!"5-;v$rJ]B8$9$k$?$a$N%U%!%$(B -$B%k$rB%$5$l$k;v$O$"$j$^$;$s!#(BGnus $B$OC1=c$K$9$Y$F$N5-;v$r%G%#%U%)%k%H$N%U%!(B -$B%$%k$KJ]B8$7$^$9!#(B - - -@vindex gnus-default-article-saver -Gnus $B$,$"$J$?$NK>$`$H$*$j$K$J$k$h$&$K!"JQ?t(B -@code{gnus-default-article-saver} $B$r%+%9%?%^%$%:$9$k;v$,$G$-$^$9!#2<$N#4$D(B -$B$N4{@=4X?t$r;H$&;v$,$G$-$^$9$7!"<+J,<+?H$N4X?t$r:n$k;v$b$G$-$^$9!#(B - -@table @code - -@item gnus-summary-save-in-rmail -@findex gnus-summary-save-in-rmail -@vindex gnus-rmail-save-name -@findex gnus-plain-save-name -$B$3$l$O%G%#%U%)%k%H$NMM<0!"(B@dfn{babyl} $B$G$9!#JQ?t(B -@code{gnus-ramil-save-name} $B$KF~$C$F$$$k4X?t$r!"5-;v$rJ]B8$9$k$?$a$N%U%!(B -$B%$%kL>$r$ro$N%U%!%$%k$N8e$KDI2C$7$^$9!#JQ?t(B @code{gnus-file-save-name} $B$K(B -$BF~$C$F$$$k4X?t$r!"5-;v$rJ]B8$9$k$?$a$N%U%!%$%kL>$ro$N%U%!%$%k$N8e$KDI2C$7$^$9!#JQ?t(B -@code{gnus-file-save-name} $B$KF~$C$F$$$k4X?t$r!"5-;v$rJ]B8$9$k$?$a$N%U%!(B -$B%$%kL>$r$r.J8;z$K$J$C$?L>A0$r$D$/$j$^$9!#(B - -@item gnus-summary-save-in-vm -@findex gnus-summary-save-in-vm -$B5-;v$r(B VM $B%U%)%k%@!<$KJ]B8$7$^$9!#$3$N@_Dj$r;H$&$?$a$K$O(B VM $B%a!<%k%j!<%@!<(B -$B$,I,MW$G$9!#(B -@end table - -@vindex gnus-article-save-directory -$B$3$l$i$NA4$F$N4X?t$O:G8e$N0l$D$r=|$$$F!"4D6-JQ?t(B @code{SAVEDIR} $B$K$h$C$F(B -$B=i4|2=$5$l$k(B @code{gnus-article-save-directory} $B$K5-;v$rJ]B8$7$^$9!#$3$l(B -$B$O%G%#%U%)%k%H$G$O(B @file{~/News/} $B$G$9!#(B - -$B>e$K$"$k$h$&$K!"5-;v$rJ]B8$9$k$?$a$N%U%!%$%k$NE,@Z$JL>A0$r8+$D$1$k$?$a$K!"(B -$B4X?t$O0c$C$?4X?t$rMQ$$$^$9!#0J2<$OL>A0$r@8@.$9$k$?$a$K;HMQ2DG=$J4X?t$N%j%9(B -$B%H$G$9!'(B - -@table @code - -@item gnus-Numeric-save-name -@findex gnus-Numeric-save-name -@file{~/News/Alt.andera-dworkin/45} $B$N$h$&$J%U%!%$%kL>!#(B - -@item gnus-numeric-save-name -@findex gnus-numeric-save-name -@file{~/News/alt.andera-dworkin/45} $B$N$h$&$J%U%!%$%kL>!#(B - -@item gnus-Plain-save-name -@findex gnus-Plain-save-name -@file{~/News/Alt.andera-dworkin} $B$N$h$&$J%U%!%$%kL>!#(B - -@item gnus-plain-save-name -@findex gnus-plain-save-name -@file{~/News/alt.andera-dworkin} $B$N$h$&$J%U%!%$%kL>!#(B -@end table - -@vindex gnus-split-methods -$BO"A[%j%9%H(B @code{gnus-split-methods} $B$K@55,I=8=$rJ|$j9~$`;v$K$h$C$F!"(B -gnus $B$K5-;v$rJ]B8$9$k>l=j$rDs0F$9$k;v$,$G$-$^$9!#Nc$($P!"(Bgnus $B$K4XO"$7$?5-(B -$B;v$r%U%!%$%k(B @file{gnus-stuff} $B$K!"(BVM $B$K4XO"$7$?5-;v$r(B @code{vm-stuff} $BJ](B -$BB8$7$?$1$l$P!"$3$NJQ?t$r0J2<$N$h$&$K$9$k;v$,$G$-$^$9!'(B - -@lisp -(("^Subject:.*gnus\\|^Newsgroups:.*gnus" "gnus-stuff") - ("^Subject:.*vm\\|^Xref:.*vm" "vm-stuff") - (my-choosing-function "../other-dir/my-stuff") - ((equal gnus-newsgroup-name "mail.misc") "mail-stuff")) -@end lisp - -$B$3$l$O$=$l$>$l$NMWAG$,!"#2$D$NMWAG!=!=(B@dfn{$B9gCW(B} $B$H(B @dfn{$B%U%!%$%k(B} $B$r;}$D(B -$B%j%9%H$G$"$k%j%9%H$G$"$k$H$$$&;v$,$o$+$j$^$9!#9gCW$OJ8;zNs!J$3$N>l9g$O5-;v(B -$B$N%X%C%@!<$K9gCW$9$k@55,I=8=$H$7$F;H$o$l$^$9!K$*$h$S!"%7%s%\%k!J%0%k!<%WL>(B -$B$r0z?t$H$7$F!"4X?t$H$7$F8F$P$l$^$9!K$*$h$S!"%j%9%H!J$3$l$OI>2A(B -(@code{eval}) $B$5$l$^$9!K$G$"$k$3$H$,$G$-$^$9!#$b$7$3$l$i$NF0:n$N0l$D$G$b(B -@code{nil} $B$G$J$$7k2L$rJV$9$H!"(B@dfn{$B%U%!%$%k(B}$B$,%G%#%U%)%k%H$NB%?J$H$7$F;H(B -$B$o$l$^$9!#2C$($F!"8F$P$l$?4X?t$+<0$,J8;zNs$+J8;zNs$N%j%9%H$rJV$7$?$H$-$O!"(B -$B1i;;$N7k2L<+BN$,;H$o$l$^$9!#(B - -$B4pK\E*$K$O!"8=:_$N5-;v$rJ]B8$9$k$N$K;H$o$l$k2DG=@-$N$"$k%U%!%$%kL>$N%j%9%H(B -$B$rA0$H$7$F;H$$$?$$$b$N$rB%$5$l!"$3$NJQ?t$rE,MQ$9$k;v$K$h$jF@$i$l$?7k2L$+$i(B -$B%U%!%$%kL>Jd40$r$7$FF~NO$7$^$9!#(B - -$B$3$NJQ?t$O%G%#%U%)%k%H$G$O(B @code{((gnus-article-archive-name))} $B$G!"(Bgnus -$BJ]B8$9$k5-;v$N(B @code{Archive-name} $B9T$rD4$Y$F!"$=$l$r%U%!%$%kL>$NDs0F$H(B -$B$7$F;H$&$H$$$&;v$G$9!#(B - -$B$3$l$O%U%!%$%kL>$r>/$7$-$l$$$K$9$k4X?t$NNc$G$9!#(B -@samp{nnml:mail.whatever} $B$N$h$&$J%a!<%k%0%k!<%W$,$?$/$5$s$"$k$N$G$"$l$P!"(B -$BJ]B8$9$k$?$a$N%U%!%$%kL>$r:n$kA0$K$3$l$i$N%0%k!<%WL>$N:G=i$r@Z$jMn$H$7$?(B -$B$$$+$b$7$l$^$;$s!#e5-$N4X?t$O%0%k!<%WL>$N$9$Y$F$N%T%j%*%I(B -(@samp{.}) $B$r%9%i%C%7%e(B (@samp{/}) $B$GCV$-49$($^$9!=!=$3$l$O4X?t$O$9$Y$F$N(B -$B%U%!%$%k$r0lHV>e$N%G%#%l%/%H%j!<$KCV$/$N$G$O$J$/!"3,AXE*$J%G%#%l%/%H%j!<$r(B -$B:n$k$H$$$&;v$G$9!J(B@file{~/News/alt.andrea-dworkin} $B$NBe$o$j$K(B -@file{~/News/alt/andrea-dworkin}$B!#!K$3$NJQ?t$O$?$$$F$$$N%7%9%F%`$K$*$$$F%G%#(B -$B%U%)%k%H$G(B @code{t} $B$G$9!#$7$+$7!"Nr;KE*$JM}M3$+$i(B Xenix $B$H(B usg-unix-v $B%^(B -$B%7%s$G$O%G%#%U%)%k%H$G(B @code{nil} $B$G$9!#(B - -$B$3$N4X?t$O:o=|$H%9%3%"$N%U%!%$%kL>$K1F6A$7$^$9!#$3$NJQ?t$,%j%9%H$G!"%j%9(B -$B%H$KMWAG(B @code{not-score} $B$,$"$k$H!"D9$$%U%!%$%kL>$O%9%3%"%U%!%$%k$K$O;H(B -$B$o$l$:!"%j%9%H$KMWAG(B @code{not-save} $B$,$"$k$H!"D9$$%U%!%$%kL>$OJ]B8$K$O(B -$B;H$o$l$:!"MWAG(B @code{not-kill} $B$,$"$k$H!"D9$$%U%!%$%kL>$O:o=|%U%!%$%k$K(B -$B$O;H$o$l$^$;$s!#(B - -$B$b$75-;v$r%9%W!<%k$N$h$&$J3,AX$KJ]B8$7$?$$$N$G$"$l$P!"e$N%G%#%l%/%H%j!<$r0z?t(B (@file{~/News/}) $B$H$7$FEO$7$^(B -$B$9!#(B - - -@node Decoding Articles -@section $B5-;v$NI|9f2=(B -@cindex decoding articles - -$B$H$-$I$-MxMQA0!"(B -@samp{[Cc][Ii][Nn][Dd][Yy][0-9]+.\\(gif\\|jpg\\)} $B$K%O!<%I%3!<%I$5$l$k!"$r(B -$B;}$D5-;v$rI|9f2=$7$h$&$H$7$?$H$-$O!"(B@code{gnus-uu} $B$OLdBj$N5-;v$r$A$g$&$I(B -$B1\Mw$7$?;v$rCN$i$;$k$?$a$K!"<+F0E*$K(B @samp{comp.unix.wizards} $B$K5-;v$rEj9F(B -$B$7$^$9!#$3$N5!G=$r;H$o$J$$$h$&$K$9$k;v$O$G$-$^$;$s!#(B - - -@node Shell Archives -@subsection $B%7%'%k%"!<%+%$%V(B -@cindex unshar -@cindex shell archives -@cindex shared articles - -$B%7%'%k%"!<%+%$%V!J!X(Bshar $B%U%!%$%k!Y!K$O%=!<%9$rG[I[$9$k$?$a$N?M5$$N$"$kJ}(B -$BK!$G$7$?$,!":#F|$G$O$=$s$J$K;H$o$l$F$$$^$;$s!#$H$K$+$/$3$l$i$r07$&$?$a$NL?(B -$BNa$,$"$j$^$9!'(B - -@table @kbd - -@item X s -@kindex X s $B!J35N,!K(B -@findex gnus-uu-decode-unshar -$B8=:_$N72$r2rE`$7$^$9(B (@code{gnus-uu-decode-unshar})$B!#(B - -@item X S -@kindex X S $B!J35N,!K(B -@findex gnus-uu-decode-unshar-and-save -$B8=:_$N72$r2rE`$7J]B8$7$^$9(B (@code{gnus-uu-decode-unshar-and-save})$B!#(B - -@item X v s -@kindex X v s $B!J35N,!K(B -@findex gnus-uu-decode-unshar-view -$B8=:_$N72$r2rE`$7I=<($7$^$9(B (@code{gnus-uu-decode-unshar-view})$B!#(B - -@item X v S -@kindex X v S $B!J35N,!K(B -@findex gnus-uu-decode-unshar-and-save-view -$B8=:_$N72$r2rE`$7!"I=<($7$FJ]B8$7$^$9(B -(@code{gnus-uu-decode-unshar-and-save-view})$B!#(B -@end table - - -@node PostScript Files -@subsection $B%]%9%H%9%/%j%W%H%U%!%$%k(B -@cindex PostScript - -@table @kbd - -@item X p -@kindex X p $B!J35N,!K(B -@findex gnus-uu-decode-postscript -$B8=:_$N%]%9%H%9%/%j%W%H72$rE83+$7$^$9(B (@code{gnus-uu-decode-postscript})$B!#(B - -@item X P -@kindex X P $B!J35N,!K(B -@findex gnus-uu-decode-postscript-and-save -$B8=:_$N%]%9%H%9%/%j%W%H72$rE83+$7$FJ]B8$7$^$9(B -(@code{gnus-uu-decode-postscript-and-save})$B!#(B - -@item X v p -@kindex X v p $B!J35N,!K(B -@findex gnus-uu-decode-postscript-view -$B8=:_$N%]%9%H%9%/%j%W%H72$rI=<($7$^$9(B -(@code{gnus-uu-decode-postscript-view})$B!#(B - -@item X v P -@kindex X v P $B!J35N,!K(B -@findex gnus-uu-decode-ostscript-and-save-view -$B8=:_$N%]%9%H%9%/%j%W%H72$rI=<($7J]B8$7$^$9(B -(@code{gnus-uu-decode-postscript-and-save-view})$B!#(B -@end table - - -@node Other Files -@subsection $BB>$N%U%!%$%k(B - -@table @kbd -@item X o -@kindex X o $B!J35N,!K(B -@findex gnus-uu-decode-save -$B8=:_$N72$rJ]B8$7$^$9(B (@code{gnus-uu-decode-save})$B!#(B - -@item X b -@kindex X b $B!J35N,!K(B -@findex gnus-uu-decode-binhex -$B8=:_$N5-;v$r(B binhex $B2rE`$7$^$9(B (@code{gnus-uu-decode-binhex})$B!#$3$l$OK\(B -$BEv$OF0:n$7$^$;$s!#(B -@end table - - -@node Decoding Variables -@subsection $BI|9f2=$N$?$a$NJQ?t(B - -$B7AMF;l$G$9!#F0;l$G$O$"$j$^$;$s!#(B - -@menu -* Rule Variables:: $B%U%!%$%k$,$I$N$h$&$KI=<($5$l$k$+$r7h$a$kJQ?t!#(B -* Other Decode Variables:: $BB>$NI|9f2=$NJQ?t!#(B -* Uuencoding and Posting:: uuencode $B$9$k$N$r%+%9%?%^%$%:$9$kJQ?t!#(B -@end menu - - -@node Rule Variables -@subsubsection $B5,B'JQ?t(B -@cindex rule variables - -Gnus $B$O%U%!%$%k$r1\Mw$9$k$N$r7hDj$9$k$N$K(B@dfn{$B5,B'JQ?t(B}$B$rMQ$$$^$9!#$3$l$i(B -$B$NJQ?t$O$9$Y$F0J2<$N$h$&$JMM<0$G$9(B - -@lisp - (list '(regexp1 command2) - '(regexp2 command2) - ...) -@end lisp - -@table @code - -@item gnus-uu-user-view-rules -@vindex gnus-uu-user-view-rules -@cindex sox -$B$3$NJQ?t$O%U%!%$%k$r1\Mw$9$k$H$-$K:G=i$KD4$Y$i$l$^$9!#Nc$($P!"$b$7(B -@samp{.au} $B2;%U%!%$%k$rJQ49$9$k$?$a$K(B @code{sox} $B$r;H$$$?$$$H$-$O!" /dev/audio\"))) -@end lisp - -@item gnus-uu-user-view-rules-end -@vindex gnus-uu-user-view-rules-end -$B$3$NJQ?t$O(B gnus $B$,MxMQ$NI|9f2=$NJQ?t(B - -@table @code -@vindex gnus-uu-grabbed-file-functions - -@item gnus-uu-grabbed-file-functions -$B$3$N%j%9%H$N$9$Y$F$N4X?t$O$=$l$>$l$N%U%!%$%k$,>e8e$K8F$P(B -$B$l$^$9!=!=$G$9$+$i!"$9$0$K%U%!%$%k$r0\F0$d1\Mw$7$?$j$9$k$3$H$,$G$-!"2?$+$r(B -$B$9$kA0$K$9$Y$F$N%U%!%$%k$,I|9f2=$5$l$k$N$rBT$DI,MW$O$"$j$^$;$s!#$3$N%j%9%H(B -$B$KF~$l$k;v$N$G$-$k4{@=4X?t$O!'(B - -@table @code - -@item gnus-uu-grab-view -@findex gnus-uu-grab-view -$B%U%!%$%k$r1\Mw$7$^$9!#(B - -@item gnus-uu-grab-move -@findex gnus-uu-grab-move -$B%U%!%$%k$r0\F0$7$^$9!J$b$7J]B84X?t$r;H$C$F$$$k$N$G$"$l$P!K!#(B -@end table - -@item gnus-uu-be-dangerous -@vindex gnus-uu-be-dangerous -$BI|9f2=$N:GCf$KJQ$J>u67$,5/$3$C$?$H$-$K2?$r$9$k$+$r;XDj$7$^$9!#$b$7(B -@code{nil} $B$G$"$k$H!"$G$-$k$@$1J]e=q$-$7$^$9!#$=$NB>$N>l9g$O!"(B -$B$=$l$>$l$N$H$-$K?R$M$^$9!#(B - -@item gnus-uu-ignore-files-by-name -@vindex gnus-uu-ignore-files-by-name -$B$3$N@55,I=8=$K9gCW$9$kL>A0$N%U%!%$%k$O1\Mw$5$l$^$;$s!#(B - -@item gnus-uu-ignore-files-by-type -@vindex gnus-uu-ignore-files-by-type -$B$3$NJQ?t$K9gCW$9$k(B @sc{mime} $B$N7?$r;}$D%U%!%$%k$O1\Mw$5$l$^$;$s!#(BGnus $B$O%U%!(B -$B%$%kL>$K4p$E$$$F7?$r?dB,$7$F$$$k;v$KCm0U$7$F$/$@$5$$!#(B@code{gnus-uu} $B$O(B -$B!J$^$@!K(B@sc{mime} $B%Q%C%1!<%8$G$O$"$j$^$;$s$N$G!"$3$l$O>/$7JQ$G$9!#(B - -@item gnus-uu-tmp-dir -@vindex gnus-uu-tmp-dir -@code{gnus-uu} $B$,$=$N;E;v$r$9$k>l=j$G$9!#(B - -@item gnus-uu-do-not-unpack-archives -@vindex gnus-uu-do-not-unpack-archives -@code{nil} $B$G$J$$$N$O!"(B@code{gnus-uu} $B$OI=<($9$k$?$a$N%U%!%$%k$rC5$9$?$a(B -$B$K%"!<%+%$%V$NCf$^$G$OF~$C$F$$$+$J$$$H$$$&;v$G$9!#(B - -@item gnus-uu-view-and-save -@vindex gnus-uu-view-and-save -@code{nil} $B$G$J$$$N$O!"MxMQo$KJ]B8$9$k$+$I$&(B -$B$+$r?R$M$i$l$k$H$$$&;v$G$9!#(B - -@item gnus-uu-ignore-default-view-rules -@vindex gnus-uu-ignore-default-view-rules -@code{nil} $B$G$J$$$N$O!"(B@code{gnus-uu} $B$O%G%#%U%)%k%H$N1\Mw5,B'$rL5;k$9$k(B -$B$H$$$&;v$G$9!#(B - -@item gnus-uu-ignore-default-archive-rules -@vindex gnus-uu-ignore-default-archive-rules -@code{nil} $B$G$J$$$N$O!"(B@code{gnus-uu} $B$O%G%#%U%)%k%H$N%"!<%+%$%VE83+L?Na(B -$B$rL5;k$9$k$H$$$&;v$G$9!#(B - -@item gnus-uu-kill-carriage-return -@vindex gnus-uu-kill-carriage-return -@code{nil} $B$G$J$$$N$O!"(B@code{gnus-uu} $B$O5-;v$+$i$9$Y$F$N%-%c%j%C%8%j%?!<(B -$B%s(B (carriage return) $B$r$K4p$E$$$?(B @sc{mime} $BFbMF$N7?$K~$j$r$7$J$$$GA4$F$r%U%!%$%k$KJ]B8$7$^$9!#MWLs(B -$B$O(B RFC1153 $B=`$8$F$$$^$9!=!=0UL#$N$"$kNL$r;XDj$7$F!"HV9f$rH/9T$9$k4JC1$JJ}(B -$BK!$,8+$D$+$i$J$+$C$?$N$G!"C1=c$K$=$l$i$O@Z$jMn$H$7$F$$$^$9!#(B - -@end table - - -@node Uuencoding and Posting -@subsubsection uuencode $B$HEj9F(B - -@table @code - -@item gnus-uu-post-include-before-composing -@vindex gnus-uu-post-include-before-composing -@code{nil} $B$G$J$$$N$O!"(B@code{gnus-uu} $B$,5-;v$r:n@.$9$kA0$KId9f2=$9$k%U%!(B -$B%$%k$r?R$M$k$H$$$&;v$G$9!#$3$NJQ?t$,(B @code{t} $B$G$"$k$H!"(B@kbd{C-c C-i} $B$K(B -$B$h$C$FId9f2=$5$l$?%U%!%$%k$r$NI|9fAuCV$,B8:_$7$J$$$+$i$G$9!#!J$(!<$H!";d$O$=$l$r$9$k0l$D$N%Q%C(B -$B%1!<%8$r8+$?;v$,$"$j$^$9!=!=(B@code{gnus-uu} $B$G$9!#$7$+$7$J$<$+!"$=$l$,?t$N(B -$B$&$A$KF~$k$H$O;W$($J$$$N$G$9(B...$B!K%G%#%U%)%k%H$O(B @code{nil} $B$G$9!#(B - -@item gnus-uu-post-separate-description -@vindex gnus-uu-post-separate-description -@code{nil} $B$G$J$$$N$O!"5-=R$OJL$N5-;v$GEj9F$5$l$k$H$$$&;v$G$9!#:G=i$N5-(B -$B;v$OIaDL$O(B (0/x) $B$N$h$&$KHV9f$,IU$1$i$l$^$9!#$b$7$3$NJQ?t$,(B @code{nil} -$B$G$"$k$H!"MxMQl9g!"(Bgnus $B$O%"!<%+%$%V$r(B -$BE83+$7$h$&$H;n$_!"%"!<%+%$%V$NCf$K1\Mw$G$-$k%U%!%$%k$,$"$k$+$rD4$Y$^$9!#Nc(B -$B$($P!"(Bgzip $B$5$l$?(B tar $B%U%!%$%k(B @file{pics.tar.gz} $B$,$"$C$F!"%U%!%$%k(B -@file{pic1.jpg} $B$H(B @file{pic2.gif} $B$r4^$s$G$$$k>l9g!"(Bgnus $B$O$l$NCj=P$5$l$?5-;v$4$H$K(B@dfn{$B5?;w5-;v(B}$B$r35N,%P%C(B -$B%U%!$KA^F~$7$^$9!#$3$l$i$N!X5-;v!Y$K0\F0$7$?>l9g$O!"$l$N%U%!%$%k$KBP$7$F:n@.$5$l$^$9!#(B@code{nil} $B$G$"$k(B -$B$H!"F1$81\MwL?Na$r;H$&$9$Y$F$NL?Na$,$=$NL?Na$N0z?t$N%j%9%H$H$7$FEO$5$l$^(B -$B$9!#(B - -@vindex gnus-insert-pseudo-articles -@code{gnus-insert-pseudo-articles} $B$,(B @code{nil} $B$G$J$$$H!"I|9f2=$N$H$-(B -$B$K5?;w5-;v$rA^F~$7$^$9!#%G%#%U%)%k%H$G$O(B @code{t}$B$G$9!#(B - -$B$=$l$G!"$=$N$h$&$J46$8$G$9!#(B@emph{$Bo$K6lpJs$O>C$75n$j$?$$$H$b;W$&!#(B -* Article Washing:: $B?M@8$r$b$C$H$h$/$9$k$?$/$5$s$N5$$NMx$$$?4X?t!#(B -* Article Buttons:: URL $B$d(B Message-ID $B$d(B $B%"%I%l%9$J$I$r%/%j%C%/$9$k!#(B -* Article Date:: $B$0$:$0$:8@$&$J!"@$3&;~$@!*(B -* Article Signature:: $B=pL>$C$F2?!)(B -@end menu - - -@node Article Highlighting -@subsection $B5-;v$N%O%$%i%$%H(B -@cindex highlighting - -$B5-;v%P%C%U%!$r2LJ*%5%i%@$N$h$&$K$7$?$$$@$1$G$J$/!"2Z$d$+$J2LJ*%5%i%@$N$h(B -$B$&$K8+$($k$h$&$K$7$?$$$G$7$g$&!#(B - -@table @kbd - -@item W H a -@kindex W H a $B!J35N,!K(B -@findex gnus-article-highlight -@findex gnus-article-maybe-highlight -$B8=:_$N5-;v$r$b$C$H%O%$%i%$%H(B (highlight) $B$7$^$9!#$3$N4X?t$O!"%X%C%@!$r%O%$%i%$%H$7!"K\BN(B (body) $B$HF,(B (head) $B$K%\%?%s$r2C$($^$9!#(B - -$B$?$$$F$$$NMxMQ/$7$@$1@Q6K@-$,8:>/$7$^$9(B---$B$=$l$O%X%C%@!<$H=p(B -$BL>$@$1$r%O%$%i%$%H$7!"%\%?%s$r2C$($^$9!#(B - -@item W H h -@kindex W H h $B!J35N,!K(B -@findex gnus-article-highlight-headers -@vindex gnus-header-face-alist -$B%X%C%@!<$r%O%$%i%$%H$7$^$9(B (@code{gnus-article-highlight-headers})$B!#%O%$(B -$B%i%$%H$OJQ?t(B @code{gnus-header-face-alist} $B$K$7$?$,$C$F$J$5$l!"$=$l$O$=(B -$B$l$>$l$NMWAG$,(B @var{($B@55,I=8=(B $BL>A0(B $BFbMF(B)} $B$H$$$&MM<0$N%j%9%H$G$9!#(B -@var{$B@55,I=8=(B}$B$O%X%C%@!<$K9gCW$9$k@55,I=8=!"(B@var{$BL>A0(B}$B$O%X%C%@!<$NL>A0$r(B -$B%O%$%i%$%H$9$k$N$K;H$o$l$k%U%'%$%9(B (face) (@pxref{Faces and Fonts})$B!"(B -@var{$BFbMF(B}$B$O%X%C%@!<$NCM$r%O%$%i%$%H$9$k%U%'%$%9$G$9!#:G=i$K9gCW$7$?$b$N(B -$B$,;H$o$l$^$9!#(B@var{$B@55,I=8=(B}$B$O(B @samp{^} $B$,IU$1$i$l$k$Y$-$G$O$J$$;v$KCm0U(B -$B$7$F$/$@$5$$!=!=(Bgnus $B$,$=$l$rIU$12C$($^$9!#(B - -@item W H c -@kindex W H c $B!J35N,!K(B -@findex gnus-article-highlight-citation -$B0zMQ$5$l$?J8$r%O%$%i%$%H$7$^$9(B (@code{gnus-article-highlight-citation})$B!#(B - -$B0zMQ%O%$%i%$%H$r%+%9%?%^%$%:$9$k$$$/$D$+$NJQ?t$O!'(B - -@table @code -@vindex gnus-cite-parse-max-size - -@item gnus-cite-parse-max-size -$B5-;v$NBg$-$5$,$3$NJQ?t!J%G%#%U%)%k%H$G$O(B 25000$B!K$h$jBg$-$$5-;v$O!"0zMQ%O%$(B -$B%i%$%H$O9T$o$l$^$;$s!#(B - -@item gnus-cite-prefix-regexp -@vindex gnus-cite-prefix-regexp -$B$"$k9T$,(B -$B$l$N5-;v$+$i$N0zMQ$r$=$lMQ$N%U%'%$%9$GI=<($7$h$&$H$7$^$9!#$3$l$K$h$j!"C/(B -$B$,2?$r=q$$$?$+$,J,$+$j$d$9$/$J$k$G$7$g$&!#(B - -@item gnus-supercite-regexp -@vindex gnus-supercite-regexp -$BIaDL$N(B Supercite $BB0@-9T$K9gCW$9$k@55,I=8=$G$9!#(B - -@item gnus-supercite-secondary-regexp -@vindex gnus-supercite-secondary-regexp -$B0z$-Nv$+$l$?(B Supercite $BB0@-9T$K9gCW$9$k@55,I=8=$G$9!#(B - -@item gnus-cite-minimum-match-count -@vindex gnus-cite-minimum-match-count -$B$=$l$,0zMQ$G$"$k$H7hDj$9$kA0$KD4$Y$J$1$l$P$J$i$J$$:G>.$NF10l@\F,8l$G$9!#(B - -@item gnus-cite-attribution-prefix -@vindex gnus-cite-attribution-prefix -$BB0@-9T$N;O$^$j$K9gCW$9$k@55,I=8=$G$9!#(B - -@item gnus-cite-attribution-suffix -@vindex gnus-cite-attribution-suffix -$BB0@-9T$N:G8e$K9gCW$9$k@55,I=8=$G$9!#(B - -@item gnus-cite-attribution-face -@vindex gnus-cite-attribution-face -$BB0@-9T$K;H$o$l$k%U%'%$%9$G$9!#$=$NB0@-$KB0$9$kJ8$N$?$a$N%U%'%$%9$HM;9g$5(B -$B$l$^$9!#(B - -@end table - - -@item W H s -@kindex W H s $B!J35N,!K(B -@vindex gnus-signature-separator -@vindex gnus-signature-face -@findex gnus-article-highlight-signature -$B=pL>(B (signature) $B$r%O%$%i%$%H$7$^$9(B -(@code{gnus-article-highlight-signature})$B!#(B -@code{gnus-signature-separator} (@pxref{Article Signature}) $B$N8e$NA4$F$N(B -$B$b$N$O=pL>$H9M$($i$l!"(B@code{gnus-signature-face} $B$G%O%$%i%$%H$5$l$^$9!#(B -$B$=$l$O%G%#%U%)%k%H$G$O(B @code{italic} $B$G$9!#5-;v$r<+F0E*$K%O%$%i%$%H$9$k(B -$BJ}K!$K$D$$$F$O(B @xref{Customizing Articles} $B$r;2>H$7$F2<$5$$!#(B -@end table - - -@node Article Fontisizing -@subsection $B5-;v$N%U%)%s%HJQ99(B -@cindex emphasis -@cindex article emphasis - -@cindex gnus-article-emphasize -@kindex W e $B!J35N,!K(B -$B?M!9$O$h$/%K%e!<%9$N5-;v$G(B @samp{_$B$3$l(B_} $B$d(B @samp{*$B$3$l(B*} $B$N$h$&$J$b$N$r(B -$B;H$C$FC18l$r6/D4$7$^$9!#(BGnus $B$O(B $B5-;v$rL?Na(B @kbd{W e} -(@code{gnus-article-emphasize}) $B$K$+$1$k;v$K$h$C$FAGE($K8+$($k$h$&$K$G$-(B -$B$^$9!#(B - -@vindex gnus-emphasis-alist -$B6/D4$,$I$N$h$&$K1i;;$5$l$k$+$OJQ?t(B @code{gnus-emphasis-alist} $B$K$h$C$F@)(B -$B8f$5$l$^$9!#$3$l$O:G=i$NMWAG$,9gCW$9$k$Y$-@55,I=8=$G$"$kO"A[%j%9%H$G$9!#(B -$B#2HVL\$NMWAG$O$I$N@55,I=8=$N%0%k!<%W$,6/D48lA4BN$r8+$D$1$k$?$a$K;H$o$l$k(B -$B$+$r<($9?t;z$G$9!##3HVL\$O$I$N@55,I=8=$N%0%k!<%W$,I=<($5$l%O%$%i%$%H$5$l(B -$B$k$+$r7h$a$k?t;z$G$9!#!J$3$N#2$D$N%0%k!<%W$N4V$N5-;v$O1#$5$l$^$9!#!K#4HV(B -$BL\$O%O%$%i%$%H$N%U%'%$%9$G$9!#(B - -@lisp -(setq gnus-emphasis-alist - '(("_\\(\\w+\\)_" 0 1 gnus-emphasis-underline) - ("\\*\\(\\w+\\)\\*" 0 1 gnus-emphasis-bold))) -@end lisp - -@vindex gnus-emphasis-underline -@vindex gnus-emphasis-bold -@vindex gnus-emphasis-italic -@vindex gnus-emphasis-underline-bold -@vindex gnus-emphasis-underline-italic -@vindex gnus-emphasis-bold-italic -@vindex gnus-emphasis-underline-bold-italic -$B=i4|@_Dj$G$O#7$D$N5,B'$,$"$j!"$=$l$i$O0J2<$N%U%'%$%9$rMQ$$$^$9!'(B -@code{gnus-emphasis-bold}, @code{gnus-emphasis-italic}, -@code{gnus-emphasis-underline}, @code{gnus-emphasis-bold-italic}, -@code{gnus-emphasis-underline-italic}, -@code{gnus-emphasis-underline-bold}, -@code{gnus-emphasis-underline-bold-italic}. - -$B$3$l$i$N%U%'%$%9$rJQ99$7$?$$$N$G$"$l$P!"(B@kbd{M-x customize} $B$+(B -@code{copy-face} $B$r;H$&;v$,$G$-$^$9!#Nc$($P!"(B@code{gnus-emphasis-italic} -$B$KBe$o$j$K@V$N%U%'%$%9$r;H$&$h$&$K$7$?$$$H$-$O!"H$7$F2<$5$$!#(B - - -@node Article Hiding -@subsection $B5-;v$r1#$9(B -@cindex article hiding - -$B$b$7$/$O!"$=$l$>$l$N5-;v$NFCDj$N$b$N$r1#$7$?$$$+$b$7$l$^$;$s!#$?$$$F$$$N(B -$B5-;v$K$OIaDL$O$"$j$9$.$k$/$i$$:n$j$+$($k$b$N$,$"$j$^$9!#(B - -@table @kbd - -@item W W a -@kindex W W a $B!J35N,!K(B -@findex gnus-article-hide -$B5-;v%P%C%U%!$G$?$/$5$s$N1#F?$r$7$^$9(B (@kbd{gnus-article-hide})$B!#FC$K!"$3(B -$B$N4X?t$O%X%C%@!$r1#$7$^$9!#(B - -@item W W h -@kindex W W h $B!J35N,!K(B -@findex gnus-article-hide-headers -$B%X%C%@!<$r1#$7$^$9(B (@code{gnus-article-hide-headers})$B!#(B @xref{Hiding -Headers}. - -@item W W b -@kindex W W b $B!J35N,!K(B -@findex gnus-article-hide-boring-headers -$B$"$^$j6=L#$N$b$F$J$$%X%C%@!<$r1#$7$^$9(B -(@code{gnus-article-hide-boring-headers})$B!#(B @xref{Hiding Headers}. - -@item W W s -@kindex W W s $B!J35N,!K(B -@findex gnus-article-hide-signature -$B=pL>$r1#$7$^$9(B (@code{gnus-article-hide-signature})$B!#(B @xref{Article -Signature}. - -@item W W p -@kindex W W p $B!J35N,!K(B -@findex gnus-article-hide-pgp -@vindex gnus-article-hide-pgp-hook -@sc{pgp} $B=pL>$r1#$7$^$9(B (@code{gnus-article-hide-pgp})$B!#(B @sc{pgp} $B=pL>$,(B -$B1#$5$l$?8e$K%U%C%/(B @code{gnus-article-hide-pgp-hook} $B$,O$N(B -$B1#JC$r@Z$jBX$($i$l$k$h$&$K$7$^$9!#$3$NJQ?t$NMM<0$O$3$l$i$N%U%)!<%^%C%H$N(B -$B$h$&$JJQ?t$K$h$C$F;XDj$5$l$^$9(B (@pxref{Formatting Variables})$B!#/$J$/$H$b$3$ND9$5(B ($B=i4|CM(B 10) $B$G$J$1$l$P$J$j$^$;$s!#(B -@end table - -@end table - -$B$3$l$i$NA4$F$N!X1#JC!YL?Na$O@Z$jBX$(L?Na$G$9$,!"$3$l$i$NL?Na$KIi$N@\F,0z?t(B -$B$rM?$($k$H!"$=$l$i$OA0$K1#$5$l$F$$$?$b$N$rI=<($7$^$9!#@5$N@\F,0z?t$rM?$($l(B -$B$P!"$=$l$i$O>o$K1#$7$^$9!#(B - -$B0zMQ%+%9%?%^%$%:$N$?$a$NB>$NJQ?t$N>pJs$N$?$a$K(B @pxref{Article -Highlighting} $B$b;2>H$7$F$/$@$5$$!#(B - -$B<+F0E*$K5-;v$NMWAG$r1#$9$?$a$NJ}K!$O(B @xref{Customizing Articles} $B$r;2>H(B -$B$7$F2<$5$$!#(B - - -@node Article Washing -@subsection $B5-;v@vBu(B -@cindex washing -@cindex article washing - -$B;d$?$A$O$3$l$r$b$C$H$b$JM}M3$N2<$G!X5-;v@vBu!Y(B(article washing) $B$H8F$s$G$$(B -$B$^$9!#$9$J$o$A!"%-!<(B @kbd{A} $B$O;H$o$l$F$$$k$N$G!"Be$o$j$K%-!<(B @kbd{W} $B$r;H(B -$B$&I,MW$,$"$k$N$G$9!#(B - -$B;d$?$A$O(B@dfn{$B@vBu(B}$B$r!X2?$+$N2?$+$r2?$+JL$N$b$N$KJQ49$9$k!Y$HDj5A$7$F$$$^$9(B -$B$,!"IaDL$O$b$C$HNI$/8+$($k2?$+$KMn$ACe$-$^$9!#$=$l$K$b$C$H$-$l$$$G$9!"$?$V(B -$B$s!#(B - -@table @kbd - -@item W l -@kindex W l $B!J35N,!K(B -@findex gnus-summary-stop-page-breaking -$B%Z!<%8$N6h@Z$j$r8=:_$N5-;v$+$iH$7$F2<$5$$!#(B - -@item W r -@kindex W r $B!J35N,!K(B -@findex gnus-summary-caesar-message -@c @icon{gnus-summary-caesar-message} -$B5-;v%P%C%U%!$G%+%(%5%kJQ49(B (Caesar rotate) (rot13) $B$r$7$^$9(B -(@code{gnus-summary-caesar-message})$B!#%+%(%5%kJQ49$+(B rot13 $B$rMQ$$$FFI$`;v(B -$B$N$G$-$k!"H=FIIT2DG=$J5-;v$G$9!JE57?E*$K$O!"967bE*$J>iCL$J$I$G$9!#!K(B - -$BIaDL$O(B ``rot13'' $B$H8F$P$l$F$$$^$9!#$=$l$O%"%k%U%!%Y%C%H$N0LCV$,(B 13 $B8D2sE>(B -$B$9$k$+$i$G$9!#Nc$($P!"(B@samp{B}$B!J#2HVL\$NJ8;z!K(B $B"*(B @samp{O}$B!J(B15$BHVL\$NJ8;z!K!#(B -$B$3$l$O;~!9!X%+%(%5%kJQ49!Y$H8F$P$l$k;v$b$"$j$^$9!#$H$$$&$N$O!"%+%(%5%k$,$3(B -$B$N7A<0$N!"$(!<$H!"$A$g$C$H4JC1$J0E9f2=$r:NMQ$7$?$H$$$&1=$,$"$k$+$i$G$9!#(B - -@item W t -@kindex W t $B!J35N,!K(B -@findex gnus-summary-toggle-header -$B5-;v%P%C%U%!$K$9$Y$F$N%X%C%@!<$rI=<($9$k$+$I$&$+$r@Z$jBX$($^$9(B -(@code{gnus-summary-toggle-header})$B!#(B - -@item W v -@kindex W v $B!J35N,!K(B -@findex gnus-summary-verbose-header -$B5-;v%P%C%U%!$K$9$Y$F$N%X%C%@!<$r1J1s$KI=<($9$k$+$I$&$+$r@Z$jBX$($^$9(B -(@code{gnus-summary-verbose-header})$B!#(B - -@item W m -@kindex W m $B!J35N,!K(B -@findex gnus-summary-toggle-mime -$B5-;v$r(B @sc{mime} $B5-;v$H$7$FI=<($9$k$+$I$&$+$r@Z$jBX$($^$9(B -(@code{gnus-summary-toggle-mime})$B!#(B - -@item W o -@kindex W o $B!J35N,!K(B -@findex gnus-article-treat-overstrike -$B%*!<%P!<%9%H%i%$%/$r=hM}$7$^$9(B (@code{gnus-article-treat-overstrike})$B!#(B - -@item W d -@kindex W d $B!J35N,!K(B -@findex gnus-article-treat-dumbquotes -M******** sm*rtq**t*s $B$r=hM}$7$^$9(B -(@code{gnus-article-treat-dumbquotes})$B!#(B - -@item W w -@kindex W w $B!J35N,!K(B -@findex gnus-article-fill-cited-article -$B8l$N@^$jJV$7$r$7$^$9(B (@code{gnus-article-fill-cited-articles})$B!#$b$7$3$N(B -$B4X?t$r(B @code{gnus-article-display-hook} $B$NCf$G;H$C$?>l9g!"$=$l$O$+$J$j8e(B -$B$NJ}$G/$7Aa$/$7$^$9!#$b$7:,K\E*(B -X-Face $B5!G=$,$J$$$N$G$"$l$P!"(Bgnus $B$O(B @code{pbmplus} $B$d$=$NCg4V$N30It%W%m%0(B -$B%i%`$r;H$C$F(B @code{X-Face} $BMs$rJQ49$7$h$&$H;n$_$^$9!#!K$3$N4X?t$rI=<(%U%C(B -$B%/$KF~$l$?$$$N$G$"$l$P!"$*$=$i$/$=$l$":G8e$K$J$k$Y$-$G$7$g$&!#(B - -@item W b -@kindex W b $B!J35N,!K(B -@findex gnus-article-add-buttons -$B%/%j%C%/$G$-$k%\%?%s$r5-;v$K2C$($^$9(B (@code{gnus-article-add-buttons})$B!#(B -@xref{Article Buttons} - -@item W B -@kindex W B $B!J35N,!K(B -@findex gnus-article-add-buttons-to-head -$B%/%j%C%/$G$-$k%\%?%s$r5-;v$N%X%C%@!<$K2C$($^$9(B -(@code{gnus-article-add-buttons-to-head})$B!#(B - -@item W E l -@kindex W E l $B!J35N,!K(B -@findex gnus-article-strip-leading-blank-lines -$B5-;v$N;O$a$+$i$N$9$Y$F$N6uGr9T$re$N#3$D$NL?Na$r$9$Y$F9T$$$^$9(B (@code{gnus-article-strip-blank-lines})$B!#(B - -@item W E A -@kindex W E A $B!J35N,!K(B -@findex gnus-article-strip-all-blank-lines -$B$9$Y$F$N6uGr9T$rH(B -$B$7$F2<$5$$!#(B - - -@node Article Buttons -@subsection $B5-;v$N%\%?%s(B -@cindex buttons - -$B$h$/5-;v$NCf$KB>$N$b$N$X$N;2>H$,F~$l$i$l$k;v$,$"$j$^$9!#$=$7$F!"(Bgnus $B$,(B -$B$=$l$K4X$9$k;v$r!"$=$l$i$N;2>H$N>e$G(B @kbd{RET} $B$rBG$D$+!"%^%&%9$N??Cf$N(B -$B%\%?%s$r;H$&;v$K$h$C$F!":G>.8B$NEXNO$GH$K(B@dfn{$B%\%?%s(B}$B$rIU$1$^$9!'(B $B$A$c$s$H$7(B -$B$?(B URL$B!"%a!<%k%"%I%l%9!"(BMessage-ID $B$G$9!#$3$l$O#2$D$NJQ?t$K$h$C$F@)8f$5$l(B -$B$F$$$F!"$=$N0l$D$O5-;v$NK\BN$r07$$!"$b$&0l$D$O5-;v$N%X%C%@!<$r07$$$^$9!#(B - -@table @code - -@item gnus-button-alist -@vindex gnus-button-alist -$B$=$l$>$l$NF~NOMWAG$,H$G$"$k$H$_$J$5$l$^$9!#(B -$B$3$l$OKd$a9~$^$l$?(B URL $B$K9gCW$9$kE57?E*$J@55,I=8=$G$9(B -@samp{]*\\)>}$B!#(B - -@item button-par -Gnus $B$O9gCW$7$?$b$N$N$I$NItJ,$,%O%$%i%$%H$5$l$k$N$+$rCN$i$J$1$l$P$J$j$^(B -$B$;$s!#$3$l$O@55,I=8=$N$I$NI{I=8=$,%O%$%i%$%H$5$l$k$+$r;XDj$9$kHV9f$G$9!#(B -$BA4$F$r%O%$%i%$%H$7$?$$$N$J$i!"$3$3$G(B 0 $B$r;H$C$F$/$@$5$$!#(B - -@item use-p -$B$3$N<0$O(B @code{$BI>2A(B} $B$5$l!"7k2L$,(B @code{nil} $B$G$J$1$l$P!"$3$l$O9gCW$G$"(B -$B$k$H$_$J$5$l$^$9!#$3$l$O4V0c$C$?9gCW$rHr$1$k$?$a$KFCJL$JA*JL$r$7$?$$$H$-(B -$B$KLr$KN)$A$^$9!#(B - -@item function -$B$3$N4X?t(B (function) $B$O$3$N%\%?%s$r%/%j%C%/$7$?$H$-$K8F$P$l$^$9!#(B - -@item data-par -@var{button-par} $B$N$h$&$K!"$3$l$OItJ,I=8=$NHV9f$G$9$,!"$3$l$O9gCW$N$I$NIt(B -$BJ,$,(B @var{function} $B$K%G!<%?$H$7$FAw$i$l$k$+$r;XDj$7$^$9!#(B - -@end table - -$B$G$9$+$i!"(BURL $B$r%\%?%s$K$9$k40A4$JF~NOMWAG$O(B - -@lisp -("]*\\)>" 0 t gnus-button-url 1) -@end lisp - -@item gnus-header-button-alist -@vindex gnus-header-button-alist -$B$=$l$,5-;v$N%X%C%@!<$@$1$KE,MQ$5$l!"$=$l$>$l$NF~NOMWAG$,$I$N%X%C%@!<$K%\(B -$B%?%s2=$rE,MQ$9$k$+$r<($9DI2C$NMWAG$,$"$k;v$r=|$-!"$3$l$OB>$NO"A[%j%9%H$H(B -$BF1$8$h$&$J$b$N$G$9!'(B - -@lisp -(HEADER REGEXP BUTTON-PAR USE-P FUNCTION DATA-PAR) -@end lisp - -@var{HEADER} $B$O@55,I=8=$G$9!#(B - -@item gnus-button-url-regexp -@vindex gnus-button-url-regexp -$BKd$a9~$^$l$?(B URL $B$K9gCW$9$k@55,I=8=$G$9!#$=$l$O>e$NJQ?t$N%G%#%U%)%k%H$N(B -$BCM$G;H$o$l$^$9!#(B - -@item gnus-article-button-face -@vindex gnus-article-button-face -$B%\%?%s$K;H$o$l$k%U%'%$%9$G$9!#(B - -@item gnus-article-mouse-face -@vindex gnus-article-mouse-face -$B%^%&%9$N%+!<%=%k$,%\%?%s$N>e$K$"$k$H$-$K;H$o$l$k%U%'%$%9$G$9!#(B - -@end table - -$B5-;v$r<+F0E*$K%\%?%s2=$9$kJ}K!$O(B @xref{Customizing Articles} $B$r;2>H$7$F(B -$B2<$5$$!#(B - - -@node Article Date -@subsection $B5-;v$NF|IU(B - -$BF|IU$OJ9$$$?;v$NL5$$2?$+JUnA$J;~4VBS(B (timezone) $B$G:n@.$5$l$F$$$k;v$,NI$/$"(B -$B$k$N$G!"5-;v$,Aw$i$l$?$H$-$K2?;~$G$"$C$?$+$rCN$k;v$,$G$-$k$N$OHs>o$KNI$$;v(B -$B$G$7$g$&!#(B - -@table @kbd - -@item W T u -@kindex W T u $B!J35N,!K(B -@findex gnus-article-date-ut -UT ($BJLL>(B GMT, ZULU) $B$GF|IU$rI=<($7$^$9(B (@code{gnus-article-date-ut})$B!#(B - -@item W T i -@kindex W T i $B!J35N,!K(B -@findex gnus-article-date-iso-8601 -@cindex ISO 8601 -$BF|IU$r9q:]E*$J7A<0!"(BISO 8601 $B$GI=<($7$^$9(B -(@code{gnus-article-date-iso8601})$B!#(B - -@item W T l -@kindex W T l $B!J35N,!K(B -@findex gnus-article-date-local -$BF|IU$r$=$NCO0h$N;~4VBS$GI=<($7$^$9(B (@code{gnus-article-date-local})$B!#(B - -@item W T s -@kindex W T s $B!J35N,!K(B -@vindex gnus-article-time-format -@findex gnus-article-date-user -@findex format-time-string -$BF|IU$rMxMQ$NJQ494X?t$r;H$C$F$$$F!"$=$l$,40A4$K4V0c$C$?;v$r$7$F$$$k$N$G$O$J$$(B -$B$+$H?4G[$7$F$$$k$H$-$KLr$KN)$A$^$9!#Nc$($P!"5-;v$,(B 1854 $BG/$KEj9F$5$l$?$H$J$C(B -$B$F$$$k$H$7$^$7$g$&!#$7$+$7!"$=$N$h$&$J;v$O(B@emph{$B40A4$K(B}$BIT2DG=$G$9!#;d$,(B -$B?.MQ$G$-$^$;$s$+!)(B *$B$/$9$/$9(B($B>P(B)* - -@end table - -$B<+F0E*$K9%$`=q<0$GF|IU$rI=<($9$kJ}K!$O(B @xref{Customizing Articles} $B$r;2(B -$B>H$7$F2<$5$$!#(B - - -@node Article Signature -@subsection $B5-;v$N=pL>(B -@cindex signatures -@cindex article signature - -@vindex gnus-signature-separator -$B$=$l$>$l$N5-;v$O#2$D$NItJ,$KJ,$1$i$l$^$9!=!=8+=P$7(B (header) $B$HK\BN(B -(body) $B$G$9!#K\BN$O=pL>ItJ,$HJ8>OItJ,$KJ,$1$i$l$^$9!#$I$l$,=pL>$H$_$J$5$l(B -$B$k$+$r7h$a$kJQ?t$O(B @code{gnus-signature-separator} $B$G$9!#$3$l$OIaDL$O(B -son-of-RFC 1036 $B$G;X<($5$l$F$$$kI8=`$N(B @samp{^-- $} $B$G$9!#$7$+$7!"B?$/$N?M(B -$B$,I8=`$G$J$$=pL>J,N%$rMQ$$$^$9$N$G!"$3$NJQ?t$O0l$D0l$D;n$5$l$k!"@55,I=8=$N(B -$B%j%9%H$G$"$k$3$H$b$G$-$^$9!#!JC5:w$OK\BN$N:G8e$+$i;O$a$X$H$J$5$l$^$9!#!K$h(B -$B$/$"$j$=$&$JCM$O!'(B - -@lisp -(setq gnus-signature-separator - '("^-- $" ; $BI8=`(B - "^-- *$" ; $BIaDL$N2u$7J}(B - "^-------*$" ; $BB?$/$N?M$OD9!$H$_$J$5$l$k$+$X$N@)8B$rDs6!$7$^(B -$B$9!#(B - -@enumerate -@item -$B$3$l$,@0?t$G$"$l$P!"=pL>$O$3$N@0?t$h$j!JJ8;z$G!KD9$/$J$C$F$$$F$O$$$1$^$;$s!#(B -@item -$B$3$l$,IbF0>.?tE@?t$G$"$l$P!"=pL>$O$=$N?t;z$h$j!J9T$G!KD9$/$J$C$F$$$F$O$$$1(B -$B$^$;$s!#(B -@item -$B$3$l$,4X?t$G$"$l$P!"$=$N4X?t$O0z?t$J$7$G8F$P$l!"$=$l$,(B @code{nil} $B$rJV$;(B -$B$P!"%P%C%U%!$K$O=pL>$,$"$j$^$;$s!#(B -@item -$B$3$l$,J8;zNs$G$"$l$P!"$=$l$O@55,I=8=$H$7$F;H$o$l$^$9!#$b$7$=$l$,9gCW$9$l(B -$B$P!"$=$NEv$NJ8;zNs$O=pL>$G$O$"$j$^$;$s!#(B -@end enumerate - -$B$3$NJQ?t$OMWAG$,>e$K5s$2$i$l$?7?$N%j%9%H$G$"$k;v$b$G$-$^$9!#$3$l$ONc$G$9!'(B - -@lisp -(setq gnus-signature-limit - '(200.0 "^---*Forwarded article")) -@end lisp - -$B$3$l$O=pL>J,N%J*$N8e$K(B 200 $B$rD6$($k9T$+!"=pL>J,N%J*$N8e$NJ8>O$,@55,I=8=(B -@samp{^---*Forwarded article} $B$K9gCW$9$l$P!"7k6I$=$l$O=pL>$G$O$J$$$H$$$&;v(B -$B$G$9!#(B - - -@node Article Commands -@section $B5-;vL?Na(B - -@table @kbd - -@item A P -@cindex PostScript -@cindex printing -@kindex A P $B!J35N,!K(B -@vindex gnus-ps-print-article -@findex gnus-summary-print-article -$B5-;v%P%C%U%!$N%]%9%H%9%/%j%W%H(B (PostScript) $B%$%a!<%8$r:n@.$7$F0u:~$7$^$9(B -(@code{gnus-summary-print-article})$B!#(B@code{gnus-ps-print-hook} $B$,%P%C%U%!(B -$B$r0u:~$9$kD>A0$KJ}$GF0:n$7$^(B -$B$9!#8el9g$O!"$9$Y$F$N35N,9T$,0l9T0l9TJB$SBX$($i$l$^$9!#A0l9g$O!"(B -$B:,K\$H:,K\$r4pK\$H$7$FJB$SBX$($i$l!"$=$l$O$"$J$?$,5a$a$F$$$k;v$H$O0[(B -$B$J$C$F$$$k$+$b$7$l$^$;$s!#%9%l%C%I$r;H$&;v$r@Z$jBX$($k$K$O(B @kbd{T T} $B$r(B -$BBG$C$F$/$@$5$$(B (@pxref{Thread Commands})$B!#(B - - -@node Finding the Parent -@section $B?F5-;v$rC5$9(B -@cindex parent articles -@cindex referring articles - -@table @kbd -@item ^ -@kindex ^ $B!J35N,!K(B -@findex gnus-summary-refer-parent-article -$B8=:_$N5-;v$N?F5-;v$rFI$_$?$/$F!"$=$l$,35N,%P%C%U%!$KI=<($5$l$F$$$J$$$/$F(B -$B$b!"$*$=$i$/$=$l$O2DG=$G$7$g$&!#$H$$$&$N$O!"8=:_$N%0%k!<%W$,(B @sc{nntp} -$B$GC5n$5$l$F$$$J$$>e!"8=:_$N5-;v$N(B -@code{References} $B$,$V$A2u$5$l$F$$$J$1$l$P!"$?$@!"(B@kbd{^} $B$+(B @kbd{A r} -$B$r2!$;$PNI$$$@$1$G$9(B (@code{gnus-summary-refer-parent-article})$B!#$b$7A4(B -$B$F$,>e/$7;~4V$,$+$+(B -$B$j$^$9!#$b$7!"$3$l$r$7$P$7$P9T$&$N$G$"$l$P!"(B -@code{gnus-fetch-old-headers} $B$r(B @code{invisible} $B$K@_Dj$9$k$3$H$r9M$($?(B -$B$[$&$,NI$$$G$7$g$&(B (@pxref{Filling In Threads})$B!#$3$l$OIaDL$O;k3PE*$J8z(B -$B2L$O$"$j$^$;$s$,!"$3$NL?Na$NF0:n$r$+$J$jB.$/$9$k$G$7$g$&!#$b$A$m$s!"%0%k!<(B -$B%W$KF~$k$N$O>/$7CY$/$J$j$^$9!#(B - -@vindex gnus-refer-thread-limit -$BJQ?t(B @code{gnus-refer-thread-limit} $B$O$3$NL?Na$re=q$-$9$k;v$,$G$-$^$9!#(B - -@item M-^ $B!J35N,!K(B -@findex gnus-summary-refer-article -@kindex M-^ $B!J35N,!K(B -@cindex Message-ID -@cindex fetching by Message-ID -$B$I$N%0%k!<%W$KB0$7$F$$$k$+$K4X$o$i$:!"G$0U$N5-;v$r(B @sc{nntp} $B%5!<%P!<$K(B -$B?R$M$k;v$,$G$-$^$9!#(B@kbd{M-^} (@code{gnus-summary-refer-article}) $B$O(B -@code{Message-ID}$B!"$=$l$O$"$ND9$/!"$J$+$J$+FI$`;v$N$G$-$J$$(B -@samp{<38o6up$6f2@@hymir.ifi.uio.no>} $B$N$h$&$J;2>H$r$"$J$?$K?R$M$^$9!#(B -$B$"$J$?$O$9$Y$F$r@53N$KBG$A9~$^$J$1$l$P$J$j$^$;$s!#;DG0$J$,$i!"$"$$$^$$$J(B -$B8!:w$O$G$-$J$$$N$G$9!#(B -@end table - -$B%K%e!<%9$G$J$$A*BrJ}K!$+$i(B @code{Message-ID} $B$Ge=q$-$9$k;v$,$G$-(B -$B$^$9!#(B - -@vindex gnus-refer-article-method -$B$b$7$"$J$?$NFI$s$G$$$k%0%k!<%W$,(B @code{Message-ID} $B$G$Nl9g!"(B -@code{gnus-refer-article-method} $B$r(B @sc{nntp} $B$K@_Dj$9$k;v$,$G$-$^$9!#$*$=(B -$B$i$/!"$"$J$?$,2qOC$7$F$$$k(B @sc{nntp} $B%5!<%P!<$,$"$J$?$NFI$s$G$$$k%9%W!<%k(B -$B$r99?7$7$F$$$k$HHs>o$KNI$$$G$7$g$&!#$7$+$7!"$=$l$O$I$&$7$F$bI,MW$J$o$1$G$O(B -$B$"$j$^$;$s!#(B - -$B$[$H$s$I$N%a!<%k%P%C%/%(%s%I$O(B @code{Message-ID} $B$G$N$N$b$N$O;~4V$,$+$+$j$9$.$^$9!#!K(B@code{nnmh} -$B$G$OA4$/IT2DG=$G$9!#(B - -@node Alternative Approaches -@section $BBeBX/$7$NA*Br;h$rM?$($F$"$j$^$9!#(B - -@menu -* Pick and Read:: $B$^$:!"5-;v$K0u$rIU$1$F!"$=$l$+$iFI$`(B -* Binary Groups:: $B$9$Y$F$N5-;v$r<+F0(B-$BI|9f2=$9$k(B -@end menu - - -@node Pick and Read -@subsection $BA*$s$GFI$`(B -@cindex pick and read - -$B$$$/$D$+$N%K%e!<%9%j!<%@!/$7(B -$B$N%W%m%;%90uL?Na$,#1BG80L?Na$K$J$j!"35N,%P%C%U%!$X@Z$jBX$($k$?$a$NDI2CL?Na(B -$B$r(B1$B$DDs6!$7$^$9!#(B - -$B$3$l$,(B pick mode $B$r;H$C$?$H$-$K;HMQ2DG=$J%-!<$G$9!'(B - -@table @kbd -@item . -@kindex . $B!JA*Br!K(B -@findex gnus-pick-article-or-thread -$B8=:_$N9T$N5-;v$+%9%l%C%I$rA*Br$7$^$9(B -(@code{gnus-pickd-article-or-thread})$B!#$b$7JQ?t(B -@code{gnus-thread-hide-subtree} $B$,(B true $B$G$"$l$P!"$3$N%-!<$O%9%l%C%I$N:G(B -$B=i$N5-;v$G;H$o$l$?$H$-$O%9%l%C%IA4BN$rA*Br$7$^$9!#$=$&$G$J$1$l$P!"$=$l$O(B -$B$=$N5-;v$@$1$rA*Br$7$^$9!#$b$7?tCM@\F,0z?t$rM?$($i$l$l$P$=$N%9%l%C%I$+5-(B -$B;v$X$H@8$s$G$$$-!"$=$l$rA*Br$7$^$9!#(B ($B9T?t$OIaDL$O35N,A*Br9T$N:G=i$KI=<((B -$B$5$l$F$$$^$9!#(B) - -@item SPACE -@kindex SPACE$B!JA*Br!K(B -@findex gnus-pick-next-page -$B35N,%P%C%U%!$r0l%Z!<%8l9g$O$=$l$O5-;v$@$1$rL$A*Br$K$7$^$9!#$=$N9T$K$"$k%9%l%C%I$+5-;v$rL$A*Br$K$9$k$?$a$K$3$N%-!<$K?tCM@\F,0z?t$rM?$($k;v$,$G$-$^$9!#(B - -@item RET -@kindex RET $B!JA*Br!K(B -@findex gnus-pick-start-reading -@vindex gnus-pick-display-summary -$BA*Br$5$l$?5-;v$rFI$_;O$a$^$9(B (@code{gnus-pick-start-reading})$B!#@\F,0z?t(B -$B$rM?$($i$l$l$P!"$^$:$9$Y$F$NL$A*Br5-;v$K4{FI$N0u$rIU$1$^$9!#(B -@code{gnus-pick-display-summary} $B$,(B @code{nil} $B$G$J$$$H!"35N,%P%C%U%!$O(B -$BFI$s$G$$$k4V$bI=<($5$l$^$9!#(B - -@end table - -$BA4$F$NIaDL$N35N,%b!<%IL?Na$OA*Br%b!<%I(B (pick-mode)$B$G$b;HMQ2DG=$G$9$,!"(B -@kbd{u} $B$ONc30$G$9!#$7$+$7!"F1$84X?t(B -@code{gnus-summary-tick-article-forward} $B$K3d$jEv$F$i$l$F$$$k(B @kbd{!} $B$r(B -$B;H$&;v$,$G$-$^$9!#(B - -$B$3$l$,NI$$9M$($@$H;W$&$N$G$"$l$P!"/$70c$$$^$9!#$=$l$>$l$N9T$N(B -$B:G=i$K9T?t$,I=<($5$l$^$9!#(B Pick $B%b!<%I$N9T$NMM<0$OJQ?t(B -@code{gnus-summary-pick-line-format} $B$G@)8f$5$l$^$9(B (@pxref{Formatting -Variables})$B!#$3$l$O(B @code{gnus-summary-line-format} $B$HF1$8MM<0;XDj$r/$7$"$j$^$9!'(B - -@table @code -@item gnus-tree-mode-hook -@vindex gnus-tree-mode-hook -$B$9$Y$F$NLZ%b!<%I%P%C%U%!$GH$7$F$/$@$5$$!#(B - -@item gnus-selected-tree-face -@vindex gnus-selected-tree-face -$BLZ%P%C%U%!$GA*Br$5$l$?5-;v$r%O%$%i%$%H$9$k$?$a$K;H$o$l$k%U%'%$%9$G$9!#%G%#(B -$B%U%)%k%H$G$O(B @code{modeline} $B$G$9!#(B - -@item gnus-tree-line-format -@vindex gnus-tree-line-format -$BLZ$N@a$N$?$a$N%U%)!<%^%C%HJ8;zNs$G$9!#$G$b$3$NL>A0$O>/$78m$C$?L>>N$G$9!=!=(B -$B$=$l$O9T$G$O$J$/!"$?$@@a$rDj5A$9$k$@$1$G$9!#%G%#%U%)%k%H$NCM$O(B -@samp{%(%[%3,3n%]%)} $B$G!"$=$l$OEj9FA0$N:G=i$N#3J8;z$rI=<($7$^$9!#$9(B -$B$Y$F$N@a$,F1$8D9$5$G$"$k$N$O=EMW$G$9$N$G!"(B@samp{%4,4n} $B$N$h$&$J;XDj$r(B -@emph{$B;H$o$J$1$l$P$J$i$J$$(B} $B$N$G$9!#(B - -$BM-8z$J;XDj$O!'(B - -@table @samp -@item n -$BEj9FA0!#(B -@item f -@code{From} $BMs!#(B -@item N -$B5-;v$NHV9f!#(B -@item [ -$B3+$-3g8L!#(B -@item ] -$BJD$83g8L!#(B -@item s -$BI=Bj!#(B -@end table - -@xref{Formatting Variables}$B!#(B - -$BI=<($K4XO"$7$?JQ?t$O!'(B - -@table @code -@item gnus-tree-brackets -@vindex gnus-tree-brackets -$B$3$l$O!XK\Ev$N!Y5-;v$H!X$^$P$i5-;v!Y$K0c$$$rIU$1$k$?$a$K;H$o$l$^$9!#(B -$BMM<0$O(B -@var{(($BK\Ev$N3+(B . $BK\Ev$NJD(B) ($B$^$P$i3+(B . $B$^$P$iJD(B) ($B56$N3+(B . $B56$NJD(B))} -$B$H$J$C$F$$$F!"%G%#%U%)%k%H$O(B -@code{((?[ . ?]) (?( . ?)) (?@{ . ?@}) (?< . ?>))} $B$G$9!#(B - -@item gnus-tree-parent-child-edges -@vindex gnus-tree-parent-child-edges -$B$3$l$O?F$N@a$r;R$K@\B3$9$k$?$a$K;H$o$l$kJ8;z$r4^$s$@%j%9%H$G$9!#%G%#%U%)(B -$B%k%H$O(B @code{(?- ?\\ ?|)} $B$G$9!#(B - -@end table - -@item gnus-tree-minimize-window -@vindex gnus-tree-minimize-winodw -$B$b$7$3$NJQ?t$,(B @code{nil} $B$G$J$$$H!"B>$N(B gnus $B%&%#%s%I%&$,$b$C$H>l=j$r.$5$/$7$^$9!#$b$7$3$NJQ?t$,?t;z(B -$B$G$"$k$H!"LZ%P%C%U%!$O$=$N?t;z$h$jBg$-$/$J$k;v$O$"$j$^$;$s!#%G%#%U%)%k%H(B -$B$O(B @code{t} $B$G$9!#%U%l!<%`$G$$$/$D$+$N%&%#%s%I%&$,2#$KJB$s$GI=<($5$l$F$$(B -$B$F!"LZ%P%C%U%!$,$=$N$&$A$N0l$D$G$"$k>l9g!"LZ%&%#%s%I%&$r:G>.2=$9$k$3$H$O(B -$B$=$NNY$KI=<($5$l$F$$$k$9$Y$F$N%&%#%s%I%&$NBg$-$5$rJQ99$9$k;v$KCm0U$7$F$/(B -$B$@$5$$!#(B - -@item gnus-generate-tree-function -@vindex gnus-generate-tree-function -@findex gnus-generate-horizontal-tree -@findex gnus-generate-vertical-tree -$BLZ%P%C%U%!(B (vertical tree buffer) $B$GI=<($5$l$?$b$N$G$9!'(B - -@example -@{***@} - |--------------------------\-----\-----\ -(***) [Bjo] [Gun] [Gun] - |--\-----\-----\ | -[odd] [Jan] [odd] (***) [Jor] - | | |--\ -[Gun] [Eri] [Eri] [odd] - | - [Paa] -@end example - -$B$b$7?eJ?LZ$r;H$C$F$$$k$N$J$i!"35N,%P%C%U%!$GLZ$rNY$j9g$o$;$GI=<($G$-$l$P(B -$B4r$7$$$G$7$g$&!#C$(5n$k(B -$B$H$$$&;v$G$9!#(B - -@item B DEL -@kindex B DEL $B!J35N,!K(B -@findex gnus-summary-delete-article -@c @icon{gnus-summary-mail-delete} -$B%a!<%k5-;v$r:o=|$7$^$9!#$3$l$O!X$"$J$?$N%G%#%9%/$+$i:#$+$i1J1s$K:o=|$7$F!"(B -$BFsEY$HLa$i$J$$!Y$N!X:o=|!Y$G$9!#Cm0U$7$F;H$C$F$/$@$5$$(B -(@code{gnus-summary-delete-article})$B!#(B - -@item B m -@kindex B m $B!J35N,!K(B -@cindex move mail -@findex gnus-summary-move-article -$B$"$k%a!<%k%0%k!<%W$+$iJL$N$H$3$m$X5-;v$r0\F0$7$^$9(B -(@code{gnus-summary-move-article})$B!#(B - -@item B c -@kindex B c $B!J35N,!K(B -@cindex copy mail -@findex gnus-summary-copy-article -@c @icon{gnus-summary-mail-copy} -$B$"$k%0%k!<%W!J%a!<%k%0%k!<%W$dB>$N$b$N!K$+$i%a!<%k%0%k!<%W$K5-;v$rJ#@=$7$^(B -$B$9(B (@code{gnus-summary-copy-article})$B!#(B - -@item B B -@kindex B B $B!J35N,!K(B -@cindex crosspost mail -@findex gnus-summary-crosspost-article -$B8=:_$N5-;v$rB>$N%0%k!<%W$K%/%m%9%]%9%H$7$^$9(B -(@code{gnus-summary-crosspost-article})$B!#$3$l$OB>$N%0%k!<%W5-;v$N?7$7$$J#(B -$B@=$r:n@.$7!"5-;v$N(B Xref $BMs$bE,@Z$K99?7$5$l$^$9!#(B - -@item B i -@kindex B i $B!J35N,!K(B -@findex gnus-summary-import-article -$BG$0U$N%U%!%$%k$r8=:_$N%a!<%k%0%k!<%W$K$H!"(B@code{From} $BMs(B -$B$H(B @code{Subject} $BMs$NF~NO$rB%$5$l$^$9!#(B - -@item B r -@kindex B r $B!J35N,!K(B -@findex gnus-summary-respool-article -$B%a!<%k5-;v$r%9%W!<%k$7D>$7$^$9(B (@code{gnus-summary-move-article})$B!#(B -@code{gnus-summary-respool-default-method} $B$,:F%9%W!<%k$9$k$H$-$N%G%#%U%)(B -$B%k%H$NA*BrJ}K!$H$7$F;HMQ$5$l$^$9!#$3$NJQ?t$O%G%#%U%)%k%H$G(B @code{nil} $B$G!"(B -$B$3$l$O8=:_$N%0%k!<%W$NA*BrJ}K!$,Be$o$j$K;H$o$l$k$H$$$&;v$G$9!#(B - -@item B w -@itemx e -@kindex B w $B!J35N,!K(B -@kindex e $B!J35N,!K(B -@findex gnus-summary-edit-article -@kindex C-c C-c $B!J5-;v!K(B -$B8=:_$N5-;v$rJT=8$7$^$9(B (@code{gnus-summary-edit-article})$B!#JT=8$r=*N;$7(B -$B$FJQ99$r1J1s$K$9$k$?$a$K!"(B@kbd{C-c C-c} $B$rBG$A$^$9!#$b$7L?Na(B -@kbd{C-c C-c} $B$K?tCM@\F,0z?t$rM?$($k$H!"(Bgnus $B$O5-;v$r:F%O%$%i%$%H$7$^$;(B -$B$s!#(B - -@item B q -@kindex B q $B!J35N,!K(B -@findex gnus-summary-respool-query -$B$b$75-;v$r:F%9%W!<%k$7$?$$$H$-$O!":F%9%W!<%k$r$9$kA0$K$I$N%0%k!<%W$K5-;v(B -$B$,0\$k$+$K6=L#$,$"$k$G$7$g$&!#$3$NL?Na$G$=$l$,$o$+$j$^$9(B -(@code{gnus-summary-respool-query})$B!#(B - -@item B t -@kindex B t ($B35N,(B) -@findex gnus-summary-respool-trace -$BF1MM$K!"$3$NL?Na$O:FN/$a9~$_$r$9$k$H$-$K;H$o$l$?A4$F$NFC5iJ,3dJ}<0$r!"$b(B -$B$7$=$l$,$"$l$PI=<($7$^$9(B (@code{gnus-summary-respool-trace})$B!#(B - -@item B p -@kindex B p $B!J35N,!K(B -@findex gnus-summary-article-posted-p -$B0lIt$N?M$O$"$J$?$NEj9F$X$N%U%)%m!<%"%C%W$r$9$k$H$-$K!"!X?F@Z$J!YJ#@=$rAw$k(B -$B798~$,$"$j$^$9!#$3$l$i$OIaDL$O$=$3$K(B @code{Newsgroups} $BMs$,IU$$$F$$$k$N$G(B -$B$9$,!"$$$D$b$=$&$G$"$k$H$O8B$j$^$;$s!#$3$NL?Na(B -(@code{gnus-summary-article-posted-p}) $B$O8=:_$N5-;v$r$"$J$?$N%K%e!<%9%5!<(B -$B%P!<$+$i!J$H$$$&$h$j$O!"$`$7$m(B @code{gnus-refer-article-method} $B$d(B -@code{gnus-select-method} $B$+$i!KpJs;X8~$NL?Na!#(B -* Searching for Articles:: $BJ#?t5-;vL?Na!#(B -* Summary Generation Commands:: $B35N,%P%C%U%!$N!J:F!K:n@.!#(B -* Really Various Summary Commands:: $B$"$N$d$C$+$$$JB>$KE,9g$7$J$$L?Na!#(B -@end menu - -@table @code -@vindex gnus-summary-mode-hook -@item gnus-summary-mode-hook -$B35N,%b!<%I%P%C%U%!$r:n@.$9$k$H$-$K$3$N%U%C%/$,8F$P$l$^$9!#(B - -@vindex gnus-summary-generate-hook -@item gnus-summary-generate-hook -$B$3$l$O%9%l%C%I:n@.$H35N,%P%C%U%!:n@.$NA0$Ko$KJXMx$G$9!#$3$N%U%C%/$O$[$H$s$I$N35N,%P%C%U%!(B -$BJQ?t$,@_Dj$5$l$?8e$K8F$P$l$^$9!#(B - -@vindex gnus-summary-prepare-hook -@item gnus-summary-prepare-hook -$B$=$l$O35N,%P%C%U%!$,:n@.$5$l$?8e$K8F$P$l$^$9!#Nc$($P!"$=$l$O2?$+B>$N$N5-;v$H(B -$BF1$8$h$&$KI=<($7$^$9!#$3$NJQ?t$,(B @code{t} $B$G$"$k$H!"$=$l$O5-;v$rI=<($7$^$;(B -$B$s(B---$B:G=i$+$iB8:_$7$J$+$C$?$+$N$h$&$K!#(B - -@end table - - -@node Summary Group Information -@subsection $B35N,%0%k!<%W>pJs(B - -@table @kbd - -@item H f -@kindex H f $B!J35N,!K(B -@findex gnus-summary-fetch-faq -@vindex gnus-grou-faq-directory -$B8=:_$N%0%k!<%W$N(B FAQ$B!J(Bfrequently asked questions$B!JIQHK$K$5$l$kl9g$O!"$3$NL?Na$K@\F,0z?t$rM?$($k;v$G$$$m$$$m$J%5%$%H(B (site) $B$+$iA*$V;v$,(B -$B$G$-$^$9!#$*$=$i$/(B @code{ange-ftp} $B$b$7$/$O(B @code{efs} $B$,%U%!%$%k$No$KC;$$5-=R$rM?$($^$9(B -(@code{gnus-summary-describe-briefly})$B!#(B - -@item H i -@kindex H i $B!J35N,!K(B -@findex gnus-info-find-node -Gnus $B$N(B info $B$N@a(B (node) $B$K0\F0$7$^$9(B (@code{gnus-info-find-node})$B!#(B -@end table - - -@node Searching for Articles -@subsection $B5-;v$rC5$9(B - -@table @kbd - -@item M-s -@kindex M-s $B!J35N,!K(B -@findex gnus-summary-search-article-forward -$BD>8e$K$"$kA4$F$N5-;v$r@55,I=8=$G8!:w$7$^$9(B -(@code{gnus-summary-search-article-forward})$B!#(B - -@item M-r -@kindex M-r $B!J35N,!K(B -@findex gnus-summary-search-article-backward -$BA0$K$"$kA4$F$N5-;v$r@55,I=8=$G8!:w$7$^$9(B -(@code{gnus-summary-search-article-backward})$B!#(B - -@item & -@kindex & $B!J35N,!K(B -@findex gnus-summary-execute-command -$B$3$NL?Na$O$"$J$?$K%X%C%@!l9g(B -$B$K$N5-;v$N=8$^$j$G$"$k$J$i$P!JNc$($P!"E&MW(B (digest)$B!K!"(B -$B$=$N$h$&$J5-;v$G$G$-$F$$$k%0%k!<%W$KF~$k$?$a$K$3$NL?Na$r;H$&$+$b$7$l$^$;$s(B -(@code{gnus-summary-enter-digest-group})$B!#(BGnus $B$O$3$NL?Na$K@\F,0z?t$rM?$((B -$B$J$$8B$j!"$I$N$h$&$J7?$N5-;v$,8=:_I=<($5$l$F$$$k$+$r?dB,$7$h$&$H$7!"$=$l$O(B -$B6/@)E*$K!XE&MW!Y$H$$$&2r$NMM<0$+$i$J$kB>$N%a%C%;!<(B -$B%8$N=89g$G$"$C$?$H$-$O!"(B@kbd{C-d} $B$H$9$k$3$H$K$h$j$b$C$HJXMx$JJ}K!$G$=$l$i(B -$B$N%a%C%;!<%8$rFI$`;v$,$G$-$k$h$&$K$J$j$^$9!#(B - -@item M-C-d -@kindex M-C-d $B!J35N,!K(B -@findex gnus-summary-read-document -$B$3$NL?Na$O>e$N$b$N$KHs>o$K;w$F$$$^$9$,!"$$$/$D$+$NJ8=q$r0l$D$NBg!<$-$$%0(B -$B%k!<%W$K=8$a$^$9(B (@code{gnus-summary-read-read-document})$B!#$=$l$O$$$/$D(B -$B$+$N(B @code{nndoc} $B%0%k!<%W$r$=$l$>$l$NJ8=q$N$?$a$K(B $B3+$-!"$=$l$+$i$3$l$i(B -$B$N(B @code{nndoc} $B%0%k!<%W$N>e$K(B @code{nnvirtual} $B%0%k!<%W$r3+$/;v$K$h$C$F(B -$B$3$N;v$r2DG=$K$7$F$$$^$9!#$3$NL?Na$O%W%m%;%9(B/$B@\F,0z?t$N=,47$rM}2r$7$^$9(B -(@pxref{Process/Prefix})$B!#(B - -@item C-t -@kindex C-t $B!J35N,!K(B -@findex gnus-summary-togle-truncation -$B35N,9T$N@ZCG$r@Z$jBX$($^$9(B (@code{gnus-summary-toggle-truncation})$B!#$3$l(B -$B$O$*$=$i$/35N,%P%C%U%!$N9TCf1{I=<(4X?t$r:.Mp$5$;$^$9$N$G!"5-;v$rFI$s$G$$(B -$B$k4V$K@ZCG$r@Z$C$F$$$k$N$ONI$$9M$($G$O$J$$$G$7$g$&!#(B - -@item = -@kindex = $B!J35N,!K(B -@findex gnus-summary-expand-window -$B35N,%P%C%U%!$N%&%#%s%I%&$r3HBg$7$^$9(B -(@code{gnus-summary-expand-window})$B!#@\F,0z?t$rM?$($i$l$l$P!"(B@code{$B5-;v(B} -$B%&%#%s%I%&$r3HBg$7$^$9!#(B - -@item M-C-e -@kindex M-C-e $B!J35N,!K(B -@findex gnus-summary-edit-parameters -$B8=:_$N%0%k!<%W$N%0%k!<%W$NG^2pJQ?t(B (parameter) (@pxref{Group -Parameters}) $B$rJT=8$7$^$9(B (@code{gnus-summary-edit-parameters})$B!#(B - -@end table - - -@node Exiting the Summary Buffer -@section $B35N,%P%C%U%!$rH4$1$k(B -@cindex summary exit -@cindex exiting groups - -$BIaDL$O35N,%P%C%U%!$+$iH4$1$k$H!"%0%k!<%W$NA4$F$N>pJs$r99?7$7$F%0%k!<%W%P%C(B -$B%U%!$KLa$j$^$9!#(B - -@table @kbd - -@item Z Z -@itemx q -@kindex Z Z (Summary) -@findex q $B!J35N,!K(B -@findex gnus-summary-exit -@vindex gnus-summary-exit-hook -@vindex gnus-summary-prepare-exit-hook -@c @icon{gnus-summary-exit} -$B8=:_$N%0%k!<%W$r=P$F!"%0%k!<%W$NA4$F$N>pJs$r99?7$7$^$9(B -(@code{gnus-summary-exit})$B!#H4$1=P$k$?$a$N$?$$$F$$$N;v$r$9$kA0$K(B -@code{gnus-summary-prepare-exit-hook} $B$,8F$P$l!"$=$l$O%G%#%U%)%k%H$G(B -@code{gnus-summary-expire-articles} $B$r8F$S$^$9!#H4$1=P$k2aDx$rDI$($?8e$K(B -@code{gnus-summary-exit-hook} $B$,8F$P$l$^$9!#(B($BL$FI$N(B) $B%0%k!<%W$,;D$C$F$$(B -$B$J$$$H$-$K%0%k!<%W%b!<%I$KLa$k$H$-$K(B -@code{gnus-group-no-more-groups-hook} $B$,pJs$b99?7$;$:$K8=:_$N%0%k!<%W$rH4$1=P$^$9(B -(@code{gnus-summary-exit-no-update})$B!#(B - -@item Z c -@itemx c -@kindex Z c $B!J35N,!K(B -@kindex c $B!J35N,!K(B -@findex gnus-summary-catchup-and-exit -@c @icon{gnus-summary-catchup-and-exit} -$B%0%k!<%W$NA4$F$NJ]N1$G$J$$5-;v(B (unticked article) $B$K4{FI$N0u$rIU$1$F!"$=(B -$B$l$+$iH4$1$^$9(B (@code{gnus-summary-catchup-and-exit})$B!#(B - -@item Z C -@kindex Z C $B!J35N,!K(B -@findex gnus-summary-catchup-all-and-exit -$BJ]N15-;v$b4^$a$F!"A4$F$N5-;v$K4{FI$N0u$rIU$1$F!"$=$l$+$iH4$1$^$9(B -(@code{gnus-summary-catchup-all-and-exit})$B!#(B - -@item Z n -@kindex Z n $B!J35N,!K(B -@findex gnus-summary-catchup-and-goto-next-group -$BA4$F$N5-;v$K4{FI$N0u$rIU$1$F$7$^$9(B -(@code{gnus-summary-reselect-current-group})$B!#$b$7@\F,0z?t$rM?$($i$l$l$P!"(B -$B4{FI$HL$FI$NN>J}$NA4$F$N5-;v$rA*Br$7$^$9!#(B - -@item Z G -@itemx M-g -@kindex Z G $B!J35N,!K(B -@kindex M-g $B!J35N,!K(B -@findex gnus-summary-rescan-group -@c @icon{gnus-summary-mail-get} -$B%0%k!<%W$rH4$1!"%0%k!<%W$N?7$7$$5-;v$rD4$Y!"%0%k!<%W$rA*Br$7$^$9(B -(@code{gnus-summary-rescan-group})$B!#$b$7@\F,0z?t$rM?$($i$l$l$P!"4{FI$HL$(B -$BFI$NN>J}$NA4$F$N5-;v$rA*Br$7$^$9!#(B - -@item Z N -@kindex Z N $B!J35N,!K(B -@findex gnus-summary-next-group -$B%0%k!<%W$rH4$1$F!"A0$r(B -@samp{*Dead Summary ... *} $B$N$h$&$J$b$N$KJQ99$7!"(B -@code{gnus-dead-summary-mode} $B$H8F$P$l$k%^%$%J!<%b!<%I$rF3F~$7$^$9!#:#$d!"(B -$B$=$N%P%C%U%!$K@Z$jBX$($l$P!"A4$F$N%-!<$,4X?t(B -@code{gnus-summary-wake-up-the-dead} $B$K3d$jEv$F$i$l$F$$$k$3$H$K5$IU$/$G$7$g(B -$B$&!#;`$s$@35N,%P%C%U%!(B (dead summary buffer) $B$G$I$l$+$N%-!<$rC!$/;v$H!"@8(B -$B$-$?IaDL$N35N,%P%C%U%!$K$J$k$G$7$g$&!#(B - -$B;`$s$@35N,%P%C%U%!$OF1;~$K0l$D$7$+B8:_$9$k;v$O$G$-$^$;$s!#(B - -@vindex gnus-use-cross-reference -$B35N,%P%C%U%!$rH4$1=P$k$H!"8=:_$N%0%k!<%W$N%G!<%?$O99?7$5$l$^$9!J$I$N5-;v$r(B -$BFI$s$G!"$I$N5-;v$KJVEz$7$?$+!"$J$I$J$I!#!K$b$7JQ?t(B -@code{gnus-use-cross-reference} $B$,(B @code{t} $B$G$"$k$H!J$=$l$,%G%#%U%)%k%H$G(B -$B$9!K!"$=$N%0%k!<%W$KAj8_;2>H$5$l$?(B (cross referenced) $B5-;v$O4{FI$N0u$,IU$-!"(B -$B$=$l$,Aj8_Ej9F(B (cross post) $B$5$l$?B>$N9XFI$7$F$$$k%0%k!<%W$G$b4{FI$N0u$,IU(B -$B$-$^$9!#$3$NJQ?t$,(B @code{nil} $B$G$b(B @code{t} $B$G$J$1$l$P!"5-;v$O9XFI$HL$9XFI(B -$B$NN>J}$N%0%k!<%W$G4{FI$N0u$,IU$-$^$9(B (@pxref{Crosspost Handling})$B!#(B - - -@node Crosspost Handling -@section $BAj8_Ej9F$N07$$(B - -@cindex velveeta -@cindex spamming -$BAj8_Ej9F(B (cross post) $B$5$l$?5-;v$K4{FI$N0u$rIU$1$k;v$O!"F1$85-;v$r#22s0J>e(B -$BFI$^$J$$$G$9$`$H$$$&;v$rJ]>Z$7$^$9!#$b$A$m$s!"$@$l$+$,$=$l$r$$$/$D$+$N%0%k!<(B -$B%W$KJL!9$KEj9F$7$J$$8B$j$O!#F1$85-;v$r$$$/$D$+$N%0%k!<%W$KEj9F$9$k;v!JAj8_(B -$BEj9F$G$J$/$F!K$O(B @dfn{spamming} $B$H8F$P$l!"$"$J$?$O$=$N$h$&$JA~$`$Y$-HH:a$r(B -$B9T$&$b$N$K$KBP$7$F!"K!N'$K$h$C$FIT2w$J5-;v$rAw$k$3$H$,5AL3$E$1$i$l$F$$$^$9!#(B -spam $B$rA*JL$9$k$?$a$K!"(BNoCeM $BjAj8_Ej9F$KBP$7$FITK~$r8@$&$?$a$KL?Na(B -@code{gnus-summary-mail-crosspost-complaint} $B$r;H$&$3$H$5$($G$-$^$9!#(B - -@cindex cross-posting -@cindex Xref -@cindex @sc{nov} -$BAj8_Ej9F$r(B gnus $B$,@5$7$/07$($J$$$h$&$K$J$k860x$N0l$D$O!"(B@sc{nov} $B9T$K(B -@code{Xref} $BMs$r4^$^$J$$!"(B@sc{xover}$B!J$3$l$OHs>o$KNI$$$G$9!"$H$$$&$N$O$=$l(B -$B$OB.EY$r$H$F$bB.$/$9$k$+$i$G$9!K$N;HMQ2DG=$J(B @sc{nntp} $B%5!<%P!<$r;H$C$F$$(B -$B$k$3$H$G$9!#$3$l$O320-$J$N$G$9$,!"$"$!!"Ha$7$$$+$J!"Hs>o$KNI$/$"$k;v$G$9!#(B -Gnus $B$O$"$J$?$,FI$s$@A4$F$N5-;v$K(B @code{Xref} $B9T$rEPO?$9$k;v$G!"@5$7$$;v$r(B -$B$7$h$&(B $B$H$7$^$9$,!"5-;v$r:o=|$9$k$+!"FI$^$J$$$G4{FI$N0u$rIU$1$k$H!"(Bgnus $B$O(B -$B$3$l$i$N5-;v$K(B @code{Xref} $B$N9T$r$N$>$-$^$o$k5!2q$rF@$k;v$,L5$/!"Aj8_;2>H(B -$B5!9=$rMQ$$$k;v$,$G$-$^$;$s!#(B - -@cindex LIST overview.fmt -@cindex overview.fmt -$B$"$J$?$N(B @sc{nntp} $B%5!<%P!<$,$=$N354Q%U%!%$%k(B (overview file) $B$K(B -@code{Xref} $BMs$r4^$s$G$$$k$+$rD4$Y$k$K$O!"(B@samp{telnet your.nntp.server -nntp} $B$H$7$F!"(B@code{inn} $B%5!<%P!<$G(B @samp{More READER} $B$H$7!"$=$l$+$i(B -@samp{LIST overview.fmt} $B$H$9$k;v$r;n$7$F$/$@$5$$!#$3$l$OF0:n$7$J$$$G$7$g(B -$B$&$,!"$b$7F0:n$7$F!"o$KB.EY$r(B -$BCY$/$7$^$9!#(B - -$B$^!"?M@8$O$=$N$h$&$J$b$N$G$9!#(B - -$BBeBXH$7$F$/$@$5$$!#(B - - -@node Duplicate Suppression -@section $B=EJ#$NM^@)(B - -$B%G%#%U%)%k%H$G$O(B gnus $B$OAj8_Ej9F5!9=$rMxMQ$9$k;v$K$h$C$F!"F1$85-;v$r#22s0J(B -$B>eFI$^$J$$$h$&$K$7$h$&$H$7$^$9(B (@pxref{Crosspost Handling})$B!#$7$+$7!"$=$N(B -$BC1=c$G8z2LE*$JJ}K!$O!"$$$m$$$m$JM}M3$K$h$j!"K~B-$9$k7k2L$r$b$?$i$5$J$$$+$b(B -$BCN$l$^$;$s!#(B - -@enumerate -@item -@sc{nntp} $B%5!<%P!<$O(B @code{Xref} $BMs$N@8@.$K<:GT$9$k$+$bCN$l$^$;$s!#$3$l$O(B -$B0-$$;v$G!"$"$^$j5/$3$j$^$;$s!#(B - -@item -@sc{nntp} $B%5!<%P!<$O(B @file{.overview} $B%G!<%?%Y!<%9$K(B @code{Xref} $BMs$r4^$a(B -$B$k$N$K<:GT$9$k$+$bCN$l$^$;$s!#$3$l$O0-$$;v$G!"Hs>o$KNI$/$"$k;v$G$9!"$"$!Ha(B -$B$7$$!#(B - -@item -$BF1$8%0%k!<%W!J$b$7$/$O$$$/$D$+$N4XO"$7$?%0%k!<%W!K$r0c$C$?(B @sc{nntp} $B%5!<(B -$B%P!<$+$iFI$s$G$$$k$+$b$7$l$^$;$s!#(B - -@item -$B%0%k!<%W$KEj9F$5$l$?5-;v$H=EJ#$9$k%a!<%k$ru67$OB>$K$b$"$j$^$9$,!"$3$l$i#4$D$,$H$F$bNI$/(B -$B$"$k>u67$G$9!#(B - -$B$b$7!"K\Ev$K$b$7$b(B @code{Xref} $B$N07$$$K<:GT$7$?$i!"(B@dfn{$B=EJ#M^@)(B}$B$K@Z$jBX(B -$B$($k;v$r9M$($k$+$b$7$l$^$;$s!#$=$&$9$l$P!"(Bgnus $B$O$"$J$?$,FI$s$@A4$F$N5-;v(B -$B$+$=$&$G$J$1$l$P!"4{FI$N0u$,IU$$$?A4$F$N5-;v$N(B @code{Message-ID} $B$r5-21$7!"(B -$B$=$l$+$i!"KbK!$N$h$&$K!"$=$N8e$N$=$l$i$H=P2q$C$?A4$F$N>l9g$K!"4{FI$N0u$rIU(B -$B$1$^$9!=!=(B@emph{$BA4$F(B}$B$N%0%k!<%W$G!#$3$N5!9=$r;H$&$N$OHs>o$KHs8zN(E*$G$9$,!"(B -$B2aEY$KHs8zN($J$o$1$G$O$"$j$^$;$s!#$b$A$m$sF1$85-;v$r0l2s0J>eFI$`$[$&$,9%$^(B -$B$7$$$G$9!#(B - -$B=EJ#M^@)$O$"$^$jA!:Y$J$b$N$G$O$"$j$^$;$s!#$I$A$i$+$H$$$&$H!"BgDH$N$h$&$J$b(B -$B$N$G$9!#$=$l$OHs>o$KC1=c$JJ}K!$GF0:n$7$F$$$^$9!=!=$b$75-;v$K4{FI$N0u$rIU$1(B -$B$l$P!"$=$l$O$3$N(B Message-ID $B$r(B $B%-%c%C%7%e$K2C$($^$9!#uBV$G$O(B @code{nil} $B$G$9!#$7$+$7!"$3$l$OC10l(B -$B$N(B gnus $B$NA0$G$9!#%G%#%U%)%k%H$O(B -@file{~/News/suppression} $B$G$9!#(B -@end table - -$B2?EY$b(B gnus $B$r=*N;$7$F5/F0$9$k798~$,$"$k$N$G$"$l$P!"$*$=$i$/(B -@code{gnus-save-duplicate-list} $B$r(B @code{t} $B$K$9$k$N$ONI$$9M$($G$7$g$&!#(B -$B$b$7(B gnus $B$rB3$1$F2?=54V$bAv$i$;$F$*$/$N$G$"$l$P!"$=$l$r(B @code{nil} $B$K$9(B -$B$k$+$b$7$l$^$;$s!#0lJ}$G!"%j%9%H$rJ]B8$9$k;v$O5/F0$H=*N;$r$:$C$HCY$/$7$^(B -$B$9$N$G!"$h$/(B gnus $B$r=*N;$7$F5/F0$9$k$N$G$"$l$P!"(B -@code{gnus-save-duplicate-list} $B$r(B @code{nil} $B$K@_Dj$9$k$Y$-$G$"$k$H$$$&(B -$B;v$K$J$j$^$9!#$&!<$`!#;d$O$"$J$?$,$I$&$9$k$+$KG$$;$?$$!"$H;W$$$^$9!#(B - - -@node The Article Buffer -@chapter $B5-;v%P%C%U%!(B -@cindex article buffer - -$B5-;v$O0l$D$7$+$J$$5-;v%P%C%U%!$KI=<($5$l$^$9!#A4$F$N35N,%P%C%U%!$O!J(Bgnus -$B$K6&M-$7$J$$$h$&$K;X<($7$J$$8B$j!KF1$85-;v%P%C%U%!$r6&M-$7$^$9!#(B - -@menu -* Hiding Headers:: $B$I$N%X%C%@!<$rI=<($9$k$+$r7h$a$k!#(B -* Using MIME:: @sc{mime} $B5-;v$H$7$F8+$;$k!#(B -* Customizing Articles:: $B5-;v$N8+1I$($r;EN)$F$k!#(B -* Article Keymap:: $B5-;v%P%C%U%!$G;H$($k%-!!#(B -@end menu - - -@node Hiding Headers -@section $BM>J,$J%X%C%@!<$r1#$9(B -@cindex hiding headers -@cindex deleting headers - -$B3F5-;v$NF,$NItJ,$O%X%C%@!<(B(@dfn{head})$B$H8F$P$l$^$9!J;D$j$NItJ,$O%\%G%#(B -(@dfn{body})$B$G$9!#$9$G$K$*5$$E$-$G$7$g$&$,!K!#(B - -@vindex gnus-show-all-headers -$B%X%C%@!<$K$O$?$/$5$s$NJXMx$J>pJs$,4^$^$l$F$$$^$9!#5-;v$r=q$$$??M$NL>A0!"$=(B -$B$l$,=q$+$l$?F|IU!"5-;v$NI=Bj$J$I$G$9!#$3$l$O$H$F$bNI$$$s$G$9$,!"%X%C%@!<$K(B -$B$OBgItJ,$N?M$K$O8+$?$/$b$J$$>pJs!=!=5-;v$,$"$J$?$N$H$3$m$KCe$/$^$G$I$s$J%7(B -$B%9%F%`$r7PM3$7$F$-$?$+!"(B@code{Message-ID}, @code{References} $B$J$I$J$I!D$b(B -$B$&$d$s$J$C$A$c$&$/$i$$!=!=$b$?$/$5$s4^$^$l$F$$$^$9!#$?$V$s$"$J$?$O$3$l$i$N(B -$B9T$O$$$/$D$+A0$HI=Bj$N$_$r8+$?$1$l$P!"$3$&;XDj$7$^$9!#(B - -@lisp -(setq gnus-visible-headers "^From:\\|^Subject:") -@end lisp - -$B$3$NJQ?t$O!"I=<($5$;$?$$%X%C%@!<$K%^%C%A$9$k@55,I=8=$r%j%9%H$G;X(B -$BDj$9$k$3$H$b$G$-$^$9!#(B - -@item gnus-ignored-headers -@vindex gnus-ignored-headers -$B$3$NJQ?t$O(B @code{gnus-visible-headers} $B$NH?BP$G$9!#$3$NJQ?t$,@_Dj$5$l$F$$(B -$B$l$P!J$+$D(B @code{gnus-visible-headers} $B$,(B @code{nil} $B$G$"$l$P!K!"$3$l$O1#(B -$B$7$?$$%X%C%@!<9TA4$F$K%^%C%A$9$k@55,I=8=$G$"$k$H$_$J$5$l$^$9!#$3$NJQ?t$K%^%C(B -$B%A$7$J$$A4$F$N%X%C%@!<9T$OI=<($5$l$^$9!#(B - -$BNc$($P!"C1$K(B @code{References} $BMs$H(B @code{Xref} $BMs$N$_$r>C$75n$j$?$1$l$P!"(B -$B0J2<$N$h$&$K$7$^$9!'(B - -@lisp -(setq gnus-ignored-headers "^References:\\|^Xref:") -@end lisp - -$B$3$NJQ?t$O>C$7$?$$%X%C%@!<$K%^%C%A$9$k@55,I=8=$N%j%9%H$G$b9=$$$^(B -$B$;$s!#(B - -$B$J$*!"(B@code{gnus-visible-headers} $B$,(B @code{nil} $B0J30$N>l9g$O!"$3(B -$B$NJQ?t$K$O8z2L$,L5$$$3$H$KCm0U$7$F$/$@$5$$!#(B - -@end table - -@vindex gnus-sorted-header-list -Gnus $B$O%X%C%@!<$NJB$YBX$((B(sort)$B$b9T$$$^$9!J$3$l$O%G%#%U%)%k%H$G9T$o$l$^$9!K!#(B -$B$3$NJB$YBX$($O(B @code{gnus-sorted-header-list} $BJQ?t$r@_Dj$9$k$3$H$G@)8f$9$k(B -$B$3$H$,$G$-$^$9!#$3$l$O%X%C%@!<$r$I$&$$$&=g=x$GI=<($9$k$+$r;XDj$9$k@55,I=8=(B -$B$N%j%9%H$G$9!#(B - -$BNc$($P!"5-;v$NCx$r:G=i$K!"A0$,F~$k$N$G$O$"$j(B -$B$^$;$s!#Be$o$j$K(B gnus $B$,%A%'%C%/$7$F;k3&$+$i>C$75n$k$?$a$N$5$^$6(B -$B$^$J!V$D$^$i$J$$>r7o!W(B@dfn{boring conditions} $B$N%j%9%H$r;XDj$7$^(B -$B$9!#(B - -$B$3$N>r7o$K$O0J2<$N$h$&$J$b$N$,$"$j$^$9!#(B -@table @code -@item empty -$B6u$N%X%C%@!<$rA4$F>C5n$7$^$9!#(B -@item newsgroups -@code{Newsgroups} $BMs$,8=:_$N%0%k!<%WL>$7$+4^$s$G$$$J$$>l9g$K$O>C5n$7$^$9!#(B -@item followup-to -@code{Followup-To} $BMs$,(B @code{Newsgroups} $BMs$HF10l$G$"$k>l9g$K$O>C5n$7$^$9!#(B -@item reply-to -@code{Reply-To} $BMs$,(B @code{From} $BMs$HF1$8%"%I%l%9$r<($7$F$$$k>l9g$K$O>C5n(B -$B$7$^$9!#(B -@item date -$B$=$N5-;v$,2a5n#3F|0JFb$N$b$N$G$"$l$P!"(B@code{Date} $BMs$r>C5n$7$^$9!#(B -@item long-to -@code{To} $BMs$,$"$^$j$K$bD9$$>l9g$K$O>C5n$7$^$9!#(B -@item many-to -@code{To} $BMs$,0l$D$h$j$bB?$1$l$P!"$=$l$i$rA4$F>C5n$7$^$9!#(B -@end table - -$B>e5-$N:G=i$N#4$D$NMWAG$rF~$l$?$1$l$P!"$3$s$JIw$K$J$j$^$9!#(B - -@lisp -(setq gnus-boring-article-headers - '(empty followup-to reply-to)) -@end lisp - -$B$3$l$O$3$NJQ?t$N%G%#%U%)%k%HCM$G$b$"$j$^$9!#(B - - -@node Using MIME -@section @sc{mime} $B$r;H$&(B -@cindex @sc{mime} - -$B%Q%s%H%^%$%`(B (mime) $B$H$O!"0UL#$bL5$/6uCf$G$N$_$@$i$J$b$N$rL5\$7(B -$B$$>pJs$O!"%^%K%e%"%k$r;2>H$7$F$/$@$5$$!J$^$@$J$$$1$I(B(;_;)$B!K!#(B - -@sc{mime} $B$r>o$K;HMQ$7$?$1$l$P!"(B@code{gnus-show-mime} $B$r(B -@code{t} $B$K@_Dj$7$F$/$@$5$$!#$7$+$7!"(B@code{gnus-strict-mime} $B$,(B -@code{nil} $B0J30$G$"$l$P!"(B@sc{mime} $B=hM}$O5-;vCf$K(B @sc{mime} $B%X%C(B -$B%@!<$,$"$k$H$-$N$_;HMQ$5$l$^$9!#(B@code{gnus-show-mime} $B$r@_Dj$7$F(B -$B$$$k$H!"1?$,0-$$$H5-;v%P%C%U%!$K$O8N>c$7$?$h$&$J2hLL$,8+$($k$3$H(B -$B$b$"$k$G$7$g$&!#$3$l$OHr$1$h$&$,$"$j$^$;$s!#(B - -GNUS $B$d(B Gnus $B$G$O!"$3$N$?$A$N0-$$LdBj$G6C$+$5$l$J$$$h$&$K$9$k$K$O!"35N,%P%C(B -$B%U%!$K$*$$$F@Z$jBX$(5!G=$r;H$&$H$$$&$N$,:GA1$+$bCN$l$^$;$s!JNc$($P!"(B -@samp{alt.sing-a-long} $B%0%k!<%W$KF~$k$H!"$"$J$?$N5$$E$+$J$$$&$A$K(B -@sc{mime} $B$O5-;vCf$N%5%&%s%I%U%!%$%k$rI|9f$7$F!"2?$d$i2x$7$2$JD9$$D9$$2N$,(B -$B$"$J$?$N%9%T!<%+!<$+$iBg2;6A$GN.$l=P$7!"$"$J$?$O%\%j%e!<%`%\%?%s$r8+$D$1$i(B -$B$l$:!"$H$$$&$N$O$=$s$J$b$N$O$b$H$b$H$D$$$F$J$$$+$i$G!"$_$s$J$O$"$J$?$NJ}$r(B -$BbK$_$O$8$a!"$"$J$?$O%W%m%0%i%`$r;_$a$h$&$H$9$k$1$I$G$-$J$/$F!"%\%j%e!<%`$r(B -$B@)8f$9$k%W%m%0%i%`$b8+$D$1$i$l$J$/$F!"$=$7$FIt20Cf$NA40w$OFMA3$"$J$?$N$3$H(B -$B$r7ZJN$N4c:9$7$G8+$k$h$&$K$J$C$F$7$^$$!"$"$J$?$O$A$g$C$HLLGr$/$J$$;W$$$r$9(B -$B$k!"$H$+!K!#(B - -$B8=o$K(B @code{gnus-show-mime} $B$r(B @code{nil} $B0J30$K$7(B -$B$F$*$-!"<~$j$K?M$,$$$J$$;~$r8+7W$i$C$F5-;v%P%C%U%!$K8=$o$l$k%\%?%s$r2!$7$^(B -$B$7$g$&!#(B - - -@node Customizing Articles -@section $B5-;v$N%+%9%?%^%$%:(B -@cindex article customization - -@vindex gnus-article-display-hook -@code{gnus-article-display-hook} $B$O5-;v$,5-;v%P%C%U%!$K=q$-9~$^(B -$B$l$?D>8e$K8F$S=P$5$l$^$9!#$3$l$O5-;v$,I=<($5$l$kA0$N=hM}$rA4$F07(B -$B$&!"$H$$$&$3$H$G$9!#(B - -@findex gnus-article-maybe-highlight -@findex gnus-article-maybe-hide-headers -$B=i4|@_Dj$G$O$G$O$3$N%U%C%/$K$O(B @code{gnus-article-maybe-hide-headers}, -@code{gnus-hide-boring-headers}, @code{gnus-article-treat-overstrike}, -@code{gnus-article-maybe-highlight} (XEmacs $B$G$O!"(B -@code{gnus-article-display-x-face} $B$b(B) $B$@$1$,4^$^$l$F$$$^$9$,!"$3$N%U%C(B -$B%/$KF~$l$k$3$H$,$G$-$k4X?t$O2?@i$b!"$$$d2?I4K|$b$"$j$^$9!#3F4X?t$N354Q$O(B -@pxref{Article Highlighting}, @pxref{Article Hiding}, @pxref{Article -Washing}, @pxref{Article Buttons}, @pxref{Article Date} $B$r;2>H$7$F$/$@$5(B -$B$$!#Cm0UE@$H$7$F!"$3$N%U%C%/$G$O4X?t$N=g=x$,1F6A$9$k$3$H$,$"$k$N$G!"$*K>(B -$B$_$N7k2L$rF@$k$K$O$A$g$C$HpJs$O2?$b$"$j$^$;$s!=!=2?$G$bJQ99$9$k$3$H$,$G$-$^$9!#(B -$B$G$9$,!"%X%C%@!<$O>C5n$7$J$$J}$,NI$$$G$9!#$=$NBe$o$j!"%X%C%@!<$r$I$3$+$K$d$C(B -$B$F$7$^$$$?$1$l$P!"$=$l$i$r8+$($J$$$h$&$K$7$F$/$@$5$$!#(B - -@node Article Keymap -@section $B5-;v$N%-!(B - -@table @code - -@item gnus-single-article-buffer -@vindex gnus-single-article-buffer -@code{nil} $B0J30$G$"$l$P!"A4$F$N%0%k!<%W$KBP$7$FF1$85-;v%P%C%U%!$r;HMQ$7$^(B -$B$9!J$3$l$O%G%#%U%)%k%H$G$9!K!#(B@code{nil} $B$G$"$l$P!"3F%0%k!<%WKh$N8GM-$N5-(B -$B;v%P%C%U%!$r;}$D$h$&$K$J$j$^$9!#(B - -@vindex gnus-article-prepare-hook -@item gnus-article-prepare-hook -$B$3$N%U%C%/$O5-;v$,5-;v%P%C%U%!$K=q$-9~$^$l$?D>8e$K8F$S=P$5$l$^$9!#(B -$B$3$l$O$C$?MM<0J8;z(B -$BNs$G$9(B (@pxref{Mode Line Formatting})$B!#$3$l$O0J2<$N0l$D$N3HD%$r=|$$$F!"(B -$B$=$NJQ?t$HF1$8MM<0;XDj$ruBV!W(B@dfn{wash status}$B!#$3$l$O5-;v$KBP$7$F9T$o$l$?(B -$B$G$"$m$&@vBuA`:n$r<($90lJ8;z$+$i$J$kC;$$J8;zNs$K$J$j$^$9!#(B -@end table - -@vindex gnus-break-pages - -@item gnus-break-pages -$B2~JG(B @dfn{page breaking} $B$r9T$&$+$I$&$+$r@)8f$7$^$9!#$3$NJQ?t$,(B -@code{nil} $B0J30$G$"$l$P!"5-;vCf$KJG6h@Z$jJ8;z$,8=$l$?>l=j$4$H$K(B -$BJGJ,3d$7$^$9!#$3$NJQ?t$,(B @code{nil} $B$G$"$l$PJGJ,$1$O9T$o$l$^$;$s!#(B - -@item gnus-page-delimiter -@vindex gnus-page-delimiter -$B$3$l$,>e$G?($l$?6h@Z$jJ8;z$G$9!#%G%#%U%)%k%H$G$O(B @samp{^L} ($B%U%)!<(B -$B%`%U%#!<%I!"2~JG(B) $B$G$9!#(B -@end table - - -@node Composing Messages -@chapter $B%a%C%;!<%8$N:n@.(B -@cindex composing messages -@cindex messages -@cindex mail -@cindex sending mail -@cindex reply -@cindex followup -@cindex post - -@kindex C-c C-c ($BEj9F(B) -$BA4$F$NEj9F$H%a!<%k$NL?Na$O!"(B@kbd{C-c C-c} $B$r2!$9;v$K$h$C$F!"5-;v$rAw?.$9$k(B -$BA0$K5-;v$r9%$-$J$h$&$KJT=8$9$k;v$N$G$-$k!"%a%C%;!<%8%P%C%U%!$K0\F0$7$^$9!#(B -@xref{Top, , Top, message, The Message Manual}$B!#$b$730It%K%e!<%9%0%k!<%W$K(B -$B$$$F!"5-;v$r30It%5!<%P!<$r;H$C$FEj9F$7$?$$$N$G$"$l$P!"(B@kbd{C-c C-c} $B$K@\F,(B -$B0z?t$rM?$($F!"(Bgnus $B$K30It%5!<%P!<$r;H$C$FEj9F$7$h$&$H;n$5$;$k;v$,$G$-$^$9!#(B - -@menu -* Mail:: $B%a!<%k$HJVEz!#(B -* Post:: $BEj9F$H%U%)%m!<%"%C%W!#(B -* Posting Server:: $B$I$N%5!<%P!<$rDL$7$FEj9F$9$k$Y$-$+!)(B -* Mail and Post:: $BF1;~$K%a!<%k$r=P$7JVEz$9$k!#(B -* Archived Messages:: $BAw$C$?%a%C%;!<%8$r(B gnus $B$,Cy$a$F$*$/$H$3$m!#(B -* Posting Styles:: $B$"$J$?$,C/$G$"$k$+$r;XDj$9$k$h$j4JC1$JJ}K!!#(B -* Drafts:: $B%a%C%;!<%8$N1d4|$H5qH]$5$l$?%a%C%;!<%8!#(B -* Rejected Articles:: $B%5!<%P!<$,$"$J$?$N5-;v$r9%$-$G$J$$$H$-$K2?$,5/$3$k!)(B -@end menu - -$BEj9F$9$k$Y$-$G$J$+$C$?5-;v$r:o=|$9$k$?$a$N>pJs$O(B @pxref{Canceling and -Superseding} $B$r;2>H$7$F$/$@$5$$!#(B - - -@node Mail -@section $B%a!<%k(B - -$B=P$F9T$/%a!<%k$r%+%9%?%^%$%:$9$kJQ?t$G$9!'(B - -@table @code -@item gnus-uu-digest-headers -@vindex gnus-uu-digest-headers -$BMWLs%a%C%;!<%8(B (digested message) $B$K4^$^$l$k%X%C%@!<$K9gCW$9$k@55,I=8=$N(B -$B%j%9%H$G$9!#%X%C%@!<$O9gCW$7$?=g$K$^$J$$$N$G$"$l$P!"$3$NJQ?t$r(B @code{nil} $B$K@_Dj$9$k;v$,$G$-$^$9!#(B - -@item gnus-sent-message-ids-length -@vindex gnus-sent-messages-ids-length -$B$3$NJQ?t$O$I$l$/$i$$B?$/$N(B @code{Message-ID} $B$rMzNr%U%!%$%k$KJ];}$9$k$+(B -$B$r;XDj$7$^$9!#%G%#%U%)%k%H$G$O(B 1000 $B$G$9!#(B - -@end table - - -@node Posting Server -@section $BEj9F$9$k%5!<%P!<(B - -$B:G?7$N!J$b$A$m$s!"Hs>o$KCNE*$J!K5-;v$rAw$j=P$9$?$a$K!"$"$NKbK!$N$h$&$J(B -@kbd{C-c C-c} $B%-!<$r2!$7$?;~!"$=$l$O$I$3$K$$$/$N$G$7$g$&!)(B - -$B?R$M$F$/$l$F$"$j$,$H$&!#$"$J$?$r:($_$^$9!#(B - -@vindex gnus-post-method - -$B$=$l$OHs>o$KJ#;($K$J$jF@$^$9!#IaDL$O!"(Bgnus $B$OF1$84pK\%5!<%P!<$r;HMQ$7$^$9!#(B -$B$7$+$7!#$"$J$?$N4pK\%5!<%P!<$,Ej9F$r5v2D$;$:!"FI$`$3$H$N$_$r5v2D$7$F$$$k$N(B -$B$J$i$P!"$*$=$i$/$"$J$?$N!JHs>o$KCNE*$G$H$s$G$b$J$/6=L#?<$$!K5-;v$rEj9F$9$k(B -$B$?$a$K!"B>$N%5!<%P!<$r;H$$$?$$$H;W$&$G$7$g$&!#(B@code{gnus-post-method} $B$rB>(B -$B$NJ}K!$K@_Dj$9$k;v$,$G$-$^$9!#(B - -@lisp -(setq gnus-post-method '(nnspool "")) -@end lisp - -$B$5$F!"$3$N@_Dj$r$7$?8e$G%5!<%P!<$,$"$J$?$N5-;v$r5qH]$7$?$j!"%5!<%P!<$,Mn$A(B -$B$F$$$?$j$7$?$i!"$I$&$7$?$i$h$$$N$G$7$g$&!)$3$NJQ?t$r>e=q$-$9$k$?$a$K!"L?Na(B -@kbd{C-c C-c} $B$KNm$G$J$$@\F,0z?t$rM?$($k;v$G!"Ej9F$K!X8=:_$N!Y%5!<%P!<$r;H(B -$B$o$;$k;v$,$G$-$^$9!#(B - -$B$b$7!"Nm@\F,0z?t$r$=$NL?Na$KM?$($?$J$i!J$9$J$o$A!"(B@kbd{C-u 0 C-c C-c}$B!K!"(B -gnus $B$OEj9F$K$I$NJ}K!$r;H$&$+$r$"$J$?$K?R$M$^$9!#(B - -@code{gnus-post-method} $B$rA*BrJ}K!$N%j%9%H$K$9$k;v$b$G$-$^$9!#$=$N>l9g$O!"(B -gnus $B$O>o$KEj9F$K$I$NJ}K!$r;H$&$+$r$"$J$?$K?R$M$^$9!#(B - - -@node Mail and Post -@section $B%a!<%k$HEj9F(B - -$B$3$l$O%a!<%k$r=P$9;v$HEj9F$9$k;v$NN>J}$K4XO"$9$kJQ?t$N%j%9%H$G$9!'(B - -@table @code -@item gnus-mailing-list-groups -@findex gnus-mailing-list-groups -@cindex mailing lists - -$B$b$7$"$J$?$N%K%e!<%9%5!<%P!<$,K\Ev$K%a!<%j%s%0%j%9%H$+$i(B @sc{nntp} $B%5!<(B -$B%P!<$X$N%2!<%H%&%'%$$rDs6!$7$F$$$k$N$G$"$l$P!"$=$l$i$N%0%k!<%W$OLdBj$J$/(B -$BFI$a$k$G$7$g$&!#$7$+$74JC1$K$O$=$l$i$KEj9F(B/$B%U%)%m!<%"%C%W$9$k$3$H$O$G$-(B -$B$^$;$s!#0l$D$N2r7hK!$O(B $B%0%k!<%W%Q%i%a!<%?(B (@pxref{Group Parameters}) $B$K(B -@code{to-address} $B$r2C$($k;v$G$9!#4JC1$K$G$-$k$N$O!"(B -@code{gnus-mailing-list-groups} $B$r!"K\Ev$K%a!<%j%s%0%j%9%H$G$"$k$h$&$J%0(B -$B%k!<%W$K9gCW$9$k@55,I=8=$K@_Dj$9$k$3$H$G$9!#$=$N8e$O!"$9$/$J$/$H$b!"%a!<(B -$B%j%s%0%j%9%H$X$N%U%)%m!<%"%C%W$O$?$$$F$$$N$H$-$KF0:n$7$^$9!#$3$l$i$N%0%k!<(B -$B%W$KEj9F$9$k;v$O(B (@kbd{a}) $B$=$l$G$b6lDK$r0z$-5/$3$9$G$7$g$&$1$I!#(B - -@end table - -$B$"$J$?$O<+J,$,Aw$k%a%C%;!<%8$NDV$j$rD4$Y$?$$$H;W$&$+$bCN$l$^$;$s!#$b$7$/(B -$B$O!"$b$7e(B -$B$N=q8K%5!<%P!<(B}(archive virtual server)$B$r;H$$$^$9!#$3$l$r40A4$K6X;_$7$?$$(B -$B$N$G$"$l$P!"JQ?t(B @code{gnus-message-archive-group} $B$O(B @code{nil} $B$K$J$k$Y(B -$B$-$G!"$3$l$,%G%#%U%)%k%H$G$9!#(B - -@vindex gnus-message-archive-method -@code{gnus-message-archive-method} $B$OAw$C$?%a%C%;!<%8$rC_@Q$9$k$?$a$K$I$N(B -$B;ve$N%5!<%P!<$r(B gnus $B$,;H$&$Y$-$+$r;XDj$7$^$9!#%G%#%U%)%k%H$O!'(B - -@lisp -(nnfolder "archive" - (nnfolder-directory "~/Mail/archive") - (nnfolder-active-file "~/Mail/archive/active") - (nnfolder-get-new-mail nil) - (nnfolder-inhibit-expiry t)) -@end lisp - -$B$7$+$7!"$I$N%a!<%kA*BrJ}K!$G$b;H$&;v$,$G$-$^$9!J(B@code{nnml}, -@code{nnmbox} $B$J$I$J$I!K!#$7$+$7(B @code{nnfolder} $B$O$3$N$h$&$J;v$r$9$k$N$K(B -$B$H$F$b9%$^$7$$A*BrJ}K!$G$9!#%G%#%U%)%k%H$N%G%#%l%/%H%j!e$N$=$N%5!<%P!<$N%0%k!<(B -$B%W$X8~$+$&(B @code{Gcc} $BMs$rA^F~$7$^$9!#$I$N%0%k!<%W$r;H$&$+$OJQ?t(B -@code{gnus-message-archive-group} $B$K$h$C$F7h$^$j$^$9!#(B - -$B$3$NJQ?t$O$N%0%k!<%W(B -$B$HF1$8$h$&$K$=$N%0%k!<%W$KF~$C$F!"5-;v$rFI$`;v$,$G$-$^$9!#$=$N%0%k!<%W$,K\(B -$BEv$KBg$-$/$J$C$F7y$K$J$C$?$i!"$J$K$+NI$$$b$N$K$=$NL>A0$rJQ99$9$k;v$,$G$-$^(B -$B$9!J%0%k!<%W%P%C%U%!$G(B @kbd{G r} $B$r;H$&;v$K$h$C$F!K!=!=(B -@samp{misc-mail-september-1995} $B$dB>$N$b$K!#?7$7$$%a%C%;!<%8$O8E$$!J:#$O6u(B -$B$K$J$C$?!K%0%k!<%W$KN/$a$i$l$^$9!#(B - -$B0J>e$,Aw$C$?%a%C%;!<%8$rJ]4I$9$k%G%#%U%)%k%H$NJ}K!$G$9!#(BGnus $B$O%G%#%U%)(B -$B%k%H$NJ}K!$r9%$-$G$O$J$$?M$K$O0c$C$?$d$jJ}$r4+$a$F$$$^$9!#$=$N$h$&$J>l9g(B -$B$O!"(B@code{gnus-message-archive-group} $B$r(B @code{nil} $B$K@_Dj$9$k$Y$-$G$9!#(B -$B$3$l$OJ]4I$r$7$J$$$h$&$K$7$^$9!#(B - -@table @code -@item gnus-outgoing-message-group -@vindex gnus-outgoing-message-group -$BA4$F$N30$K$$$/%a%C%;!<%8$O$3$N%0%k!<%W$KF~$l$i$l$^$9!#$b$7A4$F$N30$K9T$/(B -$B%a!<%k$H5-;v$r%0%k!<%W(B @samp{nnml:archive} $B$KJ]4I$7$?$$$N$G$"$l$P!"$3$N(B -$BJQ?t$r$=$NCM$K@_Dj$9$k;v$,$G$-$^$9!#$3$NJQ?t$O%0%k!<%WL>$N%j%9%H$G$"$k;v(B -$B$b$G$-$^$9!#(B - -$B$b$7$=$l$>$l$N%a%C%;!<%8$r$I$N%0%k!<%W$KF~$l$k$+$r$b$C$H@)8f$7$?$$$N$G$"$l(B -$B$P!"$3$NJQ?t$r8=:_$N%K%e!<%9%0%k!<%WL>$rD4$Y$F!"E,@Z$J%0%k!<%WL>!J$b$7$/$O(B -$BL>A0$N%j%9%H!K$rJV$94X?t$K@_Dj$9$k;v$,$G$-$^$9!#(B - -$B$3$NJQ?t$O(B @code{gnus-message-archive-group} $B$NBe$o$j$K;H$&;v$,$G$-$^$9(B -$B$,!"8e$rK>$`$N$G$7$g$&$+!)$=$7$F!"$"$J$?$O2HDm$N%^%7%s$H?&>l$N%^%7%s$NN>(B -$BJ}$+$iEj9F$7$F!"0c$C$?(B @code{From} $B9T$d$=$NB>$N$b$N$rK>$`$N$G$9$+!)(B - -@vindex gnus-posting-styles -$B$=$N$h$&$J;v$r$9$kJ}K!$N0l$D$OJQ99$5$l$kI,MW$N$"$kJQ?t$rJQ99$9$k8-$$%U%C(B -$B%/$r=q$/;v$G$9!#$=$l$O>/$7B`6~$J$N$G!"MxMQ$l$NMM<0$O:G=i$NMWAG$,2?$i$+$N7A$G(B ``$B9g(B -$BCW(B'' $B$7$?$H$-$KE,MQ$5$l$^$9!#O"A[%j%9%HA4BN$O:G=i$+$i:G8e$^$GH?I|$7$F$l$N9gCW$,E,MQ$5$l$^$9!#$3$l$O!"8e$NMM<0$NB0@-$,A0$K9gCW$7(B -$B$?MM<0$NB0@-$r>e=q$-$9$k$H8@$&;v$G$9!#$G$9$+$i!"(B -@samp{comp.programming.literate} $B$O!"=pL>(B @samp{Death to everybody} $B$H(B -@code{Organization} $B%X%C%@!<(B @samp{What me?} $B$r;}$A$^$9!#(B - -$B$=$l$>$l$NMM<0$N:G=i$NMWAG$O(B @code{$B9gCW(B} (match) $B$H8F$P$l$^$9!#$b$7$=$l(B -$B$,J8;zNs$G$"$l$P!"(Bgnus $B$O$=$l$r%0%k!<%WL>$K@55,I=8=$H$7$F9gCWA`:n$r9T$$(B -$B$^$9!#$b$7$=$l$,4X?t$N%7%s%\%k$G$"$l$P!"$=$N4X?t$,0z?tL5$7$G8F$P$l$^$9!#(B -$B$=$l$,JQ?t$N%7%s%\%k$G$"$l$P!"$=$NJQ?t$,;2>H$5$l$^$9!#$=$l$,%j%9%H$G$"$l(B -$B$P!"$=$N%j%9%H$,(B @code{$BI>2A(B} $B$5$l$^$9!#$I$N>l9g$G$b!"$3$l$,(B @code{nil} -$B$G$J$$CM$r5"$;$P!"MM<0$O(B @code{$B9gCW$7$?(B} $B$H8@$$$^$9!#(B - -$B$=$l$>$l$NMM<0$OG$0U$NNL$N(B @dfn{$BB0@-(B} $B$r;}$D;v$,$G$-$^$9!#$=$l$>$l$NB0@-(B -$B$O(B @var{(name . value)} $B$NBP$K$h$j@.$jN)$C$F$$$^$9!#B0@-L>$O!"(B -@code{signature}, @code{signature-file}, @code{organization}, -@code{address}, @code{name}, @code{body} $B$N$I$l$+$G$"$k;v$,$G$-$^$9!#B0(B -$B@-L>$OJ8;zNs$G$"$k;v$b$G$-$^$9!#$=$N>l9g$O!"$3$l$O%X%C%@!$H$7$F;H$o$l!"(B -$B$=$NCM$,5-;v$N%X%C%@!<$KA^F~$5$l$^$9!#(B - -$BB0@-CM$OJ8;zNs(B ($B$=$N$^$^;H$o$l$^$9(B)$B!"4X?t(B ($BJV$jCM$,;H$o$l$^$9(B)$B!"JQ?t(B ($B$=(B -$B$NCM$,;H$o$l$^$9(B)$B!"%j%9%H(B ($B$=$l$O(B @code{$BI>2A(B} $B$5$l$F!"JV$jCM$,;H$o$l$^$9(B) -$B$G$"$k;v$,$G$-$^$9!#(B - -$B$b$7!":n@.$7$h$&$H$7$F$$$k%a%C%;!<%8$,%K%e!<%95-;v$+%a!<%k%a%C%;!<%8$G$"(B -$B$k$+$rD4$Y$?$$$H$-$O!"(B2$B$D$NF0E*$KB+G{$5$l$kJQ?t(B -@code{message-this-is-news} $B$H(B @code{message-thiss-is-mail} $B$rD4$Y$k;v$,(B -$B$G$-$^$9!#(B - -@vindex message-this-is-mail -@vindex message-this-is-news - -$B$=$7$F!"$3$l$ONc$G$9(B: - -@lisp -(setq gnus-posting-styles - '((".*" - (signature-file "~/.signature") - (name "User Name") - ("X-Home-Page" (getenv "WWW_HOME")) - (organization "People's Front Against MWM")) - ("^rec.humor" - (signature my-funny-signature-randomizer)) - ((equal (system-name) "gnarly") - (signature my-quote-randomizer)) - (message-this-is-news - (signature my-news-signature)) - (posting-from-work-p - (signature-file "~/.work-signature") - (address "user@@bar.foo") - (body "You are fired.\n\nSincerely, your boss.") - (organization "Important Work, Inc")) - ("^nn.+:" - (signature-file "~/.mail-signature")))) -@end lisp - - -@node Drafts -@section $B2<=q$-(B -@cindex drafts - -$B$b$7%a%C%;!<%8!J%a!<%k$b$7$/$O%K%e!<%9!K$r=q$$$F$$$k$H$-$K!"FMA3%*!<%V%s(B -$B$K%9%F!<%-$,F~$C$F$$$k;v$r;W$$=P$7$?$J$i!J$b$7$/$O!"$"$J$?$,$H!<$C$F$b$9(B -$B$4$$:Z?)C$75n$kM#0l$NJ}K!$O!"$=$l$rL$9XFI$K$9$k$3$H$G$9!#(B - -@c @findex gnus-dissociate-buffer-from-draft -@c @kindex C-c M-d (Mail) -@c @kindex C-c M-d (Post) -@c @findex gnus-associate-buffer-with-draft -@c @kindex C-c C-d (Mail) -@c @kindex C-c C-d (Post) -@c If you're writing some super-secret message that you later want to -@c encode with PGP before sending, you may wish to turn the auto-saving -@c (and association with the draft group) off. You never know who might be -@c interested in reading all your extremely valuable and terribly horrible -@c and interesting secrets. The @kbd{C-c M-d} -@c (@code{gnus-dissociate-buffer-from-draft}) command does that for you. -@c If you change your mind and want to turn the auto-saving back on again, -@c @kbd{C-c C-d} (@code{gnus-associate-buffer-with-draft} does that. -@c -@c @vindex gnus-use-draft -@c To leave association with the draft group off by default, set -@c @code{gnus-use-draft} to @code{nil}. It is @code{t} by default. - -@findex gnus-draft-edit-message -@kindex D e$B!J2<=q$-!K(B -$B5-;v$NJT=8$rB3$1$?$$$H$-$O!"2<=q$-%0%k!<%W$KF~$C$F(B @kbd{D e} -(@code{gnus-draft-edit-message}) $B$r2!$9$@$1$G$9!#$"$J$?$,;D$7$?>uBV$N%P%C(B -$B%U%!$K0\F0$7$^$9!#(B - -$B5qH]$5$l$?5-;v$b$3$N2<=q$-%0%k!<%W$KF~$l$i$l$^$9(B (@pxref{Rejected -Articles})$B!#(B - -@findex gnus-draft-send-all-messages -@findex gnus-draft-send-message -$B$=$l0J>eJT=8$7$J$$$GEj9F!J$b$7$/$O%a!<%k!K$7$?$$5qH]$5$l$?%a%C%;!<%8$,$?$/(B -$B$5$s$"$k$N$G$"$l$P!"L?Na(B @kbd{D s} $B$r;H$&;v$,$G$-$^$9!#$3$NL?Na$O%W%m%;%9(B -/$B@\F,0z?t$N=,47$rM}2r$7$^$9(B (@pxref{Process/Prefix})$B!#L?Na(B @kbd{D S} -(@code{gnus-draft-send-all-messages}) $B$O%P%C%U%!$NA4$F$N%a%C%;!<%8$rAw$j=P(B -$B$7$^$9!#(B - -$BAw$j$?$/$J$$%a%C%;!<%8$,$$$/$D$+$"$k$N$G$"$l$P!"L?Na(B @kbd{D t} -(@code{gnus-draft-toggle-sending}) $B$r;H$C$F%a%C%;!<%8$rG[AwIT2D$N0u$rIU(B -$B$1$k;v$,$G$-$^$9!#$3$l$O@Z$jBX$(L?Na$G$9!#(B - - -@node Rejected Articles -@section $B5qH]$5$l$?5-;v(B -@cindex rejected articles - -$B;~!9%K%e!<%9%5!<%P!<$O5-;v$r5qH]$7$^$9!#$*$=$i$/%5!<%P!<$O$"$J$?$N4i$r9%$-(B -$B$G$O$J$$$N$G$7$g$&!#$*$=$i$/$=$l$O;4$a$K46$8$?$+$i$G$7$g$&!#$*$=$i$/(B -@emph{$B0-Kb(B (demon) $B$,$$$k$N$G$7$g$&(B}$B!#(B $B$*$=$i$/0zMQJ8$rF~$l$9$.$?$N$G$7$g(B -$B$&!#$*$=$i$/%G%#%9%/$,0lGU$@$C$?$N$G$7$g$&!#$*$=$i$/%5!<%P!<$,Mn$A$F$$$?$N(B -$B$G$7$g$&!#(B - -$B$3$l$i$N>u67$O!"$b$A$m$s!"40A4$K(B gnus $B$N07$($kHO0O30$G$9!#!J(BGnus $B$O!"$b$A(B -$B$m$s!"$"$J$?$N308+$r0&$7$F$*$j!"$$$D$b5!7y$,NI$/!"Cf$rHt$S2s$kE7;H$,$$$F!"(B -$B$I$l$/$i$$0zMQJ8$,4^$^$l$F$$$h$&$H5$$K$;$:!"0lGU$K$J$C$?$j!"Mn$C$3$A$?$j(B -$B$7$^$;$s!#!K$G$9$+$i!"(Bgnus $B$O$3$l$i$N5-;v$r8e$G%5!<%P!<$N5$J,$,$h$/$J$k(B -$B$^$GJ]B8$7$^$9!#(B - -$B5qH]$5$l$?5-;v$O<+F0E*$KFCJL$J2<=q$-%0%k!<%W(B (@pxref{Drafts}) $B$KF~$l$i$l(B -$B$^$9!#%5!<%P!<$,La$C$F$-$?$J$i!"IaDL$O$=$N%0%k!<%W$KF~$C$FA4$F$N5-;v$rAw(B -$B$j$^$9!#(B - - -@node Select Methods -@chapter $BA*BrJ}K!(B -@cindex foreign groups -@cindex select methods - -@dfn{$B30It%0%k!<%W(B} (foreign group) $B$H$O!"IaDL(B ($B$b$7$/$O%G%#%U%)%k%H(B) $B$N(B -$BJ}K!$GFI$^$l$J$$%0%k!<%W$N;v$G$9!#Nc$($P!"$=$l$O0c$C$?(B @sc{nntp} $B%5!<%P!<(B -$B$N%0%k!<%W$G$"$C$?$j!";ve$N%0%k!<%W$G$"$C$?$j!"8D?ME*$J%a!<%k%0%k!<%W(B -$B$G$"$C$?$j$9$k$G$7$g$&!#(B - -$B30It%0%k!<%W(B ($B$b$7$/$O!"K\Ev$KA4$F%0%k!<%W(B) $B$O(B @dfn{$BL>A0(B} $B$H(B - @dfn{$BA*BrJ}K!(B} $B$G;XDj$5$l$^$9!#8e(B} $B$G$"$kO"A[%j%9%H$G$9!#A*(B -$BBrJ}K!$K$O!"$=$NEv$N%P%C%/%(%s%I$K$H$C$FFCJL$N0UL#$r;}$DCM$G$"$kDI2C$NMW(B -$BAG$,$"$k$+$bCN$l$^$;$s!#(B - -$BA*BrJ}K!$O(B @dfn{$B;ve$N%5!<%P!<(B} $B$rDj5A$9$k$H8@$&$3$H$,$G$-$k$+$b$7$l$^(B -$B$;$s(B---$B$G$9$+$i;d$?$A$O$A$g$&$I$=$l$r$7$^$7$?(B (@pxref{The Server -Buffer})$B!#(B - -$B%0%k!<%W$N(B @dfn{$BL>A0(B} $B$O%P%C%/%(%s%I$,%0%k!<%W$rG'<1$9$kL>A0$G$9!#(B - -$B$?$H$($P!"(B@sc{nntp} $B%5!<%P!<$N%0%k!<%W(B @samp{soc.motss} $B$OL>A0(B -@samp{soc.motss} $B$HA*BrJ}K!(B @code{(nntp "some.where.edu")} $B$r;}$A$^$9!#(B -@code{nntp} $B%P%C%/%(%s%I$O$3$N%0%k!<%W$r(B @samp{soc.motss} $B$H$7$FCN$C$F$$(B -$B$k$@$1$G$9$,!"(Bgnus $B$O$3$N%0%k!<%W$r(B @samp{nntp+some.where.edu:soc.motss} -$B$H8F$S$^$9!#(B - -$B$b$A$m$s!"0c$C$?J}K!$OA4$F$=$lFCM-$N$b$N$,$"$j$^$9!#(B - -@menu -* The Server Buffer:: $B;ve$N%5!<%P!<$r:n$C$FJT=8$9$k!#(B -* Getting News:: USENET $B%K%e!<%9$r(B gnus $B$GFI$`!#(B -* Getting Mail:: $B8D?ME*$J%a!<%k$r(B gnus $B$GFI$`!#(B -* Other Sources:: $B%G%#%l%/%H%j!pJs$rMW5a$9$k%^%7%s(B -$B$+%=%U%H%&%'%"$G$9!#(B - -@menu -* Server Buffer Format:: $B$3$N%P%C%U%!$N308+$r%+%9%?%^%$%:$G$-$k!#(B -* Server Commands:: $B%5!<%P!<$rA`$kL?Na!#(B -* Example Methods:: $B%5!<%P!<;XDj$NNc!#(B -* Creating a Virtual Server:: $B%;%C%7%g%s$NNc!#(B -* Server Variables:: $B$I$NJQ?t$r@_Dj$9$k$+!#(B -* Servers and Methods:: $B%5!<%P!$rA*BrJ}K!$H$7$F;H$&;v$,$G$-$k!#(B -* Unavailable Servers:: $B@\B3$7$h$&$H;n$_$?%5!<%P!<$N$$$/$D$+$,Mn$A$F$$$k$+$b$7$l$J$$!#(B -@end menu - -@vindex gnus-server-mode-hook -$B%5!<%P!<%P%C%U%!$r:n@.$9$k$H$-$K(B @code{gnus-server-mode-hook} $B$,A0!#(B - -@item n -$B%5!<%P!<$NL>A0!#(B - -@item w -$B$I$3$+$i%K%e!<%9$,uBV!#(B -@end table - -@vindex gnus-server-mode-line-format -$B%b!<%I9T$bJQ?t(B @code{gnus-server-mode-line-format} $B$r;H$&;v$K$h$C$F%+%9(B -$B%?%^%$%:$9$k;v$,$G$-$^$9(B (@pxref{Mode Line Formatting})$B!#0J2<$N;XDj$OM}(B -$B2r$5$l$^$9(B: - -@table @samp -@item S -$B%5!<%P!!#(B - -@item M -$B%5!<%P!H$7$F$/$@$5$$!#(B - - -@node Server Commands -@subsection $B%5!<%P!o$K4JC1$G!"<+J,<+?H$r$h$/@bL@$7$F$$$^$9(B: - -@lisp -(nntp "news.funet.fi") -@end lisp - -$BD>@\%9%W!<%k$+$iFI$`$N$O$b$C$H4JC1$G$9(B: - -@lisp -(nnspool "") -@end lisp - -$B8+$?$H$*$j!"A*BrJ}K!$N:G=i$NMWAG$O%P%C%/%(%s%I$NL>A0$G!"(B2$BHVL\$O(B -@dfn{$B%"%I%l%9(B} (address) $B!"$b$7$/$O$=$&8F$S$?$$$N$G$"$l$P!"(B@dfn{$BL>A0(B} $B$G(B -$B$9!#(B - -$B$3$l$i$N(B2$B$D$NMWAG$N8e$K$O!"G$0U$N?t$N(B @var{($BJQ?t(B $BMM<0(B)} $B$NBP$rF~$l$k;v$,(B -$B$G$-$^$9!#(B - -$B:G=i$NNc$KLa$j$^$7$g$&(B---$B$=$N%^%7%s$N%]!<%H(B15$B$+$iFI$_$?$+$C$?$H;W$C$F$/(B -$B$@$5$$!#$3$l$,$=$N;~$K!"$J$k$Y$-A*BrJ}K!$G$9(B: - -@lisp -(nntp "news.funet.fi" (nntp-port-number 15)) -@end lisp - -$B$I$NJQ?t$,4XO"$9$k$+$r8+$D$1$k$?$a$K!"$=$l$>$l$N%P%C%/%(%s%I$N@bL@J8=q$r(B -$BFI$`$Y$-$G$7$g$&$,!"$3$l$O(B @code{nnmh} $B$NNc$G$9!#(B - -@code{nnml} $B$O%9%W!<%k$N$h$&$J9=B$$GFI$`%a!<%k%P%C%/%(%s%I$G$9!#Nc$($P!"(B -$B@\?($r?^$j$?$$(B2$B$D$N9=B$$,$"$k$H$7$^$7$g$&(B: $B0l$D$O$"$J$?$N;dE*$J%a!<%k%9(B -$B%W!<%k$G!"B>J}$O8xE*$J$b$N$G$9!#$3$l$O;dE*$J%a!<%k$N$?$a$K;HMQ2DG=$J;XDj(B -$B$G$9(B: - -@lisp -(nnmh "private" (nnmh-directory "~/private/mail/")) -@end lisp - -($B$=$&$9$k$H$3$N%5!<%P!<$O(B @samp{private} $B$H8F$P$l$^$9$,!"$"$J$?$O4{$K?d(B -$BB,$7$F$$$?$+$b$7$l$^$;$s!#(B) - -$B$3$l$O8xE*%9%W!<%k$N$?$a$NJ}K!$G$9(B: - -@lisp -(nnmh "public" - (nnmh-directory "/usr/information/spool/") - (nnmh-get-new-mail nil)) -@end lisp - -$BKIJI(B (firewall) $B$NCf$K$$$F!"KIJI%^%7%s$+$i$N(B @sc{nntp} $B%5!<%P!<$X$N@\B3(B -$B$7$+$J$$$N$G$"$l$P!"(Bgnus $B$KKIJI%^%7%s$K(B @code{rlogin} $B$7$F!"$=$3$+$i(B -@sc{nntp} $B%5!<%P!<$K(B telnet $B$r$9$k$h$&$K;X<($9$k;v$,$G$-$^$9!#(B -$B$3$l$r$9$k;v$O>/$7$P$+$i$7$$$G$9$,!";ve$N%5!<%P!<$NDj5A$O$*$=$i$/$3$N(B -$B$h$&$J$b$N$K$J$k$Y$-$G$9(B: - -@lisp -(nntp "firewall" - (nntp-address "the.firewall.machine") - (nntp-open-connection-function nntp-open-rlogin) - (nntp-end-of-line "\n") - (nntp-rlogin-parameters - ("telnet" "the.real.nntp.host" "nntp"))) -@end lisp - -$B$b$7!"$9$P$i$7$$(B @code{ssh} $B%W%m%0%i%`$r!"%b%G%`@~$+$i$N05=L$5$l$?@\B3$r(B -$BDs6!$9$k$?$a$K;H$$$?$$$N$G$"$l$P!"$3$N$h$&$J46$8$N;ve$N%5!<%P!<$r:n$k(B -$B;v$,$G$-$^$9(B: - -@lisp -(nntp "news" - (nntp-address "copper.uio.no") - (nntp-rlogin-program "ssh") - (nntp-open-connection-function nntp-open-rlogin) - (nntp-end-of-line "\n") - (nntp-rlogin-parameters - ("telnet" "news.uio.no" "nntp"))) -@end lisp - -$B$3$l$O$b$A$m$s!"<+F0G'>Z$rDs6!$9$k$?$a$K(B @code{ssh-agent} $B$rE,@Z$K@_Dj$7(B -$B$J$1$l$P$J$j$^$;$s!#05=L$5$l$?@\B3$rF@$k$?$a$K$O!"(B@code{ssh}$B$N%U%!%$%k(B -@file{config} $B$G(B @samp{Compression} $B%*%W%7%g%s$,$"$kI,MW$,$"$j$^$9!#(B - - -@node Creating a Virtual Server -@subsection $B;ve$N%5!<%P!<$r:n@.$9$k(B - -$B$b$7$"$J$?$O1JB35-;v$r;H$C$F$?$/$5$s$N5-;v$r%-%c%C%7%e$KJ]B8$7$F$$$k$N$G(B -$B$"$l$P!"%-%c%C%7%e$rFI$`$?$a$N;ve$N%5!<%P!<$r:n$j$?$$$H;W$&$+$b$7$l$^(B -$B$;$s!#(B - -$B:G=i$K!"?7$7$$%5!<%P!<$rIU$12C$($kI,MW$,$"$j$^$9!#L?Na(B @kbd{a} $B$,$=$l$r(B -$B$7$^$9!#$*$=$i$/%-%c%C%7%e$rFI$`$?$a$K$O(B @code{nnspool} $B$r;H$&$N$,0lHVNI(B -$B$$$G$7$g$&!#(B@code{nnml} $B$d(B @code{nnmh} $B$b;H$&;v$,$G$-$^$9$1$I!#(B - -@kbd{a nnspool RET cache RET} $B$HBG$C$F$/$@$5$$!#(B - -$B:#$dA4$/?7$7$$(B @samp{cache} $B$H8F$P$l$k(B @code{nnspool} $B$N;ve$N%5!<%P!<(B -$B$"$k$O$:$G$9!#e$N%5!<%P!<$G(B @kbd{RET} $B$r2!$9$H!"1\Mw%P%C%U%!$KF~$k$Y$-$G!"I=<($5$l(B -$B$F$$$k$I$N%0%k!<%W$K$G$bF~$k;v$,$G$-$k$O$:$G$9!#(B - - -@node Server Variables -@subsection $B%5!<%P!J}$G(B)$B!"(B -$BJQ?t$NDj5A$,%m!<%I$5$l$k$F$$$k4V$K!"$$$/$D$+$NJQ?t$OB>$NJQ?t$+$i=i4|2=$5(B -$B$l$k$H$$$&;v$G$9!#$b$7(B "$B4p$H$J$k(B" $BJQ?t$,%m!<%I$5$l$?8e$KJQ99$7$F$b!"(B"$BF3(B -$B$-=P$5$l$?(B" $BJQ?t$OJQ99$5$l$^$;$s!#(B - -$B$3$l$OIaDL$O%G%#%l%/%H%j!<$d%U%!%$%k$NJQ?t$K1F6A$7$^$9!#Nc$($P!"(B -@code{nnml-directory} $B$O%G%#%U%)%k%H$G(B @file{~/Mail} $B$G$9$,!"A4$F$N(B -@code{nnml} $B%G%#%l%/%H%j!e$N(B @code{nnml} $B%5!<%P!<$rDj5A$7$?>l9g!"(B@code{nnml-directory} $B$r@_Dj(B -$B$9$k$@$1$G$O=$s$@>uBV$K$J$k$h$&$K!"(B -$BA4$F$N%U%!%$%kJQ?t$rL@<(E*$K@_Dj$7$J$1$l$P$J$j$^$;$s!#$=$l$>$l$N%P%C%/%((B -$B%s%I$KBP$9$k40A4$JJQ?t$N%j%9%H$r8+$k$?$a$K$O!"$3$N%^%K%e%"%k$N8e$KB3$/$=(B -$B$l$>$l$N%P%C%/%(%s%I$NItJ,$rFI$s$G$/$@$5$$!#$G$b!"(B@code{nnml} $B$NDj5A$NNc(B -$B$O$3$3$K$"$j$^$9(B: - -@lisp -(nnml "public" - (nnml-directory "~/my-mail/") - (nnml-active-file "~/my-mail/active") - (nnml-newsgroups-file "~/my-mail/newsgroups")) -@end lisp - - -@node Servers and Methods -@subsection $B%5!<%P!<$HJ}K!(B - -$BIaDL$OA*BrJ}K!$r;H$&$H$3$m(B ($BNc$($P!"30It%5!<%P!<$r354Q$7$F$$$k$H$-$N%0%k!<(B -$B%WA*BrJ}K!$G$N(B @code{gnus-secondary-select-method}) $B$O$I$3$G$b!";ve$N(B -$B%5!<%P!$r$=$l$NBe$o$j$K;H$&;v$,$G$-$^$9!#$3$N$3$H$K$h$j$?$/$5$s%-!<%\!<(B -$B%I$rC!$+$J$/$F$9$`2DG=@-$,$"$j$^$9!#$=$7$F!"A4$F$K$o$?$C$F!"$=$NJ}$,NI$$(B -$B$G$9!#(B - - -@node Unavailable Servers -@subsection $B;HMQIT2DG=$J%5!<%P!<(B - -$B$b$7%5!<%P!<$K@\B3IT2DG=$G$"$k$J$i$P!"(Bgnus $B$O%5!<%P!<$r(B @code{$B5qH](B} $B$H$7(B -$B$F0u$rIU$1$^$9!#$3$l$O$=$N8e$N$=$N%5!<%P!<$H$N@\B3$r$O$+$k$I$N$h$&$J;n$_(B -$B$bL5;k$5$l$k$H$$$&;v$G$9!#(BGnus $B$O@\B3$,3+$1$J$$$3$H$,K\Ev$G$"$k$+$I$&$+(B -$B$r>/$7$b3N$+$a$:!"(B``It can't be opend,'' ($B@\B3$r3+$/;v$,$G$-$^$;$s(B) $B$H9p(B -$B$2$^$9!#(B - -$B$=$l$O9T57$,0-$$$H;W$&;v$,$"$k$+$b$7$l$^$;$s$,!"$=$l$O$?$$$F$$$N$H$-$K$O(B -$BNI$$J}K!$G$9!#Nc$($P!"%5!<%P!<(B @samp{nephelococcdyia.com} $B$K(B10$B8D9XFI$7$F(B -$B$$$k%0%k!<%W$,$"$k$H$7$^$7$g$&!#%5!<%P!<$O$I$3$+Hs>o$K1s$/$K$"$j!"%^%7%s(B -$B$O$H$F$bCY$$$N$G!"$=$l$,:#F|$O$"$J$?$H$N@\B3$r5qH]$9$k$+$I$&$+$rD4$Y$k$@(B -$B$1$G(B1$BJ,$+$+$j$^$9!#$b$7(B gnus $B$,$=$l$r(B10$B2s;n$9$h$&$K$J$C$F$$$?$J$i!"$"$J(B -$B$?$OHs>o$K$&$k$5$/;W$&$G$7$g$&!#$G$9$+$i!"(Bgnus $B$O$=$l$r;n$=$&$H$O$7$^$;(B -$B$s!#(B1$BEY(B ``connection refused'' ($B@\B3$O5qH]$5$l$^$7$?(B) $B$rC5n$7$^(B -$B$9(B (@code{gnus-server-remove-denials})$B!#(B -@end table - - -@node Getting News -@section $B%K%e!<%9$NpJs$rJT=8$7$J$1$l$P$J$j$^$;$s(B -(@pxref{Foreign Groups})$B!#(B - -$B30It%0%k!<%W$NL>A0$O4pK\%0%k!<%W$HF1$8$G$"$k;v$,$G$-$^$9!#A0$N>WFM$O5/$3$j$^$;$s!#(B - -$B0J2<$NJQ?t$O;ve$N(B @code{nntp} $B%5!<%P!<$r:n$k$?$a$K;H$o$l$^$9(B: - -@table @code - -@item nntp-server-opened-hook -@vindex gnus-server-opend-hook -@cindex @sc{mode reader} -@cindex authinfo -@cindex authentification -@cindex nntp authentification -@findex nntp-send-authinfo -@findex nntp-send-mode-reader -$B$O@\B3$,$G$-$?8e$Ko$K$3$N%U%C%/$K$"$k$Y$-$G$9!#(B - -@item nntp-authinfo-function -@vindex nntp-authinfo-function -@findex nntp-send-authoinfo -@vindex nntp-authinfo-file -$B$3$N4X?t$O(B @sc{nntp} $B%5!<%P!<$K(B @samp{AUTHINFO} $B$rAw$k$?$a$K;H$o$l$^$9!#(B -$B%G%#%U%)%k%H$N4X?t$O(B @code{nntp-send-authinfo} $B$G!"(B@file{~/.authinfo} -($B$b$7$/$OJQ?t(B @code{nntp-authinfo-file} $B$K@_Dj$7$?$I$N$h$&$J$b$N$G$b(B) $B$r(B -$B;HMQ2DG=$J5-:\$rD4$Y$k$?$a$KC5$7$^$9!#$b$70l$D$b8+$D$+$i$J$+$C$?$i!"$"$J(B -$B$?$K%m%0%$%sL>$H%Q%9%o!<%I$NF~NO$rB%?J$7$^$9!#%U%!%$%k(B -@file{~/.authinfo} $B$NMM<0$O(B ($B$[$H$s$I(B) @code{ftp} $B$N%U%!%$%k(B -@file{~/.netrc} $B$HF1$8$G!"$=$l$O(B @code{ftp} $B$N%^%K%e%"%k%Z!<%8$KDj5A$5$l(B -$B$F$$$^$9$,!"$3$3$N$b$N$O82Cx$J;ve$N9T$r4^$_!"$=$l$>$l$O0l$D$N%5!<%P!<$rDj5A$7$^$9!#(B - -@item -$B$=$l$>$l$N9T$OG$0U$N?t$N(B $B6h@Z$j0u(B/$BCM(B $B$NBP$r4^$`;v$,$G$-$^$9!#M-8z$J6h@Z(B -$B$j0u$O(B @samp{machine}$B!"(B@samp{login}$B!"(B@samp{password}$B!"(B@samp{default}$B!"(B -@samp{force} $B$G$9!#(B($B:G8e$N$b$N$OM-8z$J(B @code{.netrc}/@code{ftp} $B$N6h@Z$j(B -$B0u$G$O$"$j$^$;$s!#$3$l$,%U%!%$%k(B @file{.authinfo} $B$,(B @file{.netrc} $B%U%!(B -$B%$%kMM<0$+$i0o$l$kM#0l$NJ}K!$G$9!#(B) - -@end enumerate - -$B$3$l$,$=$N%U%!%$%k$NNc$G$9(B: - -@example -machine news.uio.no login larsi password geheimnis -machine nntp.ifi.uio.no login larsi force yes -@end example - -$B6h@Z$j0u(B/$BCM(B $B$NBP$O$I$N$h$&$J=gHV$G$G$b8=$l$k;v$,$G$-$^$9!#Nc$($P!"(B -@samp{machine} $B$O:G=i$K8=$l$kI,MW$O$"$j$^$;$s!#(B - -$B$3$NNc$G$O!"%m%0%$%sL>$H%Q%9%o!<%I$NN>J}$,A0$@$1$r5s$2$F$$$F!"MxMQZ>pJs(B (authinfo) $B$,Aw$i$l$k$H$$$&;v$G$9!#%G%#%U%)(B -$B%k%H(B ($B$9$P$o$A!"(B@samp{force} $B%?%0$,L5$$$H$-(B) $B$G$O(B @var{nntp} $B%5!<%P!<$,(B -$BG'>Z>pJs$r?R$M$J$$8B$j$=$l$r(B @var{nntp} $B%5!<%P!<$KAw$j$^$;$s!#(B - -@samp{machine} $B9T$K9gCW$7$J$$A4$F$N%5!<%P!<$KE,MQ$5$l$k(B @samp{default} -$B9T$rDI2C$9$k;v$b$G$-$^$9!#(B - -@example -default force yes -@end example - -$B$3$l$O0JA0$K=q$+$l$F$$$J$$A4$F$N%5!<%P!<$KL?Na(B @samp{AUTHINFO} $B$r6/@)E*(B -$B$KAw$j$^$9!#(B - -$B%U%!%$%k(B @file{~/.authinfo} $B$r@$3&Cf$,FI$a$k$h$&$J@_Dj$KJ|CV$7$J$$$h$&$K(B -$BCm0U$7$F$/$@$5$$!#(B - -@item nntp-server-action-alist -@vindex nntp-server-action-alist -$B$3$l$O%5!<%P!<$N7?$K9gCW$9$k@55,I=8=$H!"9gCW$,5/$3$C$?$H$-$Kc$,$A$G$"$k$J$i!"$3$NJQ?t$r(B1$B$K@_Dj$9$k$Y$-$G$7$g$&!#(B - -@item nntp-connection-timeout -@vindex nntp-connection-timeout -$BDj4|E*$K@\B3$9$k30It(B @code{nntp} $B%0%k!<%W$,$?$/$5$s$"$k$J$i!"E,@Z$K1~Ez(B -$B$7$J$$(B @code{nntp} $B%5!<%P!<$,$"$C$?$j!"$"$k%5!<%P!<$O>o<1E*$J;~4VFb$G$O(B -$BJVEz$G$-$J$$$/$i$$Ii2Y$,$+$+$C$F$$$k!"$J$I$NLdBj$,$"$k$G$7$g$&!#$3$l$O:$$C(B -$B$?LdBj$K$J$k$3$H$,$"$j$^$9$,!"(B@code{nntp-connection-timeout} $B$r@_Dj$9$k(B -$B;v$K$h$j$"$kDxEY2r>C$9$k;v$,$G$-$^$9!#$3$l$O@\B3$r$"$-$i$a$k$^$($K!"(B -@code{nntp} $B%P%C%/%(%s%I$,2?ICBT$D$+$r<($9@0?t$G$9!#$b$7$3$l$,(B -@code{nil} $B$G$"$k$H!"$3$l$,=i4|@_Dj$G$9$,!";~4V@Z$l@ZCG$O$J$5$l$^$;(B -$B$s!#(B - -@c @item nntp-command-timeout -@c @vindex nntp-command-timeout -@c @cindex PPP connections -@c @cindex dynamic IP addresses -@c If you're running Gnus on a machine that has a dynamically assigned -@c address, Gnus may become confused. If the address of your machine -@c changes after connecting to the @sc{nntp} server, Gnus will simply sit -@c waiting forever for replies from the server. To help with this -@c unfortunate problem, you can set this command to a number. Gnus will -@c then, if it sits waiting for a reply from the server longer than that -@c number of seconds, shut down the connection, start a new one, and resend -@c the command. This should hopefully be transparent to the user. A -@c likely number is 30 seconds. -@c -@c @item nntp-retry-on-break -@c @vindex nntp-retry-on-break -@c If this variable is non-@code{nil}, you can also @kbd{C-g} if Gnus -@c hangs. This will have much the same effect as the command timeout -@c described above. - -@item nntp-server-hook -@vindex nntp-server-hook -$B$3$N%U%C%/$O(B @sc{nntp} $B%5!<%P!<$K@\B3$9$k:G8e$N0lJb$H$7$F$N$b$K@\B3$7$^$9!#(B - -@item nntp-open-rlogin -@samp{rlogin} $B$r1s3V%7%9%F%`$K9T$C$F!"$=$3$+$i;EMM2DG=$J(B @sc{nntp} $B%5!<(B -$B%P!<$K(B @samp{telnet} $B$r$7$^$9!#(B - -@code{nntp-open-rlogin} $B$K4XO"$7$?JQ?t$G$9(B: - -@table @code - -@item nntp-rlogin-program -@vindex nntp-rlogin-program -$B1s3V%^%7%s$K%m%0%$%s$r$9$k$?$a$K;H$o$l$k%W%m%0%i%`$G$9!#%G%#%U%)%k%H$O(B -@samp{rsh} $B$G$9$,!"(B@samp{ssh} $B$,?M5$$N$"$kBeBX$G$9!#(B - -@end table - -@item nntp-open-telnet -$B1s3V%7%9%F%`$K(B @samp{telnet} $B$r$7$F!"(B@sc{nntp} $B%5!<%P!<$K$?$I$jCe$/$?$a(B -$B$K$b$&0lEY(B @code{telnet} $B$r$7$^$9!#(B - -@code{nntp-open-telnet} $B$K4XO"$7$?JQ?t$G$9(B: - -@table @code -@item nntp-telnet-command -@vindex nntp-telnet-command -@code{telnet} $B$r;O$a$k$N$K;H$o$l$kL?Na$G$9!#(B - -@item nntp-telnet-switches -@vindex nntp-telnet-switches - -$BL?Na(B @code{telnet} $B$N%9%$%C%A(B (switch) $B$H$7$F;H$o$l$kJ8;zNs$N%j%9%H$G$9!#(B - -@item nntp-telnet-user-name -@vindex nntp-telnet-user-name -$B1s3V%7%9%F%`$K%m%0%$%s$9$k$?$a$NMxMQ$G$9!#(B - -@item nntp-telnet-passwd -@vindex nntp-telnet-passwd -$B%m%0%$%s$9$k$H$-$K;H$o$l$k%Q%9%o!<%I$G$9!#(B - -@item nntp-telnet-parameters -@vindex nntp-telnet-parameters -@code{telnet} $B$G%m%0%$%s$r$7$?8e$KL?Na$H$7$F *\r?} $B$G$9!#(B - -@item nntp-open-telnet-envuser -@vindex nntp-open-telnet-envuser -@code{nil} $B$G$J$$$J$i!"(B@code{telnet} $B%;%C%7%g%s$O(B ($B%/%i%$%"%s%H$H%5!<%P!<(B -$B$NN>J}$G(B) @code{ENVIRON} $B%*%W%7%g%s$r;HMQ$9$k;v$,$G$-!"%m%0%$%sL>F~NO$r(B -$BB%?J$7$^$;$s!#$3$l$O$?$H$($P(B Solaris $B$N(B @code{telnet} $B$KBP$7$FF0:n$7$^$9!#(B - -@end table - -@findex nntp-open-ssl-stream -@item nntp-open-ssl-stream -$B%5!<%P!<$K(B @dfn{$B0BA4$J(B} $B%A%c%s%M%k$r;H$C$F%5!<%P!<$K@\B3$7$^$9!#$3$l$r;H(B -$B$&$?$a$K$O!"(BSSLay $B$,%$%s%9%H!<%k$5$l$F$$$J$1$l$P$J$j$^$;$s(B -(@file{ftp://ftp.psy.uq.oz.au/pub/Crypto/SSL} $B$H!"(B@file{ssl.el} ($BNc$($P!"(B -W3 $B$NG[I[$+$i(B) $B$,I,MW$K$J$j$^$9(B)$B!#$=$l$+$i%5!<%P!<$r$G$9!#(B - -@item nntp-address -@vindex nntp-address -@sc{nntp} $B%5!<%P!<$,F0$$$F$$$k1s3V%7%9%F%`$N%"%I%l%9$G$9!#(B - -@item nntp-port-number -@vindex nntp-port-number -@code{nntp-open-network-stream} $B@\B34X?t$r;H$C$F$$$k$H$-$N@\B3$9$k%]!<%H(B -$BHV9f$G$9!#(B - -@item nntp-buggy-select -@vindex nntp-buggy-select -$B$"$J$?$NA*Br$N0lO"$N:n6H$,8N>c$,$A$G$"$k$H$-$K$3$l$r(B @code{nil} $B$G$J$$CM(B -$B$K@_Dj$7$F$/$@$5$$!#(B - -@item nntp-nov-is-evil -@vindex nntp-nov-is-evil -@sc{nntp} $B%5!<%P!<$,(B @sc{nov} $B5!G=$rDs6!$7$F$$$J$1$l$P$3$NJQ?t$r(B -@code{t} $B$K@_Dj$9$k;v$,$G$-$^$9$,!"(B@code{nntp} $B$OIaDL$O(B @sc{nov} $B$,;H$o(B -$B$l$k$+$I$&$+$r<+F0E*$KD4$Y$^$9!#(B - -@item nntp-xover-commands -@vindex nntp-xover-commands -@cindex nov -@cindex XOVER -$B%5!<%P!<$+$i(B @sc{nov} $B9T$rl9g$O!"$3$NJQ?t$rK\Ev(B -$B$K>.$5$J?t;z$K@_Dj$9$k$H$*$=$i$//$7;(2;$,$?(B -$B$F$i$l$^$9!#(B - -@item nntp-record-commands -@vindex nntp-record-commands -$B$b$7(B @code{nil} $B$G$J$$$H!"(B@code{nntp} $B$O(B @sc{nntp} $B%5!<%P!<$KAw$C$?A4$F(B -$B$NL?Na$r(B ($B;~4V$H6&$K(B) @samp{*nntp-log*} $B%P%C%U%!$K5-O?$7$^$9!#$3$l$OF0:n(B -$B$7$F$$$J$$$H;W$o$l$k(B gnus/@sc{nntp} $B@\B3$r%G%#%P%C%0$7$F$$$k$H$-$KLr$KN)(B -$B$A$^$9!#(B - -@end table - - -@node News Spool -@subsection $B%K%e!<%9%9%W!<%k(B -@cindex nnsppl -@cindex new spool - -$B%m!<%+%k%9%W!<%k$+$i30It%0%k!<%W$r9XFI$9$k;v$OHs>o$K4JC1$G!"Lr$KN)$A$^$9!#(B -$B$?$H$($P!"Hs>o$KBg$-$J5-;v$,$"$k%0%k!<%W(B---$BNc$($P(B -@samp{alt.binaries.pictures.furniture} $B$rFI$`B.EY$,B.$/$J$j$^$9!#(B - -$B$H$K$+$/!"(B@code{nnspool} $B$rJ}K!$H$7$F!"(B @code{""} ($B$b$7$/$O2?$G$b(B) $B$r%"(B -$B%I%l%9$H$7$F;XDj$9$k$@$1$G$9!#(B - -$B$b$7%m!<%+%k%9%W!<%k$K$D$J$0;v$,2DG=$J$i!"$*$=$i$/$=$l$r4pK\A*BrJ}K!$H$7(B -$B$F;H$&$Y$-$G$7$g$&(B (@pxref{Finding the News})$B!#$=$l$OIaDL$O(B @code{nntp} -$BA*BrJ}K!$h$jB.$$$G$9$,!"$=$&$G$J$$$+$b$7$l$^$;$s!#$=$l$O>u67$K0MB8$7$^$9!#(B -$B2?$,$"$J$?$N%5%$%H$G0lHVNI$$$+$r8+$D$1$k$?$a$K!"$$$m$$$m$H;n$7$F$_$J$1$l(B -$B$P$J$j$^$;$s!#(B - -@table @code - -@item nnspool-inews-program -@vindex nnspool-inews-program -$B5-;v$rEj9F$9$k$?$a$K;H$o$l$k%W%m%0%i%`$G$9!#(B - -@item nnspool-inews-switches -@vindex nnspool-inews-switches -$B5-;v$rEj9F$9$k$H$-$K(B inews $B%W%m%0%i%`$KM?$($i$l$k%Q%i%a!<%?$G$9!#(B - -@item nnspool-spool-directory -@code{nnspool} $B$,5-;v$rC5$9$H$3$m$G$9!#$3$l$OIaDL$O(B -@file{/usr/spool/news/} $B$G$9!#(B - -@item nnspool-nov-directory -@vindex nnspool-nov-directory -@code{nnspool} $B$,(B @sc{nov} $B%U%!%$%k$rC5$9$H$3$m$G$9!#$3$l$OIaDL$O(B -@file{/usr/spool/news/over.view/} $B$G$9!#(B - -@item nnspool-lib-dir -@vindex nnspool-lib-dir -$B%K%e!<%9$N%i%$%V%i%j!<%G%#%l%/%H%j!<$N>l=j$G$9(B ($B%G%#%U%)%k%H$G(B -@file{/usr/lib/news/} $B$G$9(B)$B!#(B - -@item nnspool-active-file -@vindex nnspool-active-file -$B8=>u%U%!%$%k$X$N%Q%9$G$9!#(B - -@item nnspool-newsgroups-file -@vindex nnspool-newsgroups-file -$B%0%k!<%W5-=R%U%!%$%k$X$N%Q%9$G$9!#(B - -@item nnspool-history-file -@vindex nnspool-history-file -$B%K%e!<%9MzNr%U%!%$%k$X$N%Q%9$G$9!#(B - -@item nnspool-active-times-file -@vindex nnspool-active-times-file -$B8=>uF|IU%U%!%$%k$X$N%Q%9$G$9!#(B - -@item nnspool-nov-is-evil -@vindex nnspool-nov-is-evil -@code{nil} $B$G$J$$$H!"(B@code{nnspool} $B$O$=$l$,8+$D$1$?$I$s$J(B @sc{nov} $B%U%!(B -$B%$%k$b;H$*$&$H$O$7$^$;$s!#(B - -@item nnspool-sift-nov-with-sed -@vindex nnspool-sift-nov-with-sed -@cindex sed -@code{nil} $B$G$J$$$H!"$3$l$,%G%#%U%)%k%H$G$9$,!"354Q%U%!%$%k(B (overview) -$B$+$i4XO"$9$kItJ,$rF@$k$?$a$K(B @code{sed} $B$r;H$$$^$9!#$b$7(B nil $B$@$H!"(B -@code{nnspool} $B$O%U%!%$%kA4BN$r%P%C%U%!$KFI$_9~$s$G!"$=$3$G$N%U%!%$%k$rFI$`$?$a$K%a!<%k%P%C%/%(%s%I$r;H$&!#(B -* Choosing a Mail Backend:: Gnus $B$O?'!9$J%a!<%kMM<0$rFI$`;v$,$G$-$k!#(B -@end menu - - -@node Getting Started Reading Mail -@subsection $B%a!<%k$rFI$`;v$r;O$a$k(B - -Gnus $B$r;H$C$F?7$7$$%a!<%k$rFI$`;v$OHs>o$K4JC1$G$9!#$"$J$?$N%a!<%k%P%C%/(B -$B%(%s%I$N$"$J$?$NA*Br$r(B @code{gnus-secondary-select-methods} $B$KJ|$j9~$`$@(B -$B$1$G!"$"$H$N$3$H$O<+F0E*$K5/$3$j$^$9!#(B - -$BNc$($P!"(B@code{nnml} ($B$3$l$O(B "$B0l%a!<%k0l%U%!%$%k(B" $B%P%C%/%(%s%I$G$9(B) $B$r;H(B -$B$$$?$$$J$i!"$N%0%k!<%W$HF1$8$h$&$KFI$`;v$,$G$-$^$9!#(B - -$B$"$J$?$O$*$=$i$/%a!<%k$r$$$/$D$+$N%0%k!<%W$KJ,3d$7$?$$$G$7$g$&$1$I(B: - -@lisp -(setq nnmail-split-methods - '(("junk" "^From:.*Lars Ingebrigtsen") - ("crazy" "^Subject:.*die\\^Organization:.*flabby") - ("other" ""))) -@end lisp - -$B$3$l$O7k2L$H$7$F(B3$B$D$N?7$7$$(B @code{nnml} $B%a!<%k%0%k!<%W$r:n$j$^$9(B: -@samp{nnml:junk}$B!"(B@samp{nnml:crazy}$B!"(B@samp{nnml:other} $B$G$9!#:G=i$N(B2$B$D$N(B -$B%0%k!<%W$K9g$o$J$$%a!<%k$OA4$F:G8e$N%0%k!<%W$KF~$l$i$l$^$9!#(B - -$B$3$l$O(B gnus $B$G%a!<%k$rFI$`$?$a$K=$N9`$r=OFI$7$?$$$H;W$&$+$b$7$l$^$;$s$,!#FC$K(B @pxref{Choosing a Mail -Backend} $B$H(B @pxref{Expiring Mail} $B$r!#(B - - -@node Splitting Mail -@subsection $B%a!<%k$NJ,3d(B -@cindex splitting mail -@cindex mail splitting - -@vindex nnmail-split-methods -$BJQ?t(B @code{nnmail-split-methods} $B$OF~$C$F$/$k%a!<%k$r$I$N$h$&$K%0%k!<%W(B -$BJ,$1$9$k$+$r;XDj$7$^$9!#(B - -@lisp -(setq nnmail-split-methods - '(("mail.junk" "^From:.*Lars Ingebrigtsen") - ("mail.crazy" "^Subject:.*die\\|^Organization:.*flabby") - ("mail.other" ""))) -@end lisp - -$B$3$NJQ?t$O%j%9%H$N%j%9%H$G!"$3$l$i$N%j%9%H$N:G=i$N$=$l$>$l$NMWAG$,%a!<%k(B -$B%0%k!<%W$NL>A0$G(B ($B$H$3$m$G!"$=$l$i$O(B @samp{mail} $B$G;O$^$kI,MW$O$"$j$^$;(B -$B$s(B)$B!"(B2$B$D$a$NMWAG$,$=$l$>$l$N%a!<%k$N%X%C%@!<$+$i$=$l$,$I$N%0%k!<%W$KB0$9(B -$B$k$+$r7hDj$9$k@55,I=8=$G$9!#:G=i$NJ8;zNs$O!"(B@code{replace-match} $B$K$h$C(B -$B$F!"9gCW$7$?J8>O$+$i$NI{I=8=$rA^F~$9$k$?$a$K;H$o$l$k$h$&$J!"(B -@code{samp\\1} $B$NMM<0$r4^$`$+$b$7$l$^$;$s!#$?$H$($P(B: - -@lisp -("list.\\1" "From:.*\\(.*\\)-list@@majordomo.com") -@end lisp - -2$BHVL\$NMWAG$O4X?t$G$"$k;v$b$G$-$^$9!#$=$N>l9g$O!"$=$l$OK!B'$N:G=i$NMWAG(B -$B$r0z?t$H$7$F!"%X%C%@!<$KHO0O$r69$a$F(B (narrowed to headers) $B8F$P$l$^$9!#(B -$B$=$l$O!"%a!<%k$,$=$N%0%k!<%W$KB0$9$k$H9M$($k$N$G$"$l$P!"(B@code{nil} $B$G$J(B -$B$$CM$r5"$9I,MW$,$"$j$^$9!#(B - -$B$3$l$i$N:G8e$O>o$KAm9gE*$J$b$N$G$"$k$Y$-$G!"B>$N@55,I=8=$K9gCW$7$J$$%a!<(B -$B%k$K9gCW$9$k$?$a$K!"$3$N@55,I=8=$O(B @emph{$B$$$D$b(B} @samp{}$B$G$"$k$Y$-$G$9!#(B -($B$3$l$i$NK!B'$OO"A[%j%9%H$N=i$a$+$i=*$o$j$^$G=gHV$K!$A$^(B -$B$9(B"$B!#Aj8_Ej9F$r;HMQ2DG=$K$7$F$$$k>l9g!"A4$F$N9gCW$7$?K!B'$,(B "$B>!$A$^$9(B"$B!#(B) - -$B$b$7$"$J$?<+?H$G$3$l$r$$$8$/$j$^$o$7$?$$$H$-$O!"$"$J$?$NA*$s$@4X?t$r$3$N(B -$BJQ?t$K@_Dj$9$k;v$,$G$-$^$9!#$3$N4X?t$OF~$C$FMh$?%a!<%k%a%C%;!<%8$N%X%C%@!<(B -$B$KHO0O$r69$a$i$l$?%P%C%U%!$G0z?t$J$7$G8F$P$l$^$9!#$3$N4X?t$O!"$=$l$,$3$N(B -$B%a!<%k%a%C%;!<%8$r1?$V$Y$-$G$"$k!"$H9M$($k%0%k!<%WL>$N%j%9%H$rJV$9$Y$-$G(B -$B$9!#(B - -$BA4$F$N%a!<%k%P%C%/%(%s%I$O!"F~$C$FMh$?IOK3$G=c?h$J%X%C%@!<$rMpK=$K07$C$F(B -$B$bNI$$;v$KCm0U$7$F$/$@$5$$!#$=$l$i$O$9$Y$F(B @code{Lines} $B%X%C%@!<$rDI2C$7(B -$B$^$9!#$$$/$D$+$O(B @code{X-Gnus-Group} $B%X%C%@!<$r2C$($^$9!#$?$$$F$$$N$b$N(B -$B$O(B Unix $B$N(B mbox $B$N(B @code{From} $B9T$r2?$+JL$NL>A0$KJQ$($^$9!#(B - -@vindex nnmail-crosspost -$B%a!<%k%P%C%/%(%s%I$O$9$Y$FAj8_Ej9F$N5!G=$rDs6!$7$F$$$^$9!#$$$/$D$+$N@55,(B -$BI=8=$,9gCW$9$k$H!"%a!<%k$OA4$F$N%0%k!<%W$K(B ``$BAj8_Ej9F(B'' $B$5$l$^$9!#(B -@code{nnmail-crosspost} $B$O$3$N5!G=$r;H$&$+$I$&$+$r;XDj$7$^$9!#$I$N5-;v$b(B -$BAm9g$N(B (@samp{}) $B%0%k!<%W$KAj8_Ej9F$5$l$J$$;v$KCm0U$7$F$/$@$5$$!#(B - -@vindex nnmail-crosspost-link-function -@cindex crosspost -@cindex links -@code{nnmh} $B$H(B @code{nnml} $B$OAj8_Ej9F$5$l$?5-;v$K%O!<%I%j%s%/(B (hardlink) -$B$r:n$k;v$K$h$C$FAj8_Ej9F$r9T$$$^$9!#$7$+$7!"A4$F$N%U%!%$%k%7%9%F%`$,%O!<(B -$B%I%j%s%/$N5!G=$rDs6!$7$F$$$k$o$1$G$O$"$j$^$;$s!#$b$7$"$J$?$,$=$N>l9g$KEv(B -$B$F$O$^$k$N$G$"$l$P!"(B@code{nnmail-crosspost-link-function} $B$r(B -@code{copy-file} $B$K@_Dj$7$F$/$@$5$$!#(B ($B$3$NJQ?t$O%G%#%U%)%k%H$G(B -@code{add-name-to-file} $B$G$9!#(B) - -@kindex M-x nnmail-split-history -@kindex nnmail-split-history -$BA0$N%a!<%kJ,3d$,%a%C%;!<%8$r$I$3$KF~$l$?$+$r8+$?$$>l9g$O!"L?Na(B @kbd{M-x -nnmail-split-history} $B$r;H$&;v$,$G$-$^$9!#(B - -Gnus $B$O$"$J$?$K<+J,<+?H$KD7$MJV$C$F$/$k$h$&$J2DG=@-$N$"$kA4$F$N5!2q$rDs(B -$B6!$7$^$9!#Nc$($P!"$"$J$?$N>e;J$+$i$/$kA4$F$N%a!<%k$r4^$s$@%0%k!<%W$r:n$C(B -$B$?$H$7$^$7$g$&!#$=$l$+$i!"6vH/E*$K$=$N%0%k!<%W$N9XFIe;J$+$i$NA4$F$N%a!<%k$rL$9XFI$N%0%k!<%W$KF~$l$^(B -$B$9$N$G!">e;J$,(B ''$B7nMKF|$^$G$K$=$NJs9p=q$r=`Hw$7$J$$$Hl9g(B) $BA4$F$N0c$C$?%a!<%k%P%C%/%(%s%I$K4XO"$7$^(B -$B$9!#(B - -@table @code -@vindex nnmail-read-incoming-hook -@item nnmail-read-incoming-hook -$B%a!<%k%P%C%/%(%s%I$O?7$7$$%a!<%k$rFI$_9~$s$@8e$K$3$N%U%C%/$r8F$S$^$9!#$b(B -$B$7$=$&$7$?$$$H;W$&$J$i!"$3$N%U%C%/$r%a!<%k4F;k%W%m%0%i%`$KCN$i$;$k$?$a$K(B -$B;H$&;v$,$G$-$^$9!#(B - -@vindex nnmail-spool-file -@item nnmail-spool-file -@cindex POP mail -@cindex MAILHOST -@cindex movemail -@vindex nnmail-pop-password -@vindex nnmail-pop-password-required -$B%P%C%/%(%s%I$O$3$N%U%!%$%k$G?7$7$$%a!<%k$rC5$7$^$9!#$3$NJQ?t$,(B -@code{nil} $B$G$"$k$H!"%a!<%k%P%C%/%(%s%I$O7h$7$F<+J,<+?H$G$O%a!<%k$rA0$,(B -@samp{larsi} $B$G$"$k$J$i$P!"$3$NJQ?t$r(B @samp{po:larsi} $B$K@_Dj$9$k$Y$-$G$9!#(B -$B$b$7$"$J$?$NL>A0$,(B @samp{larsi} $B$G$J$$$J$i$P!"$*$=$i$/$3$l$r>/$7=$@5$7$J(B -$B$1$l$P$J$j$^$;$s$,!"4{$K$"$J$?$O$=$l$r?dB,$7$F$$$k$G$7$g$&!#$3$N8-$/4iN)(B -$B$A$NNI$$0-Kb$5$s!*(B $B$3$NJQ?t$r(B @code{pop} $B$K@_Dj$9$k;v$b$G$-!"$=$N;~$O(B -gnus $B$,<+J,<+?H$G(B POP $B%a!<%kJ8;zNs$rH/8+$7$h$&$H$7$^$9!#$I$N$h$&$J>l9g$G(B -$B$b!"(Bgnus $B$O(B $B4D6-JQ?t(B @code{MAILHOST} $B$G;XDj$5$l$F$$$k(B POP $B%5!<%P!<$K@\?((B -$B$r?^$m$&$H$9$k(B @code{movemail} $B$r8F$S$^$9!#(BPOP $B%5!<%P!<$,%Q%9%o!<%I$rI,(B -$BMW$H$9$k$J$i!"(B@code{nnmail-pop-password-required} $B$r(B @code{t} $B$K@_Dj$7$F(B -$B%Q%9%o!<%IF~NO$rB%?J$5$l$k$+!"(B@code{nnmail-pop-password} $B$r%Q%9%o!<%I$=(B -$B$N$b$N$K@_Dj$9$k;v$,$G$-$^$9!#(B - -@code{nnmail-spool-file} $B$O%a!<%k%\%C%/%9$N%j%9%H$G$"$k;v$b$G$-$^$9!#(B - -$B$"$J$?$N(B Emacs $B$,(B $B%3%s%Q%$%k(B (compilation) $B$NA0$K(B @samp{--with-pop} $B$H6&(B -$B$K4D6-@_Dj(B (configure) $B$5$l$J$1$l$P$J$j$^$;$s!#$3$l$O%G%#%U%)%k%H$G$9$,!"(B -$B$$$/$D$+$N%$%s%9%H!<%k$O$=$N@_Dj$r@Z$C$F$7$^$$$^$9!#(B - -$B%a!<%k%P%C%/%(%s%I$r;H$&$H$-$O!"(Bgnus $B$OA4$F$N%a!<%k$r(B inbox $B$+$i5[$$>e$2(B -$B$F!"%[!<%`%G%#%l%/%H%j!<$KJ|$jEj$2$^$9!#$"$J$?$,%a!<%k%P%C%/%(%s%I$r;H$C(B -$B$F$$$J$$>l9g$O!"(Bgnus $B$O(B1$BDL$b%a!<%k$r0\F0$7$^$;$s(B---$B:G=i$KKbK!$N8F$S=P$7(B -$B$r$?$/$5$s$7$J$1$l$P$J$j$^$;$s!#$^$:(B5$B3Q7A$rIA$-!"O9?$$K2P$rIU$1!";3MS$r(B -$B@8$1lS$H$7$FJ{$2=*$($?8e$G!"(Bgnus $B$,$"$J$?$N%a!<%k$r0\F0$7$F$bK\Ev$K$"$^(B -$B$j6C$$$F$O$$$1$^$;$s!#(B - -@vindex nnmail-use-procmail -@vindex nnmail-procmail-suffix -@item nnmail-use-procmail -$B$b$7(B @code{nil} $B$G$J$1$l$P!"%a!<%k%P%C%/%(%s%I$OF~$C$F$/$k%a!<%k$r(B -@code{nnmail-procmail-directory} $B$GC5$7$^$9!#$=$N%G%#%l%/%H%j!<$G(B -@code{nnmail-procmail-suffix} $B$G=*$o$C$F$$$kL>A0$r;}$DA4$F$N%U%!%$%k$OF~$C(B -$B$FMh$?%a!<%k%\%C%/%9$H$_$J$5$l!"$=$3$G?7$7$$%a!<%k$,C5$5$l$^$9!#(B - -@vindex nnmail-crash-box -@item nnmail-crash-box -$B%a!<%k%P%C%/%(%s%I$,%9%W!<%k%U%!%$%k$rFI$s$@$H$-$K!"%a!<%k$O:G=i$K$3$N%U%!(B -$B%$%k$K0\F0$5$l$^$9!#$3$l$O%G%#%U%)%k%H$G(B @file{~/.gnus-crash-box} $B$G$9!#(B -$B$3$N%U%!%$%k$,4{$KB8:_$9$k>l9g$O!"$=$l$O>o$KB>$N%9%W!<%k%U%!%$%k$h$j@h$K(B -$BFI$_9~$^$l(B ($B$=$7$F$l$N%a%C%;!<%8$,$=$N%X%C%@!<$K4p$E$$$FJ,3d$,$J$5$l$kD>A0$K$=$l$,J](B -$BB8$5$l$F$$$k%P%C%U%!$GC5n$5$l!"%P%C%U%!$G9T$o$l$?JQ99$O$I$N%U%!%$%k$K$b8=$l$^$;(B -$B$s!#(B@code{gnus-article-decode-rfc1522} $B$,$3$N%U%C%/$K2C$($k;v$,E,@Z$J4X(B -$B?t$N0l$D$G$9!#(B - -@vindex nnmail-pre-get-new-mail-hook -@vindex nnmail-post-get-new-mail-hook -@item nnmail-pre-get-new-mail-hook -@itemx nnmail-post-get-new-mail-hook -$B$3$l$i$OF~$C$F$/$k%a!<%k$r07$&$H$-$KA0$K8F$P(B -$B$l$^$9(B) $B$H(B @code{nnmail-post-get-new-mail-hook} ($B$3$l$O%a!<%k$N07$$$,=*(B -$B$o$C$?$H$-$K8F$P$l$^$9(B) $B$G$9!#l9g$O!"$=$N4X?t$O(B2$B$D$N%Q%i%a!<%?(B -- -$B%$%s%\%C%/%9$NL>A0$H0\F0$9$k%U%!%$%kL>A0(B $B$H6&$K8F$P$l$^$9!#(B - -@item nnmail-delete-incoming -@vindex nnmail-delete-incoming -@cindex incoming mail files -@cindex deleting incoming files -@code{nil} $B$G$J$$$J$i!"%a!<%k%P%C%/%(%s%I$O%a!<%k$rE,@Z$J%0%k!<%W$XJ,3d$7$?8e$G0l;~?7F~%U%!%$%k$r>C5n$7$^$9!#$3$l$O%G%#%U%)%k%H$G(B @code{t} $B$G$9!#(B - -@c This is @code{nil} by -@c default for reasons of security. - -@c Since Red Gnus is an alpha release, it is to be expected to lose mail. -((ding) Gnus 0.10 ($B$b$7$/$O$=$N$h$&$J$b$N(B) $B$+$i$N(B Gnus $B$N%j%j!<%9$O;d$,(B -$B;W$&$K%a!<%k$r<:$C$?;v$O$J$$$N$G$9$,!"$G$b$=$N$3$H$O$3$3$G$O=EMW$G$O$"$j(B -$B$^$;$s!#(B ($BFCJL$J%P!<%8%g%s$N(B Red Gnus $B$r=|$-$^$9!#(B)) Incoming* $B%U%!%$%k(B -$B$r>C5n$7$J$$;v$G!"%a!<%k$r<:$o$J$$;v$r3NC5n$9$k;v$,$G$-$^$9!#(B - -@item nnmail-use-long-file-names -@vindex nnmail-use-long-file-names -@code{nil} $B$G$J$$$J$i!"%a!<%k%P%C%/%(%s%I$OD9$$%U%!%$%kL>$H%G%#%l%/%H%j!<(B -$BL>$r;H$$$^$9!#(B@samp{mail.misc} $B$N$h$&$J%0%k!<%WL>$O(B @file{mail.misc} $B$H(B -$B$$$&%G%#%l%/%H%j!<(B (@code{nnml} $B%P%C%/%(%s%I$,;H$o$l$F$$$k$H$_$J$9$H(B) $B$+(B -$B%U%!%$%k(B (@code{nnfolder} $B%P%C%/%(%s%I$,;H$o$l$F$$$k$H$_$J$9$H(B) $B$H$$$&7k(B -$B2L$K$J$j$^$9!#$b$7$=$l$,(B @code{nil} $B$G$"$k$J$i!"F1$8%0%k!<%W$O(B -@file{mail/misc} $B$H$$$&7k2L$K$J$j$^$9!#(B - -@item nnmail-delete-file-function -@vindex nnmail-delete-file-function -@findex delete-file -$B%U%!%$%k$r>C5n$9$k$?$a$K8F$P$l$k4X?t$G$9!#%G%#%U%)%k%H$G(B -@code{delete-file} $B$G$9!#(B - -@item nnmail-cache-accepted-message-ids -@vindex nnmail-cache-accepted-message-ids -@code{nil} $B$G$J$$$H!"%P%C%/%(%s%I$KF~$C$FMh$?5-;v(B ($BNc$($P!"(B@code{Gcc} $B$K(B -$B$h$C$F(B) $B$N(B @code{Message-ID} $B$r%a!<%k=EJ#H/8+%U%!%$%k$KF~$l$^$9!#%G%#%U%)(B -$B%k%H$O(B @code{nil} $B$G$9!#(B - -@end table - -@node Fancy Mail Splitting -@subsection $BFC5i%a!<%kJ,3d(B -@cindex mail splitting -@cindex fancy mail splitting - -@vindex nnmail-split-fancy -@findex nnmail-split-fancy -$BHf3SE*C1=c$JI8=`$N%a!<%kJ,3d;XDj$NJ}K!$G$O$"$J$?$NK>$`;v$,$G$-$J$$>l9g!"(B -@code{nnmail-split-methods} $B$r(B @code{nnmail-split-fancy} $B$K@_Dj$9$k;v$,(B -$B$G$-$^$9!#$=$l$+$iJQ?t(B @code{nnmail-split-fancy} $B$GM7$V;v$,$G$-$^$9!#(B - -$B$^$:$3$NJQ?t$NCM$NNc$r8+$F$_$^$7$g$&(B: - -@lisp -;; $B%a!<%k%G!<%b%s(B (mailer deamon) $B$OIaDL$N%0%k!<%W$K$OAj8_Ej9F$5$l$^$;(B -;; $B$s!#7Y9p$OK\Ev$N%(%i!<$H$O0c$C$?%0%k!<%W$KF~$l$i$l$^$9!#(B -(| ("from" mail (| ("subject" "warn.*" "mail.warning") - "mail.misc")) - ;; $B%(%i!<$G$J$$%a%C%;!<%8$OA4$F$N4XO"$7$?%0%k!<%W$KAj8_Ej9F$5$l$^$9(B - ;; $B$,!"(B(ding) $B%j%9%H$HB>$N(B (ding) $B4XO"$N%a!<%k$N$?$a$N%0%k!<%W$K$O(B - ;; $BAj8_Ej9F$7$^$;$s!#(B - (& (| (any "ding@@ifi\\.uio\\.no" "ding.list" "ding.list") - ("subject "ding" "ding.misc")) - ;; $BB>$N%a!<%j%s%0%j%9%H(B... - (any "procmail@@informatik\\.rwth-aachen\\.de" "procmail.list") - (any "SmartList@@informatik\\.rwth-aachen\\.de" "SmartList.list") - ;; $B?M!9(B... - (any "larsi@@ifi\\.uio\\.no" "people.Lars_Magne_Ingebrigtsen")) - ;; $B9gCW$7$J$+$C$?%a!<%k$OA4$F$rJa$^$($k%0%k!<%W$X9T$-$^$9!#(B - "misc.misc") -@end lisp - -$B$3$NJQ?t$O(B @dfn{$BJ,3d(B} $B$NMM<0$K$J$C$F$$$^$9!#J,3d$O(B ($B$"$k$$$O(B) $B$=$l$>$l$N(B -$BJ,3d$,B>$NJ,3d$r4^$`:F5"E*9=B$$G$9!#$3$l$O;HMQ2DG=$J(B5$B$D$NJ,3d9=J8$G$9(B: - -@enumerate - -@item -@samp{group}: $B$b$7J,3d$,J8;zNs$G$"$k$H!"$=$l$O%0%k!<%WL>$H$7$F$_$J$5$l$^(B -$B$9!#IaDL$N@55,I=8=$N9gCW$,$J$5$l$^$9!#Nc$O2<$NJ}$r8+$F2<$5$$!#(B - -@item -@var{(FIELD VALUE SPLIT)}: $B$b$7J,3d$,%j%9%H$G!":G=i$NMWAG$,J8;zNs$G$"$j!"(B -$B%X%C%@!<(B FIELD ($B@55,I=8=(B) $B$,(B VALUE ($B$3$l$b@55,I=8=(B) $B$r4^$s$G$$$k>l9g!"%a%C(B -$B%;!<%8$r(B SPLIT $B$G;XDj$5$l$?$H$3$m$KC_@Q$7$^$9!#(B - -@item -@var{(| SPLIT...)}: $BJ,3d$,%j%9%H$G!":G=i$NMWAG$,(B @code{|} ($B?bD>K@(B) $B$G$"(B -$B$k$H!"$=$l$>$l$N(B SPLIT $B$r$=$N$&$A$N0l$D$,9gCW$9$k$^$Ge$N%0%k!<%W$KC_@Q$5$l$?$H$-$K(B ``$B9gCW$7$?(B'' $B$H(B -$B$7$^$9!#(B - -@item -@var{(& SPLIT...)}: $BJ,3d$,%j%9%H$G!":G=i$NMWAG$,(B @code{t} $B$G$"$k$H!"%j%9(B -$B%H$NA4$F$N(B SPLIT $B$ro$KCm0U$7$F;H$C$F2<$5$$!#(B - -@item -@var{(: function arg1 arg2 ...)}: $B$b$7J,3d$,%j%9%H$G!":G=i$N4X?t$,(B -@code{:} $B$G$"$k$H!"(B2$BHVL\$NMWAG$,(B @var{args} $B$r0z?t$H$7$F4X?t$H$7$F8F$P$l(B -$B$^$9!#4X?t$O(B SPLIT $B$rJV$9$Y$-$G$9!#(B - -@item -@code{nil}: $B$b$7J,3d$,(B @code{nil} $B$G$"$l$P!"$=$l$OL5;k$5$l$^$9!#(B - -@end enumerate - -$B$3$l$i$NJ,3d$G!"(B@var{FIELD} $B$O40A4$J%U%#!<%k%IL>$K9gCW$7$J$1$l$P$J$j$^$;(B -$B$s!#(B@var{VALUE} $B$O4pAC%b!<%I(B (fundamental mode) $B9=J8%F!<%V%k(B (syntax -table) $B$K=>$C$F40A4$K9gCW$7$J$1$l$P$J$j$^$;$s!#@55,I=8=$G%U%#!<%k%IL>$+(B -$B8l$NItJ,$K9gCW$5$;$k$?$a$K(B @code{.*} $B$r;H$&;v$,$G$-$^$9!#8@$$49$($l$P!"(B -$BA4$F$N(B @var{VALUE} $B$O(B @samp{\<} $B$H(B @samp{\>} $B$NBP$G0O$^$l$^$9!#(B - -@vindex nnmail-split-abbrev-alist -@var{FIELD} $B$H(B @var{VALUE} $B$O(B lisp $B%7%s%\%k(B (symbol) $B$G$"$k;v$b$G$-!"$=(B -$B$N>l9g$O$=$l$i$O(B @code{nnmail-split-abbrev-alist} $B$G;XDj$5$l$F$$$k$h$&$K(B -$BE83+$5$l$^$9!#$3$l$O%;%k$N(B @code{car} $B$,%-!<$r4^$s$G$$$F!"(B@code{cdr} $B$,(B -$B4XO"IU$1$i$l$?CM$r;}$C$F$$$k%3%s%9%;%k(B (cons cell) $B$NO"A[%j%9%H$G$9!#(B - -@vindex nnmail-split-fancy-syntax-table -@code{nnmail-split-fancy-syntax-table} $B$,$3$l$i$NA4$F$NJ,3d$,pJs$K4p$E$$$F!"(Bgnus $B$KF0E*$K%0%k!<%W$r:n$i$;$?$$$N$G$"$l$P(B ($BNc$($P!"%0%k!<%WL>$G(B @code{replace-match} $B$N$h$&$JBeMQ$r$9$k(B)$B!"$N%a!<%kA*JL%W%m%0%i%`$+30ItG[AwBe(B -$BM}(B---@code{slocal}$B!"(B@code{elm} $B$J$I(B) $B$rF~$C$FMh$?%a!<%k$r%0%k!<%W$KJ,3d(B -$B$9$k$?$a$K;H$$$^$9!#$b$7$=$&$7$F$$$k$N$G$"$l$P!"%a!<%k%P%C%/%(%s%I$,<+J,(B -$B<+?H$G%a!<%k$r$NJ}(B -$BK!$G1?$V;v$rH/8+$7$?B>$NA4$F$N%0%k!<%W$H6&$K!"$=$NJQ?t$NFbMF$+$iCM$r5"$7(B -$B$^$9!#(B@code{nnmh} $B0J30$N%P%C%/%(%s%I$OA0(B (name) $B$H$7$F(B @samp{foo} $B$r!"J}K!(B (method) $B$H$7$F(B @samp{nnmh} -$B$rEz$($F$/$@$5$$!#(B2$B$D$NB>$N%0%k!<%W!"(B@samp{bar} $B$H(B @samp{mail.baz} $B$N$?(B -$B$a$KF1MM$N;v$r(B2$B2s7+$jJV$7$F$/$@$5$$!#A4$F$N$"$J$?$N%a!<%k%0%k!<%W$r4^$a(B -$B$k$h$&$K$7$F$/$@$5$$!#(B - -$B$3$l$GA4It$G$9!#$b$&!"%a!<%k$rFI$`;v$,$G$-$k$h$&$K@_Dj$5$l$F$$$^$9!#$3$N(B -$BJ}K!$N8=>u%U%!%$%k$O<+F0E*$K:n@.$5$l$^$9!#(B - -@vindex nnmail-procmail-suffix -@vindex nnmail-procmail-directory -$B$b$7(B @code{nnfolder} $B$dB>$N(B2$BDL0J>e$N%a!<%k$r0l$D$N%U%!%$%k$KN/$a$k%P%C%/(B -$B%(%s%I$r;H$C$F$$$k$N$J$i!"(Bgnus $B$,8+$k%U%!%$%k$K(B procmail $B$,%a!<%k$r2C$((B -$B$J$$$h$&$K$7$J$1$l$P$J$j$^$;$s!#Be$o$j$K!"(Bprocmail $B$OA4$F$NF~$C$F$/$k%a!<(B -$B%k$r(B @code{nnmail-procmail-directory} $B$KF~$l$k$Y$-$G$9!#F~$C$FMh$?%a!<%k(B -$B$rF~$l$k%U%!%$%kL>$KE~Ce$9$k$?$a$K!"%0%k!<%WL>$K(B -@code{nnmail-procmail-suffix} $B$rIU2C$7$F$/$@$5$$!#%a!<%k%P%C%/%(%s%I$O$3(B -$B$l$i$N%U%!%$%k$+$i%a!<%k$rFI$_9~$_$^$9!#(B - -@vindex nnmail-reslpit-incoming -Gnus $B$,(B @file{mail.misc.spool} $B$H8F$P$l$F$$$k%U%!%$%k$rFI$_9~$s$@$H$-$O!"(B -$B$3$N%a!<%k$O4|BTDL$j!"(B @code{mail.misc} $B$KF~$l$i$l$^$9!#$7$+$7!"(Bgnus $B$K(B -$BIaDL$NJ}K!$G%a!<%k$rJ,3d$5$;$?$$>l9g!"(B@code{nnmail-resplit-incoming} $B$r(B -@code{t} $B$K@_Dj$9$k;v$,$G$-$^$9!#(B - -@vindex nnmail-keep-last-article -$B$b$7(B @code{procmail} $B$KF~$C$FMh$?J*$rJ,3d$7$FD>@\(B @code{nnmh} $B$N%G%#%l%/(B -$B%H%j!<$KF~$l$k$h$&$K$7$F$$$k>l9g(B ($B$3$l$O$9$k$Y$-$G$O$J$$$3$H$G$9$,(B)$B!"(B -gnus $B$,:G8e$N5-;v(B ($B$9$J$o$A!"$b$C$H$bBg$-$$5-;vHV9f$r;}$D5-;v(B) $B$r4|8B@Z(B -$B$l:o=|$9$k$N$rKI$0$?$a$K!"(B@code{nnmail-keep-last-article} $B$r(B @code{nil} -$B$G$J$$CM$K@_Dj$9$k$Y$-$G$9!#(B - -$B$3$l$O@_Dj$NNc$G$9(B: $BF~$C$F$/$k%9%W!<%k$O(B @file{~/incoming/} $B$KCV$+$l$F$$(B -$B$F!"(B@samp{""} $B$r@\Hx8l$H$7$F;}$C$F$$$^$9(B ($B$9$J$o$A!"F~$C$F$/$k%9%W!<%k%U%!(B -$B%$%k$O$=$l$HEy2A$J%0%k!<%W$HF1$8L>A0$K$J$C$F$$$^$9(B)$B!#(B @code{nnfolder} $B%P%C(B -$B%/%(%s%I$O%a!<%k%$%s%?!<%U%'!<%9$H$7$F;H$o$l!"(B@code{nnfolder} $B%G%#%l%/%H(B -$B%j!<$O(B @file{~/fMail/} $B$G$9!#(B - -@lisp -(setq nnfolder-directory "~/fMail/*) -(setq nnmail-spool-file 'procmail) -(setq nnmail-procmail-directory "~/incoming/") -(setq gnus-secondary-select-methods '((nnfolder ""))) -(setq nnmail-procmail-suffix "") -@end lisp - - -@node Incorporating Old Mail -@subsection $B8E$$%a!<%k$rc$b$J$/J*;v$,>efIW$J$h$&$G$"$l$P!"(Bmbox $B%U%!%$%k$r>C$9;v(B -$B$r9M$($k$+$b$7$l$^$;$s$,!";d$OA4$F$N%a!<%k$,$"$k$Y$-$H$3$m$KG<$^$C$F$$$k(B -$B$N$r40A4$K3NG'$9$k$^$G$O!"$=$&$O$7$^$;$s!#(B - - -@node Expiring Mail -@subsection $B%a!<%k$N4|8B@Z$l>C5n(B -@cindex article expiry - -$BEAE}E*$J%a!<%k%j!<%@!<$O!"2?$+!"4{FI$N0u$rIU$1$k$H5-;v$r:o=|$9$k798~$,$"(B -$B$j$^$9!#(B Gnus $B$O%a!<%k$rFI$`;v$KBP$7$F!"4pK\E*$KA4$/0c$C$?J}K!$rC$98"NO$,$"(B -$B$k$H$O9M$($^$;$s!#%a!<%k%0%k!<%W$KF~$C$F!"5-;v$K(B ``$B4{FI(B'' $B$N0u$rIU$1$?$j!"(B -$BB>$NN.57$G@Z$C$?$j$7$F$b!"%a!<%k5-;v$O$^$@%7%9%F%`$KB8:_$7$F$$$^$9!#7+$j(B -$BJV$7$^$9(B: gnus $B$O$"$J$?$N8E$$!"4{FI%a!<%k$r>C5n$7$^$;$s!#$b$A$m$s!"$"$J(B -$B$?$,$=$&$7$m$H?R$M$J$$8B$j$NOC$G$9$,!#(B - -Gnus $B$KK>$^$7$/$J$$%a!<%k$r:o=|$5$;$k$?$a$K$O!"5-;v$r(B @dfn{$B4|8B@Z$l>C5n(B -$B2DG=(B} (expirable) $B$H$7$F0u$rIU$1$J$1$l$P$J$j$^$;$s!#$7$+$7$J$,$i!"$3$l$O(B -$B5-;v$,B(:B$K>C$(5n$k$H$$$&;v$G$O$"$j$^$;$s!#0lHLE*$K!"%a!<%k5-;v$Ol9g$K%7%9%F%`$K$h$C$F:o=|$5$l$^$9(B 1) $B4|8B@Z$l>C5n2DG=$N0u$rIU$1$i$l(B -$B$k(B 2) 1$B=54V0J>e7P$C$?5-;v$G$"$k!#(B $B$b$75-;v$r4|8B@Z$l>C5n2DG=$K$7$J$1$l$P!"(B -$B$=$l$OCO9v$,E`$j$D$/$^$G%7%9%F%`$K;D$j$D$E$1$^$9!#$3$l$O$b$&0lEY6/D4IU$-(B -$B$G7+$jJV$5$l$k$KB-$k$b$N$G$9(B: ``$B$b$7(B'' $B$"$J$?$,5-;v$r(B ``$B4|8B@Z$l>C5n2DG=(B'' -$B$G$"$k$H(B ``$B$7$J$$(B'' $B$J$i!"(Bgnus $B$O(B ``$B7h$7$F(B'' $B$=$l$i$N(B ``$B5-;v(B'' $B$r>C5n$7(B -$B$^$;$s!#(B - -@vindex gnus-auto-expirable-newgroups -$BC5n2DG=$N0u$rIU$1$J$1$l$P$J$i$J$$$o$G$G$O$"$j$^$;$s!#(B -$B@55,I=8=(B @code{gnus-auto-expirable-newsgroups} $B$K9gCW$9$k%0%k!<%W$OA4$F(B -$B$N4{FI5-;v$K<+F0E*$K4|8B@Z$l>C5n2DG=$N0u$,IU$1$i$l$^$9!#A4$F$N4|8B@Z$l>C(B -$B5n2DG=$N0u$NIU$$$?5-;v$O35N,%P%C%U%!$N:G=i$N7e$K(B @samp{E} $B$,I=<($5$l$^$9!#(B - -$B%G%#%U%)%k%H$G$O<+F04|8B@Z$l>C5n2DG=$r;HMQ$9$k$H!"(Bgnus $B$O$"$J$?$,FI$s$@(B -$BA4$F$N5-;v$r!"$=$l$,4{FI$G$"$C$?$+L$FI$G$"$C$?$+$K4X$o$i$:!"4|8B@Z$l>C5n(B -$B2DG=$H$7$F0u$rIU$1$^$9!#4{FI$N0u$NIU$$$?5-;v$,<+F0E*$K4|8B@Z$l>C5n2DG=$H(B -$B$7$F0uIU$1$i$l$k$N$rHr$1$k$?$a$K!"0J2<$N$h$&$J$b$N$r(B @file{.gnus} $B%U%!%$(B -$B%k$K=q$/;v$,$G$-$^$9(B: - -@vindex gnus-mark-article-hook -@lisp -(remove-hook 'gnus-mark-article-hook - 'gnus-summary-mark-read-and-unread-as-read) -(add-hook 'gnus-mark-article-hook 'gnus-summary-mark-unread-as-read) -@end lisp - -$B<+F04|8B@Z$l>C5n2DG=%0%k!<%W$r:n$k;v$O!"A4$F$N4{FI5-;v$,4|8B@Z$l>C5n$5$l(B -$B$k;v$G$O$J$$;v$K5$$rIU$1$F$/$@$5$$(B---$B4|8B@Z$l>C5n2DG=$H$7$F0u$NIU$$$?5-(B -$B;v$@$1$,4|8B@Z$l>C5n$5$l$^$9!#L?Na(B @kbd{d}$B$,<+F0E*$K%0%k!<%W$r4|8B@Z$l>C(B -$B5n2DG=$K$9$k$N$G$OL5$$$H$$$&;v$K$b5$$rIU$1$F$/$@$5$$(B---$BH><+F0$N!"<+F04|(B -$B8B@Z$l>C5n2DG=%0%k!<%W$G5-;v$r4{FI$K0uIU$1$k$3$H$@$1$,5-;v$r4|8B@Z$l>C5n(B -$B2DG=$K$7$^$9!#(B - -@lisp -(setq gnus-auto-expirable-newgroups - "mail.nosense-list\\|mail.nice-list") -@end lisp - -$B<+F04|8B@Z$l>C5n$r$NJ}K!$O!"%0%k!<%W$N%0%k!<%W%Q%i%a!<%?$H$7$F!"(B -$BMWAG(B @code{auto-expirable} $B$r;}$D;v$G$9!#(B - -$B$b$7E,1~%9%3%"IU$1(B (@pxref{Adaptive Scoring}) $B$H<+F04|8B@Z$l>C5n$r;HMQ$7(B -$B$F$$$k$J$i!"LdBj$,5/$3$k$G$7$g$&!#<+F04|8B@Z$l>C5n$HE,1~%9%3%"IU$1$O$"$^(B -$B$jNI$/Aj8_:nMQ$7$^$;$s!#(B - -@vindex nnmail-expiry-wait -$BJQ?t(B @code{nnmail-expiry-wait} $B$O4|8B@Z$l>C5n2DG=5-;v$,$I$l$/$i$$$N4|4V(B -$B@8B8$7$F$$$k$+$N%G%#%U%)%k%H$N;~4V@_Dj$rDs6!$7$^$9!#(BGnus $B$O%a%C%;!<%8$,(B -$BAw$i$l$?$H$-$G$O$J$/!"$=$l$,(B @emph{$BE~Ce(B} $B$7$F$+$i$NF|$r7W;;$7$^$9!#%G%#(B -$B%U%)%k%H$O(B7$BF|4V$G$9!#(B - -Gnus $B$O5-;v$,$I$N%0%k!<%W$KB0$7$F$$$k$+$K4p$E$$$F!"$=$l$,$I$N$/$i$$@8B8(B -$B$9$k$+$r@.8y$K@_Dj$9$k4X?t$bDs6!$7$F$$$^$9!#%0%k!<%W(B @samp{mail.private} -$B$O4|8B$r(B1$B%v7n$K!"%0%k!<%W(B @samp{mail.junk} $B$G$O4|8B$r(B1$BF|$K!"$=$NB>$N$b$N(B -$B$K$O4|8B$r(B6$BF|4V$K$9$k$K$O(B: - -@vindex nnmail-expiry-wait-function -@lisp -(setq nnmail-expiry-wait-function - (lambda (group) - (cond ((string= group "mail.private") - 31) - ((string= group "mail.junk") - 1) - ((string= group "important") - 'never) - (t - 6)))) -@end lisp - -$B$3$N4X?t$KM?$($i$l$k%0%k!<%WL>$O(B ``$BAu>~L5$7(B'' $B$N%0%k!<%WL>$G$9(B--- -@samp{nnml:} $B$d$=$NB>$N;w$?$h$&$J$b$N$OIU$-$^$;$s!#(B - -$BJQ?t(B @code{nnmail-expiry-wait} $B$H4X?t(B @code{nnmail-expiry-wait-function} -$B$O?t;z(B ($B@0?t$G$"$kI,MW$O$"$j$^$;$s(B) $B$+%7%s%\%k(B @code{immediate} $B$+(B -@code{never} $B$N$I$A$i$+$G$"$k;v$,$G$-$^$9!#(B - -$B4|8B@Z$l4|4V$rA*BrE*$KJQ99$9$k$?$a$K%0%k!<%W%Q%i%a!<%?(B -@code{expiry-wait} $B$r;H$&;v$b$G$-$^$9(B (@pxref{Group Parameters})$B!#(B - -@vindex nnmail-keep-last-article -@code{nnmail-keep-last-article} $B$,(B @code{nil} $B$G$J$$$H!"(Bgnus $B$O%a!<%k%K%e!<(B -$B%9%0%k!<%W$N:G8e$N5-;v$r7h$7$F4|8B@Z$l>C5n$7$^$;$s!#$3$l$O(B procmail $B$NMx(B -$BMQC5n2DG=$G$J$$5-;v$r4|8B@Z$l(B -$B>C5n$9$k;v$O$J$$!"$H$$$&$N$O13$G$9!#(B@code{total-expire} $B$r%0%k!<%W%Q%i%a!<(B -$B%?$KF~$l$k$H!"5-;v$O4|8B@Z$l>C5n$N0u$,IU$-$^$;$s$,!"A4$F$N5-;v$O4|8B@Z$l(B -$B>C5n2aDx$KF~$l$i$l$^$9!#Hs>o$KCm0U$7$F;H$C$F$/$@$5$$!#$5$i$K$b$C$H4m81$J(B -$B$b$N$OJQ?t(B @code{gnus-total-expirable-newsgroups} $B$G$9!#$3$N@55,I=8=$K9g(B -$BCW$9$kA4$F$N%0%k!<%W$OA4$F$N4{FI5-;v$,4|8B@Z$l>C5n2DG=$N2aDx$KFM$C9~$^$l(B -$B$^$9!#$3$l$O!"Ev$N%0%k!<%W$N(B @emph{$BA4$F(B} $B$N8E$$%a!<%k5-;v$O>/$78e$G:o=|(B -$B$5$l$k$H$$$&;v$G$9!#Hs>o$KCm0U$7$F;H$C$F!"$"$J$?$,;HMQ$7$?@55,I=8=$,4V0c$C(B -$B$?%0%k!<%W$K9gCW$7$F!"$"$J$?$NA4$F$N=EMW$J%a!<%k$,>C$($F$7$^$C$?$H8@$C$F!"(B -$B;d$N$H$3$m$K5c$-IU$$$FMh$J$$$G$/$@$5$$!#(B@emph{$BCK(B}$B$K$J$j$J$5$$!*(B $B$b$7$/$O!"(B -@emph{$B=w(B} $B$K$J$j$J$5$$!*(B $B$"$J$?$,5$;}$A$h$$$H46$8$kA4$F$N$b$N$H!*(B $B$G$9$+(B -$B$i$=$3$K!*(B - -$B$?$$$F$$$N?M$O$[$H$s$I$N%a!<%k%0%k!<%W$r(B total-expirable ($BA4BN4|8B@Z$l>C(B -$B5n2DG=(B) $B$K$7$^$9$,!#(B - - -@node Washing Mail -@subsection $B%a!<%k@vBu(B -@cindex mail washing -@cindex list server brain damage -@cindex incoming mail treatment - -$B%a%$%i!<(B (mailer) $B$d%j%9%H%5!<%P!<(B (list server) $B$OK\Ev$KK\Ev$KGO9b$$$G$9!#(B ``$B$o$!!"(BRFC822 $B$O2f!9$N%5!<%P!<$rDL$C$F$$$/(B -$B%a%C%;!<%8$NA4$F$N9T$N:G8e$K(B @code{wE aRe ElIte!!!!!1!!} $B$r2C$($k;v$rL@(B -$B<(E*$K6X;_$O$7$F$$$J$$$>!#$5$!!"$d$C$F$_$h$&(B!!!!1'' $B$($'!"$=$N$H$*$j$G$9(B -$B$,!"(BRFC822 $B$OG=NO$NDc$$?M$K$h$C$FFI$^$l$k$h$&$K$O=q$+$l$F$$$^$;$s!#L@Gr(B -$B$J;v$O$=$3$G$O5DO@$5$l$F$$$^$;$s!#$G$9$+$i!#$=$&$$$&$3$H$G$9!#(B - -$BLdBjE@(B: $B%I%$%DHG(B Microsoft Exchange $B$OJVEz$NI=Bj$K(B @samp{Re: } $B$NBe$o$j(B -$B$K(B @samp{AW: } $B$rIU$12C$($^$9!#;d$O$3$l$KF0MI$7$FO5Gb$7$F$$$k$U$j$r$9$k(B -$B$3$H$b$G$-$^$7$?$,!"$=$&$9$k5$NO$,$"$j$^$;$s$G$7$?!#$=$l$O>P$&$Y$-;v$G$9!#(B - -Gnus $B$O5-;v$rI=<($9$k$H$-$K$=$l$r@vBu$9$k$?$a$K2aEY$N4X?t$rDs6!$7$F$$$^(B -$B$9$,!"%a!<%k$r%G%#%9%/$KJ]B8$9$kA0$KA*JL$r$9$k$3$H$,$G$-$?J}$,NI$$$G$7$g(B -$B$&!#$=$NL\E*$N$?$a$K!"(B3$B$D$N%U%C%/$H$=$N%U%C%/$KF~$l$k;v$N$G$-$k?'!9$J4X(B -$B?t$,$"$j$^$9!#(B - -@table @code -@item nnmail-prepare-incoming-hook -@vindex nnmail-prepare-incoming-hook -$B$3$N%U%C%/$O%a!<%k$K2?$+$r$9$kA0$K8F$P$l!"4pK\E*$J!"%a!<%k$rA]$$$F$-$l$$(B -$B$K$9$k=j:n$N$?$a$K$"$j$^$9!#;H$&;v$N$G$-$k4X?t$O(B: - -@table @code -@item nnheader-ms-strip-cr -@findex nnheader-ms-strip-cr -$B$=$l$>$l$N9T$+$i!":G8e$K$"$k%-%c%j%C%8%j%?!<%s(B (carriage return) $B$re$GF0:n$7$F$$$k(B Emacs $B$N%G%#%U%)%k%H$G$9!#(B - -@end table - -@item nnmail-prepare-incoming-header-hook -@vindex nnmail-prepare-incoming-header-hook -$B$3$N%U%C%/$O$=$l$>$l$N%X%C%@!<$KHO0O$r69$a$i$l$F(B (narrowed) $B8F$P$l$^$9!#(B -$B%X%C%@!<$r$-$l$$$K$9$k$H$-$K;H$&;v$,$G$-$^$9!#;H$&;v$N$G$-$k4X?t$O(B: - -@table @code -@item nnmail-remove-leading-whitespace -@findex nnmail-remove-leading-whitespace -$B%X%C%@!<$K$=$l$,NI$/8+$($k$h$&$K(B ``$BM-MQ$J(B'' $B%j%9%H%5!<%P!<$,A0$NJ}$KIU$1(B -$B2C$($?6uGr$rL5$/$7$^$9!#$"$!$!!#(B - -@item nnmail-remove-list-identifiers -@findex nnmail-remove-list-identifiers -$B$$$/$D$+$N%j%9%H%5!<%P!<$OF10l<1JL;R$rIU$12C$($^$9(B---$BNc$($P!"(B -@samp{(idm)}---$B$rA4$F$N(B @code{Subject} $B%X%C%@!<$N:G=i$KIU$1$^$9!#$=$l$O!"(B -$B@P4o;~Be$N%a!<%k%X%C%@!<$r;H$C$F$$$k?M$K$ONI$$;v$@$H;W$$$^$9!#$3$N4X?t$O(B -$B@55,I=8=(B @code{nnmail-list-identifiers} $B$K9gCW$9$kJ8;zNs$r$l$N%a%C%;!<%8$KHO0O$r69$a$i$l$F8F$P$l$^$9!#;H$&;v$N$G(B -$B$-$k4X?t$O(B: - -@table @code -@item article-de-quoted-unreadable -@findex article-de-quoted-unreadable -Quoted Readable $BId9f2=$rI|9f2=$7$^$9!#(B - -@end table -@end table - - -@node Duplicates -@subsection $B=EJ#(B - -@vindex nnmail-treat-duplicates -@vindex nnmail-message-id-cache-length -@vindex nnmail-message-id-cache-file -@cindex duplicate mails -$B$$$/$D$+$N%a!<%j%s%0%j%9%H$N%a%s%P!<$J$i!";~!9F1$8%a!<%k$r(B2$B$DC5n$7$^$;$s!#$=$NBe$o$j$K!"%a!<%k$N@hF,$K$3$l$O0c$C$?%a%C%;!<%8$N=E(B -$BJ#$G$"$k$H$$$&7Y9p$rA^F~$7$^$9!#(B - -$B$3$NJQ?t$O4X?t$G$"$k;v$b$G$-$^$9!#$=$N>l9g$O!"4X?t$O(B @code{Message-ID} -$B$r0z?t$H$7$F!"Ev$N%a%C%;!<%8$KHO0O$r69$a$i$l$?%P%C%U%!$+$i8F$P$l$^$9!#$3(B -$B$N4X?t$O(B @code{nil}$B!"(B@code{warn}$B!"(B@code{delete} $B$N$I$l$+$rJV$5$J$1$l$P$J(B -$B$j$^$;$s!#(B - -$BJQ?t$r(B @code{nil} $B$K@_Dj$9$k;v$K$h$C$F!"$3$N5!G=$r40A4$K;H$o$J$$$h$&$K$9(B -$B$k;v$,$G$-$^$9!#(B - -$B$b$7A4$F$N=EJ#%a!<%k$rFCJL$J(B @dfn{duplicate} $B%0%k!<%W$KF~$l$?$$$N$G$"$l(B -$B$P!"IaDL$N%a!<%kJ,3dJ}K!$r;H$C$F$=$l$r$9$k$3$H$,$G$-$^$9(B: - -@lisp -(setq nnmail-split-fancy - '(| ;; $B=EJ#%a%C%;!<%8$OJ,N%$5$l$?%0%k!<%W$X9T$-$^$9!#(B - ("gnus-warning" "duplication of message" "duplicate") - ;; $B%G!<%b%s$d%]%9%H%^%9%?!<$d;w$?$h$&$J$b$N$+$i$N(B - ;; $B%a%C%;!<%8$OB>$N$H$3$m$X!#(B - (any mail "mail.misc") - ;; $BB>$NK!B'!#(B - [ ... ] )) -@end lisp - -$B$b$7$/$O$NK!B'!#(B - [...])) -@end lisp - -$B$9$P$i$7$$5!G=$,$"$j$^$9(B: $B$b$7Dj$9$k$H$$$&$&$k$5$$JJ$,$"$j$^$9!#$3$l$O$b$C$H$b$G$J(B -$B$$;v$G$O$J$$$+$b$7$l$^$;$s$,!"$"$J$?$NK>$`;v$G$O$J$$$+$b$7$l$^$;$s!#(B - -$B$b$7(B @code{nnmail-spool-file} $B$r(B @code{nil} $B$K@_Dj$9$k$H!"$I$N%P%C%/%(%s(B -$B%I$bF~$C$F$/$k%a!<%k$rFI$b$&$H;n$_$k;v$O$J$/!"K>$`;v$No$KK~B-$7$F$$$F!"8E$$(B -@sc{rmail} $B%U%!%$%k$,(B @code{nnbabyl} $B$G1#$5$l$F$$$k$N$r$5$C$H8+$?$$$@$1(B -$B$J$i!"$3$l$OM>J,$G$7$g$&!#$9$Y$F$N%P%C%/%(%s%I$O(B $B%P%C%/%(%s%I(B- -@code{get-new-mail} $B$H$$$&JQ?t$r;}$C$F$$$^$9!#$b$7(B @code{nnbabyl} $B$N%a!<(B -$B%kFI$_9~$_$r;HMQIT2D$K$7$?$$$N$G$"$l$P!"%0%k!<%W$N;ve$N%5!<%P!<$r(B -@code{nnbabyl-get-new-mail} $B$r(B @code{nil} $B$K@_Dj$9$k$h$&$KJT=8$7$^$9!#(B - -$BA4$F$N%a!<%k%P%C%/%(%s%I$OF~$C$F$/$k%a!<%k$rFI$_9~$`$H$-$K!"J]B8$5$l$k$Y(B -$B$-5-;v$KHO0O$r69$a$F(B @code{nn}*@code{-prepare-save-mail-hook} $B$r8F$S$^$9!#(B - - -@node Choosing a Mail Backend -@subsection $B%a!<%k%P%C%/%(%s%I$rA*$V(B - -Gnus $B$O%a!<%k%0%k!<%W$rF0:n$9$k$h$&$K$9$k$H%a!<%k%9%W!<%k$rFI$_9~$_$^$9!#(B -$B%a!<%k%U%!%$%k$O$^$:$"$J$?$N%[!<%`%G%#%l%/%H%j!<$KJ#$l$N%0%k!<%W$KBP$7$F0l$D$N%U%!%$%k$r;}$D!#(B -@end menu - - -@node Unix Mail Box -@subsubsection Unix $B%a!<%k%\%C%/%9(B -@cindex nnmbox -@cindex unix mail box - -@vindex nnmbox-active-file -@vindex nnmbox-mbox-file -@dfn{nnmbox} $B%P%C%/%(%s%I$O%a!<%k$rC_B"$9$k$?$a$KI8=`$N(B Un*x mbox $B%U%!%$(B -$B%k$rMQ$$$^$9!#(B@code{nnmbox} $B$O$=$l$>$l$N%a!<%k5-;v$K$=$l$,$I$N%0%k!<%W$K(B -$BB0$7$F$$$k$+$r<($9DI2C$N%X%C%@!<$r2C$($^$9!#(B - -$B;ve$N%5!<%P!<$N@_Dj(B: - -@table @code -@item nnmbox-mbox-file -@vindex nnmbox-mbox-file -$BMxMQA0!#(B - -@item nnmbox-activate-file -@vindex nnmbox-active-file -$B%a!<%k%\%C%/%9$N8=>u%U%!%$%k$NL>A0!#(B - -@item nnmbox-get-new-mail -@vindex nnmbox-get-new-mail -@code{nil} $B$G$J$1$l$P!"(B@code{nnmbox} $B$OF~$C$FMh$?%a!<%k$rFI$_9~$s$G%0%k!<(B -$B%W$KJ,3d$7$^$9!#(B -@end table - - -@node Rmail Babyl -@subsubsection Rmail Babyl -@cindex nnbabyl -@cindex rmail mbox - -@vindex nnbabyl-active-file -@vindex nnbabyl-mbox-file -@dfn{nnbabyl} $B%P%C%/%(%s%I$O%a!<%k$rC_B"$9$k$?$a$K(B babyl $B%a!<%k%\%C%/%9(B -($BJLL>(B @dfn{rmail mbox}) $B$r;H$$$^$9!#(B@code{nnbabyl} $B$O$=$l$>$l$N5-;v$K$=(B -$B$l$,$I$N%0%k!<%W$KB0$7$F$$$k$+$r<($9DI2C$N%X%C%@!<$r2C$($^$9!#(B - -$B;ve$N%5!<%P!<$N@_Dj(B: - -@table @code -@item nnbabyl-mbox-file -@vindex nnbabyl-mbox-file -rmail mbox $B%U%!%$%k$NL>A0(B - -@item nnbabyl-active-file -@vindex nnbabyl-active-file -rmail box $B$N$?$a$N8=>u%U%!%$%k$NL>A0!#(B - -@item nnbabyl-get-new-mail -@vindex nnbabyl-get-new-mail -@code{nil} $B$G$J$1$l$P!"(B@code{nnbabyl} $B$OF~$C$F$/$k%a!<%k$rFI$_9~$_$^$9!#(B -@end table - - -@node Mail Spool -@subsubsection $B%a!<%k%9%W!<%k(B -@cindex nnml -@cindex mail @sc{nov} spool - -@dfn{nnml} $B%9%W!<%k%a!<%kMM<0$OB>$NCN$i$l$?MM<0$H$O8_49@-$,$"$j$^$;$s!#(B -$B$=$l$O>/$7Cm0U$7$F;H$o$l$k$Y$-$G$9!#(B - -@vindex nnml-directory -$B$b$7$3$N%P%C%/%(%s%I$r;H$&$H!"(Bgnus $B$OF~$C$F$/$k%a!<%k$r!"$=$l$>$l$N%a!<(B -$B%k$r(B1$B%U%!%$%k$H$7$F%U%!%$%k$KJ,3d$7!"5-;v$rJQ?t(B @code{nnml-directory} $B$G(B -$B;XDj$5$l$?%G%#%l%/%H%j!<$N2<$NBP1~$9$k%G%#%l%/%H%j!<$KF~$l$^$9!#%G%#%U%)(B -$B%k%H$NCM$O(B @file{~/Mail/} $B$G$9!#(B - -$BA0$b$C$F%G%#%l%/%H%j!<$r:n$C$F$*$/I,MW$O$"$j$^$;$s!#$=$l$NLLE]$O(B gnus $B$,(B -$B8+$F$/$l$^$9!#(B - -$B$b$7$"$J$?$N%"%+%&%s%H$KC_@Q$G$-$k%U%!%$%k$N?t$K87L)$J@)8B$,$"$k$J$i!"$3(B -$B$N%P%C%/%(%s%I$r;H$&$Y$-$G$O$"$j$^$;$s!#$=$l$>$l$N%a!<%k$O$=$l<+?H$N%U%!(B -$B%$%k$rF@$^$9$N$G!"?t=54V$G$?$/$5$s$N(B i$B%N!<%I$r@jM-$9$k2DG=@-$O==J,$K$"$j(B -$B$^$9!#JL$K$3$l$,LdBj$G$J$/!"?F@Z$J%7%9%F%`4IM}e$N%5!<%P!<$N@_Dj(B: - -@table @code -@item nnml-directory -@vindex nnml-directory -$BA4$F$N(B @code{nnml} $B%G%#%l%/%H%j!<$O$3$N%G%#%l%/%H%j!<$N2<$KCV$+$l$^$9!#(B - -@item nnml-active-file -@vindex nnml-active-file -@code{nnml} $B%5!<%P!<$N$?$a$N8=>u%U%!%$%k!#(B - -@item nnml-newsgroups-file -@vindex nnml-newgroups-file -@code{nnml} $B%0%k!<%W5-=R%U%!%$%k!#(B @xref{Newsgroups File Format}$B!#(B - -@item nnml-get-new-mail -@vindex nnml-get-new-mail -@code{nil} $B$G$J$1$l$P!"(B@code{nnml} $B$OF~$C$FMh$?%a!<%kFI$_9~$_$^$9!#(B - -@item nnml-nov-is-evil -@vindex nnml-nov-is-evil -@code{nil} $B$G$J$1$l$P!"$3$N%P%C%/%(%s%I$O$I$N(B @sc{nov} $B%U%!%$%k$bL5;k$7(B -$B$^$9!#(B - -@item nnml-nov-file-name -@vindex nnml-nov-file-name -@sc{nov} $B%U%!%$%k$NL>A0!#%G%#%U%)%k%H$O(B @file{.overview} $B$G$9!#(B - -@item nnml-prepare-save-mail-hook -@vindex nnml-prepare-save-mail-hook -$BJ]B8$9$kA0$K5-;v$KHO0O$r69$a$FuBV$G$J$/$J$C$F$7$^$C(B -$B$?$J$i!"(B@kbd{M-x nnml-generate-nov-databases} $B$HBG$D;v$K$h$C$F!"40A4$K99(B -$B?7$9$k;v$,$G$-$^$9!#$3$NL?Na$O!"$=$l$>$lA4$F$N%U%!%$%k$r8+$k;v$K$h$C$F(B -@code{nnml} $B3,AXA4BN$r%H%m!<%k5{LV$G$5$i$$$^$9$N$G!"$=$l$,=*$o$k$^$G$K$O(B -$B;~4V$,$+$+$k$+$b$7$l$^$;$s!#$3$N5!G=$X$N$h$jNI$$%$%s%?!<%U%'!<%9$O%5!<%P!<(B -$B%P%C%U%!$G8+$D$+$k$G$7$g$&(B (@pxref{Server Commands})$B!#(B - - -@node MH Spool -@subsubsection MH $B%9%W!<%k(B -@cindex nnmh -@cindex mh-e mail spool - -@code{nnmh} $B$O!"(B@sc{nov} $B%G!<%?%Y!<%9$r:n$i$J$$$3$H$H8=>u%U%!%$%k$rJ];}(B -$B$7$J$$;v$r=|$$$F!"(B @code{nnml} $B$H;w$F$$$^$9!#$=$N$3$H$O(B @code{nnmh} $B$r(B -@code{nnml} $B$h$j(B @emph{$B$+$J$j(B} $BCY$$%P%C%/%(%s%I$K$7$F$$$^$9$,!"$=$l$O(B -procmail $B$N%9%/%j%W%H$r=q$/$?$a$K$:$C$H$d$j$d$9$/$J$C$F$b$$$^$9!#(B - -$B;ve$N%5!<%P!<$N@_Dj(B: - -@table @code -@item nnmh-directory -@vindex nnmh-directory -$BA4$F$N(B @code{nnmh} $B%G%#%l%/%H%j!<$O$3$N%G%#%l%/%H%j!<$N2<$KCV$+$l$^$9!#(B - -@item nnmh-get-new-mail -@vindex nnmh-get-new-mail -@code{nil} $B$G$J$1$l$P!"(B@code{nnmh} $B$OF~$C$F$/$k%a!<%k$rFI$_9~$_$^$9!#(B - -@item nnmh-be-safe -@vindex nnmh-be-safe -@code{nil} $B$G$J$1$l$P!"(B@code{nnmh} $B$O%U%)%k%@!<$K$"$k5-;v$,pJs$rD4$Y$^$9$N$G!"$3$l$r(B @code{t} $B$K@_Dj$9$k;v$O?<(B -$B9o$JB.EYDc2<$,5/$3$k$H$$$&;v$G$9!#$b$7(B @code{nnmh} $B5-;v$rFI$`$N$K(B gnus -$B0J30$N$b$N$r;H$C$F$$$J$$$N$G$"$l$P!"$3$NJQ?t$r(B @code{t} $B$K@_Dj$9$kI,MW$O(B -$B$"$j$^$;$s!#(B -@end table - -@node Mail Folders -@subsubsection $B%a!<%k%U%)%k%@!<(B -@cindex nnfolder -@cindex mbox folders -@cindex mail folders - -@code{nnfolder} $B$O$=$l$>$l$N%a!<%k%0%k!<%W$r0c$C$?%U%!%$%k$KC_B"$9$k%P%C(B -$B%/%(%s%I$G$9!#$=$l$>$l$N%U%!%$%k$OI8=`$N(B Un*x mbox $BMM<0$G$9!#(B -@code{nnfolder} $B$O5-;vHV9f$HE~CeF|$r5-O?$7$F$*$/$?$a$NDI2C$N%X%C%@!<$r2C(B -$B$($^$9!#(B - -$B;ve$N%5!<%P!<$N@_Dj(B: - -@table @code -@item nnfolder-directory -@vindex nnfolder-directory -$BA4$F$N(B @code{nnfolder} $B%a!<%k%\%C%/%9$O$3$N%G%#%l%/%H%j!<$N2<$KCV$+$l$^(B -$B$9!#(B - -@item nnfolder-active-file -@vindex nnfolder-active-file -$B8=>u%U%!%$%k$NL>A0!#(B - -@item nnfolder-newgroups-file -@vindex nnfolder-newsgroups-file -$B%0%k!<%W5-=R%U%!%$%k$NL>A0!#(B @xref{Newsgroups File Format}$B!#(B - -@item nnfolder-get-new-mail -@vindex nnfolder-get-new-mail -@code{nil} $B$G$J$1$l$P!"(B@code{nnfolder} $B$OF~$C$F$/$k%a!<%k$rFI$_9~$_$^$9!#(B - -@item nnfolder-save-buffer-hook -@vindex nnfolder-save-buffer-hook -@cindex backup files -$B%U%)%k%@!<$rJ]B8$9$kA0$Ko$N%P%C%/%"%C%W$NJQL>$r$9$k;v$KCm0U$7$F2<$5$$!#(B -$B$3$N5!G=$rL58z$K$7$?$$$N$G$"$l$P!"%U%!%$%k(B @file{.emacs} $B$G$N%0%k!<%W8;(B - -Gnus $B$O$?$@C1$K%K%e!<%9$d%a!<%k$rFI$`0J>e$N$3$H$,$G$-$^$9!#0J2<(B -$B$K<($9J}K!$K$h$C$F!"(Bgnus $B$G%G%#%l%/%H%j!<$d%U%!%$%k$r!"$"$?$+$b(B -$B%K%e!<%9%0%k!<%W$G$"$k$+$N$h$&$K1\Mw$9$k$3$H$,$G$-$k$h$&$K$J$j$^(B -$B$9!#(B - -@menu -* Directory Groups:: $B%G%#%l%/%H%j!<$r%K%e!<%9%0%k!<%W$N$h$&$KFI$`!#(B -* Anything Groups:: Dired? $BC/$,(B dired $B$J$s$F;H$&$N(B? -* Document Groups:: $B8DJL$N%U%!%$%k72$O%0%k!<%W$NAG!#(B -* SOUP:: @sc{SOUP} $B%Q%1%C%H$r(B ``$B%*%U%i%$%s(B''$B$GFI$`!#(B -* Web Searches:: $BJ8;zNs$K%^%C%A$9$k5-;v$+$i%0%k!<%W$r:n$k!#(B -* Mail-To-News Gateways:: $B%a!<%k$+$i%K%e!<%9$X$N%2!<%H%&%'%$$rDL$7$F5-;v$rEj9F$9$k!#(B -@end menu - - -@node Directory Groups -@subsection $B%G%#%l%/%H%j!<%0%k!<%W(B -@cindex nndir -@cindex directory groups - -$B$b$7!"$?$/$5$s$N5-;v$,8DJL$N%U%!%$%k$H$7$FF~$C$F$$$k%G%#%l%/%H%j!<(B -$B$,$"$l$P!"$=$l$r%K%e!<%9%0%k!<%W$H$7$F07$&$3$H$,$G$-$^$9!#$b$A$m(B -$B$s!"%U%!%$%k$O?t;z$N%U%!%$%kL>$r$b$C$F$$$J$1$l$P$J$j$^$;$s!#(B - -$B$3$3$G(B Emacs $B$NAG@2$i$7$$%Q%C%1!<%8$NCf$G$b:G$bAG@2$i$7$$(B -@code{ange-ftp} ($B$H$=$N8e7Q$N(B @code{efs}) $B$K$D$$$F?($l$kNI$$5!2q(B -$B$G$7$g$&!#;d$,(B @code{nndir} $B$r=q$$$?$H$-$O!"$3$l(B --- $B%G%#%l%/%H(B -$B%j!<$rFI$`%P%C%/%(%s%I$K$D$$$F$O$"$^$j9M$($F$$$^$;$s$G$7$?!#$H$s(B -$B$G$b$J$$$3$H$@$M!#(B - -@code{ange-ftp} $B$O$3$N>p67$r7`E*$KJQ2=$5$;$^$7$?!#Nc$($P!"(B -@code{ange-ftp} $B%U%!%$%kL>(B -@file{/ftp.hpc.uh.edu:/pub/emacs/ding-list/} $B$r%G%#%l%/%H%j!(B -$B$H$7$FF~NO$7$?$H$9$k$H!"(B@code{ange-ftp} $B$"$k$$$O(B @code{efs} $B$OC5n$r9T$J$&$3$H$O$G$-$^$;$s!#(B -@code{nndir} $B$,;H$($k$b$N$J$i2?$G$b(B @code{nnmh} $B$"$k$$$O(B -@code{nnml} $B$r;H$&$3$H$,$G$-$k$N$G!"$b$7FI$_=P$7@lMQ$G$O$J$$(B -@code{nndir} $B$,I,MW$@$H;W$C$?$i!"$3$l$i$N$I$A$i$+$NJ}K!$K@Z$jBX(B -$B$($k$3$H$b$G$-$^$9!#(B - - -@node Anything Groups -@subsection $B$J$s$G$b%0%k!<%W(B -@cindex nneething - -($B0l$D$N%9%W!<%kIw%G%#%l%/%H%j!<$H2r$lA':w$7$F(B -$B$^$o$j$^$9!#$b$7$=$N%U%!%$%k$,5-;v$N$h$&$K8+$($?$J$i(B ($B$9$J$o$A!"(B -$B:G=i$N?t9T$,%X%C%@!<$N$h$&$K8+$($?$i(B) $B$=$l$r%X%C%@$H$7$F;H$$$^$9!#(B -$B$b$7$=$l$,%X%C%@!<$N$J$$$?$@$NE,Ev$J%U%!%$%k(B ($BNc$($P(B C $B$N%=!<%9(B -$B%U%!%$%k(B) $B$G$"$C$?$J$i!"(B@code{nneething} $B$O%X%C%@!<$r5u6u$+$i:n(B -$B$j=P$7$^$9!#$3$l$O%U%!%$%k$N=jM-A0!"F|IU$r;H$$!"$3$l$i$NMW(B -$BAG$KBP$7$F$G$-$k$3$H$r2?$G$b$d$j$^$9!#(B - -$B$3$l$O$"$J$?$K$H$C$F$OA4$F<+F0E*$K5/$3$k$3$H$G!"$"$J$?$O%K%e!<%9(B -$B%0%k!<%W$K$H$F$bNI$/;w$?2?$+$r8+$;$i$l$k$3$H$K$J$k$G$7$g$&!#$[$s(B -$B$H$&$K@#J,0c$o$J$$!"%K%e!<%9%0%k!<%W$N$h$&$J$b$N$r!#5-;v$rA*Br$9(B -$B$k$H!"$=$l$O$$$D$b$N$h$&$K!"5-;v%P%C%U%!$KI=<($5$l$k$G$7$g$&!#(B - -$B%G%#%l%/%H%j!<$rI=$o$7$F$$$k9T$rA*Br$9$k$H!"(Bgnus $B$O$"$J$?$r$3$N(B -@code{nneething} $B%0%k!<%W$N$?$a$N?7$7$$35N,%P%C%U%!$KO"$l$F9T$/(B -$B$G$7$g$&!#0J2pJs$r21$($F$*$-$^$;$s!#$b$7(B@kbd{G -m} $B$GIaDL$K8GDj(B @code{nneething} $B%0%k!<%W$r:n$k$H!"(Bgnus$B$O5-;vHV(B -$B9f$H%U%!%$%kL>$NBP1~I=$r21$($F$*$-!"$3$N%0%k!<%W$rB>$N%0%k!<%W$H(B -$BF1MM$K07$&$3$H$,$G$-$k$h$&$K$J$j$^$9!#8GDj(B@code{nneething} $B%0%k!<(B -$B%W$r:nF0$5$;$k$H!"L$FI5-;v$,$$$/$D4^$^$l$F$$$k$+$rCN$i$5$l$?$j!"(B -$B$J$I$J$I!#(B - -$B$$$/$D$+$NJQ?t$,$"$j$^$9!#(B - -@table @code -@item nneething-map-file-directory -@vindex nneething-map-file-directory -$BA4$F$N8GDj(B @code{nneething} $B%0%k!<%W$NBP1~I=$O$3$N%G%#%l%/%H%j!<(B -$B$K3JG<$5$l$^$9!#$3$N=i4|@_DjCM$O(B @file{~/.nneething/} $B$G$9!#(B - -@item nneething-exclude-files -@vindex nneething-exclude-files -$B$3$N@55,I=8=$K%^%C%A$9$k%U%!%$%k$O$9$Y$FL5;k$5$l$^$9!#<+F0J]B8%U%!(B -$B%$%k$J$I$r=|$/$N$KJXMx$K;H$($^$9!#$=$7$F$=$l$,$^$5$K=i4|@_Dj$G9T(B -$B$J$o$l$kF0:n$G$9!#(B - -@item nneething-map-file -@vindex nneething-map-file -$BBP1~I=%U%!%$%k$NL>A0!#(B -@end table - - -@node Document Groups -@subsection $BJ8=q%0%k!<%W(B -@cindex nndoc -@cindex documentation group -@cindex help group - -@code{nndoc} $B$O0l$D$N%U%!%$%k$r%K%e!<%9%0%k!<%W$H$7$FFI$`$3$H$r(B -$B$G$-$k$h$&$K$9$k!"$A$g$C$H5$$NMx$$$?$d$D$G$9!#$$$/$D$+$N%U%!%$%k(B -$BAw7A<0!#(B -@cindex forwarded messages - -@item forward -$BE>Aw$5$l$?5-;v!#(B - -@item mime-parts -$B=8G[G[Aw(B (digest) $B$NB>$N(B MIME $BB?ItJ,%a%C%;!<%8(B (multipart message) $B$G$9!#(B - -@item mime-digest -@cindex digest -@cindex MIME digest -@cindex 1153 digest -@cindex RFC 1153 digest -@cindex RFC 341 digest -MIME (RFC 1341) $B$^$H$aAw$j7A<0!#(B - -@item standard-digest -$BI8=`(B (RFC 1153) $B$^$H$aAw$j7A<0!#(B - -@item slack-digest -$BHsI8=`$^$H$aAw$j7A<0(B --- $B$@$$$?$$$O$&$^$/%^%C%A$9$k$,!"$G$b07$$$O2<J,$J%X%C%@!<$r(B -$BA^F~$7$h$&$H$7$?$j$O$7$^$;$s(B --- $BC1=c$K!"%U%!%$%k$r$=$N%0%k!<%W(B -$B$NA[%5!<%P!A0(B (@dfn{name}) $B$H$=$l$KB3$/@55,I=8=$H2>(B -$BA[JQ?t@_Dj$NNs$+$i$J$j$^$9!#0J2<$,$3$l$K;H$($kJQ?t$G$9(B --- $BJQ?t(B -$B$N?t$K05E]$5$l$J$$$G$/$@$5$$!#$[$H$s$I$NJ8=ql9g!"$3$l$O5-;v$N@hF,$K%]%$%s%H$r0\F0$5$;$k4X?t$G$J$/(B -$B$F$O$J$j$^$;$s!#(B - -@item nndoc-head-begin -$B$3$l$,$"$k>l9g!"$3$l$O5-;v$N%X%C%@!<$K%^%C%A$9$k@55,I=8=$G$J$/$F(B -$B$O$J$j$^$;$s!#(B - -@item nndoc-head-end -$B$3$l$O5-;v$N%X%C%@!<$N:G8e$K%^%C%A$7$J$/$F$O$J$j$^$;$s!#$3$N=i4|(B -$B@_DjCM$O(B @samp{^$} --- $B6u9T$G$9!#(B - -@item body-begin-function -$B$3$l$,$"$k>l9g!"$3$N4X?t$O5-;v$N%\%G%#$N3+;O0LCV$K%]%$%s%H$r0\F0(B -$B$5$;$k4X?t$G$J$/$F$O$J$j$^$;$s!#(B - -@item body-begin -$B$3$l$O5-;v$N%\%G%#$N3+;O0LCV$K%^%C%A$7$J$/$F$O$J$j$^$;$s!#$3$N=i(B -$B4|@_DjCM$O(B @samp{^\n} $B$G$9!#(B - -@item body-end-function -$B$3$l$,$"$k>l9g!"$3$N4X?t$O5-;v$N%\%G%#$N:G8e$N0LCV$K%]%$%s%H$r0\(B -$BF0$5$;$k4X?t$G$J$/$F$O$J$j$^$;$s!#(B - -@item body-end -$B$3$l$,$"$l$P!"5-;v$N%\%G%#$N:G8e$K%^%C%A$7$J$/$F$O$J$j$^$;$s!#(B - -@item file-end -$B$3$l$,$"$k>l9g!"$3$l$O%U%!%$%k$N:G8e$K%^%C%A$7$J$/$F$O$J$j$^$;$s!#(B -$B$3$N@55,I=8=$N8e$m$N%F%-%9%H$OA4$F!"40A4$KL5;k$5$l$^$9!#(B - -@end table - -$B$3$N$h$&$K!"$3$l$i$NJQ?t$r;H$C$F(B @code{nndoc} $B$OJ8=q%U%!%$%k$r!"(B -$B$=$l$>$l%X%C%@!<$H%\%G%#$r;}$C$?5-;v$NO"$J$j$H$7$F2rK6$9$k$3$H$,(B -$B$G$-$^$9!#$7$+$7!"A4$F$NJ8=ql9g$KM-MQ$G$9!#(B - -@item article-transform-function -$B$3$l$,$"$l$P!"$3$N4X?t$O5-;v$,MW5a$5$l$?$H$-$K8F$S=P$5$l$^$9!#$3(B -$B$l$O!"5-;v$N%X%C%@!<$H%\%G%#$NN>J}$K$h$j9-HO0O$JJQ7A$r9T$J$&$?$a(B -$B$K;H$o$l$k$b$N$G$9!#(B - -@item generate-head-function -$B$3$l$,$"$l$P!"$3$N4X?t$O(B gnus $B$,M}2r$G$-$k%X%C%@!<$r@8@.$9$k$?$a(B -$B$K8F$S=P$5$l$^$9!#$3$l$O5-;vHV9f$r%Q%i%a!<%?$H$7$F8F$S=P$5$l!"Ld(B -$BBj$N5-;v$N$-$l$$$J%X%C%@!<$r@8@.$9$k$3$H$r5a$a$i$l$^$9!#$3$l$OA4(B -$B$F$N5-;v$N%X%C%@!<$,MW5a$5$l$k$H$-$K8F$S=P$5$l$^$9!#(B - -@end table - -$B;d$,:n$C$?Cf$G:G$bJ#;($JNc(B --- $BI8=`$^$H$aAw$j7A<0$r8+$F$_$^$7$g$&!#(B - -@example -(standard-digest - (first-article . ,(concat "^" (make-string 70 ?-) "\n\n+")) - (article-begin . ,(concat "\n\n" (make-string 30 ?-) "\n\n+")) - (prepare-body-function . nndoc-unquote-dashes) - (body-end-function . nndoc-digest-body-end) - (head-end . "^ ?$") - (body-begin . "^ ?\n") - (file-end . "^End of .*digest.*[0-9].*\n\\*\\*\\|^End of.*Digest *$") - (subtype digest guess)) -@end example - -70 $BJ8;z$N%@%C%7%e(B(`-')$B$N9T$h$jA0$OA4$FL5;k$5$l$k$H$$$&$N$,J,$+$j$^(B -$B$9!#$^$?(B @samp{^End of} $B$G;O$^$k9T$h$j8e$m$bA4$FL5;k$5$l$^$9!#3F(B -$B5-;v$O(B30 $BJ8;z$N%@%C%7%e$N9T$G;O$^$j!"%X%C%@!<$H%\%G%#$N6h@Z$j$N(B -$B9T$O0l8D$N%9%Z!<%9$r4^$`$3$H$,$"$j!"$=$7$F%\%G%#$O$=$l$,EO$5$l$k(B -$BA0$K(B @code{nndoc-unquote-dashes} $B$rDL$5$l$^$9!#(B - -$B$"$J$?FH<+$NJ8=qDj5A$r(B @code{nndoc} $B$K@\B3$9$k$K$O!"(B -@code{nndoc-add-type} $B4X?t$r;HMQ$7$^$9!#$3$l$OFs$D$N%Q%i%a!<%?$r(B -$B$H$j$^$9(B --- $B0l$DL\$O$=$NDj5A<+?H$G!"Fs$DL\$N(B ($B>JN,2DG=$J(B) $B%Q%i(B -$B%a!<%?$O$3$NDj5A$r!"J8=ql9g$O(B -@code{nil} $B$rJV$7!"$=$Nl9g$O(B @code{t} $B$rJV$7!"$=$N$_$=$K3Z$r$5$;$kJ}$r$9$k$N$b;~$K$OJXMx(B -$B$G$9!#(B - -@sc{soup} $B$H8F$P$l$k%U%!%$%k7A<0$O%K%e!<%9$H%a!<%k$r%5!<%P!<$+$i(B -$B2H$N%^%7%s$X$HE>Aw$7!"$=$l$r$^$?La$9$?$a$K3+H/$5$l$^$7$?!#$A$g$C(B -$B$HLLE]$/$5$$$+$b$7$l$J$$$1$I$M!#(B - -$B$O$8$a$K$$$/$D$+MQ8l$r!#(B - -@table @dfn - -@item server -$B$3$l$O30$N@$3&$K7R$,$C$F$$$F!"$"$J$?$,%K%e!<%9$H%a!<%k$rAw$N@$3&$H$$$+$J$k7A$G$b@\B3$5$l$F$$$^$;$s!#(B - -@item packet -$B%a%C%;!<%8$HL?Na$r4^$s$@$b$N!#%Q%1%C%H$K$OFsA0$G$9!#$3$3$G(B @var{X} $B$O?t;z$G$9!#(B - -@item response packets -($BJV?.%Q%1%C%H(B) -$B$3$N%Q%1%C%H$O<+Bp%^%7%s$G:n$i$l$k%Q%1%C%H$G!"IaDL$O$"$J$?$N=q$$(B -$B$?JV;v$,4^$^$l$F$$$^$9!#$3$l$i$O=i4|@_Dj$G$O(B -@file{SoupinX.tgz} $B$H$$$&L>A0$G$9!#$3$3$G(B @var{X} $B$O?t;z$G$9!#(B - -@end table - -@end table - - -@enumerate - -@item -$B$^$:(B @sc{soup} $B%Q%1%C%H$r:n$k$?$a$K%5!<%P!<$K%m%0%$%s$7$^$9!#(B -@sc{soup} $B$N$?$a$N@lMQ$N%V%D(B (@code{awk} $B%W%m%0%i%`$N$h$&$J(B) $B$r(B -$B;H$C$F$bNI$$$7!"(B gnus $B$N(B @sc{soup} $BL?Na$r;H$C$F%Q%1%C%H$r:n$C$F(B -$B$bNI$$$G$9(B (@kbd{O s} $B$"$k$$$O(B @kbd{G s b} $B$=$7$F(B @kbd{G s p}) -(@pxref{SOUP Commands})$B!#(B - -@item -$B%Q%1%C%H$r<+Bp$KE>Aw$7$^$9!#EEAw$7$^$9!#(B - -@item -Gnus $B$+$i(B @kbd{G s s} $BL?Na$r;H$C$F$3$N%Q%1%C%H$+$i%a!<%k$r=P$7$^$9!#(B - -@item -$B$"$H$O$3$l$r;`$L$^$GB3$1$^$9!#(B - -@end enumerate - -$B$D$^$j4pK\E*$KFs$$$^$9!#(B - -@item G s w -@kindex G s w (Group) -@findex gnus-soup-save-areas -$BA4$F$N(B @sc{soup} $B%G!<%?%U%!%$%k$rJ]B8$7$^$9(B -(@code{gnus-soup-save-areas})$B!#(B - -@item G s s -@kindex G s s (Group) -@findex gnus-soup-send-replies -$BJV?.%Q%1%C%H$+$iA4$F$NJV?.$rAw=P$9$k(B -(@code{gnus-soup-send-replies})$B!#(B - -@item G s p -@kindex G s p (Group) -@findex gnus-soup-pack-packet -$BA4$F$N%U%!%$%k$r(B @sc{soup} $B%Q%1%C%H$K:-Jq$9$k(B -(@code{gnus-soup-pack-packet})$B!#(B - -@item G s r -@kindex G s r (Group) -@findex nnsoup-pack-replies -$BA4$F$NJV?.$rJV?.%Q%1%C%H$K:-Jq$9$k(B (@code{nnsoup-pack-replies})$B!#(B - -@item O s -@kindex O s (Summary) -@findex gnus-soup-add-article -$B$3$N35N,%b!<%IL?Na$O!"8=:_$N5-;v$r(B @sc{soup} $B%Q%1%C%H$KDI2C$7$^(B -$B$9(B (@code{gnus-soup-add-article})$B!#$3$l$O%W%m%;%9(B/$B@\F,0z?t$N=,47(B -$B$K=>$$$^$9(B (@pxref{Process/Prefix})$B!#(B - -@end table - - -gnus $B$,$3$l$i$N!#=i4|@_DjCM$O(B -@samp{gnus-prefix}$B!#(B - -@item gnus-soup-packer -@vindex gnus-soup-packer -@sc{soup} $B%Q%1%C%H$r:-Jq$9$kL?NaJ8;zNs$N7A<0!#=i4|@_DjCM$O(B -@samp{tar cf - %s | gzip > $HOME/Soupout%d.tgz}$B!#(B - -@item gnus-soup-unpacker -@vindex gnus-soup-unpacker -@sc{soup} $B%Q%1%C%H$rl=j!#=i4|@_DjCM$O(B @file{~/}$B!#(B - -@item gnus-soup-packet-regexp -@vindex gnus-soup-packet-regexp -@code{gnus-soup-packet-directory} $BFb$N(B @sc{soup} $B%Q%1%C%H$K%^%C(B -$B%A$9$k@55,I=8=!#(B - -@end table - - -@node SOUP Groups -@subsubsection @sc{soup} $B%0%k!<%W(B -@cindex nnsoup - -@code{nnsoup} $B$O(B @sc{soup} $B%Q%1%C%H$rFI$`$?$a$N%P%C%/%(%s%I$G$9!#(B -$B$3$l$OF~$C$F$-$?%Q%1%C%H$rFI$_!"$=$l$r$l$N%a%C%;!<%8$H:w0z%U%!%$%k$r$3$N(B -$B%G%#%l%/%H%j!<$K0\F0$5$;$k!#=i4|@_Dj$O(B @file{~/SOUP/}$B!#(B - -@item nnsoup-replies-directory -@vindex nnsoup-replies-directory -$BA4$F$NJV?.$O!"JV?.%Q%1%C%H$K:-Jq$5$l$kA0$K$3$N%G%#%l%/%H%j!<$K3J(B -$BG<$5$l$k!#=i4|@_Dj$O(B @file{~/SOUP/replies/"}$B!#(B - -@item nnsoup-replies-format-type -@vindex nnsoup-replies-format-type -$BJV?.%Q%1%C%H$N(B @sc{soup} $B7A<0!#=i4|@_DjCM$O(B @samp{?n} (rnews) -$B$G!"$3$NJQ?t$K$O?($k$Y$-$G$O$J$$$H;d$O;W$$$^$9!#$?$V$sJ8=q$KL@5-(B -$B$9$Y$-$G$5$($J$+$C$?$M!#$A$'$C(B! $B$b$&pJs$r3JG<$9$k>l=j!#$3$l$O(B @code{nntp} -$B$N0UL#$G$N(B ``$B%"%/%F%#%V%U%!%$%k(B'' $B$G$O$J$/!"(BEmacs Lisp $B$N%U%!%$(B -$B%k$G$9!#$3$N%U%!%$%k$rL5$/$7$F$7$^$C$?$j!"2?$+2u$7$F$7$^$C$?$i!"(B -$B$"$J$?$O;`$K$^$9!#=i4|@_DjCM$O(B @file{~/SOUP/active} $B$G$9!#(B - -@item nnsoup-packer -@vindex nnsoup-packer -$BJV?.(B @sc{soup} $B%Q%1%C%H$r:-Jq$9$kL?NaJ8;zNs$N7A<0!#=i4|@_DjCM(B -$B$O(B @samp{tar cf - %s | gzip > $HOME/Soupin%d.tgz}$B!#(B - -@item nnsoup-unpacker -@vindex nnsoup-unpacker -$BF~$C$F$/$k(B @sc{soup} $B%Q%1%C%H$rl=j!#=i4|@_DjCM$O(B -@file{~/}$B!#(B - -@item nnsoup-packet-regexp -@vindex nnsoup-packet-regexp -$BF~$C$F$-$?(B @sc{soup} $B%Q%1%C%H$K%^%C%A$9$k@55,I=8=!#=i4|@_DjCM(B -$B$O(B @samp{Soupout}$B!#(B - -@item nnsoup-always-save -@vindex nnsoup-always-save -@code{nil} $B0J30$G$"$l$P!"%a%C%;!<%8$rEj9F$7$?8e$KJV?.%P%C%U%!$r(B -$BJ]B8$9$k!#(B - -@end table - - -@node SOUP Replies -@subsubsection SOUP $BJV?.(B - -$BC1$K(B @code{nnsoup} $B$r;H$&$@$1$G$O!"(B@sc{soup} $BJV?.%Q%1%C%HCf$N$"(B -$B$J$?$NEj9F$H%a!<%k$NAw?.$,!"KbK!$N$h$&$K<+F0E*$K=*N;$9$k$o$1$G$O(B -$B$"$j$^$;$s!#$=$l$r5/$3$9$K$O$b$&$A$g$C$HF/$+$J$/$F$O$$$1$^$;$s!#(B - -@findex nnsoup-set-variables -@code{nnsoup-set-variables} $BL?Na$O!"$"$J$?$NA4$F$N%U%)%m!<%"%C%W(B -$B5-;v$HJV?.$r(B @sc{soup} $B%7%9%F%`$K3N$NIaDL$N%0%k!<%W$N(B -$B$h$&$K5-;v$rFI$_$^$9!#%0%k!<%W%P%C%U%!(B (@pxref{Foreign -Groups}) $B$N(B @kbd{G w} $BL?Na$K$h$C$F$*A[%5!<%P!A[%0%k!<%W(B -@cindex nnvirtual -@cindex virtual groups - -nnvirtual $B%0%k!<%W(B (@dfn{nnvirtual group}) $B$O$N%0%k!<%W$N(B -$B=89g0J>e$N2?J*$G$b$"$j$^$;$s!#(B - -$BNc$($P!"$b$7>.$5$J%0%k!<%W$r$?$/$5$sFI$`$N$,7y$K$J$C$F$-$?$i!"$=(B -$B$l$i$r0l$D$NBg$-$J%0%k!<%W$KF~$l$F!"7y$K$J$k$/$i$$5pBg$GA[%0%k!<%WFb$GIU$1$i$l$?A4$F$N0u$O!"$=$N9=@.%0%k!<%W$N5-;v$K$/$C(B -$B$D$1$i$l$^$9!#$D$^$j!"$b$72>A[%0%k!<%WFb$G5-;v$K2D;k5-;v$N0u$r$D(B -$B$1$k$H!"$=$N5-;v$O$b$H$b$H$N9=@.%0%k!<%W$NCf$G$b2D;k5-;v$K$J$j$^(B -$B$9!#(B ($B$=$7$F5U$b@.$jN)$A$^$9(B --- $B9=@.%0%k!<%WFb$GIU$1$?0u$O2>A[(B -$B%0%k!<%WFb$G$bI=<($5$l$^$9!#(B) - -$B$3$l$,!"(BAndrea Dworkin $B$K4X$9$kA4$F$N%K%e!<%9%0%k!<%W$r!"0l$D$N(B -$B5pBg$G%7%"%o%;$J%K%e!<%9%0%k!<%W$K$^$H$a$k(B @code{nnvirtual} $BJ}K!(B -$B$NNc$G$9!#(B - -@lisp -(nnvirtual "^alt\\.fan\\.andrea-dworkin$\\|^rec\\.dworkin.*") -@end lisp - -$B9=@.%0%k!<%W$O4pK\%0%k!<%W$G$b30It%0%k!<%W$G$b9=$$$^$;$s!#A4$FLd(B -$BBjL5$/F0$/$O$:$G$9$,!"$b$7$"$J$?$N%3%s%T%e!<%?!<$,GzH/$G$b$7$F$7(B -$B$^$C$?$i!"$=$l$O$?$V$s;d$,0-$$$s$G$7$g$&$M!#(B - -$B$$$/$D$+$N%5!<%P!<$+$iF1$8%0%k!<%W$r=8$a$k$3$H$O!"MxMQl9g$O!"Hs>o(B -$B$KNI$$$+$bCN$l$^$;$s!#$b$7$"$J$?$,(B @samp{soc.motss} $B$r!"F|K\$N%5!<(B -$B%P!<$H%N%k%&%'!<$N%5!<%P!<$NN>J}$+$iFI$_$?$1$l$P!"%0%k!<%W$N@55,(B -$BI=8=$H$7$F0J2<$NCM$,;H$($^$9!#(B - -@example -"^nntp\\+server\\.jp:soc\\.motss$\\|^nntp\\+server\\.no:soc\\.motss$" -@end example - -($B$G$b$A$g$C$HCm0U!#(B@kbd{G m} $B$G%0%k!<%W$r:n@.$9$k$H$-$O!"%P%C%/(B -$B%9%i%C%7%e$rFs=E$KIU$1$F$O$$$1$^$;$s!#$=$7$FJ8;zNs$N:G=i$H:G8e$N(B -$B0zMQ5-9f$bJ}$N%0%k!<%W$N5-;v$O(B -$BA4It40A4$K0l$D$N%0%k!<%W$K$J$j!"=EJ#$bL5$$$O$:$G$9!#%9%l%C%II=<((B -($B$H$=$NB>(B)$B$bDL>oDL$j$&$^$/F0:n$9$k$G$7$g$&$1$I!"5-;v$NJB$V=g=x$K(B -$B$OLdBj$,$"$k$+$b$7$l$^$;$s!#F|IU$K$h$kJB$YBX$($O$3$3$G$O;EMM30$H(B -$B$J$k$+$b$7$l$^$;$s(B (@pxref{Selecting a Group})$B!#(B - -$B$J$*!"$3$3$G0l$D$@$1@)8B$,$"$j$^$9(B --- $B2>A[%0%k!<%W$K4^$^$l$k%0(B -$B%k!<%W$OA4$F@8$-$F$$$k(B($B$9$J$o$A!"9XFI$^$?$OHs9XFI$N(B)$B>uBV$G$J$/$F(B -$B$O$J$j$^$;$s!#:o=|$"$k$$$O%>%s%S%0%k!<%W$O(B @code{nnvirtual} $B%0%k!<(B -$B%W$N9=@.%0%k!<%W$K$J$k$3$H$O$G$-$^$;$s!#(B - -@vindex nnvirtual-always-rescan -@code{nnvirtual-always-rescan} $B$,(B @code{nil} $B0J30$G$"$l$P!"(B -@code{nnvirtual} $B$O2>A[%0%k!<%W$KF~$C$?$H$->o$K!"L$FI5-;v$rAv::(B -$B$7$^$9!#$3$NJQ?t$,(B @code{nil} ($B$3$l$,=i4|@_Dj(B)$B$G$"$C$F!"2>A[%0%k!<(B -$B%W$r:n@.$7$?8e$K9=@.%0%k!<%WFb$N5-;v$rFI$s$@>l9g$O!"$=$N9=@.%0%k!<(B -$B%W$GFI$^$l$?5-;v$O!"2>A[%0%k!<%W$KF~$C$?$H$-$KI=<($5$l(B $B$k$G$7$g(B -$B$&!#$b$76&DL$N9=@.%0%k!<%W$r;}$DFs$D$N2>A[%0%k!<%W$,$"$k>l9g$K$b(B -$B$3$N1F6A$,$"$j$^$9!#$=$N>l9g$O$3$NJQ?t$r(B @code{t} $B$K$7$?J}$,NI$$(B -$B$G$9!#$"$k$$$O2>A[%0%k!<%W$KF~$k;~$K!"Kh2s$=$N%0%k!<%W$N>e$G(B -@code{M-g} $B$rC!$$$F$bNI$$$G$9(B --- $B$3$l$O$[$\F1MM$N8z2L$,$"$j$^$9!#(B - -@code{nnvirtual} $B$O%a!<%k$H%K%e!<%9$NN>J}$N%0%k!<%W$r9=@.%0%k!<%W$H$9$k(B -$B;v$,$G$-$^$9!#(B@code{nnvirtual} $B%0%k!<%W$N5-;v$KJVEz$9$k$H$-$O!"(B -@code{nnvirtual} $B$O5-;v$N=P=j$N9=@.%0%k!<%W$N%P%C%/%(%s%I$K$=$l$,%K%e!<(B -$B%9$N%P%C%/%(%s%I$G$"$k$+%a!<%k$N%P%C%/%(%s%I$G$"$k$+$r?R$M$J$1$l$P$J$j$^(B -$B$;$s!#$7$+$7!"(B@kbd{^} $B$r$7$?$H$-$K$O!"IaDL$O9=@.%P%C%/%(%s%I$,$3$l$rCN$k(B -$B3N$+$JJ}K!$O$J$/!"$=$N>l9g$O!"(B@code{nnvirtual} $B$O(B gnus $B$K5-;v$O%K%e!<%9(B -$B$G$J$$%P%C%/%(%s%I$+$iMh$?$H9p$2$k;v$K$J$j$^$9!#(B ($B0BA4$N$?$a$K!#(B) - -$B$3$N$h$&$J>l9g$O!"%a%C%;!<%8%P%C%U%!$G$N(B @kbd{C-c C-t} $B$,1~Ez$7$h$&$H$7(B -$B$F$$$k5-;v$+$i(B @code{Newsgroups} $B9T$rH4$-=P$7$FA^F~$7$^$9!#(B - - - -@node Kibozed Groups -@subsection Kiboze $B%0%k!<%W(B -@cindex nnkiboze -@cindex kibozing - -@dfn{Kiboze} $B$9$k!"$H$O!"(B``$B%K%e!<%9%9%W!<%kA4It(B($B$"$k$$$O$=$N0lIt(B) -$B$+$i(B grep $B$9$k$3$H(B'' $B$H%*%C%/%9%U%)!<%IBg<-E5$K$h$C$FDj5A$5$l$F$$(B -$B$^$9!#(B@code{nnkiboze} $B$O$3$l$r$"$J$?$N$?$a$K9T$C$F$/$l$k%P%C%/%((B -$B%s%I$G$9!#4r$7$$$M(B! $B$3$l$G$I$s$J(B @sc{nntp} $B%5!<%P!<$G$b!"Lr$KN)(B -$B$?$J$$MW5a$G;_$^$C$F$7$^$&$^$G9s;H$9$k$3$H$,$G$-$k$M!#$"$"!"$J$s(B -$B$F9,$;$J$s$@(B! - -@kindex G k (Group) -kiboze $B%0%k!<%W$r:n@.$9$k$K$O!"%0%k!<%W%P%C%U%!$G(B @kbd{G k} $BL?Na(B -$B$r;H$$$^$9!#(B - -@code{nnkiboze} $BJ}K!$K$*$1$k%"%I%l%9Ms$O!"(B@code{nnvirtual} $B$HF1(B -$BMM$K!"(B@code{nnkiboze} $B$K(B ``$B4^$a$?$$(B'' $B%0%k!<%W$K%^%C%A$9$k@55,I=(B -$B8=$G$9!#$3$3$,(B @code{nnkiboze} $B$H(B @code{nnvirtual} $B%P%C%/%(%s%I(B -$B$N:G$bN`;w$7$F$$$kE@$G$9!#(B - -$B$3$N9=@.%0%k!<%W$rNs5s$9$k@55,I=8=$K2C$($F!"(B@code{nnkiboze} $B%0%k!<(B -$B%W$K$O!"%0%k!<%WFb$N$I$N5-;v$r4^$a$k$+$r7h$a$k%9%3%"%U%!%$%k$,$J(B -$B$/$F$O$J$j$^$;$s(B (@pxref{Scoring})$B!#(B - -@kindex M-x nnkiboze-generate-groups -@findex nnkiboze-generate-groups -$B$"$J$?$NM_$7$$(B @code{nnkiboze} $B%0%k!<%W$r:n@.$7$?8e$K$O!"(B -@kbd{M-x nnkiboze-generate-groups} $B$rpJs$r3JG<$9$k!"(B@file{.newsrc} -$B$NJd=u%U%!%$%k$G$9!#(B - -@code{nnkiboze} $B%0%k!<%WFb$N4{FI$H$J$C$?5-;v$O!"$=$N5-;v$N(B -@sc{nov} $B9T$,(B @sc{nov} $B%U%!%$%k$+$i:o=|$5$l$^$9!#(B - - -@node Gnus Unplugged -@section Gnus $B$N@Z$jN%$7(B -@cindex offline -@cindex unplugged -@cindex Agent -@cindex Gnus Agent -@cindex Gnus Unplugged - -$B$$$K$7$($N;~Be(B($B$*$h$=(B 1988 $BG/(B 2 $B7n:"(B)$B!"?M!9$O%K%e!<%9%j!<%@!<$r!"(B -$BBg$-$J%^%7%s$N>e$G%M%C%H%o!<%/$K1JB3E*$K@\B3$7$FAv$i$;$F$$$^$7$?!#(B -$B%K%e!<%9$NG[Aw$O%K%e!<%9%5!<%P!<$K$h$C$Fe$i$J$$$h$&$K!"A4$F$N%K%e!<%9$H%a!<%k$r5[$$>e$2!"EEOC$r@Z$j!"(B -$B?t;~4V3]$1$FFI$_!"$=$7$FAw$j$?$$JV?.$rA4$FAw?.$9$k!"$H$$$&e$G%K%e!<%9$rFI$`?M$,$"$J$?$7$+$$$J$1$l$P!"%K%e!<%9%5!<(B -$B%P!<$N5!G=$r%K%e!<%9%j!<%@!<$KG$$;$k$h$&$K$9$k$3$H$OM}$K$+$J$C$F(B -$B$$$^$9!#(B - -Gnus $B$r(B ``$B%*%U%i%$%s(B'' $B$N%K%e!<%9%j!<%@!<$H$7$F;H$&$N$O6K$a$F4J(B -$BC1$G$9!#(B - -@itemize @bullet -@item -$B$^$:!"%M%C%H%o!<%/$K40A4$K7R$,$C$F$$$k%^%7%s>e$GF0:n$5$;$k$N$HF1(B -$B$8$h$&$K!"(Bgnus $B$r@_Dj$7$^$9!#$^$:$d$C$F$*$$$G!#KM$O$3$3$GBT$C$F(B -$B$k$+$i!#(B - -@item -$B$=$7$?$i!"0J2<$NKbK!$NC$9J}K!!#(B -* Outgoing Messages:: $BEj9F!"%a!<%k$r=P$9$H$-$K$J$K$,5/$3$k$N$+(B? -* Agent Variables:: $B%+%9%?%^%$%:$O3Z$7!#(B -* Example Setup:: $B%*%U%i%$%s?M4V$N$?$a$N(B @file{.gnus.el} $B$NNc!#(B -* Batching Agents:: @code{cron} $B%8%g%V$K$h$k%K%e!<%9uBV$G5/F0$7$^$9!#$3$N>uBV$G$O!"$9$G$Kl$G$9$0$K?7$7$$%K%e!<%9$rFI$`$3$H$b$G$-$^$9$7!"%K%e!<(B -$B%9$r%m!<%+%k%^%7%s$K%@%&%s%m!<%I$9$k$3$H$b$G$-$^$9!#8eH$7$F$/$@$5$$!#(B) - -@item -$B5-;v$ruBV$K(B -$B$5$;!"(BPPP $B4X78(B($B$J$I(B)$B$rJD$8$^$9!#$=$&$7$F%K%e!<%9$r%*%U%i%$%s$GFI(B -$B$`$3$H$,$G$-$^$9!#(B - -@item -$B$=$7$FBh(B 2 $B%9%F%C%W$KLa$j$^$9!#(B -@end itemize - -$B0J2<$K%(!<%8%'%s%H$r=i$a$F(B($B$+$=$3$i$K(B)$B;H$&$H$-$KI,MW$J$$$/$D$+$N(B -$B:n6H$r<($7$^$9!#(B - -@itemize @bullet - -@item -$B$I$N%5!<%P!<$r%(!<%8%'%s%H$GLLE]$r8+$k$+$r7h$a$^$9!#$b$7%a!<%k%P%C(B -$B%/%(%s%I$,$"$l$P!"$=$l$r%(!<%8%'%s%H$KLLE]$r8+$5$;$k$N$O$*$=$i$/(B -$BL50UL#$G$7$g$&!#%5!<%P!<%P%C%U%!!<$K0\F0$7(B ($B%0%k!<%W%P%C%U%!!<$G(B -@kbd{^})$B!"%(!<%8%'%s%H$K07$C$FM_$7$$%5!<%P!<(B($BJ#?t2D(B)$B$G(B @kbd{J a} -$B$r2!$7$^$9(B (@pxref{Server Agent Commands})$B!#$3$l$OBgDq$N>l9g!"%P%C(B -$B%U%!!<$N2<$K0lMwI=<($5$l$F$$$k4pK\A*BrJ}K!$@$1$G$7$g$&!#(B - -@item -$B%@%&%s%m!<%IJ}?K$r7hDj$7$^$9!#(B@xref{Agent Categories} - -@item -$B$($($H!D!"0J>e$G$9!#(B -@end itemize - - -@node Agent Categories -@subsection $B%(!<%8%'%s%HJ,N`(B - -$B%K%e!<%9G[Aw5!9=$H%K%e!<%9%j!<%@!<$rE}9g$9$k0l$D$NBg$-$JM}M3$O!"(B -$B$I$N5-;v$r%@%&%s%m!<%I$9$k$+$K$D$$$F!"$h$jNI$$@)8f$r2DG=$H$9$k$3(B -$B$H$G$9!#G|Bg$JNL$N5-;v$r%@%&%s%m!<%I$7$F$b$"$^$j0UL#$O$J$/!"$=$l(B -$B$i$rFI$s$G$b$"$^$jLLGr$/$J$$$3$H$,J,$+$k$@$1$G$9!#2?$r%@%&%s%m!<(B -$B%I$9$k$+$NA*Br$O$b$C$H?5=E$G$"$k$Y$-$G$"$j!"$=$N5-;v$,LLGr$$$HJ,(B -$B$+$C$?;~E@$G!"%@%&%s%m!<%I$9$k$?$a$N0u$ro(B) $B$I$N5-;v$r%@%&%s%m!<%I$9$k$N$,E,Ev$+$H$$$&Bg$^$+$JNX3T$r(B -$BM?$($k=R8l!#$=$7$F(B - -@item -($BDL>o(B) $B$I$N5-;v$r%@%&%s%m!<%I$9$k$+$r7h$a$k$H$-$N$h$j$-$a$N:Y$+(B -$B$$%9%3%"5,B'!#(B($B$3$N%@%&%s%m!<%I%9%3%"(B (@dfn{download score}) $B$O(B -$BDL>o$N%9%3%"$H$OA4$/4X78$,L5$$$3$H$KCm0U$7$F$/$@$5$$!#(B) -@end enumerate - -$B=R8l$OO@M}1i;;;R$,4V$K;6$j$P$a$i$l$?=R8l$NAH$_9g$o$;$+$i$J$j$^$9!#(B - -$B$*$=$i$/$$$/$D$+$NNc$,$=$N$^$^;H$($^$9!#(B - -$B0J2<$O4JC1$J=R8l$G$9!#(B($B$3$l$O=i4|@_Dj$N=R8l$G$9!#$D$^$j!"B>$N$I(B -$B$NJ,N`$K$b4^$^$l$J$$A4$F$N%0%k!<%W$KBP$7$F;HMQ$5$l$^$9!#(B) - -@lisp -short -@end lisp - -$B$H$C$F$b4JC1$G$7$g(B? $B$3$N=R8l$O!"5-;v$,C;$$(B(``$BC;$$(B'' $B2ACM$,$"$k(B) -$B>l9g$K8B$j??$K$J$j$^$9!#(B - -$B$3$l$O$b$C$HJ#;($J=R8l$G$9!#(B - -@lisp -(or high - (and - (not low) - (not long))) -@end lisp - -$B$3$N0UL#$O!"9b$$%9%3%"$r;}$C$F$$$k$+!"$"$k$$$O%9%3%"$,Dc$/$J$/$F(B -$B$+$DD9$/$J$$!"$H$$$&5-;v$r%@%&%s%m!<%I$9$k!"$H$$$&$3$H$G$9!#$o$+(B -$B$k$@$m!#(B - -$B;H$C$F$b$h$$O@M}1i;;;R$O!"(B@code{or}$B!"(B @code{and}$B!"(B@code{not} $B$G(B -$B$9!#(B($B$b$7;H$$$?$1$l$P!"$h$j(B ``C'' $BIw$N1i;;;R(B @samp{|}$B!"(B@code{&}$B!"(B -@code{!} $B$rBe$j$K;H$&$3$H$,$G$-$^$9!#(B) - -$B0J2<$N=R8l$O$"$i$+$8$aDj5A$5$l$F$$$^$9$,!"$3$l$i$N$I$l$b$"$J$?$N(B -$B$d$j$?$$$3$H$K0lCW$7$J$1$l$P!"<+J,$GFH<+$N$b$N$r=q$/$3$H$b$G$-$^$9!#(B - -@table @code -@item short -$B5-;v$,(B @code{gnus-agent-short-article} $B9T$h$jC;$+$1$l$P??!#(B -$B=i4|@_DjCM$O(B 100$B!#(B - -@item long -$B5-;v$,(B @code{gnus-agent-long-article} $B9T$h$jD9$1$l$P??!#=i4|@_Dj(B -$BCM$O(B 200$B!#(B - -@item low -$B5-;v$N%@%&%s%m!<%I%9%3%"$,(B @code{gnus-agent-low-score} $B0J2<$G$"(B -$B$l$P??!#=i4|@_DjCM$O(B 0$B!#(B - -@item high -$B5-;v$N%@%&%s%m!<%I%9%3%"$,(B @code{gnus-agent-high-score} $B0J>e$G$"(B -$B$l$P??!#=i4|@_DjCM$O(B 0$B!#(B - -@item spam -gnus $B%(!<%8%'%s%H$,$=$N5-;v$r(B SPAM $B$@$H8+Pv$7$?$i??!#$3$NH/8+E*(B -$Bo$K??!#(B - -@item false -$B>o$K56!#(B -@end table - -$B$"$J$?$,<+J,$NFH<+$N=R8l4X?t$r:n@.$7$?$1$l$P!"$3$l$rCN$C$F$*$$$F(B -$B$/$@$5$$(B: $B4X?t$O0z?tL5$7$G8F$S=P$5$l$^$9$,!"(B@code{gnus-headers} -$B$H(B @code{gnus-score} $BF0E*JQ?t$K$OJXMx$JCM$,B+G{$5$l$^$9!#(B - -$B$5$F!"%@%&%s%m!<%I%9%3%"$NJ8K!$ODL>o$N%9%3%"%U%!%$%k$NJ8K!$HF1$8(B -$B$G$9$,!"Nc30$H$7$F!"o$OA4$F$NJ,N`$OJ,N`%P%C%U%!!<$+$i4IM}$7$^$9!#(B($B%0%k!<%W%P%C%U%!!<(B -$B$+$i(B @kbd{J c} $BL?Na$K$h$C$F(B) $B=i$a$F$3$l$KF~$C$?$H$-!"=i4|@_Dj$N(B -$BJ,N`$@$1$,I=<($5$l$^$9!#(B - - -$B0J2<$NL?Na$,$3$N%P%C%U%!!<$G;HMQ$G$-$^$9!#(B - -@table @kbd -@item q -@kindex q (Category) -@findex gnus-category-exit -$B%0%k!<%W%P%C%U%!!<$KLa$k(B (@code{gnus-category-exit})$B!#(B - -@item k -@kindex k (Category) -@findex gnus-category-kill -$B8=:_$NJ,N`$r>C5n$9$k(B (@code{gnus-category-kill})$B!#(B - -@item c -@kindex c (Category) -@findex gnus-category-copy -$B8=:_$NJ,N`$rJ#@=$9$k(B (@code{gnus-category-copy})$B!#(B - -@item a -@kindex a (Category) -@findex gnus-category-add -$B?7$7$$J,N`$rDI2C$9$k(B (@code{gnus-category-add})$B!#(B - -@item p -@kindex p (Category) -@findex gnus-category-edit-predicate -$B8=:_$NJ,N`$N=R8l$rJT=8$9$k(B (@code{gnus-category-edit-predicate})$B!#(B - -@item g -@kindex g (Category) -@findex gnus-category-edit-groups -$B8=:_$NJ,N`$KB0$9$k%0%k!<%W$N0lMw$rJT=8$9$k(B -(@code{gnus-category-edit-groups})$B!#(B - -@item s -@kindex s (Category) -@findex gnus-category-edit-score -$B8=:_$NJ,N`$N%@%&%s%m!<%I%9%3%"5,B'$rJT=8$9$k(B -(@code{gnus-category-edit-score})$B!#(B - -@item l -@kindex l (Category) -@findex gnus-category-list -$BA4$F$NJ,N`$rI=<($9$k(B (@code{gnus-category-list})$B!#(B -@end table - - -@node Category Variables -@subsubsection $BJ,N`JQ?t(B - -@table @code -@item gnus-category-mode-hook -@vindex gnus-category-mode-hook -$BJ,N`%P%C%U%!!<$GA0!#(B - -@item g -$BJ,N`$KB0$9$k%0%k!<%W$N?t!#(B -@end table - -@item gnus-category-mode-line-format -@vindex gnus-category-mode-line-format -$BJ,N`%b!<%I9T$NMM<0(B (@pxref{Mode Line Formatting})$B!#(B - -@item gnus-agent-short-article -@vindex gnus-agent-short-article -$B$3$NJQ?t$h$j>/$J$$9T?t$N5-;v$OC;$$!#=i4|@_DjCM$O(B 100$B!#(B - -@item gnus-agent-long-article -@vindex gnus-agent-long-article -$B$3$NJQ?t$h$jB?$$9T?t$N5-;v$OD9$$!#=i4|@_DjCM$O(B 200$B!#(B - -@item gnus-agent-low-score -@vindex gnus-agent-low-score -$B$3$NCM$h$j>.$5$$%9%3%"$r;}$D5-;v$ODc%9%3%"$G$"$k!#=i4|@_DjCM$O(B 0$B!#(B - -@item gnus-agent-high-score -@vindex gnus-agent-high-score -$B$3$NCM$h$jBg$-$$%9%3%"$r;}$D5-;v$O9b%9%3%"$G$"$k!#=i4|@_DjCM$O(B 0$B!#(B - -@end table - - -@node Agent Commands -@subsection $B%(!<%8%'%s%HL?Na(B - -$BA4$F$N(B gnus $B%(!<%8%'%s%HL?Na$O(B @kbd{J} $B%5%V%^%C%W$K$"$j$^$9!#(B -@kbd{J j} (@code{gnus-agent-toggle-plugged}) $BL?Na$OA4$F$N%b!<%I(B -$B$GF0:n$7!"(Bgnus $B%(!<%8%'%s%H$N@Z$jN%$7(B/$B:9$79~$_>uBV$r@Z$jBX$($^$9!#(B - - -@menu -* Group Agent Commands:: -* Summary Agent Commands:: -* Server Agent Commands:: -@end menu - -$B40A4$J0l3gC5n$9$k(B -(@code{gnus-agent-unmark-article})$B!#(B - -@item @@ -@kindex @@ (Agent Summary) -@findex gnus-agent-toggle-mark -$B5-;v$r%@%&%s%m!<%I$9$k$+$I$&$+$r@Z$jBX$($k(B -(@code{gnus-agent-toggle-mark})$B!#(B - -@item J c -@kindex J c (Agent Summary) -@findex gnus-agent-catchup -$B%@%&%s%m!<%I0u$NL5$$5-;v$rA4$F4{FI$K$9$k(B -(@code{gnus-agent-catchup})$B!#(B - -@end table - - -@node Server Agent Commands -@subsubsection $B%5!<%P!<%(!<%8%'%s%HL?Na(B - -@table @kbd -@item J a -@kindex J a (Agent Server) -@findex gnus-agent-add-server -$B8=:_$N%5!<%P!<$r!"(Bgnus $B%(!<%8%'%s%H$G07$o$l$k%5!<%P!<$N0lMw$KDI(B -$B2C$9$k(B (@code{gnus-agent-add-server})$B!#(B - -@item J r -@kindex J r (Agent Server) -@findex gnus-agent-remove-server -$B8=:_$N%5!<%P!<$r!"(Bgnus $B%(!<%8%'%s%H$G07$o$l$k%5!<%P!<$N0lMw$+$i(B -$B:o=|$9$k(B (@code{gnus-agent-remove-server})$B!#(B - -@end table - - -@node Agent Expiry -@subsection $B%(!<%8%'%s%H4|8B@Z$l>C5n(B - -@vindex gnus-agent-expiry-days -@findex gnus-agent-expiry -@kindex M-x gnus-agent-expiry -@cindex Agent expiry -@cindex Gnus Agent expiry -@cindex expiry - -@code{nnagent} $B$O4|8B@Z$l>C5n$r07$$$^$;$s!#$=$NBe$o$j$K!"FCJL$J(B -@code{gnus-agent-expiry} $BL?Na$,(B @code{gnus-agent-expiry-days} $BF|(B -$B$h$j$b8E$$4{FI5-;v$rA4$F>C5n$7$^$9!#$3$l$O$"$J$?$,%G%#%9%/MFNL$r(B -$B;H$$@Z$j$=$&$@$H;W$C$?$H$-$K$$$D$G$b$G(B) $BCfCG$9$k$3$H$b$"$^$jNI$$$3$H$G$O$"$j$^$;$s!#(B - -@vindex gnus-agent-expire-all -@code{gnus-agent-expire-all} $B$,(B @code{nil} $B$G$J$1$l$P!"$3$NL?Na(B -$B$OA4$F$N5-;v(B --- $BL$FI!"4{FI!"2D;k!"J]N15-;v$r>C5n$7$^$9!#$b$7(B -@code{nil} ($B$3$l$,=i4|@_DjCM(B) $B$G$"$l$P!"4{FI5-;v$N$_$,>C5n$NBP>](B -$B$H$J$j!"L$FI!"2D;k!"J]N15-;v$O$5$i$KL54|8B$KJ];}$7$^$9!#(B - - -@node Outgoing Messages -@subsection $B:9=PMQ%a%C%;!<%8(B - -Gnus $B$,@Z$jN%$5$l$F$$$k$H$-!"A4$F$N:9=PMQ%a%C%;!<%8(B ($B%a!<%k$H%K%e!<(B -$B%9$NN>J}(B) $B$O2<=q$-%0%k!<%W(B (@pxref{Drafts}) $B$K3JG<$5$l$^$9!#Ej9F(B -$B$7$?8e$G$b!"$3$3$G$=$N%a%C%;!<%8$r8+$?$j!"JT=8$7$?$j$9$k$N$O0U$N(B -$B$^$^$G$9!#(B - -Gnus $B$,:F$S:9$79~$^$l$?$H$-!"%a%C%;!<%8$rAw?.$9$k$?$a$K!"FCJL$J(B -$BL?Na$r;H$C$F2<=q$-%0%k!<%W$+$iAw$k$3$H$b!"%0%k!<%W%P%C%U%!Fb$G(B -@kbd{J S} $B$r;H$C$F!"2<=q$-%0%k!<%WFb$NA4$F$NAw?.2DG=%a%C%;!<%8Aw(B -$B?.$9$k$3$H$b$G$-$^$9!#(B - -@node Agent Variables -@subsection $B%(!<%8%'%s%HJQ?t(B - -@table @code -@item gnus-agent-directory -@vindex gnus-agent-directory -Gnus $B%(!<%8%'%s%H$,%U%!%$%k$r3JG<$9$k>l=j!#=i4|@_DjCM$O(B -@file{~/News/agent/}$B!#(B - -@item gnus-agent-handle-level -@vindex gnus-agent-handle-level -$B$3$NJQ?t$NCM$h$j9b$$%l%Y%k(B (@pxref{Group Levels}) $B$N%0%k!<%W$O!"(B -$B%(!<%8%'%s%H$+$i$OL5;k$5$l$^$9!#=i4|@_DjCM$O(B -@code{gnus-level-subscribed} $B$G!"$3$l$O=i4|@_Dj$G$O!"9XFI$7$F$$(B -$B$k%0%k!<%W$N$_$,%(!<%8%'%s%H$N=hM}$NBP>]$H$J$k$H$$$&$3$H$G$9!#(B - -@item gnus-agent-plugged-hook -@vindex gnus-agent-plugged-hook -$B%M%C%H%o!<%/$K@\B3$5$l$?$H$-$K$K9g$o$;$FJT=8$7!"(B -PPP ($B$d2?$+(B) $B$r5/F0$7$F!"(B@kbd{M-x gnus} $B$HBG80$7$F$/$@$5$$!#(B - -$B$"$J$?$,=i$a$F(B gnus $B$ro$H$F$b;~4V$,$+$+$j$^$9$,!"0lEY$@$1$7$+C5n$7$^(B -$B$9!#(B(@kbd{A k} $B$G:o=|%0%k!<%W$OA4$FLa$C$F$-$^$9!#(B) - -$B$5$F!"$3$3$G$=$N>l$G%0%k!<%W$rFI$`$3$H$b$G$-$^$9$7!"$"$k$$$O(B -@kbd{J s} $BL?Na$G5-;v$r%@%&%s%m!<%I$9$k$3$H$b$G$-$^$9!#$"$H$O$3$N(B -$B%^%K%e%"%k$N;D$j$rFI$s$G!"$=$NB>$N2?I42/$N9`L\$+$i%+%9%?%^%$%:$7(B -$B$?$$$3$H$r8+$D$1=P$7$F$/$@$5$$!#(B - -@node Batching Agents -@subsection $B0l3g%(!<%8%'%s%H=hM}(B - -Gnus $B%(!<%8%'%s%H$K5-;v$ro$K4JC1$G$9!#0J2<$N%7%'%k%9%/%j%W%H$OI,MW$J$3$H$rA4$F$d$C$F$/(B -$B$l$k$G$7$g$&!#(B - -@example -#!/bin/sh -emacs -batch -l ~/.emacs -f gnus-agent-batch >/dev/null -@end example - - -@node Scoring -@chapter $B%9%3%"(B -@cindex scoring - -$BB>$N?M!9$O(B @dfn{$B:o=|%U%!%$%k(B} $B$r;H$$$^$9$,!"$3$3(B gnus $B%?%o!<$O:o=|$h$j$b(B -$B%9%3%"$NJ}$r9%$_$^$9$N$G!"B>$H3JF.$9$k$h$j$O@Z$jBX$($k;v$K$7$^$7$?!#$=$l(B -$B$i$O40A4$K0c$&;v$r$7$^$9$N$G!"??$CD>$0$K:B$C$FCm0U$rJ'$C$F$/$@$5$$!*(B - -@vindex gnus-summary-below -$BA4$F$N5-;v$O%9%3%"$N=i4|CM$r;}$C$F$*$j(B -(@code{gnus-summary-default-score})$B!"$3$l$O%G%#%U%)%k%H$G(B 0 $B$G$9!#$3$N%9(B -$B%3%"$OBPOCE*$d!"%9%3%"%U%!%$%k(B (score file) $B$NJ}K!$K$h$j!">e$2$i$l$?$j2<(B -$B$2$i$l$?$j$7$^$9!#(B@code{gnus-summary-bark-below} $B$h$j$bDc$$%9%3%"$N5-;v(B -$B$K$O4{FI$N0u$,IU$-$^$9!#(B - -Gnus $B$O35N,%P%C%U%!$r:n@.$9$kA0$K!"8=:_$N%0%k!<%W$KE,MQ$5$l$k$I$s$J(B -@dfn{$B%9%3%"%U%!%$%k(B} $B$bFI$_9~$_$^$9!#(B - -$B8=:_$N5-;v$K4p$E$$$F%9%3%"$NEPO?$rA^F~$9$k$$$/$D$+$NL?Na$,35N,%P%C%U%!$K(B -$B$"$j$^$9!#Nc$($P!"(Bgnus $B$KFCDj$NI=Bj$N5-;v$N%9%3%"$r2<$2$?$j>e$2$?$j$9$k(B -$B$h$&$K5a$a$k;v$,$G$-$^$9!#(B - -2$Be;H$o$l$F$$$J$$$I$s$J(B -$BEPO?$b!"%9%3%"%U%!%$%k$NBg$-$5$r>.$5$/$9$k$?$a$K!"@E$+$K:o=|$5$l$^$9!#(B - -@menu -* Summary Score Commands:: $B8=:_$N%0%k!<%W$N$?$a$N%9%3%"EPO?$rDI2C$9$k!#(B -* Group Score Commands:: $B0lHLE*$J%9%3%"L?Na!#(B -* Score Variables:: $B$"$J$?$N%9%3%"$r%+%9%?%^%$%:$9$k!#(B - ($B$^$!!"$J$s$FMQ8l$G$7$g$&(B)$B!#(B -* Score File Format:: $B%9%3%"%U%!%$%k$K2?$rF~$l$k$+!#(B -* Score File Editing:: $Bl9g$G$b!"=i4|@_Dj$G%0%k!<%W$N%m!<%+%k%9%3%"%U%!%$%k$K$J$C$F$$(B -$B$^$9!#%9%3%"L?Na$r2?$+B>$N%9%3%"%U%!%$%k(B ($BNc!"(B@file{all.SCORE}) $B$KA^F~$7(B -$B$?$$$J$i!"$^$:$3$N%9%3%"%U%!%$%k$r8=:_$N$b$N$K$7$J$1$l$P$J$j$^$;$s!#(B - -$B0lHLE*$J%9%3%"L?Na$Oo$K5,B'@5$7$$K!B'$K=>$$$^$9(B -$B$N$G!"$=$l$i$NL?NaA4$F$rI=$K>e$2$kI,MW$O$"$j$^$;$s!#(B($B$?!<$/$5$s$"$j$^$9!#(B) - -@findex gnus-summary-increase-score -@findex gnus-summary-lower-score - -@enumerate -@item -$B:G=i$N%-!<$O%9%3%"$rA}$d$9$?$a$N(B @kbd{I} (i $B$NBgJ8;z(B) $B$+!"%9%3%"$r2<$2$k(B -$B$?$a$N(B @kbd{L} $B$G$9!#(B -@item -2$BHVL\$N%-!<$O$I$N%X%C%@!<$K%9%3%"$r$7$?$$$+$rI=$7$^$9!#0J2<$N%-!<$,;HMQ(B -$B2DG=$G$9(B: -@table @kbd - -@item a -$BCxA0$K%9%3%"$rIU$1$^$9!#(B - -@item s -$BI=Bj(B (subject) $B$N9T$K%9%3%"$rIU$1$^$9!#(B - -@item x -Xref $B9T$K%9%3%"$rIU$1$^$9(B---$B$9$J$o$A!"Aj8_Ej9F9T$G$9!#(B - -@item r -References $B9T$K%9%3%"$r$D$1$^$9!#(B - -@item d -$BF|IU(B (date) $B$K%9%3%"$rIU$1$^$9!#(B - -@item l -$B9T?t(B (number of lines) $B$K%9%3%"$rIU$1$^$9!#(B - -@item i -Messsage-ID $B$K%9%3%"$rIU$1$^$9!#(B - -@item f -$B%U%)%m!<%"%C%W(B (followup) $B$K%9%3%"$rIU$1$^$9!#(B - -@item b -$BK\BN(B (body) $B$K%9%3%"$rIU$1$^$9!#(B - -@item h -$B%X%C%@!<(B (head) $B$K%9%3%"$rIU$1$^$9!#(B - -@item t -$B%9%l%C%I$K%9%3%"$rIU$1$^$9!#(B - -@end table - -@item -3$BHVL\$N%-!<$O9gCW$9$k7?$G$9!#$I$N9gCW$N7?$,M-8z$+$O$I$N%X%C%@!<$K%9%3%"(B -$B$rIU$1$h$&$H$7$F$$$k$+$K0M$j$^$9!#(B - -@table @code - -@item $BJ8;zNs(B (strings) - -@table @kbd - -@item e -$B@53N$J(B (exact) $B9gCW$G$9!#(B - -@item s -$BJ8;zNs$N0lIt$N(B (substring) $B9gCW$G$9!#(B - -@item f -$B$"$$$^$$$J(B (fuzzy) $B9gCW$G$9(B (@pxref{Fuzzy Matching})$B!#(B - -@item r -$B@55,I=8=(B (regexp) $B$N9gCW$G$9!#(B -@end table - -@item $BF|IU(B (date) -@table @kbd - -@item b -$BF|IU$NA0(B (before) $B$G$9!#(B - -@item a -$BF|IU$N8e(B (after) $B$G$9!#(B - -@item n -$B$=$NF|IU$G$9!#(B -@end table - -@item $B?t;z(B (number) -@table @kbd - -@item < -$B?t;z$h$j>.$5$$$b$N$G$9!#(B - -@item = -$B?t;z$HEy$7$$$b$N$G$9!#(B - -@item > -$B?t;z$h$jBg$-$$$b$N$G$9!#(B -@end table -@end table - -@item -4$B$D$a$G!":G8e$N%-!<$O$3$l$,0l;~E*(B ($B$9$J$o$A!"4|8B@Z$l>C5n(B) $B$N%9%3%"EPO?(B -$B$+!"1JB3E*$J(B ($B$9$J$o$A!"4|8B@Z$l>C5n$G$J$$(B) $B%9%3%"EPO?$G$"$k$+$H$$$&$3$H!"(B -$B$b$7$/$O$9$0$K$J$5$l$k$Y$-$+!"%9%3%"%U%!%$%k$KDI2C$9$k;v$O$7$J$$$+$H$$$&(B -$B;v$r;XDj$7$^$9!#(B -@table @kbd - -@item t -$B0l;~E*$J(B (temporary) $B%9%3%"EPO?$G$9!#(B - -@item p -$B1JB3E*$J(B (permanent) $B%9%3%"EPO?$G$9!#(B - -@item i -$BB(:B$N(B (immediate) $B%9%3%"IU$1$G$9!#(B -@end table - -@end enumerate - -$B$G$9$+$i!"8=:_$NCxo$K4JC1$G$9!#(B - -$BJ*;v$rJ#;($K$9$k$N$O!"C;=LBG80$,B8:_$9$k$+$i$G$9!#(B2$BHVL\$+(B3$BHVL\$NJ8;z$KBg(B -$BJ8;z$r;H$&$H!"(Bgnus $B$O;D$k(B1$B$D$+(B2$B$D$NBG80$K=i4|CM$r;H$$$^$9!#=i4|CM$O(B ``$BJ8(B -$B;zNs$N0lIt(B'' $B$H(B ``$B0l;~E*(B'' $B$G$9!#$G$9$+$i!"(B@kbd{I A} $B$O(B @kbd{I a s t} $B$H(B -$BF1$8$G!"(B@kbd{I a R} $B$O(B @kbd{I a r t} $B$HF1$8$G$9!#(B - -$B$3$l$i$N4X?t$O?t;z@\F,0z?t$H!"%7%s%\%k@\F,0z?t$re$2$k(B) $B$+$r;XDj$7$^$9!#%7%s%\%k@\F,0z?t(B @code{a} $B$OL?Na$,8=(B -$B:_$N%9%3%"%U%!%$%k$G$O$J$/%U%!%$%k(B @file{all.SCORE} $B$r;H$&;v$r;XDj$7$^$9!#(B - -@vindex gnus-score-mimic-keymap -@code{gnus-score-mimic-keymap} $B$O$3$l$i$NL?Na$,%-!<%^%C%W$G$"$k$+$N$h$&(B -$B$K?6$kIq$&$+$I$&$+$r;XDj$7$^$9!#(B - - -@node Group Score Commands -@section $B%0%k!<%W%9%3%"L?Na(B -@cindex group score commands - -$B;DG0$J$,$i!"$^$@$?$/$5$s$O$"$j$^$;$s!#(B - -@table @kbd - -@item W f -@kindex W f ($B%0%k!<%W(B) -@findex gnus-score-flush-cache -Gnus $B$O2?EY$b%9%3%"O"A[%j%9%H$rFI$_9~$`$N$rHr$1$k$?$a$K!"$=$l$N%-%c%C%7%e(B -$B$rJ];}$7$F$$$^$9!#$3$NL?Na$O%-%c%C%7%e$r=q$-=P$7$^$9(B -(@code{gnus-score-flush-cache})$B!#(B - -@end table - -$B0J2<$N$h$&$J;v$r$9$k;v$K$h$C$F!"%3%^%s%I9T$+$i%9%3%"IU$1$r$9$k;v$,$G(B -$B$-$^$9!#(B - -@findex gnus-batch-score -@cindex batch scoring -@example -& emacs -batch -l ~/.emacs -l gnus -f gnus-batch-score -@end example - - -@node Score Variables -@section $B%9%3%"JQ?t(B -@cindex score variables - -@table @code - -@item gnus-use-scoring -@vindex gnus-use-scoring -@code{nil} $B$G$"$l$P!"(Bgnus $B$O%9%3%"%U%!%$%k$rD4$Y$:!"0lHLE*$K!"%9%3%"4XO"(B -$B$N;E;v$rA4$/$7$^$;$s!#$3$l$O=i4|@_Dj$G(B @code{t} $B$G$9!#(B - -@item gnus-kill-killed -@vindex gnus-kill-killed -$B$3$NJQ?t$,(B @code{nil} $B$G$"$l$P!"(Bgnus $B$O4{$K:o=|2aDx$r$K2C$($k@\Hx8l$G$9(B ($B=i4|CM$G(B -@samp{SCORE} $B$G$9!#(B) - -@item gnus-score-uncacheable-files -@vindex gnus-score-uncacheable-files -@cindex score cache -$BA4$F$N%9%3%"%U%!%$%k$OIaDL$O%9%3%"%U%!%$%k$N2a>jFI$_9~$_$rHr$1$k$?$a$K(B -$B%-%c%C%7%e$5$l$^$9!#$7$+$7!"$3$l$K$h$j$"$J$?$N(B Emacs $B$,Bg$-$/HnBg2=$9$k(B -$B$N$G$"$l$P!":F$SI,MW$H$5$l$J$$$h$&$J%9%3%"%U%!%$%k$r=|5n$9$k$?$a$K$3$N@5(B -$B5,I=8=$r;H$&;v$,$G$-$^$9!#(B@file{all.SCORE} $B$N%-%c%C%7%e$r;_$a$k$N$O0-$$(B -$B9M$($G$9$,!"(B@file{comp.infosystems.www.authoring.misc.ADAPT} $B$r%-%c%C%7%e(B -$B$7$J$$$N$ONI$$9M$($G$7$g$&!#e$2(B/$B2<$2L?Na$K$h$C$F;H$o$l$k>e$2(B/$B2<$2$9$k%9%3%"$G$9!#(B -$B%G%#%U%)%k%H$O(B1000$B$G!"2a>j$@$H;W$&$+$b$7$l$^$;$s$,!"$3$l$OE,1~%9%3%"IU$1(B -$B$r$9$kM>CO$NB8:_$9$k;v$r3N.$5$JJQ99$G>e=q$-$5$l$?$/$O$"$j$^$;$s!#(B - -@item gnus-summary-default-score -@vindex gnus-summary-default-score -$B5-;v$N%9%3%"$N=i4|CM$G!"=i4|@_Dj$G$O(B0$B$K$J$C$F$$$^$9!#(B - -@item gnus-summary-expunge-below -@vindex gnus-summary-expunge-below -$B$3$NJQ?t$h$jDc$$%9%3%"$r;}$D5-;v$O35N,$N9T$KI=<($5$l$^$;$s!#$3$l$O=i4|@_(B -$BDj$G(B @code{nil} $B$G!"$3$l$O$I$N5-;v$b1#$5$l$J$$$H$$$&;v$G$9!#$3$NJQ?t$O3F(B -$B35N,%P%C%U%!$K8GM-$G!"(B@code{gnus-summary-mode-hook} $B$K$h$C$F@_Dj$5$l$k$Y(B -$B$-$G$9!#(B - -@item gnus-score-over-mark -@vindex gnus-score-over-mark -$B=i4|@_Dj$N%9%3%"$h$jBg$-$J%9%3%"$r;}$D5-;v$KBP$7$F(B (3$B7eL\$K(B) $B;H$o$l$k0u(B -$B$G$9!#=i4|@_Dj$O(B @samp{+} $B$G$9!#(B - -@item gnus-score-below-mark -@vindex gnus-score-below-mark -$B=i4|@_Dj$N%9%3%"$h$j>.$5$J%9%3%"$r;}$D5-;v$KBP$7$F(B (3$B7eL\$K(B) $B;H$o$l$k0u(B -$B$G$9!#=i4|@_Dj$O(B @samp{-} $B$G$9!#(B - -@item gnus-score-find-score-files-function -@vindex gnus-score-find-score-files-function -$B8=:_$N%0%k!<%W$N%9%3%"%U%!%$%k$r8+$D$1$k$?$a$K;H$o$l$k4X?t$G$9!#$3$N4X?t(B -$B$O%0%k!<%WL>$r0z?t$H$7$F8F$P$l$^$9!#(B - -$B;HMQ2DG=$J4{Dj4X?t$O(B: -@table @code - -@item gnus-score-find-single -@findex gnus-score-find-single -$B%0%k!<%W<+?H$N%9%3%"%U%!%$%k$@$1$rE,MQ$7$^$9!#(B - -@item gnus-score-find-bnews -@findex gnus-score-find-bnews -bnews $B9=J8$r;H$C$F!"A4$F$N9gCW$9$k%9%3%"%U%!%$%k$rE,MQ$7$^$9!#$3$l$,=i4|(B -$B@_Dj$G$9!#Nc$($P!"8=:_$N%0%k!<%W$,(B @samp{gnu.emacs.gnus} $B$J$i$P!"(B -@file{gnu.all.SCORE}$B!"(B@file{not.alt.SCORE} $B$H(B @file{gnu.all.SCORE} $B$,$9(B -$B$Y$FE,MQ$5$l$^$9!#MW$9$k$K!"%9%3%"%U%!%$%kL>$N(B @samp{all} $B$,(B @samp{.*} -$B$KJQ49$5$l!"$=$l$+$i@55,I=8=$N9gCW$,$J$5$l$^$9!#(B - -$B$3$l$O!"A4$F$N%0%k!<%W$KE,MQ$7$?$$%9%3%"EPO?$,$$$/$D$+$"$k>l9g$O!"$=$l$i(B -$B$NEPO?$r(B @file{all.SCORE} $B%U%!%$%k$KF~$l$k$H$$$&$3$H$G$9!#(B - -Gnus $B$O0lHLE*$J%9%3%"%U%!%$%k$rFCDj$N%9%3%"%U%!%$%k8~$1$N$b$N$h$jA0$KE,(B -$BMQ$7$h$&$H;n$_$^$9$,!"%9%3%"%U%!%$%k$O$[$H$s$IL5:n0Y$N=gHV$GE,MQ$5$l$^$9!#(B -$B$3$l$O%9%3%"%U%!%$%kL>$NMWAG$N?t$rD4$Y$k;v$K$h$C$F$J$5$l$^$9(B--- -@samp{all} $BMWAG$rl9g$O!"$3$l$i$NA4$F$N4X?t(B -$B$,8F$P$l!"%9%3%"%U%!%$%k$NJV$5$l$?A4$F$N%j%9%H$,E,MQ$5$l$^$9!#$3$l$i$N4X(B -$B?t$OD>@\%9%3%"O"A[%j%9%H$N%j%9%H$rJV$9;v$b$G$-$^$9!#$=$N>l9g$O!"$=$l$i$N(B -$B%U%!%$%k$G$J$$%9%3%"O"A[%j%9%H$rJV$94X?t$O!"JV$5$l$k:G8e$N%9%3%"%U%!%$%k(B -$B$,%m!<%+%k%9%3%"%U%!%$%k$G$"$k;v$r3NC5n$rA`:n$7$F$$$kJ}K!$G$9(B---$BA4$F$N9gCW$7$J$$EPO?(B -$B$O8E$/$J$j$9$.!"9gCW$9$kEPO?$r?7A/$G(B -$BLL$9$k;v$K$J$k$G$7$g$&!#(B - -@item gnus-score-after-write-file-function -@vindex gnus-score-after-write-file-function -$B$=$3$G$A$g$&$I=q$+$l$?%9%3%"%U%!%$%k$NL>A0$H6&$K8F$P$l$k4X?t$G$9!#(B - -@item gnus-score-thread-simplify -@vindex gnus-score-thread-simplify -$B$3$NJQ?t$,(B @code{nil} $B$G$J$$$H!"5-;vI=Bj$O%9%l%C%I$HF1$8J}K!$GI=Bj%9%3%"(B -$B$N$?$a$KC1=c2=$5$l$^$9(B---$B8=:_$N(B gnus-simplify-subject-functions $B$NCM$K$h$C(B -$B$F!#%9%3%"EPO?$,(B @code{$BJ8;zNsItJ,(B} $B$+(B @code{$B@53N$J(B} $B9gCW$r;H$C$F$$$k$H!"(B -$B9gCW$b$3$NJ}K!$GC1=c2=$5$l$^$9!#(B - -@end table - - -@node Score File Format -@section $B%9%3%"%U%!%$%kMM<0(B -@cindex score file format - -$B%9%3%"%U%!%$%k$OIaDL$OC1=c$JMM<0$N$b$N$@$1$r4^$`(B @code{emacs-lisp} $B%U%!(B -$B%$%k$G$9!#L5F\Ce$JMxMQ2A(B} (eval) $B$5$l$^$;$s!#$7$+$7!"(Blisp $B%j!<%@!<$,$3$NMM<0$rFI$_9~$`(B -$B$N$K;H$o$l$^$9$N$G!"0UL#E*$KM-8z$G$J$$$H$7$F$b!"J8K!E*$K$OM-8z$G$9!#(B - -$B$3$NO"A[%j%9%H$G$O(B6$B$D$N%-!<$r;H$&;v$,$G$-$^$9!#(B - -@table @code - -@item $BJ8;zNs(B (STRING) -$B$b$7%-!<$,J8;zNs$G$"$k$H!"$=$l$O9gCW$,A0$G$9!#%9%3(B -$B%"$O$3$l$i$N(B8$B$D$N%X%C%@!<$@$1$K$l$N%9%3%"EPO?$O(B1$B$D$+$i(B4 -$B$D$^$G$NMWAG$r;}$A$^$9!#(B -@enumerate - -@item -$B:G=i$NMWAG$O(B @dfn{$B9gCWMWAG(B} $B$G$9!#$?$$$F$$$N%X%C%@!<$G$O$3$l$OJ8;zNs$G$9(B -$B$,!"(BLines $B$H(B Chars $B%X%C%@!<$G$O$3$l$O@0?t$G$J$1$l$P$J$j$^$;$s!#(B - -@item -$B$b$7(B2$BHVL\$NMWAG$,B8:_$9$k$J$i!"$=$l$O?t;z$G$"$k$Y$-$G$9(B---@dfn{$B%9%3%"MW(B -$BAG(B}$B!#$3$N?t;z$OIi$NL58BBg$+$i@5$NL58BBg$^$G$N4V$N@0?t$G$"$k$Y$-$G$9!#$b(B -$B$79gCW$,@.8y$9$l$P!"$3$N?t;z$,5-;v$N%9%3%"$K2C$($i$l$^$9!#$b$7$3$NMWAG$,(B -$BB8:_$7$F$$$J$1$l$P!"?t;z(B @code{gnus-score-interactive-default-score} $B$,(B -$BBe$o$j$K;H$o$l$^$9!#$3$l$O=i4|@_Dj$G(B1000$B$G$9!#(B - -@item -$B$b$7(B3$BHVL\$NMWAG$,B8:_$7$F$$$k$H!"$=$l$O?t;z$G$"$k$Y$-$G$9(B---@dfn{$BF|IUMW(B -$BAG(B} $B$G$9!#$3$NF|IU$O:G8e$K$3$N%9%3%"EPO?$,9gCW$7$?;~9o$r<($7!"$3$l$O%9%3(B -$B%"EPO?$N4|8B@Z$l>C5n5!9=$N5!G=$N$?$a$K;H$o$l$^$9!#$3$NMWAG$,B8:_$7$F$$$J(B -$B$1$l$P!"%9%3%"EPO?$O1JB3$7$^$9!#F|IU$O5*85A0(B1$BG/(B12$B7n(B31$BF|$+$i7P2a$7$?F|$K(B -$B$A$N?t$GI=$5$l$^$9!#(B - -@item -$B$b$7(B4$BHVL\$NMWAG$,B8:_$7$F$$$k$H!"$=$l$O%7%s%\%k$G$"$k$Y$-$G$9(B---@dfn{$B7?(B -$BMWAG(B} $B$G$9!#$3$NMWAG$O$3$N%9%3%"EPO?$,5-;v$K9gCW$9$k$+$I$&$+$rD4$Y$k$N$K(B -$B$I$N4X?t$,;H$o$l$k$Y$-$G$"$k$+$r;XDj$7$^$9!#(B - -@table @dfn - -@item From, Subject, References, Xref, Message-ID -$B$?$$$F$$$N%X%C%@!<$N7?$KBP$7$F!"(B@code{r} $B$H(B @code{R} ($B@55,I=8=(B) (regexp) -$B$d!"(B@code{s} $B$H(B @code{S} ($BJ8;zNs$N0lIt(B) (substring) $B7?!"(B@code{e} $B$H(B -@code{E} ($B@53N$J9gCW(B) (exact match)$B!"(B@code{w} ($B8l$N9gCW(B) (word match) $B7?(B -$B$,B8:_$7$^$9!#$b$7$3$NMWAG$,B8:_$7$J$$$H!"(Bgnus $B$OJ8;zNs$N0lIt$N9gCW$,MQ(B -$B$$$i$l$k$Y$-$G$"$k$H$_$J$7$^$9!#(B@code{R}$B!"(B@code{S}$B!"(B@code{E} $B$O9gCW$,BgJ8(B -$B;z$H>.J8;z$r6hJL$9$kJ}K!$G9T$o$l$k$H$$$&E@$GB>$N$b$N$H0[$J$j$^$9!#A4$F$N(B -$B$3$l$i$N0lJ8;z7?$OK\Ev$O(B @code{regexp}$B!"(B@code{exact}$B!"(B@code{word} $B7?$NC;(B -$B=L7A$G!"$b$7$=$&$7$?$$$H;W$($P$3$A$i$rBe$o$j$K;H$&;v$,$G$-$^$9!#(B - -@item Lines, Chars -$B$3$l$i$N(B2$B$D$N%X%C%@!<$O0c$C$?9gCW$N7?$r;H$$$^$9(B: @code{<}$B!"(B@code{>}$B!"(B -@code{=}$B!"(B@code{>=}$B!"(B@code{<=} $B$G$9!#(B - -$B$3$l$i$N=R8l$O$b$7(B - -@example -(PREDICATE HEADER MATCH) -@end example - -$B$NI>2A$,(B @code{nil} $B$G$J$$$H!"??$H$J$j$^$9!#Nc$($P!">e5i9gCW(B -@code{("lines" 4 <)} (@pxref{Advanced Scoring}) $B$O7k2L$H$7$F0J2<$N<0$K$J(B -$B$j$^$9!#(B - -@lisp -(< header-value 4) -@end lisp - -$B$b$7$/$OB>$NJ}K!$K$7$^$7$g$&(B: @code{<} $B$r(B @code{Lines} $B$G(B 4 $B$r9gCW$H$7$F(B -$B;H$C$F$$$k$H$-$O!"5-;v$,(B4$B9T$h$j$b>/$J$$$H$-$K%9%3%"$,DI2C$5$l$^$9!#(B($B:.Mp(B -$B$7$F!"H?BP$G$O$J$$$+$H9M$(0W$$$G$9!#$G$b!"$=$&$G$O$J$$$N$G$9!#;d$,;W$&$K!#(B) - -$B9gCW$,(B @code{Lines} $B$G$J$5$l$F$$$k$H!"$$$/$D$+$N%P%C%/%(%s%I(B -(@code{nndir}$B$N$h$&$J$b$N(B) $B$O(B @code{Lines} $B%X%C%@!<$r:n@.$7$J$$$?$a$KA4(B -$B$F$N5-;v$,(B 0 $B9T$G$"$k$H$7$F07$o$l$k;v$K5$$rIU$1$F$/$@$5$$!#$3$l$O$b$7>/(B -$B$7$N9T$7$+$J$$5-;v$N%9%3%"$r2<$2$F$$$k$N$J$i!"JQ$J7k2L$,5/$3$jF@$k;v$K$J(B -$B$j$^$9!#(B - -@item Date -Date ($BF|IU(B) $B%X%C%@!<$K$O(B3$B$D$N$J$s$H$J$/$P$+$2$F$$$k9gCW$N7?$,$"$j$^$9(B: -@code{before}$B!"(B@code{at}$B!"(B@code{after} $B$G$9!#;d$OK\Ev$K$3$l$,LrN)$D$h$&(B -$B$J5!2q$rA[A|$G$-$J$$$N$G$9$,!"$3$N4X?t$rDs6!$7$J$$$N$b$J$s$H$J$/$P$+$2$F(B -$B$$$^$9!#$=$&$7$?>l9g$N$?$a$K$"$k$N$G$9!#$$$DI,MW$K$J$k$+$OC/$K$b$o$+$j$^(B -$B$;$s!#E>$P$L@h$N>s$G$9!#0lEY>F$1$k$H(B2$BEYCQ$:$+$7$$!"$G$9!#K\$r%+%P!<$GH=(B -$BCG$7$F$O9T$1$^$;$s!#:G=i$NF|$K@-9T0Y$r9T$C$F$$$O9T$1$^$;$s!#(B ($B$7$+$7!";d(B -$B$O>/$J$/$H$b0l?M!"0zMQ$7$^$9$,!"(B``$B$3$N4X?t$O7g$+$;$J$$$b$N$G$"$k;v$,$o$+$C(B -$B$?(B'' $B$H8@$C$??M$,F~$k$HJ9$$$F$$$^$9!#(B) - -@cindex ISO8601 -@cindex date -$B$b$C$HLrN)$D9gCW$N7?$O(B @code{$B@55,I=8=(B} $B$G$9!#$=$l$K$h$C$FF|IUJ8;zNs$K@5(B -$B5,I=8=$rMQ$$$F9gCW$5$;$k;v$,$G$-$^$9!#F|IU$O$^$:(B ISO8601 $BC;=LMM<0(B -(compact format) $B$KI8=`2=$5$l$^$9(B---@var{YYYYMMDD}@code{T}@var{HHMMSS} -$B$G$9!#Nc$($P!"$b$7A4$F$NG/$N(B4$B7n(B1$BF|$KEj9F$5$l$?A4$F$N5-;v$K$,<#$5$;$?$$$N(B -$B$G$"$l$P!"(B@samp{....0401.........} $B$r9gCWJ8;zNs$H$7$F;H$&;v$,$G$-$^$9!#(B -($BF|IU$O85!9$NI8=`;~$GJ]B8$5$l$F$$$^$9$N$G!"$=$N5-;v$,Ej9F$5$l$?$H$3$m$G(B4 -$B7n(B1$BF|$KEj9F$5$l$?5-;v$K9gCW$9$k;v$KCm0U$7$F$/$@$5$$!#I8=`;~$O0l2H$K$H$C(B -$B$FHs>o$KM-1W$J3Z$7$_$G$7$g$&!)(B) - -@item Head, Body All -$B$3$l$i$N(B3$B$D$N9gCW$N%-!<$O(B @code{From} $B%X%C%@!<(B ($B$J$I(B) $B$HF1$89gCW$N7?$r;H(B -$B$$$^$9!#(B - -@item Followup -$B$3$N9gCW$N%-!<$O>/$7FCJL$G!"$=$l$O(B @code{From} $B%X%C%@!<$K9gCW$7!"9gCW$7(B -$B$?5-;v$@$1$G$J$/$=$N5-;v$X$NA4$F$N%U%)%m!<%"%C%W$N%9%3%"$K$b1F6A$7$^$9!#(B -$B$3$l$O$?$H$($P!"$"$J$?<+?H$N5-;v$X$N%U%)%m!<%"%C%W$N%9%3%"$rA}$d$7$?$j!"(B -$BNI$/CN$i$l$?LdBj;y$X$N%U%)%m!<%"%C%W5-;v$N%9%3%"$r2<$2$?$j$9$k$N$K;H$o$l(B -$B$^$9!#(B@code{From} $B%X%C%@!<$,;H$&$N$HF1$87?$N9gCW$r;H$$$^$9!#(B ($B$3$N9gCW%-!<(B -$B$r;H$&$H!"%U%!%$%k(B @file{ADAPT} $B$r:n$k;v$K$J$j$^$9!#(B) - -@item Thread -$B$3$N9gCW%-!<$O(B @code{Followup} $B9gCW%-!<$HF1$89T$KF0:n$7$^$9!#(B -@code{Message-ID} @var{X} $B$G;O$^$C$F$$$k(B ($BI{(B)$B%9%l%C%I$K%9%3%"$rIU$1$?$$(B -$B$N$G$"$l$P!"(B@samp{thread} $B9gCW$rIU$12C$($^$9!#$3$l$O(B @code{Reference} $B%X%C(B -$B%@!<$K(B @var{X} $B$r;}$D$=$l$>$l$N5-;v$K?7$7$$(B @samp{thread} $B9gCW$rDI2C$7$^(B -$B$9!#(B ($B$3$l$i$N?7$7$$(B @samp{thread} $B9gCW$O$3$l$i$N9gCW$9$k5-;v$N(B -@code{Message-ID} $B$r;H$$$^$9!#(B) $B$3$l$O%9%l%C%I$N$$$/$D$+$N5-;v$,40A4$J(B -@code{References} $B%X%C%@!<$r;}$C$F$$$J$+$C$?$H$7$F$b!"%9%l%C%IA4BN$N%9%3(B -$B%"$r>e$2(B/$B2<$2$G$-$k;v$rJ]>Z$7$^$9!#$3$l$r;H$&$H!"%9%l%C%I$N5-;v$K7hDjE*(B -$B$G$J$$%9%3%"$,IU$/$+$b$7$l$J$$$H$$$&$3$H$KCm0U$7$F$/$@$5$$!#(B ($B$3$N9gCW%-!<(B -$B$r;H$&$H!"%U%!%$%k(B @file{ADAPT} $B$r:n$k;v$K$J$j$^$9!#(B) -@end table -@end enumerate - -@cindex Score File Atoms -@item mark -$B$3$NEPO?$NCM$O?t;z$G$"$k$Y$-$G$9!#$3$N?t;z$h$jDc$$%9%3%"$N5-;v$K$O4{FI$N(B -$B0u$,IU$-$^$9!#(B - -@item expunge -$B$3$NEPO?$NCM$O?t;z$G$"$k$Y$-$G$9!#$3$N?t;z$h$jDc$$%9%3%"$N5-;v$O35N,%P%C(B -$B%U%!$+$i:o=|$5$l$^$9!#(B - -@item mark-and-expunge -$B$3$NEPO?$NCM$O?t;z$G$"$k$Y$-$G$9!#$3$N?t;z$h$jDc$$%9%3%"$N5-;v$K$O4{FI$N(B -$B0u$,IU$-!"35N,%P%C%U%!$+$i:o=|$5$l$^$9!#(B - -@item thread-mark-and-expunge -$B$3$NEPO?$NCM$O?t;z$G$"$k$Y$-$G$9!#%9%3%"$NAm7W$,$3$N?t;z$h$jDc$$%9%l%C%I(B -$B$K$O4{FI$N0u$,IU$-!"35N,%P%C%U%!$+$i:o=|$5$l$^$9!#(B -@code{gnus-thread-score-function} $B$O%9%l%C%I$N%9%3%"$NAm7W$r$I$N$h$&$K7W(B -$B;;$9$k$+$r;XDj$7$^$9!#(B - -@item files -$B$3$NEPO?$NCM$OG$0U$N?t$N%U%!%$%kL>$G$"$k$Y$-$G$9!#$3$l$i$N%U%!%$%k$b%9%3(B -$B%"%U%!%$%k$G$"$k$H$_$J$5$l!"$3$l$,$5$l$?$N$HF1$8$h$&$JJ}K!$GFI$_9~$^$l$^(B -$B$9!#(B - -@item exclude-files -$B$3$NEPO?$N$G$"$k$Y$-$G$9!#$3$l$i$N%U%!%$%k$O2?(B -$B$i$+$NM}M3$GIaDL$OFI$_9~$^$l$k$h$&$K$J$C$F$$$?$H$7$F$b!"FI$_9~$^$l$^$;$s!#(B - -@item eval -$B$3$NEPO?$NCM$O(B @code{$BI>2A(B} $B$5$l$^$9!#$3$NMWAG$OA4BNE*%9%3%"%U%!%$%k$r07$C(B -$B$F$$$k$H$-$OL5;k$5$l$^$9!#(B - -@item read-only -$BFI$_9~$_@lMQ%9%3%"%U%!%$%k$O99?7$5$l$?$jJ]B8$5$l$?$j$7$^$;$s!#A4BNE*%9%3(B -$B%"%U%!%$%k$O$3$N%"%H%`$r;HMQ$9$k$Y$-$G$9(B (@pxref{Global Score Files})$B!#(B -($BCm0U(B: @dfn{$BA4BNE*(B} $B$O$3$3$G$OK\Ev$K(B @dfn{$BA4BNE*(B} $B$H$$$&0UL#$G$9!#8D?ME*(B -$B$JA4$F$N%0%k!<%W$KE,MQ$9$k%9%3%"%U%!%$%k$N;v$G$O$"$j$^$;$s!#(B) - -@item orphan -$B$3$NEPO?$NCM$O?t;z$G$"$k$Y$-$G$9!#?F5-;v$r;}$?$J$$5-;v$O%9%3%"$K$3$N?t;z(B -$B$,2C$($i$l$^$9!#(B@samp{comp.lang.c} $B$N$h$&$JNL$NB?$$%K%e!<%9%0%k!<%W$rDI(B -$B$$$+$1$F$$$k$H$7$F$/$@$5$$!#$*$=$i$/(B2,3$B$N%9%l%C%I$H?7$7$$%9%l%C%I$@$1$r(B -$BDI$$$?$$$G$7$g$&!#(B - -$B0J2<$N(B2$B$D$N%9%3%"%U%!%$%kEPO?$K$h$C$F$=$l$r$9$k;v$,$G$-$^$9(B: - -@example - (orphan -500) - (mark-and-expunge -100) -@end example - -$B:G=i$K$3$N%0%k!<%W$KF~$C$?$H$-$O!"?7$7$$%9%l%C%I$@$1$r8+$^$9!#$=$l$+$i$*(B -$B$b$7$m$$$H;W$C$?%9%l%C%I$N%9%3%"$r>e$2(B (@kbd{I T} $B$b$7$/$O(B @kbd{I S} $B$K(B -$B$h$C$F(B)$B!";D$j$rL5;k(B (@kbd{C y}) $B$7$^$9!#/$7B8:_$7$9$kNL$NB?$$%0%k!<%W$N$?$a$K$"$j$^$9!#(B - -@item adapt -$B$3$NEPO?$OE,1~%9%3%"$r@)8f$7$^$9!#$b$7$3$l$,(B @code{t} $B$G$"$k$H!"=i4|@_Dj(B -$B$NE,1~%9%3%"K!B'$,;H$o$l$^$9!#$b$7$3$l$,(B @code{ignore} $B$G$"$k$H!"$3$N%0(B -$B%k!<%W$K$OE,1~%9%3%"$O$N$b$N$G$"$l$P!"=i4|@_Dj$NE,1~%9%3%"K!B'$,;H$o$l$^(B -$B$9!#$?$$$F$$$N%0%k!<%W$KE,1~%9%3%"$r;H$$$?$$$N$G$"$l$P!"(B -@code{gnus-use-adaptive-scorint} $B$r(B @code{t} $B$K@_Dj$7!"(B@code{(adapt -ignore)} $B$rE,1~%9%3%"$r$7$?$/$J$$%0%k!<%W$KA^F~$9$k$G$7$g$&!#>/$7$N%0%k!<(B -$B%W$G$@$1E,1~%9%3%"$r9T$$$?$$$N$G$"$l$P!"(B@code{gnus-use-adaptive-scoring} -$B$r(B @code{nil} $B$K@_Dj$7!"(B@code{(adaptive t)} $B$r$=$l$r9T$$$?$$%0%k!<%W$N%9(B -$B%3%"%U%!%$%k$KA^F~$9$k$G$7$g$&!#(B - -@item adaptive-file -$BA4$F$NE,1~%9%3%"EPO?$O$3$NEPO?$K$h$C$FL>$E$1$i$l$?%U%!%$%k$KF~$j$^$9!#$=(B -$B$l$O%0%k!<%W$KF~$k$H$-$K$bE,MQ$5$l$^$9!#$3$N%"%H%`$OB?$/$N%0%k!<%W$KF1$8(B -$BE,1~%9%3%"%U%!%$%k$rMQ$$$k;v$K$h$C$F!"J#?t$N%0%k!<%W$K0lEY$KE,1~%9%3%"$r(B -$BIU$1$?$$$H$-$KJXMx$G$7$g$&!#(B - -@item local -@cindex local variables -$B$3$NEPO?$NCM$O(B @code{(VAR VALUE)} $BBP$N%j%9%H$G$"$k$Y$-$G$9!#$=$l$>$l$N(B -@var{var} $B$O8=:_$N35N,%P%C%U%!$N%P%C%U%!8GM-$K$J$j!";XDj$5$l$?CM(B (value) -$B$K@_Dj$5$l$^$9!#$3$l$OJXMx$J!"$b$7>/$7JQ$@$H$7$F$b!"%U%C%/$r$"$^$j9%$^$J(B -$B$$$$$/$D$+$N%0%k!<%W$GJQ?t$r@_Dj$9$kJ}K!$G$9!#(B@var{value} $B$OI>2A$5$l$J$$(B -$B;v$KCm0U$7$F$/$@$5$$!#(B -@end table - - -@node Score File Editing -@section $B%9%3%"%U%!%$%kJT=8(B - -$BIaDL$OA4$F$N%9%3%"L?Na$r35N,%P%C%U%!$+$iH/9T$7$^$9$,!"/$7%+%9%?%^%$%:$5$l$?(B @code{emacs-lisp} $B%b!<%I$G!"0J2<$NDI(B -$B2C$NL?Na$,B8:_$7$^$9(B: - -@table @kbd - -@item C-c C-c -@kindex C-c C-c ($B%9%3%"(B) -@findex gnus-score-edit-done -$B$"$J$?$,9T$C$?JQ99$rJ]B8$7$F35N,%P%C%U%!$KLa$j$^$9(B -(@code{gnus-score-edit-done})$B!#(B - -@item C-c C-d -@kindex C-c C-d ($B%9%3%"(B) -@findex gnus-score-edit-insert-date -$B8=:_$NF|IU$r?t;zMM<0$GA^F~$7$^$9(B (@code{gnus-score-edit-insert-date})$B!#(B -$B$b$7$3$l$,$I$N$h$&$J$b$N$G$"$m$&$H9M$($F$$$k$N$G$"$l$P!"$3$l$OK\Ev$KF|$N(B -$B?t;z$G$9!#(B - -@item C-c C-p -@kindex C-c C-p ($B%9%3%"(B) -@findex gnus-score-pretty-print -$BE,1~%9%3%"%U%!%$%k$O@0$($i$l$F$$$J$$N.57$GJ]B8$5$l$^$9!#$b$7$3$l$i$N%U%!(B -$B%$%k$NFb$N0l$D$rFI$_$?$$$H;W$C$F$$$k$N$G$"$l$P!"$^$:(B @dfn{$BAGE($JI=<((B} $B$r(B -$B$7$?$$$G$7$g$&!#$3$NL?Na(B (@code{gnus-score-pretty-print}) $B$,$"$J$?$N$?$a(B -$B$K$=$l$r$7$^$9!#(B - -@end table - -$B$3$N%b!<%I$r;H$&$?$a$K$O(B @kbd{M-x gnus-score-mode} $B$HBG$C$F$/$@$5$$!#(B - -@vindex gnus-score-mode-hook -@code{gnus-score-menu-hook} $B$,%9%3%"%b!<%I%P%C%U%!$GJ}$NE,1~J}K!$r;H$$$?$1$l$P!"$3$NJQ?t$r(B@code{(word -line)} $B$K@_Dj$7$F$/$@$5$$!#(B - -@vindex gnus-default-adaptive-score-alist -@code{gnus-default-adaptive-score-alist} $BJQ?t$r%+%9%?%^%$%:$9$k(B -$B$3$H$G!"%9%3%"IU$1$N=hM}$r40A4$K@)8f$G$-$^$9!#Nc$($P!"$3$N$h$&$J(B -$B46$8$K$J$j$^$9!#(B - -@lisp -(defvar gnus-default-adaptive-score-alist - '((gnus-unread-mark) - (gnus-ticked-mark (from 4)) - (gnus-dormant-mark (from 5)) - (gnus-del-mark (from -4) (subject -1)) - (gnus-read-mark (from 4) (subject 2)) - (gnus-expirable-mark (from -1) (subject -1)) - (gnus-killed-mark (from -1) (subject -3)) - (gnus-kill-file-mark) - (gnus-ancient-mark) - (gnus-low-score-mark) - (gnus-catchup-mark (from -1) (subject -1)))) -@end lisp - -$B8+$F$*J,$+$j$N$h$&$K!"$3$NO"A[%j%9%H$N3FMWAG$O!"%-!<$H$7$F0u(B ($BJQ(B -$B?tL>$+$b$7$/$O(B ``$BK\Ev$N(B'' $B0u(B --- $B$D$^$jJ8;z(B)$B$r;}$A$^$9!#$3$N%-!<(B -$B$N8e$K$OG$0U$N?t$N%X%C%@!<(B/$B%9%3%"$NAH$,B3$-$^$9!#$b$7$=$N%-!<$N(B -$B8e$K%X%C%@!<(B/$B%9%3%"$NAH$,0l$D$b$J$1$l$P!"$=$N%-!<$,5-;v$N0u$H$7(B -$B$F$D$$$F$$$k5-;v$KBP$7$F$OE,1~@-%9%3%"$Oe(B -$B5-$NNc$G$O!"(B@code{gnus-unread-mark} $B$,$D$$$F$$$k5-;v$OE,1~@-%9%3(B -$B%"$NEPO?9`L\$K$O$J$j$^$;$s!#(B - -$B3F5-;v$O$?$@0l$D$N0u$7$+;}$AF@$J$$$N$G!"$=$l$>$l$N5-;v$K$O$3$l$i(B -$B$N5,B'$N$&$A$?$@0l$D$7$+E,MQ$5$l$^$;$s!#(B - -@code{gnus-del-mark} $B$rNc$KC5n(B ($B%a!<%k(B) $B%0%k!<%W(B (@pxref{Expiring Mail}) -$B$,$"$l$P!"4{FI5-;v$K$OA4$F(B @samp{E} $B0u$,$D$1$i$l$^$9!#$3$l$O$*$=(B -$B$i$/!"E,1~@-%9%3%"IU$1$r$A$g$C$H$P$+$jIT2DG=$K$9$k$N$G!"<+F04|8B(B -$B@Z$l>C5n$HE,1~@-%9%3%"$O0l=o$K$O$&$^$/$d$C$F$$$1$^$;$s!#(B - -$B%9%3%"$r$D$1$i$l$k%X%C%@!<$K$O(B @code{from}$B!"(B @code{subject}$B!"(B -@code{message-id}$B!"(B @code{references}$B!"(B @code{xref}$B!"(B -@code{lines}$B!"(B@code{chars}$B!"(B@code{date} $B$,$"$j$^$9!#$5$i$K(B -@code{followup} $B$K$b%9%3%"IU$1$G$-$^$9!#$3$l$O8=:_$N5-;v$N(B -@code{Message-ID} $B$r;HMQ$7$F(B @code{References} $B%X%C%@!<$K%^%C%A!"(B -$B$9$J$o$A$3$l$KB3$$$?%9%l%C%I$K%^%C%A$9$kE,1~@-%9%3%"EPO?$r:n@.$7(B -$B$^$9!#(B - -$B$^$?(B @code{thread} $B$K$b%9%3%"IU$1$9$k$3$H$,$G$-$^$9!#$3$l$O%9%l%C(B -$B%ICf$NA4$F$N5-;v$K%9%3%"IU$1$7$h$&$H$7$^$9!#(B@code{thread} $B$N%^%C(B -$B%A$O!"(B@code{Message-ID} $B$r;H$C$F5-;v$N(B @code{References} $B%X%C%@!<(B -$B$K%^%C%A$5$;$^$9!#%^%C%A$,5/$3$C$?$i$=$N5-;v$N(B @code{Message-ID} -$B$,(B @code{thread} $B5,B'$KDI2C$5$l$^$9!#(B($B$A$g$C$H9M$($F$_$F$/$@$5$$!#(B -$B8e$GF,DKLt$rFsN3$*4+$a$7$H$-$^$9$,(B) - -$B$3$N5!9=$r;H$&$J$i$P!"$H$-$I$-5-;v$r4{FI$K$7$F$7$^$&>.$5$JJQ99$r(B -$BHr$1$k$?$a$K!"%9%3%"%U%!%$%k$N(B @code{mark} $B%"%H%`$r2?$+>.$5$$CM(B ---- $B$3$H$K$h$l$P(B -300 $B$/$i$$$K@_Dj$7$F$*$$$?J}$,NI$$$G$9!#(B - -$BE,1~@-%9%3%"$r0l=54V$+$=$3$i;H$C$F$/$k$H!"(Bgnus $B$O$=$lAj1~$KD465(B -$B$5$l!"$"$J$?$,2?$b8@$o$J$/$F$b!"$"$J$?$N9%$-$JEj9FC5n$9$k$h$&$K$J$k$O$:$G$9!#(B - -$B$I$N%0%k!<%W$K$*$$$FE,1~@-%9%3%"$r:nF0$5$;$k$+$O!"%9%3%"%U%!%$%k(B -(@pxref{Score File Format}) $B$r;H$&$3$H$K$h$C$F@)8f$G$-$^$9!#$^$?(B -$B$3$l$r;H$C$F!"0c$C$?%0%k!<%W$KBP$7$F0c$C$?5,B'$r;H$&$h$&$K$b$G$-(B -$B$^$9!#(B - -@vindex gnus-adaptive-file-suffix -$BE,1~@-%9%3%"EPO?9`L\$O!"%0%k!<%WL>$K(B -@code{gnus-adaptive-file-suffix} $B$rIU2C$7$?L>A0$N%U%!%$%k$KF~$l(B -$B$i$l$^$9!#=i4|@_DjCM$O(B @samp{ADAPT} $B$G$9!#(B - -@vindex gnus-score-exact-adapt-limit -$BE,1~@-%9%3%"$r9T$&$H$-$O!"ItJ,J8;zNs0lCW$d%U%!%8!<$J0lCW$r9T$C$?(B -$BJ}$,!"$*$=$i$/$[$H$s$I$N>l9g$K$*$$$FNI$$7k2L$,F@$i$l$k$G$7$g$&!#(B -$B$7$+$7!"%X%C%@!<$N0lCW$7$?ItJ,$,C;$$>l9g!"0U?^$KH?$9$k$h$&$JF0:n(B -$B$r$9$k2DG=@-$,Bg$-$/$J$k$N$G!"(B -@code{gnus-score-exact-adapt-limit} $B$h$jC;$$D9$5$7$+0lCW$7$J$$>l(B -$B9g$O40A40lCW$,9T$o$l$^$9!#$3$NJQ?t$,(B @code{nil} $B$G$"$l$P!"$3$NLd(B -$BBj$,5/$3$i$J$$$h$&$K>o$K40A40lCW$,9T$o$l$^$9!#(B - -@vindex gnus-default-adaptive-word-score-alist -$B>e$G=R$Y$?$h$&$K!"8DJL$NC18l$KBP$7$F$b%X%C%@!l9g!"(B -@code{gnus-default-adaptive-word-score-alist} $BJQ?t$K$h$C$F!"3FC1(B -$B8l$KBP$7$F$"$k0u$X$I$s$J%9%3%"$rM?$($k$+$r;XDj$7$^$9!#(B - -@lisp -(setq gnus-default-adaptive-word-score-alist - `((,gnus-read-mark . 30) - (,gnus-catchup-mark . -10) - (,gnus-killed-mark . -20) - (,gnus-del-mark . -15))) -@end lisp - -$B$3$l$,=i4|@_DjCM$G$9!#C18l$KBP$9$kE,1~$rM-8z$K$9$k$H!"(B -@code{gnus-read-mark} $B$N0u$N$D$$$?5-;v$NI=Bj$K8=$l$kA4$F$NC18l$,!"(B -$B%9%3%"$K(B 30 $BE@DI2C$9$k$H$$$&%9%3%"5,B'$r@8$_=P$7$^$9!#(B - -@vindex gnus-default-ignored-adaptive-words -@vindex gnus-ignored-adaptive-words -@code{gnus-default-ignored-adaptive-words} $B$N%j%9%H$K8=$l$kC18l(B -$B$OL5;k$5$l$^$9!#L5;k$7$?$$C18l$rDI2C$7$?$$$H$-$O!"$3$NJQ?t$G$O$J(B -$B$/(B @code{gnus-ignored-adaptive-words} $B%j%9%H$NJ}$r;H$C$F$/$@$5$$!#(B - -@vindex gnus-adaptive-word-syntax-table -$B%9%3%"IU$1$,=*N;$7$?$H$-!"(B@code{gnus-adaptive-word-syntax-table} -$B$NJ8K!I=$,$=$N1F6A$r.(B -$B$5$/$J$k$3$H$O$"$j$^$;$s!#=i4|@_DjCM$O(B @code{nil} $B$G$9!#(B - -$B$3$N5!9=$r$7$P$i$/;H$C$F$_$?8e$K$O!"$"$J$?$,$I$s$JC18l$,9%$-$G(B -$B$I$s$JC18l$,7y$$$+$r!"$3$N5,B'$rDL$7$F?GCG$9$kMxMQo$K]$G$O!"$3$l(B -$B$O8=>u$G$OA4$/;H$$J*$K$J$i$J$$$h$&$K;W$($^$9!#$3$l$r$b$C$H;H$($k(B -$B$h$&$K$9$k$?$a$K$O!"(B($B$h$j87L)$JE}7WE*o(B -($B=i4|@_Dj$G(B) $B$=$N%0%k!<%WMQ$N%9%3%"%U%!%$%k$K$J$j$^$9!#Nc$($P!"(B -@samp{gnu.emacs.gnus} $BMQ$N%[!<%`%9%3%"%U%!%$%k$O(B -@file{gnu.emacs.gnus.SCORE} $B$H$J$k$o$1$G$9!#(B - -$B$7$+$7$J$,$i!"$3$l$O$"$J$?$N$*K>$_$G$O$J$$$+$b$7$l$^$;$s!#$?$/$5(B -$B$s$N%0%k!<%W4V$G6&DL$N%[!<%`%9%3%"%U%!%$%k$r6&M-$9$k$HJXMx$J$H$-(B -$B$,B?$$$G$7$g$&(B --- $BNc$($PA4$F$N(B @samp{emacs} $B%0%k!<%W$GF1$8%[!<(B -$B%`%9%3%"%U%!%$%k$r;H$&$3$H$b$G$-$^$9!#(B - -@vindex gnus-home-score-file -$B$3$l$r@)8f$9$kJQ?t$,(B @code{gnus-home-score-file} $B$G$9!#$3$l$O0J(B -$B2<$NCM$rl9g$3$N%U%!%$%k$,A4$F$N%0%k!<%W$G%[!<%`%9%3%"%U%!%$(B -$B%k$H$7$F;HMQ$5$l$^$9!#(B - -@item -$B4X?t!#$3$N4X?t$N7k2L$,%[!<%`%9%3%"%U%!%$%k$H$7$F;HMQ$5$l$^$9!#$3(B -$B$N4X?t$O%0%k!<%W$NL>A0$r0z?t$H$7$F8F$S=P$5$l$^$9!#(B - -@item -$B%j%9%H!#$3$N%j%9%H$NMWAG$O0J2<$NCM$r$K%^%C%A$9$l(B -$B$P!"(B@var{file-name} $B$,%[!<%`%9%3%"%U%!%$%k$H$7$F;HMQ$5$l$^$9!#(B - -@item -$B4X?t!#$3$N4X?t$,(B @code{nil} $B0J30$rJV$;$P!"$=$NJV5QCM$,%[!<%`%9%3(B -$B%"%U%!%$%k$H$7$F;HMQ$5$l$^$9!#(B - -@item -$BJ8;zNs!#(B $B$3$NJ8;zNs$r%[!<%`%9%3%"%U%!%$%k$H$7$F;HMQ$7$^$9!#(B -@end enumerate - -$B$3$N%j%9%H$NCf$+$i%^%C%A$9$k$b$N$r!":G=i$+$i8e$m$NJ}$K8~$+$C$FC5(B -$B$7$F$$$-$^$9!#(B - -@end enumerate - -$B$H$$$&$o$1$G!"C1$K0l8D$N%9%3%"%U%!%$%k$r;H$$$?$$>l9g$O!"0J2<$N$h(B -$B$&$K$9$l$P$G$-$^$9!#(B - -@lisp -(setq gnus-home-score-file - "my-total-score-file.SCORE") -@end lisp - -$B$b$7A4(B @samp{gnu} $B%0%k!<%W$KBP$7$F(B @file{gnu.SCORE} $B$r!"(B -$BA4(B @samp{rec} $B%0%k!<%W$KBP$7$F(B @file{rec.SCORE} ($BEy!9(B) $B$r;H$$$?(B -$B$1$l$P!"$3$N$h$&$K$G$-$^$9!#(B - -@findex gnus-hierarchial-home-score-file -@lisp -(setq gnus-home-score-file - 'gnus-hierarchial-home-score-file) -@end lisp - -$B$3$l$OJXMx$J$h$&$K$"$i$+$8$aDs6!$5$l$F$$$k4X?t$G$9!#(B -$BB?$N4X?t$O0J2<$N0J2<$N$b$N$r4^$_$^$9(B - -@table @code -@item gnus-current-home-scre-file -@findex gnus-current-home-score-file -``$B8=:_$N(B'' $BI8=`%9%3%"%U%!%$%k$rJV$7$^$9!#$3$l$O%9%3%"L?Na$K%9%3%"%U%!%$(B -$B%k$N(B ``$B:GFbIt(B'' $B9gCW$X$NEPO?$r2C$($k$h$&$K$7$^$9!#(B - -@end table - -$B$b$7(B @samp{emacs} $B%0%k!<%WMQ$N%9%3%"%U%!%$%k$H!"$=$l$H$OJL$N(B -@samp{comp} $B%0%k!<%WMQ$N%9%3%"%U%!%$%k$r;H$$!"B>$NA4It$N%0%k!<%W(B -$B$G$O$=$l$>$lFH<+$N%9%3%"%U%!%$%k$r;H$$$?$$$N$G$"$l$P!"(B - -@lisp -(setq gnus-home-score-file - ;; All groups that match the regexp "\\.emacs" - '(("\\.emacs" "emacs.SCORE") - ;; All the comp groups in one score file - ("^comp" "comp.SCORE"))) -@end lisp - -@vindex gnus-home-adapt-file -@code{gnus-home-adapt-file} $B$O(B @code{gnus-home-score-file} $B$HA4(B -$B$/F1$8$h$&$KF0:n$7$^$9$,!"$3$l$OBe$o$j$K2?$r%[!<%`E,MQ%9%3%"%U%!(B -$B%$%k$K$9$k$+$r;XDj$7$^$9!#?7$7$$E,MQ%U%!%$%kEPO?9`L\$OA4$F!"$3$N(B -$BJQ?t$G;XDj$5$l$k%U%!%$%k$KF~$l$i$l$^$9!#CM$K$OF1$8J8K!$,5v$5$l$^(B -$B$9!#(B - -@code{gnus-home-score-file} $B$H(B @code{gnus-home-adapt-file} $B$N;H(B -$BMQ$K2C$($F!"%0%k!<%W%Q%i%a!<%?(B (@pxref{Group Parameters}) $B$H%H%T%C(B -$B%/%Q%i%a!<%?(B (@pxref{Topic Parameters}) $B$r;H$C$F$[$\F1MM$N$3$H$,(B -$B$G$-$^$9!#%0%k!<%W!"%H%T%C%/%Q%i%a!<%?$O$3$NJQ?t$h$j$bM%@h$5$l$^$9!#(B - - -@node Followups To Yourself -@section $B<+J,<+?H$X$N%U%)%m!<%"%C%W(B - -Gnus $B$O8=:_$N%P%C%U%!!<$+$i(B @code{Message-ID} $B%X%C%@!<$r8+$D$1=P(B -$B$9$?$a$KFs$D$NL?Na$rDs6!$7$F$$$^$9!#(B $B$=$7$F(B gnus $B$O!"B>$N5-;v$K(B -$B$*$1$k(B@code{References} $B%X%C%@!@\%U%)%m!<%"%C%W$7$?5-;v$K%9%3%"$r2C;;(B -$B$7$^$9!#(B - -@item gnus-score-followup-thread -@findex gnus-score-followup-thread -$B$3$l$O$"$J$?$N5-;v$h$j(B ``$B2<(B'' $B$N%9%l%C%I$K8=$l$k5-;vA4$F$KBP$7$F(B -$B%9%3%"$r2C;;$7$^$9!#(B -@end table - -@vindex message-sent-hook -$B$3$l$iFs$D$N4X?t$O!"4pK\E*$K$O$I$A$i$b(B @code{message-sent-hook} -$B$N$h$&$J%U%C%/$NCf$G;H$&$?$a$N$b$N$G$9!#(B - -$B$"$J$?$N<+J,$N(B @code{Message-ID} $B$r$8$C$/$j$HD/$a$F$_$k$H!"$O$8(B -$B$a$NFs!";0J8;z$O>o$KF1$8$G$"$k$3$H$K5$$,$D$/$G$7$g$&!#0J2<$NFs$D(B -$B$O;d$N$b$N$G$9!#(B - -@example - - -@end example - -$B$D$^$j$3$N%^%7%s>e$G$N(B ``$B;d$N(B'' $B$N<1JL$O(B @samp{x6} $B$G$"$k$H$$$&(B -$B$3$H$G$9!#$3$l$O;H$($^$9(B --- $B0J2<$N5,B'$O;d<+?H$X$N%U%)%m!<%"%C(B -$B%WA4$F$KBP$7$F%9%3%"$rA}2C$5$;$k$G$7$g$&!#(B - -@lisp -("references" - ("" - 1000 nil r)) -@end lisp - -``$B$"$J$?$N(B'' $B$,:G=i$NFsJ8;z$K$J$k$+:G=i$N;0J8;z$K$J$k$+$O%7%9%F(B -$B%`$K0MB8$7$^$9!#(B - - -@node Scoring Tips -@section $B%9%3%"IU$1$N1|5A(B -@cindex scoring tips - -@table @dfn - -@item $B%/%m%9%]%9%H(B -@cindex crossposts -@cindex scoring crossposts -$B%/%m%9%]%9%H$N%9%3%"$rDc$/$7$?$1$l$P!"%^%C%A$5$;$k$Y$-9T$O(B -@code{Xref} $B%X%C%@!<$G$9!#(B -@lisp -("xref" (" talk.politics.misc:" -1000)) -@end lisp - -@item $BJ#?t$N%/%m%9%]%9%H(B -$B$"$k?t!"Nc$($P(B 3 $B$D0J>e$N%0%k!<%W$K%/%m%9%]%9%H$5$l$F$$$k5-;v$N(B -$B%9%3%"$rDc$/$7$?$1$l$P!"(B -@lisp -("xref" ("[^:\n]+:[0-9]+ +[^:\n]+:[0-9]+ +[^:\n]+:[0-9]+" -1000 nil r)) -@end lisp - -@item $BK\J8$X$N%^%C%A(B -$B$3$l$O0lHLE*$K$O$"$^$jNI$$9M$($G$O$"$j$^$;$s(B --- $B$=$l$O$H$F$bD9(B -$B;~4V$+$+$C$F$7$^$&$+$i$G$9!#$l$N5-;v$r8DJL$K(B -$B%5!<%P!<$+$i$l$N5-;v$O(B @emph{$BFs2s(B} $B$K(B @code{All} $B$r;H$C$FA4It%^%C%A(B -$B$5$;$F$/$@$5$$!#(B - -@item $B4{FI$N0uIU$1(B -$B$"$k0lDj?t;z0J2<$N%9%3%"$r;}$D5-;v$K$O!"$*$=$i$/4{FI$N0u$r$D$1$F(B -$B$7$^$$$?$/$J$k$G$7$g$&!#$3$l$O(B @file{all.SCORE} $B%U%!%$%k$K0J2<$N(B -$B$b$N$rF~$l$F$*$/$3$H$K$h$C$F:G$b4JC1$K$N5-;vA4$F$r>C5n$7$F$7$^$$$?$1$l$P!"%9%3%"%U%!(B -$B%$%k$K0J2<$N$h$&$J$b$N$rF~$l$k$3$H$b$G$-$^$9!#(B - -@lisp -(("subject" - ("Sex with Emacs" 2)) - (mark 1) - (expunge 1)) -@end lisp - -$B$=$7$F(B @samp{Sex with Emacs} $B$K%^%C%A$9$kA4$F$N5-;v$r=8$a$F!";D(B -$B$j$r=3Ht$P$9$?$a$K4{FI$N0u$r$D$1!">C5n$7$^$9!#(B - - -@node Global Score Files -@section $B%0%m!<%P%k%9%3%"%U%!%$%k(B -@cindex global score files - -$B4V0c$$$J$/!"B>$N%K%e!<%9%j!<%@!<$O(B ``$B%0%m!<%P%k:o=|%U%!%$%k(B -(global kill file)'' $B$r;}$C$F$$$^$9!#$3$l$OIaDL!"A4$F$N%0%k!<%W(B -$B$KE,MQ$5$l$k!"%f!<%6!<$N%[!<%`%G%#%l%/%H%j!<$K3JG<$5$l$F$$$k0l$D(B -$B$N:o=|%U%!%$%k0J>e$N2?J*$G$b$"$j$^$;$s!#$O$s(B! $B$A$C$]$1$J%K%e!<%9(B -$B%j!<%@!<$@$M!#$N?M$N%9%3%"%U%!%$%k$r;H$&$?$a$K$7$J$1$l$P$J$i$J$$$3$H$O!"(B -@code{gnus-global-score-files} $BJQ?t$r@_Dj$9$k$3$H$@$1$G$9!#$=$l(B -$B$>$l$N%9%3%"%U%!%$%kKh$K!"$"$k$$$O$=$l$>$l$N%9%3%"%U%!%$%k%G%#%l(B -$B%/%H%jKh$KBP$7$F0l$D$N9`L\$K$J$j$^$9!#(BGnus $B$O$I$N%9%3%"%U%!%$%k(B -$B$r$I$N%0%k!<%W$K;H$&$N$,E,@Z$G$"$k$+$r<+J,$G7hDj$7$^$9!#(B - -$BNc$($P(B -@file{/ftp@@ftp.gnus.org:/pub/larsi/ding/score/soc.motss.SCORE} -$B$N%9%3%"%U%!%$%k$H(B @file{/ftp@@ftp.some-where:/pub/score} $B%G%#%l(B -$B%/%H%j$K$"$kA4$F$N%9%3%"%U%!%$%k$r;H$$$?$1$l$P!"(B - -@lisp -(setq gnus-global-score-files - '("/ftp@@ftp.gnus.org:/pub/larsi/ding/score/soc.motss.SCORE" - "/ftp@@ftp.some-where:/pub/score/")) -@end lisp - -@findex gnus-score-search-global-directories -$B$I$&$@$$!"4JC1$@$m$&(B? $B%G%#%l%/%H%jL>$O(B @samp{/} $B$G=*$o$i$J$/$F$O(B -$B$J$j$^$;$s!#$3$l$i$N%G%#%l%/%H%j$OIaDL$O!"0l2s$N(B gnus $B;HMQ4|4VCf(B -$B$K0l2s$@$1$7$+FI$_9~$_$^$;$s!#$b$71s3V%G%#%l%/%H%j$r$N?M$?$A$K;H$C$F$b$i$&$h$&$K0];}$7$?$/$J$C(B -$B$F$-$?$i!"C1$K$"$J$?$N%9%3%"%U%!%$%k$rF?L>(B FTP $B$KCV$$$F!"@$3&Cf(B -$B$K8xI=$7$F$/$@$5$$!#5U;J2q!$Ao$KB?$/$N>l=j$K%/%m%9%]%9%H$5$l$F$$$k5-;v$O4V0c$$$J$/6}$G$"$k!#(B -@item -$B0l8D$NITE,@Z$J5-;v$r8:E@$9$k$K$O!"(B@code{Message-ID} $B$G8:E@$9$k!#(B -@item -$BFC$KAG@2$i$7$$Ej9FOL5;k$NEj9F$rIQHK$K7+$jJV$9Ej9FC5n$N%9%3%"9`L\$r;H$C$F%U%!%$%k$NBg$-$5$r>.$5$/M^$($k!#$G$b$*$=(B -$B$i$/$O!"%5%$%H$K$h$C$F8E$$5-;v$rD94|4VJ]B8$9$k$h$&$K!"4|8B@Z$l>C(B -$B5n$N4|4V$OD9$/$N%K%e!<%9%j!<%@!<$O>-Mh!"%0%m!<%P%k%9%3%"%U%!%$%k(B -$B$r%5%]!<%H$9$k$G$7$g$&$+(B? @emph{$B$&$U$U(B}$B!#$=$&!"$I$&9M$($F$_$?$C(B -$B$F!"(BBlue Wave $B$d(B xrn $B$d(B 1stReader $B$H$+$$$C$?%K%e!<%9%j!<%@!<$O%9(B -$B%3%"$r%5%]!<%H$9$k$Y$-$@$M!#:#$O8GBC$r0{$s$G8+C5n%U%!%$%k(B -@cindex kill files - -Gnus $B$O$^$@!"$"$N$&$6$C$?$$8E$$>C5n%U%!%$%k$r%5%]!<%H$7$F$$$^$9!#(B -$BC5n%U%!%$%k$N9`L\$O$b$&>C$7$F$b$h$$$N$G$9$,!"$=$l$O(B Daniel -Quinlan $B$,%9%3%"%U%!%$%k$r9M$(=P$9A0$K;d$,=q$$$?$b$N$J$N$G!"$=$N(B -$B%3!<%I$O$^$@;D$C$F$$$^$9!#(B - -$BMW$9$k$K!">C5n=hM}$O%9%3%"=hM}$h$j$b$+$J$jCY$$$N$G(B ($B;d$N8@$$$?$$(B -$B$N$O(B @emph{$B$b$N$9$4$/(B})$B!"$"$J$?$N>C5n%U%!%$%k$O%9%3%"%U%!%$%k$K(B -$B=q$-49$($?J}$,NI$$$+$b$7$l$^$;$s!#(B - -$B$$$:$l$K$;$h!">C5n%U%!%$%k$OIaDL$N(B @code{emacs-lisp} $B%U%!%$%k$G$9!#(B -$B$3$N%U%!%$%k$NCf$K$O$I$s$J7A<0$G$bF~$l$k$3$H$,$G$-$^$9!#$D$^$j>C(B -$B5n%U%!%$%k$r%0%k!<%W$KF~$C$?$H$-$Ko$N>C5n%U%!%$%k$O0J2<$N$h$&$K$J$j$^$9!#(B - -@lisp -(gnus-kill "From" "Lars Ingebrigtsen") -(gnus-kill "Subject" "ding") -(gnus-expunge "X") -@end lisp - -$B$3$l$O;d$,=q$$$?A4$F$N5-;v$K4{FI$N0u$r$D$1!"35N,%P%C%U%!$+$i0u$N(B -$B$D$$$?5-;v$r:o=|$7$^$9!#$H$C$F$bJXMx$G$9!#$"$J$?$b$=$&;W$&$G$7$g!#(B - -$BB>$N%W%m%0%i%`$G$OA4$/0c$&>C5n%U%!%$%k$N9=J8$r;H$C$F$$$^$9!#$b$7(B -gnus $B$,(B @code{rn} $B$N>C5n%U%!%$%k$i$7$-$b$N$K=P2q$C$?$i!"2?$H$+$=(B -$B$l$r2rC5n%U%!%$%k$rJT=8$9$k$?$a$NFs$D$N35N,%P%C%U%!4X?t$,$"$j$^(B -$B$9!#(B - -@table @kbd - -@item M-k -@kindex M-k (Summary) -@findex gnus-summary-edit-local-kill -$B$=$N%0%k!<%W$N>C5n%U%!%$%k$rJT=8$9$k(B -(@code{gnus-summary-edit-local-kill})$B!#(B - -@item M-K -@kindex M-K (Summary) -@findex gnus-summary-edit-global-kill -$B0lHL>C5n%U%!%$%k$rJT=8$9$k(B -(@code{gnus-summary-edit-global-kill})$B!#(B -@end table - -$B>C5n%U%!%$%k$rJT=8$9$kFs$D$N%0%k!<%W%b!<%I4X?t$,$"$j$^$9!#(B - -@table @kbd - -@item M-k -@kindex M-k (Group) -@findex gnus-group-edit-local-kill -$B$=$N%0%k!<%W$N>C5n%U%!%$%k$rJT=8$9$k(B -(@code{gnus-group-edit-local-kill})$B!#(B - -@item M-K -@kindex M-K (Group) -@findex gnus-group-edit-global-kill -$B0lHL>C5n%U%!%$%k$rJT=8$9$k(B (@code{gnus-group-edit-global-kill})$B!#(B -@end table - -$B>C5n%U%!%$%kJQ?t!#(B - -@table @code -@item gnus-kill-file-name -@vindex gnus-kill-file-name -@samp{soc.motss} $B%0%k!<%WMQ$N>C5n%U%!%$%k$ODL>o(B -@file{soc.motss.KILL} $B$H$$$&L>A0$G$9!#$3$N%U%!%$%kL>$rF@$k$?$a$K(B -$B%0%k!<%WL>$KIU2C$5$l$k@\Hx<-$O!"(B@code{gnus-kill-file-name} $BJQ?t(B -$B$GM?$($i$l$^$9!#(B``$B%0%m!<%P%k(B'' $B>C5n%U%!%$%k$O(B ($B%9%3%"%U%!%$%k$N(B -$B0UL#$G$N(B ``$B%0%m!<%P%k(B'' $B$8$c$J$$$h!"$b$A$m$s(B) $BC1$K(B @file{KILL}$B$H(B -$B$$$&L>A0$G$9!#(B - -@vindex gnus-kill-save-kill-file -@item gnus-kill-save-kill-file -$B$3$NJQ?t$,(B @code{nil} $B0J30$G$"$l$P!"(Bgnus $B$O=hM}$N8e$K>C5n%U%!%$(B -$B%k$rJ]B8$7$^$9!#$3$l$O4|8B@Z$l:o=|$r9T$&>C5n$r;H$C$F$$$k$H$-$KI,(B -$BMW$G$9!#(B - -@item gnus-apply-kill-hook -@vindex gnus-apply-kill-hook -@findex gnus-apply-kill-file-unless-scored -@findex gnus-apply-kill-file -$B%0%k!<%W$K>C5n%U%!%$%k$rE,MQ$9$k$?$a$K8F$S=P$5$l$k%U%C%/!#$3$l$O(B -$B=i4|@_Dj$G$O(B @code{(gnus-apply-kill-file)} $B$G$9!#$b$7F1$8%0%k!<(B -$B%W$KBP$7$F%9%3%"%U%!%$%k$,$"$k>l9g$K$O>C5n%U%!%$%k$rL5;k$7$?$1$l(B -$B$P!"$3$N%U%C%/$r(B @code{(gnus-apply-kill-file-unless-scored)} $B$K(B -$B@_Dj$7$^$9!#>C5n%U%!%$%k$r=hM}$5$;$?$/$J$1$l$P!"$3$NJQ?t$r(B -@code{nil} $B$K@_Dj$7$F$/$@$5$$!#(B - -@item gnus-kill-file-mode-hook -@vindex gnus-kill-file-mode-hook -$B>C5n%U%!%$%k%b!<%I%P%C%U%!Fb$G8F$S=P$5$l$k%U%C%/!#(B - -@end table - - -@node Converting Kill Files -@section $B>C5n%U%!%$%k$NJQ49(B -@cindex kill files -@cindex converting kill files - -$B$"$J$?$,8E$$>C5n%U%!%$%k$r$I$C$5$j;}$C$F$$$k$N$G$"$l$P!"$=$l$i$r(B -$B%9%3%"%U%!%$%k$KJQ49$7$?$/$J$k$G$7$g$&!#$b$7$=$l$i$,(B ``$BIaDL$N(B'' -$B$d$D$G$"$l$P!"(B@file{gnus-kill-to-score.el} $B%Q%C%1!<%8$r;H$&$3$H(B -$B$,$G$-$^$9!#$=$&$G$J$1$l$P!"C5n%U%!%$%k$+$i%9%3%"%U%!%$%k$X$NJQ49%Q%C%1!<%8$O!"I8=`$G$O(B -gnus $B$K$O4^$^$l$^$;$s!#(B -@file{http://www.stud.ifi.uio.no/~larsi/ding-other/gnus-kill-to-score} -$B$+$iF~C5n%U%!%$%k$,Hs>o$KJ#;($J$b$N$G$"$l$P(B --- $B$=$l$K(B -@code{gnus-kill} $B7A<00J30$N$b$N$,$?$/$5$s4^$^$l$F$$$l$P!"$=$l$i(B -$B$r$N(B -$B?M$H6&$K8+$D$1$k$N$r=u$1$k$?$a$N6&F1A*JL5!9=$G$9!#(B - -$B$3$l$rC#@.$9$k$?$a$K!"(BGroupLens $B5!9=$O$"$J$?$,4{$KFI$s$@5-;v$KBP$9$k0U8+(B -$B$r!"F1$8$h$&$J;v$r$7$?B>$N?M$N0U8+$H7k9g$7$F!"$=$l$>$l$NL$FI%K%e!<%95-;v(B -$B$K8D?M2=$5$l$?M=8@$rM?$($^$9!#(BGroupLens $B$rCg?M$N$h$&$J$b$N$@$H8+$J$7$F$/(B -$B$@$5$$!#(BGroupLens $B$O$"$J$?$,$I$N$h$&$K5-;v$N2ACM$rIU$1$k$+$r8+$F!"F1$8$h(B -$B$&$K5-;v$N2ACM$rIU$1$k?M$rC5$7$^$9!#0lEY$"$J$?$N0U8+$H0lCW$9$k?M$rH/8+$9(B -$B$l$P!"M=8@$N7A$G!"$=$l$i$N?M$,5-;v$r$I$&;W$&$+$r$"$J$?$K9p$2$^$9!#$"$J$?(B -$B$O$3$NM=8@$r5-;v$rFI$_$?$$$+$I$&$+$r7hDj$9$k$N$KLrN)$F$k;v$,$G$-$^$9!#(B - -@menu -* Using GroupLens:: $B$I$N$h$&$K(B gnus $B$K(B GroupLens $B$r;H$o$;$k$h$&(B - $B$K$9$k$+!#(B -* Rating Articles:: GropLens $B$K$"$J$?$,$I$N$h$&$KCM$rIU$1$k$+$r(B - $BCN$i$;$k!#(B -* Displaying Predictions:: GropuLens $B$K$h$C$FM?$($i$l$?M=8@$rI=<($9$k!#(B -* GroupLens Variables:: GoupLens $B$r%+%9%?%^%$%:$9$k!#(B -@end menu - - -@node Using GroupLens -@subsection GroupLens $B$r;H$&(B - -GroupLens $B$r;H$&$?$a$K$O!"%m!<%+%k$N(B Better Bit Berau (BBB) $B$KI.L>(B -(pseudonym) $B$rEPO?$7$J$1$l$P$J$j$^$;$s!#(B -@samp{http://www.cs.umn.edu/Research/GroupLens/bbb.html} $B$,8=:_!"$A$^$?(B -$B$KB8:_$9$kM#0l$N(B better bit $B$G$9!#(B - -$BEPO?$7$?8e$G!"$$$/$D$+$NJQ?t$r@_Dj$9$kI,MW$,$"$j$^$9!#(B - -@table @code - -@item gnus-use-grouplens -@vindex gnus-use-grouplens -$B$3$NJQ?t$r(B @code{nil} $B$G$J$$CM$K@_Dj$9$k$H!"(BGnus $B$,A4$F$N(B GroupLens $B4XO"(B -$B4X?t$r%U%C%/$9$k$h$&$K$J$j$^$9!#(B - -@item grouplens-pseudonym -@vindex grouplens-pseudonym -$B$3$NJQ?t$O(B Better Bit Bureau $B$KEPO?$7$?$H$-$K$b$i$C$?I.L>$K@_Dj$5$l$k$Y(B -$B$-$G$9!#(B - -@item grouplens-newsgroups -@vindex grouplens-newsgroups -GroupLens $B$NM=8@$rF@$?$$$H;W$&%0%k!<%W$N%j%9%H$G$9!#(B - -@end table - -$B$3$l$,5/$->e$,$C$F(B GroupLens $B$r$N?M$,9M$($kJ?6Q$K4p$E$$$?%9%3%"$r$"(B -$B$J$?$KDs6!$9$k$3$H$r;O$a$^$9!#$7$+$7!"(BGroupLens $B$NK\Ev$NMx1W$ro$KLr$KN)$A$^$9!#(B - -@end table - -$Be=q$-$9$k$+$rA*$V;v$,$G$-$^$9!#>e(B -$B=q$-$,=i4|@_Dj$G$9!#$7$+$7!"(Bgnus $B$N%9%3%"$r(B grouplens $B$N%9%3%"$KB-$9$N$r(B -$B9%$`?M$b$$$^$9!#J,N%%9%3%"$N?6$kIq$$$rF@$k$?$a$K$O!"(B -@code{gnus-grouplens-override-scoring} $B$r(B @code{'separate} $B$K@_Dj$9$kI,(B -$BMW$,$"$j$^$9!#(BGroupLens $B$NM=8@$H(B grouplens $B%9%3%"$r7k9g$9$k$?$a$K$O$=$l(B -$B$r(B @code{'override} $B$K@_Dj$7!"%9%3%"$r7k9g$9$k$?$a$K$O(B -@code{gnus-grouplens-override-scoring} $B$r(B @code{'combine} $B$K@_Dj$7$^$9!#(B -$B7k9gIU2C5!G=$rMQ$$$k$H$-$O!"(B@code{grouplens-prediction-offset} $B$H(B -@code{grouplens-score-scale-factor} $B$NCM$r@_Dj$7$?$$$H;W$&$G$7$g$&!#(B - -@vindex grouplens-prediction-display -$B$I$A$i$N>l9g$G$b!"(BGroupLens $B$O(B2,3$B$NM=8@$,$I$N$h$&I=<($5$l$?$$$+$NA*Br$r(B -$BM?$($^$9!#M=8@$NI=<($OJQ?t(B @code{grouplens-prediction-display} $B$K$h$C$F(B -$B@)8f$5$l$^$9!#(B - -$B0J2<$N$b$N$,$=$NJQ?t$GM-8z$JCM$G$9!#(B - -@table @code -@item prediction-spot -$BM=8@$,9b$$$[$I!"1&$NJ}$K(B @samp{*} $B$,I=<($5$l$^$9!#(B - -@item confidence-interval -$B?t;z$N3N?.(B (confidence) $B4V3V$G$9!#(B - -@item prediction-bar -$BM=8@$,9b$$$[$I!"K@$,D9$/$J$j$^$9!#(B - -@item confidence-bar -$B?t;z3N?.$G$9!#(B - -@item confidence-spot -$B3N?.$,9b$$$[$IE@$,Bg$-$/$J$j$^$9!#(B - -@item prediction-num -$BIaDL$N@N$J$,$i$N?tCM$G$9!#(B - -@item confidence-plus-minus -$BM=8@$N(B +/- $B3N?.$G$9!#(B - -@end table - - -@node GroupLens Variables -@subsection GroupLens $BJQ?t(B - -@table @code - -@item gnus-summary-grouplens-line-format -GropuLens $B3HD%$N35N,%P%C%U%!$G;H$o$l$k35N,9TMM<0$G$9!#IaDL$N35N,9TMM<0$,(B -$Be5i%9%3%"IU$1(B - -$BI=Bj$d(B From $B%X%C%@!<$K%9%3%"$rIU$1$k$N$O==J,AGE($G$9$,!"$"$k?MFCDj$NBj$K(B -$B4X$7$F8@$C$F$$$k;v$K$@$1K\Ev$K6=L#$,$"$k>l9g$O$I$&$9$l$PNI$$$N$G$7$g$&!)(B -$B$b$7$/$O!"(BA$B$5$s$,(B B$B$5$s$K%U%)%m!<%"%C%W$7$F$$$k$H$-$K8@$C$F$$$k;v$rFI$_(B -$B$?$/$J$$$1$l$I!"(BC$B$5$s$K%U%)%m!<%"%C%W$7$F$$$k$H$-$O2?$r8@$C$F$$$k$+$rCN(B -$B$j$?$$$H$$$&>l9g$O!)(B - -$B>e5i%9%3%"K!B'$r;H$&;v$G!"G$0U$NJ#;($J%9%3%"$NIU$1J}$r:n@.$9$k;v$,$G$-$^(B -$B$9!#(B - -@menu -* Advanced Scoring Syntax:: $BDj5A!#(B -* Advanced Scoring Examples:: $B$I$N$h$&$K8+$($k$+!#(B -* Advanced Scoring Tips:: $B$=$l$r:GBg8BMxMQ$9$k!#(B -@end menu - - -@node Advanced Scoring Syntax -@subsection $B>e5i%9%3%"IU$19=J8(B - -$BIaDL$N%9%3%"K!B'$OK!B'$N:G=i$NMWAG$KJ8;zNs$,$"$j$^$9!#>e5i%9%3%"IU$1K!B'(B -$B$O:G=i$NMWAG$K%j%9%H$,$"$j$^$9!#(B2$BHVL\$N%j%9%H$O:G=i$NMWAG$,(B @code{nil} -$B$G$J$$CM$KI>2A$5$l$?$H$-$KE,MQ$5$l$^$9!#(B - -$B$3$l$i$N%j%9%H$O(B3$B$D$NO@M}:nMQ;R$+$i$J$C$F$*$j!"$=$l$i$O(B1$BJ}8~:nMQ;R$G!"?'!9(B -$B$J9gCW:nMQ;R$G$9!#(B - -$BO@M}:nMQ;R(B: - -@table @code -@item & -@itemx and -$B$3$NO@M}:nMQ;R$O$=$l$>$l$N0z?t$r(B @code{false} $B$KI>2A$5$l$k$b$N$r8+$D$1$k(B -$B$^$GI>2A$7!"$=$l$+$iDd;_$7$^$9!#A4$F$N0z?t$,(B @code{true} $B$NCM$KI>2A$5$l(B -$B$?>l9g$O!"$3$N:nMQ;R$O(B @code{true} $B$rJV$7$^$9!#(B - -@item | -@itemx or -$B$3$NO@M}:nMQ;R$O$=$l$>$l$N0z?t$r(B @code{true} $B$KI>2A$5$l$k$b$N$r8+$D$1$k(B -$B$^$GI>2A$7$^$9!#$b$7$I$N0z?t$b(B @code{true} $B$G$J$$$H!"$3$N:nMQ;R$O(B -@code{false} $B$rJV$7$^$9!#(B - -@item ! -@itemx not -@itemx \254 -$B$3$NO@M}:nMQ;R$OC10l$N0z?t$N$_$r$H$j$^$9!#$=$l$O$=$N0z?t$NCM$NO@M}H]Dj$r(B -$BJV$7$^$9!#(B - -@end table - -$B0z?t$r%9%3%"IU$1$5$l$F$$$k8=:_$N5-;v$NAD@h$KE,MQ$9$k(B @dfn{$B4V@\:nMQ;R(B} $B$,(B -$B$"$j$^$9!#Nc$($P!"(B@code{1-} $B$O8=:_$N5-;v$N?F$K$b%9%3%"K!B'$rE,MQ$7$^$9!#(B -@code{2-} $B$O8=:_$N5-;v$NADIcJl$K%9%3%"K!B'$rE,MQ$7$^$9!#Be$o$j$K!"(B -@code{^^} $B$r=q$/;v$b$G$-!"$3$N;~!"(B@code{^} ($B%-%c%i%C%H(B) (carat) $B$N?t$O$I(B -$B$N$/$i$$AD@h$N5-;v$^$G$5$+$N$\$k$+$r<($7$^$9!#(B - -$B:G8e$K!"9gCW:nMQ;R$,$"$j$^$9!#$3$l$i$,K\Ev$N;E;v$r$9$k$b$N$G$9!#9gCW:nMQ(B -$B;R$O%X%C%@!$NJ8;zNs$G!"$=$N8e$K9gCW$H9gCW$N7?$,B3$-$^$9!#E57?E*$J9gCW(B -$B:nMQ;R$O(B @samp{("form" "Lars Ingebrigtsen" s)} $B$N$h$&$J$b$N$G$9!#%X%C%@!<(B -$BL>$OC1=c$J%9%3%"IU$1$r$9$k$H$-$N$b$N$HF1$8$G!"9gCW$N7?$bF1$8$G$9!#(B - - -@node Advanced Scoring Examples -@subsection $B>e5i%9%3%"IU$1$NNc(B - -Lars $B$,(B Gnus $B$K4X$7$FOC$r$7$F$$$k$H$-$KH`$K$h$C$F=q$+$l$?5-;v$N%9%3%"$r(B -$BA}$d$7$?$$$H$7$^$7$g$&(B: - -@example -((& - ("from" "Lars Ingebrigtsen") - ("subject" "Gnus")) - 1000) -@end example - -$B$M!"$H$F$bC1=c$G$7$g!)(B - -$BD9$$5-;v$r=q$$$F$$$k$H$-$O!";~!92?$+AGE($J;v$r8@$$$^$9(B: - -@example -((& - ("from" "Lars Ingebrigtsen") - (| - ("subject" "Gnus") - ("lines" 100 >))) - 1000) -@end example - -$B$7$+$7!"H`$,(B Reig Eigil Logge $B$K$h$C$F=q$+$l$?$b$N$KH?1~$7$F$$$k$H$-$O!"(B -$BH`$,=q$$$?$b$N$rFI$_$?$/$"$j$^$;$s(B: - -@example -((& - ("from" "Lars Ingebrigtsen") - (1- ("from" "Reig Eigir Logge"))) - -100000) -@end example - -Redmondo $B$,>C$($?7$2<$K$D$$$F=q$$$?$H$-$K%U%)%m!<%"%C%W$7$?A4$F$N?M$O%9(B -$B%3%"$,>e$2$i$l$^$9$,!"$=$l$OH`$i$,Gr$$7$2<$K$D$$$F8l$C$F$$$k$H$-$N$_$G$9!#(B -$B$7$+$7!"(BLars $B$,7$2<$K$D$$$FOC$r$7$F$$$k$H$-$O!"$?$$$F$$$"$^$j$*$b$7$m$/(B -$B$"$j$^$;$s(B: - -@example -((& - (1- - (& - ("from" "redmondo@@.*no" r) - ("body" "disappearing.*socks" t))) - (! ("from" "Lars Ingebrigtsen")) - ("body" "white.*socks")) - 1000) -@end example - -$B2DG=@-$OL58BBg$G$9!#(B - - -@node Advanced Scoring Tips -@subsection $B>e5i%9%3%"$N$A$g$C$H$7$?Hk7m(B - -@code{&} $B$H(B @code{|} $BO@M}:nMQ;R$O!"C;=L2sO)O@M}$r9T$$$^$9!#$9$J$o$A!"$=(B -$B$N:nMQ$N7k2L$,L@$i$+$K$J$C$F;~E@$G!"0z?t$r2A$,(B @code{false} $B$K$J$k$H!";D$j$N0z?t$rI>2A(B -$B$9$kL\E*$OB8:_$7$J$/$J$j$^$9!#$3$l$OCY$$9gCW(B (@samp{body} $B$d(B -@samp{header}) $B$r:G8e$K;}$C$F$-$F!"B.$$9gCW(B (@samp{from} $B$d(B -@samp{subject}) $B$r:G=i$K;}$C$F$/$k$Y$-$G$"$k$H$$$&;v$r0UL#$7$^$9!#(B - -$B4V@\:nMQ;R(B (@code{1-} $B$J$I(B) $B$O$=$l$i$N0z?t$r%9%l%C%I$N(B1$B@$BeA0$K:nMQ$9$k(B -$B$h$&$K$7$^$9!#e$,$k798~$,$"$k;v$K5$IU$/$+$b$7$l$^$;$s!#FC$K!"E,1~(B -$B%9%3%"$r;H$C$F$$$k$H$-$O!#%9%3%"$,Bg$-$/$J$j$9$.$k$H!"$=$l$i$O0UL#$r<:$$(B -$B$^$9(B---$B$=$l$i$OC1$K:GBg$rDL$j1[$7$F$7$^$C$F!"$=$l$r0UL#$N$"$kJ}K!$G;H$&(B -$B;v$OFq$7$/$J$j$^$9!#(B - -@vindex gnus-decay-scores -@findex gnus-decay-score -@vindex gnus-decay-score-function -Gnus $B$O$3$NLdBj$N2r7h$r=u$1$k$?$a$K%9%3%"$rIe$i$;$k5!9=$rDs6!$7$^$9!#%9(B -$B%3%"%U%!%$%k$OFI$_9~$^$l!"(B @code{gnus-decay-scores} $B$,(B @code{nil} $B$G$J$$(B -$B$H!"(Bgnus $B$O%9%3%"%U%!%$%k$rIeGT5!9=$rDL$7!"A4$F$N1JB3$G$J$$%9%3%"K!B'$N(B -$B%9%3%"$r2<$2$^$9!#IeGT<+?H$O4X?t(B @code{gnus-decay-score-function} $B$K$h$C(B -$B$Fe$2$k$+!#(B -* Mode Lines:: $B%b!<%I9T$K>pJs$rI=<($9$k!#(B -* Highlighting and Menus:: $B%P%C%U%!$rAGE($G?4CO$h$/8+$;$k!#(B -* Buttons:: $B4JC1$J(B10$BJb$G%"%-%l%9g'$rF@$k!#(B -* Daemons:: Gnus $B$O$"$J$?$NN"$GJ*;v$r$NB@$j$d$9$$?);v$rHr$1$kJ}K!!#(B -* Undo:: $B$$$/$D$+$NF0:n$O85$KLa$9;v$,$G$-$k!#(B -* Moderation:: $B$"$J$?$,%b%G%l!<%?!<$@$C$?$i$I$&$9$k$+!#(B -* XEmacs Enhancements:: XEmacs $B$G$O$b$C$H3($d$=$NB>$N$b$N$,B8:_$9$k!#(B -* Fuzzy Matching:: $BBg$-$JLJLS$C$F2?!)(B -* Thwarting Email Spam:: $BM>7W$J>&6HE*EE;R%a!<%k$rHr$1$kJ}K!!#(B -* Various Various:: $BK\Ev$K$$$m$$$m$J$b$N!#(B -@end menu - - -@node Process/Prefix -@section $B%W%m%;%9(B/$B@\F,0z?t(B -@cindex process/prefix convention - -$BB?$/$N4X?t!"$=$NCf$G$b5-;v$N0\F0!"I|9f2=!"J]B8$r$9$k$?$a$N4X?t$O!"(B -@dfn{$B%W%m%;%9(B/$B@\F,0z?t$N=,47(B} $B$H$7$FCN$i$l$F$$$k$b$N$r;H$$$^$9!#(B - -$B$3$l$OMxMQl(B -$B9g$O!"%W%m%;%90u$NIU$$$F$$$k5-;v$K:n6H$,l9g$O!"8=:_$N5-;v$K$@$1:n(B -$B6H$ro$K4JC1$G$9$,!"6CC2$rHr$1$i$l$k$h$&$K>\:Y$rL@$i$+$K$7$F$*(B -$B$/I,MW$,$"$k$N$G$9!#(B - -$B%W%m%;%90u$KH?1~$9$k5-;v$O8=:_$N%W%m%;%90u$NIU$$$F$$$k5-;v$N%j%9%H$r%9%?%C(B -$B%/$K@Q$_!"A4$F$N%W%m%;%90u$N5-;v$N%j%9%H$r>C5n$7$^$9!#A02s$N@_Dj$r(B -@kbd{M P y} $B$GI|5l$5$;$k;v$,$G$-$^$9(B (@pxref{Setting Process Marks})$B!#(B - -@vindex gnus-summary-goto-unread -$BB?$/$N?M!9$r6C$+$;!"62$,$i$;$k$H;W$o$l$k$3$H$O!"Nc$($P!"(B@kbd{3 d} $B$OK\Ev(B -$B$K(B @kbd{d} @kbd{d} @kbd{d} $B$HF1$8;v$r$9$k;v$G$9!#$=$l$>$l$N(B @kbd{d} ($B$3(B -$B$l$O8=:_$N5-;v$K4{FI$N0u$rIU$1$^$9(B) $B$O=i4|@_Dj$G$O0u$rIU$1$?8e$Ko$K?5=E$J?M$G!"$3$l$OK\Ev$KNI$$;v$G$9!#2?$+4m81$J;v$r(B -$B$9$kA0$K!"(B``$BK\Ev$K$3$l$r$7$?$$$N$G$9$+!)(B'' $B$H$$$&$h$&$Jo$KB?$/$N(B Emacs $B$NL?Na$O(B ($B?tCM(B) $B@\F,0z?t$KH?1~$7$^$9!#Nc$($P!"(B -@kbd{C-u 4 C-f} $B$O%]%$%s%H$r(B4$BJ8;z@h$K0\F0$7!"(B@kbd{C-u 9 0 0 I s s p} $B$O(B -$B1JB3(B @code{Suject} $BJ8;zNs$N0lIt%9%3%"K!B'$N(B900$B$r8=:_$N5-;v$K2C$($^$9!#(B - -$B$3$l$OAGE($GNI$$$N$G$9$,!"L?Na$K$b$&>/$7DI2C$N>pJs$rM?$($?$$$H$-$O$I$&$9(B -$B$l$PNI$$$N$G$7$g$&!)$(!<$H!"$?$$$F$$$NL?Na$,$7$F$$$k;v$O!"(B``$B@8$N(B'' $B@\F,(B -$B0z?t$rFCJL$JJ}K!$G2r$`$@$1B?(B -$B$/$N(B @kbd{M-i} $B@\F,8l$r@Q$_=E$M$k;v$,$G$-$^$9!#(B@kbd{M-i a M-C-u} $B$O(B ``$BL?(B -$BNa(B @kbd{M-C-u} $B$K%7%s%\%k@\F,0z?t(B @code{a} $B$rM?$($k(B'' $B$H$$$&$3$H$G$9!#(B -@kbd{M-i a M-i b M-C-u} $B$OL?Na(B @kbd{M-C-u} $B$K%7%s%\%k@\F,0z?t(B @code{a} -@code{b} $B$rM?$($k(B'' $B$H$$$&;v$G$9!#o$K$?$/$5$s$N$b$N$,$"$j$^$9!#9,1?$J;v$K!"$=$l(B -$B$i$O$9$Y$FF1$89=J8$r;H$$$^$9$N$G!"$"$^$j7y$JL\$K$O2q$o$J$$$G$7$g$&!#(B - -$B=qK!;EMM(B (format) $B;XDj$NNc$,$"$j$^$9(B ($B%0%k!<%W%P%C%U%!$h$j(B): -@samp{%M%S%5y: %(%g%)\n}$B!#$=$l$Oo$K=9$/!"$?$/$5$s$N%Q!<%;%s%H5-(B -$B9f$,$I$3$K$G$b$"$j$^$9!#(B - -@menu -* Formatting Basics:: $B=qK!;EMMJQ?t$O4pK\E*$K=qK!;XDjJ8;zNs$G$"$k!#(B -* Mode Line Formatting:: $B%b!<%I9T$N=qK!;EMMJQ?t$K4X$9$k$$$/$D$+$N5,B'!#(B -* Advanced Formatting:: $B?'!9$JJ}K!$G=PNO$r=$@5$9$k!#(B -* User-Defined Specs:: Gnus $B$K$"$J$?<+?H$N4X?t$r8F$P$;$k!#(B -* Formatting Fonts:: $B;EMM$rB?:L$GAGE($K8+$;$k!#(B -@end menu - -$B8=:_$N$H$3$m!"(Bgnus $B$O0J2<$N=qK!;EMMJQ?t$r;H$$$^$9(B: -@code{gnus-group-line-format}$B!"(B@code{gnus-summary-line-format}$B!"(B -@code{gnus-server-line-format}$B!"(B@code{gnus-topic-line-format}$B!"(B -@code{gnus-group-mode-line-format}$B!"(B@code{gnus-summary-mode-line-format}$B!"(B -@code{gnus-article-mode-line-format}$B!"(B -@code{gnus-server-mode-line-format}$B!"(B -@code{gnus-summary-pick-line-format}$B!#(B - -$B$3$l$iA4$F$N=qK!;EMMJQ?t$OG$0U$N(B elisp $B<0$G$"$k;v$b$G$-$^$9!#$=$N>l9g$O!"(B -$B$=$l$i$OMW5a$5$l$k9T$KA^F~$9$k$?$a$K(B @code{$BI>2A(B} $B$5$l$^$9!#(B - -@kindex M-x gnus-update-format -@findex gnus-update-format -Gnus $B$O$"$J$?<+?H$N=qK!;EMM;XDj$r:n$k2A(B} $B$7!"Ev$N;XDj$r99?7(B -$B$7!"7k2L$N(B lisp $B<0$r$l$NMWAG(B @samp{%} $B$OEv$N%P%C%U%!$,:n@.$5$l$k$H$-$K2?$i$+$NJ8;zNs$d(B -$BB>$N$b$N$GCV$-49$($i$l$^$9!#(B@samp{%5y} $B$O(B ``@samp{y} $B;XDj$rA^F~$7!"(B5$BJ8;z(B -$B$N>l=j$rF@$k$?$a$K6uGr$rF~$l$J$5$$(B'' $B$H$$$&;v$G$9!#(B - -$BIaDL$N(B C $B$d(B Emacs Lisp $B$N=qK!;EMM(B (format) $BJ8;zNs$HF1$8$h$&$K!"(B@samp{%} -$B$H=qK!;EMM$N7?$NJ8;z$N4V$N?tCM=$>~;R$O>o$K>/$J$/$H$b$=$ND9$5$K$J$k$h$&$K!"(B -$B=PNO$K(B @dfn{$B5M$a(B} $B$l$i$l$^$9!#(B@samp{%5y} $B$O$=$NItJ,$r>o$K(B ($B>/$J$/$H$b(B) 5 -$BJ8;z$ND9$5$K$J$k$h$&$K!":8$K6uGr$r5M$a$^$9!#$b$7(B @samp{%-5y} $B$H$9$l$P!"(B -$BBe$o$j$K1&B&$K5M$a9~$_$^$9!#(B - -$BFC$KD9$$CM$+$i$=$NItJ,$rJ]8n$9$k$?$a$K!"D9$5$r@)8B$7$?$$$H$b;W$&$G$7$g$&!#(B -$B$=$N$?$a$K$O!"(B@samp{%4,6y} $B$H$9$k;v$,$G$-$F!"$3$l$O$=$NNN0h$O7h$7$F(B6$BJ8;z(B -$B$rD6$($kD9$5$K$O$J$i$:!"(B4$BJ8;z$h$j>/$J$$D9$5$K$J$i$J$$$H$$$&;v$G$9!#(B - - -@node Mode Line Formatting -@subsection $B%b!<%I9T=qK!;EMM(B - -$B%b!<%I9T=qK!;EMMJQ?t(B ($B$9$J$o$A!"(B@code{gnus-summary-mode-line-format}) $B$O(B -$B0J2<$N(B2$B$D$N0c$$0J30$O!"%P%C%U%!9T$K4p$E$/=qK!;EMMJQ?t$H(B -(@pxref{Formatting Basics}) $BF1$8$h$&$J5,B'$K=>$$$^$9(B: - -@enumerate - -@item -$B:G8e$K2~9T(B (@samp{\n}) $B$,$"$C$F$O$J$j$^$;$s!#(B - -@item -$BFCJL$J(B @samp{%%b} $B;XDj$r%P%C%U%!L>$rI=<($9$k$?$a$K;H$&$3$H$,$G$-$^$9!#$(!<(B -$B$H!"K\Ev$O$=$l$O;XDj$G$O$J$$$N$G$9(B---@samp{%%} $B$OC1$K=qK!;EMM$,5!3#E*$K(B -$B@Z$jNv$/$N$r@Z$jH4$1$F(B @samp{%} $B$r$=$N$^$^EO$9$?$a$NJ}K!$G!"(BEmacs $B$,(B -@samp{%b} $B$r(B -$B$rI=<($7$J$5$$(B'' $B$H2re5i=qK!;EMM(B - -$B2?$i$+$NJ}K!$GNN0h$r8e$G=hM}$9$k$N$OIQHK$KLr$KN)$A$^$9!#ItJ,$r5M$a9~$`!"(B -$B@)8B$9$k!"@Z$j~;R(B} $B$r;H(B -$B$&;v$K$h$jC#@.$5$l$^$9!#$h$/$"$k%A%k%@;XDj$O$3$N$h$&$K8+$($k$+$b$7$l$^$;(B -$B$s(B @samp{%~(cut 3)~(ignore "0")y}$B!#(B - -$B$3$l$i$OM-8z$J=$>~;R$G$9(B: - -@table @code -@item pad -@itemx pad-left -$BMW5a$5$l$?D9$5$K$J$k$^$G!"NN0h$K6uGr$r:8B&$+$i5M$a9~$_$^$9!#(B - -@item pad-right -$BMW5a$5$l$?D9$5$K$J$k$^$G!"NN0h$K6uGr$r1&B&$+$i5M$a9~$_$^$9!#(B - -@item max -@itemx max-left -$B;XDj$5$l$?D9$5$K$J$k$h$&$K!"J8;z$r:8B&$+$i@Z$j.7?$N(B ISO0861 $BMM(B -$B<0$NF|IU$rJV$7$^$9(B---@samp{19960809T230410} $B$G$9!#$3$l$OH/2;$7$K$/$$$N$G!"(B -$B@$5*$rI=$9?t$H;~4V$r:o$.Mn$H$7$F!"(B6$BJ8;z$NF|IU$r;D$7$?$$$H;W$$$^$9!#$=$l(B -$B$O(B @samp{%~(cut-left 2)~(max-right 6)~(pad 6)o} $B$H$J$k$G$7$g$&!#(B($B@Z$jMn(B -$B$H$7(B (cutting) $B$O(B $B:GBg8B(B (maxing) $B$h$j@h$K$J$5$l$^$9$N$G!"7e$GAGE($K8+$((B -$B$k$h$&$K$9$k$?$a$KF|IU$,(B6$BJ8;z$h$j>/$J$/L5$/$J$i$J$$;v$rJ]>Z$9$k$?$a$K5M(B -$B$a9~$_(B (padding) $B$,I,MW$K$J$j$^$9!#(B) - -$BL5;k(B (ignore) $B$,:G=i$K$J$5$l$^$9!#$=$l$+$i@Z$jMn$H$7(B (cut) $B$,9T$o$l$^$9!#(B -$B$=$7$F!"$=$l$+$i:G8e$NA`:n!"5M$a9~$_(B (pad) $B$,9T$o$l$^$9!#(B - -$B$b$7$3$l$i$N>e5i;2>H$r$?$/$5$s;H$C$F$$$k$J$i!"(Bgnus $B$,$H$F$bCY$/$J$k$N$,(B -$B$o$+$k$G$7$g$&!#$3$l$O$"$J$?$N9T$N308+$KK~B-$7$?$H$-$K(B @kbd{M-x -gnus-compile} $B$r$N;XDj$+$i$N>pJs$HA4$/F1$8$h$&$K%P%C%U%!$K(B -$BA^F~$5$l$^$9!#4X?t$O0UL#$NL5$$CM$H6&$K8F$P$l$k;v$b$"$j$($^$9$N$G!"$=$l$N(B -$BBP:v$r$9$k$Y$-$G$9!#(B - -$B?7$7$$4X?t$rDj5A$7$J$$$G$b!"%A%k%@=$>~;R(B (@pxref{Advanced Formatting}) -$B$r;H$C$F$[$H$s$IF1$8;v$rC#@.$9$k;v$,$G$-$^$9!#Nc$G$9(B: @samp{%~(form -(count-lines (point-min) (point)))@@}$B!#$3$3$GM?$($i$l$?<0$OI>2A$5$l$F!"(B -$B8=:_$N9T?t$r$b$?$i$7!"$=$l$+$iA^F~$5$l$^$9!#(B - - -@node Formatting Fonts -@subsection $B=qK!;EMM%U%)%s%H(B - -$B%O%$%i%$%H$N$?$a$N;XDj$,$"$j!"$=$l$i$OA4$F$N=qK!;EMMJQ?t$K$h$C$F6&M-$5$l(B -$B$F$$$^$9!#(B@samp{%(} $B$H(B @samp{%)} $B;XDj$N4V$NJ8>O$OFCJL$J(B -@code{mouse-face} $B%W%m%Q%F%#$,@_Dj$5$l!"$=$l$O$=$3$K%^%&%9$N%]%$%s%?!<$r(B -$B$"$o$;$?$H$-$K(B (@code{gnus-mouse-face} $B$K$h$C$F(B) $B%O%$%i%$%H$5$l$k$3$H$K(B -$B$J$j$^$9!#(B - - -@samp{%@{} $B$H(B @samp{%@}} $B;XDj$N4V$NJ8>O$O(B @code{gnus-face-0} $B$r;H$C$FIa(B -$BDL$N%U%'%$%9$,@_Dj$5$l!"$=$l$O=i4|@_Dj$G(B @code{bold} $B$G$9!#$b$7(B -@samp{%@{1} $B$H$7$?$J$i!"Be$o$j$K(B @code{gnus-face-1} $B$rF@!"0J2eEy$N=qK!;EMM$r@_Dj$9$k!#(B -(setq gnus-group-line-format - "%M%S%3@{%5y%@}%2[:%] %(%1@{%g%@}%)\n") -@end lisp - -$B$"$J$?$,$3$N0F$r;H$C$F40A4$KFI$a$J$/$FHs>o$K2(B -$B$N%&%#%s%I%&$r>C$7$F!"(BEmacs $B$N2hLLA4BN$r@jM-$7$^$9!#$3$l$O=i4|@_Dj$G(B -@code{t} $B$G$9!#(B - -@vindex gnus-buffer-configuration -@code{gnus-buffer-configuration} $B$O$=$l$>$l$N(B gnus $B$N%P%C%U%!$,$I$N$/$i(B -$B$$$N6u4V$rM?$($i$l$k$Y$-$+$r8=$7$^$9!#$3$l$O$3$NJQ?t$NH4?h$G$9(B: - -@lisp -((group (vertical 1.0 (group 1.0 point) - (if gnus-carpal (group-carpal 4)))) - (article (vertical 1.0 (summary 0.25 point) - (article 1.0)))) -@end lisp - -$B$3$l$OO"A[%j%9%H$G$9!#(B@dfn{$B%-!<(B} $B$O2?$i$+$NF0:n$dB>$N$b$N$rG$L?$9$k%7%s(B -$B%\%k$G$9!#Nc$($P!"%0%k!<%W%P%C%U%!$rI=<($9$k$H$-$O!"%&%#%s%I%&@_Dj4X?t$O(B -@code{group} $B$r%-!<$H$7$F;H$$$^$9!#;HMQ2DG=$JL>A0$N40A4$J0lMw$O2<$K5s$2(B -$B$i$l$F$$$^$9!#(B - -@dfn{$BCM(B} ($B$9$J$o$A!"(B@dfn{$BJ,3d(B}) $B$O$=$l$>$l$N%P%C%U%!$,$I$l$/$i$$$r@j$a$k(B -$B$Y$-$+$r;XDj$7$^$9!#(B@code{article} $BJ,3d$rNc$Ke$N(B 25% $B$r@j$a(B -$B$k$Y$-$G!"$=$l$O5-;v%P%C%U%!(B (article buffer) $B$N>e$KG[CV$5$l$^$9!#$*5$$E(B -$B$-$NDL$j!"(B100% + 25% $B$OJN,2DG=$J(B3$B$DL\$NMWAG!"(B@code{point} $B$r;}$D%P%C%U%!$KCV$+$l$^$9!#(B -@code{frame} $BJ,3d$G$O!"%?%0(B @code{frame-focus} $B$,9=@.MWAG$G$"$k(B ($B$9$J$o(B -$B$A!"(B@code{point} $B%?%0$,B8:_$9$k$+$I$&$+$K$h$C$F!"%j%9%H$N(B3$BHVL\$+(B4$BHVL\$+(B -$B$KB8:_$9$kMWAG(B) $BMUJ,3d$r;}$D:G8e$NI{J,3d$,>GE@$rF@$k;v$K$J$j$^$9!#(B - -$B.?tE@?t$NBe$o$j$K@0?t$G$"$C$?$J$i!"$=$l$O3d9g$G$O$J(B -$B$/!"$I$N$/$i$$B?$/$N9T$r%P%C%U%!$,@j$a$k$Y$-$+$r;XDj$9$k$?$a$K;H$o$l$^$9!#(B - -$B$b$7(B @dfn{$BJ,3d(B} $B$,(B @code{$BI>2A(B} $B$5$l$k$b$N$N$h$&$K8+$($k$H$-$O(B ($BL@3N$K$9(B -$B$k$H(B---$BJ,3d$N(B @code{car} $B$,4X?t$+86;O4X?t(B (subr) $B$G$"$k$H$-$O(B)$B!"$3$NJ,3d(B -$B$O(B @code{$BI>2A(B} $B$5$l$^$9!#7k2L$,(B @code{nil} $B$G$J$$$J$i!"$=$l$OJ,3d$H$7$F(B -$BMQ$$$i$l$^$9!#$3$l$O!"(B@code{gnus-carpal} $B$,(B @code{nil} $B$G$"$l$P(B3$B$D$N%P%C(B -$B%U%!$,!"(B@code{gnus-carpal} $B$,(B @code{nil} $B$G$J$$$J$i!"(B4$B$D$N%P%C%U%!$,B8:_(B -$B$9$k$H$$$&;v$G$9!#(B - -$B$^$@J#;($G$O$J$$$G$9$C$F!)(B $B$=$l$G$O!"Bg$-$5$K$3$l$r;n$7$F$_$F2<$5$$(B: - -@lisp -(article (horizontal 1.0 - (vertical 0.5 - (group 1.0) - (gnus-carpal 4)) - (vertical 1.0 - (summary 0.25 point) - (summary-carpal 4) - (article 1.0)))) -@end lisp - -$B$*$)$C$H!#(B2$B$D$N%P%C%U%!$KIT;W5D$J(B 100% $B%?%0$,IU$$$F$$$^$9!#$=$7$F!"$"$N(B -@code{horizontal} $B$C$F$$$&$b$N$O2?$G$7$g$&!)(B - -$B$b$7J,3d$N0l$D$N:G=i$NMWAG$,(B @code{horizontal} $B$G$"$C$?$J$i!"(Bgnus $B$O(B $B%&%#(B -$B%s%I%&$r?eJ?$KJ,3d$7!"(B2$B$D$N%&%#%s%I%&$r2#$KJB$Y$^$9!#$3$l$i$N$=$l$>$l$N(B -$B>.JR$NCf$G$O!"A4$F$rIaDL$NN.57$G9T$&;v$,$G$-$^$9!#(B@code{horizontal} $B$N8e(B -$B$N?t;z$O!"$3$N>.JR$K2hLL$N$I$l$/$i$$$N3d9g$,M?$($i$l$k$+$r;XDj$7$^$9!#(B - -$B$=$l$>$l$NJ,3d$G$O!"(B100% $B$N%?%0$r;}$DMWAG$,(B @emph{$BI,$:(B} $B0l$D$"$kI,MW$,$"(B -$B$j$^$9!#J,3d$O7h$7$F@53N$K$O9T$o$l$^$;$s$N$G!"$3$N%P%C%U%!$,J,3d$+$i;D$5(B -$B$l$?A4$F$N9T$r@jNN$7$^$9!#(B - -$B$b$&>/$7@5<0$K$9$k$?$a$K!"$3$3$KM-8z$JJ,3d$,$I$N$h$&$K$J$k$+$NDj5A$,$"$j(B -$B$^$9(B: - -@example -split = frame | horizontal | vertical | buffer | form -frame = "(frame " size *split ")" -horizontal = "(horizontal " size *split ")" -vertical = "(vertical " size *split ")" -buffer = "(" buffer-name " " size *[ "point" ] *[ "frame-focus"] ")" -size = number | frame-params -buffer-name = group | article | summary ... -@end example - -$B@)8B$K$O!"(B@code{frame} $B$O:G>e0L$NJ,3d$H$7$F$7$+8=$l$k;v$,$G$-$J$$$H$$$&(B -$B$b$N$,$"$j$^$9!#(B@var{form} $B$OM-8z$JJ,3d$rJV$9(B Emacs Lisp $B$N<0(B (form) $B$G(B -$B$J$1$l$P$J$j$^$;$s!#$=$l$>$l$NJ,3d$O40A4$K:F5"E*$G!"G$0U$N?t$N(B -@code{vertical} $B$H(B @code{horizontal} $BJ,3d$r4^$`;v$,$G$-$^$9!#(B - -@vindex gnus-window-min-width -@vindex gnus-window-min-height -@cindex window height -@cindex window width -$B@5$7$$Bg$-$5$r8+$D$1$k$N$O>/$7J#;($G$9!#$I$N%&%#%s%I%&$b(B -@code{gnus-window-min-height} ($B=i4|CM(B 1) $B$NJ8;z$N9b$5$h$j$b>.$5$/$F$O$J(B -$B$i$:!">/$J$/$H$b(B @code{gnus-window-min-width} ($B=i4|CM(B 1) $B$NJ8;zI}$G$J$/(B -$B$F$O$J$j$^$;$s!#(BGnus $B$OJ,3d$rE,MQ$9$kA0$K$3$l$r6/@)$7$h$&$H;n$_$^$9!#$b(B -$B$7IaDL$N(B Emacs $B$N%&%#%s%I%&$NI}(B/$B9b$5@)8B$r;H$$$?$$$J$i!"$3$N(B2$B$D$NJQ?t$r(B -@code{nil} $B$K$9$k$@$1$GNI$$$G$9!#(B - -$B$b$7(B Emacs $B$NMQ8l$K$J$8$s$G$$$J$$$N$J$i!"(B@code{horizontal} $B$H(B -@code{vertical} $BJ,3d$O!"4|BT$9$k$b$N$HH?BP$NF0:n$r$9$k$G$7$g$&!#(B -@code{horizontal} $BJ,3d$NCf$N%&%#%s%I%&$O2#$KJB$s$GI=<($5$l!"(B -@code{vertical} $BJ,3d$NCf$N%&%#%s%I%&$O>e2<$KI=<($5$l$^$9!#(B - -@findex gnus-configure-frame -$B%&%#%s%I%&$N@_CV$K4X$7$F@\(B -@code{gnus-configure-frame} $B$r8F$V$3$H$G$9!#$3$l$O%P%C%U%!$rJ,3d$9$k$H$-(B -$B$KA4$F$NK\Ev$N;E;v$r$9$k4X?t$G$9!#2<$N$b$N$O(B5$B%&%#%s%I%&$N$H$F$b$P$+$2$?(B -$B@_Dj$G$9!#(B2$B$D$r%0%k!<%W%P%C%U%!$K!"(B3$B$D$r5-;v%P%C%U%!$N$?$a$K=<$F$^$9!#(B -($B$=$l$O$P$+$2$F$$$k$H8@$C$?$G$7$g!#(B) $B$b$72<$NJ8$r(B @code{$BI>2A(B} $B$9$k$H!"Ia(B -$BDL$N(B gnus $B$N7PO)$r;H$o$J$$$G!"$9$0$K$=$l$,$I$N$h$&$K8+$($k$+$N9M$($rF@$k(B -$B;v$,$G$-$^$9!#K~B-$9$k$^$G$=$l$GM7$s$G!"$=$l$+$i(B -@code{gnus-add-configuration} $B$r;H$C$F?7$7$$A[A|$r%P%C%U%!@_Dj%j%9%H$K2C(B -$B$($F2<$5$$!#(B - -@lisp -(gnus-configure-frame - '(horizontal 1.0 - (vertical 10 - (group 1.0) - (article 0.3 point)) - (vertical 1.0 - (article 1.0) - (horizontal 4 - (group 1.0) - (article 10))))) -@end lisp - -$B$$$/$D$+$N%U%l!<%`$bM_$7$$$+$b$7$l$^$;$s!#4JC1$G$9(B---@code{frame} $BJ,3d$r(B -$B;H$&$@$1$G$9(B: - -@lisp -(gnus-configure-frame - '(frame 1.0 - (vertical 1.0 - (summary 0.25 point frame-focus) - (article 1.0)) - (vertical ((height . 5) (width . 15) - (user-position . t) - (left . -1) (top . 1)) - (picon 1.0)))) - -@end lisp - -$B$3$NJ,3d$N7k2L$O!":G=i(B ($B$b$7$/$O!"(B``$B.$5$JDI2C$N%U%l!<%`$,(B picon $B$rI=<($9$k$?$a$K:n$i$l$k(B -$B$H$$$&;v$K$J$j$^$9!#$4Mw$NDL$j!"IaDL$N(B @code{1.0} $B:G>e0L;XDj$NBe$o$j$K!"(B -$B$=$l$>$l$NDI2C$NJ,3d$,%U%l!<%`%Q%i%a!<%?O"A[%j%9%H$rBg$-$5;XDj$H$7$F;}$?(B -$B$J$1$l$P$J$j$^$;$s!#(B@xref{Frame Parameters, , Frame Parameters, elisp, -The GNU Emacs Lisp Reference Manual}. XEmacs $B$G$O!"%U%l!<%`%W%m%Q%F%#%j(B -$B%9%H$b;H$($^$9(B---$BNc$($P!"(B@code{(height 5 width 15 left -1 top 1)} $B$O$=$N(B -$B$h$&$J%Q%i%a!<%?%j%9%H$G$9!#(B - -$B$3$l$O(B @code{gnus-buffer-configuration} $B$K;EMM2DG=$J%-!<$N0lMw$G$9(B: - -@code{group}$B!"(B@code{summary}$B!"(B@code{article}$B!"(B@code{server}$B!"(B -@code{browse}$B!"(B@code{message}$B!"(B@code{pick}$B!"(B@code{info}$B!"(B -@code{summary-faq}$B!"(B@code{edit-group}$B!"(B@code{edit-server}$B!"(B -@code{edit-score}$B!"(B@code{post}$B!"(B@code{reply}$B!"(B@code{forward}$B!"(B -@code{reply-yank}$B!"(B@code{mail-bounce}$B!"(B@code{draft}$B!"(B@code{pipe}$B!"(B -@code{bug}$B!"(B@code{compose-bounce}$B!"(B@code{score-trace}$B!#(B - -$B%-!<(B @code{message} $B$O(B @code{gnus-group-mail} $B$H(B -@code{gnus-summary-mail-other-window} $B$NN>J}$G;H$o$l$k;v$KCm0U$7$F2<$5$$!#(B -$B$b$7(B2$B$D$r6hJL$9$k$[$&$,K>$^$7$$$J$i!"$3$N$h$&$JJ*$r;H$&;v$,$G$-$^$9(B: - -@lisp -(message (horizontal 1.0 - (vertical 1.0 (message 1.0 point)) - (vertical 0.24 - (if (buffer-live-p gnus-summary-buffer) - '(summary 0.5)) - (group 1.0))))) -@end lisp - -@findex gnus-add-configuration -$BJQ?t(B @code{gnus-buffer-configuration} $B$O$H$F$bD9$/J#;($J$N$G!"C10l$N@_Dj(B -$B$NJQ99$r4JC1$K$9$k$?$a$N4X?t$,$"$j$^$9(B: @code{gnus-add-configuration} $B$G(B -$B$9!#$b$7!"Nc$($P!"(B@code{article} $B$N@_Dj$rJQ$($?$$$N$J$i!"o$K(B ``$B@5$7$$(B'' $B%&%#%s%I%&@_Dj$r6/@)(B -$B$7$?$$$N$G$"$l$P!"(B@code{gnus-always-force-window-configuration} $B$r(B -@code{nil} $B$G$J$$CM$K@_Dj$9$k;v$,$G$-$^$9!#(B - - -@node Faces and Fonts -@section $B%U%'%$%9$H%U%)%s%H(B -@cindex faces -@cindex fonts -@cindex colors - -$B%U%)%s%H$H%U%'%$%9$rO.$k$N$OHs>o$KFq$7$+$C$?$N$G$9$,!":#F|$G$OHs>o$K4JC1(B -$B$G$9!#C1$K(B @kbd{M-x customize-face} $B$H$d$C$F!"JQ$($?$$%U%'%$%9$rA*$S=P$7(B -$B$F!"I8=`$N%+%9%?%^%$%:%$%s%?!<%U%'!<%9$r;H$C$FJQ99$9$k;v$,$G$-$^$9!#(B - - -@node Compilation -@section $B%3%s%Q%$%k(B -@cindex compilation -@cindex byte-compilation - -@findex gnus-compile - -$B$"$N9T=qK!;EMM;XDjJQ?t$r3P$($F$$$^$9$+!)(B @code{gnus-summary-line-format}$B!"(B -@code{gnus-group-line-format} $B$J$I$J$I$G$9!#$5$F!"(Bgnus $B$O$b$A$m$s$3$l$i(B -$B$NJQ?t$,$I$N$h$&$J$b$N$G$bCm0U$7$^$9$,!"IT1?$J;v$K!"$=$l$i$rJQ99$9$k$H!"(B -$BBgJQ=EBg$JB.EYDc2<$r0z$-5/$3$9;v$K$J$j$^$9!#(B ($B$3$l$i$NJQ?t$N=i4|CM$O$=$l(B -$B$i$K4XO"IU$1$i$l$?%P%$%H%3%s%Q%$%k$5$l$?4X?t$r;}$C$F$$$^$9$,!"MxMQo$K:G?7$N(B -$B$b$N$K$7$F$*$/$+$r;XDj$7$^$9!#$=$l$O%7%s%\%k$N%j%9%H$G$9!#;H$&;v$N$G$-$k(B -$B%7%s%\%k$O(B @code{group} $B!"(B@code{article}$B!"(B@code{summary}$B!"(B@code{server}$B!"(B -@code{browse}$B!"(B@code{tree} $B$J$I$G$9!#$b$7BP1~$9$k%7%s%\%k$,B8:_$9$k$H!"(B -gnus $B$O3:Ev$9$k$G$"$m$&>pJs$G%b!<%I9T$r99?7$7$^$9!#$3$NJQ?t$,(B @code{nil} -$B$G$"$k$J$i!"2hLL$N:FIA2h$O$b$C$HB.$$$G$7$g$&!#(B - -@cindex display-time - -@vindex gnus-mode-non-string-length -$B=i4|@_Dj$G$O!"(Bgnus $B$O35N,%P%C%U%!$H5-;v%P%C%U%!$N%b!<%I9T$K8=:_$N5-;v$N(B -$B>pJs$rI=<($7$^$9!#(BGnus $B$,I=<($7$?$$>pJs(B ($BNc$($P!"5-;v$NI=Bj(B) $B$O$7$P$7$P(B -$B%b!<%I9T$h$j$bD9$$$3$H$,$"$k$N$G!"$I$3$+$G@Z$jMn$H$5$l$J$1$l$P$J$j$^$;$s!#(B -$BJQ?t(B @code{gnus-mode-non-string-length} $B$O$=$N9T$NB>$NMWAG(B ($B$9$J$o$A!">p(B -$BJs$G$J$$ItJ,(B) $B$,$I$N$/$i$$$ND9$5$G$"$k$+$r;XDj$7$^$9!#$b$7%b!<%I9T$KDI2C(B -$B$NMWAG$rF~$l$?$J$i!"$3$NJQ?t$r=$@5$9$kI,MW$,$"$j$^$9(B: - -@c Hook written by Francesco Potorti` -@lisp -(add-hook 'display-time-hook - (lambda () (setq gnus-mode-non-string-length - (+ 21 - (if line-number-mode 5 0) - (if column-number-mode 4 0) - (length display-time-string))))) -@end lisp - -$B$b$7$3$NJQ?t$,(B @code{nil} $B$G$"$k$J$i(B ($B$3$l$,=i4|CM$G$9$,(B)$B!"%b!<%I9T$O@Z(B -$B$jMn$H$5$l$:!"5M$a9~$_$b$5$l$^$;$s!#=i4|@_Dj$O!"%P%C%U%!$N40A4$J%Q!<%;%s(B -$B%HI=<($5$($b%b!<%I9T$+$iDI$$$d$i$l$k2DG=@-$b$"$j$^$9$N$G!"$*$=$i$/K>$^$7(B -$B$$@_Dj$G$O$J$$$H$$$&;v$KCm0U$7$F2<$5$$!#MxMQl9g$O!"$3$N$h$&$K$9$k;v$,$G$-$^$9(B: - -@lisp -(setq gnus-visual '(article-highlight menu)) -@end lisp - -$B$b$7%O%$%i%$%H$@$1$G!"%a%K%e!<$NN`$OM_$7$/$J$$$H$-$O!"$NA4$F$N%P%C%U%!$N308+$K1F6A$9$kAm9gE*$JJQ?t$O(B: - -@table @code -@item gnus-mouse-face -@vindex gnus-mouse-face -$B$3$l$O(B gnus $B$G%^%&%9$N%O%$%i%$%H$K;H$o$l$k%U%'%$%9(B ($B$9$J$o$A!"%U%)%s%H(B) -$B$G$9!#(B@code{gnus-visual} $B$,(B @code{nil} $B$G$"$k$H!"%^%&%9%O%$%i%$%H$O$J$5(B -$B$l$^$;$s!#(B - -@end table - -$BA4$/0c$C$?%a%K%e!<$r:n@.$9$k$?$a$K4XO"$9$k%U%C%/$,$"$j$^$9(B: - -@table @code - -@item gnus-article-menu-hook -@vindex gnus-article-menu-hook -$B5-;v%b!<%I(B (article mode) $B%a%K%e!<$r:n@.$7$?8e$K8F$P$l$k%U%C%/$G$9!#(B - -@item gnus-group-menu-hook -@vindex gnus-group-menu-hook -$B%0%k!<%W%b!<%I(B (group mode) $B%a%K%e!<$r:n@.$7$?8e$K8F$P$l$k%U%C%/$G$9!#(B - -@item gnus-summary-menu-hook -@vindex gnus-summary-menu-hook -$B35N,%b!<%I(B (summary mode) $B%a%K%e!<$r:n@.$7$?8e$K8F$P$l$k%U%C%/$G$9!#(B - -@item gnus-server-menu-hook -@vindex gnus-server-menu-hook -$B%5!<%P!<%b!<%I(B (server mode) $B%a%K%e!<$r:n@.$7$?8e$K8F$P$l$k%U%C%/$G$9!#(B - -@item gnus-browse-menu-hook -@vindex gnus-browse-menu-hook -$B354Q%b!<%I(B (browse mode) $B%a%K%e!<$r:n@.$7$?8e$K8F$P$l$k%U%C%/$G$9!#(B - -@item gnus-score-menu-hook -@vindex gnus-score-menu-hook -$B%9%3%"%b!<%I(B (score mode) $B%a%K%e!<$r:n@.$7$?8e$K8F$P$l$k%U%C%/$G$9!#(B - -@end table - - -@node Buttons -@section $B%\%?%s(B -@cindex buttons -@cindex mouse -@cindex click - -$B:G6a$G$O!":G?7N.9T$N%^%&%9(B @dfn{mouse} $BAuCV$,!"$A$c$s$H$7$?A`:nK!$r3X$S(B -$B$?$,$i$J$$%J%&$J%d%s%0$N4V$GBg?M5$$G$9!#$=$l$G$O!";d$,(BTops 20 $B%7%9%F%`>e(B -$B$G(B Emacs $B$r;H$C$F$$$?:"$N(B '89 $BG/$N2F$r;W$$5/$3$7$F$_$^$7$g$&!#(B300 $B?M$NMx(B -$BMQe$G!"$_$s$J$,(B Simula $B%3%s%Q%$%i$rAv$i$;$F$$$^$7$?!#(B -$B$"$"!"$P$+$P$+$7$$(B! - -$B$[$s$H$K$=$&$@$M!#(B - -@vindex gnus-carpal -$B$^$:$G$9$M!"(B@code{gnus-carpal} $B$r(B @code{t} $B$K@_Dj$9$k$3$H$K$h$C(B -$B$F!"%/%j%C%/$9$k$@$1$G2?$G$b$G$-$k%\%?%s$@$i$1$N%P%C%U%!$r(B gnus -$B$KI=<($5$;$k$3$H$,$G$-$^$9!#$H$C$F$b4JC1$G$9!"$[$s$H$K!#;X05NEK!(B -$B$N@h@8$K65$($F$"$2$F!#(B($BLuCm(B: carpal $B$H$O$K$b2?$+$=$&$$$C$?$3$H$G$9!#(B - -Gnus $B$O$5$^$6$^$J@)8f;R(B @dfn{handlers} $B$rDj5A$9$k$3$H$K$h$C$F$=(B -$B$N$h$&$J$3$H$r2DG=$K$7$^$9!#3F@)8f;R$O;0$D$NMWAG$+$i@.$j$^$9!#(B -@var{$B4X?t(B}$B!"(B@var{$B;~4V(B}$B!"(B@var{$B6uE>(B} $B%Q%i%a!<%?$G$9!#(B - -$B0J2<$O(B Emacs $B$,2?$b$7$J$$6uE>>uBV$,;0==J,B3$$$?$H$-$K@\B3$r@ZCG(B -$B$9$k@)8f;R$NNc$G$9!#(B - -@lisp -(gnus-demon-close-connections nil 30) -@end lisp - -$B0J2<$O(B Emacs $B$,2?$b$7$F$$$J$$$H$-!"0l;~4VKh$K(B PGP $B%X%C%@!<$rAv::(B -$B$9$k@)8f;R$G$9!#(B - -@lisp -(gnus-demon-scan-pgp 60 t) -@end lisp - -$B$3$N(B @var{$B;~4V(B} $B%Q%i%a!<%?$H$=$7$F(B @var{$B6uE>(B} $B%Q%i%a!<%?$O!"4qL/$G$+$DAG(B -$B@2$i$7$$J}K!$G0l=o$KF0:n$7$^$9!#4pK\E*$K$O!"(B@var{$B6uE>(B} $B$,(B @code{nil} $B$N(B -$B;~$K$O$3$N4X?t$O(B @var{$B;~4V(B} $BJ,Kh$K8F$S=P$5$l$^$9!#(B - -$B$b$7(B @var{$B6uE>(B} $B$,(B @code{t} $B$G$"$l$P!"$3$N4X?t$O(B Emacs $B$,2?$b$7(B -$B$F$$$J$$;~$K8B$j!"(B@var{$B;~4V(B} $BJ,8e$K8F$S=P$5$l$^$9!#0lC6(B Emacs $B$,(B -$B$:$C$H6uE>>uBV$K$J$C$?8e$O!"$3$N4X?t$O(B @var{$B;~4V(B} $BJ,Kh$K8F$S=P$5(B -$B$l$^$9!#(B - -@var{$B6uE>(B} $B$,?t$G(B @var{$B;~4V(B} $B$b?t$G$"$k>l9g!"$3$N4X?t$O!"(B Emacs -$B$N6uE>>uBV$,(B @var{$B6uE>(B} $BJ,B3$$$?;~$K8B$j!"(B@var{$B;~4V(B} $BJ,Kh$K8F$S(B -$B=P$5$l$^$9!#(B - -@var{$B6uE>(B} $B$,?t$G(B @var{$B;~4V(B} $B$,(B @code{nil} $B$N>l9g!"$3$N4X?t$O!"(B -Emacs $B$N6uE>>uBV$,(B @var{$B6uE>(B} $BJ,B3$/EY$K0lEY8F$S=P$5$l$^$9!#(B - -$B$=$7$F(B @var{$B;~4V(B} $B$,J8;zNs$N>l9g$O!"(B@samp{07:31} $B$N$h$&$J7A<0$G(B -$B$J$1$l$P$J$i$:!"$3$N4X?t$OKhF|$=$N:"$N;~4V$K$J$k$H0lEY8F$S=P$5$l(B -$B$^$9!#$b$A$m$s!"(B@var{$B6uE>(B} $B%Q%i%a!<%?$GF0:n$,JQ$o$j$^$9!#(B - -@vindex gnus-demon-timestep -($B$3$3$G(B ``$BJ,(B'' $B$H8@$C$?$H$-!"$=$l$O$9$k$h$&$K@_Dj$9$k$K$O!"(B -@code{gnus-use-demon} $B$r(B @code{t} $B$K@_Dj$7$J$-$c$$$1$J$$$s$@$1$I(B -$B$M!#(B - -$B$H$$$&$o$1$G!"@)8f;R$rDI2C$7$?$1$l$P!"(B @file{.gnus} $B%U%!%$%k$K!"(B -$B0J2<$N$h$&$J$b$N$r=q$/$3$H$,$G$-$^$9!#(B - -@findex gnus-demon-add-handler -@lisp -(gnus-demon-add-handler 'gnus-demon-close-connections 30 t) -@end lisp - -@findex gnus-demon-add-nocem -@findex gnus-demon-add-scanmail -@findex gnus-demon-add-rescan -@findex gnus-demon-add-scan-timestamps -@findex gnus-demon-add-disconnection -$B$3$N$?$a$N4{@=4X?t$,$$$/$D$+:n@.$5$l$F$$$^$9!#(B -@code{gnus-demon-add-nocem}$B!"(B -@code{gnus-demon-add-disconnection}$B!"(B -@code{gnus-demon-add-nntp-close-connection}$B!"(B -@code{gnus-demon-add-scan-timestamps}$B!"(B -@code{gnus-demon-add-rescan}$B!"(B@code{gnus-demon-add-scanmail} $B$G(B -$B$9!#$3$l$i$NG=NO$,M_$7$1$l$P!"C1$K$3$l$i$N4X?t$r(B @file{.gnus} $B$K(B -$BF~$l$F$/$@$5$$!#(B - -@findex gnus-demon-init -@findex gnus-demon-cancel -@vindex gnus-demon-handlers -$B$b$7(B @code{gnus-demon-handlers} $B$G@)8f;R$rD>@\DI2C$7$?>l9g$K$O!"(B -$B$=$l$r8z$+$;$k$?$a$K(B @code{gnus-demon-init} $B$rC$9$K$O!"(B@code{gnus-demon-cancel} $B4X?t$r;H(B -$B$&$3$H$,$G$-$^$9!#(B - -$B%G!<%b%s$NDI2C$O!"$d$j$9$.$k$N$O$H$C$F$b$*9T57$N$h$/$J$$$3$H$G$9!#(B -$BA4$F$N%5!<%P!<$+$iA4$F$N%K%e!<%9$H%a!<%k$rFsICKh$KD4$Y$^$o$94X?t(B -$B$rIU$12C$($A$c$C$?$j$9$k$H!"$I$s$JN)GI$J%7%9%F%`$G$b4V0c$$$J$/$*(B -$BJ'$$H"$K$7$F$7$^$$$^$9!#$=$&F0$/$s$@$b$s!#(B - - -@node NoCeM -@section NoCeM -@cindex nocem -@cindex spam - -$B%9%Q%`(B @dfn{Spam} $B$H$O!"F1$85-;v$r2?2s$b2?2s$b2?2s$bEj9F$9$k$3$H(B -$B$G$9!#%9%Q%`$O0-$$$3$H$G$9!#%9%Q%`$O6'0-$G$9!#(B - -$B%9%Q%`$ODL>o0lF|$+$=$3$i$G!"$5$^$6$^$JH?%9%Q%`5!4X$+$iC$7$5(B -$B$l$^$9!#$3$l$i$N5!4X$ODL>o0l=o$K!"(B@dfn{NoCeM} $B%a%C%;!<%8$bAw?.$7(B -$B$^$9!#(B@dfn{NoCeM} $B$O(B ``no see-'em'' ($BH`$i$r8+$?$/$J$$(B)$B$HH/2;$5$l!"(B -$B0UL#$O$=$NL>A0$NDL$j$G$9(B --- $B$3$N%a%C%;!<%8$O!":a$rHH$7$F$$$k5-(B -$B;v$r!"$D$^$j!">C$7$F$7$^$$$^$9!#(B - -$B$I$&$;$=$N5-;v$,C$7$5$l$F$7$^$&$N$J$i!"$3$l$i(B NoCeM $B%a%C%;!<(B -$B%8$O2?$K;H$o$l$k$N$G$7$g$&(B? $B$"$k%5%$%H$G$OC$7%a%C%;!<%8$r0z(B -$B$-C$7%a%C%;!<%8$N$_$7(B -$B$+0z$-C$75n$j$^$9!#(B - -$B$b$A$m$s!"$3$l$i$r%+%9%?%^%$%:$9$k$?$a$NJQ?t$,$$$/$D$+$"$j$^$9!#(B - -@table @code -@item gnus-use-nocem -@vindex gnus-use-nocem -$B$3$NJQ?t$r(B @code{t} $B$K@_Dj$9$k$3$H$G3hF0$r3+;O$5$;$^$9!#=i4|@_Dj(B -$B$G$O(B @code{nil} $B$G$9!#(B - -@item gnus-nocem-groups -@vindex gnus-nocem-groups -Gnus $B$O$3$N%0%k!<%W%j%9%H$+$i(B NoCeM $B%a%C%;!<%8$rC5$7$^$9!#=i4|@_(B -$BDjCM$O(B @code{("news.lists.filters" "news.admin.net-abuse.bulletins" -"alt.nocem.misc" "news.admin.net-abuse.announce")} $B$G$9!#(B - -@item gnus-nocem-issuers -@vindex gnus-nocem-issuers -NoCeM $B%a%C%;!<%8$rH/9T$9$k?M$O$?$/$5$s$$$^$9!#$3$N%j%9%H$G$O!"C/(B -$B$N8@$&$3$H$K=>$$$?$$$+$r;XDj$7$^$9!#=i4|@_DjCM$O(B @code{("Automoose-1" -"rbraver@@ohww.norman.ok.us" "clewis@@ferret.ocunix.on.ca" -"jem@@xpat.com" "snowhare@@xmission.com" "red@@redpoll.mrfs.oh.us -(Richard E. Depew)")} $B$G$9!#H`$i$O$_$s$J!"N)GI$G9b7i$J;TL1$G$9!#(B - -$B$3$N%j%9%H$K4^$a$i$l$kM-L>$JH?%9%Q%`2H$O0J2<$G$9!#(B - -@table @samp -@item clewis@@ferret.ocunix.on.ca; -@cindex Chris Lewis -Chris Lewis --- $BC$7$F$$$^$9!#(B - -@item Automoose-1 -@cindex CancelMoose[tm] -$B<+F01?E>$N(B CancelMoose[tm]$B!#(B CancelMoose[tm] $B$O%N%k%&%'!C$7$H!"(Bspew ($B5UN.5-;v(B) $B$r:o=|$7$F$$(B -$B$^$9!#(B -@end table - -$B$3$l$iA4$F$N?M!9$N(B NoCeM $B%a%C%;!<%8$KN10U$9$kI,MW$O$"$j$^$;$s(B --- $B8@$&$3(B -$B$H$rJ9$-$?$$?M$@$1$G$$$$$s$G$9!#$^$?$=$N?M$+$i$N(B NoCeM$B%a%C%;!<%8A4$F$r$l/$O(B -$B87L)$J!"DxEY$M!#$?$$$F$$$O>/$@$1$I(B)$B!#NI$/;H$o$l$kr7o(B ...)} $BMWAG$r;H$&I,MW$,$"$j(B -$B$^$9!#3F>r7o$OJ8;zNs(B ($B;H$$$?$$l9g$O(B @var{$BJ8;zNs(B} $B$O;H(B -$B$$$?$/$J$$l9g$K$O!"(B - -@lisp -("clewis@@ferret.ocunix.on.ca" ".*" (not "troll")) -@end lisp - -$B0lJ}!"H`$N(B @samp{spam} $B$H(B @samp{spew} $B%a%C%;!<%80J30$O2?$b$7$?$/(B -$B$J$1$l$P!"0J2<$N$h$&$K$G$-$^$9!#(B - -@lisp -("clewis@@ferret.ocunix.on.ca" (not ".*") "spew" "spam") -@end lisp - -$B$3$N;XDj$O:8$+$i1&$KE,MQ$5$l$^$9!#(B - - -@item gnus-nocem-verifyer -@vindex gnus-nocem-verifyer -@findex mc-verify -$B$3$l$O(B NoCeM $BH/9TZL@$9$k4X?t$G$J(B -$B$/$F$O$J$j$^$;$s!#=i4|@_Dj$G$O(B @code{mc-verify} $B$G$"$j!"$3$l$O(B -Mailcrypt $B4X?t$G$9!#$b$7$3$l$,Hs>o$KCY$/$F!"$"$J$?$,>ZL@7k2L$r5$(B -$B$K$7$J$$(B ($B$3$l$O$?$V$s4m81$G$9(B) $B$N$G$"$l$P!"$3$NJQ?t$r(B -@code{nil} $B$K$9$k$3$H$,$G$-$^$9!#(B - -$B$b$7=pL>:Q$_$N(B NoCeM $B%a%C%;!<%8$r>ZL@:Q$_!"L$=pL>$N%a%C%;!<%8$r(B -$BL$>ZL@(B($B$G$b$=$l$r;H$&(B)$B$H$7$?$$$N$J$i!"0J2<$N$h$&$K$9$k$3$H$,$G$-(B -$B$^$9!#(B - -@lisp -(setq gnus-nocem-verifyer 'my-gnus-mc-verify) - -(defun my-gnus-mc-verify () - (not (eq 'forged - (ignore-errors - (if (mc-verify) - t - 'forged))))) -@end lisp - -$B$^$"!"$3$l$O$?$V$s4m81$G$7$g$&$1$I$M!#(B - -@item gnus-nocem-directory -@vindex gnus-nocem-directory -$B$3$l$O(B gnus $B$,(B NoCeM $B%-%c%C%7%e%U%!%$%k$rJ]B8$9$k>l=j$G$9!#=i4|(B -$B@_DjCM$O(B @file{~/News/NoCeM/} $B$G$9!#(B - -@item gnus-nocem-expiry-wait -@vindex gnus-nocem-expiry-wait -$B8E$$(B NoCeM $B9`L\$r%-%c%C%7%e$+$i>C$9$^$G$NF|?t!#=i4|@_DjCM$O(B 15 -$B$G$9!#$3$l$rC;$/$9$k$[$I(B gnus $B$OB.$/$J$j$^$9$,!"8E$$%9%Q%`$r8+$k(B -$B$3$H$K$J$C$F$7$^$&$+$b$7$l$^$;$s!#(B - -@end table - -NoCeM $B$r;H$&$H!"$b$7$+$9$k$H%a%b%j6t$$$K$J$k$+$b$7$l$^$;$s!#$"$J(B -$B$?$,$?$/$5$s$N@8$-$?%0%k!<%W(B ($B$D$^$j9XFI$"$k$$$OHs9XFI%0%k!<%W(B) -$B$r;}$C$F$$$k$N$J$i!"(BEmacs $B%W%m%;%9$OBg$-$/$J$C$F$7$^$&$G$7$g$&!#(B -$B$b$7$3$l$,LdBj$G$"$l$P!"Hs9XFI$N%0%k!<%W$rA4It(B ($B$"$k$$$O$=$NB?$/(B -$B$r(B) $B>C$75n$C$F$7$^$C$?J}$,NI$$$G$9(B (@pxref{Subscription -Commands})$B!#(B - - -@node Undo -@section $B$d$jD>$7(B -@cindex undo - -$B$7$,$G$-$k$H!"$H$F$bJXMx$G$9!#IaDL$N(B Emacs -$B%P%C%U%!$G$O!"$3$l$O==J,4JC1$G$9(B --- $BC1$K(B @code{undo} $B%\%?%s$r2!(B -$B$9$@$1$G$9!#$7$+$7(B gnus $B$N%P%C%U%!$G$O!"$3$l$O4JC1$G$O$"$j$^$;$s!#(B - -Gnus $B$,%P%C%U%!!C5n$9$k$N$O!"$=$N9T$O>C$(5n$j$^$9$,!"$=$l$O$7$O!"DL>o$N(B Emacs -$B$N(B @code{undo} $B4X?t$G$O9T$J$&$3$H$,$G$-$^$;$s!#(B - -Gnus $B$O!"MxMQ$72DG=$J(B -$B%-!<4X?t$O6O$+$7$+Ds6!$7$F$$$^$;$s!#$3$l$i$O!"%0%k!<%W$N:o=|!"%0%k!<(B -$B%W$NE=$jIU$1!"%0%k!<%W$N4{FI5-;v$N%j%9%H$NJQ99!"$=$l$@$1$J$s$G$9!#(B -$B>-Mh$O$b$C$H4X?t$,DI2C$5$l$k$+$b$7$l$^$;$s$,!"4X?t$NDI2C$O$=$l$>(B -$B$lJ]B8$9$k$Y$-%G!<%?$rA}$d$9$3$H$K$J$k$N$G!"(Bgnus $B$O7h$7$F40A4$d(B -$B$jD>$72DG=$K$O$J$i$J$$$G$7$g$&!#(B - -@findex gnus-undo-mode -@vindex gnus-use-undo -@findex gnus-undo -$B$d$jD>$75!G=$O(B @code{gnus-undo-mode} $B%^%$%J!<%b!<%I$K$h$C$FDs6!(B -$B$5$l$^$9!#$3$l$O(B @code{gnus-use-undo} $B$,(B @code{nil} $B0J30$G$"$l$P(B -$B;HMQ$5$l!"$3$l$,=i4|@_Dj$G$9!#(B@kbd{M-C-_} $B%-!<$,(B -@code{gnus-undo} $BL?Na$ro$N(B Emacs $B$N(B -@code{undo} $BL?Na$K$A$g$C$H$@$1;w$F$$$k$H;W$o$l$k$G$7$g$&!#(B - - -@node Moderation -@section $B;J2qLr(B -@cindex moderation - -$B$b$7$"$J$?$,;J2q5G'$7$F$$$J$$5-;v$r$r$?$^$?$^8+$D$1$?$H$7$?$i!"(B@kbd{c} $BL?Na$G(B -$BC$7$G$-$^$9!#(B -@end enumerate - -$BFs$D$N%0%k!<%W$G;J2q$N$b$N$rI=<($9$k$3$H$,$G$-$k$N$G!"(Bgnus $B$O$3$l(B -$B$rMxMQ$9$k$3$H$K$7$^$9!#(B - -@menu -* Picons:: $B$"$J$?$,FI$s$G$$$k$b$N$N3($rI=<($9$kJ}K!!#(B -* Smileys:: $BI=<($5$l$k$Y$/@8$^$l$?9,$;$=$&$J4i$rI=<($9$kJ}K!!#(B -* Toolbar:: $B%/%j%C%/1n!#(B -* XVarious:: $B$=$NB>$N(B XEmacs $B$G(B Gnus $B$JJQ?t!#(B -@end menu - - -@node Picons -@subsection Picons - -@iftex -@iflatex -\include{picons} -@end iflatex -@end iftex - -$B$=$l$G!D!"$"$J$?$O$3$N%K%e!<%9%j!<%@!<$r$5$i$K$b$C$HCY$/$7$?$$$C(B -$B$F$o$1$@$M(B! $B$3$l$O$=$&$9$k$N$K$T$C$?$j$JJ}K!$G$9!#$5$i$K$3$l$O!"(B -$B$"$J$?$,%K%e!<%9$rFI$s$G$$$k$s$@$H$$$&$3$H$r!"$"$J$?$N8*1[$7$K8+(B -$B$D$a$F$$$k?M$K0u>]$E$1$k$?$a$NAG@2$i$7$$J}K!$G$b$"$j$^$9!#(B - -@menu -* Picon Basics:: picon $B$H$O2?$G!"$I$&$d$C$F$N$V$C2u$7$?$j$R$M$C$?$j$$$8$C$?$jM7$s$@$j$9$kJQ?t!#(B -@end menu - - -@node Picon Basics -@subsubsection Picon $B$N4pAC(B - -Picon $B$H$O$J$s$G$7$g$&(B? Picons $B%&%'%V%5%$%H$+$iD>@\0zMQ$7$^$7$g$&!#(B - -@iftex -@iflatex -\margindex{} -@end iflatex -@end iftex - -@quotation -@dfn{Picon} $B$H$O!"(B``$B8D?M%"%$%3%s(B (personal icons)'' $B$NN,$G$9!#$3(B -$B$l$O!"%M%C%H>e$NMxMQ.$5(B -$B$J2hA|$G!"%G!<%?%Y!<%9$r;}$?$;$F!"$"$kEE;R%a!<%k%"%I%l%9$,$"$C$?(B -$B$i!"$=$l$KE,@Z$J2hA|$r8+$D$1$i$l$k$h$&$K$7$F$*$/$b$N$G$9!#MxMQo;~@\B3$7$F$$$k$N$J$i$P!"(B -@code{gnus-picons-piconsearch-url} $B$KJ8;zNs(B @* -@file{http://www.cs.indiana.edu/picons/search.html} $B$r@_Dj$9$k$3(B -$B$H$G!"(BSteve Kinzler $B$N(B picon $B8!:w%(%s%8%s$r;H$&$3$H$,$G$-$^$9!#(B - -@vindex gnus-picons-database -$B$=$&$G$J$1$l$P!"H`$N%G!<%?%Y!<%9$rl=j$K%$%s(B -$B%9%H!<%k$7$F$"$k$b$N$H4|BT$7$^$9!#(B - - -@node Picon Requirements -@subsubsection Picon $B$NF0:n>r7o(B - -Gnus $B$K(B picon $B$rI=<($5$;$k$K$O!"(BXEmacs 19.13 $B$+$=$l0J9_$r$NHG$N(B Emacs $B$G$O$I$l$b$^$@2hA|$rI=<((B -$B$G$-$J$$$+$i$G$9!#(B - -$B$5$i$K!"(B@code{x} $B%5%]!<%HIU$-$G(B XEmacs $B$r%3%s%Q%$%k$7$F$$$J$/$F(B -$B$O$J$j$^$;$s!#Gr9u$h$j$b$b$C$H4qNo$J?'IU$-$N(B picon $B$rI=<($9$k$?(B -$B$a$K$O!"(B@code{xpm} $B$+(B @code{gif} $B$I$A$i$+$r(B XEmacs $B$H0l=o$K%3%s(B -$B%Q%$%k$7$F$$$kI,MW$b$"$j$^$9!#(B - -@vindex gnus-picons-convert-x-face -@code{X-Face} $B%X%C%@!<$N4i$rI=<($7$?$$$N$J$i!"(BXEmacs $B$r(B -@code{xface} $B%5%]!<%HIU$-$G%3%s%Q%$%k$7$J$1$l$P$J$j$^$;$s!#$=$&(B -$B$G$J$1$l$P!"(B@code{netpbm} $B%f!<%F%#%j%F%#$r%$%s%9%H!<%k$7$F$*$/$+!"(B -$B$"$k$$$OB>$N2?$+$r;H$&$h$&$K(B @code{gnus-picons-convert-x-face} -$BJQ?t$r$$$8$/$C$F$/$@$5$$!#(B - - -@node Easy Picons -@subsubsection $B3Z!9(B Picons - -picon $BI=<($rM-8z$K$9$k$K$O!"C1$K0J2<$N9T$r(B @file{~/.gnus} $B%U%!%$(B -$B%k$KF~$l$F!"(Bgnus $B$r5/F0$7$F$/$@$5$$!#(B - -@lisp -(setq gnus-use-picons t) -(add-hook 'gnus-article-display-hook - 'gnus-article-display-picons t) -(add-hook 'gnus-article-display-hook - 'gnus-picons-article-display-x-face) -@end lisp - -@code{gnus-picons-database} $B$,(B picon $B%G!<%?%Y!<%9$,4^$^$l$F$$$k(B -$B%G%#%l%/%H%j$r;X$7$F$$$k$3$H$r3NG'$7$F$/$@$5$$!#(B - -$B$=$NBe$o$j$K(B Web $B>e$N(B picon $B8!:w%(%s%8%s$r;H$$$?$1$l$P!"$3$l$rDI(B -$B2C$7$^$9!#(B - -@lisp -(setq gnus-picons-piconsearch-url - "http://www.cs.indiana.edu:800/piconsearch") -@end lisp - - -@node Hard Picons -@subsubsection $BFq2r(B Picons - -@iftex -@iflatex -\margindex{} -@end iflatex -@end iftex - -Gnus $B$O!"%0%k!<%W$d5-;v$KF~$C$?$j=P$?$j$9$k$N$K=>$C$F(B picon $B$rI=(B -$B<($9$k$3$H$,$G$-$^$9!#(BGnus $B$O(B picon $B%G!<%?%Y!<%9$N;0$D$N>O$H$I$&(B -$BAj8_:nMQ$9$l$P$h$$$+$rCN$C$F$$$^$9!#$9$J$o$A!"(Bgnus $B$O%K%e!<%9%0(B -$B%k!<%W$N3(!"Cxl=j!#(B@file{news}$B!"(B @file{domains}$B!"(B -@file{users} ($B$J$I$J$I(B) $B$N%5%V%G%#%l%/%H%j!<$,4^$^$l$F$$$k%G%#%l(B -$B%/%H%j!<$r;X$7$F$$$J$1$l$P$J$j$^$;$s!#$3$l$O(B -@code{gnus-picons-piconsearch-url} $B$,(B @code{nil} $B$G$"$k$H$-$N$_(B -$B;HMQ$5$l$^$9!#=i4|@_DjCM$O(B @file{/usr/local/faces/} $B$G$9!#(B - -@item gnus-picons-piconsearch-url -@vindex gnus-picons-piconsearch-url -Web $B>e$N(B picon $B8!:w%(%s%8%s$N(B URL$B!#8=:_CN$i$l$F$$$kM#0l$N%(%s%8(B -$B%s$O(B @file{http://www.cs.indiana.edu:800/piconsearch} $B$G$9!#%M%C(B -$B%H%o!<%/CY1d$r2sHr$9$k$?$a$K(B icon $B$O%P%C%/%0%i%&%s%I$Gl=j!#$3$l$O=i4|@_Dj$G$O(B @code{picons} $B$G(B -$B$9(B ($B$3$l$O=i4|@_Dj$G(B @samp{*Picons*} $B%P%C%U%!$K0LCV$7$^$9(B)$B!#B>$N(B -$BM-8z$J>l=j$H$7$F$O(B @code{article}$B!"(B @code{summary}$B!"$"$k$$$O(B -@samp{*scratch*} $B$@$m$&$HCN$C$?$3$H$G$O$"$j$^$;$s!#$?$@$=$N%P%C(B -$B%U%!$rI8=`$N(B gnus $BAkG[CV=hM}(B --- @pxref{Windows Configuration}$B$K(B -$B$h$C$F8+$($k$h$&$K$7$F$*$/$3$H$r3NG'$7$F$/$@$5$$!#(B - -@item gnus-picons-group-excluded-groups -@vindex gnus-picons-group-excluded-groups -$B$3$N@55,I=8=$K%^%C%A$9$k%0%k!<%W$G$O$=$N%0%k!<%W%"%$%3%s$rI=<($5(B -$B$;$^$;$s!#(B - -@end table - -$BCm0U(B: $B$b$7(B @code{gnus-use-picons} $B$r(B @code{t} $B$K@_Dj$9$k$H!"AkG[(B -$BCV$K(B @code{picons} $B%P%C%U%!$r4^$a$k$h$&$K@_Dj$5$l$^$9!#(B - -$B$5$F!"$3$l$i$r7hDj$7$?8e$K$O!"$3$l$i$N3($,@5$7$$;~$KI=<($5$l$k$h(B -$B$&$K!"0J2<$N4X?t$rE,@Z$J%U%C%/$KDI2C$9$kI,MW$,$"$j$^$9!#(B - -@vindex gnus-article-display-hook -@vindex gnus-picons-display-where -@table @code -@item gnus-article-display-picons -@findex gnus-article-display-picons -$BCxLr$K$bN)$?$J$$$I$&$G$b$h$$$3$H$r@)8f$G$-$k$h$&$K$7$^$9!#(B - -@table @code - -@item gnus-picons-news-directories -@vindex gnus-picons-news-directories -@code{gnus-picons-database} $B$+$i%K%e!<%9%0%k!<%W%U%'%$%9$rC5$9$?(B -$B$a$N%5%V%G%#%l%/%H%j!<$N%j%9%H!#(B@code{("news")} $B$,=i4|@_DjCM$G$9!#(B - -@item gnus-picons-user-directories -@vindex gnus-picons-user-directories -@code{gnus-picons-database} $B$+$iMxMQ%U%'%$%9$rC5$9$?$a$N%5(B -$B%V%G%#%l%/%H%j!<$N%j%9%H!#=i4|@_DjCM$O(B @code{("domains")} $B$G$9!#(B -$B$3$N%j%9%H$K(B @samp{"unknown"} $B$rDI2C$7$F$*$-$?$/$J$k?M$b$$$k$G$7$g(B -$B$&!#(B - -@item gnus-picons-convert-x-face -@vindex gnus-picons-convert-x-face -$B$b$7(B XEmacs $B$K(B @code{xface} $B%5%]!<%H$,AH$_9~$^$l$F$$$J$1$l$P!"$3(B -$B$NL?Na$,(B @code{X-Face} $B%X%C%@!<$r(B X $B%S%C%H%^%C%W(B (@code{xbm}) $B$K(B -$BJQ49$9$k$N$K;HMQ$5$l$^$9!#=i4|@_DjCM$O(B @code{(format "@{ echo '/* Width=48, -Height=48 */'; uncompface; @} | icontopbm | pbmtoxbm > %s" -gnus-picons-x-face-file-name)} $B$G$9!#(B - -@item gnus-picons-x-face-file-name -@vindex gnus-picons-x-face-file-name -@code{X-Face} $B%S%C%H%^%C%W$r3JG<$7$F$*$/0l;~%U%!%$%k$NL>A0!#=i4|(B -$B@_DjCM$O(B @code{(format "/tmp/picon-xface.%s.xbm" -(user-login-name))}$B!#(B - -@item gnus-picons-has-modeline-p -@vindex gnus-picons-has-modeline-p -@code{gnus-picons-display-where} $B$r(B @code{picons} $B$K@_Dj$7$F$7$^(B -$B$&$H!"(BXEmacs $B$N%U%l!<%`$O$a$A$c$a$A$c$K$J$C$F$7$^$&$G$7$g$&!#$3(B -$B$l$rB?>/$J$j$H$b7Z8:$9$k$K$O!"(B@code{gnus-picons-has-modeline-p} -$B$r(B @code{nil} $B$K@_Dj$7$F$/$@$5$$!#$3$l$O(B picon $B%P%C%U%!$+$i%b!<(B -$B%I9T$r$H$7$F;n$7$F$_$k3HD%;R$N=g=x%j%9%H!#=i4|@_DjCM$O(B -@code{("xpm" "gif" "xbm")} $B$+$i(B XEmacs $B$KAH$_9~$^$l$F$$$J$$$b$N(B -$B$r0z$$$?$b$N$G$9!#(B - -@item gnus-picons-display-article-move-p -@vindex gnus-picons-display-article-move-p -picon $B$rI=<($7$F$$$k$H$-$K%+!<%=%k0LCV$r:G=i$N6u9T$^$GF0$+$9$+$I(B -$B$&$+$r;XDj!#$3$l$O(B @code{gnus-picons-display-where} $B$NCM$,(B -@code{article} $B$G$"$k$H$-$N$_8z2L$,$"$j$^$9!#(B - -@item gnus-picons-clear-cache-on-shutdown -@vindex gnus-picons-clear-cache-on-shutdown -Gnus $B$r=*N;$9$k$H$-$K(B picon $B%-%c%C%7%e$r>C$75n$k$+$I$&$+!#(BGnus -$B$O/@aLs$G$-$^$9$,!"%a%b%j$r$$$/$i$+?)$$$^$9!#$b$7$3$NJQ(B -$B?t$r(B @code{nil} $B$K@_Dj$9$l$P!"(Bgnus $B$O$=$N%-%c%C%7%e$r7h$7$F>C$7(B -$B$^$;$s!#$=$l$r>C$75n$k$K$OC5n$5$l$^$9!#=i4|@_DjCM$O(B @code{t} $B$G$9!#(B - -@iftex -@iflatex -\margindex{} -@end iflatex -@end iftex - -@end table - -@node Smileys -@subsection $B%9%^%$%j!<(B -@cindex smileys - -@iftex -@iflatex -\gnusfig{-3cm}{0.5cm}{\epsfig{figure=tmp/BigFace.ps,height=20cm}} -\input{smiley} -@end iflatex -@end iftex - -$B%9%^%$%j!<(B @dfn{smiley} $B$O(B gnus $B$H$OJL$N%Q%C%1!<%8$G$9$,!"%9%^%$(B -$B%j!<$r;H$C$F$$$k%Q%C%1!<%8$O8=:_(B gnus $B$@$1$G$9$N$G!"$3$3$G@bL@$7(B -$B$^$9!#(B - -$B0l8@$G8@$($P(B --- gnus $B$G%9%^%$%j!<$r;H$&$K$O!"0J2<$r(B -@file{.gnus.el} $B$U$!$$$k$K=q$$$F$/$@$5$$!#(B - -@lisp -(add-hook 'gnus-article-display-hook 'gnus-smiley-display t) -@end lisp - -$B%9%^%$%j!<$O!"J8;z$N4i%^!<%/(B --- @samp{:-)}$B!"(B@samp{:-=}$B!"(B -@samp{:-(} $B$J$I$H$$$C$?$b$N(B --- $B$r3($KBP1~$5$;!"J8;z$N4i%^!<%/$N(B -$BBe$o$j$K$=$N3($rI=<($7$^$9!#$3$NJQ49$OJ8;z$K%^%C%A$9$k@55,I=8=$H(B -$B$=$l$N%U%!%$%kL>$X$NBP1~$N%j%9%H$G@)8f$5$l$^$9!#(B - -@vindex smiley-nosey-regexp-alist -@vindex smiley-deformed-regexp-alist -$B%9%^%$%j!<$O=i4|@_Dj$G$OFs$D$NJQ49O"A[%j%9%H$NNc$rDs6!$7$F$$$^$9!#(B -@code{smiley-deformed-regexp-alist} (@samp{:)}$B!"(B @samp{:(} $B$J$I(B -$B$K%^%C%A$9$k(B) $B$H!"(B@code{smiley-nosey-regexp-alist} (@samp{:-)}$B!"(B -@samp{:-(} $B$J$I$K%^%C%A$9$k(B) $B$G$9!#(B - -$B;HMQ$5$l$kO"A[%j%9%H$O(B @code{smiley-regexp-alist} $BJQ?t$G;XDj$5$l(B -$B$^$9!#$3$N=i4|@_DjCM$O(B @code{smiley-deformed-regexp-alist} $B$G$9!#(B - -$B3FMWAG$N:G=i$N9`L\$O%^%C%A$5$;$?$$@55,I=8=$G!"FsHVL\$NMWAG$O3($G(B -$BCV$-49$($?$$%0%k!<%W$K%^%C%A$9$k@55,I=8=!"$=$7$F;0HVL\$NMWAG$OI=(B -$B<($5$;$?$$%U%!%$%k$NL>A0$G$9!#(B - -$B0J2<$NJQ?t$O!"%9%^%$%j!<$,$3$l$i$N%U%!%$%k$rC5$9>l=j!"$"$k$$$O$I(B -$B$N?'$r;H$&$+$H!"$=$NB>$N$b$N$r%+%9%?%^%$%:$7$^$9!#(B - -@table @code - -@item smiley-data-directory -@vindex smiley-data-directory -$B%9%^%$%j!<$,4i%U%!%$%k$rC5$9>l=j!#(B - -@item smiley-flesh-color -@vindex smiley-flesh-color -$BH)$N?'!#=i4|@_DjCM$O!"?Ml9g$O!"(B -@code{default-toolbar}$B!"(B@code{top-toolbar}$B!"(B -@code{bottom-toolbar}$B!"(B@code{right-toolbar}$B!"(B@code{left-toolbar} -$B$N$I$l$+$G$J$/$F$O$J$j$^$;$s!#(B - -@item gnus-group-toolbar -@vindex gnus-group-toolbar -$B%0%k!<%W%P%C%U%!Fb$N%D!<%k%P!l=j$G$9!#(BGnus $B$ODL>o$3$N%G%#%l%/%H%j$r<+(B -$BF08!=P$7$^$9$,!"$b$7I8=`E*$G$J$$%G%#%l%/%H%j!<9=B$$r;}$C$F$$$k>l(B -$B9g$O!"$3$l$rl9gBEEv$J7k2L$r=P$7$^$9(B --- -$B$?$H$(%K%e!<%9%j!<%@!<$N2>LL$r$+$V$C$?J8;zNs@Z$j9o$_5!$G@8@.$5$l(B -$B$?J8;zNs$,:9$7=P$5$l$F$b!"$G$9!#(B - - -@node Thwarting Email Spam -@section spam $B%a!<%k$NN"$r$+$/(B -@cindex email spam -@cindex spam -@cindex UCE -@cindex unsolicited commercial email - -$B$3$3:G6a$N(B USENET $B$G$O!"@kEA$N%O%2%?%+$I$b$,!"H`$i$N:>5=$d@=IJ$r(B -$B2!$7IU$1$k$?$a$NEE;R%a!<%k%"%I%l%9$rC5$=$&$H$7$F!"5$0c$$$N$h$&$K(B -$B%K%e!<%9>e$r$&$m$D$$$F(B grep $B$7$^$/$C$F$$$^$9!#$3$l$KBP$9$kH?F0$H(B -$B$7$F!"B?$/$N?M!9$,(B @code{From} $B9T$KL50UL#$J%"%I%l%9$rF~$l$O$8$a(B -$B$k$h$&$K$J$C$F$7$^$$$^$7$?!#$3$l$OHs@8;:E*$J$3$H$@$H;d$O;W$$$^$9(B ---- $B$"$J$?$,=q$$$?$3$H$KBP$9$kJV?.$H$7$F@5Ev$J%a!<%k$rAw$k$3$H$r(B -$BLLE]$K$5$;!"$^$?C/$,=q$$$?$b$N$J$N$+$rJ,$+$j$E$i$/$7$^$9!#$3$s$J(B -$B=q$-49$($O7k6I$O!"2!$7IU$1@kEA%a!<%k$=$l<+?H$h$j$bBg$-$J6<0R$H$J(B -$B$k$+$b$7$l$^$;$s!#(B - -$B;d$K$H$C$F$N(B spam $B%a!<%k$N:GBg$NLdBj$O!"13$N8}\n") -@end lisp - -$B$=$7$F(B @code{nnmail-split-fancy} $B$K0J2<$NJ,N%5,B'$rF~$l$^$9(B -(@pxref{Fancy Mail Splitting})$B!#(B - -@lisp -( - ... - (to "larsi@@trym.ifi.uio.no" - (| ("subject" "re:.*" "misc") - ("references" ".*@@.*" "misc") - "spam")) - ... -) -@end lisp - -$B$3$N0UL#$O!"$3$N%"%I%l%9$KFO$$$?A4$F$N%a!<%k$r$^$:5?$$$^$9$,!"(B -@samp{Re:} $B$G;O$^$k(B @code{Subject} $B$,$D$$$F$$$k$+!"(B -@code{References} $B%X%C%@!<$,$D$$$F$$$l$P$*$=$i$/(B OK $B$@$m$&!"$H$$(B -$B$&$3$H$G$9!#;D$j$OA4$F(B @samp{spam} $B%0%k!<%W$K9T$-$^$9!#(B($B$3$N%"%$(B -$B%G%"$O$*$=$i$/(B Tim Pierce $B;a$K$h$k$b$N$G$9!#(B) - -$B$3$l$K2C$($F!"B?$/$N%a!<%k(B spam $B20$O!"$"$J$?$N$H$3$m$N(B -@code{smtp} $B%5!<%P!<$HD>@\OC$7!"(B@code{To} $B%X%C%@!<$K$"$J$?$N%a!<(B -$B%k%"%I%l%9$,L@<($5$l$J$$$h$&$K$7$^$9!#$J$s$G$=$s$J$3$H$r$9$k$N$+(B -$B$O$o$+$j$^$;$s$,(B --- $B$*$=$i$/;d$?$A$NN"$r$+$/5!9=$NN"$r$+$/$?$a(B -$B$+$J(B? $B$I$A$i$K$7$F$b!"BP=h$O4JC1$J$3$H$G$9(B --- $B$"$J$?08$F$G(B -$B$J$$$b$N$rA4It(B @samp{spam} $B%0%k!<%W$K$$$l$k$@$1$G$9!#$3$l$O$*9%(B -$B$_J,N%5,B'$N:G8e$K$3$s$JIw$KF~$l$k$3$H$G$G$-$^$9!#(B - -@lisp -( - ... - (to "larsi" "misc") - "spam") -@end lisp - -$B;d$N7P83$G$O!"$3$l$G;veA4$F$,@5$7$$%0%k!<%W$KJ,N`$5$l$^$9!#$^(B -$B$"!"$=$l$G$b$H$-$I$-(B @samp{spam} $B%0%k!<%W$r%A%'%C%/$7$F!"@5$7$$(B -$B%a!<%k$,$"$k$+%A%'%C%/$7$J$/$F$O$$$1$^$;$s$1$I$M!#$b$7$"$J$?$O<+(B -$BJ,$,NI$$%M%C%H%o!<%/;TL1$G$"$k$H;W$C$F$$$k$J$i!"$=$l$>$l$N2!$7IU(B -$B$1@kEA%a!<%k$N4X78Ev6I$K6l>p$rAw$jIU$1$k$3$H$5$($b$G$-$^$9(B --- -$B2K$J$H$-$K$G$b$M!#(B - -$B$^$?!"$"$J$?$,BU$1p$r$$$&J}$,NI$$(B -$B$H;W$&$+$b$7$l$^$;$s!#$3$l$O(B @* -@file{} -$B$+$i!VL5NA$G!WMxMQ$G$-$^$9!#$[$H$s$I$N(B spam $B%a!<%k$O<+F0E*$KAw$i(B -$B$l$F$$$k$N$G!"$A$g$C$H$@$11'Ch$N%P%i%s%9$,$H$l$k$+$b$7$l$^$;$s!#(B - -$B$3$l$G;d$N$H$3$m$G$OF0$$$F$$$^$9!#$3$l$G$_$s$J$O4JC1$JJ}K!$G;d$K(B -$BO"Mm$ruBV$G$9!#;d$N0U8+$H(B -$B$7$F$O!"(B @code{From} $B%X%C%@!<$K56B$$7$FB8:_$7$J$$%I%a%$%s$KAw$i(B -$B$;$k$N$O%-%?%J%$$G$9!#(B - - -@node Various Various -@section $B$$$m$$$m$N$$$m$$$m(B -@cindex mode lines -@cindex highlights - -@table @code - -@item gnus-home-directory -$BA4$F$N(B gnus $B$N%Q%9JQ?t$O$3$NJQ?t$K$h$C$F=i4|2=$5$l$^$9!#$=$N=i4|(B -$B@_DjCM$O(B @file{~/} $B$G$9!#(B - -@item gnus-directory -@vindex gnus-directory -$B$?$/$5$s$N(B gnus $B3JG<%Q%9JQ?t$O$3$NJQ?t$K$h$C$F=i4|2=$5$l$^$9!#$=(B -$B$N=i4|@_DjCM$O(B @samp{SAVEDIR} $B4D6-JQ?t$NCM$+!"$=$NJQ?t$,@_Dj$5$l(B -$B$F$$$J$$>l9g$O(B @file{~/News/} $B$G$9!#(B - -@file{.gnus.el} $B%U%!%$%k$,FI$^$l$?$H$-$O(B gnus $B$N$[$H$s$I$O$9$G$K(B -$BFI$_9~$^$l$F$$$k$H$$$&$3$H$KCm0U$7$F$/$@$5$$!#$3$l$O$D$^$j!"$3$N(B -$BJQ?t$r(B @file{.gnus.el} $B$NCf$G@_Dj$7$F$b!"$3$NJQ?t$K$h$C$F=i4|2=(B -$B$5$l$kB>$N%G%#%l%/%H%j!e5-$NJQ?t$K$OA4$/4X78$"$j$^$;$s(B --- $B$3$NJQ?t$OA4$F$N(B gnus $B%P%C(B -$B%U%!!<$N%G%#%U%)%k%H%G%#%l%/%H%j!<$r$I$&$9$Y$-$+$r@_Dj$7$^$9!#$b(B -$B$7(B @kbd{C-x C-f} $B$N$h$&$JL?Na$r/$J$$NL$@$1$rFI$b$&$HEXNO$7$^$9!#$3$NJQ?t(B ($B=i4|@_DjCM(B 4096) -$B$O!"%P%C%/%(%s%I$,%X%C%@!<$HK\J8$N4V$N6h@Z$j9T$r8+$D$1$k$^$G$KFI(B -$B$_9~$b$&$H$9$k@dBP:GBgD9$r;XDj$7$^$9!#$3$NJQ?t$,(B @code{nil} $B$G$"(B -$B$l$P!"FI$_9~$_>e8B$O$"$j$^$;$s!#$b$7(B @code{t} $B$G$"$l$P!"%P%C%/%((B -$B%s%I$O5-;v$rItJ,ItJ,$GFI$_9~$b$&$H$O$;$:!"5-;vA4BN$rFI$_9~$_$^$9!#(B -$B$3$l$O(B @code{ange-ftp} $B$d(B @code{efs} $B$N$"$k%P!<%8%g%s$G0UL#$r$b(B -$B$A$^$9!#(B - -@item nnheader-head-chop-length -@vindex nnheader-head-chop-length -$B$3$NJQ?t(B ($B=i4|@_DjCM(B 2048) $B$O!"A05-$NA`:n$r9T$C$F$$$k$H$-$K!"$I(B -$B$l$/$i$$$NBg$-$5$NC10L$G3F5-;v$rFI$_9~$`$+$r@_Dj$7$^$9!#(B - -@item nnheader-file-name-translation-alist -@vindex nnheader-file-name-translation-alist -@cindex file names -@cindex invalid characters in file names -@cindex characters in file names -$B$3$l$O%U%!%$%kL>$NJ8;z$r$I$N$h$&$KJQ49$9$k$+$r;XDj$9$kO"A[%j%9%H(B -$B$G$9!#Nc$($P!"$b$7(B @samp{:} $B$,$"$J$?$N%7%9%F%`$G$O%U%!%$%kL>$NJ8(B -$B;z$H$7$F$O;H$($J$$>l9g(B ($B$"$J$?$O(B OS/2 $B%f!<%6$G$9(B) $B!"0J2<$N$h$&$K(B -$B$9$k$3$H$,$G$-$^$9!#(B - -@lisp -(setq nnheader-file-name-translation-alist - '((?: . ?_))) -@end lisp - -$Be$G$N$3$NJQ(B -$B?t$N=i4|@_DjCM$G$9!#(B - -@item gnus-hidden-properties -@vindex gnus-hidden-properties -$B$3$l$O(B ``$BIT2D;k(B'' $B%F%-%9%H$r1#$9$?$a$K;H$o$l$kB0@-$N%j%9%H$G$9!#(B -$B$[$H$s$I$N%7%9%F%`$G$O=i4|@_DjCM$O(B @code{(invisible t intangible -t)} $B$G!"$3$l$OIT2D;k%F%-%9%H$r8+$($J$/$7$F?($l$J$/$7$^$9!#(B - -@item gnus-parse-headers-hook -@vindex gnus-parse-headers-hook -$B%X%C%@!<$r2rpJs$re$,%^%K%e%"%k$G$9(B---$B$"$J$?$O$b$&<+J,<+?H$N?M@8$rAw$k;v$,$G$-$^(B -$B$9!#O"Mm$r$H$C$F2<$5$$!#$"$J$?$NG-$K:#F|$O!"$H$$$C$F$*$$$F2<$5$$!#(B - -$B$*$*!"(B@strong{$B?@$h(B}---$B$5$h$J$i$rBQ$($k;v$O$G$-$^$;$s!#(B($B$9$9$j5c$-!#(B) - -Ol' Charles Reznikoff $B$O$=$l$rHs>o$K$h$/8=$7$F$$$^$9$N$G!"$3$3$OH`$N$?$a(B -$B$K>y$j$^$9(B: - -@quotation -@strong{Te Deum} - -@sp 1 -Not because of victories @* -I sing,@* -having none,@* -but for the common sunshine,@* -the breeze,@* -the largess of the spring. - -@sp 1 -Not for victory@* -but for the day's work done@* -as well as I was able;@* -not for a seat upon the dais@* -but at the common table.@* -@end quotation - -$B;nLu(B: - -@quotation -@strong{Te Deum} - -@sp 1 -$B>!Mx$7$?$+$i$G$O$J$/(B @* -$B;d$O2N$&(B @* -$B2?$bL5$$$1$l$I(B @* -$B$"$NF|8w$d(B @* -$BB)?a$d(B @* -$B=U$NBg$-$5$N$?$a$K(B @* - -@sp 1 -$B>!Mx$N$?$a$G$O$J$/(B @* -$B0lF|$NO+F/$N$?$a$K(B @* -$B$^$?!"$=$l$rC#@.$G$-$?$3$H$K(B @* -$B9b:B$N>e$N@J$N$?$a$G$O$J$/(B @* -$BIaDL$N%F!<%V%k$N$H$3$m$G(B @* -@end quotation - - -@node Appendices -@chapter $BIUO?(B - -@menu -* History:: $B$I$&$d$C$F(B gnus $B$,:#F|$N$h$&$K$J$C$?$+!#(B -* Terminology:: $B2f!9$OK\Ev$KFq$7$$!"8l$N$h$&$J8l$r;H$&!#(B -* Customization:: $B$"$J$?$NMW5a$K1h$C$F(B gnus $B$r;EN)$F$k!#(B -* Troubleshooting:: $B>e$=$&$H7h?4$7$^$7(B -$B$?!#(B - -$B$3$NL5Ni$r9T$C$??MJ*$rD4$Y$F$_$?$$$N$J$i!"$"$J$?$N(B ($B$/$=!*(B) $B%&%'%V%V%i%&(B -$B%6!<$r(B @file{http://www.stud.ifi.uio.no/~larsi/} $B$K8~$1$k;v$,$G$-$^$9!#(B -$B$3$l$O?7$7$/$F?h$JHG$N(B gnus $B$NBh0lG[I[>l=j$G!"(BNewsrc $B$r$V$C2u$7$F?M!9$r(B -$B7cE\$5$l$k%5%$%H$H$7$FCN$i$l$F$$$^$9!#(B - -$B:G=i$N%"%k%U%!HG$N3+H/4|4V$K!"?7$7$$(B Gnus $B$O(B ``(ding) Gnus'' $B$H8F$P$l$F(B -$B$$$^$7$?!#(B@dfn{(ding)} $B$O$b$A$m$s!"(B@dfn{ding is not Gnus} $B$NC;=L7A$G!"$3(B -$B$l$OA4$/40A4$J13$G$9$,!"$@$l$,$=$s$J$3$H$r5$$K$9$k$G$7$g$&$+!)(B($B$H$3$m$G!"(B -$B$3$NC;=L7A$N(B ``Gnus'' $B$O$*$=$i$/G_ED$5$s$N0U?^DL$j(B ``$B%K%e!<%9(B'' $B$HH/2;$5(B -$B$l$k$Y$-$G!"$=$&$9$k$H$b$C$HE,@Z$JL>A0$K$J$j$^$9!#$=$&;W$$$^$;$s$+!)(B) - -$B$I$A$i$K$;$h!"A4$F$N%(%M%k%.!<$r?7$7$$855$$NNI$$L>A0$rIU$1$k$N$K;H$$2L$?(B -$B$7$?8e!"$=$NL>A0$O(B @emph{$B$"$^$j$K(B} $B855$$,NI$9$.$k$H$$$&;v$K$J$j!"$=$l$r(B -``Gnus'' $B$H:F$SL?L>$7$^$7$?!#$G$b!":#2s$OBgJ8;z$H>.J8;z$r:.$<$F$$$^$9!#(B -``Gnus'' $B$H(B ``@sc{gnus}'' $B$G$9!#(B $B?7$7$$$b$N(B $B$H(B $B8E$$$b$N!#(B - -$B:G=i$N(B ``$BE,@Z$J(B'' Gnus 5 $B$N%j%j!<%9$O(B1995$BG/(B11$B7n$K(B Emacs 19.30 $B$NG[I[$K4^(B -$B$^$l$?$H$-$K$J$5$l$^$7$?(B (132 $B$N(B (ding) Gnus $B$N%j%j!<%9(B $BB-$9$3$H$N(B -Gnus5.0 $B$N(B15$B%j%j!<%9(B)$B!#(B - -1996$BG/(B3$B7n$K(B ``September Gnus'' (99$B%j%j!<%9$N8e$G(B)) -$B$,(B ''Gnus 5.2`` $B$H$$$&L>A0$G%j%j!<%9$5$l$^$7$?(B (40$B%j%j!<%9(B)$B!#(B - -1996$BG/$N(B7$B7n(B28$BF|$K(B Red Gnus $B$N:n6H$,;O$^$j!"$=$l$O(B1997$BG/(B1$B7n(B25$BF|$K(B (84$B%j%j!<(B -$B%9$N8e$G(B) ``Gnus 5.4'' $B$H$7$F%j%j!<%9$5$l$^$7$?(B (67 $B%j%j!<%9(B)$B!#(B - -1997$BG/(B9$B7n(B13$BF|$K!"(BQuassia Gnus $B$,3+;O$5$l!"(B37$B%j%j!<%9B3$-$^$7$?!#$=$l$O(B -``Gnus 5.6'' $B$H$7$F(B1998$BG/(B3$B7n(B8$BF|$K%j%j!<%9$5$l$^$7$?!#(B - -$B$b$7@\F,<-$r;}$C$?HG$N(B Gnus -- ``(ding) Gnus'', ``September Gnus'', -``Red Gnus'', ``Quassia Gnus'' -- $B$K=P2q$C$F$b!":.Mp$7$J$$$G$/$@$5$$!#$"(B -$B$J$?$,62$,$C$F$$$k;v$rCN$i$l$F$O$$$1$^$;$s!#8e$m$K2<$,$j$J$5$$!#$f$C$/$j(B -$B$H!#B>$K2?$r$7$F$b!"Av$C$F$O9T$1$^$;$s!#$=$l$,FO$+$/$J$k$^$G!"@E$+$KJb$-(B -$B5n$j$J$5$$!#E,@Z$K%j%j!<%9$5$l$?HG$N(B Gnus $B$r8+$D$1$F!"Be$o$j$K$=$l$K4s$j(B -$BE:$C$F2<$5$$!#(B - -@menu -* Why?:: Gnus $B$NL\E*$O2?!)(B -* Compatibility:: Gnus $B$O(B @sc{gnus} $B$H$I$l$/$i$$8_49@-$,$"$k$N!)(B -* Conformity:: Gnus $B$OA4$F$NI8=`$rK~$?$=$&$H$9$k!#(B -* Emacsen:: Gnus $B$O$$$/$D$+$N8=BeE*$J(B Emacs $B4D6-$Gl$H$7$F;H$o$l$FM_$7$$$G$9!#G_ED$5(B -$B$s$N%K%e!<%9%j!<%@!<$r%P%C%/%(%s%I$+$iJ,N%$9$k$H$$$&8-L@$JJ}?K$r3HD%$9$k(B -$B;v$K$h$C$F!"(BGnus $B$O%a!<%k$r7$$$F$$$k$N$G$9!#(B - -$B$*$=$i$/(B Gnus $B$O40@.$9$k;v$O$J$$$N$+$b$7$l$^$;$s!#(B @kbd{C-u 100 M-x -all-hail-emacs} $B$H(B @kbd{C-u 100 M-x all-hail-xemacs} $B$G$9!#(B - - -@node Compatibility -@subsection $B8_49@-(B - -@cindex compatibility -Gnus $B$O(B @sc{gnus} $B$H40A4$K8_49@-$,$"$k$h$&$K@_7W$5$l$F$$$^$9!#$[$H$s$IA4(B -$B$F$N%-!<%P%$%s%G%#%s%0$O$=$N$^$^;D$C$F$$$^$9!#$b$A$m$s!"B?$/$N%-!<%P%$%s(B -$B%G%#%s%0$,DI2C$5$l$^$7$?$,!"0l$D$+Fs$D$N$"$$$^$$$J>l9g$r=|$$$F!"8E$$%P%$(B -$B%s%G%#%s%0$,JQ99$5$l$?;v$O$"$j$^$;$s!#(B - -$B2f!9$N%b%C%H!<$O(B: -@quotation -@cartouche -@center $B9]E4$N9|AH$_$N6u9b$/!#(B -@end cartouche -@end quotation -$B$G$9!#(B - -$BA4$F$NL?Na$O$=$NL>A0$,JQ$o$C$F$$$^$;$s!#$$$/$D$+$NFbIt4X?t$OL>A0$rJQ$($^(B -$B$7$?!#(B - -@code{gnus-uu} $B%Q%C%1!<%8$O7`E*$KJQ2=$7$F$$$^$9!#(B@xref{Decoding -Articles}. - -$B0l$D$Ne$2$^$9(B)$B!"D>@\O"A[%j%9%H$rJQ99$9$k;v$O0[>o$J7k2L$r$b$?$i$9$G$7$g$&!#(B - -@cindex hilit19 -@cindex highlighting -$B8E$$(B hilit19 $B$N%3!<%I$OA4$/F0:n$7$^$;$s!#$N%3!<%I(B) -$B$r>C5n$9$k$Y$-$G$7$g$&!#(B@sc{gnus} $B$Ko$K(B} $B$h$/%P%0Js9p$rAw$kJJ$,$"$k$N$G$"$l$P!"$7$P$i$/$9$k$HLr$KN)(B -$B$D(B help $B%P%C%U%!$,$&$k$5$$$H46$8$k$+$b$7$l$^$;$s!#$=$&$G$"$l$P!"$=$l$,I=(B -$B<($5$l$k$N$rHr$1$k$?$a$K!"(B@code{gnus-bug-create-help-buffer} $B$r(B -@code{nil} $B$K@_Dj$7$F2<$5$$!#(B - - -@node Conformity -@subsection $B0lCW@-(B - -$B$3$3$K$OCHqpJs$G$"(B -$B$k$H8+$J$7$F$$$^$9!#(B@code{tin} $B$H(B @code{Netscape} $B$+$iAw$i$l$F$/$kHs>o$K(B -$BB?$/$NMM<0$K1h$C$F$$$J$$5-;v$r8+$?8e$G!";d$O$=$l$i$r5-;v$rEj9F$9$k$?$a$K(B -$B$O;H$o$J$$J}$,NI$$$H$$$&;v$rCN$j$^$7$?!#$b$7(B @code{X-Nesreader} $B%X%C%@!<(B -$B$,L5$1$l$P;d$O$=$N>pJs$rF@$k;v$O$J$+$C$?$G$7$g$&!#(B -@end table - -@end table - -$B>e$K=q$+$l$F$$$kJ8>O$K4X$9$k;v$G!"(BGnus $B$,$=$l$rK~$?$7$F$$$J$$$h$&$JF0:n(B -$B$r$7$F$$$k;v$K5$IU$$$?$i!"$?$a$i$o$:$K(B Gnus $B%?%o!<$H2f!9$KCN$i$;$F2<$5$$!#(B - - -@node Emacsen -@subsection Emacsen -@cindex Emacsen -@cindex XEmacs -@cindex Mule -@cindex Emacs - -Gnus $B$O0J2<$N$b$N$GF0:n$7$^$9(B: - -@itemize @bullet - -@item -Emacs 19.32 $B$H$=$l0J9_!#(B - -@item -XEmacs 19.14 $B$H$=$l0J9_!#(B - -@item -Emacs 19.32 $B$H$=$l0J9_$K4p$E$$$?(B Mule$B!#(B - -@end itemize - -Gnus $B$O$3$l$h$j8E$$$I$s$J(B Emacsen $B$G$b40A4$KF0:n$7$J$$$G$7$g$&!#>/$J$/$H(B -$B$b!"?.Mj$G$-$kF0:n$O$7$J$$$G$7$g$&!#(B - -$B$$$m$$$m$J%W%i%C%H%U%)!<%`$N(B Gnus $B$N4V$K$O$$$/$D$+$NGyA3$H$7$?0c$$$,$"$j(B -$B$^$9(B---XEmacs $B$O$b$C$H2hA|5!G=(B ($B%m%4$H%D!<%k%P!<(B) $B$rFCD'$K$7$F$$$^$9(B--$B$7(B -$B$+$7!"$=$NB>$O!"A4$F$N(B Emacsen $B$G$[$H$s$IF1$8$O$:$G$9!#(B - - -@node Contributors -@subsection $B9W8%e!";d$OKhF|$H$F$b$?$/$5$s$NAGE($J%P%0%l%]!<%H$r(B -$B$l$,;d$r4n$S$GK~$?$7$^$7$?!#0&Io!#$3$N%j%9%H$N?M!9$O(B -$BG&BQ$rD6$($F;d$N(B ``$B$"$!!"$=$l$O$9$P$i$7$$9M$($@(B $B!"$&$s!";d$O(B -$BBT$?$:$K$=$l$r$9$0%j%j!<%9$7$h$&(B $B!"$=$l$OA4$/F0:n$7$J$$(B $B!"$&$s!";d$O$9$0$K=P$=$&(B $B$$$d!"E;$&!"$=$l$OA4$/F0:n$7$J(B -$B$$$>(B''' $B$H$$$&%j%j!<%9$K4X$9$k$NB?$/(B -$B$N;v$H6&$K(B)$B!#(B - -@item -Luis Fernandes---$B%G%6%$%s$H%0%i%U%#%C%/!#(B - -@item -Erik Naggum---$B1g=u!"9M$(!"%5%]!<%H!"%3!<%I$H$=$NB>!#(B - -@item -Wes Hardaker---@file{gnus-picon.el} $B$H(B @dfn{picon} $B$NItJ,$N%^%K%e%"%k(B -(@pxref{Picons})$B!#(B - -@item -Kim-Minh Kaplan---picon $B%3!<%I$KCV$1$k99$J$k:n6H!#(B - -@item -Brad Miller---@file{gnus-gl.el} $B$H(B Grouplens $B$NItJ,$N%^%K%e%"%k(B -(@pxref{GroupLens})$B!#(B - -@item -Sudish Joseph---$B?t$(@Z$l$J$$$[$I$N%P%0$N=$@5!#(B - -@item -Ilja Weis---@file{gnus-topic.el}$B!#(B - -@item -Steven L. Baur---$B$?$/$5$s$N$?$/$5$s$N$?$/$5$s$N%P%0$NH/8+$H=$@5!#(B - -@item -Vladimir Alexiev---refcard $B$H%j%U%!%l%s%9$N>.:};R!#(B - -@item -Felix Lee & Jamie Zawinski---$B;d$O(B Felix Lee $B$H(B JWZ $B$N(B XGnus $BG[I[$+$i$$$/(B -$B$D$+$NItJ,$rEp$_$^$7$?!#(B - -@item -Scott Byer---@file{nnfolder.el} $B$N3HD%$H2~D{!#(B - -@item -Peter Mutsaers---$B8E;v5-;v$N%9%3%"%3!<%I!#(B - -@item -Ken Raebburn---POP $B%a!<%k%5%]!<%H!#(B - -@item -Hallvard B Furuseth---$B$$$m$$$m$J>.$5$JJ*$dItJ,!"FC$K(B .newsrc $B%U%!%$%k$r(B -$B07$&ItJ,!#(B - -@item -Brian Edmonds---@file{gnus-bbdbb.el}$B!#(B - -@item -David Moore--@file{nnvirtual.el} $B$N2~D{$HB?$/$NB>$N;v!#(B - -@item -Kevin Davidson---@dfn{ding} $B$NL>A0$r;W$$IU$-$^$7$?!#$G$9$+$i!"H`$r@U$a$F(B -$B2<$5$$!#(B - -@item -Fran,Ag(Bois Pinard---$BB?$/$N!"B?$/$N6=L#?<$/40A4$J%P%0%l%]!<%H$H(B autoconf $B$N(B -$B%5%]!<%H!#(B - -@end itemize - -$B$3$N%^%K%e%"%k(B (Gnus $B1Q8lHG(B) $B$O(B Adrian Aichner $B$H(B Ricardo Nassif$B!"(BMark -Borges $B$K$h$C$F9;@5$5$l!"(BJost Krieger $B$K$h$C$F0lItJ,$r9;@5$5$l$^$7$?!#(B - -$B0J2<$N?M!9$OB?$/$N%Q%C%A$HDs0F$G9W8%$7$^$7$?(B: - -Christopher Davis, -Andrew Eskilsson, -Kai Grossjohann, -David K,Ae(Bgedal, -Richard Pieri, -Fabrice Popineau, -Daniel Quinlan, -Jason L. Tibbitts, III, -and -Jack Vinson. - -$B$=$l$H!"0J2<$N?M$K$b%Q%C%A$d$=$NB>$N$b$N$r46$l$N?M!9$,9T$C$?;v$N40A4$J354Q$rF@$k$?$a$K!"(BChangeLog $B$,(B Gnus $B$N%"(B -$B%k%U%!G[I[$K$O4^$^$l$F$$$F!"K-IY$JFI$_J*$rM?$($k$G$7$g$&!#(B(550KB $B$H$$$/(B -$B$i$+(B)$B!#(B - -$B;d$,K:$l$?A4$F$N?M$Ke$N$b$N(B---Gnus 5.4/5.5 -* Quassia Gnus:: 2$B$+$1$k(B2$B$O(B4$B!"$b$7$/$O(B Gnus 5.6/5.7$B!#(B -@end menu - -$B$3$N%j%9%H$O!"$b$A$m$s!"(B@emph{$B$?$$$F$$$N(B} $B=EMW$J?7$7$$5!G=$K4X$9$k(B -@emph{$BC;$$(B}$B354Q$G$7$+$"$j$^$;$s!#$$$$$(!"K\Ev$O$=$&$G$O$"$j$^$;$s!#$b$C(B -$B$H$b$C$H$?$/$5$s$N$b$N$,$"$j$^$9!#$O$$!"2f!9$OAOB$@-$N40A4$J8z2L$r46$8$F(B -$B$$$k$N$G$9!#(B - - -@node ding Gnus -@subsubsection (ding) Gnus - -Gnus 5.0/5.1 $B$N?7$7$$5!G=(B: - -@itemize @bullet - -@item -$BA4$F$N%P%C%U%!$N304Q$O%U%)!<%^%C%H$N$h$&$JJQ?t(B (@pxref{Group Buffer -Format} $B$H(B @pxref{Summary Buffer Format}) $B$K$h$C$F@_Dj$rJQ$($k;v$,$G$-$k(B -$B$h$&$K$J$j$^$7$?!#(B - -@item -$B%m!<%+%k%9%W!<%k$H!"$$$/$D$+$N(B @sc{nntp} $B%5!<%P!<$rF1;~$K;H$&;v$,$G$k$h(B -$B$&$K$J$j$^$7$?(B (@pxref{Select Methods})$B!#(B - -@item -$B%0%k!<%W$r;ve$N%0%k!<%W$K7k9g$G$-$k$h$&$K$J$j$^$7$?(B (@pxref{Virtual -Groups})$B!#(B - -@item -$BB?$/$N0c$C$?%a!<%kMM<0(B (@pxref{Getting Mail}) $B$rFI$a$k$h$&$K$J$j$^$7$?!#(B -$BA4$F$N%a!<%k%P%C%/%(%s%I$OJXMx$J%a!<%k4|8B@Z$l>C5n5!9=$re$2$k$N$K==J,$J%X%C%@!<$ru%U%!%$%kA4BN$r$r$C$F5-;v$K%9%3%"$rIU$1$k;v$,$G$-$^$9(B (@pxref{Scoring})$B!#(B -$B$"$J$?$N$?$a$K5-;v$r$I$N$h$&$K%9%3%"$rIU$1$k$+$r(B Gnus $B$K8+$D$1$5$;$k;v$b(B -$B$G$-$^$9(B (@pxref{Adaptive Scoring})$B!#(B - -@item -Gnus $B$OIaDL$N(B Emacs $B$NJ}K!$G<+F0J]B8$5$l$k%I%j%V%k%P%C%U%!$rJ];}$7$F$$$^(B -$B$9$N$G!"$"$J$?$N%^%7%s$,Mn$C$3$A$?$H$-$G$b$"$^$j%G!<%?$r<:$o$J$$$G$7$g$&(B -(@pxref{Auto Save})$B!#(B - -@item -Gnus $B$O:#$d%U%!%$%k(B @file{.emacs} $B$r$0$A$c$0$A$c$K$9$k;v$rHr$1$k$?$a$K@l(B -$BMQ$N5/F0%U%!%$%k(B (@file{.gnus}) $B$r;}$D$h$&$K$J$j$^$7$?!#(B - -@item -$B%0%k!<%W$H5-;v$NN>J}$K%W%m%;%90u$rIU$1$k$3$H$,$G$-!"A4$F$N0u$NIU$$$?9`L\(B -$B$K1i;;$r$9$k;v$,$G$-$^$9(B (@pxref{Process/Prefix})$B!#(B - -@item -$B%0%k!<%W$N0lIt$r(B grep $B$7$F!"$=$N7k2L$+$i%0%k!<%W$r:n$k;v$,$G$-$^$9(B -(@pxref{Kibozed Groups})$B!#(B - -@item -$B$(!<$H!"A4$F$K$7$?$,$C$F!"%0%k!<%W$N0lMw$r5s$2$k;v$,$G$-$^$9(B -(@pxref{Listing Groups})$B!#(B - -@item -$B30It%5!<%P!<$r354Q$7$F!"$=$l$i$N%5!<%P!<$N%0%k!<%W$r9XFI$9$k;v$,$G$-$^$9(B -(@pxref{Browse Foreign Server})$B!#(B - -@item -Gnus $B$O%5!<%P!<$H$N(B2$B$D@\B3$G!"5-;v$rHsF14|$K$H$C$F$/$k;v$,$G$-$^$9(B -(@pxref{Asynchronous Fetching})$B!#(B - -@item -$B5-;v$r%m!<%+%k$K%-%c%C%7%e$9$k;v$,$G$-$^$9(B (@pxref{Article Caching})$B!#(B - -@item -uudecode $B$N4X?t$,3HD%$5$l!"0lHL2=$5$l$^$7$?(B (@pxref{Decoding Articles})$B!#(B - -@item -$B2a5n$N(B @sc{gnus} $B$N$"$^$jCN$i$l$F$$$J$$5!G=$N(B uuencode $B$5$l$?5-;v$r$^$@(B -$BEj9F$9$k;v$,$G$-$^$9(B (@pxref{Uuencoding and Posting})$B!#(B - -@item -$B?F5-;v(B ($B$HB>$N5-;v(B) $B$Nc$9$k;vL5$/F0:n$9$k$h$&$K(B -$B$J$j$^$7$?(B (@pxref{Finding the Parent})$B!#(B - -@item -Gnus $B$O(B FAQ $B$H%0%k!<%W$N5-=R$r$N30It;2>H$,%\%?%s$K$J$k$h$&$K$J$j$^$7$?(B (@pxref{Article -Buttons})$B!#(B - -@item -Gnus $B$N%&%#%s%I%&$H%U%l!<%`$N@_Dj$G$?$/$5$s$NJQ$J;v$r$G$-$k$h$&$K$J$j$^(B -$B$7$?(B (@pxref{Windows Configuration})$B!#(B - -@item -$B%-!<%\!<%I$r;H$&Be$o$j$K!"%\%?%s$r%/%j%C%/$G$-$k$h$&$K$J$j$^$7$?(B -(@pxref{Buttons})$B!#(B - -@end itemize - - -@node September Gnus -@subsubsection September Gnus - -@iftex -@iflatex -\gnusfig{-28cm}{0cm}{\epsfig{figure=tmp/september.ps,height=20cm}} -@end iflatex -@end iftex - -Gnus 5.2/5.3 $B$N?7$7$$5!G=(B: - -@itemize @bullet - -@item -$B?7$7$$%a%C%;!<%8:n@.%b!<%I$,;H$o$l$^$9!#(B@code{mail-mode}$B!"(B -@code{rnews-reply-mode} $B$H(B @code{gnus-msg} $B$NA4$F$N8E$$%+%9%?%^%$%:JQ?t(B -$B$O:#$d5l<0$K$J$j$^$7$?!#(B - -@item -Gnus $B$O(B @dfn{$B$^$P$i(B} $B%9%l%C%I$r:n@.$9$k;v$,$G$-$k$h$&$K$J$j$^$7$?(B---$B%9%l%C(B -$B%I$N<:$o$l$?5-;v$,$"$k$H$3$m$O6u$N@a$GI=8=$5$l$k$h$&$K$J$C$F$$$^$9(B -(@pxref{Customizing Threading})$B!#(B - -@lisp -(setq gnus-build-sparse-threads 'some) -@end lisp - -@item -$B30$K=P$F$$$/5-;v$OFCJL$JJ]4I%5!<%P!<$KJ]B8$5$l$k$h$&$K$J$j$^$7$?(B -(@pxref{Archived Messages})$B!#(B - -@item -$B5-;v$,;2>H$5$l$?$H$-$K!"%9%l%C%I$NItJ,:n@.$,5/$3$k$h$&$K$J$j$^$7$?!#(B - -@item -Gnus $B$O(B GroupLens $B$NM=8@$r;H$&;v$,$G$-$k$h$&$K$J$j$^$7$?(B -(@pxref{GroupLens})$B!#(B - -@item -Picons (personal icons) ($B8D?M%"%$%3%s(B) $B$,(B XEmacs $B$GI=<($G$-$k$h$&$K$J$j(B -$B$^$7$?(B (@pxref{Picons})$B!#(B - -@item -@code{trn} $B$N$h$&$JLZ%P%C%U%!$,I=<($5$l$k$h$&$K$J$j$^$7$?(B (@pxref{Tree -Display})$B!#(B - -@lisp -(setq gnus-use-trees t) -@end lisp - -@item -@code{nn} $B$N$h$&$Jv$_%H%T%C%/3,AX$K%0%k!<%WJ,$1$G$-$k$h$&$K$J$j$^$7$?(B -(@pxref{Group Topics})$B!#(B - -@lisp -(add-hook 'gnus-group-mode-hook 'gnus-topic-mode) -@end lisp - -@item -Gnus $B$,<:GT%a!<%k$r:FAw$G$-$k$h$&$K$J$j$^$7$?(B (@pxref{Summary Mail -Commands})$B!#(B - -@item -$B%0%k!<%W$,%9%3%"$r;}$D;v$,$G$-$k$h$&$K$J$j!"K,$l$k2s?t$K4p$E$$$FJB$SBX$($r(B -$B$G$-$k$h$&$K$J$j$^$7$?(B (@pxref{Group Score})$B!#(B - -@lisp -(add-hook 'gnus-summary-exit-hook 'gnus-summary-bubble-group) -@end lisp - -@item -$B%0%k!<%W$K%W%m%;%90u$rIU$1$i$l$k$h$&$K$J$j!"%0%k!<%W$N$0%k!<%W$KL?Na$,e$N%0%k!<%W$G%-%c%C%7%e$,$G$-$k$h$&$K$J$j$^$7$?!#(B - -@item -@code{nndoc} $B$OA4$F$N=8G[G[Aw!"%a!<%k%\%C%/%9!"(Brnews $B%K%e!<%90l3g!"(B -ClariNet $BC;<}=8!"$=$7$FA4$F$N$=$NB>$rM}2r$G$-$k$h$&$K$J$j$^$7$?(B -(@pxref{Document Groups})$B!#(B - -@item -Gnus $B$O(B SOUP $B%Q%1%C%H$r:n@.(B/$BFI$_9~$_$r$9$k$?$a$N?7$7$$%P%C%/%(%s%I(B -(@code{nnsoup}) $B$r;}$C$F$$$^$9!#(B - -@item -Gnus $B%-%c%C%7%e$,$:$C$HB.$/$J$j$^$7$?!#(B - -@item -$B%0%k!<%W$rB?$/$N4p=`$K=>$C$FJB$SBX$($G$-$k$h$&$K$J$j$^$7$?(B -(@pxref{Sorting Groups})$B!#(B - -@item -$B%"%I%l%9$N%j%9%H$H4|8B@Z$l>C5n$N;~4V$r@_Dj$9$k?7$7$$%0%k!<%W%Q%i%a!<%?$,(B -$BF3F~$5$l$^$7$?(B (@pxref{Group Parameters})$B!#(B - -@item -$BA4$F$N%U%)!<%^%C%H;XDj$,;H$o$l$k%U%'%$%9$r;XDj$G$-$k$h$&$K$J$j$^$7$?(B -(@pxref{Formatting Fonts})$B!#(B - -@item -@kbd{M P} $BI{%^%C%W$K%W%m%;%90u$NIU$$$?5-;v$N@_Dj(B/$B:o=|(B/$B@\;HMQ$G$-$k$h$&$K$J$j$^$7$?(B -(@pxref{Article Keymap})$B!#(B - -@item -$B%U%l!<%`$,(B @code{gnus-buffer-configuration} $B$NItJ,$K$J$k;v$,$G$-$^$9(B -(@pxref{Windows Configuration})$B!#(B - -@item -$B%G!<%b%s$N%W%m%;%9$G%a!<%k$r:FAv::$9$k$3$H$,$G$-$k$h$&$K$J$j$^$7$?(B -(@pxref{Daemons})$B!#(B -@iftex -@iflatex -\marginpar[\mbox{}\hfill\epsfig{figure=tmp/fseptember.ps,height=5cm}]{\epsfig{figure=tmp/fseptember.ps,height=5cm}} -@end iflatex -@end iftex - -@item -Gnus $B$O%9%Q%`$r:,@d$d$7$K$9$k$?$a$K(B NoCeM $B%U%!%$%k$r;H$&;v$,$G$-$k$h$&$K(B -$B$J$j$^$7$?(B (@pxref{NoCeM})$B!#(B - -@lisp -(setq gnus-use-nocem t) -@end lisp - -@item -$B%0%k!<%W$r1J5W2D;k$K$9$k;v$,$G$-$k$h$&$K$J$j$^$7$?(B (@pxref{Listing -Groups})$B!#(B - -@lisp -(setq gnus-permanently-visible-groups "^nnml:") -@end lisp - -@item -$B%+%9%?%^%$%:$r4JC1$K$9$k$?$a$KB?$/$N?7$7$$%U%C%/$,F3F~$5$l$^$7$?!#(B - -@item -Gnus $B$O(B @code{Mail-Copies-To} $B%X%C%@!<$KCm0U$rJ'$&$h$&$K$J$j$^$7$?!#(B - -@item -@code{References} $B%X%C%@!<$r=8$a$k;v$K$h$j%9%l%C%I$r=8$a$k;v$,$G$-$k$h$&(B -$B$K$J$j$^$7$?(B (@pxref{Customizing Threading})$B!#(B - -@lisp -(setq gnus-summary-thread-gathering-function - 'gnus-gather-threads-by-references) -@end lisp - -@item -$B4{FI5-;v$O:FO$KBP$7$F!"5-;v%P%C%U%!$G$N@^$jJV$7$,E,@Z$KF0:n$9$k$h$&$K$J(B -$B$j$^$7$?(B (@pxref{Article Washing})$B!#(B - -@item -$B1#$5$l$?0zMQJ8$O1#$9;v$r@Z$jBX$($k%\%?%s$r2C$(!"$I$N$/$i$$$N0zMQJ8$r1#$9(B -$B$+$r%+%9%?%^%$%:$G$-$k$h$&$K$J$j$^$7$?(B (@pxref{Article Hiding})$B!#(B - -@lisp -(setq gnus-cited-lines-visible 2) -@end lisp - -@item -$BB`6~$J%X%C%@!<$r1#$9;v$,$G$-$^$9(B (@pxref{Article Hiding})$B!#(B - -@lisp -(add-hook 'gnus-article-display-hook - 'gnus-article-hide-boring-headers t) -@end lisp - -@item -$B%9%3%"$N=i4|CM$,%a%K%e!<%P!<$+$i@_Dj$G$-$k$h$&$K$J$j$^$7$?!#(B - -@item -$B=P$F9T$/5-;v$N99$J$k9=J8%A%'%C%/$,$G$-$k$h$&$K$J$j$^$7$?!#(B - -@end itemize - - -@node Red Gnus -@subsubsection Red Gnus - -Gnus 5.4/5.5 $B$N?7$7$$5!G=(B: - -@iftex -@iflatex -\gnusfig{-5.5cm}{-4cm}{\epsfig{figure=tmp/red.ps,height=20cm}} -@end iflatex -@end iftex - -@itemize @bullet - -@item -@file{nntp.el} $B$OHsF14|$NN.57$G40A4$K2~D{$5$l$^$7$?!#(B - -@item -$B%9%3%"IU$1$O(B @code{and}$B!"(B@code{or}$B!"(B@code{not} $B$N$h$&$JO@M}1i;;;R$H!"?F(B -$B$N:FJ}8~$GuBV$,5-;v%b!<%I9T$KI=<($5$l$k$h$&$K$J$j$^$7$?(B (@pxref{Misc -Article})$B!#(B - -@item -@file{gnus.el} $B$,B?$/$N>.$5$$%U%!%$%k$KJ,3d$5$l$^$7$?!#(B - -@item -Message-ID $B$K4p$E$$$?!"=EJ#5-;v$NM^@)$,$J$5$l$k$h$&$K$J$j$^$7$?(B -(@pxref{Duplicate Suppression})$B!#(B - -@lisp -(setq gnus-suppress-duplicates t) -@end lisp - -@item -$B$I$N%9%3%"$HE,1~%U%!%$%k$,%[!<%`$N%9%3%"$HE,1~%U%!%$%k$G$"$k$+$r;XDj$9$k(B -(@pxref{Home Score File}) $B?7$7$$JQ?t$,2C$($i$l$^$7$?!#(B - -@item -@code{nndoc} $B$,4JC1$K3HD%2DG=$K$J$k$h$&$K2~D{$5$l$^$7$?(B (@pxref{Document -Server Internals})$B!#(B - -@item -$B%0%k!<%W$O?F$N%H%T%C%/$+$i%0%k!<%W%Q%i%a!<%?$r7Q>5$G$-$k$h$&$K$J$j$^$7$?(B -(@pxref{Topic Parameters})$B!#(B - -@item -$B5-;vJT=8$,2~D{$5$l!"$,$b$C$HCNE*$JJ}K!$GG'<1$5$l$k$h$&$K$J$j$^$7$?(B (@pxref{Article -Signature})$B!#(B - -@item -$B35N,%T%C%/%b!<%I$,$b$C$H(B @code{nn} $B$N$h$&$K$J$j$^$7$?!#9T?t$,I=<($5$l$F!"(B -$BL?Na(B @kbd{.} $B$,5-;v$re(B -$B$G(B) $B$,2C$($i$l$^$7$?(B---@kbd{M-C-d} (@pxref{Really Various Summary -Commands})$B!#(B - -@item -$B%W%m%;%90u$N@_Dj$,(B push $B$H(B pop $B$G$-$k$h$&$K$J$j$^$7$?(B (@pxref{Setting -Process Marks})$B!#(B - -@item -$B?7$7$$%a!<%k$+$i%K%e!<%9$X$N%P%C%/%(%s%I$,(B NNTP $B%5!<%P!<$,Ej9F$r5v2D$7$F(B -$B$$$J$$>l9g$G$b!"Ej9F$G$-$k$h$&$K$J$j$^$7$?(B (@pxref{Mail-To-News -Gateways})$B!#(B - -@item -$B%&%'%V8!:w%(%s%8%s(B (@dfn{DejaNews}$B!"(B@dfn{Alta Vista}$B!"(B@dfn{InReference}) -$B$+$i$N8!:w7k2L$rFI$`?7$7$$%P%C%/%(%s%I$,2C$($i$l$^$7$?(B (@pxref{Web -Searches})$B!#(B - -@item -$BI8=`$NJB$SBX$(4X?t$r;H$C$F%0%k!<%W$NCf$N%H%T%C%/$rJB$SBe$($9$k;v$,$G$-!"(B -$B$=$l$>$l$N%H%T%C%/$,FHN)$7$FJB$SBX$($G$-$k$h$&$K$J$j$^$7$?(B (@pxref{Topic -Sorting})$B!#(B - -@item -$B%0%k!<%W$N0lItJ,$,FHN)$7$FJB$SBX$($G$-$k$h$&$K$J$j$^$7$?(B -(@code{Sorting})$B!#(B - -@item -$B%-%c%C%7%e$5$l$?5-;v$,%0%k!<%W$KF~$l$i$l$k$h$&$K$J$j$^$7$?(B -(@pxref{Summary Generation Commands})$B!#(B -@iftex -@iflatex -\marginpar[\mbox{}\hfill\epsfig{figure=tmp/fred.ps,width=3cm}]{\epsfig{figure=tmp/fred.ps,width=3cm}} -@end iflatex -@end iftex - -@item -$B%9%3%"%U%!%$%k$,$b$C$H?.Mj$G$-$k=gHV$GE,MQ$G$-$k$h$&$K$J$j$^$7$?(B -(@pxref{Score Variables})$B!#(B - -@item -$B%a!<%k%a%C%;!<%8$,$I$3$K9T$/$+$NJs9p$r:n@.$9$k;v$,$G$-$k$h$&$K$J$j$^$7$?(B -(@pxref{Splitting Mail})$B!#(B - -@item -$BF~$C$FMh$?%a!<%k$rJ]B8$9$kA0$K$,$i$/$?$rj(B -$B$J$[$I$N?7$7$$L?Na$H%b!<%I$,DI2C$5$l$^$7$?!#40A4$JOC$KIU$$$F$O(B -@pxref{Gnus Unplugged} $B$r8+$F2<$5$$!#(B - -@item -@code{nndraft} $B%P%C%/%(%s%I$,La$C$F$-$^$7$?$,!"0MA3$H$O0c$&$h$&$KF0:n$9(B -$B$k$h$&$K$J$j$^$7$?!#A4$F$N%a%C%;!<%8%P%C%U%!$O(B @code{nndraft} $B%0%k!<%W$N(B -$B5-;v$G$b$"$j!"$=$l$O<+F0E*$K:n@.$5$l$^$9!#(B - -@item -@code{gnus-alter-header-function} $B$,%X%C%@!<$NCM$rJQ$($k$?$a$K;H$o$l$k$h(B -$B$&$K$J$j$^$7$?!#(B - -@item -@code{gnus-summary-goto-article} $B$,(B Message-ID $B$rO$r>C5n$9$k$?$a$N?7$7$$%a%C%;!<%8L?(B -$BNa$,$"$j$^$9(B: @kbd{C-c C-v}$B!#(B - -@item -@kbd{C-u C-c C-c} $B$K$h$C$F(B @code{nnvirtual} $B%0%k!<%W$r@8@.$7$F$$$k%0%k!<(B -$B%W$KEj9F$G$-$k$h$&$K$J$j$^$7$?!#(B - -@item -@code{nntp-rlogin-program}---$B%+%9%?%^%$%:$r4JC1$K$9$k$?$a$N?7$7$$JQ?t$G(B -$B$9!#(B - -@item -@code{gnus-article-edit-mode} $B$N(B @code{C-u C-c C-c} $B$O5-;v%P%C%U%!$N:F%O(B -$B%$%i%$%H$r6X;_$9$k$h$&$K$J$j$^$7$?!#(B - -@item -@code{gnus-boring-article-headers} $B$K?7$7$$MWAG$,$"$j$^$9(B--- -@code{long-to}$B!#(B - -@item -@kbd{M-i} $B%7%s%\%k@\F,0z?tL?Na$,$"$j$^$9!#>\:Y$O(B "Symbolic Prefixes" $B$N(B -$BItJ,$r8+$F2<$5$$!#(B - -@item -$B35N,%P%C%U%!$N(B @kbd{L} $B$H(B @kbd{I} $B$O%U%!%$%k(B "all.SCORE" $B$K%9%3%"K!B'$r(B -$B2C$($k$?$a$K%7%s%\%k@\F,0z?t(B @kbd{a} $B$r$5$J$1$l$P$J$j$^$;$s!#(B - -@item -$BEj9FC$7$O8=:_$NA*BrJ}K!$r;H$&$h$&$K$J$j$^$7$?!#%7%s%\%k@\F,<-(B -@kbd{a} $B$OIaDL$NEj9FJ}K!$r6/@)$7$^$9!#(B - -@item -M******** sm*rtq**t*s $B$rE,@Z$JJ8>O$KK]0F$9$k?7$7$$L?Na$,$"$j$^$9(B--- -@kbd{W d}$B!#(B - -@item -@code{nntp} $B$N$h$j4JC1$J%G%P%C%0$N$?$a$K!"(B@code{nntp-record-commands} $B$r(B -@code{nil} $B$G$J$$CM$K@_Dj$9$k;v$,$G$-$^$9!#(B - -@item -@code{nntp} $B$O(B @file{~/.authinfo} $B$r;H$&$h$&$K$J$j!"$3$l$O(B @file{.netrc} -$B$N$h$&$J%U%!%$%k$G!"$I$3$G$I$N$h$&$K(B @sc{authinfo} $B$r(B @sc{nntp} $B%5!<%P!<(B -$B$KAw$k$+$r@)8f$9$k$?$a$N$b$N$G$9!#(B - -@item -$B35N,%P%C%U%!$N%0%k!<%W%Q%i%a!<%?$rJT=8$9$k$?$a$NL?Na$,2C$($i$l$^$7$?!#(B - -@item -$B%a!<%k$,$I$3$KJ,3d$5$l$?$+$NMzNr$r;HMQ2DG=$K$J$j$^$7$?!#(B - -@item -$B?7$7$$5-;vF|IUL?Na$,2C$($i$l$^$7$?(B---@code{article-date-iso8601}$B!#(B - -@item -@code{gnus-score-thread-simplify} $B$r@_Dj$9$k;v$K$h$j%9%l%C%I$r:n@.$7$F$$(B -$B$k$H$-$OI=Bj$,C1=c2=$5$l$k$h$&$K$J$j$^$7$?!#(B - -@item -$B%a%C%;!<%8$G0zMQ$r$9$k$?$a$N?7$7$$4X?t$,2C$($i$l$^$7$?(B--- -@code{message-cite-original-without-signature}$B!#(B - -@item -@code{article-strip-all-blank-lines}---$B?7$7$$5-;vL?Na$G$9!#(B - -@item -$B5-;v$N=*$o$j$^$G$r@Z$k?7$7$$%a%C%;!<%8L?Na$,2C$($i$l$^$7$?!#(B - -@item -$BJQ?t(B @code{gnus-adaptive-word-minimum} $B$r;H$&;v$K$h$j:G>.8BE,1~%9%3%"$r(B -$B;XDj$9$k;v$,$G$-$^$9!#(B - -@item -$BL?Na(B @code{gnus-start-date-timer} $B$K$h$j(B ``$B2a<:F|IU(B'' $B5-;v%X%C%@!<$,7QB3(B -$BE*$K99?7$5$l$k$h$&$K$J$j$^$7$?!#(B - -@item -$B%&%'%V(B listserv $B%"!<%+%$%V$,(B @code{nnlistserv} $B%P%C%/%(%s%I$K$h$jFI$`;v(B -$B$,$G$-$k$h$&$K$J$j$^$7$?!#(B - -@item -$B8E$$(B dejanews $B%"!<%+%$%V$,(B @code{nnweb} $B$+$iFI$`;v$,$G$-$k$h$&$K$J$j$^$7(B -$B$?!#(B - -@end itemize - - - -@node Newest Features -@subsection $B:G?7$N5!G=(B -@cindex todo - -@dfn{todo list} $B$H$7$F$bCN$i$l$F$$$^$9!#o$K62$l$F2<$5$$!#(B - -($B$3$N0lMw$K8=$o$l$F$$$k5!G=$OI,$:$7$b;d$,$=$l$r - - - -http://www.uwsg.indiana.edu/hypermail/linux/kernel/9610/index.html - -http://www.miranova.com/gnus-list/ - -@end example - -@item -@samp{^-- } is made into - in LaTeX. - -@item - gnus-kill is much slower than it was in GNUS 4.1.3. - -@item - when expunging articles on low score, the sparse nodes keep hanging on? -@item - starting the first time seems to hang Gnus on some systems. Does -NEWGROUPS answer too fast? -@item - nndir doesn't read gzipped files. -@item - FAQ doesn't have an up node? -@item - when moving mail from a procmail spool to the crash-box, -the crash-box is only appropriate to one specific group. -@item - `t' `t' makes X-Faces disappear. -@item - nnmh-be-safe means that crossposted articles will -be marked as unread. -@item - Orphan score entries don't show on "V t" score trace -@item - when clearing out data, the cache data should also be reset. -@item - rewrite gnus-summary-limit-children to be non-recursive -to avoid exceeding lisp nesting on huge groups. -@item - expunged articles are counted when computing scores. -@item - implement gnus-batch-brew-soup -@item - ticked articles aren't easy to read in pick mode -- `n' and -stuff just skips past them. Read articles are the same. -@item - topics that contain just groups with ticked -articles aren't displayed. -@item - nndoc should always allocate unique Message-IDs. -@item - If there are mail groups the first time you use Gnus, Gnus'll -make the mail groups killed. -@item - no "no news is good news" when using topics. -@item - when doing crosspost marking, the cache has to be consulted -and articles have to be removed. -@item - nnweb should fetch complete articles when they are split into several -parts. -@item - scoring on head immediate doesn't work. -@item - finding short score file names takes forever. -@item - canceling articles in foreign groups. -@item - nntp-open-rlogin no longer works. -@item - C-u C-x C-s (Summary) switches to the group buffer. -@item - move nnmail-split-history out to the backends. -@item - nnweb doesn't work properly. -@item - using a virtual server name as `gnus-select-method' doesn't work? -@item - when killing/yanking a group from one topic to another in a slave, the -master will yank it first to one topic and then add it to another. -Perhaps. - -@item - warn user about `=' redirection of a group in the active file? -@item - really unbinhex binhex files. -@item - take over the XEmacs menubar and offer a toggle between the XEmacs -bar and the Gnus bar. -@item -@example - push active file and NOV file parsing down into C code. -`(canonize-message-id id)' -`(mail-parent-message-id references n)' -`(parse-news-nov-line &optional dependency-hashtb)' -`(parse-news-nov-region beg end &optional dependency-hashtb fullp)' -`(parse-news-active-region beg end hashtb)' - -@end example - -@item - nnml .overview directory with splits. -@item - asynchronous cache -@item - postponed commands. -@item - the selected article show have its Subject displayed in its summary line. -@item - when entering groups, get the real number of unread articles from -the server? -@item - sort after gathering threads -- make false roots have the -headers of the oldest orphan with a 0 article number? -@item - nndoc groups should inherit the score files of their parents? Also -inherit copy prompts and save files. -@item - command to start up Gnus (if not running) and enter a mail mode buffer. -@item - allow editing the group description from the group buffer -for backends that support that. -@item -gnus-hide,show-all-topics -@item - groups and sub-topics should be allowed to mingle inside each topic, -and not just list all subtopics at the end. -@item - a command to remove all read articles that are not needed to connect -threads -- `gnus-summary-limit-to-sparse-unread'? -@item - a variable to turn off limiting/cutting of threads in the tree buffer. -@item - a variable to limit how many files are uudecoded. -@item - add zombie groups to a special "New Groups" topic. -@item - server mode command: close/open all connections -@item - put a file date in gnus-score-alist and check whether the file -has been changed before using it. -@item - on exit from a digest group, go to the next article in the parent group. -@item - hide (sub)threads with low score. -@item - when expiring, remove all marks from expired articles. -@item - gnus-summary-limit-to-body -@item - a regexp alist that says what level groups are to be subscribed -on. Eg. -- `(("nnml:" . 1))'. -@item - easier interface to nnkiboze to create ephemeral groups that -contain groups that match a regexp. -@item - allow newlines in urls, but remove them before using -the URL. -@item - If there is no From line, the mail backends should fudge one from the -"From " line. -@item - fuzzy simplifying should strip all non-alpha-numerical info -from subject lines. -@item - gnus-soup-brew-soup-with-high-scores. -@item - nntp-ping-before-connect -@item - command to check whether NOV is evil. "list overview.fmt". -@item - when entering a group, Gnus should look through the score -files very early for `local' atoms and set those local variables. -@item - message annotations. -@item - topics are always yanked before groups, and that's not good. -@item - (set-extent-property extent 'help-echo "String to display in minibuf") -to display help in the minibuffer on buttons under XEmacs. -@item - allow group line format spec to say how many articles there -are in the cache. -@item - AUTHINFO GENERIC -@item - support qmail maildir spools -@item - `run-with-idle-timer' in gnus-demon. -@item - stop using invisible text properties and start using overlays instead -@item - C-c C-f C-e to add an Expires header. -@item - go from one group to the next; everything is expunged; go to the -next group instead of going to the group buffer. -@item - gnus-renumber-cache -- to renumber the cache using "low" numbers. -@item - record topic changes in the dribble buffer. -@item - `nnfolder-generate-active-file' should look at the folders it -finds and generate proper active ranges. -@item - nneething-look-in-files-for-article-heads variable to control -whether nneething should sniff all files in the directories. -@item - gnus-fetch-article -- start Gnus, enter group, display article -@item - gnus-dont-move-articles-to-same-group variable when respooling. -@item - when messages are crossposted between several auto-expirable groups, -articles aren't properly marked as expirable. -@item - nneething should allow deletion/moving. -@item - TAB on the last button should go to the first button. -@item - if the car of an element in `mail-split-methods' is a function, -and the function returns non-nil, use that as the name of the group(s) to -save mail in. -@item - command for listing all score files that have been applied. -@item - a command in the article buffer to return to `summary' config. -@item - `gnus-always-post-using-current-server' -- variable to override -`C-c C-c' when posting. -@item - nnmail-group-spool-alist -- says where each group should use -as a spool file. -@item - when an article is crossposted to an auto-expirable group, the article -should be marker as expirable. -@item - article mode command/menu for "send region as URL to browser". -@item - on errors, jump to info nodes that explain the error. For instance, -on invalid From headers, or on error messages from the nntp server. -@item - when gathering threads, make the article that has no "Re: " the parent. -Also consult Date headers. -@item - a token in splits to call shrink-window-if-larger-than-buffer -@item - `1 0 A M' to do matches on the active hashtb. -@item - duplicates -- command to remove Gnus-Warning header, use the read -Message-ID, delete the "original". -@item - when replying to several messages at once, put the "other" message-ids -into a See-Also header. -@item - support setext: URL:http://www.bsdi.com/setext/ -@item - support ProleText: -@item - when browsing a foreign server, the groups that are already subscribed -should be listed as such and not as "K". -@item - generate font names dynamically. -@item - score file mode auto-alist. -@item - allow nndoc to change/add/delete things from documents. Implement -methods for each format for adding an article to the document. -@item - `gnus-fetch-old-headers' `all' value to incorporate -absolutely all headers there is. -@item - function like `|', but concatenate all marked articles -and pipe them to the process. -@item - cache the list of killed (or active) groups in a separate file. Update -the file whenever we read the active file or the list -of killed groups in the .eld file reaches a certain length. -@item - function for starting to edit a file to put into -the current mail group. -@item - score-find-trace should display the total score of the article. -@item - "ghettozie" -- score on Xref header and nix it out after using it -to avoid marking as read in other groups it has been crossposted to. -@item - look at procmail splitting. The backends should create -the groups automatically if a spool file exists for that group. -@item - function for backends to register themselves with Gnus. -@item - when replying to several process-marked articles, -have all the From end up in Cc headers? Variable to toggle. -@item - command to delete a crossposted mail article from all -groups it has been mailed to. -@item - `B c' and `B m' should be crosspost aware. -@item - hide-pgp should also hide PGP public key blocks. -@item - Command in the group buffer to respool process-marked groups. -@item - `gnus-summary-find-matching' should accept -pseudo-"headers" like "body", "head" and "all" -@item - When buttifying things, all white space (including -newlines) should be ignored. -@item - Process-marking all groups in a topic should process-mark -groups in subtopics as well. -@item - Add non-native groups to the list of killed groups when killing them. -@item - nntp-suggest-kewl-config to probe the nntp server and suggest -variable settings. -@item - add edit and forward secondary marks. -@item - nnml shouldn't visit its .overview files. -@item - allow customizing sorting within gathered threads. -@item - `B q' shouldn't select the current article. -@item - nnmbox should support a newsgroups file for descriptions. -@item - allow fetching mail from several pop servers. -@item - Be able to specify whether the saving commands save the original -or the formatted article. -@item - a command to reparent with the child process-marked (cf. `T ^'.). -@item - I think the possibility to send a password with nntp-open-rlogin -should be a feature in Red Gnus. -@item - The `Z n' command should be possible to execute from a mouse click. -@item - more limiting functions -- date, etc. -@item - be able to limit on a random header; on body; using reverse matches. -@item - a group parameter (`absofucking-total-expiry') that will make Gnus expire -even unread articles. -@item - a command to print the article buffer as postscript. -@item - variable to disable password fetching when opening by nntp-open-telnet. -@item - manual: more example servers -- nntp with rlogin, telnet -@item - checking for bogus groups should clean topic alists as well. -@item - canceling articles in foreign groups. -@item - article number in folded topics isn't properly updated by -Xref handling. -@item - Movement in the group buffer to the next unread group should go to the -next closed topic with unread messages if no group can be found. -@item - Extensive info pages generated on the fly with help everywhere -- -in the "*Gnus edit*" buffers, for instance. -@item - Topic movement commands -- like thread movement. Up, down, forward, next. -@item - a way to tick/mark as read Gcc'd articles. -@item - a way to say that all groups within a specific topic comes -from a particular server? Hm. -@item - `gnus-article-fill-if-long-lines' -- a function to fill -the article buffer if there are any looong lines there. -@item - `T h' should jump to the parent topic and fold it. -@item - a command to create an ephemeral nndoc group out of a file, -and then splitting it/moving it to some other group/backend. -@item - a group parameter for nnkiboze groups that says that -all kibozed articles should be entered into the cache. -@item - It should also probably be possible to delimit what -`gnus-jog-cache' does -- for instance, work on just some groups, or on -some levels, and entering just articles that have a score higher than -a certain number. -@item - nnfolder should append to the folder instead of re-writing -the entire folder to disk when accepting new messages. -@item - allow all backends to do the proper thing with .gz files. -@item - a backend for reading collections of babyl files nnbabylfolder? -@item - a command for making the native groups into foreign groups. -@item - server mode command for clearing read marks from all groups -from a server. -@item - when following up multiple articles, include all To, Cc, etc headers -from all articles. -@item - a command for deciding what the total score of the current -thread is. Also a way to highlight based on this. -@item - command to show and edit group scores -@item - a gnus-tree-minimize-horizontal to minimize tree buffers -horizontally. -@item - command to generate nnml overview file for one group. -@item - `C-u C-u a' -- prompt for many crossposted groups. -@item - keep track of which mail groups have received new articles (in this session). -Be able to generate a report and perhaps do some marking in the group -buffer. -@item - gnus-build-sparse-threads to a number -- build only sparse threads -that are of that length. -@item - have nnmh respect mh's unseen sequence in .mh_profile. -@item - cache the newsgroups descriptions locally. -@item - asynchronous posting under nntp. -@item - be able to control word adaptive scoring from the score files. -@item - a variable to make `C-c C-c' post using the "current" select method. -@item - `limit-exclude-low-scored-articles'. -@item - if `gnus-summary-show-thread' is a number, hide threads that have -a score lower than this number. -@item - split newsgroup subscription variable up into "order" and "method". -@item - buttonize ange-ftp file names. -@item - a command to make a duplicate copy of the current article -so that each copy can be edited separately. -@item - nnweb should allow fetching from the local nntp server. -@item - record the sorting done in the summary buffer so that -it can be repeated when limiting/regenerating the buffer. -@item - nnml-generate-nov-databses should generate for -all nnml servers. -@item - when the user does commands in the group buffer, check -the modification time of the .newsrc.eld file and use -ask-user-about-supersession-threat. Also warn when trying -to save .newsrc.eld and it has changed. -@item - M-g on a topic will display all groups with 0 articles in -the topic. -@item - command to remove all topic stuff. -@item - allow exploding incoming digests when reading incoming mail -and splitting the resulting digests. -@item - nnsoup shouldn't set the `message-' variables. -@item - command to nix out all nnoo state information. -@item - nnmail-process-alist that calls functions if group names -matches an alist -- before saving. -@item - use buffer-invisibility-spec everywhere for hiding text. -@item - variable to activate each group before entering them -to get the (new) number of articles. `gnus-activate-before-entering'. -@item - command to fetch a Message-ID from any buffer, even -starting Gnus first if necessary. -@item - when posting and checking whether a group exists or not, just -ask the nntp server instead of relying on the active hashtb. -@item - buttonize the output of `C-c C-a' in an apropos-like way. -@item - `G p' should understand process/prefix, and allow editing -of several groups at once. -@item - command to create an ephemeral nnvirtual group that -matches some regexp(s). -@item - nndoc should understand "Content-Type: message/rfc822" forwarded messages. -@item - it should be possible to score "thread" on the From header. -@item - hitting RET on a "gnus-uu-archive" pseudo article should unpack it. -@item - `B i' should display the article at once in the summary buffer. -@item - remove the "*" mark at once when unticking an article. -@item - `M-s' should highlight the matching text. -@item - when checking for duplicated mails, use Resent-Message-ID if present. -@item - killing and yanking groups in topics should be better. If killing one copy -of a group that exists in multiple topics, only that copy should -be removed. Yanking should insert the copy, and yanking topics -should be possible to be interspersed with the other yankings. -@item - command for enter a group just to read the cached articles. A way to say -"ignore the nntp connection; just read from the cache." -@item - `X u' should decode base64 articles. -@item - a way to hide all "inner" cited text, leaving just the most -recently cited text. -@item - nnvirtual should be asynchronous. -@item - after editing an article, gnus-original-article-buffer should -be invalidated. -@item - there should probably be a way to make Gnus not connect to the -server and just read the articles in the server -@item - allow a `set-default' (or something) to change the default -value of nnoo variables. -@item - a command to import group infos from a .newsrc.eld file. -@item - groups from secondary servers have the entire select method -listed in each group info. -@item - a command for just switching from the summary buffer to the group -buffer. -@item - a way to specify that some incoming mail washing functions -should only be applied to some groups. -@item - Message `C-f C-t' should ask the user whether to heed -mail-copies-to: never. -@item - new group parameter -- `post-to-server' that says to post -using the current server. Also a variable to do the same. -@item - the slave dribble files should autosave to the slave file names. -@item - a group parameter that says what articles to display on group entry, based -on article marks. -@item - a way to visually distinguish slave Gnusae from masters. (Whip instead -of normal logo?) -@item - Use DJ Bernstein "From " quoting/dequoting, where applicable. -@item - Why is hide-citation-maybe and hide-citation different? Also -clear up info. -@item - group user-defined meta-parameters. - - - -From: John Griffith -@item - I like the option for trying to retrieve the FAQ for a group and I was -thinking it would be great if for those newsgroups that had archives -you could also try to read the archive for that group. Part of the -problem is that archives are spread all over the net, unlike FAQs. -What would be best I suppose is to find the one closest to your site. - -In any case, there is a list of general news group archives at @* -ftp://ftp.neosoft.com/pub/users/claird/news.lists/newsgroup_archives.html - - - - -@item -@example -From: Jason L Tibbitts III -(add-hook 'gnus-select-group-hook - (lambda () - (gnus-group-add-parameter group - (cons 'gnus-group-date-last-entered (list (current-time-string)))))) - -(defun gnus-user-format-function-d (headers) - "Return the date the group was last read." - (cond ((car (gnus-group-get-parameter gnus-tmp-group 'gnus-group-date-last-entered))) - (t ""))) -@end example - -@item - tanken var at n,Ae(Br du bruker `gnus-startup-file' som prefix (FOO) til ,Ae(B lete -opp en fil FOO-SERVER, FOO-SERVER.el, FOO-SERVER.eld, kan du la den v,Af(Bre en -liste hvor du bruker hvert element i listen som FOO, istedet. da kunne man -hatt forskjellige serveres startup-filer forskjellige steder. - - -@item -LMI> Well, nnbabyl could alter the group info to heed labels like -LMI> answered and read, I guess. - -It could also keep them updated (the same for the Status: header of -unix mbox files). - -They could be used like this: - - -@example -`M l RET' add label to current message. -`M u RET' remove label from current message. -`/ l RET' limit summary buffer according to . - - would be a boolean expression on the labels, e.g. - -`/ l bug & !fixed RET' -@end example - -would show all the messages which are labeled `bug' but not labeled -`fixed'. - -One could also imagine the labels being used for highlighting, or -affect the summary line format. - - -@item -Sender: abraham@@dina.kvl.dk - -I'd like a gnus-find-file which work like find file, except that it -would recognize things that looks like messages or folders: - -- If it is a directory containing numbered files, create an nndir -summary buffer. - -- For other directories, create a nneething summary buffer. - -- For files matching "\\`From ", create a nndoc/mbox summary. - -- For files matching "\\`BABYL OPTIONS:", create a nndoc/baby summary. - -- For files matching "\\`[^ \t\n]+:", create an *Article* buffer. - -- For other files, just find them normally. - -I'd like `nneething' to use this function, so it would work on a -directory potentially containing mboxes or babyl files. - -@item -Please send a mail to bwarsaw@@cnri.reston.va.us (Barry A. Warsaw) and -tell him what you are doing. - -@item -Currently, I get prompted: - -decend into sci? -- type y -decend into sci.something ? -- type n -decend into ucd? - -The problem above is that since there is really only one subsection of -science, shouldn't it prompt you for only descending sci.something? If -there was a sci.somethingelse group or section, then it should prompt -for sci? first the sci.something? then sci.somethingelse?... - -@item -Ja, det burde v,Af(Bre en m,Ae(Bte ,Ae(B si slikt. Kanskje en ny variabel? -`gnus-use-few-score-files'? S,Ae(B kunne score-regler legges til den -"mest" lokale score-fila. F. eks. ville no-gruppene betjenes av -"no.all.SCORE", osv. - -@item -What i want is for Gnus to treat any sequence or combination of the following -as a single spoiler warning and hide it all, replacing it with a "Next Page" -button: - - -^L's - -more than n blank lines - -more than m identical lines -(which should be replaced with button to show them) - -any whitespace surrounding any of the above - - -@item -Well, we could allow a new value to `gnus-thread-ignore-subject' -- -`spaces', or something. (We could even default to that.) And then -subjects that differ in white space only could be considered the -"same" subject for threading purposes. - -@item -Modes to preprocess the contents (e.g. jka-compr) use the second form -"(REGEXP FUNCTION NON-NIL)" while ordinary modes (e.g. tex) use the first -form "(REGEXP . FUNCTION)", so you could use it to distinguish between -those two types of modes. (auto-modes-alist, insert-file-contents-literally.) - -@item - Under XEmacs -- do funny article marks: -tick - thumb tack -killed - skull -soup - bowl of soup -score below - dim light bulb -score over - bright light bulb - -@item -Yes. I think the algorithm is as follows: - -@example -Group-mode - - show-list-of-articles-in-group - if (key-pressed == SPACE) - if (no-more-articles-in-group-to-select) - if (articles-selected) - start-reading-selected-articles; - junk-unread-articles; - next-group; - else - show-next-page; - - else if (key-pressed = '.') - if (consolidated-menus) # same as hide-thread in Gnus - select-thread-under-cursor; - else - select-article-under-cursor; - - -Article-mode - if (key-pressed == SPACE) - if (more-pages-in-article) - next-page; - else if (more-selected-articles-to-read) - next-article; - else - next-group; -@end example - -@item -My precise need here would have been to limit files to Incoming*. -One could think of some `nneething-only-files' variable, but I guess -it would have been unacceptable if one was using many unrelated such -nneething groups. - -A more useful approach would be to, in response to the `G D' prompt, be -allowed to say something like: `~/.mail/Incoming*', somewhat limiting -the top-level directory only (in case directories would be matched by -the wildcard expression). - -@item -It would be nice if it also handled - - - -which should correspond to `B nntp RET sunsite.auc.dk' in *Group*. - - -@item - - Take a look at w3-menu.el in the Emacs-W3 distribution - this works out -really well. Each menu is 'named' by a symbol that would be on a -gnus-*-menus (where * would be whatever, but at least group, summary, and -article versions) variable. - - So for gnus-summary-menus, I would set to '(sort mark dispose ...) - - A value of '1' would just put _all_ the menus in a single 'GNUS' menu in -the main menubar. This approach works really well for Emacs-W3 and VM. - - -@item - nndoc should take care to create unique Message-IDs for all its -articles. -@item - gnus-score-followup-article only works when you have a summary buffer -active. Make it work when posting from the group buffer as well. -(message-sent-hook). -@item - rewrite gnus-demon to use run-with-idle-timers. - -@item - * Enhancements to Gnus: - - Add two commands: - - * gnus-servers (gnus-start-server-buffer?)--enters Gnus and goes - straight to the server buffer, without opening any connections to - servers first. - - * gnus-server-read-server-newsrc--produces a buffer very similar to - the group buffer, but with only groups from that server listed; - quitting this buffer returns to the server buffer. - -@item - add a command to check the integrity of an nnfolder folder -- -go through the article numbers and see that there are no duplicates, -and stuff. - -@item - `unsmileyfy-buffer' to undo smileification. - -@item - a command to give all relevant info on an article, including all -secondary marks. - -@item - when doing `-request-accept-article', the backends should do -the nnmail duplicate checking. - -@item - allow `message-signature-file' to be a function to return the -value of the signature file. - -@item - In addition, I would love it if I could configure message-tab so that it -could call `bbdb-complete-name' in other headers. So, some sort of -interface like - -(setq message-tab-alist - '((message-header-regexp message-expand-group) - ("^\\(To\\|[cC]c\\|[bB]cc\\)" bbdb-complete-name))) - -then you could run the relevant function to complete the information in -the header - -@item - cache the newsgroups file locally to avoid reloading it all the time. - -@item - a command to import a buffer into a group. - -@item - nnweb should allow fetching by Message-ID from servers. - -@item - point in the article buffer doesn't always go to the -beginning of the buffer when selecting new articles. - -@item - a command to process mark all unread articles. - -@item - `gnus-gather-threads-by-references-and-subject' -- first -do gathering by references, and then go through the dummy roots and -do more gathering by subject. - -@item - gnus-uu-mark-in-numerical-order -- process mark articles in -article numerical order. - -@item - (gnus-thread-total-score - (gnus-id-to-thread (mail-header-id (gnus-summary-article-header)))) -bind to a key. - -@item - sorting by score is wrong when using sparse threads. - -@item - a command to fetch an arbitrary article -- without having to be -in the summary buffer. - -@item - a new nncvs backend. Each group would show an article, using -version branches as threading, checkin date as the date, etc. - -@item - http://www.dejanews.com/forms/dnsetfilter_exp.html ? -This filter allows one to construct advance queries on the Dejanews -database such as specifying start and end dates, subject, author, -and/or newsgroup name. - -@item - new Date header scoring type -- older, newer - -@item - use the summary toolbar in the article buffer. - -@item - a command to fetch all articles that are less than X days old. - -@item - in pick mode, `q' should save the list of selected articles in the -group info. The next time the group is selected, these articles -will automatically get the process mark. - -@item - Isn't it possible to (also?) allow M-^ to automatically try the -default server if it fails on the current server? (controlled by a -user variable, (nil, t, 'ask)). - -@item - make it possible to cancel articles using the select method for the -current group. - -@item - `gnus-summary-select-article-on-entry' or something. It'll default -to t and will select whatever article decided by `gnus-auto-select-first'. - -@item - a new variable to control which selection commands should be unselecting. -`first', `best', `next', `prev', `next-unread', `prev-unread' are -candidates. - -@item - be able to select groups that have no articles in them -to be able to post in them (using the current select method). - -@item - be able to post via DejaNews. - -@item - `x' should retain any sortings that have been performed. - -@item - allow the user to specify the precedence of the secondary marks. Also -allow them to be displayed separately. - -@item - gnus-summary-save-in-pipe should concatenate the results from -the processes when doing a process marked pipe. - -@item - a new match type, like Followup, but which adds Thread matches on all -articles that match a certain From header. - -@item - a function that can be read from kill-emacs-query-functions to offer -saving living summary buffers. - -@item - a function for selecting a particular group which will contain -the articles listed in a list of article numbers/id's. - -@item - a battery of character translation functions to translate common -Mac, MS (etc) characters into ISO 8859-1. - -@example -(defun article-fix-m$word () - "Fix M$Word smartquotes in an article." - (interactive) - (save-excursion - (let ((buffer-read-only nil)) - (goto-char (point-min)) - (while (search-forward "\221" nil t) - (replace-match "`" t t)) - (goto-char (point-min)) - (while (search-forward "\222" nil t) - (replace-match "'" t t)) - (goto-char (point-min)) - (while (search-forward "\223" nil t) - (replace-match "\"" t t)) - (goto-char (point-min)) - (while (search-forward "\224" nil t) - (replace-match "\"" t t))))) -@end example - -@item -@example - (add-hook 'gnus-exit-query-functions -'(lambda () - (if (and (file-exists-p nnmail-spool-file) - (> (nnheader-file-size nnmail-spool-file) 0)) - (yes-or-no-p "New mail has arrived. Quit Gnus anyways? ") - (y-or-n-p "Are you sure you want to quit Gnus? ")))) -@end example - -@item - allow message-default-headers to be a function. - -@item - new Date score match types -- < > = (etc) that take floating point -numbers and match on the age of the article. - -@item -@example -> > > If so, I've got one gripe: It seems that when I fire up gnus 5.2.25 -> > > under xemacs-19.14, it's creating a new frame, but is erasing the -> > > buffer in the frame that it was called from =:-O -> -> > Hm. How do you start up Gnus? From the toolbar or with -> > `M-x gnus-other-frame'? -> -> I normally start it up from the toolbar; at -> least that's the way I've caught it doing the -> deed before. -@end example - -@item - all commands that react to the process mark should push -the current process mark set onto the stack. - -@item - gnus-article-hide-pgp -Selv ville jeg nok ha valgt ,Ae(B slette den dersom teksten matcher -@example -"\\(This\s+\\)?[^ ]+ has been automatically signed by" -@end example -og det er maks hundre tegn mellom match-end og ----linja. Men -det- -er min type heuristikk og langt fra alles. - -@item - `gnus-subscribe-sorted' -- insert new groups where they would have been -sorted to if `gnus-group-sort-function' were run. - -@item - gnus-(group,summary)-highlight should respect any `face' text props set -on the lines. - -@item - use run-with-idle-timer for gnus-demon instead of the -home-brewed stuff for better reliability. - -@item - add a way to select which NoCeM type to apply -- spam, troll, etc. - -@item - nndraft-request-group should tally autosave files. - -@item - implement nntp-retry-on-break and nntp-command-timeout. - -@item - gnus-article-highlight-limit that says when not to highlight (long) -articles. - -@item - (nnoo-set SERVER VARIABLE VALUE) - -@item - nn*-spool-methods - -@item - interrupitng agent fetching of articles should save articles. - -@item - command to open a digest group, and copy all the articles there to the -current group. - -@item - a variable to disable article body highlights if there's more than -X characters in the body. - -@item - handle 480/381 authinfo requests separately. - -@item - include the texi/dir file in the distribution. - -@item - format spec to "tab" to a position. - -@item - Move all prompting to the new `M-n' default style. - -@item - command to display all dormant articles. - -@item - gnus-auto-select-next makeover -- list of things it should do. - -@item - a score match type that adds scores matching on From if From has replied -to something someone else has said. - -@item - Read Netscape discussion groups: -snews://secnews.netscape.com/netscape.communicator.unix - -@item -One command to edit the original version if an article, and one to edit -the displayed version. - -@item -@kbd{T v} -- make all process-marked articles the children of the -current article. - -@item -Switch from initial text to the new default text mechanism. - -@item -How about making it possible to expire local articles? Will it be -possible to make various constraints on when an article can be -expired, e.g. (read), (age > 14 days), or the more interesting (read -& age > 14 days)? - -@item -New limit command---limit to articles that have a certain string -in the head or body. - -@item -Allow breaking lengthy NNTP commands. - -@item -gnus-article-highlight-limit, to disable highlighting in big articles. - -@item -Editing an article should put the article to be edited -in a special, unique buffer. - -@item -A command to send a mail to the admin-address group param. - -@item -A Date scoring type that will match if the article -is less than a certain number of days old. - -@item -New spec: %~(tab 56) to put point on column 56 - -@item -Allow Gnus Agent scoring to use normal score files. - -@item -Rething the Agent active file thing. `M-g' doesn't update the active -file, for instance. - -@item -With dummy roots, `^' and then selecing the first article -in any other dummy thread will make gnus highlight the -dummy root instead of the first article. - -@item -Propagate all group properties (marks, article numbers, etc) up to the -topics for displaying. - -@item -`n' in the group buffer with topics should go to the next group -with unread articles, even if that group is hidden in a topic. - -@item -gnus-summary-limit-include-cached is slow when there are -many articles in the cache, since it regenerates big parts of the -summary buffer for each article. - -@item -Implement gnus-batch-brew-soup. - -@item -Group parameters and summary commands for un/subscribing to mailing -lists. - -@item -Introduce nnmail-home-directory. - -@item -gnus-fetch-group and friends should exit Gnus when the user -exits the group. - -@item -Solve the halting problem. - -@c TODO -@end itemize - -@iftex - -@page -@node The Manual -@section $B%^%K%e%"%k(B -@cindex colophon -@cindex manual - -$B$3$N%^%K%e%"%k$O(B TeXinfo $B%U%!%$%k$+$i:n@.$5$l!"$=$l$+$i(B @code{texi2dvi} -@iflatex -$B$b$7$/$O!"(BLars $B$5$s$N:n$i$l$?(B Texinfo to \LaTeX $BJQ49$rDL$j!"$=$l$+$i!"(B -@code{latex} $B$H(B @code{dvips} -@end iflatex -$B$rP$o$l$k$G$7$g$&!#$"$J$?$NCN$i$J$$$H$3$m$G!#(B - -@item $B%a!<%k(B (mail) -@cindex mail -$B$"$J$?$K8D?ME*$KG[Aw$5$l$k$b$NA4$F$,%a!<%k$G$9!#$$$/$D$+$N%K%e!<%9(B/$B%a!<(B -$B%k%j!<%@!<(B (gnus $B$N$h$&$J(B) $B$O%a!<%k$H%K%e!<%9$N0c$$$r$\$d$1$5$;$^$9$,!"(B -$B$=$3$K$O0c$$$OB8:_$7$^$9!#%a!<%k$O;dE*$G$9!#%K%e!<%9$O8xE*$G$9!#%a!<%k$r(B -$BAw?.$9$k;v$OEj9F$G$O$J$/!"JV?.$O%U%)%m!<%"%C%W$G$O$"$j$^$;$s!#(B - -@item $BJV?.(B (reply) -@cindex reply -$B$"$J$?$,FI$s$G$$$k$b$N$r=q$$$??M$K%a!<%k$rAw$k;v$G$9!#(B - -@item $B%U%)%m!<%"%C%W(B (follow up) -@cindex follow up -$B$"$J$?$,FI$s$G$$$k5-;v$K1~Ez$7$F8=:_$N%K%e!<%9%0%k!<%W$K5-;v$rEj9F$9$k;v(B -$B$G$9!#(B - -@item $B%P%C%/%(%s%I(B (backend) -@cindex backend -Gnus $B$O%K%e!<%9$H%a!<%k$NN>J}$N$$$m$$$m$J%P%C%/%(%s%I$,M?$($?5-;v$rF@$^(B -$B$9!#(BGnus $B$O$O!"$$$o$f$k2<$K2#$?$o$C$F$$$k%a%G%#%"$r07$&;v$O$7$^$;$s(B---$B$3(B -$B$l$O$9$Y$F%P%C%/%(%s%I$K$h$C$F$J$5$l$^$9!#(B - -@item $B4pK\(B (native) -@cindex native -Gnus $B$O$$$D$b0l$D$NJ}K!(B ($B$H%P%C%/%(%s%I(B) $B$r%K%e!<%9$rF@$k$?$a$N(B @dfn{$B4p(B -$BK\(B}$B!"$b$7$/$O=i4|@_Dj(B $B$H$7$F;H$$$^$9!#(B - -@item $B30It(B (foreign) -@cindex foreign -$BF1;~$KG$0U$N?t$N30It%0%k!<%W$r3hF0>uBV$K$9$k$3$H$b$G$-$^$9!#$3$l$i$O%K%e!<(B -$B%9$reIt$G!"G'>Z>pJs(B ($BEy(B) $B$,F~$l$i$l$F$$$k$H$3$m$G$9!#(B - -@item $BK\BN(B (body) -@cindex body -$B5-;v$N;D$j$NItJ,$G$9!#%X%C%I$G$J$$$b$N$O$9$Y$FK\BN$G$9!#(B - -@item $B%X%C%@!<(B (header) -@cindex header -$B5-;v$N%X%C%I$+$i$N9T$G$9!#(B - -@item $B%X%C%@!<72(B (headers) -@cindex headers -$B$=$N$h$&$J9T$N=89g$b$7$/$O!"%X%C%I$N=89g$G$9!#$b$7$/$O!"(B@sc{nov} $B9T$N=8(B -$B9g$G$9!#(B - -@item @sc{nov} -@cindex nov -Gnus $B$,%0%k!<%W$KF~$k$H!"%0%k!<%W$NA4$F$NL$FI5-;v$N%X%C%@!<$r%P%C%/%(%s(B -$B%I$K5a$a$^$9!#$[$H$s$I$N%5!<%P!<$O(B News OverView $BMM<0$,;HMQ2DG=$G!"$=$l(B -$B$OIaDL$N(B @sc{head} $BMM<0$h$j$b$C$H$l$N%0%k!<%W$O2?$i$+$N(B @dfn{$B%l%Y%k(B} $B$+B>$N$b$N(B (1-9) $B$G9XFI$5$l$F(B -$B$$$^$9!#Dc$$%l%Y%k$N$b$N$O9b$$%l%Y%k$N$b$N$h$j(B ``$B$h$j(B'' $B9XFI$5$l$F$$$^$9!#(B -$B%s%S(B}; 9 $B$O(B @dfn{$B@Z$i$l$?(B} $B$H8+$J$5$l$^$9!#%0%k!<%W$r%j%9%H$7$?(B -$B$j!"?7$7$$%0%k!<%W$rAv::$7$?$j$9$kL?Na$O$9$Y$F?tCM@\F,0z?t$r(B @dfn{$BF0:n%l(B -$B%Y%k(B} $B$H$7$F;H$$$^$9!#(B - -@item $B@Z$i$l$?%0%k!<%W(B (killed groups) -@cindex killed groups -$B@Z$i$l$?%0%k!<%W$N>pJs$OC_@Q$5$l$?$j99?7$5$l$?$j$7$^$;$s$N$G!"@Z$i$l$?%0(B -$B%k!<%W$r9XFI$5$l$?%0%k!<%W$h$j4JC1$K07$($k$h$&$K$J$j$^$9!#(B - -@item $B%>%s%S%0%k!<%W(B (zombie groups) -@cindex zombie groups -$B$[$H$s$I@Z$i$l$?%0%k!<%W$HF1$8$G!"$=$l$h$j>/$7;`$s$G$$$k$@$1$G$9!#(B - -@item $B8=>u%U%!%$%k(B (active file) -@cindex active file -$B%K%e!<%9%5!<%P!<$O$I$N5-;v$r1?$s$G$$$k$+!"$I$N%0%k!<%W$,B8:_$9$k$+$r5-O?(B -$B$7$F$*$+$J$1$l$P$J$j$^$;$s!#A4$F$N$3$N>pJs$O8=>u%U%!%$%k$KC_@Q$5$l!"$=$l(B -$B$O$"$J$?$,A[A|$9$k$h$&$KHf3SE*Bg$-$$$G$9!#(B - -@item $B56%0%k!<%W(B (bogus groups) -@cindex bogus groups -$B%U%!%$%k(B @file{.newsrc} $B$KB8:_$9$k%0%k!<%W$G$9$,!"%5!<%P!<$KCN$i$l$F$$$J(B -$B$$%0%k!<%W(B ($B$9$J$o$A!"$=$l$O8=>u%U%!%$%k$K$"$j$^$;$s(B) $B$O(B @emph{$B56%0%k!<(B -$B%W(B} $B$G$9!#$3$l$O!"$*$=$i$/(B ($B$9$G$K(B) $B$=$N%0%k!<%W$OB8:_$7$F$$$J$$$N$G$7$g(B -$B$&!#(B - -@item $B3hF02=(B (activating) -@cindex activating groups -$B%5!<%P!<$K%0%k!<%W$N>pJs$r?R$M!"L$FI5-;v$N?t$r1i;;$9$k9T0Y$O(B @dfn{$B%0%k!<(B -$B%W$r3hF02=$9$k(B} $B$H8F$P$l$F$$$^$9!#Hs3hF0%0%k!<%W$O%0%k!<%W%P%C%U%!$K(B -@samp{*} $B$H$H$b$K0lMwI=<($5$l$^$9!#(B - -@item $B%5!<%P!<(B (server) -@cindex server -$B@\B3$7$F!"%K%e!<%9(B ($B$b$7$/$O%a!<%k(B) $B$re$N%5!<%P!<@_Dj$r;XDj$9$k9=B$$G$9!#(B - -@item $B;ve$N%5!<%P!<(B (virtual server) -@cindex virtual server -$BL?L>$5$l$?A*BrJ}K!$G$9!#A*BrJ}K!$O(B ($BJ*M}E*(B) $B%5!<%P!<$K@\B3$9$k$?$a$KI,MW(B -$B$JJ}K!$rDj5A$9$k$?$a!"J*;v$rA4BN$H$7$Fe$N%5!<%P!<$K$J$j$^(B -$B$9!#(B - -@item $B@vBu(B (washing) -@cindex washing -$B%P%C%U%!$r;}$C$F$-$F!"2?$i$+$N/$J$+$l(B) $B85$N$b$N$h$j$b$h$j$-$l$$$G4n$P$7$$$b$N$K$J$k$G$7$g$&!#(B - -@item $B0l;~%0%k!<%W(B (ephemeral groups) -@cindex ephemeral groups -$B$?$$$F$$$N%0%k!<%W$O$I$N5-;v$rFI$s$@$+$N%G!<%?$rC_@Q$7$^$9!#(B@dfn{$B0l;~(B} -$B%0%k!<%W$O%G!<%?$,N/$a$i$l$J$$%0%k!<%W$G$9(B---$B%0%k!<%W$r=P$k$H!"$=$l$OE7(B -$B6u$K>C$(5n$j$^$9!#(B - -@item $B8GDj%0%k!<%W(B (solid groups) -@cindex solid groups -$B$3$l$O0l;~%0%k!<%W$NH?BP$G$9!#%0%k!<%W%P%C%U%!$K5s$2$i$l$F$$$kA4$F$N%0%k!<(B -$B%W$O8GDj%0%k!<%W$G$9!#(B - -@item $B$^$P$i5-;v(B (sparse articles) -@cindex sparse articles -@code{gnus-build-sparse-threads} $B$N5!G=$r;HMQ$7$F$$$k$H$-$O!"35N,%P%C%U%!(B -$B$K5-;v$NF~$l>l=j$,I=<($5$l$^$9!#(B - -@item $B%9%l%C%I:n$j(B (threading) -@cindex threading -$B$=$l$,1~Ez$7$?5-;v$ND>8e$K$=$N5-;v$X$N1~Ez$rCV$/$3$H$G$9(B---$B3,AXE*N.57$G!#(B - -@item $B:,(B (root) -@cindex root -@cindex thread root -$B%9%l%C%I$N:G=i$N5-;v$,:,$G$9!#$=$l$O%9%l%C%I$NA4$F$N5-;v$NAD@h$G$9!#(B - -@item $B?F(B (parent) -@cindex parent -$B1~Ez$N$"$k5-;v$G$9!#(B - -@item $B;R(B (child) -@cindex child -$B0c$C$?5-;v(B---$B$=$N?F(B $B$K1~Ez$9$k5-;v$G$9!#(B - -@item $B=8G[(B (digest) -@cindex digest -$BJ#?t$N%a%C%;!<%8$r0l$D$N%U%!%$%k$K=8$a$?$b$N$G$9!#$b$C$H$bIaDL$N=8G[MM<0(B -$B$O(B RFC1153 $B$G;XDj$5$l$F$$$^$9!#(B - -@end table - - -@page -@node Customization -@section $B%+%9%?%^%$%:(B -@cindex gerenal customization - -$BA4$F$NJQ?t$O$3$N%^%K%e%"%k$N$I$3$+JL$N$H$3$m$GE,@Z$K@bL@$5$l$F$$$^$9!#$3(B -$B$NItJ,$OHs>o$KNI$/$"$k>u67$G$I$N$h$&$K(B gnus $B$r%+%9%?%^%$%:$9$l$PNI$$$+$N(B -$BAm9gE,;X<(@h$rM?$($k$?$a$K9M0F$5$l$F$$$^$9!#(B - -@menu -* Slow/Expensive Connection:: $B%m!<%+%k$N(B Emacs $B$rN)$A>e$2$F!"(B - $BB>$N$H$3$m$+$i%K%e!<%9$rF@$k;v$,$G$-$k!#(B -* Slow Terminal Connection:: $B1s3V(B Emacs $B$ro$K:Y$$@~$N8~$3$&$N%^%7(B -$B%s$+$i%K%e!<%9$ru%U%!(B -$B%$%kA4BN$rMW5a$9$k;v$r6X;_$G$-$^$9!#$3$N%U%!%$%k$O$7$P$7$PHs>o$KBg$-$/$J$C(B -$B$F$$$^$9!#$=$l$K2C$($F!"(Bgnus $B$,FMA3$H$K$+$/8=>u%U%!%$%k$ro$K35N,%P%C%U%!$rCf?4:F@_Dj$r$9$k$3$H$r6X;_$9$k$?$a$K$3$l$r(B -@code{nil} $B$K@_Dj$7$F2<$5$$!#$3$l$,(B @code{vertical} $B$G$"$k$H!"?bD>J}8~$N(B -(vertical) $BCf?4:F@_Dj$N$_$r$7$^$9!#(B@code{nil} $B$G$b(B @code{vertical} $B$G$b(B -$BL5$1$l$P!"?eJ?J}8~$H?bD>J}8~$NN>J}$NCf?4:F@_Dj$r9T$$$^$9!#(B - -@item gnus-visible-headers -$B5-;v$K4^$^$l$k%X%C%@!<$r:G>.8B$K8:$i$7$^$9!#.$5$/$9$k;v$,$G$-$^(B -$B$9!#$3$l$OAm$8$F$=$s$J$K8:$i$7$^$;$s!#$3$l$O!"5-;v$r$I$C$A$K$7$mFI$_$?$/(B -$B$J$$$H$$$&;v$r7hDj$9$kA0$K!">/$7$NItJ,$7$+8+$kI,MW$,L5$$$H$$$&;v$G$9!#(B - -@item gnus-threada-hide-subtree -$B$3$l$,(B @code{nil} $B$G$J$1$l$P!"A4$F$N35N,%P%C%U%!$N%9%l%C%I$O=i$a$K1#$5$l(B -$B$^$9!#(B - -@item gnus-updated-mode-lines -$B$3$l$,(B @code{nil} $B$G$"$k$H!"(Bgnus $B$O%P%C%U%!$N%b!<%I9T$K>pJs$rF~$l$^$;$s(B -$B$N$G!";~4V$r@aLs$G$-$k$G$7$g$&!#(B -@end table - - -@node Little Disk Space -@subsection $B>/$7$N%G%#%9%/MFNL(B -@cindex disk space - -$B5/F0%U%!%$%k$OHf3SE*Bg$-$/$J$j$^$9$N$G!"6u$-MFNL$,>/$J$/$J$C$F$-$F$$$k$H(B -$B$-$O$=$NBg$-$5$r>/$7>.$5$/$7$?$$$H;W$&$G$7$g$&!#(B - -@table @code - -@item gnus-save-newsrc-file -$B$3$l$,(B @code{nil} $B$G$"$k$H!"(Bgnus $B$O7h$7$F(B @file{.newsrc} $B$rJ]B8$7$^$;$s(B--- -$B$=$l$O(B @file{.newsrc.eld} $B$N$_$rJ]B8$7$^$9!#$3$l$O!"(Bgnus $B$NB>$N%K%e!<%9(B -$B%j!<%@!<$r;H$($J$$$H$$$&;v$G$9!#$3$NJQ?t$O=i4|@_Dj$G(B @code{t} $B$G$9!#(B - -@item gnus-save-killed-list -$B$3$l$,(B @code{nil} $B$G$"$k$H!"(Bgnus $B$O;`$s$@%0%k!<%W$N%j%9%H$rJ]B8$7$^$;$s!#(B -$B$3$NJQ?t$r(B @code{nil} $B$K@_Dj$7$?$H$-$O!"(B@code{gnus-check-new-newsgroups} -$B$r(B @code{ask-server} $B$K!"(B@code{gnus-check-bogus-newsgroups} $B$r(B -@code{nil} $B$K@_Dj$9$k$Y$-$G$7$g$&!#$3$NJQ?t$O=i4|@_Dj$G(B @code{t} $B$G$9!#(B - -@end table - - -@node Slow Machine -@subsection $BCY$$5!3#(B -@cindex slow machine - -$B$b$7CY$$5!3#$r;}$C$F$$$k$+!"$b$7$/$OC1$KK\Ev$KG&BQNO$,$J$$;~$O!"(Bgnus $B$N(B -$B/$7$"$j$^$9!#(B - -$B5/F0$rB.$/$9$k$?$a$K(B @code{gnus-check-new-newsgroups} $B$H(B -@code{gnus-check-bogus-newsgroups} $B$r(B @code{nil} $B$K@_Dj$7$F2<$5$$!#(B - -$B35N,%P%C%U%!$KF~$k;v$HH4$1$k;v$rB.$/$9$k$?$a$K!"(B@code{gnus-show-threads} -$B$H(B @code{gnus-use-cross-reference} $B$H(B @code{gnus-nov-is-evil} $B$r(B -@code{nil} $B$K@_Dj$7$F2<$5$$!#(B - -$B5-;v$K4X$9$k/$7B.$/$9$k$?$a$K!"(B@code{gnus-article-display-hook} -$B$r(B @code{nil} $B$K@_Dj$7$F2<$5$$!#(B - - -@page -@node Troubleshooting -@section $BLdBj2r7h(B -@cindex troubleshooting - -Gnus $B$OH"$+$i=P$7$F$9$0$K(B @emph{$BHs>o$K(B} $B$h$/F0:n$7$^$9(B---$B2?$bLdBj$N5/$3(B -$B$k$3$H$OA[A|$G$-$^$;$s!"K\Ev$K!#(B - -$B%*%C%[%s!#(B - -@enumerate - -@item -$B$"$J$?$N%3%s%T%e!<%?$N%9%$%C%A$,F~$C$F$$$k;v$r3N$+$a$F2<$5$$!#(B - -@item -$BK\Ev$K8=9T$N(B gnus $BHG$rFI$_9~$s$G$$$k;v$r3NG'$7$F2<$5$$!#:#$^$G(B @sc{gnus} -$B$rC$7$F2<$5$$!#(B - -@item -FAQ $B$H(B how-to $B$rFI$`$?$a$K%X%k%W%0%k!<%W(B ($B%0%k!<%W%P%C%U%!$G(B @kbd{G h}) -$B$rFI$s$G2<$5$$!#(B - -@item -@vindex max-lisp-eval-depth -Gnus $B$OB?$/$NB?$/$N:F5"9=B$$GF0:n$7!"2?$i$+$N6KC<$J(B ($B$=$7$FHs>o$K$^$l$J(B) -$B;vNc$G$O!"(Bgnus $B$O:F5"$r(B ``$B$"$^$j$K?<$/(B'' $B9_$j$9$.$F!"(BEmacs $B$,$"$J$?$K%S!<(B -$B%W2;$rLD$i$9;v$,$"$j$^$9!#$b$7$3$l$,5/$3$C$?$J$i!"(B -@code{max-lisp-eval-depth} $B$r(B 500 $B$+$=$l$/$i$$$NCM$K@_Dj$7$F2<$5$$!#(B -@end enumerate - -$B$b$7B>$NA4$F$,<:GT$7$?$J$i!"%P%0$H$7$FLdBj$rJs9p$7$F2<$5$$!#(B - -@cindex bugs -@cindex reporting bugs - -@kindex M-x gnus-bug -@findex gnus-bug -$B$b$7(B gnus $B$N%P%0$r8+$D$1$?$J$i!"L?Na(B @kbd{M-x gnus-bug} $B$K$h$C$F$=$l$rJs(B -$B9p$9$k;v$,$G$-$^$9!#(B@kbd{M-x set-variable RET debug-on-error RET t RET} -$B$H$7$F!"$=$l$+$i;d$K%P%C%/%H%l!<%9$rAw$C$F2<$5$$!#;d$O%P%0$r=$@5$7$h$&$H(B -$B$7$^$9$,!"$"$J$?$,%P%0$r:F8=$5$;$kJ}K!$r@53N$K=q$$$F$/$l$?$H$-$N$_!"$=$l(B -$B$r=$@5$9$k;v$,$G$-$^$9!#(B - -$B%P%0Js9p$G$O!">\:Y$9$.$k$3$H$O7h$7$F$"$j$^$;$s!#%P%0Js9p$r$9$k$H$-$O!"$=(B -$B$l$,;H$&$?$S$K(B 10Kb $B%a!<%k$r:n$j!"$b$7$"$J$?$N4D6-$r0JA0;d$K(B 500 $B2sAw$C(B -$B$F$-$?$H$7$F$b!"L?Na(B @kbd{M-x gnus-bug} $B$r;H$C$F2<$5$$!#(B - -$B;d$O!"5-21$H$$$&o$K!"A4$F$r@bL@$7$9$.(B -$B$F2<$5$$!#$=$l$O2f!9A4$F$K$H$C$F$b$C$H4JC1$K$J$j$^$9(B---$B$b$7;d$,I,MW$JA4(B -$B$F$N>pJs$rF@$i$l$J$+$C$?$i!";d$O$"$J$?$K%a!<%k$rAw$C$F$5$i$J$k>pJs$r5a$a!"(B -$B$=$N7k2LA4$F$,$h$jB?$/$N;~4V$rLL$7$F$$$kLdBj$,Hs>o$K;k3PE*$G!"$=$l$r>el(B -$B9g$O!"(BEmacs $B$N%&%#%s%I%&$r%U%!%$%k$K%3%T!<$7$F(B ($BNc$($P!"(B@kbd{xwd} $B$G(B)$B!"(B -$B$=$l$r$I$3$+$NC/$+$,(B gnus $B$G$G$-$k2?$+8-$$$b$N$r9M$(=P$7!"$=$N(B -$B>e$=$N8-$$$b$N$r=q$$$F$/$l$k$H$$$&$3$H$G$9!#$3$l$rMF0W$K$9$k$?$a(B -$B$K$O!"(Bgnus $B$NFbItF0:n$r5-=R$9$k$N$,NI$$J}K!$@$m$&$H;d$O;W$$$^$7(B -$B$?!#$"$H!"$=$s$J$KFbIt$8$c$J$$F0:n$r$$$/$D$+$H!";d$,:#$d$C$F$k$3(B -$B$H$H!#(B - -$B%W%m%0%i%`$NFbIt9=B$$,JQ99$5$l$k$3$H$O$J$$!"$J$I$H;W$C$F$O$$$1$^(B -$B$;$s$,!"(Bgnus $B$H$=$N%P%C%/%(%s%I4V$N%$%s%?!<%U%'!<%9(B($B$3$l$O40A4$K(B -$B5-=R$5$l$F$$$k(B)$B$d!"%9%3%"%U%!%$%k$N7A<0(B($B$3$l$bF1MM(B)$B!"%G!<%?9=B$(B -($B$3$l$OB>$h$jJQ99$5$l$d$9$$$b$N$b$"$k(B)$B!"A`:nMQ$N0lHL%a%=%C%I!"$J(B -$B$I$r(B($B:YIt$K$o$?$C$F(B)$BDj5A$7$F$$$-$^$9!#(B - -@menu -* Gnus Utility Functions:: $B;HMQ$G$-$k6&DL$N4X?t$HJQ?t!#(B -* Backend Interface:: Gnus $B$O$I$&$d$C$F%5!<%P!<$HDL?.$9$k$N$+!#(B -* Score File Syntax:: $B%9%3%"%U%!%$%k5,3J$N(B BNF $BDj5A!#(B -* Headers:: Gnus $B$O%X%C%@!<$rFbItE*$K$I$N$h$&$K3JG<$9$k$+!#(B -* Ranges:: $B$?$/$5$s$N?t$r3JG<$9$kJXMx$J7A<0!#(B -* Group Info:: $B%0%k!<%W>pJs7A<0!#(B -* Extended Interactive:: $B5-9f@\F,<-$J$I!#(B -* Emacs/XEmacs Code:: Gnus $B$OA4$F$N6aBe(B Emacsen $B$GF0:n$9$k!#(B -* Various File Formats:: Gnus $B$N;HMQ$9$k%U%!%$%k$N7A<0!#(B -@end menu - - -@node Gnus Utility Functions -@subsection Gnus $B$NM-MQ$J4X?t(B -@cindex Gnus utility functions -@cindex utility functions -@cindex functions -@cindex internal variables - -$B%U%C%/$J$I$+$i.$5$J4X?t$r=q$/$H$-$O!"(Bgnus $B$NFbIt4X?t(B -$B$dJQ?t$K%"%/%;%9$9$k$3$H$O@dBPI,MW$G$9!#0J2<$,:G$b$h$/;H$o$l$k$b(B -$B$N$N0lMw$G$9!#(B - -@table @code - -@item gnus-newsgroup-name -@vindex gnus-newsgroup-name -$B$3$NJQ?t$O8=:_$N%K%e!<%9%0%k!<%W$NL>A0$rJ];}$7$F$$$^$9!#(B - -@item gnus-find-method-for-group -@findex gnus-find-method-for-group -@var{group} $B$NA*BrJ}K!$rJV$94X?t$G$9!#(B - -@item gnus-group-real-name -@findex gnus-group-real-name -$B@55,$N(B ($B@\F,<-IU$-$N(B) gnus $B%0%k!<%WL>$rA0(B -$B$rJV$7$^$9!#(B - -@item gnus-group-prefixed-name -@findex gnus-group-prefixed-name -$B@\F,<-L5$7$N%0%k!<%WL>$HA*BrJ}K!$r$rJV$7$^$9!#(B - -@item gnus-get-info -@findex gnus-get-info -@var{group} $B$N%0%k!<%W>pJs0lMw$rJV$7$^$9!#(B - -@item gnus-group-unread -@findex gnus-group-unread -@var{group} $B$NL$FI5-;v$N?t$+!"$b$7$/$O$=$l$,J,$+$i$J$$>l9g$O(B @code{t} $B$G(B -$B$9!#(B - -@item gnus-active -@findex gnus-active -@var{group} $B$N3hF0EPO?$G$9!#(B - -@item gnus-set-active -@findex gnus-set-active -@var{group} $B$K3hF0EPO?$r@_Dj$7$^$9!#(B - -@item gnus-add-current-to-buffer-list -@findex gnus-add-current-to-buffer-list -Gnus $B=*N;;~$K>C5n$9$k%P%C%U%!$N0lMw$K8=:_$N%P%C%U%!$rDI2C$7$^$9!#(B - -@item gnus-continuum-version -@findex gnus-continuum-version -$B0z?t$H$7$F(B gnus $B$N%P!<%8%g%sJ8;zNs$r.?tE@?t$rJV$7(B -$B$^$9!#8E$$%P!<%8%g%s$OI,$:?7$7$$%P!<%8%g%s$h$j$b>.$5$$?t$K$J$j$^(B -$B$9!#(B - -@item gnus-group-read-only-p -@findex gnus-group-read-only-p -@var{group} $B$,FI$_=P$7@lMQ$G$"$k$+$I$&$+$r<($7$^$9!#(B - -@item gnus-news-group-p -@findex gnus-news-group-p -@var{group} $B$,%K%e!<%9%P%C%/%(%s%I$G$"$k$+$I$&$+$r<($7$^$9!#(B - -@item gnus-ephemeral-group-p -@findex gnus-ephemeral-group-p -@var{group} $B$,C;4|%0%k!<%W$G$"$k$+$I$&$+$r<($7$^$9!#(B - -@item gnus-server-to-method -@findex gnus-server-to-method -@var{server} $B$KBP1~$7$F$$$kA*BrJ}K!$rJV$7$^$9!#(B - -@item gnus-server-equal -@findex gnus-server-equal -$BFs$D$N2>A[%5!<%P!<$,F10l$N$b$N$G$"$k$+$I$&$+$r<($7$^$9!#(B - -@item gnus-group-native-p -@findex gnus-group-native-p -@var{group} $B$,4pK\%0%k!<%W$G$"$k$+$I$&$+$r<($7$^$9!#(B - -@item gnus-group-secondary-p -@findex gnus-group-secondary-p -@var{group} $B$,Fs t -@end lisp - -@item gnus-read-method -@findex gnus-read-method -$BMxMQA[%0%k!<%W$K$D$$$F$O2?$K(B -$B$bCN$j$^$;$s!#$?$@2>A[%5!<%P!<(B @dfn{virtual servers} $B$HBPOC$9$k(B -$BJ}K!$rCN$C$F$$$k$@$1$G$9!#2>A[%5!<%P!<$O%P%C%/%(%s%I(B -@dfn{backend} $B$H$$$/$D$+$N%P%C%/%(%s%IJQ?t(B @dfn{backend -variables} $B$+$i$J$j$^$9!#A0pJs$rMW(B -$B5a$9$k$H$-$O!"DL>o4X?t$N0z?t$H$7$F2>A[%5!<%P!$r4^$a$^$9!#(B ($B$b(B -$B$7$J$1$l$P!"%P%C%/%(%s%I$O(B ``$B8=:_$N(B'' $B2>A[%5!<%P!<$r;HMQ$7$^$9!#(B) -$BNc$($P!"(B@code{nntp-request-list} $B$O$=$NM#0l$N(B ($B>JN,2DG=$J(B) $B0z?t(B -$B$H$7$F2>A[%5!<%P!<$rA[%5!<%P!<$,3+$+$l$F$$$J(B -$B$1$l$P!"$3$N4X?t$O<:GT$7$^$9!#(B - -$B2>A[%5!<%P!$O!"J*M}E*$J%5!<%P!$H$O2?$N4X78$bL5$$$3$H$KCm0U(B -$B$7$F$/$@$5$$!#$3$NNc$r8+$F$/$@$5$$!#(B - -@lisp -(nntp "odd-one" - (nntp-address "ifi.uio.no") - (nntp-port-number 4324)) -@end lisp - -$B$3$3$G!"J*M}%5!<%P!$O(B @samp{ifi.uio.no} $B$G$"$k$N$KBP$7!"2>A[(B -$B%5!<%P!$O(B @samp{odd-one} $B$G$9!#(B - -$B%P%C%/%(%s%I$OJ#?t$N2>A[%5!<%P!<$r@Z$jBX$(2DG=$G$J$1$l$P$J$j$^$;(B -$B$s!#I8=`$N%P%C%/%(%s%I$O$3$l$r!"2>A[%5!<%P!<4D6-$rI,MW$J$H$-$Ko$K3NG'$9$kG$0U4X?t(B @dfn{optional -functions} $B$G$9!#(B - -$B$3$l$i$N4X?t$OA4$F!"JV5Q%G!<%?$r(B @code{nntp-server-buffer} -(@samp{ *nntpd*}) $B%P%C%U%!!<$KJV$9$3$H$,5a$a$i$l$^$9!#$3$l$O$A$g$C(B -$B$HIT1?$JL>A0IU$1$G$9$,!"$3$l$G2fK}$7$J$1$l$P$J$j$^$;$s!#;d$,7k2L(B -$B$N%G!<%?(B @dfn{resulting data} $B$H8@$C$?$H$-$O!"$=$N%P%C%U%!!<$NCf(B -$B$N%G!<%?$r;X$7$F$$$^$9!#JV5QCM(B @dfn{return value} $B$H8@$C$?$H$-$O!"(B -$B4X?t8F$S=P$7$K$h$C$FJV$5$l$k4X?t$NCM$N$3$H$r8@$C$F$$$^$9!#4X?t$,(B -$B<:GT$7$?$H$-$OJV5QCM$H$7$F(B @code{nil} $B$rJV$5$J$/$F$O$$$1$^$;$s!#(B - -$B%P%C%/%(%s%I$K$O%5!<%P!<7A<0(B @dfn{server-forming} $B$N%P%C%/%(%s%I(B -$B$G$"$k$H8F$P$l$k$b$N$,$"$j!"$^$?$=$&8F$P$l$J$$$b$N$b$"$j$^$9!#8e(B -$BpJs$rG[Aw$9$k$b$N$G!"$=$l0J>e$N$b$N$G$O$"$j$^$;$s!#(B - -$B$3$3$G$NNc$HDj5A$G$O!"A[A|>e$N%P%C%/%(%s%I(B @code{nnchoke} $B$r0z$-(B -$B9g$$$K=P$9$3$H$K$7$^$9!#(B - -@cindex @code{nnchoke} - -@menu -* Required Backend Functions:: $BJ,$J(B -$B%X%C%@!o!"(B@code{articles} $B$NCf(B -$B$N:G>.HV9f$N5-;v$h$j$b>.$5$$5-;v$+$i(B ($B>/$J$/$H$b(B) -@var{fetch-old} $B8D$NM>J,$J%X%C%@!<$r$&$3$H$rHQ$o$7$$$H;W$C$?(B -$B>l9g$K$O!"$3$N%Q%i%a!<%?$NB8:_$OL5;k$5$l$k$3$H$b$"$j$^$9!#$3$NCM(B -$B$,(B @code{nil} $B$G$b?t;z$G$b$J$1$l$P!":GBg8B$N -References: <38jdmq$4qu@@visbur.ifi.uio.no> -NNTP-Posting-Host: holmenkollen.ifi.uio.no -. -@end example - -$B$D$^$j!"JV5QCM$,(B @code{headers} $B$G$"$k$H$-$O!"%G!<%?%P%C%U%!$K$3(B -$B$l$i%X%C%@!<$,$$$/$D$+$"$k$H$$$&$3$H$r0UL#$7$^$9!#(B - -$B$3$l$,$=$N%P%C%U%!!<$N(B BNF $BDj5A$G$9!#(B - -@example -headers = *head -head = error / valid-head -error-message = [ "4" / "5" ] 2number " " eol -valid-head = valid-message *header "." eol -valid-message = "221 " " Article retrieved." eol -header = eol -@end example - -$B$b$7JV5QCM$,(B @code{nov} $B$G$"$l$P!"%G!<%?%P%C%U%!!<$K$O(B -@dfn{network overview database} $B9T$,4^$^$l$F$J$/$F$O$J$j$^$;$s!#(B -$B$3$l$O4pK\E*$K$OJ#?t$NMs$r%?%V$G6h@Z$C$?$b$N$G$9!#(B - -@example -nov-buffer = *nov-line -nov-line = 8*9 [ field ] eol -field = -@end example - -$B$3$l$i$NMs$K$I$N$h$&$J$b$N$,4^$^$l$k$+$r$h$j>\$7$/8+$?$1$l$P!"(B -@pxref{Headers} $B$r;2>H$7$F$/$@$5$$!#(B - - -@item (nnchoke-open-server SERVER &optional DEFINITIONS) - -$B$3$3$G$N(B @var{server} $B$O2>A[%5!<%P!$G$9!#(B@var{definitions} $B$O(B -$B$3$N2>A[%5!<%P!<$rDj5A$9$k(B @code{(VARIABLE VALUE)} $BAH$N%j%9%H$G(B -$B$9!#(B - -$B$b$7%5!<%P!<$r3+$/$3$H$,$G$-$J$1$l$P!"%(%i!<$O%7%0%J%k$G$ODLCN$5(B -$B$l$^$;$s!#$=$7$F%P%C%/%(%s%I$O!"$=$l0J8e$N$3$N%5!<%P!<$X$N@\B3MW(B -$B5a$r5qH]$9$k$3$H$b$G$-$^$9!#o!"(Bgnus $B$,=*N;$9$k$H$-$K$N$_8F$S=P$5$l$^$9!#(B - -$BJV$5$l$k7k2L$N%G!<%?$O$"$j$^$;$s!#(B - - -@item (nnchoke-server-opened &optional SERVER) - -$B$b$7(B @var{server} $B$,8=:_$N2>A[%5!<%P!<$G!"$=$NJ*M}%5!<%P!<$X$N@\(B -$BB3$,@8$-$F$$$l$P!"$3$N4X?t$O(B @code{nil} $B0J30$NCM$rJV$7$^$9!#$3$N(B -$B4X?t$O$I$s$J>l9g$G$b!"@\B3$,<:$o$l$?%5!<%P!<$X$N:F@\B3$r9T$J$&$3(B -$B$H$O$"$j$^$;$s!#(B - -$BJV$5$l$k7k2L$N%G!<%?$O$"$j$^$;$s!#(B - - -@item (nnchoke-status-message &optional SERVER) - -$B$3$N4X?t$O(B @var{server} $B$+$i$N:G8e$N%(%i!<%a%C%;!<%8$rJV5Q$7$^$9!#(B - -$BJV$5$l$k7k2L$N%G!<%?$O$"$j$^$;$s!#(B - - -@item (nnchoke-request-article ARTICLE &optional GROUP SERVER TO-BUFFER) - -$B$3$N4X?t$N7k2L$N%G!<%?$O!"(B@var{article} $B$G;XDj$5$l$?5-;v$G$9!#$3(B -$B$N;XDj$O(B @code{Message-ID} $B$+HV9f$N$$$:$l$+$G$9!#(B -@code{Message-ID} $B$K$h$k5-;v$No$N(B -$B%G!<%?%P%C%U%!$NBe$o$j$K!"$3$N%P%C%U%!$KJV$5$l$^$9!#$3$l$K$h$jB?(B -$BNL$N%G!<%?$r$"$k%P%C%U%!$+$iJL$N%P%C%U%!$K%3%T!<$9$k$3$H$rHr$1$k(B -$B$3$H$,$G$-!"$=$7$F(B gnus $B$ODL>o!"5-;v%P%C%U%!$KD>@\5-;v$rA^F~$9$k(B -$B$h$&$KMW5a$7$F$$$^$9!#(B - -$B$b$72DG=$G$"$k$N$J$i!"$3$N4X?t$O!"(B@code{car}$B$,$G!"(B@code{cdr} $B$,5-;vHV9f$G$"$k(B cons $B%;%k$rJV$9$Y$-$G(B -$B$9!#$3$l$K$h$j(B @code{Message-ID} $B$K$h$C$F5-;v$rl9g$K$O!"5-;v$NuBV$G!"$3$l$O(B 211 $B$G$J$/$F$O$J$j$^$;$s!#.$N5-;vHV9f!":GBg$N5-;vHV9f!"$=$7$F:G(B -$B8e$,%0%k!<%WL>$G$9!#5-;v$NAm?t$O!":GBg!&:G>.5-;vHV9f$+$iC1=c$K9M(B -$B$($i$l$k?t$h$j$b>.$5$$$3$H$,$"$k$3$H$KCm0U$7$F$/$@$5$$!#$$$/$D$+(B -$B$N5-;v$OC$5$l$F$$$k$+$b$7$l$^$;$s!#(BGnus $B$OAm?t$OC1$K " " -info = "211 " 3* [ " " ] -@end example - - -@item (nnchoke-close-group GROUP &optional SERVER) - -@var{group} $B$rJD$8!"$=$l$K@\B3$5$l$F$$$kA4$F$N;q8;$r3+J|$7$^$9!#(B -$B$3$l$O$[$H$s$I$N%P%C%/%(%s%I$G$O2?$b$9$k$3$H$,$J$$$G$7$g$&!#(B - -$BJV$5$l$k7k2L$N%G!<%?$O$"$j$^$;$s!#(B - - -@item (nnchoke-request-list &optional SERVER) - -@var{server} $B>e$GMxMQ2DG=$JA4$F$N%0%k!<%W$N0lMw$rJV$7$^$9!#$3$l(B -$B$O(B @emph{$BA4It(B} $B$H$$$&0UL#$G$9!#(B - -$B$3$l$,!"$?$C$?Fs$D$7$+%0%k!<%W$r;}$C$F$$$J$$%5!<%P!<$+$i$NNc$G$9!#(B - -@example -ifi.test 0000002200 0000002000 y -ifi.discussion 3324 3300 n -@end example - -$B3F9T$K$O%0%k!<%WL>$,$"$j!"$=$7$F$=$N%0%k!<%WFb$N:GBg$N5-;vHV9f!"(B -$B:G>.$N5-;vHV9f!"$=$7$F:G8e$K%U%i%0$G$9!#(B - -@example -active-file = *active-line -active-line = name " " " " " " flags eol -name = -flags = "n" / "y" / "m" / "x" / "j" / "=" name -@end example - -$B%U%i%0$O!"$=$N%0%k!<%W$,FI$_=P$7@lMQ(B (@samp{n}) $B$G$"$k$+!";J2q$N%0(B -$B%k!<%W$NJLL>(B (@samp{=other-group}) $B$G$"$k$+!">e5-$N$I$l$G$b$J$$(B -(@samp{y}) $B$+!"$H$$$&$3$H$r<($7$F$$$^$9!#(B - - -@item (nnchoke-request-post &optional SERVER) - -$B$3$N4X?t$O!"8=:_$N%P%C%U%!$rEj9F$7$^$9!#$3$l$OEj9F$,@.8y$7$?$+$I(B -$B$&$+$rJV5Q$7$F$b9=$$$^$;$s$,!"I,?\$G$O$"$j$^$;$s!#Nc$($P!"Ej9F$,(B -$BHsF14|$K9T$o$l$k$N$G$"$l$P!"$3$N4X?t$,=*N;$7$?;~E@$G$OEj9F$OIaDL(B -$B40N;$7$F$$$^$;$s!#$=$N>l9g$3$N4X?t$O!"Ej9F$r40N;$5$;$k$3$H$,$G$-(B -$B$J$$$H$-!"$=$l$r$O$C$-$j$HMxMQpJs(B (@pxref{Group Info}) $B$,JQ992U=j$H$7$F%P%C%/%((B -$B%s%I$KEO$5$l$^$9!#$3$l$O%P%C%/%(%s%I$,(B ($B2>A[%0%k!<%W$d(B imap $B%0%k!<(B -$B%W$N>l9g$N$h$&$K(B) $BK\Ev$KA4$F$N>pJs$r;}$C$F$$$k>l9g$KJXMx$K$J$j$^(B -$B$9!#$3$N4X?t$O!"$=$NMW5a$KE,9g$5$;$k>pJs$rGK2uE*$KCV$-49$(!"$=$N(B -($BCV$-49$($i$l$?(B) $B%0%k!<%W>pJs$rJV$7$^$9!#(B - -$B$3$N4X?t$+$iJV$5$l$k7k2L$N%G!<%?$O$"$j$^$;$s!#(B - - -@item (nnchoke-request-type GROUP &optional ARTICLE) - -$BMxMQJ}$H$b(B @code{nil} $B$G$"$k$+$b$7$l$^$;$s!#(B - -$B$3$N4X?t$+$iJV$5$l$k7k2L$N%G!<%?$O$"$j$^$;$s!#(B - - -@item (nnchoke-request-update-mark GROUP ARTICLE MARK) - -$B$b$7MxMQ$N%4%_$r(B -$BJV$7$F$O$$$1$^$;$s!#(B - -$B;d$,CN$C$F$$$k$3$l$N$3$l$NMxMQK!$O!"(B@code{nnvirtual} $B$,9T$J$C$F(B -$B$$$k$3$H$@$1$G$9(B --- $B$b$79=@.%0%k!<%W$,<+F04|8B@Z$l>C5n2DG=$G$"(B -$B$l$P!"$3$N2>A[%0%k!<%W$G4{FI$N0u$rIU$1$k$H!"7k2L$H$7$F$=$N5-;v$K(B -$B4|8B@Z$l>C5n$N0u$,IU$1$i$l$^$9!#(B - -$B$3$N4X?t$+$iJV$5$l$k7k2L$N%G!<%?$O$"$j$^$;$s!#(B - - -@item (nnchoke-request-scan &optional GROUP SERVER) - -$B$3$N4X?t$O!"%P%C%/%(%s%I$,E~Ce5-;v$r3NG'$9$kMW5a$r9T$J$&$H$-$K$$(B -$B$D$G$b(B (gnus $B$+$=$l0J30$K$h$C$F(B) $B!"$"$l$d$3$l$d$H8F$S=P$5$l$k$3(B -$B$H$,$"$j$^$9!#%a!<%k%P%C%/%(%s%I$O$3$N4X?t$,5/F0$5$l$?$H$-!"E57?(B -$BE*$K$O%9%W!<%k%U%!%$%k$rFI$`$+(B POP $B%5!<%P!<$KLd$$9g$o$;$K$$$-$^(B -$B$9!#(B@var{group} $B$OFC$K5$$KN1$a$kI,MW$O$"$j$^$;$s(B --- $B$b$7%P%C%/(B -$B%(%s%I$,!"0l$D$@$1$N%0%k!<%W$rAv::$9$k$N$OBgJQ$9$.$k$HH=CG$7$?>l(B -$B9g$K$O!"A4%0%k!<%W$NA4Av::$r9T$J$C$F$b9=$$$^$;$s!#$G$9$,!" description eol -name = -description = -@end example - -@item (nnchoke-request-list-newsgroups &optional SERVER) - -$B$3$N4X?t$K$h$C$FJV$5$l$k7k2L$N%G!<%?$O!"%5!<%P!<>e$GMxMQ$G$-$k%0(B -$B%k!<%WA4$F$N@bL@$G$9!#(B - -@example -description-buffer = *description-line -@end example - - -@item (nnchoke-request-newgroups DATE &optional SERVER) - -$B$3$N4X?t$+$iJV$5$l$k7k2L$N%G!<%?$O!"(B@samp{date} $B0J9_$K:n@.$5$l$?(B -$BA4$F$N%0%k!<%W$G$9!#(B@samp{date} $B$ODL>o$N?M4V$,FI$a$kF|IU$N7A<0$G(B -$B$9!#%G!<%?$O(B active $B%P%C%U%!$N7A<0$G$J$1$l$P$J$j$^$;$s!#(B - - -@item (nnchoke-request-create-group GROUP &optional SERVER) - -$B$3$N4X?t$O!"(B@var{group} $B$H$$$&L>A0$N6u$N%0%k!<%W$r:n@.$7$^$9!#(B - -$BJV$5$l$k7k2L$N%G!<%?$O$"$j$^$;$s!#(B - - -@item (nnchoke-request-expire-articles ARTICLES &optional GROUP SERVER FORCE) - -$B$3$N4X?t$O!"(B@var{articles} $B$NHO0O$NA4$F$N5-;v$KBP$7$F4|8B@Z$l>C(B -$B5n=hM}$r9T$J$$$^$9!#(B (@var{articles} $B$O8=:_$O5-;vHV9f$NC1=c$J%j(B -$B%9%H$G$9!#(B) $B$3$N4X?t$G>C5n$5$l$kA0$N!"5-;v$,$I$l$@$18E$$5-;v$G$"(B -$B$k$+$N7hDj$O%P%C%/%(%s%I$KG$$5$l$F$$$^$9!#(B@var{force} $B$,(B -@code{nil} $B0J30$G$"$l$P!"$=$l$,$I$s$J$K?7$7$$$b$N$G$"$C$F$b!"A4(B -$B$F$N(B @var{articles} $B$,>C5n$5$l$^$9!#(B - -$B$3$N4X?t$O:o=|$7$J$+$C$?!"$"$k$$$O:o=|$9$k$3$H$,$G$-$J$+$C$?5-;v(B -$B$N%j%9%H$rJV$7$^$9!#(B - -$BJV$5$l$k7k2L$N%G!<%?$O$"$j$^$;$s!#(B - - -@item (nnchoke-request-move-article ARTICLE GROUP SERVER ACCEPT-FORM -&optional LAST) - -$B$3$N4X?t$O(B @var{article} ($BHV9f(B) $B$r!"(B @var{group} $B$+$i(B -@var{accept-form} $B$r8F$S=P$7$F0\F0$7$^$9!#(B - -$B$3$N4X?t$O!"LdBj$N5-;v$r0\F0$5$;$k$?$a$N=`Hw$H$7$F!"5-;v$KIU2C$5(B -$B$l$?%X%C%@!<9T$rA4$F:o=|$7!"0lHL$K5-;v$r!V$-$l$$$5$C$Q$j!W$K$7$^(B -$B$9!#$=$7$F(B ``$B$-$l$$$J(B'' $B5-;v$N$"$k%P%C%U%!!<$G(B @var{accept-form} -$B$r(B @code{eval} $B$7$^$9!#$3$l$OK\Ev$KJ#@=$r9T$J$$$^$9!#$b$7(B -@code{eval} $B$,(B @code{nil} $B0J30$NCM$rJV$7$?$i!"$=$N5-;v$O:o=|$5$l(B -$B$^$;$s!#(B - -@var{last} $B$,(B @code{nil} $B$G$"$l$P!"$3$ND>8e$K$5$i$KMW5a$,H/9T$5(B -$B$l$k8+9~$_$,9b$$!"$H$$$&0UL#$K$J$j!"$3$l$K$h$C$F:GE,2=$,$$$/$i$+(B -$B$G$-$k$h$&$K$J$j$^$9!#(B - -$B$3$N4X?t$O!"%0%k!<%WL>$,(B @code{car} $B$G!"$=$N5-;v$N0\F0@h$N5-;vHV(B -$B9f$,(B @code{cdr} $B$G$"$k(B cons $B%;%k$rJV$7$^$9!#(B - -$BJV$5$l$k7k2L$N%G!<%?$O$"$j$^$;$s!#(B - - -@item (nnchoke-request-accept-article GROUP &optional SERVER LAST) - -$B$3$N4X?t$O!"8=:_$N%P%C%U%!$r$A$K9T$o$l$k$H$$$&0UL#$G$9!#(B - -$B$3$N4X?t$O%0%k!<%WL>$,(B @code{car} $B$G!"$=$N5-;v$N0\F0@h$N5-;vHV9f(B -$B$,(B @code{cdr} $B$G$"$k(B cons $B%;%k$rJV$7$^$9!#(B - -$BJV$5$l$k7k2L$N%G!<%?$O$"$j$^$;$s!#(B - - -@item (nnchoke-request-replace-article ARTICLE GROUP BUFFER) - -$B$3$N4X?t$O(B @var{article} ($BHV9f(B) $B$r(B @var{group} $B$+$i:o=|$7!"Be$o(B -$B$j$K(B @var{buffer} $B$r$=$3$KA^F~$7$^$9!#(B - -$BJV$5$l$k7k2L$N%G!<%?$O$"$j$^$;$s!#(B - - -@item (nnchoke-request-delete-group GROUP FORCE &optional SERVER) - -$B$3$N4X?t$O(B @var{group} $B$r>C5n$7$^$9!#(B $B$b$7(B @var{force} $B$,$"$l$P!"(B -$B$=$N%0%k!<%WFb$NA4$F$N5-;v$rK\Ev$K>C5n$7!"$=$7$F$=$N%0%k!<%W<+?H(B -$B$r>C5n$7$^$9!#(B ($B$b$7(B ``$B%0%k!<%W<+?H(B'' $B$H$$$&$b$N$,$"$l$P!#(B) - -$BJV$5$l$k7k2L$N%G!<%?$O$"$j$^$;$s!#(B - - -@item (nnchoke-request-rename-group GROUP NEW-NAME &optional SERVER) - -$B$3$N4X?t$O(B @var{group} $B$+$i(B @var{new-name} $B$KL>A0$rJQ99$7$^$9!#(B -@var{group} $BFb$K$"$k5-;v$OA4$F(B @var{new-name} $B$K0\F0$7$^$9!#(B - -$BJV$5$l$k7k2L$N%G!<%?$O$"$j$^$;$s!#(B - -@end table - - -@node Error Messaging -@subsubsection $B%(%i!<%a%C%;!<%8I=<((B - -@findex nnheader-report -@findex nnheader-get-report -$B%P%C%/%(%s%I$O%(%i!<>u67$rJs9p$9$k$N$K(B @code{nnheader-report} $B$r(B -$B;H$o$J$/$F$O$J$j$^$;$s(B --- $BMW5a$r$N%7%s%\(B -$B%k$G!";D$j$O!"J#?t$N0z?t$,$"$l$P(B @code{format} $B$X$N0z?t$H$7$F2r(B -$Bo$K(B -@code{nil} $B$rJV$5$J$/$F$O$J$j$^$;$s!#(B - -@lisp -(nnheader-report 'nnchoke "You did something totally bogus") - -(nnheader-report 'nnchoke "Could not request group %s" group) -@end lisp - -$B0lJ}(B gnus $B$O!"%5!<%P!<$+$i(B @code{nil} $B$rJV$5$l$?$H$-$K(B -@code{nnheader-get-report} $B$r8F$S=P$7!"$=$7$F$3$N4X?t$,LdBj$N%P%C(B -$B%/%(%s%I$KBP$7$F:G8e$KJs9p$5$l$?%a%C%;!<%8$rJV$7$^$9!#$3$N4X?t$O(B -$B0l$D$N0z?t(B --- $B%5!<%P!<$N%7%s%\%k$re$N5-;v$rJT=8$9$k(B -$B$3$H$,$G$-$^$9!#(B@code{nnmh} $B$O(B @code{nnml} $B$K$H$F$b;w$F$$$^$9$,!"(B -$B$3$l$O%"%/%F%#%V%U%!%$%k$r;H$o$:!"35MW%G!<%?%Y!<%9$bJ];}$7$^$;$s!#(B -@code{nndir} $B$O(B @code{nnml} $B$K$H$F$b;w$F$$$^$9$,!"$3$l$K$O(B ``$B%0(B -$B%k!<%W(B'' $B$N35G0$O$J$/!"5-;v$N=$@5$O$G$-$^$;$s!#(B - -$B?7$7$$%P%C%/%(%s%I$r=q$/$H$-$KB>$N%P%C%/%(%s%I$+$i4X?t$r(B ``$B7Q>5(B'' -$B$9$k$3$H$,2DG=$G$"$C$F$[$7$$!"$H;W$&$N$OM}$KE,$C$F$$$^$9!#$=$7$F(B -$B$^$5$K!"$"$J$?$,$=$&$7$?$1$l$P!"$=$l$,$G$-$k$N$G$9!#(B($B$"$J$?$,$=(B -$B$&$7$?$/$J$1$l$P$7$J$/$F$bNI$$$G$9$h!"$b$A$m$s!#(B) - -$BA4$F$N%P%C%/%(%s%I$O8x3+JQ?t$H8x3+4X?t$r!"(B @code{nnoo} $B$H8F$P$l(B -$B$k%Q%C%1!<%8$r;H$C$F@k8@$7$^$9!#(B - -$BB>$N%P%C%/%(%s%I$+$i4X?t$r7Q>5$9$k$K$O(B ($B$=$7$F8=:_$N%P%C%/%(%s%I(B -$B$+$iB>$N%P%C%/%(%s%I$K4X?t$r7Q>5$G$-$k$h$&$K$9$k$K$O(B) $B!"0J2<$N%^(B -$B%/%m$r;HMQ$7$J$1$l$P$J$j$^$;$s!#(B - -@table @code - -@item nnoo-declare -$B$3$N%^%/%m$O!":G=i$N0z?t$r!"$=$N8e$KB3$/0z?t$N;R6!$G$"$k$3$H$r@k(B -$B8@$7$^$9!#Nc$($P!"(B - -@lisp -(nnoo-declare nndir - nnml nnmh) -@end lisp - -$B$3$l$G(B @code{nndir}$B$O!"(B@code{nnml} $B$H(B @code{nnmh} $B$NN>J}$+$i4X?t(B -$B$r7Q>5$7$h$&$H$7$F$$$k$3$H$r@k8@$7$^$9!#(B - -@item defvoo -$B$3$N%^%/%m$O(B @code{defvar} $B$HF15A$G$9$,!"$=$NJQ?t$r8x3+%5!<%P!<(B -$BJQ?t$H$7$FEPO?$7$^$9!#$[$H$s$I$N>uBV;X8~7?$NJQ?t$O(B @code{defvar} -$B$G$O$J$/(B @code{defvoo} $B$K$h$C$F@k8@$9$k$Y$-$G$9!#(B - -$BDL>o$N(B @code{defvar} $B0z?t$K2C$($F!"$3$N%^%/%m$O?F%P%C%/%(%s%I$N(B -$BJQ?t$N%j%9%H$ro$N(B @code{defun} $B=hM}$K2C$($F!"$3$N%^%/%m$O$=$N4X?t$r8x(B -$B3+$7$F$$$k$b$N$H$7$FEPO?$7!"B>$N%P%C%/%(%s%I$,$=$l$r7Q>5$G$-$k$h(B -$B$&$K$7$^$9!#(B - -@item nnoo-map-functions -$B$3$N%^%/%m$O8=:_$N%P%C%/%(%s%I$N4X?t$+$i?F%P%C%/%(%s%I$N4X?t$X$N(B -$BCV$-49$($r9T$J$($k$h$&$K$7$^$9!#(B - -@example -(nnoo-map-functions nndir - (nnml-retrieve-headers 0 nndir-current-group 0 0) - (nnmh-request-article 0 nndir-current-group 0 0)) -@end example - -$B$3$l$O(B @code{nndir-retrieve-headers} $B$,8F$S=P$5$l$?$H$-!"0lHVL\!"(B -$B;0HVL\!";MHVL\$N0z?t$,(B @code{nnml-retrieve-headers} $B$KEO$5$l!"0l(B -$BJ}!"FsHVL\$N0z?t$O(B @code{nndir-current-group} $B$NCM$H$7$F@_Dj$5$l(B -$B$k!"$H$$$&0UL#$G$9!#(B - -@item nnoo-import -$B$3$N%^%/%m$OB>$N%P%C%/%(%s%I$+$i4X?t$rA0$HE,Ev$J?t$NG=NO(B @dfn{abilities} $B$G$9!#(B - -$B$3$l$,Nc$G$9!#(B - -@lisp -(gnus-declare-backend "nnchoke" 'mail 'respool 'address) -@end lisp - -$BG=NO$K$O0J2<$N$b$N$,$"$j$^$9!#(B - -@table @code -@item mail -$B$3$l$O%a!<%kIw%P%C%/%(%s%I$G$9(B --- $B%U%)%m!<%"%C%W$O(B ($B$?$$$F$$$O(B) -$B%a!<%k$GAw$i$l$^$9!#(B -@item post -$B$3$l$O%K%e!<%9Iw%P%C%/%(%s%I$G$9(B --- $B%U%)%m!<%"%C%W$O(B ($B$?$$$F$$(B -$B$O(B) $B%K%e!<%9$GAw$i$l$^$9!#(B -@item post-mail -$B$3$N%P%C%/%(%s%I$O%a!<%k$H%K%e!<%9$NN>J}$r%5%]!<%H$7$^$9!#(B -@item none -$B$3$l$O%K%e!<%9$G$b%a!<%k$G$b$J$$%P%C%/%(%s%I$G$9(B --- $BA4$/0c$C$?(B -$B2?$+$G$9!#(B -@item respool -$B$3$l$O:F%9%W!<%k$r%5%]!<%H$7$^$9(B --- $B$H$$$&$h$j$O!"$=$N85$N5-;v(B -$B$H%0%k!<%W$r=$@5$9$k$3$H$,$G$-$^$9!#(B -@item address -$B2>A[%5!<%P!$NCf$K%5!<%P!<$NL>A0$,4^$^$k$H$$$&$3$H$G$9!#$3$l$O(B -$B$[$H$s$IA4It$N%P%C%/%(%s%I$GI,MW$K$J$j$^$9!#(B -@item prompt-address -$B%0%k!<%W%P%C%U%!$G(B @kbd{B} $B$J$I$G$3$NL?Na$r$N%P%C%/%(%s%I$KBP$7$F0l@~$r2h$7$F$$$k(B -$BE@$O!"%a!<%k%P%C%/%(%s%I$O(B @file{nnmail.el} $B$NCf$N6&DL4X?t$K6/$/(B -$B0MB8$7$F$$$k$H$$$&E@$G$9!#Nc$($P!"(B@code{nnml-request-scan} $B$NDj(B -$B5A$O$3$N$h$&$K$J$j$^$9!#(B - -@lisp -(deffoo nnml-request-scan (&optional group server) - (setq nnml-article-file-alist nil) - (nnmail-get-new-mail 'nnml 'nnml-save-nov nnml-directory group)) -@end lisp - -$BC1$K(B @code{nnmail-get-new-mail} $B$K$$$/$D$+0z?t$rM?$($F8F$S=P$9$@(B -$B$1$G!"(B@code{nnmail} $B$,%a!<%k$N0\F0$dJ,N%$rA4$F$NLLE]$r8+$F$/$l$^(B -$B$9!#(B - -$B$3$N4X?t$O;M$D$N0z?t$rl=j$G$9!#(B - -@item group -$B$3$N>JN,2DG=$J0z?t$O!"J,N%$,0l$D$N%0%k!<%W$KBP$7$F$N$_$G$9!#(B -@end table - -@code{nnmail-get-new-mail} $B$O3F5-;v$rJ]B8$9$k$?$a$K(B -@var{backend}@code{-save-mail} $B$r8F$S=P$7$^$9!#(B -@var{backend}@code{-active-number} $B$O$3$N5-;v$K3d$jEv$F$i$l$?5-(B -$B;vHV9f$rD4$Y$k$?$a$K8F$S=P$5$l$^$9!#(B - -$B$3$N4X?t$Oo$K=@Fp$J$h$&$K0U?^$5$l$F$$$^(B -$B$9!#$=$l$K$O(B Emacs Lisp $B$N%j%9%H$HF1$8FI$_9~$_9=J8$JMM$J$b$N$,$=$N;XDj$K(B -$B9g$&$@$m$&$H$$$&;v$,7hDj$5$l$^$7$?!#(B - -$B$3$l$ONI$/$"$k%9%3%"%U%!%$%k$G$9(B: - -@lisp -(("summary" - ("win95" -10000 nil s) - ("Gnus")) - ("from" - ("Lars" -1000)) - (mark -100)) -@end lisp - -$B%9%3%"%U%!%$%k$N(B BNF $BDj5A$G$9!#(B - -@example -score-file = "" / "(" *element ")" -element = rule / atom -rule = string-rule / number-rule / date-rule -string-rule = "(" quote string-header quote space *string-match ")" -number-rule = "(" quote number-header quote space *number-match ")" -date-rule = "(" quote date-header quote space *date-match ")" -quote = -string-header = "subject" / "from" / "references" / "message-id" / - "xref" / "body" / "head" / "all" / "followup" -number-header = "lines" / "chars" -date-header = "date" -string-match = "(" quote quote [ "" / [ space score [ "" / - space date [ "" / [ space string-match-t ] ] ] ] ] ")" -score = "nil" / -date = "nil" / -string-match-t = "nil" / "s" / "substring" / "S" / "Substring" / - "r" / "regex" / "R" / "Regex" / - "e" / "exact" / "E" / "Exact" / - "f" / "fuzzy" / "F" / "Fuzzy" -number-match = "(" [ "" / [ space score [ "" / - space date [ "" / [ space number-match-t ] ] ] ] ] ")" -number-match-t = "nil" / "=" / "<" / ">" / ">=" / "<=" -date-match = "(" quote quote [ "" / [ space score [ "" / - space date [ "" / [ space date-match-t ] ] ] ] ")" -date-match-t = "nil" / "at" / "before" / "after" -atom = "(" [ required-atom / optional-atom ] ")" -required-atom = mark / expunge / mark-and-expunge / files / - exclude-files / read-only / touched -optional-atom = adapt / local / eval -mark = "mark" space nil-or-number -nil-or-number = "nil" / -expunge = "expunge" space nil-or-number -mark-and-expunge = "mark-and-expunge" space nil-or-number -files = "files" *[ space ] -exclude-files = "exclude-files" *[ space ] -read-only = "read-only" [ space "nil" / space "t" ] -adapt = "adapt" [ space "ignore" / space "t" / space adapt-rule ] -adapt-rule = "(" *[ *[ "(" ")" ] ")" -local = "local" *[ space "(" space
    ")" ] -eval = "eval" space -space = *[ " " / / ] -@end example - -$B%9%3%"%U%!%$%k$NG'<1IT2DG=$JMWAG$OL5;k$5$l$k$Y$-$G$9$,!"o$KIiC4$N$+$1$i$l$9$.$?8l$G$9!#(B ``$B%X%C%@!<(B'' $B$O(B -RFC1036 $B$G$O5-;v$NF,$N9T$N;v(B ($BNc$($P!"(B@code{From}) $B$rOC$9$N$KMQ$$$i$l$F(B -$B$$$^$9!#$=$l$OB?$/$N?M$+$i(B ``$B%X%C%I(B''---``$B%X%C%@!<$HK\BN(B'' $B$NF15A8l$H$7(B -$B$F;H$o$l$F$$$^$9!#(B ($B$3$l$O!";d$N0U8+$G$OHr$1$i$l$k$Y$-$G$9!#(B) $B$=$7$F!"(B -gnus $B$OFbIt$G$O(B ``$B%X%C%@!<(B'' $B$H8F$VMM<0$r;H$C$F$*$j!";d$O$3$3$G$=$l$K$D(B -$B$$$F@bL@$7$^$9!#$3$l$O(B9$B$D$NMWAG$+$i$J$k%Y%/%H%k$G!"4pK\E*$K!"$=$l$>$l$N(B -$B%X%C%@!<(B ($B$"DK(B) $B$,0l$D$N6u$->l=j$r@j$a$F$$$^$9!#(B - -$B$3$l$i$N6u$->l=j$O!"=gHV$K(B: @code{number}$B!"(B@code{subject}$B!"(B@code{from}$B!"(B -@code{date}$B!"(B@code{id}$B!"(B@code{chars}$B!"(B@code{lines}$B!"(B@code{xref} $B$G$9!#$3(B -$B$l$i$N6u$->l=j$K?($C$F@_Dj$9$k%^%/%m$,$"$j$^$9(B---$B$=$l$i$OA4$F!"$=$l$>$l(B -@code{mail-header-} $B$H(B @code{mail-header-set-} $B$$$&M=A[$5$l$kL>A0$r;}$C(B -$B$F$$$^$9!#(B - -$B>l=j(B @code{xref} $B$OK\Ev$O(B @code{misc} $B$N>l=j$G$9!#$$$m$s$JDI2C$N>pJs$O$=(B -$B$3$KF~$l$i$l$^$9!#(B - - -@node Ranges -@subsection $BHO0O(B - -@sc{gnus} $B$O;d$K$OHs>o$KLr$KN)$D$H;W$o$l$k35G0$rF3F~$7$^$7$?$N$G!";d$O$=(B -$B$l$r$?$/$5$s;H$$!"$+$J$jG0F~$j$K:n$j>e$2$F$-$^$7$?!#(B - -$BZ$5$l$k(B $B$b$N(B -(object) (@emph{$BMpK=$J(B} $BNc$r>e$2$k$H!"5-;v$,$=$&$G$9(B) $B$r(B ``$B4^$^$l$F$$$k(B'' -$B$H$7$F8+$J$7$?$$$H$-$O!"IaDL$NO"B3E*9T0Y$O$"$^$jLr$KN)$A$^$;$s!#(B ($BD9$5(B -200,000 $B$NO"B3J*$O>/$7B)$,D9$9$.$^$9!#(B) - -$B$3$l$N2r7h:v$O/$7e$NMW5a$O2<9_$7$F$$$J$$(B -$B$H$$$&;v$O3P$($F$*$/I,MW$,$"$j$^$9!#(B ($BG$0U$N2s?t$NF1$8?t;z$N7+$jJV$7$O5v(B -$B$5$l$F$$$^$9$,!"HO0O$N07$$$+$i$O>C$(5n$k798~$,$"$j$^$9!#(B) - -@example -range = simple-range / normal-range -simple-range = "(" number " . " number ")" -normal-range = "(" start-contents ")" -contents = "" / simple-range *[ " " contents ] / - number *[ " " contents ] -@end example - -Gnus $B$O8=:_$N$H$3$m4{FI5-;v$H5-;v$N0u$N>pJs$rIU$1$F$*$/$?$a$KHO0O$r;H$C(B -$B$F$$$^$9!#;d$O(B $B$5$J$$$G@$$NCf$r40A4$KHO0O$K4p$E$$$?$b$N$K$9$k(B -$B$?$a$K$b$&>/$79M$($kI,MW$,$"$k$+$i$G$9!#(B) - - -@node Group Info -@subsection $B%0%k!<%W>pJs(B - -Gnus $B$O%0%k!<%W$NA4$F$N1JB3>pJs$r(B @dfn{group info} $B%j%9%H$KJ]B8$7$^$9!#(B -$B$3$N%j%9%H$ND9$5$O(B3$B$+$i(B6 ($B$b$7$/$O$b$C$H(B) $B$NMWAG$GE0DlE*$K%0%k!<%W$r5-=R(B -$B$7$^$9!#(B - -$B$3$3$K$"$k$N$O%0%k!<%W>pJs(B (group info) $B$N(B2$B$D$NNc$G$9!#(B1$B$D$OHs>o$KC1=c$J(B -$B%0%k!<%W$G!"(B2$B$D$a$O$b$C$HJ#;($J$b$N$G$9(B: - -@example -("no.group" 5 (1 . 54324)) - -("nnml:my.mail" 3 ((1 . 5) 9 (20 . 55)) - ((tick (15 . 19)) (replied 3 6 (19 . 3))) - (nnml "") - ((auto-expire . t) (to-address . "ding@@gnus.org"))) -@end example - -$B:G=i$NMWAG$O(B @dfn{$B%0%k!<%WL>(B} $B$G$9(B---$B$I$N$h$&$K$7$m!"(Bgnus $B$,$=$l$K$h$C$F(B -$B%0%k!<%W$rCN$C$F$$$k$b$N$G$9!#(B2$BHVL\$NMWAG$O(B @dfn{$B9XFIEY(B} $B$G!"IaDL$O>.$5(B -$B$J@0?t$G$9!#(B($B$=$l$O(B @dfn{$B3,5i(B} $B$K$J$k;v$b$G$-$^$9!#$=$l$O!"%3%s%9%;%k$G!"(B -@code{car} $B$,%l%Y%k$G!"(B@code{cdr} $B$,%9%3%"$G$9!#(B) 3$BHVL\$NMWAG$O4{FI5-;v(B -$B$NHO0O$N%j%9%H$G$9!#(B4$BHVL\$NMWAG$O$$$m$$$m$Je$N%5!<%P!<$G$9(B)$B!#(B6$BHVL\$NMWAG$O(B @dfn{$B%0%k!<%W%Q%i%a!<%?(B} $B$N%j%9%H$G!"(B -$B$3$NItJ,$O$=$N$?$a$K$"$j$^$9!#(B - -$B:G8e$N(B3$B$D$NMWAG$O$I$l$G$b!"I,MW$,L5$1$l$PB8:_$7$J$$;v$b$"$j$^$9!#o$KBgItJ,$O:G=i$N(B3$B$D$NMWAG$@$1$r;}$A!"$=$l$O$?$/$5$s$N%3%s(B -$B%9%;%k$r@aLs$9$k;v$,$G$-$^$9!#(B - -$B$3$l$O%0%k!<%W>pJsMM<0$N(B BNF $BDj5A$G$9(B: - -@example -info = "(" group space ralevel space read - [ "" / [ space marks-list [ "" / [ space method [ "" / - space parameters ] ] ] ] ] ")" -group = quote quote -ralevel = rank / level -level = -rank = "(" level "." score ")" -score = -read = range -marks-lists = nil / "(" *marks ")" -marks = "(" range ")" -method = "(" *elisp-forms ")" -parameters = "(" *elisp-forms ")" -@end example - -$B} $B$,(B -@samp{range} $B$N>e$K9;@5$5$l$F$$$k$b$N$G$9$,!"5?;w(B BNF $B$G$=$l$r8=$9$N$OIT(B -$BL{2w$J$b$N$G$9!#(B - -$B$b$7(B gnus $B>pJs$r;}$C$F$$$F!"MWAG$rD4$Y$?$$$N$H$-$O!"(Bgnus $B$O$=$l$i$NMWAG(B -$B$r$rpJs$N%j%9%H$G$9!#@_Dj4X?t$O(B2$B$D$N(B -$B0z?t$rpJs%j%9%H$H?7$7$$CM$G$9!#(B - -$B%0%k!<%W>pJs$N:G8e$N(B3$B$D$NMWAG$O6/@)E*$J$b$N$G$O$"$j$^$;$s$N$G!"MWAG$r@_(B -$BDj$9$kA0$K%0%k!<%W>pJs$r3HD%$9$kI,MW$,$"$k$+$bCN$l$^$;$s!#$b$7$3$l$,I,MW(B -$B$J>l9g$O!"$3$l$,<+F0E*$K5/$3$k$?$a$K(B @code{nil} $B$G$J$$(B3$BHVL\$N0z?t$r(B3$B$D$N(B -$B:G=*@_Dj4X?t$KM?$($k$@$1$G$9!#(B - - -@node Extended Interactive -@subsection $B3HD%BPOC(B -@cindex interactive -@findex gnus-interactive - -Gnus $B$O(B Emacs $B$NI8=`$N(B @code{interactive} $B;XDj$r%7%s%\%k@\F,<-$r4JC1$K;H(B -$B$($k$?$a$K>/$73HD%$7$F$$$^$9(B (@pxref{Symbolic Prefixes})$B!#$3$l$O$=$N;H$$(B -$BJ}$NNc$G$9(B: - -@lisp -(defun gnus-summary-increase-score (&optional score symp) - (interactive (gnus-interactive "P\ny")) - ... - ) -@end lisp - -$B:G>e$NJ}K!$O(B @code{gnus-interactive} $B$r<0(B @code{interactive} $B$rJV$9%^%/(B -$B%m$H$7$F/$72C$($^$9!#(B - -@table @samp -@item y -@vindex gnus-current-prefix-symbol -$B8=:_$N@\F,0z?t%7%s%\%k(B---$BJQ?t(B @code{gnus-current-prefix-symbol} $B$G$9!#(B - -@item Y -@vindex gnus-current-prefix-symbols -$B8=:_$N@\F,0z?t%7%s%\%k$N%j%9%H$G$9(B---$BJQ?t(B -@code{gnus-current-prefix-symbol} $B$G$9!#(B - -@item A -$B8=:_$N5-;vHV9f$G$9(B---$B4X?t(B @code{gnus-summary-article-number} $B$G$9!#(B - -@item H -$B8=:_$N5-;v%X%C%@!<$G$9(B---$B4X?t(B @code{gnus-summary-article-header} $B$G$9!#(B - -@item g -$B8=:_$N%0%k!<%WL>$G$9(B---$B4X?t(B @code{gnus-group-group-name} $B$G$9!#(B -@end table - - -@node Emacs/XEmacs Code -@subsection Emacs/XEmacs $B%3!<%I(B -@cindex XEmacs -@cindex Emacsen - -Gnus $B$O(B Emacs$B!"(BXEmacs $B$H(B Mule $B$GF0:n$7$^$9$N$G!"$=$N$&$A$N0l$D$ro$KLr$KN)$A$^$9!#(B - -$B;d$O7QB3E*$K(B Emacs $B$N4X?t$N3&LL(B (interface) $B$r;H$C$F$-$^$7$?$,!"4X?t$K$O(B -gnus $B$NJLL>4X?t(B (alias) $B$r;H$C$F$-$^$7$?!#Nc$r=P$7$^$7$g$&(B: Emacs $B$O4X?t(B -@code{run-at-time} $B$rDj5A$7$F$$$^$9$,!"(BXEmacs $B$O4X?t(B @code{start-itimer} -$B$rDj5A$7$F$$$^$9!#$=$3$G;d$O(B @code{gnus-run-at-time} $B$H8F$P$l$k4X?t$rDj(B -$B5A$7!"$=$l$O(B Emacs $B$N(B @code{run-at-time} $B$HF1$80z?t$r4X?t(B (alias) $B$K(B -$B$J$C$F$$$^$9!#$7$+$7!"(BXEmacs $B$G4X?t(B -(alias) $B$H$J$C$F$$$^$9(B: - -@lisp -(defun gnus-xmas-run-at-time (time repeat function &rest args) - (start-itimer - "gnus-run-at-time" - `(lambda () - (,function ,@@args)) - time repeat)) -@end lisp - -$B$3$Nl9g$O!";d$OBe$o$j$K$=$l$r;H$$$^(B -$B$9!#Nc$($P!"(B@code{gnus-region-active-p} $B$O(B XEmacs $B$G$O(B -@code{region-active-p} $B$NJLL>$G$"$k$N$KBP$7$F!"(BEmacs $B$G$O4X?t$G$9!#(B - -$B$b$A$m$s!";d$O(B XEmacs $B$r;d$N4pK\%W%i%C%H%U%)!<%`$KA*$s$G!"4X?t$N3d$jEv$F(B -$B$r5U$K$9$k;v$b$G$-$^$7$?!#$G$b!";d$O$=$&$7$^$;$s$G$7$?!#(BXEmacs $B$G(B gnus -$B$r/$7$G$7$g$&!#(B - - -@node Various File Formats -@subsection $B$$$m$$$m$J%U%!%$%kMM<0(B - -@menu -* Active File Format:: $B;HMQ2DG=$J5-;v%0%k!<%W$N>pJs!#(B -* Newsgroups File Format:: $B%0%k!<%W$N5-=R!#(B -@end menu - - -@node Active File Format -@subsubsection $B8=>u%U%!%$%kMM<0(B - -$B8=>u%U%!%$%k$OEv$N%5!<%P!<$NA4$F$N;HMQ2DG=$J%0%k!<%W$N0lMw$r5s$2$^$9!#$=(B -$B$l$O$=$l$>$l$N%0%k!<%W$N:GDc$H:G9b$N5-;vHV9f$N0lMw$b$"$j$^$9!#(B - -$B$3$l$OIaDL$N8=>u%U%!%$%k$+$i$NH4?h$G$9(B: - -@example -soc.motss 296030 293865 y -alt.binaries.pictures.fractals 3922 3913 n -comp.sources.unix 1605 1593 m -comp.binaries.ibm.pc 5097 5089 y -no.general 1000 900 y -@end example - -$B$3$l$O$3$N%U%!%$%k$N5?;w(B BNF $BDj5A$G$9!#(B - -@example -active = *group-line -group-line = group space high-number space low-number space flag -group = -space = " " -high-number = -low-number = -flag = "y" / "n" / "m" / "j" / "x" / "=" group -@end example - -$B$3$N%U%!%$%k$N40A4$J5-=R$rF@$k$?$a$K$O!"(B@samp{innd} $B$N%^%K%e%"%kJG!"FC$K(B -@samp{active(5)} $B$r8+$F2<$5$$!#(B - - -@node Newsgroups File Format -@subsubsection $B%K%e!<%9%0%k!<%W%U%!%$%kMM<0(B - -$B%K%e!<%9%0%k!<%W%U%!%$%k$O%0%k!<%W$r$=$N5-=R$H6&$K0lMw$r5s$2$^$9!#%5!<%P!<(B -$B$K$"$kA4$F$N%0%k!<%W$,0lMw$K$5$l$J$1$l$P$J$i$J$$$N$G$O$J$/!"$^$?!"%U%!%$(B -$B%k$NA4$F$N%0%k!<%W$,%5!<%P!<$KB8:_$7$J$1$l$P$J$i$J$$$N$G$O$"$j$^$;$s!#$3(B -$B$N%U%!%$%k$O=c?h$KMxMQpJs$N$?$a$K$"$j$^$9!#(B - -$BMM<0$OHs>o$K4JC1$G$9(B: $B%0%k!<%WL>!"%?%V!"$=$7$F5-=R$G$9!#$3$l$ODj5A$G$9(B: - -@example -newsgroups = *line -line = group tab description -group = -tab = -description = -@end example - - -@page -@node Emacs for Heathens -@section $B0[65EL$X$N(B Emacs - -$B?.$8$k$+$I$&$+$OCN$j$^$;$s$,!"(Bgnus $B$r;H$&?M$NCf$K$O(B Gnus Love Boat $B$G$N(B -$BN9$KEk>h$9$kA0$K$"$^$j(B Emacs $B$r;H$C$?;v$,L5$$$H$$$&?M$,$$$^$9!#$b$7$"$J(B -$B$?$,(B ``@kbd{M-C-a}'' $B$d(B ``$B%j!<%8%g%s$r@Z$k(B''$B!"$=$7$F(B -``@code{gnus-flargblossen} $B$rO"A[%j%9%H$K@_Dj$7$F$/$@$5$$!#$=$N%-!<$O%0(B -$B%k!<%WL>$K9gCW$9$k$?$a$K;H$o$l$k@55,I=8=$G$9(B'' $B$,>/$7$N0UL#$+A4$/0UL#$N(B -$BL5$$KbK!$N8@MU$G$"$kIT9,$J?M$G$"$l$P!"$3$NIUO?$O$"$J$?$N$?$a$K$"$j$^$9!#(B -$B$b$7$"$J$?$,4{$K(B Emacs $B$K?F$7$s$G$$$k$N$G$"$l$P!"$3$l$rL5;k$7$FO$rF~NO$7$FL?Na$ro$K$&$k$5$/46$8$i$l$k$G$7$g$&!#;D$j$N?M!9$O!"$=$l$K$h$j$b(B -$B$?$i$5$l$kCO9v$r0&$7$^$9!#$"$-$i$a$FI~=>$7$F2<$5$$!#(BEmacs $B$OK\Ev$O(B -``Escape-Meta-Alt-Control-Shift'' $B$NN,$G!"B>$NI>H=$N0-$$=P=j(B (Emacs $B$N:n(B -$B.;X$N6a$/$K0LCV$7$F$*$j!"IaDL$OBgJ8;z$d$=$NB>$N$b$rF@(B -$B$k$?$a$K;H$o$l$^$9!#$"$J$?$O$:$C$H$=$l$r;H$&;v$G$7$g$&!#%3%s%H%m!<%k%-!<(B -$B$OIaDL$O(B ``CTRL'' $B$d$=$N$h$&$J$b$N$G0u$,IU$$$F$$$^$9!#%a%?%-!<$O!"$*$b$7(B -$B$m$$;v$K!"$I$N%-!<%\!<%I$G$b$=$N$h$&$K0u$,IU$1$i$l$F$$$^$;$s!#$=$l$OIaDL(B -$B$O%-!<%\!<%I$N:8/$7J#;($K$J$C$F$$$^$9!#$=$N$h$&$J>l9g$O!"(B``$B%(%9%1!<%W(B'' $B%-!<$r;H$&;v$,(B -$B$G$-$^$9!#$=$l$O%a%?%-!<$r;}$C$F$$$k$H$-$h$j$b$C$H:n6H$,BgJQ$K$J$j$^$9$N(B -$B$G!"$=$&$$$&>l9g$O!";d$O%a%?%-!<$N$"$k%-!<%\!<%I$r$l$NA4$F$N%-!<$O2?$i$+$N(B Emacs Lisp $B$N%3!<%I$N(B -$B>.JR$r/$J$/$H$b(B Lisp $B%3!<%I$N=q$-J}$rCN$C$F$$$l$P!#(B) $B$7$+$7!"$=$l$O$3$N%^(B -$B%K%e%"%k$NHO0O30$J$N$G!"2f!9$OC1$K(B gnus $B$r%+%9%?%^%$%:$9$k$?$a$K%U%!%$%k(B -@file{.emacs} $B$GIaDL;H$o$l$k$$$/$D$+$NIaDL$N9=J8$K$D$$$F$@$1OC$r$7$^$9!#(B - -$B$b$7JQ?t(B@code{gnus-florgbnize} $B$r;M(B (4) $B$K@_Dj$7$?$$$N$G$"$l$P!"0J2<$N$b(B -$B$N$r=q$-$^$9(B: - -@lisp -(setq gnus-florgbnize 4) -@end lisp - -$B$3$N4X?t(B @code{setq} ($BK\Ev$O(B ``$BFC2A(B} ($B$=$l$O(B ``$B(B -$B2A(B} $B$7!"$=$l$O$3$3$G$O4JC1$J(B @code{setq} $BJ8$G$9!#(B - -$B$,$s$P$C$F(B---$B$b$7$"$J$?$,(B Emacs $B$NA0$K$"$k$N$G$"$l$P$A$g$C$H;n$7$F2<$5$$!#(B -@kbd{C-x C-e} $B$N8e$G!"H?6A6h0h(B (echo area) $B$K(B @samp{4} $B$,8=$o$l$k$N$,8+(B -$B$($k$G$7$g$&!#$=$l$O$"$J$?$,(B @code{$BI>2A(B} $B$7$?<0$NJV$jCM$G$9!#(B - -$B$$$/$D$+$NMn$H$77j(B: - -$B$b$7%^%K%e%"%k$,(B ``@code{gnus-read-active-file} $B$r(B @code{some} $B$K@_Dj$7(B -$B$J$5$$(B'' $B$H8@$C$?$J$i!"$=$l$O(B: - -@lisp -(setq gnus-read-active-file 'some) -@end lisp - -$B$H8@$&;v$G$9!#(B - -$B0lJ}!"%^%K%e%"%k$,(B ``@code{gnus-nntp-server} $B$r(B @samp{nntp.ifi.uio.no} -$B$K@_Dj$7$J$5$$(B'' $B$H8@$C$?$J$i!"$=$l$O(B: - -@lisp -(setq gnus-nntp-server "nntp.ifi.uio.no") -@end lisp - -$B$H8@$&;v$G$9!#(B - -$B$G$9$+$i!"J8;zNs(B ($B8eu%U%!%$%k!"%"%/%F%#%V%U%!%$%k(B -adapt $BE,MQ(B -adaptive $BE,1~@-(B -address $B%"%I%l%9(B -agent $B%(!<%8%'%s%H(B -alist $BO"A[%j%9%H(B -alternate $BBeBX(B -anything group $B$J$s$G$b%0%k!<%W(B -archive $B%"!<%+%$%V(B -asterisk $B%"%9%?%j%9%/(B -auto-save file $B<+F0J]B8%U%!%$%k(B -backend $B%P%C%/%(%s%I(B -batch $B0l3g(B -bogus group $B56%0%k!<%W(B -browse $B%V%i%&%:!";2>H!"354Q(B -buffer $B%P%C%U%!(B -buggy $B8N>c$,$A(B -category $BJ,N`(B -collapsed group name $BC;=L%0%k!<%WL>(B -combined groups $B7k9g%0%k!<%W(B -command $BL?Na(B -command line $B%3%^%s%I9T(B -configure (shell script) $B4D6-@_Dj(B -copy $B%3%T!C5n!"4|8B@Z$l:o=|(B -expunge $B>C5n(B -field $BMs(B -firewall $BKIJI(B -flag $B%U%i%0(B -flush cache $B%-%c%C%7%e$r=q$-9~$`(B -follow up $B%U%)%m!<%"%C%W(B -foreign $B30It(B -format $BMM<0!"%U%)!<%^%C%H(B -frame $B%U%l!<%`(B -gateway $B%2!<%H%&%'%$(B -global $B%0%m!<%P%k(B -Gnus gnus -group buffer $B%0%k!<%W%P%C%U%!(B -header $B%X%C%@!<(B -highlight $B%O%$%i%$%H(B -history $BMzNr(B -home score file $B%[!<%`%9%3%"%U%!%$%k(B -hook $B%U%C%/(B -inbox $B%$%s%\%C%/%9(B -indentation $B;z2<$2(B -interactive command $BBPOCL?Na(B -interface $B%$%s%?!<%U%'!<%9(B -kiboze kiboze -key (alist) $B%-!<(B -keymap $B%-!<%^%C%W(B -kiboze kiboze -kill $B:o=|!"@Z$k!"%-%k(B -kill file $B:o=|%U%!%$%k!"(B($B>C5n%U%!%$%k(B) -level $B%l%Y%k(B -load $B%m!<%I(B -local variable $B6I=jJQ?t!"%m!<%+%kJQ?t(B -lower lebel $B>.$5$$%l%Y%k(B -mail $B%a!<%k(B -mailbox $B%a!<%k%\%C%/%9(B -mail-to-news gateway $B%a!<%k$+$i%K%e!<%:$X$N%2!<%H%&%'%$(B -mark $B0u(B -meta-variable $B%a%?JQ?t(B -message $B%a%C%;!<%8(B -method $BJ}K!(B -minor mode $B%^%$%J!<%b!<%I(B -modeline $B%b!<%I9T(B -moderated $B;J2quBV(B -sub-topic $BI{%H%T%C%/(B -submap $B%5%V%^%C%W(B -subscribe $B9XFI(B -subscribedness $B9XFIEY(B -summary buffer $B35N,%P%C%U%!(B -superseding $BBeBX(B -symbolic prefix $B5-9f@\F,<-(B -syntax table $BJ8K!I=(B -text properties $B%F%-%9%HB0@-(B -thread $B%9%l%C%I(B -ticked article ($B0uIU$-5-;v(B) -toggle $B%H%0%k(B $B@Z$jBX$((B -token -topic $B%H%T%C%/(B -unplugged $B@Z$jN%$7(B -unsubscribe $BHs9XFI(B -user $BMxMQ%s%S(B - -summary $B35N,(B -body $B%\%G%#(B -head $B%X%C%@!<(B -subject $BI=Bj(B -match $B%^%C%A(B -encode $BId9f2=(B -character set $BJ8;z=89g(B -hook $B%U%C%/(B -keystroke $B%-!$}} -\newcommand{\gnusbraceleft}{{$>$}} -\newcommand{\gnusbraceright}{{$>$}} - -\newcommand{\gnushead}{\raisebox{-1cm}{\epsfig{figure=ps/gnus-head.eps,height=1cm}}} -\newcommand{\gnusinteresting}{ -\marginpar[\mbox{}\hfill\gnushead]{\gnushead} -} - -\newcommand{\gnuscleardoublepage}{\ifodd\count0\mbox{}\clearpage\thispagestyle{empty}\mbox{}\clearpage\else\clearpage\fi} - -\newcommand{\gnuspagechapter}[1]{ -{\mbox{}} -} - -\newdimen{\gnusdimen} -\gnusdimen 0pt - -\newcommand{\gnuschapter}[2]{ -\gnuscleardoublepage -\ifdim \gnusdimen = 0pt\setcounter{page}{1}\pagestyle{gnus}\pagenumbering{arabic} \gnusdimen 1pt\fi -\chapter{#2} -\renewcommand{\gnussectionname}{} -\renewcommand{\gnuschaptername}{#2} -\thispagestyle{empty} -\hspace*{-2cm} -\begin{picture}(500,500)(0,0) -\put(480,350){\makebox(0,0)[tr]{#1}} -\put(40,300){\makebox(500,50)[bl]{{\Huge\bf{#2}}}} -\end{picture} -\clearpage -} - -\newcommand{\gnusfigure}[3]{ -\begin{figure} -\mbox{}\ifodd\count0\hspace*{-0.8cm}\else\hspace*{-3cm}\fi\begin{picture}(440,#2) -#3 -\end{picture} -\caption{#1} -\end{figure} -} - -\newcommand{\gnusicon}[1]{ -\marginpar[\mbox{}\hfill\raisebox{-1.5cm}{\epsfig{figure=tmp/#1-up.ps,height=1.5cm}}]{\raisebox{-1cm}{\epsfig{figure=tmp/#1-up.ps,height=1cm}}} -} - -\newcommand{\gnuspicon}[1]{ -\margindex{\epsfig{figure=#1,width=2cm}} -} - -\newcommand{\gnusxface}[2]{ -\margindex{\epsfig{figure=#1,width=1cm}\epsfig{figure=#2,width=1cm}} -} - -\newcommand{\gnussmiley}[2]{ -\margindex{\makebox[2cm]{\hfill\epsfig{figure=#1,width=0.5cm}\hfill\epsfig{figure=#2,width=0.5cm}\hfill}} -} - -\newcommand{\gnusitemx}[1]{\mbox{}\vspace*{-\itemsep}\vspace*{-\parsep}\item#1} - -\newcommand{\gnussection}[1]{ -\renewcommand{\gnussectionname}{#1} -\section{#1} -} - -\newenvironment{codelist}% -{\begin{list}{}{ -} -}{\end{list}} - -\newenvironment{kbdlist}% -{\begin{list}{}{ -\labelwidth=0cm -} -}{\end{list}} - -\newenvironment{dfnlist}% -{\begin{list}{}{ -} -}{\end{list}} - -\newenvironment{stronglist}% -{\begin{list}{}{ -} -}{\end{list}} - -\newenvironment{samplist}% -{\begin{list}{}{ -} -}{\end{list}} - -\newenvironment{varlist}% -{\begin{list}{}{ -} -}{\end{list}} - -\newenvironment{emphlist}% -{\begin{list}{}{ -} -}{\end{list}} - -\newlength\gnusheadtextwidth -\setlength{\gnusheadtextwidth}{\headtextwidth} -\addtolength{\gnusheadtextwidth}{1cm} - -\newpagestyle{gnuspreamble}% -{ -{ -\ifodd\count0 -{ -\hspace*{-0.23cm}\underline{\makebox[\gnusheadtextwidth]{\mbox{}}\textbf{\hfill\roman{page}}} -} -\else -{ -\hspace*{-3.25cm}\underline{\makebox[\gnusheadtextwidth]{\textbf{\roman{page}\hfill\mbox{}}} -} -} -\fi -} -} -{ -\ifodd\count0 -\mbox{} \hfill -\raisebox{-0.5cm}{\epsfig{figure=ps/gnus-big-logo.eps,height=1cm}} -\else -\raisebox{-0.5cm}{\epsfig{figure=ps/gnus-big-logo.eps,height=1cm}} -\hfill \mbox{} -\fi -} - -\newpagestyle{gnusindex}% -{ -{ -\ifodd\count0 -{ -\hspace*{-0.23cm}\underline{\makebox[\gnusheadtextwidth]{\textbf{\gnuschaptername\hfill\arabic{page}}}} -} -\else -{ -\hspace*{-3.25cm}\underline{\makebox[\gnusheadtextwidth]{\textbf{\arabic{page}\hfill\gnuschaptername}}} -} -\fi -} -} -{ -\ifodd\count0 -\mbox{} \hfill -\raisebox{-0.5cm}{\epsfig{figure=ps/gnus-big-logo.eps,height=1cm}} -\else -\raisebox{-0.5cm}{\epsfig{figure=ps/gnus-big-logo.eps,height=1cm}} -\hfill \mbox{} -\fi -} - -\newpagestyle{gnus}% -{ -{ -\ifodd\count0 -{ -\makebox[12cm]{\hspace*{3.1cm}\underline{\makebox[\gnusheadtextwidth]{\textbf{\arabic{chapter}.\arabic{section}} \textbf{\gnussectionname\hfill\arabic{page}}}}} -} -\else -{ -\makebox[12cm]{\hspace*{-2.95cm}\underline{\makebox[\gnusheadtextwidth]{\textbf{\arabic{page}\hfill\gnuschaptername}}}} -} -\fi -} -} -{ -\ifodd\count0 -\mbox{} \hfill -\raisebox{-0.5cm}{\epsfig{figure=ps/gnus-big-logo.eps,height=1cm}} -\else -\raisebox{-0.5cm}{\epsfig{figure=ps/gnus-big-logo.eps,height=1cm}} -\hfill \mbox{} -\fi -} - -\pagenumbering{roman} -\pagestyle{gnuspreamble} - -@end iflatex -@end iftex - -@iftex -@iflatex -\begin{titlepage} -{ - -%\addtolength{\oddsidemargin}{-5cm} -%\addtolength{\evensidemargin}{-5cm} -\parindent=0cm -\addtolength{\textheight}{2cm} - -\gnustitle{\gnustitlename}\\ -\rule{15cm}{1mm}\\ -\vfill -\hspace*{0cm}\epsfig{figure=ps/gnus-big-logo.eps,height=15cm} -\vfill -\rule{15cm}{1mm}\\ -\gnusauthor{by Lars Magne Ingebrigtsen} -\newpage -} - -\mbox{} -\vfill - -\thispagestyle{empty} - -Copyright \copyright{} 1995,96,97 Free Software Foundation, Inc. - -Permission is granted to make and distribute verbatim copies of -this manual provided the copyright notice and this permission notice -are preserved on all copies. - -Permission is granted to copy and distribute modified versions of this -manual under the conditions for verbatim copying, provided that the -entire resulting derived work is distributed under the terms of a -permission notice identical to this one. - -Permission is granted to copy and distribute translations of this manual -into another language, under the above conditions for modified versions. - -\newpage -\end{titlepage} -@end iflatex -@end iftex - -@ifinfo - -This file documents gnus, the GNU Emacs newsreader. - -Copyright (C) 1995,96 Free Software Foundation, Inc. - -Permission is granted to make and distribute verbatim copies of -this manual provided the copyright notice and this permission notice -are preserved on all copies. - -@ignore -Permission is granted to process this file through Tex and print the -results, provided the printed document carries copying permission -notice identical to this one except for the removal of this paragraph -(this paragraph not being relevant to the printed manual). - -@end ignore -Permission is granted to copy and distribute modified versions of this -manual under the conditions for verbatim copying, provided also that the -entire resulting derived work is distributed under the terms of a -permission notice identical to this one. - -Permission is granted to copy and distribute translations of this manual -into another language, under the above conditions for modified versions. -@end ifinfo - -@tex - -@titlepage -@title Semi-gnus 6.8.19 Manual - -@author by Lars Magne Ingebrigtsen -@page - -@vskip 0pt plus 1filll -Copyright @copyright{} 1995,96,97 Free Software Foundation, Inc. - -Permission is granted to make and distribute verbatim copies of -this manual provided the copyright notice and this permission notice -are preserved on all copies. - -Permission is granted to copy and distribute modified versions of this -manual under the conditions for verbatim copying, provided that the -entire resulting derived work is distributed under the terms of a -permission notice identical to this one. - -Permission is granted to copy and distribute translations of this manual -into another language, under the above conditions for modified versions. - -@end titlepage -@page - -@end tex - - -@node Top -@top The gnus Newsreader - -@ifinfo - -You can read news (and mail) from within Emacs by using gnus. The news -can be gotten by any nefarious means you can think of---@sc{nntp}, local -spool or your mbox file. All at the same time, if you want to push your -luck. - -<<<} if a foreign select method is -used. - -@item P -Indentation based on the level of the topic (@pxref{Group Topics}). - -@item c -@vindex gnus-group-uncollapsed-levels -Short (collapsed) group name. The @code{gnus-group-uncollapsed-levels} -variable says how many levels to leave at the end of the group name. -The default is 1---this will mean that group names like -@samp{gnu.emacs.gnus} will be shortened to @samp{g.emacs.gnus}. - -@item m -@vindex gnus-new-mail-mark -@cindex % -@samp{%} (@code{gnus-new-mail-mark}) if there has arrived new mail to -the group lately. - -@item d -A string that says when you last read the group (@pxref{Group -Timestamp}). - -@item u -User defined specifier. The next character in the format string should -be a letter. Gnus will call the function -@code{gnus-user-format-function-}@samp{X}, where @samp{X} is the letter -following @samp{%u}. The function will be passed a single dummy -parameter as argument. The function should return a string, which will -be inserted into the buffer just like information from any other -specifier. -@end table - -@cindex * -All the ``number-of'' specs will be filled with an asterisk (@samp{*}) -if no info is available---for instance, if it is a non-activated foreign -group, or a bogus native group. - - -@node Group Modeline Specification -@subsection Group Modeline Specification -@cindex group modeline - -@vindex gnus-group-mode-line-format -The mode line can be changed by setting -@code{gnus-group-mode-line-format} (@pxref{Mode Line Formatting}). It -doesn't understand that many format specifiers: - -@table @samp -@item S -The native news server. -@item M -The native select method. -@end table - - -@node Group Highlighting -@subsection Group Highlighting -@cindex highlighting -@cindex group highlighting - -@vindex gnus-group-highlight -Highlighting in the group buffer is controlled by the -@code{gnus-group-highlight} variable. This is an alist with elements -that look like @var{(form . face)}. If @var{form} evaluates to -something non-@code{nil}, the @var{face} will be used on the line. - -Here's an example value for this variable that might look nice if the -background is dark: - -@lisp -(face-spec-set 'my-group-face-1 - '((t (:foreground "Red" :bold t)))) -(face-spec-set 'my-group-face-2 - '((t (:foreground "SeaGreen" :bold t)))) -(face-spec-set 'my-group-face-3 - '((t (:foreground "SpringGreen" :bold t)))) -(face-spec-set 'my-group-face-4 - '((t (:foreground "SteelBlue" :bold t)))) -(face-spec-set 'my-group-face-5 - '((t (:foreground "SkyBlue" :bold t)))) - -(setq gnus-group-highlight - '(((> unread 200) . my-group-face-1) - ((and (< level 3) (zerop unread)) . my-group-face-2) - ((< level 3) . my-group-face-3) - ((zerop unread) . my-group-face-4) - (t . my-group-face-5))) -@end lisp - -Also @pxref{Faces and Fonts}. - -Variables that are dynamically bound when the forms are evaluated -include: - -@table @code -@item group -The group name. -@item unread -The number of unread articles in the group. -@item method -The select method. -@item mailp -Whether the group is a mail group. -@item level -The level of the group. -@item score -The score of the group. -@item ticked -The number of ticked articles in the group. -@item total -The total number of articles in the group. Or rather, MAX-NUMBER minus -MIN-NUMBER plus one. -@item topic -When using the topic minor mode, this variable is bound to the current -topic being inserted. -@end table - -When the forms are @code{eval}ed, point is at the beginning of the line -of the group in question, so you can use many of the normal gnus -functions for snarfing info on the group. - -@vindex gnus-group-update-hook -@findex gnus-group-highlight-line -@code{gnus-group-update-hook} is called when a group line is changed. -It will not be called when @code{gnus-visual} is @code{nil}. This hook -calls @code{gnus-group-highlight-line} by default. - - -@node Group Maneuvering -@section Group Maneuvering -@cindex group movement - -All movement commands understand the numeric prefix and will behave as -expected, hopefully. - -@table @kbd - -@item n -@kindex n (Group) -@findex gnus-group-next-unread-group -Go to the next group that has unread articles -(@code{gnus-group-next-unread-group}). - -@item p -@itemx DEL -@kindex DEL (Group) -@kindex p (Group) -@findex gnus-group-prev-unread-group -Go to the previous group that has unread articles -(@code{gnus-group-prev-unread-group}). - -@item N -@kindex N (Group) -@findex gnus-group-next-group -Go to the next group (@code{gnus-group-next-group}). - -@item P -@kindex P (Group) -@findex gnus-group-prev-group -Go to the previous group (@code{gnus-group-prev-group}). - -@item M-n -@kindex M-n (Group) -@findex gnus-group-next-unread-group-same-level -Go to the next unread group on the same (or lower) level -(@code{gnus-group-next-unread-group-same-level}). - -@item M-p -@kindex M-p (Group) -@findex gnus-group-prev-unread-group-same-level -Go to the previous unread group on the same (or lower) level -(@code{gnus-group-prev-unread-group-same-level}). -@end table - -Three commands for jumping to groups: - -@table @kbd - -@item j -@kindex j (Group) -@findex gnus-group-jump-to-group -Jump to a group (and make it visible if it isn't already) -(@code{gnus-group-jump-to-group}). Killed groups can be jumped to, just -like living groups. - -@item , -@kindex , (Group) -@findex gnus-group-best-unread-group -Jump to the unread group with the lowest level -(@code{gnus-group-best-unread-group}). - -@item . -@kindex . (Group) -@findex gnus-group-first-unread-group -Jump to the first group with unread articles -(@code{gnus-group-first-unread-group}). -@end table - -@vindex gnus-group-goto-unread -If @code{gnus-group-goto-unread} is @code{nil}, all the movement -commands will move to the next group, not the next unread group. Even -the commands that say they move to the next unread group. The default -is @code{t}. - - -@node Selecting a Group -@section Selecting a Group -@cindex group selection - -@table @kbd - -@item SPACE -@kindex SPACE (Group) -@findex gnus-group-read-group -Select the current group, switch to the summary buffer and display the -first unread article (@code{gnus-group-read-group}). If there are no -unread articles in the group, or if you give a non-numerical prefix to -this command, gnus will offer to fetch all the old articles in this -group from the server. If you give a numerical prefix @var{N}, @var{N} -determines the number of articles gnus will fetch. If @var{N} is -positive, gnus fetches the @var{N} newest articles, if @var{N} is -negative, gnus fetches the @var{abs(N)} oldest articles. - -@item RET -@kindex RET (Group) -@findex gnus-group-select-group -Select the current group and switch to the summary buffer -(@code{gnus-group-select-group}). Takes the same arguments as -@code{gnus-group-read-group}---the only difference is that this command -does not display the first unread article automatically upon group -entry. - -@item M-RET -@kindex M-RET (Group) -@findex gnus-group-quick-select-group -This does the same as the command above, but tries to do it with the -minimum amount of fuzz (@code{gnus-group-quick-select-group}). No -scoring/killing will be performed, there will be no highlights and no -expunging. This might be useful if you're in a real hurry and have to -enter some humongous group. If you give a 0 prefix to this command -(i.e., @kbd{0 M-RET}), gnus won't even generate the summary buffer, -which is useful if you want to toggle threading before generating the -summary buffer (@pxref{Summary Generation Commands}). - -@item M-SPACE -@kindex M-SPACE (Group) -@findex gnus-group-visible-select-group -This is yet one more command that does the same as the @kbd{RET} -command, but this one does it without expunging and hiding dormants -(@code{gnus-group-visible-select-group}). - -@item M-C-RET -@kindex M-C-RET (Group) -@findex gnus-group-select-group-ephemerally -Finally, this command selects the current group ephemerally without -doing any processing of its contents -(@code{gnus-group-select-group-ephemerally}). Even threading has been -turned off. Everything you do in the group after selecting it in this -manner will have no permanent effects. - -@end table - -@vindex gnus-large-newsgroup -The @code{gnus-large-newsgroup} variable says what gnus should consider -to be a big group. This is 200 by default. If the group has more -(unread and/or ticked) articles than this, gnus will query the user -before entering the group. The user can then specify how many articles -should be fetched from the server. If the user specifies a negative -number (@code{-n}), the @code{n} oldest articles will be fetched. If it -is positive, the @code{n} articles that have arrived most recently will -be fetched. - -@vindex gnus-select-group-hook -@vindex gnus-auto-select-first -@code{gnus-auto-select-first} control whether any articles are selected -automatically when entering a group with the @kbd{SPACE} command. - -@table @code - -@item nil -Don't select any articles when entering the group. Just display the -full summary buffer. - -@item t -Select the first unread article when entering the group. - -@item best -Select the highest scored article in the group when entering the -group. -@end table - -If you want to prevent automatic selection in some group (say, in a -binary group with Huge articles) you can set this variable to @code{nil} -in @code{gnus-select-group-hook}, which is called when a group is -selected. - - -@node Subscription Commands -@section Subscription Commands -@cindex subscription - -@table @kbd - -@item S t -@itemx u -@kindex S t (Group) -@kindex u (Group) -@findex gnus-group-unsubscribe-current-group -@c @icon{gnus-group-unsubscribe} -Toggle subscription to the current group -(@code{gnus-group-unsubscribe-current-group}). - -@item S s -@itemx U -@kindex S s (Group) -@kindex U (Group) -@findex gnus-group-unsubscribe-group -Prompt for a group to subscribe, and then subscribe it. If it was -subscribed already, unsubscribe it instead -(@code{gnus-group-unsubscribe-group}). - -@item S k -@itemx C-k -@kindex S k (Group) -@kindex C-k (Group) -@findex gnus-group-kill-group -@c @icon{gnus-group-kill-group} -Kill the current group (@code{gnus-group-kill-group}). - -@item S y -@itemx C-y -@kindex S y (Group) -@kindex C-y (Group) -@findex gnus-group-yank-group -Yank the last killed group (@code{gnus-group-yank-group}). - -@item C-x C-t -@kindex C-x C-t (Group) -@findex gnus-group-transpose-groups -Transpose two groups (@code{gnus-group-transpose-groups}). This isn't -really a subscription command, but you can use it instead of a -kill-and-yank sequence sometimes. - -@item S w -@itemx C-w -@kindex S w (Group) -@kindex C-w (Group) -@findex gnus-group-kill-region -Kill all groups in the region (@code{gnus-group-kill-region}). - -@item S z -@kindex S z (Group) -@findex gnus-group-kill-all-zombies -Kill all zombie groups (@code{gnus-group-kill-all-zombies}). - -@item S C-k -@kindex S C-k (Group) -@findex gnus-group-kill-level -Kill all groups on a certain level (@code{gnus-group-kill-level}). -These groups can't be yanked back after killing, so this command should -be used with some caution. The only time where this command comes in -really handy is when you have a @file{.newsrc} with lots of unsubscribed -groups that you want to get rid off. @kbd{S C-k} on level 7 will -kill off all unsubscribed groups that do not have message numbers in the -@file{.newsrc} file. - -@end table - -Also @pxref{Group Levels}. - - -@node Group Data -@section Group Data - -@table @kbd - -@item c -@kindex c (Group) -@findex gnus-group-catchup-current -@vindex gnus-group-catchup-group-hook -@c @icon{gnus-group-catchup-current} -Mark all unticked articles in this group as read -(@code{gnus-group-catchup-current}). -@code{gnus-group-catchup-group-hook} is called when catching up a group -from the group buffer. - -@item C -@kindex C (Group) -@findex gnus-group-catchup-current-all -Mark all articles in this group, even the ticked ones, as read -(@code{gnus-group-catchup-current-all}). - -@item M-c -@kindex M-c (Group) -@findex gnus-group-clear-data -Clear the data from the current group---nix out marks and the list of -read articles (@code{gnus-group-clear-data}). - -@item M-x gnus-group-clear-data-on-native-groups -@kindex M-x gnus-group-clear-data-on-native-groups -@findex gnus-group-clear-data-on-native-groups -If you have switched from one @sc{nntp} server to another, all your marks -and read ranges have become worthless. You can use this command to -clear out all data that you have on your native groups. Use with -caution. - -@end table - - -@node Group Levels -@section Group Levels -@cindex group level -@cindex level - -All groups have a level of @dfn{subscribedness}. For instance, if a -group is on level 2, it is more subscribed than a group on level 5. You -can ask gnus to just list groups on a given level or lower -(@pxref{Listing Groups}), or to just check for new articles in groups on -a given level or lower (@pxref{Scanning New Messages}). - -Remember: The higher the level of the group, the less important it is. - -@table @kbd - -@item S l -@kindex S l (Group) -@findex gnus-group-set-current-level -Set the level of the current group. If a numeric prefix is given, the -next @var{n} groups will have their levels set. The user will be -prompted for a level. -@end table - -@vindex gnus-level-killed -@vindex gnus-level-zombie -@vindex gnus-level-unsubscribed -@vindex gnus-level-subscribed -Gnus considers groups from levels 1 to -@code{gnus-level-subscribed} (inclusive) (default 5) to be subscribed, -@code{gnus-level-subscribed} (exclusive) and -@code{gnus-level-unsubscribed} (inclusive) (default 7) to be -unsubscribed, @code{gnus-level-zombie} to be zombies (walking dead) -(default 8) and @code{gnus-level-killed} to be killed (completely dead) -(default 9). Gnus treats subscribed and unsubscribed groups exactly the -same, but zombie and killed groups have no information on what articles -you have read, etc, stored. This distinction between dead and living -groups isn't done because it is nice or clever, it is done purely for -reasons of efficiency. - -It is recommended that you keep all your mail groups (if any) on quite -low levels (e.g. 1 or 2). - -If you want to play with the level variables, you should show some care. -Set them once, and don't touch them ever again. Better yet, don't touch -them at all unless you know exactly what you're doing. - -@vindex gnus-level-default-unsubscribed -@vindex gnus-level-default-subscribed -Two closely related variables are @code{gnus-level-default-subscribed} -(default 3) and @code{gnus-level-default-unsubscribed} (default 6), -which are the levels that new groups will be put on if they are -(un)subscribed. These two variables should, of course, be inside the -relevant valid ranges. - -@vindex gnus-keep-same-level -If @code{gnus-keep-same-level} is non-@code{nil}, some movement commands -will only move to groups of the same level (or lower). In -particular, going from the last article in one group to the next group -will go to the next group of the same level (or lower). This might be -handy if you want to read the most important groups before you read the -rest. - -@vindex gnus-group-default-list-level -All groups with a level less than or equal to -@code{gnus-group-default-list-level} will be listed in the group buffer -by default. - -@vindex gnus-group-list-inactive-groups -If @code{gnus-group-list-inactive-groups} is non-@code{nil}, non-active -groups will be listed along with the unread groups. This variable is -@code{t} by default. If it is @code{nil}, inactive groups won't be -listed. - -@vindex gnus-group-use-permanent-levels -If @code{gnus-group-use-permanent-levels} is non-@code{nil}, once you -give a level prefix to @kbd{g} or @kbd{l}, all subsequent commands will -use this level as the ``work'' level. - -@vindex gnus-activate-level -Gnus will normally just activate (i. e., query the server about) groups -on level @code{gnus-activate-level} or less. If you don't want to -activate unsubscribed groups, for instance, you might set this variable -to 5. The default is 6. - - -@node Group Score -@section Group Score -@cindex group score -@cindex group rank -@cindex rank - -You would normally keep important groups on high levels, but that scheme -is somewhat restrictive. Don't you wish you could have Gnus sort the -group buffer according to how often you read groups, perhaps? Within -reason? - -This is what @dfn{group score} is for. You can assign a score to each -group. You can then sort the group buffer based on this score. -Alternatively, you can sort on score and then level. (Taken together, -the level and the score is called the @dfn{rank} of the group. A group -that is on level 4 and has a score of 1 has a higher rank than a group -on level 5 that has a score of 300. (The level is the most significant -part and the score is the least significant part.)) - -@findex gnus-summary-bubble-group -If you want groups you read often to get higher scores than groups you -read seldom you can add the @code{gnus-summary-bubble-group} function to -the @code{gnus-summary-exit-hook} hook. This will result (after -sorting) in a bubbling sort of action. If you want to see that in -action after each summary exit, you can add -@code{gnus-group-sort-groups-by-rank} or -@code{gnus-group-sort-groups-by-score} to the same hook, but that will -slow things down somewhat. - - -@node Marking Groups -@section Marking Groups -@cindex marking groups - -If you want to perform some command on several groups, and they appear -subsequently in the group buffer, you would normally just give a -numerical prefix to the command. Most group commands will then do your -bidding on those groups. - -However, if the groups are not in sequential order, you can still -perform a command on several groups. You simply mark the groups first -with the process mark and then execute the command. - -@table @kbd - -@item # -@kindex # (Group) -@itemx M m -@kindex M m (Group) -@findex gnus-group-mark-group -Set the mark on the current group (@code{gnus-group-mark-group}). - -@item M-# -@kindex M-# (Group) -@itemx M u -@kindex M u (Group) -@findex gnus-group-unmark-group -Remove the mark from the current group -(@code{gnus-group-unmark-group}). - -@item M U -@kindex M U (Group) -@findex gnus-group-unmark-all-groups -Remove the mark from all groups (@code{gnus-group-unmark-all-groups}). - -@item M w -@kindex M w (Group) -@findex gnus-group-mark-region -Mark all groups between point and mark (@code{gnus-group-mark-region}). - -@item M b -@kindex M b (Group) -@findex gnus-group-mark-buffer -Mark all groups in the buffer (@code{gnus-group-mark-buffer}). - -@item M r -@kindex M r (Group) -@findex gnus-group-mark-regexp -Mark all groups that match some regular expression -(@code{gnus-group-mark-regexp}). -@end table - -Also @pxref{Process/Prefix}. - -@findex gnus-group-universal-argument -If you want to execute some command on all groups that have been marked -with the process mark, you can use the @kbd{M-&} -(@code{gnus-group-universal-argument}) command. It will prompt you for -the command to be executed. - - -@node Foreign Groups -@section Foreign Groups -@cindex foreign groups - -Below are some group mode commands for making and editing general foreign -groups, as well as commands to ease the creation of a few -special-purpose groups. All these commands insert the newly created -groups under point---@code{gnus-subscribe-newsgroup-method} is not -consulted. - -@table @kbd - -@item G m -@kindex G m (Group) -@findex gnus-group-make-group -@cindex making groups -Make a new group (@code{gnus-group-make-group}). Gnus will prompt you -for a name, a method and possibly an @dfn{address}. For an easier way -to subscribe to @sc{nntp} groups, @pxref{Browse Foreign Server}. - -@item G r -@kindex G r (Group) -@findex gnus-group-rename-group -@cindex renaming groups -Rename the current group to something else -(@code{gnus-group-rename-group}). This is valid only on some -groups---mail groups mostly. This command might very well be quite slow -on some backends. - -@item G c -@kindex G c (Group) -@cindex customizing -@findex gnus-group-customize -Customize the group parameters (@code{gnus-group-customize}). - -@item G e -@kindex G e (Group) -@findex gnus-group-edit-group-method -@cindex renaming groups -Enter a buffer where you can edit the select method of the current -group (@code{gnus-group-edit-group-method}). - -@item G p -@kindex G p (Group) -@findex gnus-group-edit-group-parameters -Enter a buffer where you can edit the group parameters -(@code{gnus-group-edit-group-parameters}). - -@item G E -@kindex G E (Group) -@findex gnus-group-edit-group -Enter a buffer where you can edit the group info -(@code{gnus-group-edit-group}). - -@item G d -@kindex G d (Group) -@findex gnus-group-make-directory-group -@cindex nndir -Make a directory group (@pxref{Directory Groups}). You will be prompted -for a directory name (@code{gnus-group-make-directory-group}). - -@item G h -@kindex G h (Group) -@cindex help group -@findex gnus-group-make-help-group -Make the gnus help group (@code{gnus-group-make-help-group}). - -@item G a -@kindex G a (Group) -@cindex (ding) archive -@cindex archive group -@findex gnus-group-make-archive-group -@vindex gnus-group-archive-directory -@vindex gnus-group-recent-archive-directory -Make a gnus archive group (@code{gnus-group-make-archive-group}). By -default a group pointing to the most recent articles will be created -(@code{gnus-group-recent-archive-directory}), but given a prefix, a full -group will be created from @code{gnus-group-archive-directory}. - -@item G k -@kindex G k (Group) -@findex gnus-group-make-kiboze-group -@cindex nnkiboze -Make a kiboze group. You will be prompted for a name, for a regexp to -match groups to be ``included'' in the kiboze group, and a series of -strings to match on headers (@code{gnus-group-make-kiboze-group}). -@xref{Kibozed Groups}. - -@item G D -@kindex G D (Group) -@findex gnus-group-enter-directory -@cindex nneething -Read an arbitrary directory as if it were a newsgroup with the -@code{nneething} backend (@code{gnus-group-enter-directory}). -@xref{Anything Groups}. - -@item G f -@kindex G f (Group) -@findex gnus-group-make-doc-group -@cindex ClariNet Briefs -@cindex nndoc -Make a group based on some file or other -(@code{gnus-group-make-doc-group}). If you give a prefix to this -command, you will be prompted for a file name and a file type. -Currently supported types are @code{babyl}, @code{mbox}, @code{digest}, -@code{mmdf}, @code{news}, @code{rnews}, @code{clari-briefs}, -@code{rfc934}, @code{rfc822-forward}, and @code{forward}. If you run -this command without a prefix, gnus will guess at the file type. -@xref{Document Groups}. - -@item G u -@kindex G u (Group) -@vindex gnus-useful-groups -@findex gnus-group-make-useful-group -Create one of the groups mentioned in @code{gnus-useful-groups} -(@code{gnus-group-make-useful-group}). - -@item G w -@kindex G w (Group) -@findex gnus-group-make-web-group -@cindex DejaNews -@cindex Alta Vista -@cindex InReference -@cindex nnweb -Make an ephemeral group based on a web search -(@code{gnus-group-make-web-group}). If you give a prefix to this -command, make a solid group instead. You will be prompted for the -search engine type and the search string. Valid search engine types -include @code{dejanews}, @code{altavista} and @code{reference}. -@xref{Web Searches}. - -If you use the @code{dejanews} search engine, you can limit the search -to a particular group by using a match string like -@samp{~g alt.sysadmin.recovery shaving}. - -@item G DEL -@kindex G DEL (Group) -@findex gnus-group-delete-group -This function will delete the current group -(@code{gnus-group-delete-group}). If given a prefix, this function will -actually delete all the articles in the group, and forcibly remove the -group itself from the face of the Earth. Use a prefix only if you are -absolutely sure of what you are doing. This command can't be used on -read-only groups (like @code{nntp} group), though. - -@item G V -@kindex G V (Group) -@findex gnus-group-make-empty-virtual -Make a new, fresh, empty @code{nnvirtual} group -(@code{gnus-group-make-empty-virtual}). @xref{Virtual Groups}. - -@item G v -@kindex G v (Group) -@findex gnus-group-add-to-virtual -Add the current group to an @code{nnvirtual} group -(@code{gnus-group-add-to-virtual}). Uses the process/prefix convention. -@end table - -@xref{Select Methods} for more information on the various select -methods. - -@vindex gnus-activate-foreign-newsgroups -If @code{gnus-activate-foreign-newsgroups} is a positive number, -gnus will check all foreign groups with this level or lower at startup. -This might take quite a while, especially if you subscribe to lots of -groups from different @sc{nntp} servers. Also @pxref{Group Levels}; -@code{gnus-activate-level} also affects activation of foreign -newsgroups. - - -@node Group Parameters -@section Group Parameters -@cindex group parameters - -The group parameters store information local to a particular group. -Here's an example group parameter list: - -@example -((to-address . "ding@@gnus.org") - (auto-expire . t)) -@end example - -We see that each element consists of a ``dotted pair''---the thing -before the dot is the key, while the thing after the dot is the value. -All the parameters have this form @emph{except} local variable specs, -which are not dotted pairs, but proper lists. - -The following group parameters can be used: - -@table @code -@item to-address -@cindex to-address -Address used by when doing followups and new posts. - -@example -(to-address . "some@@where.com") -@end example - -This is primarily useful in mail groups that represent closed mailing -lists---mailing lists where it's expected that everybody that writes to -the mailing list is subscribed to it. Since using this parameter -ensures that the mail only goes to the mailing list itself, it means -that members won't receive two copies of your followups. - -Using @code{to-address} will actually work whether the group is foreign -or not. Let's say there's a group on the server that is called -@samp{fa.4ad-l}. This is a real newsgroup, but the server has gotten -the articles from a mail-to-news gateway. Posting directly to this -group is therefore impossible---you have to send mail to the mailing -list address instead. - -@item to-list -@cindex to-list -Address used when doing a @kbd{a} in that group. - -@example -(to-list . "some@@where.com") -@end example - -It is totally ignored -when doing a followup---except that if it is present in a news group, -you'll get mail group semantics when doing @kbd{f}. - -If you do an @kbd{a} command in a mail group and you have neither a -@code{to-list} group parameter nor a @code{to-address} group parameter, -then a @code{to-list} group parameter will be added automatically upon -sending the message if @code{gnus-add-to-list} is set to @code{t}. -@vindex gnus-add-to-list - -If you do an @kbd{a} command in a mail group and you don't have a -@code{to-list} group parameter, one will be added automatically upon -sending the message. - -@item visible -@cindex visible -If the group parameter list has the element @code{(visible . t)}, -that group will always be visible in the Group buffer, regardless -of whether it has any unread articles. - -@item broken-reply-to -@cindex broken-reply-to -Elements like @code{(broken-reply-to . t)} signals that @code{Reply-To} -headers in this group are to be ignored. This can be useful if you're -reading a mailing list group where the listserv has inserted -@code{Reply-To} headers that point back to the listserv itself. This is -broken behavior. So there! - -@item to-group -@cindex to-group -Elements like @code{(to-group . "some.group.name")} means that all -posts in that group will be sent to @code{some.group.name}. - -@item newsgroup -@cindex newsgroup -If you have @code{(newsgroup . t)} in the group parameter list, gnus -will treat all responses as if they were responses to news articles. -This can be useful if you have a mail group that's really a mirror of a -news group. - -@item gcc-self -@cindex gcc-self -If @code{(gcc-self . t)} is present in the group parameter list, newly -composed messages will be @code{Gcc}'d to the current group. If -@code{(gcc-self . none)} is present, no @code{Gcc:} header will be -generated, if @code{(gcc-self . "string")} is present, this string will -be inserted literally as a @code{gcc} header. This parameter takes -precedence over any default @code{Gcc} rules as described later -(@pxref{Archived Messages}). - -@item auto-expire -@cindex auto-expire -If the group parameter has an element that looks like @code{(auto-expire -. t)}, all articles read will be marked as expirable. For an -alternative approach, @pxref{Expiring Mail}. - -@item total-expire -@cindex total-expire -If the group parameter has an element that looks like -@code{(total-expire . t)}, all read articles will be put through the -expiry process, even if they are not marked as expirable. Use with -caution. Unread, ticked and dormant articles are not eligible for -expiry. - -@item expiry-wait -@cindex expiry-wait -@vindex nnmail-expiry-wait-function -If the group parameter has an element that looks like @code{(expiry-wait -. 10)}, this value will override any @code{nnmail-expiry-wait} and -@code{nnmail-expiry-wait-function} when expiring expirable messages. -The value can either be a number of days (not necessarily an integer) or -the symbols @code{never} or @code{immediate}. - -@item score-file -@cindex score file group parameter -Elements that look like @code{(score-file . "file")} will make -@file{file} into the current score file for the group in question. All -interactive score entries will be put into this file. - -@item adapt-file -@cindex adapt file group parameter -Elements that look like @code{(adapt-file . "file")} will make -@file{file} into the current adaptive file for the group in question. -All adaptive score entries will be put into this file. - -@item admin-address -When unsubscribing from a mailing list you should never send the -unsubscription notice to the mailing list itself. Instead, you'd send -messages to the administrative address. This parameter allows you to -put the admin address somewhere convenient. - -@item display -Elements that look like @code{(display . MODE)} say which articles to -display on entering the group. Valid values are: - -@table @code -@item all -Display all articles, both read and unread. - -@item default -Display the default visible articles, which normally includes unread and -ticked articles. -@end table - -@item comment -Elements that look like @code{(comment . "This is a comment")} are -arbitrary comments on the group. They are currently ignored by gnus, -but provide a place for you to store information on particular groups. - -@item @var{(variable form)} -You can use the group parameters to set variables local to the group you -are entering. If you want to turn threading off in @samp{news.answers}, -you could put @code{(gnus-show-threads nil)} in the group parameters of -that group. @code{gnus-show-threads} will be made into a local variable -in the summary buffer you enter, and the form @code{nil} will be -@code{eval}ed there. - -This can also be used as a group-specific hook function, if you'd like. -If you want to hear a beep when you enter a group, you could put -something like @code{(dummy-variable (ding))} in the parameters of that -group. @code{dummy-variable} will be set to the result of the -@code{(ding)} form, but who cares? - -@end table - -Use the @kbd{G p} command to edit group parameters of a group. You -might also be interested in reading about topic parameters (@pxref{Topic -Parameters}). - - -@node Listing Groups -@section Listing Groups -@cindex group listing - -These commands all list various slices of the groups available. - -@table @kbd - -@item l -@itemx A s -@kindex A s (Group) -@kindex l (Group) -@findex gnus-group-list-groups -List all groups that have unread articles -(@code{gnus-group-list-groups}). If the numeric prefix is used, this -command will list only groups of level ARG and lower. By default, it -only lists groups of level five (i. e., -@code{gnus-group-default-list-level}) or lower (i.e., just subscribed -groups). - -@item L -@itemx A u -@kindex A u (Group) -@kindex L (Group) -@findex gnus-group-list-all-groups -List all groups, whether they have unread articles or not -(@code{gnus-group-list-all-groups}). If the numeric prefix is used, -this command will list only groups of level ARG and lower. By default, -it lists groups of level seven or lower (i.e., just subscribed and -unsubscribed groups). - -@item A l -@kindex A l (Group) -@findex gnus-group-list-level -List all unread groups on a specific level -(@code{gnus-group-list-level}). If given a prefix, also list the groups -with no unread articles. - -@item A k -@kindex A k (Group) -@findex gnus-group-list-killed -List all killed groups (@code{gnus-group-list-killed}). If given a -prefix argument, really list all groups that are available, but aren't -currently (un)subscribed. This could entail reading the active file -from the server. - -@item A z -@kindex A z (Group) -@findex gnus-group-list-zombies -List all zombie groups (@code{gnus-group-list-zombies}). - -@item A m -@kindex A m (Group) -@findex gnus-group-list-matching -List all unread, subscribed groups with names that match a regexp -(@code{gnus-group-list-matching}). - -@item A M -@kindex A M (Group) -@findex gnus-group-list-all-matching -List groups that match a regexp (@code{gnus-group-list-all-matching}). - -@item A A -@kindex A A (Group) -@findex gnus-group-list-active -List absolutely all groups in the active file(s) of the -server(s) you are connected to (@code{gnus-group-list-active}). This -might very well take quite a while. It might actually be a better idea -to do a @kbd{A M} to list all matching, and just give @samp{.} as the -thing to match on. Also note that this command may list groups that -don't exist (yet)---these will be listed as if they were killed groups. -Take the output with some grains of salt. - -@item A a -@kindex A a (Group) -@findex gnus-group-apropos -List all groups that have names that match a regexp -(@code{gnus-group-apropos}). - -@item A d -@kindex A d (Group) -@findex gnus-group-description-apropos -List all groups that have names or descriptions that match a regexp -(@code{gnus-group-description-apropos}). - -@end table - -@vindex gnus-permanently-visible-groups -@cindex visible group parameter -Groups that match the @code{gnus-permanently-visible-groups} regexp will -always be shown, whether they have unread articles or not. You can also -add the @code{visible} element to the group parameters in question to -get the same effect. - -@vindex gnus-list-groups-with-ticked-articles -Groups that have just ticked articles in it are normally listed in the -group buffer. If @code{gnus-list-groups-with-ticked-articles} is -@code{nil}, these groups will be treated just like totally empty -groups. It is @code{t} by default. - - -@node Sorting Groups -@section Sorting Groups -@cindex sorting groups - -@kindex C-c C-s (Group) -@findex gnus-group-sort-groups -@vindex gnus-group-sort-function -The @kbd{C-c C-s} (@code{gnus-group-sort-groups}) command sorts the -group buffer according to the function(s) given by the -@code{gnus-group-sort-function} variable. Available sorting functions -include: - -@table @code - -@item gnus-group-sort-by-alphabet -@findex gnus-group-sort-by-alphabet -Sort the group names alphabetically. This is the default. - -@item gnus-group-sort-by-real-name -@findex gnus-group-sort-by-real-name -Sort the group alphabetically on the real (unprefixed) group names. - -@item gnus-group-sort-by-level -@findex gnus-group-sort-by-level -Sort by group level. - -@item gnus-group-sort-by-score -@findex gnus-group-sort-by-score -Sort by group score. @xref{Group Score}. - -@item gnus-group-sort-by-rank -@findex gnus-group-sort-by-rank -Sort by group score and then the group level. The level and the score -are, when taken together, the group's @dfn{rank}. @xref{Group Score}. - -@item gnus-group-sort-by-unread -@findex gnus-group-sort-by-unread -Sort by number of unread articles. - -@item gnus-group-sort-by-method -@findex gnus-group-sort-by-method -Sort alphabetically on the select method. - - -@end table - -@code{gnus-group-sort-function} can also be a list of sorting -functions. In that case, the most significant sort key function must be -the last one. - - -There are also a number of commands for sorting directly according to -some sorting criteria: - -@table @kbd -@item G S a -@kindex G S a (Group) -@findex gnus-group-sort-groups-by-alphabet -Sort the group buffer alphabetically by group name -(@code{gnus-group-sort-groups-by-alphabet}). - -@item G S u -@kindex G S u (Group) -@findex gnus-group-sort-groups-by-unread -Sort the group buffer by the number of unread articles -(@code{gnus-group-sort-groups-by-unread}). - -@item G S l -@kindex G S l (Group) -@findex gnus-group-sort-groups-by-level -Sort the group buffer by group level -(@code{gnus-group-sort-groups-by-level}). - -@item G S v -@kindex G S v (Group) -@findex gnus-group-sort-groups-by-score -Sort the group buffer by group score -(@code{gnus-group-sort-groups-by-score}). @xref{Group Score}. - -@item G S r -@kindex G S r (Group) -@findex gnus-group-sort-groups-by-rank -Sort the group buffer by group rank -(@code{gnus-group-sort-groups-by-rank}). @xref{Group Score}. - -@item G S m -@kindex G S m (Group) -@findex gnus-group-sort-groups-by-method -Sort the group buffer alphabetically by backend name -(@code{gnus-group-sort-groups-by-method}). - -@end table - -When given a prefix, all these commands will sort in reverse order. - -You can also sort a subset of the groups: - -@table @kbd -@item G P a -@kindex G P a (Group) -@findex gnus-group-sort-selected-groups-by-alphabet -Sort the process/prefixed groups in the group buffer alphabetically by -group name (@code{gnus-group-sort-selected-groups-by-alphabet}). - -@item G P u -@kindex G P u (Group) -@findex gnus-group-sort-selected-groups-by-unread -Sort the process/prefixed groups in the group buffer by the number of -unread articles (@code{gnus-group-sort-selected-groups-by-unread}). - -@item G P l -@kindex G P l (Group) -@findex gnus-group-sort-selected-groups-by-level -Sort the process/prefixed groups in the group buffer by group level -(@code{gnus-group-sort-selected-groups-by-level}). - -@item G P v -@kindex G P v (Group) -@findex gnus-group-sort-selected-groups-by-score -Sort the process/prefixed groups in the group buffer by group score -(@code{gnus-group-sort-selected-groups-by-score}). @xref{Group Score}. - -@item G P r -@kindex G P r (Group) -@findex gnus-group-sort-selected-groups-by-rank -Sort the process/prefixed groups in the group buffer by group rank -(@code{gnus-group-sort-selected-groups-by-rank}). @xref{Group Score}. - -@item G P m -@kindex G P m (Group) -@findex gnus-group-sort-selected-groups-by-method -Sort the process/prefixed groups in the group buffer alphabetically by -backend name (@code{gnus-group-sort-selected-groups-by-method}). - -@end table - - - -@node Group Maintenance -@section Group Maintenance -@cindex bogus groups - -@table @kbd -@item b -@kindex b (Group) -@findex gnus-group-check-bogus-groups -Find bogus groups and delete them -(@code{gnus-group-check-bogus-groups}). - -@item F -@kindex F (Group) -@findex gnus-group-find-new-groups -Find new groups and process them (@code{gnus-group-find-new-groups}). -With 1 @kbd{C-u}, use the @code{ask-server} method to query the server -for new groups. With 2 @kbd{C-u}'s, use most complete method possible -to query the server for new groups, and subscribe the new groups as -zombies. - -@item C-c C-x -@kindex C-c C-x (Group) -@findex gnus-group-expire-articles -Run all expirable articles in the current group through the expiry -process (if any) (@code{gnus-group-expire-articles}). - -@item C-c M-C-x -@kindex C-c M-C-x (Group) -@findex gnus-group-expire-all-groups -Run all articles in all groups through the expiry process -(@code{gnus-group-expire-all-groups}). - -@end table - - -@node Browse Foreign Server -@section Browse Foreign Server -@cindex foreign servers -@cindex browsing servers - -@table @kbd -@item B -@kindex B (Group) -@findex gnus-group-browse-foreign-server -You will be queried for a select method and a server name. Gnus will -then attempt to contact this server and let you browse the groups there -(@code{gnus-group-browse-foreign-server}). -@end table - -@findex gnus-browse-mode -A new buffer with a list of available groups will appear. This buffer -will use the @code{gnus-browse-mode}. This buffer looks a bit (well, -a lot) like a normal group buffer. - -Here's a list of keystrokes available in the browse mode: - -@table @kbd -@item n -@kindex n (Browse) -@findex gnus-group-next-group -Go to the next group (@code{gnus-group-next-group}). - -@item p -@kindex p (Browse) -@findex gnus-group-prev-group -Go to the previous group (@code{gnus-group-prev-group}). - -@item SPACE -@kindex SPACE (Browse) -@findex gnus-browse-read-group -Enter the current group and display the first article -(@code{gnus-browse-read-group}). - -@item RET -@kindex RET (Browse) -@findex gnus-browse-select-group -Enter the current group (@code{gnus-browse-select-group}). - -@item u -@kindex u (Browse) -@findex gnus-browse-unsubscribe-current-group -Unsubscribe to the current group, or, as will be the case here, -subscribe to it (@code{gnus-browse-unsubscribe-current-group}). - -@item l -@itemx q -@kindex q (Browse) -@kindex l (Browse) -@findex gnus-browse-exit -Exit browse mode (@code{gnus-browse-exit}). - -@item ? -@kindex ? (Browse) -@findex gnus-browse-describe-briefly -Describe browse mode briefly (well, there's not much to describe, is -there) (@code{gnus-browse-describe-briefly}). -@end table - - -@node Exiting Gnus -@section Exiting gnus -@cindex exiting gnus - -Yes, gnus is ex(c)iting. - -@table @kbd -@item z -@kindex z (Group) -@findex gnus-group-suspend -Suspend gnus (@code{gnus-group-suspend}). This doesn't really exit -gnus, but it kills all buffers except the Group buffer. I'm not sure -why this is a gain, but then who am I to judge? - -@item q -@kindex q (Group) -@findex gnus-group-exit -@c @icon{gnus-group-exit} -Quit gnus (@code{gnus-group-exit}). - -@item Q -@kindex Q (Group) -@findex gnus-group-quit -Quit gnus without saving the @file{.newsrc} files -(@code{gnus-group-quit}). The dribble file will be saved, though -(@pxref{Auto Save}). -@end table - -@vindex gnus-exit-gnus-hook -@vindex gnus-suspend-gnus-hook -@code{gnus-suspend-gnus-hook} is called when you suspend gnus and -@code{gnus-exit-gnus-hook} is called when you quit gnus, while -@code{gnus-after-exiting-gnus-hook} is called as the final item when -exiting gnus. - -@findex gnus-unload -@cindex unloading -If you wish to completely unload gnus and all its adherents, you can use -the @code{gnus-unload} command. This command is also very handy when -trying to customize meta-variables. - -Note: - -@quotation -Miss Lisa Cannifax, while sitting in English class, felt her feet go -numbly heavy and herself fall into a hazy trance as the boy sitting -behind her drew repeated lines with his pencil across the back of her -plastic chair. -@end quotation - - -@node Group Topics -@section Group Topics -@cindex topics - -If you read lots and lots of groups, it might be convenient to group -them hierarchically according to topics. You put your Emacs groups over -here, your sex groups over there, and the rest (what, two groups or so?) -you put in some misc section that you never bother with anyway. You can -even group the Emacs sex groups as a sub-topic to either the Emacs -groups or the sex groups---or both! Go wild! - -@iftex -@iflatex -\gnusfigure{Group Topics}{400}{ -\put(75,50){\epsfig{figure=tmp/group-topic.ps,height=9cm}} -} -@end iflatex -@end iftex - -Here's an example: - -@example -Gnus - Emacs -- I wuw it! - 3: comp.emacs - 2: alt.religion.emacs - Naughty Emacs - 452: alt.sex.emacs - 0: comp.talk.emacs.recovery - Misc - 8: comp.binaries.fractals - 13: comp.sources.unix -@end example - -@findex gnus-topic-mode -@kindex t (Group) -To get this @emph{fab} functionality you simply turn on (ooh!) the -@code{gnus-topic} minor mode---type @kbd{t} in the group buffer. (This -is a toggling command.) - -Go ahead, just try it. I'll still be here when you get back. La de -dum... Nice tune, that... la la la... What, you're back? Yes, and now -press @kbd{l}. There. All your groups are now listed under -@samp{misc}. Doesn't that make you feel all warm and fuzzy? Hot and -bothered? - -If you want this permanently enabled, you should add that minor mode to -the hook for the group mode: - -@lisp -(add-hook 'gnus-group-mode-hook 'gnus-topic-mode) -@end lisp - -@menu -* Topic Variables:: How to customize the topics the Lisp Way. -* Topic Commands:: Interactive E-Z commands. -* Topic Sorting:: Sorting each topic individually. -* Topic Topology:: A map of the world. -* Topic Parameters:: Parameters that apply to all groups in a topic. -@end menu - - -@node Topic Variables -@subsection Topic Variables -@cindex topic variables - -Now, if you select a topic, it will fold/unfold that topic, which is -really neat, I think. - -@vindex gnus-topic-line-format -The topic lines themselves are created according to the -@code{gnus-topic-line-format} variable (@pxref{Formatting Variables}). -Valid elements are: - -@table @samp -@item i -Indentation. -@item n -Topic name. -@item v -Visibility. -@item l -Level. -@item g -Number of groups in the topic. -@item a -Number of unread articles in the topic. -@item A -Number of unread articles in the topic and all its subtopics. -@end table - -@vindex gnus-topic-indent-level -Each sub-topic (and the groups in the sub-topics) will be indented with -@code{gnus-topic-indent-level} times the topic level number of spaces. -The default is 2. - -@vindex gnus-topic-mode-hook -@code{gnus-topic-mode-hook} is called in topic minor mode buffers. - -@vindex gnus-topic-display-empty-topics -The @code{gnus-topic-display-empty-topics} says whether to display even -topics that have no unread articles in them. The default is @code{t}. - - -@node Topic Commands -@subsection Topic Commands -@cindex topic commands - -When the topic minor mode is turned on, a new @kbd{T} submap will be -available. In addition, a few of the standard keys change their -definitions slightly. - -@table @kbd - -@item T n -@kindex T n (Topic) -@findex gnus-topic-create-topic -Prompt for a new topic name and create it -(@code{gnus-topic-create-topic}). - -@item T m -@kindex T m (Topic) -@findex gnus-topic-move-group -Move the current group to some other topic -(@code{gnus-topic-move-group}). This command uses the process/prefix -convention (@pxref{Process/Prefix}). - -@item T c -@kindex T c (Topic) -@findex gnus-topic-copy-group -Copy the current group to some other topic -(@code{gnus-topic-copy-group}). This command uses the process/prefix -convention (@pxref{Process/Prefix}). - -@item T D -@kindex T D (Topic) -@findex gnus-topic-remove-group -Remove a group from the current topic (@code{gnus-topic-remove-group}). -This command is mainly useful if you have the same group in several -topics and wish to remove it from one of the topics. You may also -remove a group from all topics, but in that case, Gnus will add it to -the root topic the next time you start Gnus. In fact, all new groups -(which, naturally, don't belong to any topic) will show up in the root -topic. - -This command uses the process/prefix convention -(@pxref{Process/Prefix}). - -@item T M -@kindex T M (Topic) -@findex gnus-topic-move-matching -Move all groups that match some regular expression to a topic -(@code{gnus-topic-move-matching}). - -@item T C -@kindex T C (Topic) -@findex gnus-topic-copy-matching -Copy all groups that match some regular expression to a topic -(@code{gnus-topic-copy-matching}). - -@item T H -@kindex T H (Topic) -@findex gnus-topic-toggle-display-empty-topics -Toggle hiding empty topics -(@code{gnus-topic-toggle-display-empty-topics}). - -@item T # -@kindex T # (Topic) -@findex gnus-topic-mark-topic -Mark all groups in the current topic with the process mark -(@code{gnus-topic-mark-topic}). - -@item T M-# -@kindex T M-# (Topic) -@findex gnus-topic-unmark-topic -Remove the process mark from all groups in the current topic -(@code{gnus-topic-unmark-topic}). - -@item RET -@kindex RET (Topic) -@findex gnus-topic-select-group -@itemx SPACE -Either select a group or fold a topic (@code{gnus-topic-select-group}). -When you perform this command on a group, you'll enter the group, as -usual. When done on a topic line, the topic will be folded (if it was -visible) or unfolded (if it was folded already). So it's basically a -toggling command on topics. In addition, if you give a numerical -prefix, group on that level (and lower) will be displayed. - -@item T TAB -@itemx TAB -@kindex T TAB (Topic) -@kindex TAB (Topic) -@findex gnus-topic-indent -``Indent'' the current topic so that it becomes a sub-topic of the -previous topic (@code{gnus-topic-indent}). If given a prefix, -``un-indent'' the topic instead. - -@item M-TAB -@kindex M-TAB (Topic) -@findex gnus-topic-unindent -``Un-indent'' the current topic so that it becomes a sub-topic of the -parent of its current parent (@code{gnus-topic-unindent}). - -@item C-k -@kindex C-k (Topic) -@findex gnus-topic-kill-group -Kill a group or topic (@code{gnus-topic-kill-group}). All groups in the -topic will be removed along with the topic. - -@item C-y -@kindex C-y (Topic) -@findex gnus-topic-yank-group -Yank the previously killed group or topic -(@code{gnus-topic-yank-group}). Note that all topics will be yanked -before all groups. - -@item T r -@kindex T r (Topic) -@findex gnus-topic-rename -Rename a topic (@code{gnus-topic-rename}). - -@item T DEL -@kindex T DEL (Topic) -@findex gnus-topic-delete -Delete an empty topic (@code{gnus-topic-delete}). - -@item A T -@kindex A T (Topic) -@findex gnus-topic-list-active -List all groups that gnus knows about in a topics-ified way -(@code{gnus-topic-list-active}). - -@item G p -@kindex G p (Topic) -@findex gnus-topic-edit-parameters -@cindex group parameters -@cindex topic parameters -@cindex parameters -Edit the topic parameters (@code{gnus-topic-edit-parameters}). -@xref{Topic Parameters}. - -@end table - - -@node Topic Sorting -@subsection Topic Sorting -@cindex topic sorting - -You can sort the groups in each topic individually with the following -commands: - - -@table @kbd -@item T S a -@kindex T S a (Topic) -@findex gnus-topic-sort-groups-by-alphabet -Sort the current topic alphabetically by group name -(@code{gnus-topic-sort-groups-by-alphabet}). - -@item T S u -@kindex T S u (Topic) -@findex gnus-topic-sort-groups-by-unread -Sort the current topic by the number of unread articles -(@code{gnus-topic-sort-groups-by-unread}). - -@item T S l -@kindex T S l (Topic) -@findex gnus-topic-sort-groups-by-level -Sort the current topic by group level -(@code{gnus-topic-sort-groups-by-level}). - -@item T S v -@kindex T S v (Topic) -@findex gnus-topic-sort-groups-by-score -Sort the current topic by group score -(@code{gnus-topic-sort-groups-by-score}). @xref{Group Score}. - -@item T S r -@kindex T S r (Topic) -@findex gnus-topic-sort-groups-by-rank -Sort the current topic by group rank -(@code{gnus-topic-sort-groups-by-rank}). @xref{Group Score}. - -@item T S m -@kindex T S m (Topic) -@findex gnus-topic-sort-groups-by-method -Sort the current topic alphabetically by backend name -(@code{gnus-topic-sort-groups-by-method}). - -@end table - -@xref{Sorting Groups} for more information about group sorting. - - -@node Topic Topology -@subsection Topic Topology -@cindex topic topology -@cindex topology - -So, let's have a look at an example group buffer: - -@example -Gnus - Emacs -- I wuw it! - 3: comp.emacs - 2: alt.religion.emacs - Naughty Emacs - 452: alt.sex.emacs - 0: comp.talk.emacs.recovery - Misc - 8: comp.binaries.fractals - 13: comp.sources.unix -@end example - -So, here we have one top-level topic (@samp{Gnus}), two topics under -that, and one sub-topic under one of the sub-topics. (There is always -just one (1) top-level topic). This topology can be expressed as -follows: - -@lisp -(("Gnus" visible) - (("Emacs -- I wuw it!" visible) - (("Naughty Emacs" visible))) - (("Misc" visible))) -@end lisp - -@vindex gnus-topic-topology -This is in fact how the variable @code{gnus-topic-topology} would look -for the display above. That variable is saved in the @file{.newsrc.eld} -file, and shouldn't be messed with manually---unless you really want -to. Since this variable is read from the @file{.newsrc.eld} file, -setting it in any other startup files will have no effect. - -This topology shows what topics are sub-topics of what topics (right), -and which topics are visible. Two settings are currently -allowed---@code{visible} and @code{invisible}. - - -@node Topic Parameters -@subsection Topic Parameters -@cindex topic parameters - -All groups in a topic will inherit group parameters from the parent (and -ancestor) topic parameters. All valid group parameters are valid topic -parameters (@pxref{Group Parameters}). - -Group parameters (of course) override topic parameters, and topic -parameters in sub-topics override topic parameters in super-topics. You -know. Normal inheritance rules. (@dfn{Rules} is here a noun, not a -verb, although you may feel free to disagree with me here.) - -@example -Gnus - Emacs - 3: comp.emacs - 2: alt.religion.emacs - 452: alt.sex.emacs - Relief - 452: alt.sex.emacs - 0: comp.talk.emacs.recovery - Misc - 8: comp.binaries.fractals - 13: comp.sources.unix - 452: alt.sex.emacs -@end example - -The @samp{Emacs} topic has the topic parameter @code{(score-file -. "emacs.SCORE")}; the @samp{Relief} topic has the topic parameter -@code{(score-file . "relief.SCORE")}; and the @samp{Misc} topic has the -topic parameter @code{(score-file . "emacs.SCORE")}. In addition, -@* @samp{alt.religion.emacs} has the group parameter @code{(score-file -. "religion.SCORE")}. - -Now, when you enter @samp{alt.sex.emacs} in the @samp{Relief} topic, you -will get the @file{relief.SCORE} home score file. If you enter the same -group in the @samp{Emacs} topic, you'll get the @file{emacs.SCORE} home -score file. If you enter the group @samp{alt.religion.emacs}, you'll -get the @file{religion.SCORE} home score file. - -This seems rather simple and self-evident, doesn't it? Well, yes. But -there are some problems, especially with the @code{total-expiry} -parameter. Say you have a mail group in two topics; one with -@code{total-expiry} and one without. What happens when you do @kbd{M-x -gnus-expire-all-expirable-groups}? Gnus has no way of telling which one -of these topics you mean to expire articles from, so anything may -happen. In fact, I hereby declare that it is @dfn{undefined} what -happens. You just have to be careful if you do stuff like that. - - -@node Misc Group Stuff -@section Misc Group Stuff - -@menu -* Scanning New Messages:: Asking gnus to see whether new messages have arrived. -* Group Information:: Information and help on groups and gnus. -* Group Timestamp:: Making gnus keep track of when you last read a group. -* File Commands:: Reading and writing the gnus files. -@end menu - -@table @kbd - -@item ^ -@kindex ^ (Group) -@findex gnus-group-enter-server-mode -Enter the server buffer (@code{gnus-group-enter-server-mode}). -@xref{The Server Buffer}. - -@item a -@kindex a (Group) -@findex gnus-group-post-news -Post an article to a group (@code{gnus-group-post-news}). If given a -prefix, the current group name will be used as the default. - -@item m -@kindex m (Group) -@findex gnus-group-mail -Mail a message somewhere (@code{gnus-group-mail}). - -@end table - -Variables for the group buffer: - -@table @code - -@item gnus-group-mode-hook -@vindex gnus-group-mode-hook -is called after the group buffer has been -created. - -@item gnus-group-prepare-hook -@vindex gnus-group-prepare-hook -is called after the group buffer is -generated. It may be used to modify the buffer in some strange, -unnatural way. - -@item gnus-group-prepared-hook -@vindex gnus-group-prepare-hook -is called as the very last thing after the group buffer has been -generated. It may be used to move point around, for instance. - -@item gnus-permanently-visible-groups -@vindex gnus-permanently-visible-groups -Groups matching this regexp will always be listed in the group buffer, -whether they are empty or not. - -@end table - - -@node Scanning New Messages -@subsection Scanning New Messages -@cindex new messages -@cindex scanning new news - -@table @kbd - -@item g -@kindex g (Group) -@findex gnus-group-get-new-news -@c @icon{gnus-group-get-new-news} -Check the server(s) for new articles. If the numerical prefix is used, -this command will check only groups of level @var{arg} and lower -(@code{gnus-group-get-new-news}). If given a non-numerical prefix, this -command will force a total re-reading of the active file(s) from the -backend(s). - -@item M-g -@kindex M-g (Group) -@findex gnus-group-get-new-news-this-group -@vindex gnus-goto-next-group-when-activating -@c @icon{gnus-group-get-new-news-this-group} -Check whether new articles have arrived in the current group -(@code{gnus-group-get-new-news-this-group}). -@code{gnus-goto-next-group-when-activating} says whether this command is -to move point to the next group or not. It is @code{t} by default. - -@findex gnus-activate-all-groups -@cindex activating groups -@item C-c M-g -@kindex C-c M-g (Group) -Activate absolutely all groups (@code{gnus-activate-all-groups}). - -@item R -@kindex R (Group) -@cindex restarting -@findex gnus-group-restart -Restart gnus (@code{gnus-group-restart}). This saves the @file{.newsrc} -file(s), closes the connection to all servers, clears up all run-time -gnus variables, and then starts gnus all over again. - -@end table - -@vindex gnus-get-new-news-hook -@code{gnus-get-new-news-hook} is run just before checking for new news. - -@vindex gnus-after-getting-new-news-hook -@code{gnus-after-getting-new-news-hook} is run after checking for new -news. - - -@node Group Information -@subsection Group Information -@cindex group information -@cindex information on groups - -@table @kbd - - -@item H f -@kindex H f (Group) -@findex gnus-group-fetch-faq -@vindex gnus-group-faq-directory -@cindex FAQ -@cindex ange-ftp -Try to fetch the FAQ for the current group -(@code{gnus-group-fetch-faq}). Gnus will try to get the FAQ from -@code{gnus-group-faq-directory}, which is usually a directory on a -remote machine. This variable can also be a list of directories. In -that case, giving a prefix to this command will allow you to choose -between the various sites. @code{ange-ftp} (or @code{efs}) will be used -for fetching the file. - -If fetching from the first site is unsuccessful, gnus will attempt to go -through @code{gnus-group-faq-directory} and try to open them one by one. - -@item H d -@itemx C-c C-d -@c @icon{gnus-group-describe-group} -@kindex H d (Group) -@kindex C-c C-d (Group) -@cindex describing groups -@cindex group description -@findex gnus-group-describe-group -Describe the current group (@code{gnus-group-describe-group}). If given -a prefix, force Gnus to re-read the description from the server. - -@item M-d -@kindex M-d (Group) -@findex gnus-group-describe-all-groups -Describe all groups (@code{gnus-group-describe-all-groups}). If given a -prefix, force gnus to re-read the description file from the server. - -@item H v -@itemx V -@kindex V (Group) -@kindex H v (Group) -@cindex version -@findex gnus-version -Display current gnus version numbers (@code{gnus-version}). - -@item ? -@kindex ? (Group) -@findex gnus-group-describe-briefly -Give a very short help message (@code{gnus-group-describe-briefly}). - -@item C-c C-i -@kindex C-c C-i (Group) -@cindex info -@cindex manual -@findex gnus-info-find-node -Go to the gnus info node (@code{gnus-info-find-node}). -@end table - - -@node Group Timestamp -@subsection Group Timestamp -@cindex timestamps -@cindex group timestamps - -It can be convenient to let gnus keep track of when you last read a -group. To set the ball rolling, you should add -@code{gnus-group-set-timestamp} to @code{gnus-select-group-hook}: - -@lisp -(add-hook 'gnus-select-group-hook 'gnus-group-set-timestamp) -@end lisp - -After doing this, each time you enter a group, it'll be recorded. - -This information can be displayed in various ways---the easiest is to -use the @samp{%d} spec in the group line format: - -@lisp -(setq gnus-group-line-format - "%M\%S\%p\%P\%5y: %(%-40,40g%) %d\n") -@end lisp - -This will result in lines looking like: - -@example -* 0: mail.ding 19961002T012943 - 0: custom 19961002T012713 -@end example - -As you can see, the date is displayed in compact ISO 8601 format. This -may be a bit too much, so to just display the date, you could say -something like: - -@lisp -(setq gnus-group-line-format - "%M\%S\%p\%P\%5y: %(%-40,40g%) %6,6~(cut 2)d\n") -@end lisp - - -@node File Commands -@subsection File Commands -@cindex file commands - -@table @kbd - -@item r -@kindex r (Group) -@findex gnus-group-read-init-file -@vindex gnus-init-file -@cindex reading init file -Re-read the init file (@code{gnus-init-file}, which defaults to -@file{~/.gnus}) (@code{gnus-group-read-init-file}). - -@item s -@kindex s (Group) -@findex gnus-group-save-newsrc -@cindex saving .newsrc -Save the @file{.newsrc.eld} file (and @file{.newsrc} if wanted) -(@code{gnus-group-save-newsrc}). If given a prefix, force saving the -file(s) whether Gnus thinks it is necessary or not. - -@c @item Z -@c @kindex Z (Group) -@c @findex gnus-group-clear-dribble -@c Clear the dribble buffer (@code{gnus-group-clear-dribble}). - -@end table - - -@node The Summary Buffer -@chapter The Summary Buffer -@cindex summary buffer - -A line for each article is displayed in the summary buffer. You can -move around, read articles, post articles and reply to articles. - -The most common way to a summary buffer is to select a group from the -group buffer (@pxref{Selecting a Group}). - -You can have as many summary buffers open as you wish. - -@menu -* Summary Buffer Format:: Deciding how the summary buffer is to look. -* Summary Maneuvering:: Moving around the summary buffer. -* Choosing Articles:: Reading articles. -* Paging the Article:: Scrolling the current article. -* Reply Followup and Post:: Posting articles. -* Canceling and Superseding:: ``Whoops, I shouldn't have called him that.'' -* Marking Articles:: Marking articles as read, expirable, etc. -* Limiting:: You can limit the summary buffer. -* Threading:: How threads are made. -* Sorting:: How articles and threads are sorted. -* Asynchronous Fetching:: Gnus might be able to pre-fetch articles. -* Article Caching:: You may store articles in a cache. -* Persistent Articles:: Making articles expiry-resistant. -* Article Backlog:: Having already read articles hang around. -* Saving Articles:: Ways of customizing article saving. -* Decoding Articles:: Gnus can treat series of (uu)encoded articles. -* Article Treatment:: The article buffer can be mangled at will. -* Article Commands:: Doing various things with the article buffer. -* Summary Sorting:: Sorting the summary buffer in various ways. -* Finding the Parent:: No child support? Get the parent. -* Alternative Approaches:: Reading using non-default summaries. -* Tree Display:: A more visual display of threads. -* Mail Group Commands:: Some commands can only be used in mail groups. -* Various Summary Stuff:: What didn't fit anywhere else. -* Exiting the Summary Buffer:: Returning to the Group buffer. -* Crosspost Handling:: How crossposted articles are dealt with. -* Duplicate Suppression:: An alternative when crosspost handling fails. -@end menu - - -@node Summary Buffer Format -@section Summary Buffer Format -@cindex summary buffer format - -@iftex -@iflatex -\gnusfigure{The Summary Buffer}{180}{ -\put(0,0){\epsfig{figure=tmp/summary.ps,width=7.5cm}} -\put(445,0){\makebox(0,0)[br]{\epsfig{figure=tmp/summary-article.ps,width=7.5cm}}} -} -@end iflatex -@end iftex - -@menu -* Summary Buffer Lines:: You can specify how summary lines should look. -* Summary Buffer Mode Line:: You can say how the mode line should look. -* Summary Highlighting:: Making the summary buffer all pretty and nice. -@end menu - -@findex mail-extract-address-components -@findex gnus-extract-address-components -@vindex gnus-extract-address-components -Gnus will use the value of the @code{gnus-extract-address-components} -variable as a function for getting the name and address parts of a -@code{From} header. Three pre-defined functions exist: -@code{gnus-extract-address-components}, which is the default, quite -fast, and too simplistic solution; -@code{mail-extract-address-components}, which works nicely, but is -slower; and @code{std11-extract-address-components}, which works very -nicely, but is slower. The default function will return the wrong -answer in 5% of the cases. If this is unacceptable to you, use the -other function instead. - -@vindex gnus-summary-same-subject -@code{gnus-summary-same-subject} is a string indicating that the current -article has the same subject as the previous. This string will be used -with those specs that require it. The default is @code{""}. - - -@node Summary Buffer Lines -@subsection Summary Buffer Lines - -@vindex gnus-summary-line-format -You can change the format of the lines in the summary buffer by changing -the @code{gnus-summary-line-format} variable. It works along the same -lines as a normal @code{format} string, with some extensions -(@pxref{Formatting Variables}). - -The default string is @samp{%U%R%z%I%(%[%4L: %-20,20n%]%) %s\n}. - -The following format specification characters are understood: - -@table @samp -@item N -Article number. -@item S -Subject string. -@item s -Subject if the article is the root of the thread or the previous article -had a different subject, @code{gnus-summary-same-subject} otherwise. -(@code{gnus-summary-same-subject} defaults to @code{""}.) -@item F -Full @code{From} header. -@item n -The name (from the @code{From} header). -@item a -The name (from the @code{From} header). This differs from the @code{n} -spec in that it uses the function designated by the -@code{gnus-extract-address-components} variable, which is slower, but -may be more thorough. -@item A -The address (from the @code{From} header). This works the same way as -the @code{a} spec. -@item L -Number of lines in the article. -@item c -Number of characters in the article. -@item I -Indentation based on thread level (@pxref{Customizing Threading}). -@item T -Nothing if the article is a root and lots of spaces if it isn't (it -pushes everything after it off the screen). -@item [ -Opening bracket, which is normally @samp{[}, but can also be @samp{<} -for adopted articles (@pxref{Customizing Threading}). -@item ] -Closing bracket, which is normally @samp{]}, but can also be @samp{>} -for adopted articles. -@item > -One space for each thread level. -@item < -Twenty minus thread level spaces. -@item U -Unread. - -@item R -This misleadingly named specifier is the @dfn{secondary mark}. This -mark will say whether the article has been replied to, has been cached, -or has been saved. - -@item i -Score as a number (@pxref{Scoring}). -@item z -@vindex gnus-summary-zcore-fuzz -Zcore, @samp{+} if above the default level and @samp{-} if below the -default level. If the difference between -@code{gnus-summary-default-score} and the score is less than -@code{gnus-summary-zcore-fuzz}, this spec will not be used. -@item V -Total thread score. -@item x -@code{Xref}. -@item D -@code{Date}. -@item d -The @code{Date} in @code{DD-MMM} format. -@item o -The @code{Date} in @var{YYYYMMDD}@code{T}@var{HHMMSS} format. -@item M -@code{Message-ID}. -@item r -@code{References}. -@item t -Number of articles in the current sub-thread. Using this spec will slow -down summary buffer generation somewhat. -@item e -An @samp{=} (@code{gnus-not-empty-thread-mark}) will be displayed if the -article has any children. -@item P -The line number. -@item O -Download mark. -@item u -User defined specifier. The next character in the format string should -be a letter. Gnus will call the function -@code{gnus-user-format-function-}@samp{X}, where @samp{X} is the letter -following @samp{%u}. The function will be passed the current header as -argument. The function should return a string, which will be inserted -into the summary just like information from any other summary specifier. -@end table - -The @samp{%U} (status), @samp{%R} (replied) and @samp{%z} (zcore) specs -have to be handled with care. For reasons of efficiency, gnus will -compute what column these characters will end up in, and ``hard-code'' -that. This means that it is invalid to have these specs after a -variable-length spec. Well, you might not be arrested, but your summary -buffer will look strange, which is bad enough. - -The smart choice is to have these specs as far to the left as possible. -(Isn't that the case with everything, though? But I digress.) - -This restriction may disappear in later versions of gnus. - - -@node Summary Buffer Mode Line -@subsection Summary Buffer Mode Line - -@vindex gnus-summary-mode-line-format -You can also change the format of the summary mode bar (@pxref{Mode Line -Formatting}). Set @code{gnus-summary-mode-line-format} to whatever you -like. The default is @samp{Gnus: %%b [%A] %Z}. - -Here are the elements you can play with: - -@table @samp -@item G -Group name. -@item p -Unprefixed group name. -@item A -Current article number. -@item z -Current article score. -@item V -Gnus version. -@item U -Number of unread articles in this group. -@item e -Number of unread articles in this group that aren't displayed in the -summary buffer. -@item Z -A string with the number of unread and unselected articles represented -either as @samp{<%U(+%e) more>} if there are both unread and unselected -articles, and just as @samp{<%U more>} if there are just unread articles -and no unselected ones. -@item g -Shortish group name. For instance, @samp{rec.arts.anime} will be -shortened to @samp{r.a.anime}. -@item S -Subject of the current article. -@item u -User-defined spec (@pxref{User-Defined Specs}). -@item s -Name of the current score file (@pxref{Scoring}). -@item d -Number of dormant articles (@pxref{Unread Articles}). -@item t -Number of ticked articles (@pxref{Unread Articles}). -@item r -Number of articles that have been marked as read in this session. -@item E -Number of articles expunged by the score files. -@end table - - -@node Summary Highlighting -@subsection Summary Highlighting - -@table @code - -@item gnus-visual-mark-article-hook -@vindex gnus-visual-mark-article-hook -This hook is run after selecting an article. It is meant to be used for -highlighting the article in some way. It is not run if -@code{gnus-visual} is @code{nil}. - -@item gnus-summary-update-hook -@vindex gnus-summary-update-hook -This hook is called when a summary line is changed. It is not run if -@code{gnus-visual} is @code{nil}. - -@item gnus-summary-selected-face -@vindex gnus-summary-selected-face -This is the face (or @dfn{font} as some people call it) used to -highlight the current article in the summary buffer. - -@item gnus-summary-highlight -@vindex gnus-summary-highlight -Summary lines are highlighted according to this variable, which is a -list where the elements are of the format @var{(FORM . FACE)}. If you -would, for instance, like ticked articles to be italic and high-scored -articles to be bold, you could set this variable to something like -@lisp -(((eq mark gnus-ticked-mark) . italic) - ((> score default) . bold)) -@end lisp -As you may have guessed, if @var{FORM} returns a non-@code{nil} value, -@var{FACE} will be applied to the line. -@end table - - -@node Summary Maneuvering -@section Summary Maneuvering -@cindex summary movement - -All the straight movement commands understand the numeric prefix and -behave pretty much as you'd expect. - -None of these commands select articles. - -@table @kbd -@item G M-n -@itemx M-n -@kindex M-n (Summary) -@kindex G M-n (Summary) -@findex gnus-summary-next-unread-subject -Go to the next summary line of an unread article -(@code{gnus-summary-next-unread-subject}). - -@item G M-p -@itemx M-p -@kindex M-p (Summary) -@kindex G M-p (Summary) -@findex gnus-summary-prev-unread-subject -Go to the previous summary line of an unread article -(@code{gnus-summary-prev-unread-subject}). - -@item G j -@itemx j -@kindex j (Summary) -@kindex G j (Summary) -@findex gnus-summary-goto-article -Ask for an article number or @code{Message-ID}, and then go to that -article (@code{gnus-summary-goto-article}). - -@item G g -@kindex G g (Summary) -@findex gnus-summary-goto-subject -Ask for an article number and then go to the summary line of that article -without displaying the article (@code{gnus-summary-goto-subject}). -@end table - -If gnus asks you to press a key to confirm going to the next group, you -can use the @kbd{C-n} and @kbd{C-p} keys to move around the group -buffer, searching for the next group to read without actually returning -to the group buffer. - -Variables related to summary movement: - -@table @code - -@vindex gnus-auto-select-next -@item gnus-auto-select-next -If you issue one of the movement commands (like @kbd{n}) and there are -no more unread articles after the current one, gnus will offer to go to -the next group. If this variable is @code{t} and the next group is -empty, gnus will exit summary mode and return to the group buffer. If -this variable is neither @code{t} nor @code{nil}, gnus will select the -next group, no matter whether it has any unread articles or not. As a -special case, if this variable is @code{quietly}, gnus will select the -next group without asking for confirmation. If this variable is -@code{almost-quietly}, the same will happen only if you are located on -the last article in the group. Finally, if this variable is -@code{slightly-quietly}, the @kbd{Z n} command will go to the next group -without confirmation. Also @pxref{Group Levels}. - -@item gnus-auto-select-same -@vindex gnus-auto-select-same -If non-@code{nil}, all the movement commands will try to go to the next -article with the same subject as the current. (@dfn{Same} here might -mean @dfn{roughly equal}. See @code{gnus-summary-gather-subject-limit} -for details (@pxref{Customizing Threading}).) If there are no more -articles with the same subject, go to the first unread article. - -This variable is not particularly useful if you use a threaded display. - -@item gnus-summary-check-current -@vindex gnus-summary-check-current -If non-@code{nil}, all the ``unread'' movement commands will not proceed -to the next (or previous) article if the current article is unread. -Instead, they will choose the current article. - -@item gnus-auto-center-summary -@vindex gnus-auto-center-summary -If non-@code{nil}, gnus will keep the point in the summary buffer -centered at all times. This makes things quite tidy, but if you have a -slow network connection, or simply do not like this un-Emacsism, you can -set this variable to @code{nil} to get the normal Emacs scrolling -action. This will also inhibit horizontal re-centering of the summary -buffer, which might make it more inconvenient to read extremely long -threads. - -@end table - - -@node Choosing Articles -@section Choosing Articles -@cindex selecting articles - -@menu -* Choosing Commands:: Commands for choosing articles. -* Choosing Variables:: Variables that influence these commands. -@end menu - - -@node Choosing Commands -@subsection Choosing Commands - -None of the following movement commands understand the numeric prefix, -and they all select and display an article. - -@table @kbd -@item SPACE -@kindex SPACE (Summary) -@findex gnus-summary-next-page -Select the current article, or, if that one's read already, the next -unread article (@code{gnus-summary-next-page}). - -@item G n -@itemx n -@kindex n (Summary) -@kindex G n (Summary) -@findex gnus-summary-next-unread-article -@c @icon{gnus-summary-next-unread} -Go to next unread article (@code{gnus-summary-next-unread-article}). - -@item G p -@itemx p -@kindex p (Summary) -@findex gnus-summary-prev-unread-article -@c @icon{gnus-summary-prev-unread} -Go to previous unread article (@code{gnus-summary-prev-unread-article}). - -@item G N -@itemx N -@kindex N (Summary) -@kindex G N (Summary) -@findex gnus-summary-next-article -Go to the next article (@code{gnus-summary-next-article}). - -@item G P -@itemx P -@kindex P (Summary) -@kindex G P (Summary) -@findex gnus-summary-prev-article -Go to the previous article (@code{gnus-summary-prev-article}). - -@item G C-n -@kindex G C-n (Summary) -@findex gnus-summary-next-same-subject -Go to the next article with the same subject -(@code{gnus-summary-next-same-subject}). - -@item G C-p -@kindex G C-p (Summary) -@findex gnus-summary-prev-same-subject -Go to the previous article with the same subject -(@code{gnus-summary-prev-same-subject}). - -@item G f -@itemx . -@kindex G f (Summary) -@kindex . (Summary) -@findex gnus-summary-first-unread-article -Go to the first unread article -(@code{gnus-summary-first-unread-article}). - -@item G b -@itemx , -@kindex G b (Summary) -@kindex , (Summary) -@findex gnus-summary-best-unread-article -Go to the article with the highest score -(@code{gnus-summary-best-unread-article}). - -@item G l -@itemx l -@kindex l (Summary) -@kindex G l (Summary) -@findex gnus-summary-goto-last-article -Go to the previous article read (@code{gnus-summary-goto-last-article}). - -@item G o -@kindex G o (Summary) -@findex gnus-summary-pop-article -@cindex history -@cindex article history -Pop an article off the summary history and go to this article -(@code{gnus-summary-pop-article}). This command differs from the -command above in that you can pop as many previous articles off the -history as you like, while @kbd{l} toggles the two last read articles. -For a somewhat related issue (if you use these commands a lot), -@pxref{Article Backlog}. -@end table - - -@node Choosing Variables -@subsection Choosing Variables - -Some variables relevant for moving and selecting articles: - -@table @code -@item gnus-auto-extend-newsgroup -@vindex gnus-auto-extend-newsgroup -All the movement commands will try to go to the previous (or next) -article, even if that article isn't displayed in the Summary buffer if -this variable is non-@code{nil}. Gnus will then fetch the article from -the server and display it in the article buffer. - -@item gnus-select-article-hook -@vindex gnus-select-article-hook -This hook is called whenever an article is selected. By default it -exposes any threads hidden under the selected article. - -@item gnus-mark-article-hook -@vindex gnus-mark-article-hook -@findex gnus-summary-mark-unread-as-read -@findex gnus-summary-mark-read-and-unread-as-read -@findex gnus-unread-mark -This hook is called whenever an article is selected. It is intended to -be used for marking articles as read. The default value is -@code{gnus-summary-mark-read-and-unread-as-read}, and will change the -mark of almost any article you read to @code{gnus-unread-mark}. The -only articles not affected by this function are ticked, dormant, and -expirable articles. If you'd instead like to just have unread articles -marked as read, you can use @code{gnus-summary-mark-unread-as-read} -instead. It will leave marks like @code{gnus-low-score-mark}, -@code{gnus-del-mark} (and so on) alone. - -@end table - - -@node Paging the Article -@section Scrolling the Article -@cindex article scrolling - -@table @kbd - -@item SPACE -@kindex SPACE (Summary) -@findex gnus-summary-next-page -Pressing @kbd{SPACE} will scroll the current article forward one page, -or, if you have come to the end of the current article, will choose the -next article (@code{gnus-summary-next-page}). - -@item DEL -@kindex DEL (Summary) -@findex gnus-summary-prev-page -Scroll the current article back one page (@code{gnus-summary-prev-page}). - -@item RET -@kindex RET (Summary) -@findex gnus-summary-scroll-up -Scroll the current article one line forward -(@code{gnus-summary-scroll-up}). - -@item M-RET -@kindex M-RET (Summary) -@findex gnus-summary-scroll-down -Scroll the current article one line backward -(@code{gnus-summary-scroll-down}). - -@item A g -@itemx g -@kindex A g (Summary) -@kindex g (Summary) -@findex gnus-summary-show-article -(Re)fetch the current article (@code{gnus-summary-show-article}). If -given a prefix, fetch the current article, but don't run any of the -article treatment functions. This will give you a ``raw'' article, just -the way it came from the server. - -@item A < -@itemx < -@kindex < (Summary) -@kindex A < (Summary) -@findex gnus-summary-beginning-of-article -Scroll to the beginning of the article -(@code{gnus-summary-beginning-of-article}). - -@item A > -@itemx > -@kindex > (Summary) -@kindex A > (Summary) -@findex gnus-summary-end-of-article -Scroll to the end of the article (@code{gnus-summary-end-of-article}). - -@item A s -@itemx s -@kindex A s (Summary) -@kindex s (Summary) -@findex gnus-summary-isearch-article -Perform an isearch in the article buffer -(@code{gnus-summary-isearch-article}). - -@item h -@kindex h (Summary) -@findex gnus-summary-select-article-buffer -Select the article buffer (@code{gnus-summary-select-article-buffer}). - -@end table - - -@node Reply Followup and Post -@section Reply, Followup and Post - -@menu -* Summary Mail Commands:: Sending mail. -* Summary Post Commands:: Sending news. -@end menu - - -@node Summary Mail Commands -@subsection Summary Mail Commands -@cindex mail -@cindex composing mail - -Commands for composing a mail message: - -@table @kbd - -@item S r -@itemx r -@kindex S r (Summary) -@kindex r (Summary) -@findex gnus-summary-reply -@c @icon{gnus-summary-mail-reply} -@c @icon{gnus-summary-reply} -Mail a reply to the author of the current article -(@code{gnus-summary-reply}). - -@item S R -@itemx R -@kindex R (Summary) -@kindex S R (Summary) -@findex gnus-summary-reply-with-original -@c @icon{gnus-summary-reply-with-original} -Mail a reply to the author of the current article and include the -original message (@code{gnus-summary-reply-with-original}). This -command uses the process/prefix convention. - -@item S w -@kindex S w (Summary) -@findex gnus-summary-wide-reply -Mail a wide reply to the author of the current article -(@code{gnus-summary-wide-reply}). A @dfn{wide reply} is a reply that -goes out to all people listed in the @code{To}, @code{From} (or -@code{Reply-to}) and @code{Cc} headers. - -@item S W -@kindex S W (Summary) -@findex gnus-summary-wide-reply-with-original -Mail a wide reply to the current article and include the original -message (@code{gnus-summary-reply-with-original}). This command uses -the process/prefix convention. - -@item S o m -@kindex S o m (Summary) -@findex gnus-summary-mail-forward -@c @icon{gnus-summary-mail-forward} -Forward the current article to some other person -(@code{gnus-summary-mail-forward}). If given a prefix, include the full -headers of the forwarded article. - -@item S m -@itemx m -@kindex m (Summary) -@kindex S m (Summary) -@findex gnus-summary-mail-other-window -@c @icon{gnus-summary-mail-originate} -Send a mail to some other person -(@code{gnus-summary-mail-other-window}). - -@item S D b -@kindex S D b (Summary) -@findex gnus-summary-resend-bounced-mail -@cindex bouncing mail -If you have sent a mail, but the mail was bounced back to you for some -reason (wrong address, transient failure), you can use this command to -resend that bounced mail (@code{gnus-summary-resend-bounced-mail}). You -will be popped into a mail buffer where you can edit the headers before -sending the mail off again. If you give a prefix to this command, and -the bounced mail is a reply to some other mail, gnus will try to fetch -that mail and display it for easy perusal of its headers. This might -very well fail, though. - -@item S D r -@kindex S D r (Summary) -@findex gnus-summary-resend-message -Not to be confused with the previous command, -@code{gnus-summary-resend-message} will prompt you for an address to -send the current message off to, and then send it to that place. The -headers of the message won't be altered---but lots of headers that say -@code{Resent-To}, @code{Resent-From} and so on will be added. This -means that you actually send a mail to someone that has a @code{To} -header that (probably) points to yourself. This will confuse people. -So, natcherly you'll only do that if you're really eVIl. - -This command is mainly used if you have several accounts and want to -ship a mail to a different account of yours. (If you're both -@code{root} and @code{postmaster} and get a mail for @code{postmaster} -to the @code{root} account, you may want to resend it to -@code{postmaster}. Ordnung mu,A_(B sein! - -This command understands the process/prefix convention -(@pxref{Process/Prefix}). - -@item S O m -@kindex S O m (Summary) -@findex gnus-uu-digest-mail-forward -Digest the current series (@pxref{Decoding Articles}) and forward the -result using mail (@code{gnus-uu-digest-mail-forward}). This command -uses the process/prefix convention (@pxref{Process/Prefix}). - -@item S M-c -@kindex S M-c (Summary) -@findex gnus-summary-mail-crosspost-complaint -@cindex crossposting -@cindex excessive crossposting -Send a complaint about excessive crossposting to the author of the -current article (@code{gnus-summary-mail-crosspost-complaint}). - -@findex gnus-crosspost-complaint -This command is provided as a way to fight back against the current -crossposting pandemic that's sweeping Usenet. It will compose a reply -using the @code{gnus-crosspost-complaint} variable as a preamble. This -command understands the process/prefix convention -(@pxref{Process/Prefix}) and will prompt you before sending each mail. - -@end table - -Also @pxref{(message)Header Commands} for more information. - - -@node Summary Post Commands -@subsection Summary Post Commands -@cindex post -@cindex composing news - -Commands for posting a news article: - -@table @kbd -@item S p -@itemx a -@kindex a (Summary) -@kindex S p (Summary) -@findex gnus-summary-post-news -@c @icon{gnus-summary-post-news} -Post an article to the current group -(@code{gnus-summary-post-news}). - -@item S f -@itemx f -@kindex f (Summary) -@kindex S f (Summary) -@findex gnus-summary-followup -@c @icon{gnus-summary-followup} -Post a followup to the current article (@code{gnus-summary-followup}). - -@item S F -@itemx F -@kindex S F (Summary) -@kindex F (Summary) -@c @icon{gnus-summary-followup-with-original} -@findex gnus-summary-followup-with-original -Post a followup to the current article and include the original message -(@code{gnus-summary-followup-with-original}). This command uses the -process/prefix convention. - -@item S n -@kindex S n (Summary) -@findex gnus-summary-followup-to-mail -Post a followup to the current article via news, even if you got the -message through mail (@code{gnus-summary-followup-to-mail}). - -@item S N -@kindex S N (Summary) -@findex gnus-summary-followup-to-mail-with-original -Post a followup to the current article via news, even if you got the -message through mail and include the original message -(@code{gnus-summary-followup-to-mail-with-original}). This command uses -the process/prefix convention. - -@item S o p -@kindex S o p (Summary) -@findex gnus-summary-post-forward -Forward the current article to a newsgroup -(@code{gnus-summary-post-forward}). If given a prefix, include the full -headers of the forwarded article. - -@item S O p -@kindex S O p (Summary) -@findex gnus-uu-digest-post-forward -@cindex digests -@cindex making digests -Digest the current series and forward the result to a newsgroup -(@code{gnus-uu-digest-mail-forward}). This command uses the -process/prefix convention. - -@item S u -@kindex S u (Summary) -@findex gnus-uu-post-news -@c @icon{gnus-uu-post-news} -Uuencode a file, split it into parts, and post it as a series -(@code{gnus-uu-post-news}). (@pxref{Uuencoding and Posting}). -@end table - -Also @pxref{(message)Header Commands} for more information. - - -@node Canceling and Superseding -@section Canceling Articles -@cindex canceling articles -@cindex superseding articles - -Have you ever written something, and then decided that you really, -really, really wish you hadn't posted that? - -Well, you can't cancel mail, but you can cancel posts. - -@findex gnus-summary-cancel-article -@kindex C (Summary) -@c @icon{gnus-summary-cancel-article} -Find the article you wish to cancel (you can only cancel your own -articles, so don't try any funny stuff). Then press @kbd{C} or @kbd{S -c} (@code{gnus-summary-cancel-article}). Your article will be -canceled---machines all over the world will be deleting your article. -This command uses the process/prefix convention (@pxref{Process/Prefix}). - -Be aware, however, that not all sites honor cancels, so your article may -live on here and there, while most sites will delete the article in -question. - -Gnus will use the ``current'' select method when canceling. If you -want to use the standard posting method, use the @samp{a} symbolic -prefix (@pxref{Symbolic Prefixes}). - -If you discover that you have made some mistakes and want to do some -corrections, you can post a @dfn{superseding} article that will replace -your original article. - -@findex gnus-summary-supersede-article -@kindex S (Summary) -Go to the original article and press @kbd{S s} -(@code{gnus-summary-supersede-article}). You will be put in a buffer -where you can edit the article all you want before sending it off the -usual way. - -The same goes for superseding as for canceling, only more so: Some -sites do not honor superseding. On those sites, it will appear that you -have posted almost the same article twice. - -If you have just posted the article, and change your mind right away, -there is a trick you can use to cancel/supersede the article without -waiting for the article to appear on your site first. You simply return -to the post buffer (which is called @code{*sent ...*}). There you will -find the article you just posted, with all the headers intact. Change -the @code{Message-ID} header to a @code{Cancel} or @code{Supersedes} -header by substituting one of those words for the word -@code{Message-ID}. Then just press @kbd{C-c C-c} to send the article as -you would do normally. The previous article will be -canceled/superseded. - -Just remember, kids: There is no `c' in `supersede'. - - -@node Marking Articles -@section Marking Articles -@cindex article marking -@cindex article ticking -@cindex marks - -There are several marks you can set on an article. - -You have marks that decide the @dfn{readedness} (whoo, neato-keano -neologism ohoy!) of the article. Alphabetic marks generally mean -@dfn{read}, while non-alphabetic characters generally mean @dfn{unread}. - -In addition, you also have marks that do not affect readedness. - -@menu -* Unread Articles:: Marks for unread articles. -* Read Articles:: Marks for read articles. -* Other Marks:: Marks that do not affect readedness. -@end menu - -@ifinfo -There's a plethora of commands for manipulating these marks: -@end ifinfo - -@menu -* Setting Marks:: How to set and remove marks. -* Setting Process Marks:: How to mark articles for later processing. -@end menu - - -@node Unread Articles -@subsection Unread Articles - -The following marks mark articles as (kinda) unread, in one form or -other. - -@table @samp -@item ! -@vindex gnus-ticked-mark -Marked as ticked (@code{gnus-ticked-mark}). - -@dfn{Ticked articles} are articles that will remain visible always. If -you see an article that you find interesting, or you want to put off -reading it, or replying to it, until sometime later, you'd typically -tick it. However, articles can be expired, so if you want to keep an -article forever, you'll have to make it persistent (@pxref{Persistent -Articles}). - -@item ? -@vindex gnus-dormant-mark -Marked as dormant (@code{gnus-dormant-mark}). - -@dfn{Dormant articles} will only appear in the summary buffer if there -are followups to it. If you want to see them even if they don't have -followups, you can use the @kbd{/ D} command (@pxref{Limiting}). - -@item SPACE -@vindex gnus-unread-mark -Marked as unread (@code{gnus-unread-mark}). - -@dfn{Unread articles} are articles that haven't been read at all yet. -@end table - - -@node Read Articles -@subsection Read Articles -@cindex expirable mark - -All the following marks mark articles as read. - -@table @samp - -@item r -@vindex gnus-del-mark -These are articles that the user has marked as read with the @kbd{d} -command manually, more or less (@code{gnus-del-mark}). - -@item R -@vindex gnus-read-mark -Articles that have actually been read (@code{gnus-read-mark}). - -@item O -@vindex gnus-ancient-mark -Articles that were marked as read in previous sessions and are now -@dfn{old} (@code{gnus-ancient-mark}). - -@item K -@vindex gnus-killed-mark -Marked as killed (@code{gnus-killed-mark}). - -@item X -@vindex gnus-kill-file-mark -Marked as killed by kill files (@code{gnus-kill-file-mark}). - -@item Y -@vindex gnus-low-score-mark -Marked as read by having too low a score (@code{gnus-low-score-mark}). - -@item C -@vindex gnus-catchup-mark -Marked as read by a catchup (@code{gnus-catchup-mark}). - -@item G -@vindex gnus-canceled-mark -Canceled article (@code{gnus-canceled-mark}) - -@item F -@vindex gnus-souped-mark -@sc{SOUP}ed article (@code{gnus-souped-mark}). @xref{SOUP}. - -@item Q -@vindex gnus-sparse-mark -Sparsely reffed article (@code{gnus-sparse-mark}). @xref{Customizing -Threading}. - -@item M -@vindex gnus-duplicate-mark -Article marked as read by duplicate suppression -(@code{gnus-duplicated-mark}). @xref{Duplicate Suppression}. - -@end table - -All these marks just mean that the article is marked as read, really. -They are interpreted differently when doing adaptive scoring, though. - -One more special mark, though: - -@table @samp -@item E -@vindex gnus-expirable-mark -Marked as expirable (@code{gnus-expirable-mark}). - -Marking articles as @dfn{expirable} (or have them marked as such -automatically) doesn't make much sense in normal groups---a user doesn't -control expiring of news articles, but in mail groups, for instance, -articles marked as @dfn{expirable} can be deleted by gnus at any time. -@end table - - -@node Other Marks -@subsection Other Marks -@cindex process mark -@cindex bookmarks - -There are some marks that have nothing to do with whether the article is -read or not. - -@itemize @bullet - -@item -You can set a bookmark in the current article. Say you are reading a -long thesis on cats' urinary tracts, and have to go home for dinner -before you've finished reading the thesis. You can then set a bookmark -in the article, and gnus will jump to this bookmark the next time it -encounters the article. @xref{Setting Marks} - -@item -@vindex gnus-replied-mark -All articles that you have replied to or made a followup to (i.e., have -answered) will be marked with an @samp{A} in the second column -(@code{gnus-replied-mark}). - -@item -@vindex gnus-cached-mark -Articles stored in the article cache will be marked with an @samp{*} in -the second column (@code{gnus-cached-mark}). @xref{Article Caching} - -@item -@vindex gnus-saved-mark -Articles ``saved'' (in some manner or other; not necessarily -religiously) are marked with an @samp{S} in the second column -(@code{gnus-saved-mark}). - -@item -@vindex gnus-not-empty-thread-mark -@vindex gnus-empty-thread-mark -If the @samp{%e} spec is used, the presence of threads or not will be -marked with @code{gnus-not-empty-thread-mark} and -@code{gnus-empty-thread-mark} in the third column, respectively. - -@item -@vindex gnus-process-mark -Finally we have the @dfn{process mark} (@code{gnus-process-mark}). A -variety of commands react to the presence of the process mark. For -instance, @kbd{X u} (@code{gnus-uu-decode-uu}) will uudecode and view -all articles that have been marked with the process mark. Articles -marked with the process mark have a @samp{#} in the second column. - -@end itemize - -You might have noticed that most of these ``non-readedness'' marks -appear in the second column by default. So if you have a cached, saved, -replied article that you have process-marked, what will that look like? - -Nothing much. The precedence rules go as follows: process -> cache -> -replied -> saved. So if the article is in the cache and is replied, -you'll only see the cache mark and not the replied mark. - - -@node Setting Marks -@subsection Setting Marks -@cindex setting marks - -All the marking commands understand the numeric prefix. - -@table @kbd -@item M c -@itemx M-u -@kindex M c (Summary) -@kindex M-u (Summary) -@findex gnus-summary-clear-mark-forward -@cindex mark as unread -Clear all readedness-marks from the current article -(@code{gnus-summary-clear-mark-forward}). In other words, mark the -article as unread. - -@item M t -@itemx ! -@kindex ! (Summary) -@kindex M t (Summary) -@findex gnus-summary-tick-article-forward -Tick the current article (@code{gnus-summary-tick-article-forward}). -@xref{Article Caching} - -@item M ? -@itemx ? -@kindex ? (Summary) -@kindex M ? (Summary) -@findex gnus-summary-mark-as-dormant -Mark the current article as dormant -(@code{gnus-summary-mark-as-dormant}). @xref{Article Caching} - -@item M d -@itemx d -@kindex M d (Summary) -@kindex d (Summary) -@findex gnus-summary-mark-as-read-forward -Mark the current article as read -(@code{gnus-summary-mark-as-read-forward}). - -@item D -@kindex D (Summary) -@findex gnus-summary-mark-as-read-backward -Mark the current article as read and move point to the previous line -(@code{gnus-summary-mark-as-read-backward}). - -@item M k -@itemx k -@kindex k (Summary) -@kindex M k (Summary) -@findex gnus-summary-kill-same-subject-and-select -Mark all articles that have the same subject as the current one as read, -and then select the next unread article -(@code{gnus-summary-kill-same-subject-and-select}). - -@item M K -@itemx C-k -@kindex M K (Summary) -@kindex C-k (Summary) -@findex gnus-summary-kill-same-subject -Mark all articles that have the same subject as the current one as read -(@code{gnus-summary-kill-same-subject}). - -@item M C -@kindex M C (Summary) -@findex gnus-summary-catchup -@c @icon{gnus-summary-catchup} -Mark all unread articles as read (@code{gnus-summary-catchup}). - -@item M C-c -@kindex M C-c (Summary) -@findex gnus-summary-catchup-all -Mark all articles in the group as read---even the ticked and dormant -articles (@code{gnus-summary-catchup-all}). - -@item M H -@kindex M H (Summary) -@findex gnus-summary-catchup-to-here -Catchup the current group to point -(@code{gnus-summary-catchup-to-here}). - -@item C-w -@kindex C-w (Summary) -@findex gnus-summary-mark-region-as-read -Mark all articles between point and mark as read -(@code{gnus-summary-mark-region-as-read}). - -@item M V k -@kindex M V k (Summary) -@findex gnus-summary-kill-below -Kill all articles with scores below the default score (or below the -numeric prefix) (@code{gnus-summary-kill-below}). - -@item M e -@itemx E -@kindex M e (Summary) -@kindex E (Summary) -@findex gnus-summary-mark-as-expirable -Mark the current article as expirable -(@code{gnus-summary-mark-as-expirable}). - -@item M b -@kindex M b (Summary) -@findex gnus-summary-set-bookmark -Set a bookmark in the current article -(@code{gnus-summary-set-bookmark}). - -@item M B -@kindex M B (Summary) -@findex gnus-summary-remove-bookmark -Remove the bookmark from the current article -(@code{gnus-summary-remove-bookmark}). - -@item M V c -@kindex M V c (Summary) -@findex gnus-summary-clear-above -Clear all marks from articles with scores over the default score (or -over the numeric prefix) (@code{gnus-summary-clear-above}). - -@item M V u -@kindex M V u (Summary) -@findex gnus-summary-tick-above -Tick all articles with scores over the default score (or over the -numeric prefix) (@code{gnus-summary-tick-above}). - -@item M V m -@kindex M V m (Summary) -@findex gnus-summary-mark-above -Prompt for a mark, and mark all articles with scores over the default -score (or over the numeric prefix) with this mark -(@code{gnus-summary-clear-above}). -@end table - -@vindex gnus-summary-goto-unread -The @code{gnus-summary-goto-unread} variable controls what action should -be taken after setting a mark. If non-@code{nil}, point will move to -the next/previous unread article. If @code{nil}, point will just move -one line up or down. As a special case, if this variable is -@code{never}, all the marking commands as well as other commands (like -@kbd{SPACE}) will move to the next article, whether it is unread or not. -The default is @code{t}. - - -@node Setting Process Marks -@subsection Setting Process Marks -@cindex setting process marks - -@table @kbd - -@item M P p -@itemx # -@kindex # (Summary) -@kindex M P p (Summary) -@findex gnus-summary-mark-as-processable -Mark the current article with the process mark -(@code{gnus-summary-mark-as-processable}). -@findex gnus-summary-unmark-as-processable - -@item M P u -@itemx M-# -@kindex M P u (Summary) -@kindex M-# (Summary) -Remove the process mark, if any, from the current article -(@code{gnus-summary-unmark-as-processable}). - -@item M P U -@kindex M P U (Summary) -@findex gnus-summary-unmark-all-processable -Remove the process mark from all articles -(@code{gnus-summary-unmark-all-processable}). - -@item M P i -@kindex M P i (Summary) -@findex gnus-uu-invert-processable -Invert the list of process marked articles -(@code{gnus-uu-invert-processable}). - -@item M P R -@kindex M P R (Summary) -@findex gnus-uu-mark-by-regexp -Mark articles that have a @code{Subject} header that matches a regular -expression (@code{gnus-uu-mark-by-regexp}). - -@item M P r -@kindex M P r (Summary) -@findex gnus-uu-mark-region -Mark articles in region (@code{gnus-uu-mark-region}). - -@item M P t -@kindex M P t (Summary) -@findex gnus-uu-mark-thread -Mark all articles in the current (sub)thread -(@code{gnus-uu-mark-thread}). - -@item M P T -@kindex M P T (Summary) -@findex gnus-uu-unmark-thread -Unmark all articles in the current (sub)thread -(@code{gnus-uu-unmark-thread}). - -@item M P v -@kindex M P v (Summary) -@findex gnus-uu-mark-over -Mark all articles that have a score above the prefix argument -(@code{gnus-uu-mark-over}). - -@item M P s -@kindex M P s (Summary) -@findex gnus-uu-mark-series -Mark all articles in the current series (@code{gnus-uu-mark-series}). - -@item M P S -@kindex M P S (Summary) -@findex gnus-uu-mark-sparse -Mark all series that have already had some articles marked -(@code{gnus-uu-mark-sparse}). - -@item M P a -@kindex M P a (Summary) -@findex gnus-uu-mark-all -Mark all articles in series order (@code{gnus-uu-mark-series}). - -@item M P b -@kindex M P b (Summary) -@findex gnus-uu-mark-buffer -Mark all articles in the buffer in the order they appear -(@code{gnus-uu-mark-buffer}). - -@item M P k -@kindex M P k (Summary) -@findex gnus-summary-kill-process-mark -Push the current process mark set onto the stack and unmark all articles -(@code{gnus-summary-kill-process-mark}). - -@item M P y -@kindex M P y (Summary) -@findex gnus-summary-yank-process-mark -Pop the previous process mark set from the stack and restore it -(@code{gnus-summary-yank-process-mark}). - -@item M P w -@kindex M P w (Summary) -@findex gnus-summary-save-process-mark -Push the current process mark set onto the stack -(@code{gnus-summary-save-process-mark}). - -@end table - - -@node Limiting -@section Limiting -@cindex limiting - -It can be convenient to limit the summary buffer to just show some -subset of the articles currently in the group. The effect most limit -commands have is to remove a few (or many) articles from the summary -buffer. - -All limiting commands work on subsets of the articles already fetched -from the servers. None of these commands query the server for -additional articles. - -@table @kbd - -@item / / -@itemx / s -@kindex / / (Summary) -@findex gnus-summary-limit-to-subject -Limit the summary buffer to articles that match some subject -(@code{gnus-summary-limit-to-subject}). - -@item / a -@kindex / a (Summary) -@findex gnus-summary-limit-to-author -Limit the summary buffer to articles that match some author -(@code{gnus-summary-limit-to-author}). - -@item / u -@itemx x -@kindex / u (Summary) -@kindex x (Summary) -@findex gnus-summary-limit-to-unread -Limit the summary buffer to articles not marked as read -(@code{gnus-summary-limit-to-unread}). If given a prefix, limit the -buffer to articles strictly unread. This means that ticked and -dormant articles will also be excluded. - -@item / m -@kindex / m (Summary) -@findex gnus-summary-limit-to-marks -Ask for a mark and then limit to all articles that have been marked -with that mark (@code{gnus-summary-limit-to-marks}). - -@item / t -@kindex / t (Summary) -@findex gnus-summary-limit-to-age -Ask for a number and then limit the summary buffer to articles older than (or equal to) that number of days -(@code{gnus-summary-limit-to-marks}). If given a prefix, limit to -articles younger than that number of days. - -@item / n -@kindex / n (Summary) -@findex gnus-summary-limit-to-articles -Limit the summary buffer to the current article -(@code{gnus-summary-limit-to-articles}). Uses the process/prefix -convention (@pxref{Process/Prefix}). - -@item / w -@kindex / w (Summary) -@findex gnus-summary-pop-limit -Pop the previous limit off the stack and restore it -(@code{gnus-summary-pop-limit}). If given a prefix, pop all limits off -the stack. - -@item / v -@kindex / v (Summary) -@findex gnus-summary-limit-to-score -Limit the summary buffer to articles that have a score at or above some -score (@code{gnus-summary-limit-to-score}). - -@item / E -@itemx M S -@kindex M S (Summary) -@kindex / E (Summary) -@findex gnus-summary-limit-include-expunged -Include all expunged articles in the limit -(@code{gnus-summary-limit-include-expunged}). - -@item / D -@kindex / D (Summary) -@findex gnus-summary-limit-include-dormant -Include all dormant articles in the limit -(@code{gnus-summary-limit-include-dormant}). - -@item / * -@kindex / * (Summary) -@findex gnus-summary-limit-include-cached -Include all cached articles in the limit -(@code{gnus-summary-limit-include-cached}). - -@item / d -@kindex / d (Summary) -@findex gnus-summary-limit-exclude-dormant -Exclude all dormant articles from the limit -(@code{gnus-summary-limit-exclude-dormant}). - -@item / T -@kindex / T (Summary) -@findex gnus-summary-limit-include-thread -Include all the articles in the current thread in the limit. - -@item / c -@kindex / c (Summary) -@findex gnus-summary-limit-exclude-childless-dormant -Exclude all dormant articles that have no children from the limit -(@code{gnus-summary-limit-exclude-childless-dormant}). - -@item / C -@kindex / C (Summary) -@findex gnus-summary-limit-mark-excluded-as-read -Mark all excluded unread articles as read -(@code{gnus-summary-limit-mark-excluded-as-read}). If given a prefix, -also mark excluded ticked and dormant articles as read. - -@end table - - -@node Threading -@section Threading -@cindex threading -@cindex article threading - -Gnus threads articles by default. @dfn{To thread} is to put responses -to articles directly after the articles they respond to---in a -hierarchical fashion. - -Threading is done by looking at the @code{References} headers of the -articles. In a perfect world, this would be enough to build pretty -trees, but unfortunately, the @code{References} header is often broken -or simply missing. Weird news propagation excarcerbates the problem, -so one has to employ other heuristics to get pleasing results. A -plethora of approaches exists, as detailed in horrible detail in -@pxref{Customizing Threading}. - -First, a quick overview of the concepts: - -@table @dfn -@item root -The top-most article in a thread; the first article in the thread. - -@item thread -A tree-like article structure. - -@item sub-thread -A small(er) section of this tree-like structure. - -@item loose threads -Threads often lose their roots due to article expiry, or due to the root -already having been read in a previous session, and not displayed in the -summary buffer. We then typically have many sub-threads that really -belong to one thread, but are without connecting roots. These are -called loose threads. - -@item thread gathering -An attempt to gather loose threads into bigger threads. - -@item sparse threads -A thread where the missing articles have been ``guessed'' at, and are -displayed as empty lines in the summary buffer. - -@end table - - -@menu -* Customizing Threading:: Variables you can change to affect the threading. -* Thread Commands:: Thread based commands in the summary buffer. -@end menu - - -@node Customizing Threading -@subsection Customizing Threading -@cindex customizing threading - -@menu -* Loose Threads:: How gnus gathers loose threads into bigger threads. -* Filling In Threads:: Making the threads displayed look fuller. -* More Threading:: Even more variables for fiddling with threads. -* Low-Level Threading:: You thought it was over... but you were wrong! -@end menu - - -@node Loose Threads -@subsubsection Loose Threads -@cindex < -@cindex > -@cindex loose threads - -@table @code -@item gnus-summary-make-false-root -@vindex gnus-summary-make-false-root -If non-@code{nil}, gnus will gather all loose subtrees into one big tree -and create a dummy root at the top. (Wait a minute. Root at the top? -Yup.) Loose subtrees occur when the real root has expired, or you've -read or killed the root in a previous session. - -When there is no real root of a thread, gnus will have to fudge -something. This variable says what fudging method gnus should use. -There are four possible values: - -@iftex -@iflatex -\gnusfigure{The Summary Buffer}{390}{ -\put(0,0){\epsfig{figure=tmp/summary-adopt.ps,width=7.5cm}} -\put(445,0){\makebox(0,0)[br]{\epsfig{figure=tmp/summary-empty.ps,width=7.5cm}}} -\put(0,400){\makebox(0,0)[tl]{\epsfig{figure=tmp/summary-none.ps,width=7.5cm}}} -\put(445,400){\makebox(0,0)[tr]{\epsfig{figure=tmp/summary-dummy.ps,width=7.5cm}}} -} -@end iflatex -@end iftex - -@cindex adopting articles - -@table @code - -@item adopt -Gnus will make the first of the orphaned articles the parent. This -parent will adopt all the other articles. The adopted articles will be -marked as such by pointy brackets (@samp{<>}) instead of the standard -square brackets (@samp{[]}). This is the default method. - -@item dummy -@vindex gnus-summary-dummy-line-format -Gnus will create a dummy summary line that will pretend to be the -parent. This dummy line does not correspond to any real article, so -selecting it will just select the first real article after the dummy -article. @code{gnus-summary-dummy-line-format} is used to specify the -format of the dummy roots. It accepts only one format spec: @samp{S}, -which is the subject of the article. @xref{Formatting Variables}. - -@item empty -Gnus won't actually make any article the parent, but simply leave the -subject field of all orphans except the first empty. (Actually, it will -use @code{gnus-summary-same-subject} as the subject (@pxref{Summary -Buffer Format}).) - -@item none -Don't make any article parent at all. Just gather the threads and -display them after one another. - -@item nil -Don't gather loose threads. -@end table - -@item gnus-summary-gather-subject-limit -@vindex gnus-summary-gather-subject-limit -Loose threads are gathered by comparing subjects of articles. If this -variable is @code{nil}, gnus requires an exact match between the -subjects of the loose threads before gathering them into one big -super-thread. This might be too strict a requirement, what with the -presence of stupid newsreaders that chop off long subject lines. If -you think so, set this variable to, say, 20 to require that only the -first 20 characters of the subjects have to match. If you set this -variable to a really low number, you'll find that gnus will gather -everything in sight into one thread, which isn't very helpful. - -@cindex fuzzy article gathering -If you set this variable to the special value @code{fuzzy}, gnus will -use a fuzzy string comparison algorithm on the subjects (@pxref{Fuzzy -Matching}). - -@item gnus-simplify-subject-fuzzy-regexp -@vindex gnus-simplify-subject-fuzzy-regexp -This can either be a regular expression or list of regular expressions -that match strings that will be removed from subjects if fuzzy subject -simplification is used. - -@item gnus-simplify-ignored-prefixes -@vindex gnus-simplify-ignored-prefixes -If you set @code{gnus-summary-gather-subject-limit} to something as low -as 10, you might consider setting this variable to something sensible: - -@c Written by Michael Ernst -@lisp -(setq gnus-simplify-ignored-prefixes - (concat - "\\`\\[?\\(" - (mapconcat - 'identity - '("looking" - "wanted" "followup" "summary\\( of\\)?" - "help" "query" "problem" "question" - "answer" "reference" "announce" - "How can I" "How to" "Comparison of" - ;; ... - ) - "\\|") - "\\)\\s *\\(" - (mapconcat 'identity - '("for" "for reference" "with" "about") - "\\|") - "\\)?\\]?:?[ \t]*")) -@end lisp - -All words that match this regexp will be removed before comparing two -subjects. - -@item gnus-simplify-subject-functions -@vindex gnus-simplify-subject-functions -If non-@code{nil}, this variable overrides -@code{gnus-summary-gather-subject-limit}. This variable should be a -list of functions to apply to the @code{Subject} string iteratively to -arrive at the simplified version of the string. - -Useful functions to put in this list include: - -@table @code -@item gnus-simplify-subject-re -@findex gnus-simplify-subject-re -Strip the leading @samp{Re:}. - -@item gnus-simplify-subject-fuzzy -@findex gnus-simplify-subject-fuzzy -Simplify fuzzily. - -@item gnus-simplify-whitespace -@findex gnus-simplify-whitespace -Remove excessive whitespace. -@end table - -You may also write your own functions, of course. - - -@item gnus-summary-gather-exclude-subject -@vindex gnus-summary-gather-exclude-subject -Since loose thread gathering is done on subjects only, that might lead -to many false hits, especially with certain common subjects like -@samp{} and @samp{(none)}. To make the situation slightly better, -you can use the regexp @code{gnus-summary-gather-exclude-subject} to say -what subjects should be excluded from the gathering process.@* -The default is @samp{^ *$\\|^(none)$}. - -@item gnus-summary-thread-gathering-function -@vindex gnus-summary-thread-gathering-function -Gnus gathers threads by looking at @code{Subject} headers. This means -that totally unrelated articles may end up in the same ``thread'', which -is confusing. An alternate approach is to look at all the -@code{Message-ID}s in all the @code{References} headers to find matches. -This will ensure that no gathered threads ever include unrelated -articles, but it also means that people who have posted with broken -newsreaders won't be gathered properly. The choice is yours---plague or -cholera: - -@table @code -@item gnus-gather-threads-by-subject -@findex gnus-gather-threads-by-subject -This function is the default gathering function and looks at -@code{Subject}s exclusively. - -@item gnus-gather-threads-by-references -@findex gnus-gather-threads-by-references -This function looks at @code{References} headers exclusively. -@end table - -If you want to test gathering by @code{References}, you could say -something like: - -@lisp -(setq gnus-summary-thread-gathering-function - 'gnus-gather-threads-by-references) -@end lisp - -@end table - - -@node Filling In Threads -@subsubsection Filling In Threads - -@table @code -@item gnus-fetch-old-headers -@vindex gnus-fetch-old-headers -If non-@code{nil}, gnus will attempt to build old threads by fetching -more old headers---headers to articles marked as read. If you would -like to display as few summary lines as possible, but still connect as -many loose threads as possible, you should set this variable to -@code{some} or a number. If you set it to a number, no more than that -number of extra old headers will be fetched. In either case, fetching -old headers only works if the backend you are using carries overview -files---this would normally be @code{nntp}, @code{nnspool} and -@code{nnml}. Also remember that if the root of the thread has been -expired by the server, there's not much gnus can do about that. - -This variable can also be set to @code{invisible}. This won't have any -visible effects, but is useful if you use the @kbd{A T} command a lot -(@pxref{Finding the Parent}). - -@item gnus-build-sparse-threads -@vindex gnus-build-sparse-threads -Fetching old headers can be slow. A low-rent similar effect can be -gotten by setting this variable to @code{some}. Gnus will then look at -the complete @code{References} headers of all articles and try to string -together articles that belong in the same thread. This will leave -@dfn{gaps} in the threading display where gnus guesses that an article -is missing from the thread. (These gaps appear like normal summary -lines. If you select a gap, gnus will try to fetch the article in -question.) If this variable is @code{t}, gnus will display all these -``gaps'' without regard for whether they are useful for completing the -thread or not. Finally, if this variable is @code{more}, gnus won't cut -off sparse leaf nodes that don't lead anywhere. This variable is -@code{nil} by default. - -@end table - - -@node More Threading -@subsubsection More Threading - -@table @code -@item gnus-show-threads -@vindex gnus-show-threads -If this variable is @code{nil}, no threading will be done, and all of -the rest of the variables here will have no effect. Turning threading -off will speed group selection up a bit, but it is sure to make reading -slower and more awkward. - -@item gnus-thread-hide-subtree -@vindex gnus-thread-hide-subtree -If non-@code{nil}, all threads will be hidden when the summary buffer is -generated. - -@item gnus-thread-expunge-below -@vindex gnus-thread-expunge-below -All threads that have a total score (as defined by -@code{gnus-thread-score-function}) less than this number will be -expunged. This variable is @code{nil} by default, which means that no -threads are expunged. - -@item gnus-thread-hide-killed -@vindex gnus-thread-hide-killed -if you kill a thread and this variable is non-@code{nil}, the subtree -will be hidden. - -@item gnus-thread-ignore-subject -@vindex gnus-thread-ignore-subject -Sometimes somebody changes the subject in the middle of a thread. If -this variable is non-@code{nil}, the subject change is ignored. If it -is @code{nil}, which is the default, a change in the subject will result -in a new thread. - -@item gnus-thread-indent-level -@vindex gnus-thread-indent-level -This is a number that says how much each sub-thread should be indented. -The default is 4. - -@end table - - -@node Low-Level Threading -@subsubsection Low-Level Threading - -@table @code - -@item gnus-parse-headers-hook -@vindex gnus-parse-headers-hook -Hook run before parsing any headers. The default value is -@code{(gnus-set-summary-default-charset)}, which sets up local value of -@code{default-mime-charset} in summary buffer based on variable -@code{gnus-newsgroup-default-charset-alist}. - -@item gnus-alter-header-function -@vindex gnus-alter-header-function -If non-@code{nil}, this function will be called to allow alteration of -article header structures. The function is called with one parameter, -the article header vector, which it may alter in any way. For instance, -if you have a mail-to-news gateway which alters the @code{Message-ID}s -in systematic ways (by adding prefixes and such), you can use this -variable to un-scramble the @code{Message-ID}s so that they are more -meaningful. Here's one example: - -@lisp -(setq gnus-alter-header-function 'my-alter-message-id) - -(defun my-alter-message-id (header) - (let ((id (mail-header-id header))) - (when (string-match - "\\(<[^<>@@]*\\)\\.?cygnus\\..*@@\\([^<>@@]*>\\)" id) - (mail-header-set-id - (concat (match-string 1 id) "@@" (match-string 2 id)) - header)))) -@end lisp - -@end table - - -@node Thread Commands -@subsection Thread Commands -@cindex thread commands - -@table @kbd - -@item T k -@itemx M-C-k -@kindex T k (Summary) -@kindex M-C-k (Summary) -@findex gnus-summary-kill-thread -Mark all articles in the current (sub-)thread as read -(@code{gnus-summary-kill-thread}). If the prefix argument is positive, -remove all marks instead. If the prefix argument is negative, tick -articles instead. - -@item T l -@itemx M-C-l -@kindex T l (Summary) -@kindex M-C-l (Summary) -@findex gnus-summary-lower-thread -Lower the score of the current (sub-)thread -(@code{gnus-summary-lower-thread}). - -@item T i -@kindex T i (Summary) -@findex gnus-summary-raise-thread -Increase the score of the current (sub-)thread -(@code{gnus-summary-raise-thread}). - -@item T # -@kindex T # (Summary) -@findex gnus-uu-mark-thread -Set the process mark on the current (sub-)thread -(@code{gnus-uu-mark-thread}). - -@item T M-# -@kindex T M-# (Summary) -@findex gnus-uu-unmark-thread -Remove the process mark from the current (sub-)thread -(@code{gnus-uu-unmark-thread}). - -@item T T -@kindex T T (Summary) -@findex gnus-summary-toggle-threads -Toggle threading (@code{gnus-summary-toggle-threads}). - -@item T s -@kindex T s (Summary) -@findex gnus-summary-show-thread -Expose the (sub-)thread hidden under the current article, if any -(@code{gnus-summary-show-thread}). - -@item T h -@kindex T h (Summary) -@findex gnus-summary-hide-thread -Hide the current (sub-)thread (@code{gnus-summary-hide-thread}). - -@item T S -@kindex T S (Summary) -@findex gnus-summary-show-all-threads -Expose all hidden threads (@code{gnus-summary-show-all-threads}). - -@item T H -@kindex T H (Summary) -@findex gnus-summary-hide-all-threads -Hide all threads (@code{gnus-summary-hide-all-threads}). - -@item T t -@kindex T t (Summary) -@findex gnus-summary-rethread-current -Re-thread the current article's thread -(@code{gnus-summary-rethread-current}). This works even when the -summary buffer is otherwise unthreaded. - -@item T ^ -@kindex T ^ (Summary) -@findex gnus-summary-reparent-thread -Make the current article the child of the marked (or previous) article -(@code{gnus-summary-reparent-thread}). - -@end table - -The following commands are thread movement commands. They all -understand the numeric prefix. - -@table @kbd - -@item T n -@kindex T n (Summary) -@findex gnus-summary-next-thread -Go to the next thread (@code{gnus-summary-next-thread}). - -@item T p -@kindex T p (Summary) -@findex gnus-summary-prev-thread -Go to the previous thread (@code{gnus-summary-prev-thread}). - -@item T d -@kindex T d (Summary) -@findex gnus-summary-down-thread -Descend the thread (@code{gnus-summary-down-thread}). - -@item T u -@kindex T u (Summary) -@findex gnus-summary-up-thread -Ascend the thread (@code{gnus-summary-up-thread}). - -@item T o -@kindex T o (Summary) -@findex gnus-summary-top-thread -Go to the top of the thread (@code{gnus-summary-top-thread}). -@end table - -@vindex gnus-thread-operation-ignore-subject -If you ignore subject while threading, you'll naturally end up with -threads that have several different subjects in them. If you then issue -a command like `T k' (@code{gnus-summary-kill-thread}) you might not -wish to kill the entire thread, but just those parts of the thread that -have the same subject as the current article. If you like this idea, -you can fiddle with @code{gnus-thread-operation-ignore-subject}. If it -is non-@code{nil} (which it is by default), subjects will be ignored -when doing thread commands. If this variable is @code{nil}, articles in -the same thread with different subjects will not be included in the -operation in question. If this variable is @code{fuzzy}, only articles -that have subjects fuzzily equal will be included (@pxref{Fuzzy -Matching}). - - -@node Sorting -@section Sorting - -@findex gnus-thread-sort-by-total-score -@findex gnus-thread-sort-by-date -@findex gnus-thread-sort-by-score -@findex gnus-thread-sort-by-subject -@findex gnus-thread-sort-by-author -@findex gnus-thread-sort-by-number -@vindex gnus-thread-sort-functions -If you are using a threaded summary display, you can sort the threads by -setting @code{gnus-thread-sort-functions}, which is a list of functions. -By default, sorting is done on article numbers. Ready-made sorting -predicate functions include @code{gnus-thread-sort-by-number}, -@code{gnus-thread-sort-by-author}, @code{gnus-thread-sort-by-subject}, -@code{gnus-thread-sort-by-date}, @code{gnus-thread-sort-by-score}, and -@code{gnus-thread-sort-by-total-score}. - -Each function takes two threads and returns non-@code{nil} if the first -thread should be sorted before the other. Note that sorting really is -normally done by looking only at the roots of each thread. If you use -more than one function, the primary sort key should be the last function -in the list. You should probably always include -@code{gnus-thread-sort-by-number} in the list of sorting -functions---preferably first. This will ensure that threads that are -equal with respect to the other sort criteria will be displayed in -ascending article order. - -If you would like to sort by score, then by subject, and finally by -number, you could do something like: - -@lisp -(setq gnus-thread-sort-functions - '(gnus-thread-sort-by-number - gnus-thread-sort-by-subject - gnus-thread-sort-by-total-score)) -@end lisp - -The threads that have highest score will be displayed first in the -summary buffer. When threads have the same score, they will be sorted -alphabetically. The threads that have the same score and the same -subject will be sorted by number, which is (normally) the sequence in -which the articles arrived. - -If you want to sort by score and then reverse arrival order, you could -say something like: - -@lisp -(setq gnus-thread-sort-functions - '((lambda (t1 t2) - (not (gnus-thread-sort-by-number t1 t2))) - gnus-thread-sort-by-score)) -@end lisp - -@vindex gnus-thread-score-function -The function in the @code{gnus-thread-score-function} variable (default -@code{+}) is used for calculating the total score of a thread. Useful -functions might be @code{max}, @code{min}, or squared means, or whatever -tickles your fancy. - -@findex gnus-article-sort-functions -@findex gnus-article-sort-by-date -@findex gnus-article-sort-by-score -@findex gnus-article-sort-by-subject -@findex gnus-article-sort-by-author -@findex gnus-article-sort-by-number -If you are using an unthreaded display for some strange reason or other, -you have to fiddle with the @code{gnus-article-sort-functions} variable. -It is very similar to the @code{gnus-thread-sort-functions}, except that -it uses slightly different functions for article comparison. Available -sorting predicate functions are @code{gnus-article-sort-by-number}, -@code{gnus-article-sort-by-author}, @code{gnus-article-sort-by-subject}, -@code{gnus-article-sort-by-date}, and @code{gnus-article-sort-by-score}. - -If you want to sort an unthreaded summary display by subject, you could -say something like: - -@lisp -(setq gnus-article-sort-functions - '(gnus-article-sort-by-number - gnus-article-sort-by-subject)) -@end lisp - - - -@node Asynchronous Fetching -@section Asynchronous Article Fetching -@cindex asynchronous article fetching -@cindex article pre-fetch -@cindex pre-fetch - -If you read your news from an @sc{nntp} server that's far away, the -network latencies may make reading articles a chore. You have to wait -for a while after pressing @kbd{n} to go to the next article before the -article appears. Why can't gnus just go ahead and fetch the article -while you are reading the previous one? Why not, indeed. - -First, some caveats. There are some pitfalls to using asynchronous -article fetching, especially the way gnus does it. - -Let's say you are reading article 1, which is short, and article 2 is -quite long, and you are not interested in reading that. Gnus does not -know this, so it goes ahead and fetches article 2. You decide to read -article 3, but since gnus is in the process of fetching article 2, the -connection is blocked. - -To avoid these situations, gnus will open two (count 'em two) -connections to the server. Some people may think this isn't a very nice -thing to do, but I don't see any real alternatives. Setting up that -extra connection takes some time, so gnus startup will be slower. - -Gnus will fetch more articles than you will read. This will mean that -the link between your machine and the @sc{nntp} server will become more -loaded than if you didn't use article pre-fetch. The server itself will -also become more loaded---both with the extra article requests, and the -extra connection. - -Ok, so now you know that you shouldn't really use this thing... unless -you really want to. - -@vindex gnus-asynchronous -Here's how: Set @code{gnus-asynchronous} to @code{t}. The rest should -happen automatically. - -@vindex gnus-use-article-prefetch -You can control how many articles are to be pre-fetched by setting -@code{gnus-use-article-prefetch}. This is 30 by default, which means -that when you read an article in the group, the backend will pre-fetch -the next 30 articles. If this variable is @code{t}, the backend will -pre-fetch all the articles it can without bound. If it is -@code{nil}, no pre-fetching will be done. - -@vindex gnus-async-prefetch-article-p -@findex gnus-async-read-p -There are probably some articles that you don't want to pre-fetch---read -articles, for instance. The @code{gnus-async-prefetch-article-p} variable controls whether an article is to be pre-fetched. This function should -return non-@code{nil} when the article in question is to be -pre-fetched. The default is @code{gnus-async-read-p}, which returns -@code{nil} on read articles. The function is called with an article -data structure as the only parameter. - -If, for instance, you wish to pre-fetch only unread articles shorter -than 100 lines, you could say something like: - -@lisp -(defun my-async-short-unread-p (data) - "Return non-nil for short, unread articles." - (and (gnus-data-unread-p data) - (< (mail-header-lines (gnus-data-header data)) - 100))) - -(setq gnus-async-prefetch-article-p 'my-async-short-unread-p) -@end lisp - -These functions will be called many, many times, so they should -preferably be short and sweet to avoid slowing down gnus too much. It's -probably a good idea to byte-compile things like this. - -@vindex gnus-prefetched-article-deletion-strategy -Articles have to be removed from the asynch buffer sooner or later. The -@code{gnus-prefetched-article-deletion-strategy} says when to remove -articles. This is a list that may contain the following elements: - -@table @code -@item read -Remove articles when they are read. - -@item exit -Remove articles when exiting the group. -@end table - -The default value is @code{(read exit)}. - -@c @vindex gnus-use-header-prefetch -@c If @code{gnus-use-header-prefetch} is non-@code{nil}, prefetch articles -@c from the next group. - - -@node Article Caching -@section Article Caching -@cindex article caching -@cindex caching - -If you have an @emph{extremely} slow @sc{nntp} connection, you may -consider turning article caching on. Each article will then be stored -locally under your home directory. As you may surmise, this could -potentially use @emph{huge} amounts of disk space, as well as eat up all -your inodes so fast it will make your head swim. In vodka. - -Used carefully, though, it could be just an easier way to save articles. - -@vindex gnus-use-long-file-name -@vindex gnus-cache-directory -@vindex gnus-use-cache -To turn caching on, set @code{gnus-use-cache} to @code{t}. By default, -all articles ticked or marked as dormant will then be copied -over to your local cache (@code{gnus-cache-directory}). Whether this -cache is flat or hierarchal is controlled by the -@code{gnus-use-long-file-name} variable, as usual. - -When re-selecting a ticked or dormant article, it will be fetched from the -cache instead of from the server. As articles in your cache will never -expire, this might serve as a method of saving articles while still -keeping them where they belong. Just mark all articles you want to save -as dormant, and don't worry. - -When an article is marked as read, is it removed from the cache. - -@vindex gnus-cache-remove-articles -@vindex gnus-cache-enter-articles -The entering/removal of articles from the cache is controlled by the -@code{gnus-cache-enter-articles} and @code{gnus-cache-remove-articles} -variables. Both are lists of symbols. The first is @code{(ticked -dormant)} by default, meaning that ticked and dormant articles will be -put in the cache. The latter is @code{(read)} by default, meaning that -articles marked as read are removed from the cache. Possibly -symbols in these two lists are @code{ticked}, @code{dormant}, -@code{unread} and @code{read}. - -@findex gnus-jog-cache -So where does the massive article-fetching and storing come into the -picture? The @code{gnus-jog-cache} command will go through all -subscribed newsgroups, request all unread articles, score them, and -store them in the cache. You should only ever, ever ever ever, use this -command if 1) your connection to the @sc{nntp} server is really, really, -really slow and 2) you have a really, really, really huge disk. -Seriously. One way to cut down on the number of articles downloaded is -to score unwanted articles down and have them marked as read. They will -not then be downloaded by this command. - -@vindex gnus-uncacheable-groups -@vindex gnus-cacheable-groups -It is likely that you do not want caching on all groups. For instance, -if your @code{nnml} mail is located under your home directory, it makes no -sense to cache it somewhere else under your home directory. Unless you -feel that it's neat to use twice as much space. - -To limit the caching, you could set @code{gnus-cacheable-groups} to a -regexp of groups to cache, @samp{^nntp} for instance, or set the -@code{gnus-uncacheable-groups} regexp to @samp{^nnml}, for instance. -Both variables are @code{nil} by default. If a group matches both -variables, the group is not cached. - -@findex gnus-cache-generate-nov-databases -@findex gnus-cache-generate-active -@vindex gnus-cache-active-file -The cache stores information on what articles it contains in its active -file (@code{gnus-cache-active-file}). If this file (or any other parts -of the cache) becomes all messed up for some reason or other, gnus -offers two functions that will try to set things right. @kbd{M-x -gnus-cache-generate-nov-databases} will (re)build all the @sc{nov} -files, and @kbd{gnus-cache-generate-active} will (re)generate the active -file. - - -@node Persistent Articles -@section Persistent Articles -@cindex persistent articles - -Closely related to article caching, we have @dfn{persistent articles}. -In fact, it's just a different way of looking at caching, and much more -useful in my opinion. - -Say you're reading a newsgroup, and you happen on to some valuable gem -that you want to keep and treasure forever. You'd normally just save it -(using one of the many saving commands) in some file. The problem with -that is that it's just, well, yucky. Ideally you'd prefer just having -the article remain in the group where you found it forever; untouched by -the expiry going on at the news server. - -This is what a @dfn{persistent article} is---an article that just won't -be deleted. It's implemented using the normal cache functions, but -you use two explicit commands for managing persistent articles: - -@table @kbd - -@item * -@kindex * (Summary) -@findex gnus-cache-enter-article -Make the current article persistent (@code{gnus-cache-enter-article}). - -@item M-* -@kindex M-* (Summary) -@findex gnus-cache-remove-article -Remove the current article from the persistent articles -(@code{gnus-cache-remove-article}). This will normally delete the -article. -@end table - -Both these commands understand the process/prefix convention. - -To avoid having all ticked articles (and stuff) entered into the cache, -you should set @code{gnus-use-cache} to @code{passive} if you're just -interested in persistent articles: - -@lisp -(setq gnus-use-cache 'passive) -@end lisp - - -@node Article Backlog -@section Article Backlog -@cindex backlog -@cindex article backlog - -If you have a slow connection, but the idea of using caching seems -unappealing to you (and it is, really), you can help the situation some -by switching on the @dfn{backlog}. This is where gnus will buffer -already read articles so that it doesn't have to re-fetch articles -you've already read. This only helps if you are in the habit of -re-selecting articles you've recently read, of course. If you never do -that, turning the backlog on will slow gnus down a little bit, and -increase memory usage some. - -@vindex gnus-keep-backlog -If you set @code{gnus-keep-backlog} to a number @var{n}, gnus will store -at most @var{n} old articles in a buffer for later re-fetching. If this -variable is non-@code{nil} and is not a number, gnus will store -@emph{all} read articles, which means that your Emacs will grow without -bound before exploding and taking your machine down with you. I put -that in there just to keep y'all on your toes. - -This variable is @code{nil} by default. - - -@node Saving Articles -@section Saving Articles -@cindex saving articles - -Gnus can save articles in a number of ways. Below is the documentation -for saving articles in a fairly straight-forward fashion (i.e., little -processing of the article is done before it is saved). For a different -approach (uudecoding, unsharing) you should use @code{gnus-uu} -(@pxref{Decoding Articles}). - -@vindex gnus-save-all-headers -If @code{gnus-save-all-headers} is non-@code{nil}, gnus will not delete -unwanted headers before saving the article. - -@vindex gnus-saved-headers -If the preceding variable is @code{nil}, all headers that match the -@code{gnus-saved-headers} regexp will be kept, while the rest will be -deleted before saving. - -@table @kbd - -@item O o -@itemx o -@kindex O o (Summary) -@kindex o (Summary) -@findex gnus-summary-save-article -@c @icon{gnus-summary-save-article} -Save the current article using the default article saver -(@code{gnus-summary-save-article}). - -@item O m -@kindex O m (Summary) -@findex gnus-summary-save-article-mail -Save the current article in mail format -(@code{gnus-summary-save-article-mail}). - -@item O r -@kindex O r (Summary) -@findex gnus-summary-save-article-rmail -Save the current article in rmail format -(@code{gnus-summary-save-article-rmail}). - -@item O f -@kindex O f (Summary) -@findex gnus-summary-save-article-file -@c @icon{gnus-summary-save-article-file} -Save the current article in plain file format -(@code{gnus-summary-save-article-file}). - -@item O F -@kindex O F (Summary) -@findex gnus-summary-write-article-file -Write the current article in plain file format, overwriting any previous -file contents (@code{gnus-summary-write-article-file}). - -@item O b -@kindex O b (Summary) -@findex gnus-summary-save-article-body-file -Save the current article body in plain file format -(@code{gnus-summary-save-article-body-file}). - -@item O h -@kindex O h (Summary) -@findex gnus-summary-save-article-folder -Save the current article in mh folder format -(@code{gnus-summary-save-article-folder}). - -@item O v -@kindex O v (Summary) -@findex gnus-summary-save-article-vm -Save the current article in a VM folder -(@code{gnus-summary-save-article-vm}). - -@item O p -@kindex O p (Summary) -@findex gnus-summary-pipe-output -Save the current article in a pipe. Uhm, like, what I mean is---Pipe -the current article to a process (@code{gnus-summary-pipe-output}). -@end table - -@vindex gnus-prompt-before-saving -All these commands use the process/prefix convention -(@pxref{Process/Prefix}). If you save bunches of articles using these -functions, you might get tired of being prompted for files to save each -and every article in. The prompting action is controlled by -the @code{gnus-prompt-before-saving} variable, which is @code{always} by -default, giving you that excessive prompting action you know and -loathe. If you set this variable to @code{t} instead, you'll be prompted -just once for each series of articles you save. If you like to really -have Gnus do all your thinking for you, you can even set this variable -to @code{nil}, which means that you will never be prompted for files to -save articles in. Gnus will simply save all the articles in the default -files. - - -@vindex gnus-default-article-saver -You can customize the @code{gnus-default-article-saver} variable to make -gnus do what you want it to. You can use any of the four ready-made -functions below, or you can create your own. - -@table @code - -@item gnus-summary-save-in-rmail -@findex gnus-summary-save-in-rmail -@vindex gnus-rmail-save-name -@findex gnus-plain-save-name -This is the default format, @dfn{babyl}. Uses the function in the -@code{gnus-rmail-save-name} variable to get a file name to save the -article in. The default is @code{gnus-plain-save-name}. - -@item gnus-summary-save-in-mail -@findex gnus-summary-save-in-mail -@vindex gnus-mail-save-name -Save in a Unix mail (mbox) file. Uses the function in the -@code{gnus-mail-save-name} variable to get a file name to save the -article in. The default is @code{gnus-plain-save-name}. - -@item gnus-summary-save-in-file -@findex gnus-summary-save-in-file -@vindex gnus-file-save-name -@findex gnus-numeric-save-name -Append the article straight to an ordinary file. Uses the function in -the @code{gnus-file-save-name} variable to get a file name to save the -article in. The default is @code{gnus-numeric-save-name}. - -@item gnus-summary-save-body-in-file -@findex gnus-summary-save-body-in-file -Append the article body to an ordinary file. Uses the function in the -@code{gnus-file-save-name} variable to get a file name to save the -article in. The default is @code{gnus-numeric-save-name}. - -@item gnus-summary-save-in-folder -@findex gnus-summary-save-in-folder -@findex gnus-folder-save-name -@findex gnus-Folder-save-name -@vindex gnus-folder-save-name -@cindex rcvstore -@cindex MH folders -Save the article to an MH folder using @code{rcvstore} from the MH -library. Uses the function in the @code{gnus-folder-save-name} variable -to get a file name to save the article in. The default is -@code{gnus-folder-save-name}, but you can also use -@code{gnus-Folder-save-name}, which creates capitalized names. - -@item gnus-summary-save-in-vm -@findex gnus-summary-save-in-vm -Save the article in a VM folder. You have to have the VM mail -reader to use this setting. -@end table - -@vindex gnus-article-save-directory -All of these functions, except for the last one, will save the article -in the @code{gnus-article-save-directory}, which is initialized from the -@code{SAVEDIR} environment variable. This is @file{~/News/} by -default. - -As you can see above, the functions use different functions to find a -suitable name of a file to save the article in. Below is a list of -available functions that generate names: - -@table @code - -@item gnus-Numeric-save-name -@findex gnus-Numeric-save-name -File names like @file{~/News/Alt.andrea-dworkin/45}. - -@item gnus-numeric-save-name -@findex gnus-numeric-save-name -File names like @file{~/News/alt.andrea-dworkin/45}. - -@item gnus-Plain-save-name -@findex gnus-Plain-save-name -File names like @file{~/News/Alt.andrea-dworkin}. - -@item gnus-plain-save-name -@findex gnus-plain-save-name -File names like @file{~/News/alt.andrea-dworkin}. -@end table - -@vindex gnus-split-methods -You can have gnus suggest where to save articles by plonking a regexp -into the @code{gnus-split-methods} alist. For instance, if you would -like to save articles related to gnus in the file @file{gnus-stuff}, and -articles related to VM in @code{vm-stuff}, you could set this variable -to something like: - -@lisp -(("^Subject:.*gnus\\|^Newsgroups:.*gnus" "gnus-stuff") - ("^Subject:.*vm\\|^Xref:.*vm" "vm-stuff") - (my-choosing-function "../other-dir/my-stuff") - ((equal gnus-newsgroup-name "mail.misc") "mail-stuff")) -@end lisp - -We see that this is a list where each element is a list that has two -elements---the @dfn{match} and the @dfn{file}. The match can either be -a string (in which case it is used as a regexp to match on the article -head); it can be a symbol (which will be called as a function with the -group name as a parameter); or it can be a list (which will be -@code{eval}ed). If any of these actions have a non-@code{nil} result, -the @dfn{file} will be used as a default prompt. In addition, the -result of the operation itself will be used if the function or form -called returns a string or a list of strings. - -You basically end up with a list of file names that might be used when -saving the current article. (All ``matches'' will be used.) You will -then be prompted for what you really want to use as a name, with file -name completion over the results from applying this variable. - -This variable is @code{((gnus-article-archive-name))} by default, which -means that gnus will look at the articles it saves for an -@code{Archive-name} line and use that as a suggestion for the file name. - -Here's an example function to clean up file names somewhat. If you have -lots of mail groups called things like -@samp{nnml:mail.whatever}, you may want to chop off the beginning of -these group names before creating the file name to save to. The -following will do just that: - -@lisp -(defun my-save-name (group) - (when (string-match "^nnml:mail." group) - (substring group (match-end 0)))) - -(setq gnus-split-methods - '((gnus-article-archive-name) - (my-save-name))) -@end lisp - - -@vindex gnus-use-long-file-name -Finally, you have the @code{gnus-use-long-file-name} variable. If it is -@code{nil}, all the preceding functions will replace all periods -(@samp{.}) in the group names with slashes (@samp{/})---which means that -the functions will generate hierarchies of directories instead of having -all the files in the top level directory -(@file{~/News/alt/andrea-dworkin} instead of -@file{~/News/alt.andrea-dworkin}.) This variable is @code{t} by default -on most systems. However, for historical reasons, this is @code{nil} on -Xenix and usg-unix-v machines by default. - -This function also affects kill and score file names. If this variable -is a list, and the list contains the element @code{not-score}, long file -names will not be used for score files, if it contains the element -@code{not-save}, long file names will not be used for saving, and if it -contains the element @code{not-kill}, long file names will not be used -for kill files. - -If you'd like to save articles in a hierarchy that looks something like -a spool, you could - -@lisp -(setq gnus-use-long-file-name '(not-save)) ; to get a hierarchy -(setq gnus-default-article-saver 'gnus-summary-save-in-file) ; no encoding -@end lisp - -Then just save with @kbd{o}. You'd then read this hierarchy with -ephemeral @code{nneething} groups---@kbd{G D} in the group buffer, and -the top level directory as the argument (@file{~/News/}). Then just walk -around to the groups/directories with @code{nneething}. - - -@node Decoding Articles -@section Decoding Articles -@cindex decoding articles - -Sometime users post articles (or series of articles) that have been -encoded in some way or other. Gnus can decode them for you. - -@menu -* Uuencoded Articles:: Uudecode articles. -* Shell Archives:: Unshar articles. -* PostScript Files:: Split PostScript. -* Other Files:: Plain save and binhex. -* Decoding Variables:: Variables for a happy decoding. -* Viewing Files:: You want to look at the result of the decoding? -@end menu - -@cindex series -@cindex article series -All these functions use the process/prefix convention -(@pxref{Process/Prefix}) for finding out what articles to work on, with -the extension that a ``single article'' means ``a single series''. Gnus -can find out by itself what articles belong to a series, decode all the -articles and unpack/view/save the resulting file(s). - -Gnus guesses what articles are in the series according to the following -simplish rule: The subjects must be (nearly) identical, except for the -last two numbers of the line. (Spaces are largely ignored, however.) - -For example: If you choose a subject called @samp{cat.gif (2/3)}, gnus -will find all the articles that match the regexp @samp{^cat.gif -([0-9]+/[0-9]+).*$}. - -Subjects that are non-standard, like @samp{cat.gif (2/3) Part 6 of a -series}, will not be properly recognized by any of the automatic viewing -commands, and you have to mark the articles manually with @kbd{#}. - - -@node Uuencoded Articles -@subsection Uuencoded Articles -@cindex uudecode -@cindex uuencoded articles - -@table @kbd - -@item X u -@kindex X u (Summary) -@findex gnus-uu-decode-uu -@c @icon{gnus-uu-decode-uu} -Uudecodes the current series (@code{gnus-uu-decode-uu}). - -@item X U -@kindex X U (Summary) -@findex gnus-uu-decode-uu-and-save -Uudecodes and saves the current series -(@code{gnus-uu-decode-uu-and-save}). - -@item X v u -@kindex X v u (Summary) -@findex gnus-uu-decode-uu-view -Uudecodes and views the current series (@code{gnus-uu-decode-uu-view}). - -@item X v U -@kindex X v U (Summary) -@findex gnus-uu-decode-uu-and-save-view -Uudecodes, views and saves the current series -(@code{gnus-uu-decode-uu-and-save-view}). - -@end table - -Remember that these all react to the presence of articles marked with -the process mark. If, for instance, you'd like to decode and save an -entire newsgroup, you'd typically do @kbd{M P a} -(@code{gnus-uu-mark-all}) and then @kbd{X U} -(@code{gnus-uu-decode-uu-and-save}). - -All this is very much different from how @code{gnus-uu} worked with -@sc{GNUS 4.1}, where you had explicit keystrokes for everything under -the sun. This version of @code{gnus-uu} generally assumes that you mark -articles in some way (@pxref{Setting Process Marks}) and then press -@kbd{X u}. - -@vindex gnus-uu-notify-files -Note: When trying to decode articles that have names matching -@code{gnus-uu-notify-files}, which is hard-coded to -@samp{[Cc][Ii][Nn][Dd][Yy][0-9]+.\\(gif\\|jpg\\)}, @code{gnus-uu} will -automatically post an article on @samp{comp.unix.wizards} saying that -you have just viewed the file in question. This feature can't be turned -off. - - -@node Shell Archives -@subsection Shell Archives -@cindex unshar -@cindex shell archives -@cindex shared articles - -Shell archives (``shar files'') used to be a popular way to distribute -sources, but it isn't used all that much today. In any case, we have -some commands to deal with these: - -@table @kbd - -@item X s -@kindex X s (Summary) -@findex gnus-uu-decode-unshar -Unshars the current series (@code{gnus-uu-decode-unshar}). - -@item X S -@kindex X S (Summary) -@findex gnus-uu-decode-unshar-and-save -Unshars and saves the current series (@code{gnus-uu-decode-unshar-and-save}). - -@item X v s -@kindex X v s (Summary) -@findex gnus-uu-decode-unshar-view -Unshars and views the current series (@code{gnus-uu-decode-unshar-view}). - -@item X v S -@kindex X v S (Summary) -@findex gnus-uu-decode-unshar-and-save-view -Unshars, views and saves the current series -(@code{gnus-uu-decode-unshar-and-save-view}). -@end table - - -@node PostScript Files -@subsection PostScript Files -@cindex PostScript - -@table @kbd - -@item X p -@kindex X p (Summary) -@findex gnus-uu-decode-postscript -Unpack the current PostScript series (@code{gnus-uu-decode-postscript}). - -@item X P -@kindex X P (Summary) -@findex gnus-uu-decode-postscript-and-save -Unpack and save the current PostScript series -(@code{gnus-uu-decode-postscript-and-save}). - -@item X v p -@kindex X v p (Summary) -@findex gnus-uu-decode-postscript-view -View the current PostScript series -(@code{gnus-uu-decode-postscript-view}). - -@item X v P -@kindex X v P (Summary) -@findex gnus-uu-decode-postscript-and-save-view -View and save the current PostScript series -(@code{gnus-uu-decode-postscript-and-save-view}). -@end table - - -@node Other Files -@subsection Other Files - -@table @kbd -@item X o -@kindex X o (Summary) -@findex gnus-uu-decode-save -Save the current series -(@code{gnus-uu-decode-save}). - -@item X b -@kindex X b (Summary) -@findex gnus-uu-decode-binhex -Unbinhex the current series (@code{gnus-uu-decode-binhex}). This -doesn't really work yet. -@end table - - -@node Decoding Variables -@subsection Decoding Variables - -Adjective, not verb. - -@menu -* Rule Variables:: Variables that say how a file is to be viewed. -* Other Decode Variables:: Other decode variables. -* Uuencoding and Posting:: Variables for customizing uuencoding. -@end menu - - -@node Rule Variables -@subsubsection Rule Variables -@cindex rule variables - -Gnus uses @dfn{rule variables} to decide how to view a file. All these -variables are of the form - -@lisp - (list '(regexp1 command2) - '(regexp2 command2) - ...) -@end lisp - -@table @code - -@item gnus-uu-user-view-rules -@vindex gnus-uu-user-view-rules -@cindex sox -This variable is consulted first when viewing files. If you wish to use, -for instance, @code{sox} to convert an @samp{.au} sound file, you could -say something like: -@lisp -(setq gnus-uu-user-view-rules - (list '(\"\\\\.au$\" \"sox %s -t .aiff > /dev/audio\"))) -@end lisp - -@item gnus-uu-user-view-rules-end -@vindex gnus-uu-user-view-rules-end -This variable is consulted if gnus couldn't make any matches from the -user and default view rules. - -@item gnus-uu-user-archive-rules -@vindex gnus-uu-user-archive-rules -This variable can be used to say what commands should be used to unpack -archives. -@end table - - -@node Other Decode Variables -@subsubsection Other Decode Variables - -@table @code -@vindex gnus-uu-grabbed-file-functions - -@item gnus-uu-grabbed-file-functions -All functions in this list will be called right after each file has been -successfully decoded---so that you can move or view files right away, -and don't have to wait for all files to be decoded before you can do -anything. Ready-made functions you can put in this list are: - -@table @code - -@item gnus-uu-grab-view -@findex gnus-uu-grab-view -View the file. - -@item gnus-uu-grab-move -@findex gnus-uu-grab-move -Move the file (if you're using a saving function.) -@end table - -@item gnus-uu-be-dangerous -@vindex gnus-uu-be-dangerous -Specifies what to do if unusual situations arise during decoding. If -@code{nil}, be as conservative as possible. If @code{t}, ignore things -that didn't work, and overwrite existing files. Otherwise, ask each -time. - -@item gnus-uu-ignore-files-by-name -@vindex gnus-uu-ignore-files-by-name -Files with name matching this regular expression won't be viewed. - -@item gnus-uu-ignore-files-by-type -@vindex gnus-uu-ignore-files-by-type -Files with a @sc{mime} type matching this variable won't be viewed. -Note that Gnus tries to guess what type the file is based on the name. -@code{gnus-uu} is not a @sc{mime} package (yet), so this is slightly -kludgey. - -@item gnus-uu-tmp-dir -@vindex gnus-uu-tmp-dir -Where @code{gnus-uu} does its work. - -@item gnus-uu-do-not-unpack-archives -@vindex gnus-uu-do-not-unpack-archives -Non-@code{nil} means that @code{gnus-uu} won't peek inside archives -looking for files to display. - -@item gnus-uu-view-and-save -@vindex gnus-uu-view-and-save -Non-@code{nil} means that the user will always be asked to save a file -after viewing it. - -@item gnus-uu-ignore-default-view-rules -@vindex gnus-uu-ignore-default-view-rules -Non-@code{nil} means that @code{gnus-uu} will ignore the default viewing -rules. - -@item gnus-uu-ignore-default-archive-rules -@vindex gnus-uu-ignore-default-archive-rules -Non-@code{nil} means that @code{gnus-uu} will ignore the default archive -unpacking commands. - -@item gnus-uu-kill-carriage-return -@vindex gnus-uu-kill-carriage-return -Non-@code{nil} means that @code{gnus-uu} will strip all carriage returns -from articles. - -@item gnus-uu-unmark-articles-not-decoded -@vindex gnus-uu-unmark-articles-not-decoded -Non-@code{nil} means that @code{gnus-uu} will mark unsuccessfully -decoded articles as unread. - -@item gnus-uu-correct-stripped-uucode -@vindex gnus-uu-correct-stripped-uucode -Non-@code{nil} means that @code{gnus-uu} will @emph{try} to fix -uuencoded files that have had trailing spaces deleted. - -@item gnus-uu-pre-uudecode-hook -@vindex gnus-uu-pre-uudecode-hook -Hook run before sending a message to @code{uudecode}. - -@item gnus-uu-view-with-metamail -@vindex gnus-uu-view-with-metamail -@cindex metamail -Non-@code{nil} means that @code{gnus-uu} will ignore the viewing -commands defined by the rule variables and just fudge a @sc{mime} -content type based on the file name. The result will be fed to -@code{metamail} for viewing. - -@item gnus-uu-save-in-digest -@vindex gnus-uu-save-in-digest -Non-@code{nil} means that @code{gnus-uu}, when asked to save without -decoding, will save in digests. If this variable is @code{nil}, -@code{gnus-uu} will just save everything in a file without any -embellishments. The digesting almost conforms to RFC1153---no easy way -to specify any meaningful volume and issue numbers were found, so I -simply dropped them. - -@end table - - -@node Uuencoding and Posting -@subsubsection Uuencoding and Posting - -@table @code - -@item gnus-uu-post-include-before-composing -@vindex gnus-uu-post-include-before-composing -Non-@code{nil} means that @code{gnus-uu} will ask for a file to encode -before you compose the article. If this variable is @code{t}, you can -either include an encoded file with @kbd{C-c C-i} or have one included -for you when you post the article. - -@item gnus-uu-post-length -@vindex gnus-uu-post-length -Maximum length of an article. The encoded file will be split into how -many articles it takes to post the entire file. - -@item gnus-uu-post-threaded -@vindex gnus-uu-post-threaded -Non-@code{nil} means that @code{gnus-uu} will post the encoded file in a -thread. This may not be smart, as no other decoder I have seen is able -to follow threads when collecting uuencoded articles. (Well, I have -seen one package that does that---@code{gnus-uu}, but somehow, I don't -think that counts...) Default is @code{nil}. - -@item gnus-uu-post-separate-description -@vindex gnus-uu-post-separate-description -Non-@code{nil} means that the description will be posted in a separate -article. The first article will typically be numbered (0/x). If this -variable is @code{nil}, the description the user enters will be included -at the beginning of the first article, which will be numbered (1/x). -Default is @code{t}. - -@end table - - -@node Viewing Files -@subsection Viewing Files -@cindex viewing files -@cindex pseudo-articles - -After decoding, if the file is some sort of archive, gnus will attempt -to unpack the archive and see if any of the files in the archive can be -viewed. For instance, if you have a gzipped tar file @file{pics.tar.gz} -containing the files @file{pic1.jpg} and @file{pic2.gif}, gnus will -uncompress and de-tar the main file, and then view the two pictures. -This unpacking process is recursive, so if the archive contains archives -of archives, it'll all be unpacked. - -Finally, gnus will normally insert a @dfn{pseudo-article} for each -extracted file into the summary buffer. If you go to these -``articles'', you will be prompted for a command to run (usually Gnus -will make a suggestion), and then the command will be run. - -@vindex gnus-view-pseudo-asynchronously -If @code{gnus-view-pseudo-asynchronously} is @code{nil}, Emacs will wait -until the viewing is done before proceeding. - -@vindex gnus-view-pseudos -If @code{gnus-view-pseudos} is @code{automatic}, Gnus will not insert -the pseudo-articles into the summary buffer, but view them -immediately. If this variable is @code{not-confirm}, the user won't even -be asked for a confirmation before viewing is done. - -@vindex gnus-view-pseudos-separately -If @code{gnus-view-pseudos-separately} is non-@code{nil}, one -pseudo-article will be created for each file to be viewed. If -@code{nil}, all files that use the same viewing command will be given as -a list of parameters to that command. - -@vindex gnus-insert-pseudo-articles -If @code{gnus-insert-pseudo-articles} is non-@code{nil}, insert -pseudo-articles when decoding. It is @code{t} by default. - -So; there you are, reading your @emph{pseudo-articles} in your -@emph{virtual newsgroup} from the @emph{virtual server}; and you think: -Why isn't anything real anymore? How did we get here? - - -@node Article Treatment -@section Article Treatment - -Reading through this huge manual, you may have quite forgotten that the -object of newsreaders is to actually, like, read what people have -written. Reading articles. Unfortunately, people are quite bad at -writing, so there are tons of functions and variables to make reading -these articles easier. - -@menu -* Article Highlighting:: You want to make the article look like fruit salad. -* Article Fontisizing:: Making emphasized text look nice. -* Article Hiding:: You also want to make certain info go away. -* Article Washing:: Lots of way-neat functions to make life better. -* Article Buttons:: Click on URLs, Message-IDs, addresses and the like. -* Article Date:: Grumble, UT! -* Article Signature:: What is a signature? -@end menu - - -@node Article Highlighting -@subsection Article Highlighting -@cindex highlighting - -Not only do you want your article buffer to look like fruit salad, but -you want it to look like technicolor fruit salad. - -@table @kbd - -@item W H a -@kindex W H a (Summary) -@findex gnus-article-highlight -@findex gnus-article-maybe-highlight -Do much highlighting of the current article -(@code{gnus-article-highlight}). This function highlights header, cited -text, the signature, and adds buttons to the body and the head. - -Most users would prefer using @code{gnus-article-maybe-highlight} in -@code{gnus-article-display-hook} (@pxref{Customizing Articles}) instead. -This is a bit less agressive---it highlights only the headers, the -signature and adds buttons. - -@item W H h -@kindex W H h (Summary) -@findex gnus-article-highlight-headers -@vindex gnus-header-face-alist -Highlight the headers (@code{gnus-article-highlight-headers}). The -highlighting will be done according to the @code{gnus-header-face-alist} -variable, which is a list where each element has the form @var{(regexp -name content)}. @var{regexp} is a regular expression for matching the -header, @var{name} is the face used for highlighting the header name -(@pxref{Faces and Fonts}) and @var{content} is the face for highlighting -the header value. The first match made will be used. Note that -@var{regexp} shouldn't have @samp{^} prepended---Gnus will add one. - -@item W H c -@kindex W H c (Summary) -@findex gnus-article-highlight-citation -Highlight cited text (@code{gnus-article-highlight-citation}). - -Some variables to customize the citation highlights: - -@table @code -@vindex gnus-cite-parse-max-size - -@item gnus-cite-parse-max-size -If the article size if bigger than this variable (which is 25000 by -default), no citation highlighting will be performed. - -@item gnus-cite-prefix-regexp -@vindex gnus-cite-prefix-regexp -Regexp matching the longest possible citation prefix on a line. - -@item gnus-cite-max-prefix -@vindex gnus-cite-max-prefix -Maximum possible length for a citation prefix (default 20). - -@item gnus-cite-face-list -@vindex gnus-cite-face-list -List of faces used for highlighting citations (@pxref{Faces and Fonts}). -When there are citations from multiple articles in the same message, -gnus will try to give each citation from each article its own face. -This should make it easier to see who wrote what. - -@item gnus-supercite-regexp -@vindex gnus-supercite-regexp -Regexp matching normal Supercite attribution lines. - -@item gnus-supercite-secondary-regexp -@vindex gnus-supercite-secondary-regexp -Regexp matching mangled Supercite attribution lines. - -@item gnus-cite-minimum-match-count -@vindex gnus-cite-minimum-match-count -Minimum number of identical prefixes we have to see before we believe -that it's a citation. - -@item gnus-cite-attribution-prefix -@vindex gnus-cite-attribution-prefix -Regexp matching the beginning of an attribution line. - -@item gnus-cite-attribution-suffix -@vindex gnus-cite-attribution-suffix -Regexp matching the end of an attribution line. - -@item gnus-cite-attribution-face -@vindex gnus-cite-attribution-face -Face used for attribution lines. It is merged with the face for the -cited text belonging to the attribution. - -@end table - - -@item W H s -@kindex W H s (Summary) -@vindex gnus-signature-separator -@vindex gnus-signature-face -@findex gnus-article-highlight-signature -Highlight the signature (@code{gnus-article-highlight-signature}). -Everything after @code{gnus-signature-separator} (@pxref{Article -Signature}) in an article will be considered a signature and will be -highlighted with @code{gnus-signature-face}, which is @code{italic} by -default. - -@end table - -@xref{Customizing Articles} for how to highlight articles automatically. - - -@node Article Fontisizing -@subsection Article Fontisizing -@cindex emphasis -@cindex article emphasis - -@findex gnus-article-emphasize -@kindex W e (Summary) -People commonly add emphasis to words in news articles by writing things -like @samp{_this_} or @samp{*this*}. Gnus can make this look nicer by -running the article through the @kbd{W e} -(@code{gnus-article-emphasize}) command. - -@vindex gnus-emphasis-alist -How the emphasis is computed is controlled by the -@code{gnus-emphasis-alist} variable. This is an alist where the first -element is a regular expression to be matched. The second is a number -that says what regular expression grouping is used to find the entire -emphasized word. The third is a number that says what regexp grouping -should be displayed and highlighted. (The text between these two -groupings will be hidden.) The fourth is the face used for -highlighting. - -@lisp -(setq gnus-article-emphasis - '(("_\\(\\w+\\)_" 0 1 gnus-emphasis-underline) - ("\\*\\(\\w+\\)\\*" 0 1 gnus-emphasis-bold))) -@end lisp - -@vindex gnus-emphasis-underline -@vindex gnus-emphasis-bold -@vindex gnus-emphasis-italic -@vindex gnus-emphasis-underline-bold -@vindex gnus-emphasis-underline-italic -@vindex gnus-emphasis-bold-italic -@vindex gnus-emphasis-underline-bold-italic -By default, there are seven rules, and they use the following faces: -@code{gnus-emphasis-bold}, @code{gnus-emphasis-italic}, -@code{gnus-emphasis-underline}, @code{gnus-emphasis-bold-italic}, -@code{gnus-emphasis-underline-italic}, -@code{gnus-emphasis-underline-bold}, and -@code{gnus-emphasis-underline-bold-italic}. - -If you want to change these faces, you can either use @kbd{M-x -customize}, or you can use @code{copy-face}. For instance, if you want -to make @code{gnus-emphasis-italic} use a red face instead, you could -say something like: - -@lisp -(copy-face 'red 'gnus-emphasis-italic) -@end lisp - -@xref{Customizing Articles} for how to fontize articles automatically. - - -@node Article Hiding -@subsection Article Hiding -@cindex article hiding - -Or rather, hiding certain things in each article. There usually is much -too much cruft in most articles. - -@table @kbd - -@item W W a -@kindex W W a (Summary) -@findex gnus-article-hide -Do quite a lot of hiding on the article buffer -(@kbd{gnus-article-hide}). In particular, this function will hide -headers, PGP, cited text and the signature. - -@item W W h -@kindex W W h (Summary) -@findex gnus-article-hide-headers -Hide headers (@code{gnus-article-hide-headers}). @xref{Hiding -Headers}. - -@item W W b -@kindex W W b (Summary) -@findex gnus-article-hide-boring-headers -Hide headers that aren't particularly interesting -(@code{gnus-article-hide-boring-headers}). @xref{Hiding Headers}. - -@item W W s -@kindex W W s (Summary) -@findex gnus-article-hide-signature -Hide signature (@code{gnus-article-hide-signature}). @xref{Article -Signature}. - -@item W W p -@kindex W W p (Summary) -@findex gnus-article-hide-pgp -@vindex gnus-article-hide-pgp-hook -Hide @sc{pgp} signatures (@code{gnus-article-hide-pgp}). The -@code{gnus-article-hide-pgp-hook} hook will be run after a @sc{pgp} -signature has been hidden. - -@item W W P -@kindex W W P (Summary) -@findex gnus-article-hide-pem -Hide @sc{pem} (privacy enhanced messages) cruft -(@code{gnus-article-hide-pem}). - -@item W W c -@kindex W W c (Summary) -@findex gnus-article-hide-citation -Hide citation (@code{gnus-article-hide-citation}). Some variables for -customizing the hiding: - -@table @code - -@item gnus-cited-opened-text-button-line-format -@itemx gnus-cited-closed-text-button-line-format -@vindex gnus-cited-closed-text-button-line-format -@vindex gnus-cited-opened-text-button-line-format -Gnus adds buttons to show where the cited text has been hidden, and to -allow toggle hiding the text. The format of the variable is specified -by these format-like variable (@pxref{Formatting Variables}). These -specs are valid: - -@table @samp -@item b -Starting point of the hidden text. -@item e -Ending point of the hidden text. -@item l -Number of characters in the hidden region. -@item n -Number of lines of hidden text. -@end table - -@item gnus-cited-lines-visible -@vindex gnus-cited-lines-visible -The number of lines at the beginning of the cited text to leave shown. - -@end table - -@item W W C-c -@kindex W W C-c (Summary) -@findex gnus-article-hide-citation-maybe - -Hide citation (@code{gnus-article-hide-citation-maybe}) depending on the -following two variables: - -@table @code -@item gnus-cite-hide-percentage -@vindex gnus-cite-hide-percentage -If the cited text is of a bigger percentage than this variable (default -50), hide the cited text. - -@item gnus-cite-hide-absolute -@vindex gnus-cite-hide-absolute -The cited text must have at least this length (default 10) before it -is hidden. -@end table - -@item W W C -@kindex W W C (Summary) -@findex gnus-article-hide-citation-in-followups -Hide cited text in articles that aren't roots -(@code{gnus-article-hide-citation-in-followups}). This isn't very -useful as an interactive command, but might be a handy function to stick -in @code{gnus-article-display-hook} (@pxref{Customizing Articles}). - -@end table - -All these ``hiding'' commands are toggles, but if you give a negative -prefix to these commands, they will show what they have previously -hidden. If you give a positive prefix, they will always hide. - -Also @pxref{Article Highlighting} for further variables for -citation customization. - -@xref{Customizing Articles} for how to hide article elements -automatically. - - -@node Article Washing -@subsection Article Washing -@cindex washing -@cindex article washing - -We call this ``article washing'' for a really good reason. Namely, the -@kbd{A} key was taken, so we had to use the @kbd{W} key instead. - -@dfn{Washing} is defined by us as ``changing something from something to -something else'', but normally results in something looking better. -Cleaner, perhaps. - -@table @kbd - -@item W l -@kindex W l (Summary) -@findex gnus-summary-stop-page-breaking -Remove page breaks from the current article -(@code{gnus-summary-stop-page-breaking}). @xref{Misc Article} for page -delimiters. - -@item W r -@kindex W r (Summary) -@findex gnus-summary-caesar-message -@c @icon{gnus-summary-caesar-message} -Do a Caesar rotate (rot13) on the article buffer -(@code{gnus-summary-caesar-message}). -Unreadable articles that tell you to read them with Caesar rotate or rot13. -(Typically offensive jokes and such.) - -It's commonly called ``rot13'' because each letter is rotated 13 -positions in the alphabet, e. g. @samp{B} (letter #2) -> @samp{O} (letter -#15). It is sometimes referred to as ``Caesar rotate'' because Caesar -is rumored to have employed this form of, uh, somewhat weak encryption. - -@item W t -@kindex W t (Summary) -@findex gnus-summary-toggle-header -Toggle whether to display all headers in the article buffer -(@code{gnus-summary-toggle-header}). - -@item W v -@kindex W v (Summary) -@findex gnus-summary-verbose-header -Toggle whether to display all headers in the article buffer permanently -(@code{gnus-summary-verbose-header}). - -@item W m -@kindex W m (Summary) -@findex gnus-summary-toggle-mime -Toggle whether to display the article as @sc{mime} message -(@code{gnus-summary-toggle-mime}). - -@item W o -@kindex W o (Summary) -@findex gnus-article-treat-overstrike -Treat overstrike (@code{gnus-article-treat-overstrike}). - -@item W d -@kindex W d (Summary) -@findex gnus-article-treat-dumbquotes -Treat M******** sm*rtq**t*s (@code{gnus-article-treat-dumbquotes}). - -@item W w -@kindex W w (Summary) -@findex gnus-article-fill-cited-article -Do word wrap (@code{gnus-article-fill-cited-article}). If you use this -function in @code{gnus-article-display-hook}, it should be run fairly -late and certainly after any highlighting. - -You can give the command a numerical prefix to specify the width to use -when filling. - -@item W c -@kindex W c (Summary) -@findex gnus-article-remove-cr -Remove CR (i. e., @samp{^M}s on the end of the lines) -(@code{gnus-article-remove-cr}). - -@item W f -@kindex W f (Summary) -@cindex x-face -@findex gnus-article-display-x-face -@findex gnus-article-x-face-command -@vindex gnus-article-x-face-command -@vindex gnus-article-x-face-too-ugly -@iftex -@iflatex -\include{xface} -@end iflatex -@end iftex -Look for and display any X-Face headers -(@code{gnus-article-display-x-face}). The command executed by this -function is given by the @code{gnus-article-x-face-command} variable. -If this variable is a string, this string will be executed in a -sub-shell. If it is a function, this function will be called with the -face as the argument. If the @code{gnus-article-x-face-too-ugly} (which -is a regexp) matches the @code{From} header, the face will not be shown. -The default action under Emacs is to fork off an @code{xv} to view the -face; under XEmacs the default action is to display the face before the -@code{From} header. (It's nicer if XEmacs has been compiled with X-Face -support---that will make display somewhat faster. If there's no native -X-Face support, Gnus will try to convert the @code{X-Face} header using -external programs from the @code{pbmplus} package and friends.) If you -want to have this function in the display hook, it should probably come -last. - -@item W b -@kindex W b (Summary) -@findex gnus-article-add-buttons -Add clickable buttons to the article (@code{gnus-article-add-buttons}). -@xref{Article Buttons} - -@item W B -@kindex W B (Summary) -@findex gnus-article-add-buttons-to-head -Add clickable buttons to the article headers -(@code{gnus-article-add-buttons-to-head}). - -@item W E l -@kindex W E l (Summary) -@findex gnus-article-strip-leading-blank-lines -Remove all blank lines from the beginning of the article -(@code{gnus-article-strip-leading-blank-lines}). - -@item W E m -@kindex W E m (Summary) -@findex gnus-article-strip-multiple-blank-lines -Replace all blank lines with empty lines and then all multiple empty -lines with a single empty line. -(@code{gnus-article-strip-multiple-blank-lines}). - -@item W E t -@kindex W E t (Summary) -@findex gnus-article-remove-trailing-blank-lines -Remove all blank lines at the end of the article -(@code{gnus-article-remove-trailing-blank-lines}). - -@item W E a -@kindex W E a (Summary) -@findex gnus-article-strip-blank-lines -Do all the three commands above -(@code{gnus-article-strip-blank-lines}). - -@item W E A -@kindex W E A (Summary) -@findex gnus-article-strip-all-blank-lines -Remove all blank lines -(@code{gnus-article-strip-all-blank-lines}). - -@item W E s -@kindex W E s (Summary) -@findex gnus-article-strip-leading-space -Remove all white space from the beginning of all lines of the article -body (@code{gnus-article-strip-leading-space}). - -@end table - -@xref{Customizing Articles} for how to wash articles automatically. - - -@node Article Buttons -@subsection Article Buttons -@cindex buttons - -People often include references to other stuff in articles, and it would -be nice if Gnus could just fetch whatever it is that people talk about -with the minimum of fuzz when you hit @kbd{RET} or use the middle mouse -button on these references. - -Gnus adds @dfn{buttons} to certain standard references by default: -Well-formed URLs, mail addresses and Message-IDs. This is controlled by -two variables, one that handles article bodies and one that handles -article heads: - -@table @code - -@item gnus-button-alist -@vindex gnus-button-alist -This is an alist where each entry has this form: - -@lisp -(REGEXP BUTTON-PAR USE-P FUNCTION DATA-PAR) -@end lisp - -@table @var - -@item regexp -All text that match this regular expression will be considered an -external reference. Here's a typical regexp that matches embedded URLs: -@samp{]*\\)>}. - -@item button-par -Gnus has to know which parts of the matches is to be highlighted. This -is a number that says what sub-expression of the regexp is to be -highlighted. If you want it all highlighted, you use 0 here. - -@item use-p -This form will be @code{eval}ed, and if the result is non-@code{nil}, -this is considered a match. This is useful if you want extra sifting to -avoid false matches. - -@item function -This function will be called when you click on this button. - -@item data-par -As with @var{button-par}, this is a sub-expression number, but this one -says which part of the match is to be sent as data to @var{function}. - -@end table - -So the full entry for buttonizing URLs is then - -@lisp -("]*\\)>" 0 t gnus-button-url 1) -@end lisp - -@item gnus-header-button-alist -@vindex gnus-header-button-alist -This is just like the other alist, except that it is applied to the -article head only, and that each entry has an additional element that is -used to say what headers to apply the buttonize coding to: - -@lisp -(HEADER REGEXP BUTTON-PAR USE-P FUNCTION DATA-PAR) -@end lisp - -@var{HEADER} is a regular expression. - -@item gnus-button-url-regexp -@vindex gnus-button-url-regexp -A regular expression that matches embedded URLs. It is used in the -default values of the variables above. - -@item gnus-article-button-face -@vindex gnus-article-button-face -Face used on buttons. - -@item gnus-article-mouse-face -@vindex gnus-article-mouse-face -Face used when the mouse cursor is over a button. - -@end table - -@xref{Customizing Articles} for how to buttonize articles automatically. - - -@node Article Date -@subsection Article Date - -The date is most likely generated in some obscure timezone you've never -heard of, so it's quite nice to be able to find out what the time was -when the article was sent. - -@table @kbd - -@item W T u -@kindex W T u (Summary) -@findex gnus-article-date-ut -Display the date in UT (aka. GMT, aka ZULU) -(@code{gnus-article-date-ut}). - -@item W T i -@kindex W T i (Summary) -@findex gnus-article-date-iso8601 -@cindex ISO 8601 -Display the date in international format, aka. ISO 8601 -(@code{gnus-article-date-iso8601}). - -@item W T l -@kindex W T l (Summary) -@findex gnus-article-date-local -Display the date in the local timezone (@code{gnus-article-date-local}). - -@item W T s -@kindex W T s (Summary) -@vindex gnus-article-time-format -@findex gnus-article-date-user -@findex format-time-string -Display the date using a user-defined format -(@code{gnus-article-date-user}). The format is specified by the -@code{gnus-article-time-format} variable, and is a string that's passed -to @code{format-time-string}. See the documentation of that variable -for a list of possible format specs. - -@item W T e -@kindex W T e (Summary) -@findex gnus-article-date-lapsed -@findex gnus-start-date-timer -@findex gnus-stop-date-timer -Say how much time has elapsed between the article was posted and now -(@code{gnus-article-date-lapsed}). If you want to have this line -updated continually, you can put - -@lisp -(gnus-start-date-timer) -@end lisp - -in your @file{.gnus.el} file, or you can run it off of some hook. If -you want to stop the timer, you can use the @code{gnus-stop-date-timer} -command. - -@item W T o -@kindex W T o (Summary) -@findex gnus-article-date-original -Display the original date (@code{gnus-article-date-original}). This can -be useful if you normally use some other conversion function and are -worried that it might be doing something totally wrong. Say, claiming -that the article was posted in 1854. Although something like that is -@emph{totally} impossible. Don't you trust me? *titter* - -@end table - -@xref{Customizing Articles} for how to display the date in your -preferred format automatically. - - -@node Article Signature -@subsection Article Signature -@cindex signatures -@cindex article signature - -@vindex gnus-signature-separator -Each article is divided into two parts---the head and the body. The -body can be divided into a signature part and a text part. The variable -that says what is to be considered a signature is -@code{gnus-signature-separator}. This is normally the standard -@samp{^-- $} as mandated by son-of-RFC 1036. However, many people use -non-standard signature separators, so this variable can also be a list -of regular expressions to be tested, one by one. (Searches are done -from the end of the body towards the beginning.) One likely value is: - -@lisp -(setq gnus-signature-separator - '("^-- $" ; The standard - "^-- *$" ; A common mangling - "^-------*$" ; Many people just use a looong - ; line of dashes. Shame! - "^ *--------*$" ; Double-shame! - "^________*$" ; Underscores are also popular - "^========*$")) ; Pervert! -@end lisp - -The more permissive you are, the more likely it is that you'll get false -positives. - -@vindex gnus-signature-limit -@code{gnus-signature-limit} provides a limit to what is considered a -signature. - -@enumerate -@item -If it is an integer, no signature may be longer (in characters) than -that integer. -@item -If it is a floating point number, no signature may be longer (in lines) -than that number. -@item -If it is a function, the function will be called without any parameters, -and if it returns @code{nil}, there is no signature in the buffer. -@item -If it is a string, it will be used as a regexp. If it matches, the text -in question is not a signature. -@end enumerate - -This variable can also be a list where the elements may be of the types -listed above. Here's an example: - -@lisp -(setq gnus-signature-limit - '(200.0 "^---*Forwarded article")) -@end lisp - -This means that if there are more than 200 lines after the signature -separator, or the text after the signature separator is matched by -the regular expression @samp{^---*Forwarded article}, then it isn't a -signature after all. - - -@node Article Commands -@section Article Commands - -@table @kbd - -@item A P -@cindex PostScript -@cindex printing -@kindex A P (Summary) -@vindex gnus-ps-print-hook -@findex gnus-summary-print-article -Generate and print a PostScript image of the article buffer -(@code{gnus-summary-print-article}). @code{gnus-ps-print-hook} will be -run just before printing the buffer. - -@end table - - -@node Summary Sorting -@section Summary Sorting -@cindex summary sorting - -You can have the summary buffer sorted in various ways, even though I -can't really see why you'd want that. - -@table @kbd - -@item C-c C-s C-n -@kindex C-c C-s C-n (Summary) -@findex gnus-summary-sort-by-number -Sort by article number (@code{gnus-summary-sort-by-number}). - -@item C-c C-s C-a -@kindex C-c C-s C-a (Summary) -@findex gnus-summary-sort-by-author -Sort by author (@code{gnus-summary-sort-by-author}). - -@item C-c C-s C-s -@kindex C-c C-s C-s (Summary) -@findex gnus-summary-sort-by-subject -Sort by subject (@code{gnus-summary-sort-by-subject}). - -@item C-c C-s C-d -@kindex C-c C-s C-d (Summary) -@findex gnus-summary-sort-by-date -Sort by date (@code{gnus-summary-sort-by-date}). - -@item C-c C-s C-l -@kindex C-c C-s C-l (Summary) -@findex gnus-summary-sort-by-lines -Sort by lines (@code{gnus-summary-sort-by-lines}). - -@item C-c C-s C-i -@kindex C-c C-s C-i (Summary) -@findex gnus-summary-sort-by-score -Sort by score (@code{gnus-summary-sort-by-score}). -@end table - -These functions will work both when you use threading and when you don't -use threading. In the latter case, all summary lines will be sorted, -line by line. In the former case, sorting will be done on a -root-by-root basis, which might not be what you were looking for. To -toggle whether to use threading, type @kbd{T T} (@pxref{Thread -Commands}). - - -@node Finding the Parent -@section Finding the Parent -@cindex parent articles -@cindex referring articles - -@table @kbd -@item ^ -@kindex ^ (Summary) -@findex gnus-summary-refer-parent-article -If you'd like to read the parent of the current article, and it is not -displayed in the summary buffer, you might still be able to. That is, -if the current group is fetched by @sc{nntp}, the parent hasn't expired -and the @code{References} in the current article are not mangled, you -can just press @kbd{^} or @kbd{A r} -(@code{gnus-summary-refer-parent-article}). If everything goes well, -you'll get the parent. If the parent is already displayed in the -summary buffer, point will just move to this article. - -If given a positive numerical prefix, fetch that many articles back into -the ancestry. If given a negative numerical prefix, fetch just that -ancestor. So if you say @kbd{3 ^}, gnus will fetch the parent, the -grandparent and the grandgrandparent of the current article. If you say -@kbd{-3 ^}, gnus will only fetch the grandgrandparent of the current -article. - -@item A R (Summary) -@findex gnus-summary-refer-references -@kindex A R (Summary) -Fetch all articles mentioned in the @code{References} header of the -article (@code{gnus-summary-refer-references}). - -@item A T (Summary) -@findex gnus-summary-refer-thread -@kindex A T (Summary) -Display the full thread where the current article appears -(@code{gnus-summary-refer-thread}). This command has to fetch all the -headers in the current group to work, so it usually takes a while. If -you do it often, you may consider setting @code{gnus-fetch-old-headers} -to @code{invisible} (@pxref{Filling In Threads}). This won't have any -visible effects normally, but it'll make this command work a whole lot -faster. Of course, it'll make group entry somewhat slow. - -@vindex gnus-refer-thread-limit -The @code{gnus-refer-thread-limit} variable says how many old (i. e., -articles before the first displayed in the current group) headers to -fetch when doing this command. The default is 200. If @code{t}, all -the available headers will be fetched. This variable can be overridden -by giving the @kbd{A T} command a numerical prefix. - -@item M-^ (Summary) -@findex gnus-summary-refer-article -@kindex M-^ (Summary) -@cindex Message-ID -@cindex fetching by Message-ID -You can also ask the @sc{nntp} server for an arbitrary article, no -matter what group it belongs to. @kbd{M-^} -(@code{gnus-summary-refer-article}) will ask you for a -@code{Message-ID}, which is one of those long, hard-to-read thingies -that look something like @samp{<38o6up$6f2@@hymir.ifi.uio.no>}. You -have to get it all exactly right. No fuzzy searches, I'm afraid. -@end table - -The current select method will be used when fetching by -@code{Message-ID} from non-news select method, but you can override this -by giving this command a prefix. - -@vindex gnus-refer-article-method -If the group you are reading is located on a backend that does not -support fetching by @code{Message-ID} very well (like @code{nnspool}), -you can set @code{gnus-refer-article-method} to an @sc{nntp} method. It -would, perhaps, be best if the @sc{nntp} server you consult is the one -updating the spool you are reading from, but that's not really -necessary. - -Most of the mail backends support fetching by @code{Message-ID}, but do -not do a particularly excellent job at it. That is, @code{nnmbox} and -@code{nnbabyl} are able to locate articles from any groups, while -@code{nnml} and @code{nnfolder} are only able to locate articles that -have been posted to the current group. (Anything else would be too time -consuming.) @code{nnmh} does not support this at all. - - -@node Alternative Approaches -@section Alternative Approaches - -Different people like to read news using different methods. This being -gnus, we offer a small selection of minor modes for the summary buffers. - -@menu -* Pick and Read:: First mark articles and then read them. -* Binary Groups:: Auto-decode all articles. -@end menu - - -@node Pick and Read -@subsection Pick and Read -@cindex pick and read - -Some newsreaders (like @code{nn} and, uhm, @code{Netnews} on VM/CMS) use -a two-phased reading interface. The user first marks in a summary -buffer the articles she wants to read. Then she starts reading the -articles with just an article buffer displayed. - -@findex gnus-pick-mode -@kindex M-x gnus-pick-mode -Gnus provides a summary buffer minor mode that allows -this---@code{gnus-pick-mode}. This basically means that a few process -mark commands become one-keystroke commands to allow easy marking, and -it provides one additional command for switching to the summary buffer. - -Here are the available keystrokes when using pick mode: - -@table @kbd -@item . -@kindex . (Pick) -@findex gnus-pick-article-or-thread -Pick the article or thread on the current line -(@code{gnus-pick-article-or-thread}). If the variable -@code{gnus-thread-hide-subtree} is true, then this key selects the -entire thread when used at the first article of the thread. Otherwise, -it selects just the article. If given a numerical prefix, go to that -thread or article and pick it. (The line number is normally displayed -at the beginning of the summary pick lines.) - -@item SPACE -@kindex SPACE (Pick) -@findex gnus-pick-next-page -Scroll the summary buffer up one page (@code{gnus-pick-next-page}). If -at the end of the buffer, start reading the picked articles. - -@item u -@kindex u (Pick) -@findex gnus-pick-unmark-article-or-thread. -Unpick the thread or article -(@code{gnus-pick-unmark-article-or-thread}). If the variable -@code{gnus-thread-hide-subtree} is true, then this key unpicks the -thread if used at the first article of the thread. Otherwise it unpicks -just the article. You can give this key a numerical prefix to unpick -the thread or article at that line. - -@item RET -@kindex RET (Pick) -@findex gnus-pick-start-reading -@vindex gnus-pick-display-summary -Start reading the picked articles (@code{gnus-pick-start-reading}). If -given a prefix, mark all unpicked articles as read first. If -@code{gnus-pick-display-summary} is non-@code{nil}, the summary buffer -will still be visible when you are reading. - -@end table - -All the normal summary mode commands are still available in the -pick-mode, with the exception of @kbd{u}. However @kbd{!} is available -which is mapped to the same function -@code{gnus-summary-tick-article-forward}. - -If this sounds like a good idea to you, you could say: - -@lisp -(add-hook 'gnus-summary-mode-hook 'gnus-pick-mode) -@end lisp - -@vindex gnus-pick-mode-hook -@code{gnus-pick-mode-hook} is run in pick minor mode buffers. - -@vindex gnus-mark-unpicked-articles-as-read -If @code{gnus-mark-unpicked-articles-as-read} is non-@code{nil}, mark -all unpicked articles as read. The default is @code{nil}. - -@vindex gnus-summary-pick-line-format -The summary line format in pick mode is slightly different from the -standard format. At the beginning of each line the line number is -displayed. The pick mode line format is controlled by the -@code{gnus-summary-pick-line-format} variable (@pxref{Formatting -Variables}). It accepts the same format specs that -@code{gnus-summary-line-format} does (@pxref{Summary Buffer Lines}). - - -@node Binary Groups -@subsection Binary Groups -@cindex binary groups - -@findex gnus-binary-mode -@kindex M-x gnus-binary-mode -If you spend much time in binary groups, you may grow tired of hitting -@kbd{X u}, @kbd{n}, @kbd{RET} all the time. @kbd{M-x gnus-binary-mode} -is a minor mode for summary buffers that makes all ordinary Gnus article -selection functions uudecode series of articles and display the result -instead of just displaying the articles the normal way. - -@kindex g (Binary) -@findex gnus-binary-show-article -The only way, in fact, to see the actual articles is the @kbd{g} -command, when you have turned on this mode -(@code{gnus-binary-show-article}). - -@vindex gnus-binary-mode-hook -@code{gnus-binary-mode-hook} is called in binary minor mode buffers. - - -@node Tree Display -@section Tree Display -@cindex trees - -@vindex gnus-use-trees -If you don't like the normal gnus summary display, you might try setting -@code{gnus-use-trees} to @code{t}. This will create (by default) an -additional @dfn{tree buffer}. You can execute all summary mode commands -in the tree buffer. - -There are a few variables to customize the tree display, of course: - -@table @code -@item gnus-tree-mode-hook -@vindex gnus-tree-mode-hook -A hook called in all tree mode buffers. - -@item gnus-tree-mode-line-format -@vindex gnus-tree-mode-line-format -A format string for the mode bar in the tree mode buffers (@pxref{Mode -Line Formatting}). The default is @samp{Gnus: %%b %S %Z}. For a list -of valid specs, @pxref{Summary Buffer Mode Line}. - -@item gnus-selected-tree-face -@vindex gnus-selected-tree-face -Face used for highlighting the selected article in the tree buffer. The -default is @code{modeline}. - -@item gnus-tree-line-format -@vindex gnus-tree-line-format -A format string for the tree nodes. The name is a bit of a misnomer, -though---it doesn't define a line, but just the node. The default value -is @samp{%(%[%3,3n%]%)}, which displays the first three characters of -the name of the poster. It is vital that all nodes are of the same -length, so you @emph{must} use @samp{%4,4n}-like specifiers. - -Valid specs are: - -@table @samp -@item n -The name of the poster. -@item f -The @code{From} header. -@item N -The number of the article. -@item [ -The opening bracket. -@item ] -The closing bracket. -@item s -The subject. -@end table - -@xref{Formatting Variables}. - -Variables related to the display are: - -@table @code -@item gnus-tree-brackets -@vindex gnus-tree-brackets -This is used for differentiating between ``real'' articles and -``sparse'' articles. The format is @var{((real-open . real-close) -(sparse-open . sparse-close) (dummy-open . dummy-close))}, and the -default is @code{((?[ . ?]) (?( . ?)) (?@{ . ?@}) (?< . ?>))}. - -@item gnus-tree-parent-child-edges -@vindex gnus-tree-parent-child-edges -This is a list that contains the characters used for connecting parent -nodes to their children. The default is @code{(?- ?\\ ?|)}. - -@end table - -@item gnus-tree-minimize-window -@vindex gnus-tree-minimize-window -If this variable is non-@code{nil}, gnus will try to keep the tree -buffer as small as possible to allow more room for the other gnus -windows. If this variable is a number, the tree buffer will never be -higher than that number. The default is @code{t}. Note that if you -have several windows displayed side-by-side in a frame and the tree -buffer is one of these, minimizing the tree window will also resize all -other windows displayed next to it. - -@item gnus-generate-tree-function -@vindex gnus-generate-tree-function -@findex gnus-generate-horizontal-tree -@findex gnus-generate-vertical-tree -The function that actually generates the thread tree. Two predefined -functions are available: @code{gnus-generate-horizontal-tree} and -@code{gnus-generate-vertical-tree} (which is the default). - -@end table - -Here's an example from a horizontal tree buffer: - -@example -@{***@}-(***)-[odd]-[Gun] - | \[Jan] - | \[odd]-[Eri] - | \(***)-[Eri] - | \[odd]-[Paa] - \[Bjo] - \[Gun] - \[Gun]-[Jor] -@end example - -Here's the same thread displayed in a vertical tree buffer: - -@example -@{***@} - |--------------------------\-----\-----\ -(***) [Bjo] [Gun] [Gun] - |--\-----\-----\ | -[odd] [Jan] [odd] (***) [Jor] - | | |--\ -[Gun] [Eri] [Eri] [odd] - | - [Paa] -@end example - -If you're using horizontal trees, it might be nice to display the trees -side-by-side with the summary buffer. You could add something like the -following to your @file{.gnus.el} file: - -@lisp -(setq gnus-use-trees t - gnus-generate-tree-function 'gnus-generate-horizontal-tree - gnus-tree-minimize-window nil) -(gnus-add-configuration - '(article - (vertical 1.0 - (horizontal 0.25 - (summary 0.75 point) - (tree 1.0)) - (article 1.0)))) -@end lisp - -@xref{Windows Configuration}. - - -@node Mail Group Commands -@section Mail Group Commands -@cindex mail group commands - -Some commands only make sense in mail groups. If these commands are -invalid in the current group, they will raise a hell and let you know. - -All these commands (except the expiry and edit commands) use the -process/prefix convention (@pxref{Process/Prefix}). - -@table @kbd - -@item B e -@kindex B e (Summary) -@findex gnus-summary-expire-articles -Expire all expirable articles in the group -(@code{gnus-summary-expire-articles}). - -@item B M-C-e -@kindex B M-C-e (Summary) -@findex gnus-summary-expire-articles-now -Delete all the expirable articles in the group -(@code{gnus-summary-expire-articles-now}). This means that @strong{all} -articles eligible for expiry in the current group will -disappear forever into that big @file{/dev/null} in the sky. - -@item B DEL -@kindex B DEL (Summary) -@findex gnus-summary-delete-article -@c @icon{gnus-summary-mail-delete} -Delete the mail article. This is ``delete'' as in ``delete it from your -disk forever and ever, never to return again.'' Use with caution. -(@code{gnus-summary-delete-article}). - -@item B m -@kindex B m (Summary) -@cindex move mail -@findex gnus-summary-move-article -Move the article from one mail group to another -(@code{gnus-summary-move-article}). - -@item B c -@kindex B c (Summary) -@cindex copy mail -@findex gnus-summary-copy-article -@c @icon{gnus-summary-mail-copy} -Copy the article from one group (mail group or not) to a mail group -(@code{gnus-summary-copy-article}). - -@item B B -@kindex B B (Summary) -@cindex crosspost mail -@findex gnus-summary-crosspost-article -Crosspost the current article to some other group -(@code{gnus-summary-crosspost-article}). This will create a new copy of -the article in the other group, and the Xref headers of the article will -be properly updated. - -@item B i -@kindex B i (Summary) -@findex gnus-summary-import-article -Import an arbitrary file into the current mail newsgroup -(@code{gnus-summary-import-article}). You will be prompted for a file -name, a @code{From} header and a @code{Subject} header. - -@item B r -@kindex B r (Summary) -@findex gnus-summary-respool-article -Respool the mail article (@code{gnus-summary-respool-article}). -@code{gnus-summary-respool-default-method} will be used as the default -select method when respooling. This variable is @code{nil} by default, -which means that the current group select method will be used instead. - -@item B w -@itemx e -@kindex B w (Summary) -@kindex e (Summary) -@findex gnus-summary-edit-article -@kindex C-c C-c (Article) -Edit the current article (@code{gnus-summary-edit-article}). To finish -editing and make the changes permanent, type @kbd{C-c C-c} -(@kbd{gnus-summary-edit-article-done}). If you give a prefix to the -@kbd{C-c C-c} command, gnus won't re-highlight the article. - -@item B q -@kindex B q (Summary) -@findex gnus-summary-respool-query -If you want to re-spool an article, you might be curious as to what group -the article will end up in before you do the re-spooling. This command -will tell you (@code{gnus-summary-respool-query}). - -@item B t -@kindex B t (Summary) -@findex gnus-summary-respool-trace -Similarly, this command will display all fancy splitting patterns used -when repooling, if any (@code{gnus-summary-respool-trace}). - -@item B p -@kindex B p (Summary) -@findex gnus-summary-article-posted-p -Some people have a tendency to send you "courtesy" copies when they -follow up to articles you have posted. These usually have a -@code{Newsgroups} header in them, but not always. This command -(@code{gnus-summary-article-posted-p}) will try to fetch the current -article from your news server (or rather, from -@code{gnus-refer-article-method} or @code{gnus-select-method}) and will -report back whether it found the article or not. Even if it says that -it didn't find the article, it may have been posted anyway---mail -propagation is much faster than news propagation, and the news copy may -just not have arrived yet. - -@end table - -@vindex gnus-move-split-methods -@cindex moving articles -If you move (or copy) articles regularly, you might wish to have gnus -suggest where to put the articles. @code{gnus-move-split-methods} is a -variable that uses the same syntax as @code{gnus-split-methods} -(@pxref{Saving Articles}). You may customize that variable to create -suggestions you find reasonable. - -@lisp -(setq gnus-move-split-methods - '(("^From:.*Lars Magne" "nnml:junk") - ("^Subject:.*gnus" "nnfolder:important") - (".*" "nnml:misc"))) -@end lisp - - -@node Various Summary Stuff -@section Various Summary Stuff - -@menu -* Summary Group Information:: Information oriented commands. -* Searching for Articles:: Multiple article commands. -* Summary Generation Commands:: (Re)generating the summary buffer. -* Really Various Summary Commands:: Those pesky non-conformant commands. -@end menu - -@table @code -@vindex gnus-summary-mode-hook -@item gnus-summary-mode-hook -This hook is called when creating a summary mode buffer. - -@vindex gnus-summary-generate-hook -@item gnus-summary-generate-hook -This is called as the last thing before doing the threading and the -generation of the summary buffer. It's quite convenient for customizing -the threading variables based on what data the newsgroup has. This hook -is called from the summary buffer after most summary buffer variables -have been set. - -@vindex gnus-summary-prepare-hook -@item gnus-summary-prepare-hook -It is called after the summary buffer has been generated. You might use -it to, for instance, highlight lines or modify the look of the buffer in -some other ungodly manner. I don't care. - -@vindex gnus-summary-ignore-duplicates -@item gnus-summary-ignore-duplicates -When gnus discovers two articles that have the same @code{Message-ID}, -it has to do something drastic. No articles are allowed to have the -same @code{Message-ID}, but this may happen when reading mail from some -sources. Gnus allows you to customize what happens with this variable. -If it is @code{nil} (which is the default), gnus will rename the -@code{Message-ID} (for display purposes only) and display the article as -any other article. If this variable is @code{t}, it won't display the -article---it'll be as if it never existed. - -@end table - - -@node Summary Group Information -@subsection Summary Group Information - -@table @kbd - -@item H f -@kindex H f (Summary) -@findex gnus-summary-fetch-faq -@vindex gnus-group-faq-directory -Try to fetch the FAQ (list of frequently asked questions) for the -current group (@code{gnus-summary-fetch-faq}). Gnus will try to get the -FAQ from @code{gnus-group-faq-directory}, which is usually a directory -on a remote machine. This variable can also be a list of directories. -In that case, giving a prefix to this command will allow you to choose -between the various sites. @code{ange-ftp} or @code{efs} will probably -be used for fetching the file. - -@item H d -@kindex H d (Summary) -@findex gnus-summary-describe-group -Give a brief description of the current group -(@code{gnus-summary-describe-group}). If given a prefix, force -rereading the description from the server. - -@item H h -@kindex H h (Summary) -@findex gnus-summary-describe-briefly -Give an extremely brief description of the most important summary -keystrokes (@code{gnus-summary-describe-briefly}). - -@item H i -@kindex H i (Summary) -@findex gnus-info-find-node -Go to the gnus info node (@code{gnus-info-find-node}). -@end table - - -@node Searching for Articles -@subsection Searching for Articles - -@table @kbd - -@item M-s -@kindex M-s (Summary) -@findex gnus-summary-search-article-forward -Search through all subsequent articles for a regexp -(@code{gnus-summary-search-article-forward}). - -@item M-r -@kindex M-r (Summary) -@findex gnus-summary-search-article-backward -Search through all previous articles for a regexp -(@code{gnus-summary-search-article-backward}). - -@item & -@kindex & (Summary) -@findex gnus-summary-execute-command -This command will prompt you for a header field, a regular expression to -match on this field, and a command to be executed if the match is made -(@code{gnus-summary-execute-command}). If given a prefix, search -backward instead. - -@item M-& -@kindex M-& (Summary) -@findex gnus-summary-universal-argument -Perform any operation on all articles that have been marked with -the process mark (@code{gnus-summary-universal-argument}). -@end table - -@node Summary Generation Commands -@subsection Summary Generation Commands - -@table @kbd - -@item Y g -@kindex Y g (Summary) -@findex gnus-summary-prepare -Regenerate the current summary buffer (@code{gnus-summary-prepare}). - -@item Y c -@kindex Y c (Summary) -@findex gnus-summary-insert-cached-articles -Pull all cached articles (for the current group) into the summary buffer -(@code{gnus-summary-insert-cached-articles}). - -@end table - - -@node Really Various Summary Commands -@subsection Really Various Summary Commands - -@table @kbd - -@item C-d -@kindex C-d (Summary) -@findex gnus-summary-enter-digest-group -If the current article is a collection of other articles (for instance, -a digest), you might use this command to enter a group based on the that -article (@code{gnus-summary-enter-digest-group}). Gnus will try to -guess what article type is currently displayed unless you give a prefix -to this command, which forces a ``digest'' interpretation. Basically, -whenever you see a message that is a collection of other messages of -some format, you @kbd{C-d} and read these messages in a more convenient -fashion. - -@item M-C-d -@kindex M-C-d (Summary) -@findex gnus-summary-read-document -This command is very similar to the one above, but lets you gather -several documents into one biiig group -(@code{gnus-summary-read-document}). It does this by opening several -@code{nndoc} groups for each document, and then opening an -@code{nnvirtual} group on top of these @code{nndoc} groups. This -command understands the process/prefix convention -(@pxref{Process/Prefix}). - -@item C-t -@kindex C-t (Summary) -@findex gnus-summary-toggle-truncation -Toggle truncation of summary lines -(@code{gnus-summary-toggle-truncation}). This will probably confuse the -line centering function in the summary buffer, so it's not a good idea -to have truncation switched off while reading articles. - -@item = -@kindex = (Summary) -@findex gnus-summary-expand-window -Expand the summary buffer window (@code{gnus-summary-expand-window}). -If given a prefix, force an @code{article} window configuration. - -@item M-C-e -@kindex M-C-e (Summary) -@findex gnus-summary-edit-parameters -Edit the group parameters (@pxref{Group Parameters}) of the current -group (@code{gnus-summary-edit-parameters}). - -@end table - - -@node Exiting the Summary Buffer -@section Exiting the Summary Buffer -@cindex summary exit -@cindex exiting groups - -Exiting from the summary buffer will normally update all info on the -group and return you to the group buffer. - -@table @kbd - -@item Z Z -@itemx q -@kindex Z Z (Summary) -@kindex q (Summary) -@findex gnus-summary-exit -@vindex gnus-summary-exit-hook -@vindex gnus-summary-prepare-exit-hook -@c @icon{gnus-summary-exit} -Exit the current group and update all information on the group -(@code{gnus-summary-exit}). @code{gnus-summary-prepare-exit-hook} is -called before doing much of the exiting, which calls -@code{gnus-summary-expire-articles} by default. -@code{gnus-summary-exit-hook} is called after finishing the exit -process. @code{gnus-group-no-more-groups-hook} is run when returning to -group mode having no more (unread) groups. - -@item Z E -@itemx Q -@kindex Z E (Summary) -@kindex Q (Summary) -@findex gnus-summary-exit-no-update -Exit the current group without updating any information on the group -(@code{gnus-summary-exit-no-update}). - -@item Z c -@itemx c -@kindex Z c (Summary) -@kindex c (Summary) -@findex gnus-summary-catchup-and-exit -@c @icon{gnus-summary-catchup-and-exit} -Mark all unticked articles in the group as read and then exit -(@code{gnus-summary-catchup-and-exit}). - -@item Z C -@kindex Z C (Summary) -@findex gnus-summary-catchup-all-and-exit -Mark all articles, even the ticked ones, as read and then exit -(@code{gnus-summary-catchup-all-and-exit}). - -@item Z n -@kindex Z n (Summary) -@findex gnus-summary-catchup-and-goto-next-group -Mark all articles as read and go to the next group -(@code{gnus-summary-catchup-and-goto-next-group}). - -@item Z R -@kindex Z R (Summary) -@findex gnus-summary-reselect-current-group -Exit this group, and then enter it again -(@code{gnus-summary-reselect-current-group}). If given a prefix, select -all articles, both read and unread. - -@item Z G -@itemx M-g -@kindex Z G (Summary) -@kindex M-g (Summary) -@findex gnus-summary-rescan-group -@c @icon{gnus-summary-mail-get} -Exit the group, check for new articles in the group, and select the -group (@code{gnus-summary-rescan-group}). If given a prefix, select all -articles, both read and unread. - -@item Z N -@kindex Z N (Summary) -@findex gnus-summary-next-group -Exit the group and go to the next group -(@code{gnus-summary-next-group}). - -@item Z P -@kindex Z P (Summary) -@findex gnus-summary-prev-group -Exit the group and go to the previous group -(@code{gnus-summary-prev-group}). - -@item Z s -@kindex Z s (Summary) -@findex gnus-summary-save-newsrc -Save the current number of read/marked articles in the dribble buffer -and then save the dribble buffer (@code{gnus-summary-save-newsrc}). If -given a prefix, also save the @file{.newsrc} file(s). Using this -command will make exit without updating (the @kbd{Q} command) worthless. -@end table - -@vindex gnus-exit-group-hook -@code{gnus-exit-group-hook} is called when you exit the current -group. - -@findex gnus-summary-wake-up-the-dead -@findex gnus-dead-summary-mode -@vindex gnus-kill-summary-on-exit -If you're in the habit of exiting groups, and then changing your mind -about it, you might set @code{gnus-kill-summary-on-exit} to @code{nil}. -If you do that, gnus won't kill the summary buffer when you exit it. -(Quelle surprise!) Instead it will change the name of the buffer to -something like @samp{*Dead Summary ... *} and install a minor mode -called @code{gnus-dead-summary-mode}. Now, if you switch back to this -buffer, you'll find that all keys are mapped to a function called -@code{gnus-summary-wake-up-the-dead}. So tapping any keys in a dead -summary buffer will result in a live, normal summary buffer. - -There will never be more than one dead summary buffer at any one time. - -@vindex gnus-use-cross-reference -The data on the current group will be updated (which articles you have -read, which articles you have replied to, etc.) when you exit the -summary buffer. If the @code{gnus-use-cross-reference} variable is -@code{t} (which is the default), articles that are cross-referenced to -this group and are marked as read, will also be marked as read in the -other subscribed groups they were cross-posted to. If this variable is -neither @code{nil} nor @code{t}, the article will be marked as read in -both subscribed and unsubscribed groups (@pxref{Crosspost Handling}). - - -@node Crosspost Handling -@section Crosspost Handling - -@cindex velveeta -@cindex spamming -Marking cross-posted articles as read ensures that you'll never have to -read the same article more than once. Unless, of course, somebody has -posted it to several groups separately. Posting the same article to -several groups (not cross-posting) is called @dfn{spamming}, and you are -by law required to send nasty-grams to anyone who perpetrates such a -heinous crime. You may want to try NoCeM handling to filter out spam -(@pxref{NoCeM}). - -Remember: Cross-posting is kinda ok, but posting the same article -separately to several groups is not. Massive cross-posting (aka. -@dfn{velveeta}) is to be avoided at all costs, and you can even use the -@code{gnus-summary-mail-crosspost-complaint} command to complain about -excessive crossposting (@pxref{Summary Mail Commands}). - -@cindex cross-posting -@cindex Xref -@cindex @sc{nov} -One thing that may cause Gnus to not do the cross-posting thing -correctly is if you use an @sc{nntp} server that supports @sc{xover} -(which is very nice, because it speeds things up considerably) which -does not include the @code{Xref} header in its @sc{nov} lines. This is -Evil, but all too common, alas, alack. Gnus tries to Do The Right Thing -even with @sc{xover} by registering the @code{Xref} lines of all -articles you actually read, but if you kill the articles, or just mark -them as read without reading them, Gnus will not get a chance to snoop -the @code{Xref} lines out of these articles, and will be unable to use -the cross reference mechanism. - -@cindex LIST overview.fmt -@cindex overview.fmt -To check whether your @sc{nntp} server includes the @code{Xref} header -in its overview files, try @samp{telnet your.nntp.server nntp}, -@samp{MODE READER} on @code{inn} servers, and then say @samp{LIST -overview.fmt}. This may not work, but if it does, and the last line you -get does not read @samp{Xref:full}, then you should shout and whine at -your news admin until she includes the @code{Xref} header in the -overview files. - -@vindex gnus-nov-is-evil -If you want Gnus to get the @code{Xref}s right all the time, you have to -set @code{gnus-nov-is-evil} to @code{t}, which slows things down -considerably. - -C'est la vie. - -For an alternative approach, @pxref{Duplicate Suppression}. - - -@node Duplicate Suppression -@section Duplicate Suppression - -By default, gnus tries to make sure that you don't have to read the same -article more than once by utilizing the crossposting mechanism -(@pxref{Crosspost Handling}). However, that simple and efficient -approach may not work satisfactory for some users for various reasons. - -@enumerate -@item -The @sc{nntp} server may fail to generate the @code{Xref} header. This -is evil and not very common. - -@item -The @sc{nntp} server may fail to include the @code{Xref} header in the -@file{.overview} data bases. This is evil and all too common, alas. - -@item -You may be reading the same group (or several related groups) from -different @sc{nntp} servers. - -@item -You may be getting mail that duplicates articles posted to groups. -@end enumerate - -I'm sure there are other situations where @code{Xref} handling fails as -well, but these four are the most common situations. - -If, and only if, @code{Xref} handling fails for you, then you may -consider switching on @dfn{duplicate suppression}. If you do so, Gnus -will remember the @code{Message-ID}s of all articles you have read or -otherwise marked as read, and then, as if by magic, mark them as read -all subsequent times you see them---in @emph{all} groups. Using this -mechanism is quite likely to be somewhat inefficient, but not overly -so. It's certainly preferable to reading the same articles more than -once. - -Duplicate suppression is not a very subtle instrument. It's more like a -sledge hammer than anything else. It works in a very simple -fashion---if you have marked an article as read, it adds this Message-ID -to a cache. The next time it sees this Message-ID, it will mark the -article as read with the @samp{M} mark. It doesn't care what group it -saw the article in. - -@table @code -@item gnus-suppress-duplicates -@vindex gnus-suppress-duplicates -If non-@code{nil}, suppress duplicates. - -@item gnus-save-duplicate-list -@vindex gnus-save-duplicate-list -If non-@code{nil}, save the list of duplicates to a file. This will -make startup and shutdown take longer, so the default is @code{nil}. -However, this means that only duplicate articles read in a single gnus -session are suppressed. - -@item gnus-duplicate-list-length -@vindex gnus-duplicate-list-length -This variable says how many @code{Message-ID}s to keep in the duplicate -suppression list. The default is 10000. - -@item gnus-duplicate-file -@vindex gnus-duplicate-file -The name of the file to store the duplicate suppression list in. The -default is @file{~/News/suppression}. -@end table - -If you have a tendency to stop and start gnus often, setting -@code{gnus-save-duplicate-list} to @code{t} is probably a good idea. If -you leave gnus running for weeks on end, you may have it @code{nil}. On -the other hand, saving the list makes startup and shutdown much slower, -so that means that if you stop and start gnus often, you should set -@code{gnus-save-duplicate-list} to @code{nil}. Uhm. I'll leave this up -to you to figure out, I think. - - -@node The Article Buffer -@chapter The Article Buffer -@cindex article buffer - -The articles are displayed in the article buffer, of which there is only -one. All the summary buffers share the same article buffer unless you -tell gnus otherwise. - -@menu -* Hiding Headers:: Deciding what headers should be displayed. -* Using MIME:: Pushing to mime articles as @sc{mime} messages. -* Customizing Articles:: Tailoring the look of the articles. -* Article Keymap:: Keystrokes available in the article buffer. -* Misc Article:: Other stuff. -@end menu - - -@node Hiding Headers -@section Hiding Headers -@cindex hiding headers -@cindex deleting headers - -The top section of each article is the @dfn{head}. (The rest is the -@dfn{body}, but you may have guessed that already.) - -@vindex gnus-show-all-headers -There is a lot of useful information in the head: the name of the person -who wrote the article, the date it was written and the subject of the -article. That's well and nice, but there's also lots of information -most people do not want to see---what systems the article has passed -through before reaching you, the @code{Message-ID}, the -@code{References}, etc. ad nauseum---and you'll probably want to get rid -of some of those lines. If you want to keep all those lines in the -article buffer, you can set @code{gnus-show-all-headers} to @code{t}. - -Gnus provides you with two variables for sifting headers: - -@table @code - -@item gnus-visible-headers -@vindex gnus-visible-headers -If this variable is non-@code{nil}, it should be a regular expression -that says what headers you wish to keep in the article buffer. All -headers that do not match this variable will be hidden. - -For instance, if you only want to see the name of the person who wrote -the article and the subject, you'd say: - -@lisp -(setq gnus-visible-headers "^From:\\|^Subject:") -@end lisp - -This variable can also be a list of regexps to match headers to -remain visible. - -@item gnus-ignored-headers -@vindex gnus-ignored-headers -This variable is the reverse of @code{gnus-visible-headers}. If this -variable is set (and @code{gnus-visible-headers} is @code{nil}), it -should be a regular expression that matches all lines that you want to -hide. All lines that do not match this variable will remain visible. - -For instance, if you just want to get rid of the @code{References} field -and the @code{Xref} field, you might say: - -@lisp -(setq gnus-ignored-headers "^References:\\|^Xref:") -@end lisp - -This variable can also be a list of regexps to match headers to -be removed. - -Note that if @code{gnus-visible-headers} is non-@code{nil}, this -variable will have no effect. - -@end table - -@vindex gnus-sorted-header-list -Gnus can also sort the headers for you. (It does this by default.) You -can control the sorting by setting the @code{gnus-sorted-header-list} -variable. It is a list of regular expressions that says in what order -the headers are to be displayed. - -For instance, if you want the name of the author of the article first, -and then the subject, you might say something like: - -@lisp -(setq gnus-sorted-header-list '("^From:" "^Subject:")) -@end lisp - -Any headers that are to remain visible, but are not listed in this -variable, will be displayed in random order after all the headers listed -in this variable. - -@findex gnus-article-hide-boring-headers -@vindex gnus-article-display-hook -@vindex gnus-boring-article-headers -You can hide further boring headers by entering -@code{gnus-article-hide-boring-headers} into -@code{gnus-article-display-hook}. What this function does depends on -the @code{gnus-boring-article-headers} variable. It's a list, but this -list doesn't actually contain header names. Instead is lists various -@dfn{boring conditions} that gnus can check and remove from sight. - -These conditions are: -@table @code -@item empty -Remove all empty headers. -@item followup-to -Remove the @code{Followup-To} header if it is identical to the -@code{Newsgroups} header. -@item reply-to -Remove the @code{Reply-To} header if it lists the same address as the -@code{From} header. -@item newsgroups -Remove the @code{Newsgroups} header if it only contains the current group -name. -@item date -Remove the @code{Date} header if the article is less than three days -old. -@item long-to -Remove the @code{To} header if it is very long. -@item many-to -Remove all @code{To} headers if there are more than one. -@end table - -To include the four three elements, you could say something like; - -@lisp -(setq gnus-boring-article-headers - '(empty followup-to reply-to)) -@end lisp - -This is also the default value for this variable. - - -@node Using MIME -@section Using @sc{mime} -@cindex @sc{mime} - -Mime is a standard for waving your hands through the air, aimlessly, -while people stand around yawning. - -@sc{mime}, however, is a standard for encoding your articles, aimlessly, -while all newsreaders die of fear. - -@sc{mime} may specify what character set the article uses, the encoding -of the characters, and it also makes it possible to embed pictures and -other naughty stuff in innocent-looking articles. - -@vindex gnus-show-mime -@vindex gnus-article-display-method-for-mime -@vindex gnus-strict-mime -@findex gnus-article-display-mime-message -Gnus handles @sc{mime} by pushing the articles through -@code{gnus-article-display-method-for-mime}, which is -@code{gnus-article-display-mime-message} by default. This function -calls the SEMI MIME-View program to actually do the work. For more -information on SEMI MIME-View, see its manual page (however it is not -existed yet, sorry). - -Set @code{gnus-show-mime} to @code{t} if you want to use -@sc{mime} all the time. However, if @code{gnus-strict-mime} is -non-@code{nil}, the @sc{mime} method will only be used if there are -@sc{mime} headers in the article. If you have @code{gnus-show-mime} -set, then you'll see some unfortunate display glitches in the article -buffer. These can't be avoided. - -In GNUS or Gnus, it might be best to just use the toggling functions -from the summary buffer to avoid getting nasty surprises. (For instance, -you enter the group @samp{alt.sing-a-long} and, before you know it, -@sc{mime} has decoded the sound file in the article and some horrible -sing-a-long song comes screaming out your speakers, and you can't find -the volume button, because there isn't one, and people are starting to -look at you, and you try to stop the program, but you can't, and you -can't find the program to control the volume, and everybody else in the -room suddenly decides to look at you disdainfully, and you'll feel -rather stupid.) - -Any similarity to real events and people is purely coincidental. Ahem. - -To avoid such kind of situation, gnus stops to use -@code{metamail-buffer}. So now, you can set @code{gnus-show-mime} to -non-@code{nil} every-time, then you can push button in the article -buffer when there are nobody else. - - -@node Customizing Articles -@section Customizing Articles -@cindex article customization - -@vindex gnus-article-display-hook -The @code{gnus-article-display-hook} is called after the article has -been inserted into the article buffer. It is meant to handle all -treatment of the article before it is displayed. - -@findex gnus-article-maybe-highlight -@findex gnus-article-maybe-hide-headers -By default this hook just contains -@code{gnus-article-maybe-hide-headers}, -@code{gnus-hide-boring-headers}, @code{gnus-article-treat-overstrike}, -and @code{gnus-article-maybe-highlight} (and under XEmacs, -@code{gnus-article-display-x-face}), but there are thousands, nay -millions, of functions you can put in this hook. For an overview of -functions @pxref{Article Highlighting}, @pxref{Article Hiding}, -@pxref{Article Washing}, @pxref{Article Buttons} and @pxref{Article -Date}. Note that the order of functions in this hook might affect -things, so you may have to fiddle a bit to get the desired results. - -You can, of course, write your own functions. The functions are called -from the article buffer, and you can do anything you like, pretty much. -There is no information that you have to keep in the buffer---you can -change everything. However, you shouldn't delete any headers. Instead -make them invisible if you want to make them go away. - - -@node Article Keymap -@section Article Keymap - -Most of the keystrokes in the summary buffer can also be used in the -article buffer. They should behave as if you typed them in the summary -buffer, which means that you don't actually have to have a summary -buffer displayed while reading. You can do it all from the article -buffer. - -A few additional keystrokes are available: - -@table @kbd - -@item SPACE -@kindex SPACE (Article) -@findex gnus-article-next-page -Scroll forwards one page (@code{gnus-article-next-page}). - -@item DEL -@kindex DEL (Article) -@findex gnus-article-prev-page -Scroll backwards one page (@code{gnus-article-prev-page}). - -@item C-c ^ -@kindex C-c ^ (Article) -@findex gnus-article-refer-article -If point is in the neighborhood of a @code{Message-ID} and you press -@kbd{C-c ^}, Gnus will try to get that article from the server -(@code{gnus-article-refer-article}). - -@item C-c C-m -@kindex C-c C-m (Article) -@findex gnus-article-mail -Send a reply to the address near point (@code{gnus-article-mail}). If -given a prefix, include the mail. - -@item s -@kindex s (Article) -@findex gnus-article-show-summary -Reconfigure the buffers so that the summary buffer becomes visible -(@code{gnus-article-show-summary}). - -@item ? -@kindex ? (Article) -@findex gnus-article-describe-briefly -Give a very brief description of the available keystrokes -(@code{gnus-article-describe-briefly}). - -@item TAB -@kindex TAB (Article) -@findex gnus-article-next-button -Go to the next button, if any (@code{gnus-article-next-button}). This -only makes sense if you have buttonizing turned on. - -@item M-TAB -@kindex M-TAB (Article) -@findex gnus-article-prev-button -Go to the previous button, if any (@code{gnus-article-prev-button}). - -@end table - - -@node Misc Article -@section Misc Article - -@table @code - -@item gnus-single-article-buffer -@vindex gnus-single-article-buffer -If non-@code{nil}, use the same article buffer for all the groups. -(This is the default.) If @code{nil}, each group will have its own -article buffer. - -@vindex gnus-article-prepare-hook -@item gnus-article-prepare-hook -This hook is called right after the article has been inserted into the -article buffer. It is mainly intended for functions that do something -depending on the contents; it should probably not be used for changing -the contents of the article buffer. - -@vindex gnus-article-display-hook -@item gnus-article-display-hook -This hook is called as the last thing when displaying an article, and is -intended for modifying the contents of the buffer, doing highlights, -hiding headers, and the like. - -@item gnus-article-mode-hook -@vindex gnus-article-mode-hook -Hook called in article mode buffers. - -@item gnus-article-mode-syntax-table -@vindex gnus-article-mode-syntax-table -Syntax table used in article buffers. It is initialized from -@code{text-mode-syntax-table}. - -@vindex gnus-article-mode-line-format -@item gnus-article-mode-line-format -This variable is a format string along the same lines as -@code{gnus-summary-mode-line-format} (@pxref{Mode Line Formatting}). It -accepts the same format specifications as that variable, with one -extension: - -@table @samp -@item w -The @dfn{wash status} of the article. This is a short string with one -character for each possible article wash operation that may have been -performed. -@end table - -@vindex gnus-break-pages - -@item gnus-break-pages -Controls whether @dfn{page breaking} is to take place. If this variable -is non-@code{nil}, the articles will be divided into pages whenever a -page delimiter appears in the article. If this variable is @code{nil}, -paging will not be done. - -@item gnus-page-delimiter -@vindex gnus-page-delimiter -This is the delimiter mentioned above. By default, it is @samp{^L} -(formfeed). -@end table - - -@node Composing Messages -@chapter Composing Messages -@cindex composing messages -@cindex messages -@cindex mail -@cindex sending mail -@cindex reply -@cindex followup -@cindex post - -@kindex C-c C-c (Post) -All commands for posting and mailing will put you in a message buffer -where you can edit the article all you like, before you send the article -by pressing @kbd{C-c C-c}. @xref{Top, , Top, message, The Message -Manual}. If you are in a foreign news group, and you wish to post the -article using the foreign server, you can give a prefix to @kbd{C-c C-c} -to make gnus try to post using the foreign server. - -@menu -* Mail:: Mailing and replying. -* Post:: Posting and following up. -* Posting Server:: What server should you post via? -* Mail and Post:: Mailing and posting at the same time. -* Archived Messages:: Where gnus stores the messages you've sent. -* Posting Styles:: An easier way to specify who you are. -* Drafts:: Postponing messages and rejected messages. -* Rejected Articles:: What happens if the server doesn't like your article? -@end menu - -Also see @pxref{Canceling and Superseding} for information on how to -remove articles you shouldn't have posted. - - -@node Mail -@section Mail - -Variables for customizing outgoing mail: - -@table @code -@item gnus-uu-digest-headers -@vindex gnus-uu-digest-headers -List of regexps to match headers included in digested messages. The -headers will be included in the sequence they are matched. - -@item gnus-add-to-list -@vindex gnus-add-to-list -If non-@code{nil}, add a @code{to-list} group parameter to mail groups -that have none when you do a @kbd{a}. - -@end table - - -@node Post -@section Post - -Variables for composing news articles: - -@table @code -@item gnus-sent-message-ids-file -@vindex gnus-sent-message-ids-file -Gnus will keep a @code{Message-ID} history file of all the mails it has -sent. If it discovers that it has already sent a mail, it will ask the -user whether to re-send the mail. (This is primarily useful when -dealing with @sc{soup} packets and the like where one is apt to send the -same packet multiple times.) This variable says what the name of this -history file is. It is @file{~/News/Sent-Message-IDs} by default. Set -this variable to @code{nil} if you don't want gnus to keep a history -file. - -@item gnus-sent-message-ids-length -@vindex gnus-sent-message-ids-length -This variable says how many @code{Message-ID}s to keep in the history -file. It is 1000 by default. - -@end table - - -@node Posting Server -@section Posting Server - -When you press those magical @kbd{C-c C-c} keys to ship off your latest -(extremely intelligent, of course) article, where does it go? - -Thank you for asking. I hate you. - -@vindex gnus-post-method - -It can be quite complicated. Normally, gnus will use the same native -server. However. If your native server doesn't allow posting, just -reading, you probably want to use some other server to post your -(extremely intelligent and fabulously interesting) articles. You can -then set the @code{gnus-post-method} to some other method: - -@lisp -(setq gnus-post-method '(nnspool "")) -@end lisp - -Now, if you've done this, and then this server rejects your article, or -this server is down, what do you do then? To override this variable you -can use a non-zero prefix to the @kbd{C-c C-c} command to force using -the ``current'' server for posting. - -If you give a zero prefix (i.e., @kbd{C-u 0 C-c C-c}) to that command, -gnus will prompt you for what method to use for posting. - -You can also set @code{gnus-post-method} to a list of select methods. -If that's the case, gnus will always prompt you for what method to use -for posting. - -Finally, if you want to always post using the same select method as -you're reading from (which might be convenient if you're reading lots of -groups from different private servers), you can set this variable to -@code{current}. - - -@node Mail and Post -@section Mail and Post - -Here's a list of variables relevant to both mailing and -posting: - -@table @code -@item gnus-mailing-list-groups -@findex gnus-mailing-list-groups -@cindex mailing lists - -If your news server offers groups that are really mailing lists -gatewayed to the @sc{nntp} server, you can read those groups without -problems, but you can't post/followup to them without some difficulty. -One solution is to add a @code{to-address} to the group parameters -(@pxref{Group Parameters}). An easier thing to do is set the -@code{gnus-mailing-list-groups} to a regexp that matches the groups that -really are mailing lists. Then, at least, followups to the mailing -lists will work most of the time. Posting to these groups (@kbd{a}) is -still a pain, though. - -@end table - -You may want to do spell-checking on messages that you send out. Or, if -you don't want to spell-check by hand, you could add automatic -spell-checking via the @code{ispell} package: - -@cindex ispell -@findex ispell-message -@lisp -(add-hook 'message-send-hook 'ispell-message) -@end lisp - - -@node Archived Messages -@section Archived Messages -@cindex archived messages -@cindex sent messages - -Gnus provides a few different methods for storing the mail and news you -send. The default method is to use the @dfn{archive virtual server} to -store the messages. If you want to disable this completely, the -@code{gnus-message-archive-group} variable should be @code{nil}, which -is the default. - -@vindex gnus-message-archive-method -@code{gnus-message-archive-method} says what virtual server gnus is to -use to store sent messages. The default is: - -@lisp -(nnfolder "archive" - (nnfolder-directory "~/Mail/archive") - (nnfolder-active-file "~/Mail/archive/active") - (nnfolder-get-new-mail nil) - (nnfolder-inhibit-expiry t)) -@end lisp - -You can, however, use any mail select method (@code{nnml}, -@code{nnmbox}, etc.). @code{nnfolder} is a quite likeable select method -for doing this sort of thing, though. If you don't like the default -directory chosen, you could say something like: - -@lisp -(setq gnus-message-archive-method - '(nnfolder "archive" - (nnfolder-inhibit-expiry t) - (nnfolder-active-file "~/News/sent-mail/active") - (nnfolder-directory "~/News/sent-mail/"))) -@end lisp - -@vindex gnus-message-archive-group -@cindex Gcc -Gnus will insert @code{Gcc} headers in all outgoing messages that point -to one or more group(s) on that server. Which group to use is -determined by the @code{gnus-message-archive-group} variable. - -This variable can be used to do the following: - -@itemize @bullet -@item a string -Messages will be saved in that group. -@item a list of strings -Messages will be saved in all those groups. -@item an alist of regexps, functions and forms -When a key ``matches'', the result is used. -@item @code{nil} -No message archiving will take place. This is the default. -@end itemize - -Let's illustrate: - -Just saving to a single group called @samp{MisK}: -@lisp -(setq gnus-message-archive-group "MisK") -@end lisp - -Saving to two groups, @samp{MisK} and @samp{safe}: -@lisp -(setq gnus-message-archive-group '("MisK" "safe")) -@end lisp - -Save to different groups based on what group you are in: -@lisp -(setq gnus-message-archive-group - '(("^alt" "sent-to-alt") - ("mail" "sent-to-mail") - (".*" "sent-to-misc"))) -@end lisp - -More complex stuff: -@lisp -(setq gnus-message-archive-group - '((if (message-news-p) - "misc-news" - "misc-mail"))) -@end lisp - -How about storing all news messages in one file, but storing all mail -messages in one file per month: - -@lisp -(setq gnus-message-archive-group - '((if (message-news-p) - "misc-news" - (concat "mail." (format-time-string - "%Y-%m" (current-time)))))) -@end lisp - -(XEmacs 19.13 doesn't have @code{format-time-string}, so you'll have to -use a different value for @code{gnus-message-archive-group} there.) - -Now, when you send a message off, it will be stored in the appropriate -group. (If you want to disable storing for just one particular message, -you can just remove the @code{Gcc} header that has been inserted.) The -archive group will appear in the group buffer the next time you start -gnus, or the next time you press @kbd{F} in the group buffer. You can -enter it and read the articles in it just like you'd read any other -group. If the group gets really big and annoying, you can simply rename -if (using @kbd{G r} in the group buffer) to something -nice---@samp{misc-mail-september-1995}, or whatever. New messages will -continue to be stored in the old (now empty) group. - -That's the default method of archiving sent messages. Gnus offers a -different way for the people who don't like the default method. In that -case you should set @code{gnus-message-archive-group} to @code{nil}; -this will disable archiving. - -@table @code -@item gnus-outgoing-message-group -@vindex gnus-outgoing-message-group -All outgoing messages will be put in this group. If you want to store -all your outgoing mail and articles in the group @samp{nnml:archive}, -you set this variable to that value. This variable can also be a list of -group names. - -If you want to have greater control over what group to put each -message in, you can set this variable to a function that checks the -current newsgroup name and then returns a suitable group name (or list -of names). - -This variable can be used instead of @code{gnus-message-archive-group}, -but the latter is the preferred method. -@end table - - -@node Posting Styles -@section Posting Styles -@cindex posting styles -@cindex styles - -All them variables, they make my head swim. - -So what if you want a different @code{Organization} and signature based -on what groups you post to? And you post both from your home machine -and your work machine, and you want different @code{From} lines, and so -on? - -@vindex gnus-posting-styles -One way to do stuff like that is to write clever hooks that change the -variables you need to have changed. That's a bit boring, so somebody -came up with the bright idea of letting the user specify these things in -a handy alist. Here's an example of a @code{gnus-posting-styles} -variable: - -@lisp -((".*" - (signature "Peace and happiness") - (organization "What me?")) - ("^comp" - (signature "Death to everybody")) - ("comp.emacs.i-love-it" - (organization "Emacs is it"))) -@end lisp - -As you might surmise from this example, this alist consists of several -@dfn{styles}. Each style will be applicable if the first element -``matches'', in some form or other. The entire alist will be iterated -over, from the beginning towards the end, and each match will be -applied, which means that attributes in later styles that match override -the same attributes in earlier matching styles. So -@samp{comp.programming.literate} will have the @samp{Death to everybody} -signature and the @samp{What me?} @code{Organization} header. - -The first element in each style is called the @code{match}. If it's a -string, then Gnus will try to regexp match it against the group name. -If it's a function symbol, that function will be called with no -arguments. If it's a variable symbol, then the variable will be -referenced. If it's a list, then that list will be @code{eval}ed. In -any case, if this returns a non-@code{nil} value, then the style is said -to @dfn{match}. - -Each style may contain a arbitrary amount of @dfn{attributes}. Each -attribute consists of a @var{(name . value)} pair. The attribute name -can be one of @code{signature}, @code{signature-file}, -@code{organization}, @code{address}, @code{name} or @code{body}. The -attribute name can also be a string. In that case, this will be used as -a header name, and the value will be inserted in the headers of the -article. - -The attribute value can be a string (used verbatim), a function (the -return value will be used), a variable (its value will be used) or a -list (it will be @code{eval}ed and the return value will be used). - -If you wish to check whether the message you are about to compose is -meant to be a news article or a mail message, you can check the values -of the two dynamically bound variables @code{message-this-is-news} and -@code{message-this-is-mail}. - -@vindex message-this-is-mail -@vindex message-this-is-news - -So here's a new example: - -@lisp -(setq gnus-posting-styles - '((".*" - (signature-file "~/.signature") - (name "User Name") - ("X-Home-Page" (getenv "WWW_HOME")) - (organization "People's Front Against MWM")) - ("^rec.humor" - (signature my-funny-signature-randomizer)) - ((equal (system-name) "gnarly") - (signature my-quote-randomizer)) - (message-this-is-news - (signature my-news-signature)) - (posting-from-work-p - (signature-file "~/.work-signature") - (address "user@@bar.foo") - (body "You are fired.\n\nSincerely, your boss.") - (organization "Important Work, Inc")) - ("^nn.+:" - (signature-file "~/.mail-signature")))) -@end lisp - - -@node Drafts -@section Drafts -@cindex drafts - -If you are writing a message (mail or news) and suddenly remember that -you have a steak in the oven (or some pesto in the food processor, you -craaazy vegetarians), you'll probably wish there was a method to save -the message you are writing so that you can continue editing it some -other day, and send it when you feel its finished. - -Well, don't worry about it. Whenever you start composing a message of -some sort using the gnus mail and post commands, the buffer you get will -automatically associate to an article in a special @dfn{draft} group. -If you save the buffer the normal way (@kbd{C-x C-s}, for instance), the -article will be saved there. (Auto-save files also go to the draft -group.) - -@cindex nndraft -@vindex nndraft-directory -The draft group is a special group (which is implemented as an -@code{nndraft} group, if you absolutely have to know) called -@samp{nndraft:drafts}. The variable @code{nndraft-directory} says where -@code{nndraft} is to store its files. What makes this group special is -that you can't tick any articles in it or mark any articles as -read---all articles in the group are permanently unread. - -If the group doesn't exist, it will be created and you'll be subscribed -to it. The only way to make it disappear from the Group buffer is to -unsubscribe it. - -@c @findex gnus-dissociate-buffer-from-draft -@c @kindex C-c M-d (Mail) -@c @kindex C-c M-d (Post) -@c @findex gnus-associate-buffer-with-draft -@c @kindex C-c C-d (Mail) -@c @kindex C-c C-d (Post) -@c If you're writing some super-secret message that you later want to -@c encode with PGP before sending, you may wish to turn the auto-saving -@c (and association with the draft group) off. You never know who might be -@c interested in reading all your extremely valuable and terribly horrible -@c and interesting secrets. The @kbd{C-c M-d} -@c (@code{gnus-dissociate-buffer-from-draft}) command does that for you. -@c If you change your mind and want to turn the auto-saving back on again, -@c @kbd{C-c C-d} (@code{gnus-associate-buffer-with-draft} does that. -@c -@c @vindex gnus-use-draft -@c To leave association with the draft group off by default, set -@c @code{gnus-use-draft} to @code{nil}. It is @code{t} by default. - -@findex gnus-draft-edit-message -@kindex D e (Draft) -When you want to continue editing the article, you simply enter the -draft group and push @kbd{D e} (@code{gnus-draft-edit-message}) to do -that. You will be placed in a buffer where you left off. - -Rejected articles will also be put in this draft group (@pxref{Rejected -Articles}). - -@findex gnus-draft-send-all-messages -@findex gnus-draft-send-message -If you have lots of rejected messages you want to post (or mail) without -doing further editing, you can use the @kbd{D s} command -(@code{gnus-draft-send-message}). This command understands the -process/prefix convention (@pxref{Process/Prefix}). The @kbd{D S} -command (@code{gnus-draft-send-all-messages}) will ship off all messages -in the buffer. - -If you have some messages that you wish not to send, you can use the -@kbd{D t} (@code{gnus-draft-toggle-sending}) command to mark the message -as unsendable. This is a toggling command. - - -@node Rejected Articles -@section Rejected Articles -@cindex rejected articles - -Sometimes a news server will reject an article. Perhaps the server -doesn't like your face. Perhaps it just feels miserable. Perhaps -@emph{there be demons}. Perhaps you have included too much cited text. -Perhaps the disk is full. Perhaps the server is down. - -These situations are, of course, totally beyond the control of gnus. -(Gnus, of course, loves the way you look, always feels great, has angels -fluttering around inside of it, doesn't care about how much cited text -you include, never runs full and never goes down.) So gnus saves these -articles until some later time when the server feels better. - -The rejected articles will automatically be put in a special draft group -(@pxref{Drafts}). When the server comes back up again, you'd then -typically enter that group and send all the articles off. - - -@node Select Methods -@chapter Select Methods -@cindex foreign groups -@cindex select methods - -A @dfn{foreign group} is a group not read by the usual (or -default) means. It could be, for instance, a group from a different -@sc{nntp} server, it could be a virtual group, or it could be your own -personal mail group. - -A foreign group (or any group, really) is specified by a @dfn{name} and -a @dfn{select method}. To take the latter first, a select method is a -list where the first element says what backend to use (e.g. @code{nntp}, -@code{nnspool}, @code{nnml}) and the second element is the @dfn{server -name}. There may be additional elements in the select method, where the -value may have special meaning for the backend in question. - -One could say that a select method defines a @dfn{virtual server}---so -we do just that (@pxref{The Server Buffer}). - -The @dfn{name} of the group is the name the backend will recognize the -group as. - -For instance, the group @samp{soc.motss} on the @sc{nntp} server -@samp{some.where.edu} will have the name @samp{soc.motss} and select -method @code{(nntp "some.where.edu")}. Gnus will call this group -@samp{nntp+some.where.edu:soc.motss}, even though the @code{nntp} -backend just knows this group as @samp{soc.motss}. - -The different methods all have their peculiarities, of course. - -@menu -* The Server Buffer:: Making and editing virtual servers. -* Getting News:: Reading USENET news with Gnus. -* Getting Mail:: Reading your personal mail with Gnus. -* Other Sources:: Reading directories, files, SOUP packets. -* Combined Groups:: Combining groups into one group. -* Gnus Unplugged:: Reading news and mail offline. -@end menu - - -@node The Server Buffer -@section The Server Buffer - -Traditionally, a @dfn{server} is a machine or a piece of software that -one connects to, and then requests information from. Gnus does not -connect directly to any real servers, but does all transactions through -one backend or other. But that's just putting one layer more between -the actual media and Gnus, so we might just as well say that each -backend represents a virtual server. - -For instance, the @code{nntp} backend may be used to connect to several -different actual @sc{nntp} servers, or, perhaps, to many different ports -on the same actual @sc{nntp} server. You tell Gnus which backend to -use, and what parameters to set by specifying a @dfn{select method}. - -These select method specifications can sometimes become quite -complicated---say, for instance, that you want to read from the -@sc{nntp} server @samp{news.funet.fi} on port number 13, which -hangs if queried for @sc{nov} headers and has a buggy select. Ahem. -Anyways, if you had to specify that for each group that used this -server, that would be too much work, so Gnus offers a way of naming -select methods, which is what you do in the server buffer. - -To enter the server buffer, use the @kbd{^} -(@code{gnus-group-enter-server-mode}) command in the group buffer. - -@menu -* Server Buffer Format:: You can customize the look of this buffer. -* Server Commands:: Commands to manipulate servers. -* Example Methods:: Examples server specifications. -* Creating a Virtual Server:: An example session. -* Server Variables:: Which variables to set. -* Servers and Methods:: You can use server names as select methods. -* Unavailable Servers:: Some servers you try to contact may be down. -@end menu - -@vindex gnus-server-mode-hook -@code{gnus-server-mode-hook} is run when creating the server buffer. - - -@node Server Buffer Format -@subsection Server Buffer Format -@cindex server buffer format - -@vindex gnus-server-line-format -You can change the look of the server buffer lines by changing the -@code{gnus-server-line-format} variable. This is a @code{format}-like -variable, with some simple extensions: - -@table @samp - -@item h -How the news is fetched---the backend name. - -@item n -The name of this server. - -@item w -Where the news is to be fetched from---the address. - -@item s -The opened/closed/denied status of the server. -@end table - -@vindex gnus-server-mode-line-format -The mode line can also be customized by using the -@code{gnus-server-mode-line-format} variable (@pxref{Mode Line -Formatting}). The following specs are understood: - -@table @samp -@item S -Server name. - -@item M -Server method. -@end table - -Also @pxref{Formatting Variables}. - - -@node Server Commands -@subsection Server Commands -@cindex server commands - -@table @kbd - -@item a -@kindex a (Server) -@findex gnus-server-add-server -Add a new server (@code{gnus-server-add-server}). - -@item e -@kindex e (Server) -@findex gnus-server-edit-server -Edit a server (@code{gnus-server-edit-server}). - -@item SPACE -@kindex SPACE (Server) -@findex gnus-server-read-server -Browse the current server (@code{gnus-server-read-server}). - -@item q -@kindex q (Server) -@findex gnus-server-exit -Return to the group buffer (@code{gnus-server-exit}). - -@item k -@kindex k (Server) -@findex gnus-server-kill-server -Kill the current server (@code{gnus-server-kill-server}). - -@item y -@kindex y (Server) -@findex gnus-server-yank-server -Yank the previously killed server (@code{gnus-server-yank-server}). - -@item c -@kindex c (Server) -@findex gnus-server-copy-server -Copy the current server (@code{gnus-server-copy-server}). - -@item l -@kindex l (Server) -@findex gnus-server-list-servers -List all servers (@code{gnus-server-list-servers}). - -@item s -@kindex s (Server) -@findex gnus-server-scan-server -Request that the server scan its sources for new articles -(@code{gnus-server-scan-server}). This is mainly sensible with mail -servers. - -@item g -@kindex g (Server) -@findex gnus-server-regenerate-server -Request that the server regenerate all its data structures -(@code{gnus-server-regenerate-server}). This can be useful if you have -a mail backend that has gotten out of synch. - -@end table - - -@node Example Methods -@subsection Example Methods - -Most select methods are pretty simple and self-explanatory: - -@lisp -(nntp "news.funet.fi") -@end lisp - -Reading directly from the spool is even simpler: - -@lisp -(nnspool "") -@end lisp - -As you can see, the first element in a select method is the name of the -backend, and the second is the @dfn{address}, or @dfn{name}, if you -will. - -After these two elements, there may be an arbitrary number of -@var{(variable form)} pairs. - -To go back to the first example---imagine that you want to read from -port 15 on that machine. This is what the select method should -look like then: - -@lisp -(nntp "news.funet.fi" (nntp-port-number 15)) -@end lisp - -You should read the documentation to each backend to find out what -variables are relevant, but here's an @code{nnmh} example: - -@code{nnmh} is a mail backend that reads a spool-like structure. Say -you have two structures that you wish to access: One is your private -mail spool, and the other is a public one. Here's the possible spec for -your private mail: - -@lisp -(nnmh "private" (nnmh-directory "~/private/mail/")) -@end lisp - -(This server is then called @samp{private}, but you may have guessed -that.) - -Here's the method for a public spool: - -@lisp -(nnmh "public" - (nnmh-directory "/usr/information/spool/") - (nnmh-get-new-mail nil)) -@end lisp - -If you are behind a firewall and only have access to the @sc{nntp} -server from the firewall machine, you can instruct Gnus to @code{rlogin} -on the firewall machine and telnet from there to the @sc{nntp} server. -Doing this can be rather fiddly, but your virtual server definition -should probably look something like this: - -@lisp -(nntp "firewall" - (nntp-address "the.firewall.machine") - (nntp-open-connection-function nntp-open-rlogin) - (nntp-end-of-line "\n") - (nntp-rlogin-parameters - ("telnet" "the.real.nntp.host" "nntp"))) -@end lisp - -If you want to use the wonderful @code{ssh} program to provide a -compressed connection over the modem line, you could create a virtual -server that would look something like this: - -@lisp -(nntp "news" - (nntp-address "copper.uio.no") - (nntp-rlogin-program "ssh") - (nntp-open-connection-function nntp-open-rlogin) - (nntp-end-of-line "\n") - (nntp-rlogin-parameters - ("telnet" "news.uio.no" "nntp"))) -@end lisp - -This means that you have to have set up @code{ssh-agent} correctly to -provide automatic authorization, of course. And to get a compressed -connection, you have to have the @samp{Compression} option in the -@code{ssh} @file{config} file. - - -@node Creating a Virtual Server -@subsection Creating a Virtual Server - -If you're saving lots of articles in the cache by using persistent -articles, you may want to create a virtual server to read the cache. - -First you need to add a new server. The @kbd{a} command does that. It -would probably be best to use @code{nnspool} to read the cache. You -could also use @code{nnml} or @code{nnmh}, though. - -Type @kbd{a nnspool RET cache RET}. - -You should now have a brand new @code{nnspool} virtual server called -@samp{cache}. You now need to edit it to have the right definitions. -Type @kbd{e} to edit the server. You'll be entered into a buffer that -will contain the following: - -@lisp -(nnspool "cache") -@end lisp - -Change that to: - -@lisp -(nnspool "cache" - (nnspool-spool-directory "~/News/cache/") - (nnspool-nov-directory "~/News/cache/") - (nnspool-active-file "~/News/cache/active")) -@end lisp - -Type @kbd{C-c C-c} to return to the server buffer. If you now press -@kbd{RET} over this virtual server, you should be entered into a browse -buffer, and you should be able to enter any of the groups displayed. - - -@node Server Variables -@subsection Server Variables - -One sticky point when defining variables (both on backends and in Emacs -in general) is that some variables are typically initialized from other -variables when the definition of the variables is being loaded. If you -change the "base" variable after the variables have been loaded, you -won't change the "derived" variables. - -This typically affects directory and file variables. For instance, -@code{nnml-directory} is @file{~/Mail/} by default, and all @code{nnml} -directory variables are initialized from that variable, so -@code{nnml-active-file} will be @file{~/Mail/active}. If you define a -new virtual @code{nnml} server, it will @emph{not} suffice to set just -@code{nnml-directory}---you have to explicitly set all the file -variables to be what you want them to be. For a complete list of -variables for each backend, see each backend's section later in this -manual, but here's an example @code{nnml} definition: - -@lisp -(nnml "public" - (nnml-directory "~/my-mail/") - (nnml-active-file "~/my-mail/active") - (nnml-newsgroups-file "~/my-mail/newsgroups")) -@end lisp - - -@node Servers and Methods -@subsection Servers and Methods - -Wherever you would normally use a select method -(e.g. @code{gnus-secondary-select-method}, in the group select method, -when browsing a foreign server) you can use a virtual server name -instead. This could potentially save lots of typing. And it's nice all -over. - - -@node Unavailable Servers -@subsection Unavailable Servers - -If a server seems to be unreachable, Gnus will mark that server as -@code{denied}. That means that any subsequent attempt to make contact -with that server will just be ignored. ``It can't be opened,'' Gnus -will tell you, without making the least effort to see whether that is -actually the case or not. - -That might seem quite naughty, but it does make sense most of the time. -Let's say you have 10 groups subscribed to on server -@samp{nephelococcygia.com}. This server is located somewhere quite far -away from you and the machine is quite slow, so it takes 1 minute just -to find out that it refuses connection to you today. If Gnus were to -attempt to do that 10 times, you'd be quite annoyed, so Gnus won't -attempt to do that. Once it has gotten a single ``connection refused'', -it will regard that server as ``down''. - -So, what happens if the machine was only feeling unwell temporarily? -How do you test to see whether the machine has come up again? - -You jump to the server buffer (@pxref{The Server Buffer}) and poke it -with the following commands: - -@table @kbd - -@item O -@kindex O (Server) -@findex gnus-server-open-server -Try to establish connection to the server on the current line -(@code{gnus-server-open-server}). - -@item C -@kindex C (Server) -@findex gnus-server-close-server -Close the connection (if any) to the server -(@code{gnus-server-close-server}). - -@item D -@kindex D (Server) -@findex gnus-server-deny-server -Mark the current server as unreachable -(@code{gnus-server-deny-server}). - -@item M-o -@kindex M-o (Server) -@findex gnus-server-open-all-servers -Open the connections to all servers in the buffer -(@code{gnus-server-open-all-servers}). - -@item M-c -@kindex M-c (Server) -@findex gnus-server-close-all-servers -Close the connections to all servers in the buffer -(@code{gnus-server-close-all-servers}). - -@item R -@kindex R (Server) -@findex gnus-server-remove-denials -Remove all marks to whether Gnus was denied connection from any servers -(@code{gnus-server-remove-denials}). - -@end table - - -@node Getting News -@section Getting News -@cindex reading news -@cindex news backends - -A newsreader is normally used for reading news. Gnus currently provides -only two methods of getting news---it can read from an @sc{nntp} server, -or it can read from a local spool. - -@menu -* NNTP:: Reading news from an @sc{nntp} server. -* News Spool:: Reading news from the local spool. -@end menu - - -@node NNTP -@subsection @sc{nntp} -@cindex nntp - -Subscribing to a foreign group from an @sc{nntp} server is rather easy. -You just specify @code{nntp} as method and the address of the @sc{nntp} -server as the, uhm, address. - -If the @sc{nntp} server is located at a non-standard port, setting the -third element of the select method to this port number should allow you -to connect to the right port. You'll have to edit the group info for -that (@pxref{Foreign Groups}). - -The name of the foreign group can be the same as a native group. In -fact, you can subscribe to the same group from as many different servers -you feel like. There will be no name collisions. - -The following variables can be used to create a virtual @code{nntp} -server: - -@table @code - -@item nntp-server-opened-hook -@vindex nntp-server-opened-hook -@cindex @sc{mode reader} -@cindex authinfo -@cindex authentification -@cindex nntp authentification -@findex nntp-send-authinfo -@findex nntp-send-mode-reader -is run after a connection has been made. It can be used to send -commands to the @sc{nntp} server after it has been contacted. By -default it sends the command @code{MODE READER} to the server with the -@code{nntp-send-mode-reader} function. This function should always be -present in this hook. - -@item nntp-authinfo-function -@vindex nntp-authinfo-function -@findex nntp-send-authinfo -@vindex nntp-authinfo-file -This function will be used to send @samp{AUTHINFO} to the @sc{nntp} -server. The default function is @code{nntp-send-authinfo}, which looks -through your @file{~/.authinfo} (or whatever you've set the -@code{nntp-authinfo-file} variable to) for applicable entries. If none -are found, it will prompt you for a login name and a password. The -format of the @file{~/.authinfo} file is (almost) the same as the -@code{ftp} @file{~/.netrc} file, which is defined in the @code{ftp} -manual page, but here are the salient facts: - -@enumerate -@item -The file contains one or more line, each of which define one server. - -@item -Each line may contain an arbitrary number of token/value pairs. The -valid tokens include @samp{machine}, @samp{login}, @samp{password}, -@samp{default} and @samp{force}. (The latter is not a valid -@file{.netrc}/@code{ftp} token, which is the only way the -@file{.authinfo} file format deviates from the @file{.netrc} file -format.) - -@end enumerate - -Here's an example file: - -@example -machine news.uio.no login larsi password geheimnis -machine nntp.ifi.uio.no login larsi force yes -@end example - -The token/value pairs may appear in any order; @samp{machine} doesn't -have to be first, for instance. - -In this example, both login name and password have been supplied for the -former server, while the latter has only the login name listed, and the -user will be prompted for the password. The latter also has the -@samp{force} tag, which means that the authinfo will be sent to the -@var{nntp} server upon connection; the default (i.e., when there is not -@samp{force} tag) is to not send authinfo to the @var{nntp} server -until the @var{nntp} server asks for it. - -You can also add @samp{default} lines that will apply to all servers -that don't have matching @samp{machine} lines. - -@example -default force yes -@end example - -This will force sending @samp{AUTHINFO} commands to all servers not -previously mentioned. - -Remember to not leave the @file{~/.authinfo} file world-readable. - -@item nntp-server-action-alist -@vindex nntp-server-action-alist -This is a list of regexps to match on server types and actions to be -taken when matches are made. For instance, if you want Gnus to beep -every time you connect to innd, you could say something like: - -@lisp -(setq nntp-server-action-alist - '(("innd" (ding)))) -@end lisp - -You probably don't want to do that, though. - -The default value is - -@lisp -'(("nntpd 1\\.5\\.11t" - (remove-hook 'nntp-server-opened-hook 'nntp-send-mode-reader))) -@end lisp - -This ensures that Gnus doesn't send the @code{MODE READER} command to -nntpd 1.5.11t, since that command chokes that server, I've been told. - -@item nntp-maximum-request -@vindex nntp-maximum-request -If the @sc{nntp} server doesn't support @sc{nov} headers, this backend -will collect headers by sending a series of @code{head} commands. To -speed things up, the backend sends lots of these commands without -waiting for reply, and then reads all the replies. This is controlled -by the @code{nntp-maximum-request} variable, and is 400 by default. If -your network is buggy, you should set this to 1. - -@item nntp-connection-timeout -@vindex nntp-connection-timeout -If you have lots of foreign @code{nntp} groups that you connect to -regularly, you're sure to have problems with @sc{nntp} servers not -responding properly, or being too loaded to reply within reasonable -time. This is can lead to awkward problems, which can be helped -somewhat by setting @code{nntp-connection-timeout}. This is an integer -that says how many seconds the @code{nntp} backend should wait for a -connection before giving up. If it is @code{nil}, which is the default, -no timeouts are done. - -@c @item nntp-command-timeout -@c @vindex nntp-command-timeout -@c @cindex PPP connections -@c @cindex dynamic IP addresses -@c If you're running Gnus on a machine that has a dynamically assigned -@c address, Gnus may become confused. If the address of your machine -@c changes after connecting to the @sc{nntp} server, Gnus will simply sit -@c waiting forever for replies from the server. To help with this -@c unfortunate problem, you can set this command to a number. Gnus will -@c then, if it sits waiting for a reply from the server longer than that -@c number of seconds, shut down the connection, start a new one, and resend -@c the command. This should hopefully be transparent to the user. A -@c likely number is 30 seconds. -@c -@c @item nntp-retry-on-break -@c @vindex nntp-retry-on-break -@c If this variable is non-@code{nil}, you can also @kbd{C-g} if Gnus -@c hangs. This will have much the same effect as the command timeout -@c described above. - -@item nntp-server-hook -@vindex nntp-server-hook -This hook is run as the last step when connecting to an @sc{nntp} -server. - -@findex nntp-open-rlogin -@findex nntp-open-telnet -@findex nntp-open-network-stream -@item nntp-open-connection-function -@vindex nntp-open-connection-function -This function is used to connect to the remote system. Four pre-made -functions are supplied: - -@table @code -@item nntp-open-network-stream -This is the default, and simply connects to some port or other on the -remote system. - -@item nntp-open-rlogin -Does an @samp{rlogin} on the -remote system, and then does a @samp{telnet} to the @sc{nntp} server -available there. - -@code{nntp-open-rlogin}-related variables: - -@table @code - -@item nntp-rlogin-program -@vindex nntp-rlogin-program -Program used to log in on remote machines. The default is @samp{rsh}, -but @samp{ssh} is a popular alternative. - -@item nntp-rlogin-parameters -@vindex nntp-rlogin-parameters -This list will be used as the parameter list given to @code{rsh}. - -@item nntp-rlogin-user-name -@vindex nntp-rlogin-user-name -User name on the remote system. - -@end table - -@item nntp-open-telnet -Does a @samp{telnet} to the remote system and then another @samp{telnet} -to get to the @sc{nntp} server. - -@code{nntp-open-telnet}-related variables: - -@table @code -@item nntp-telnet-command -@vindex nntp-telnet-command -Command used to start @code{telnet}. - -@item nntp-telnet-switches -@vindex nntp-telnet-switches -List of strings to be used as the switches to the @code{telnet} command. - -@item nntp-telnet-user-name -@vindex nntp-telnet-user-name -User name for log in on the remote system. - -@item nntp-telnet-passwd -@vindex nntp-telnet-passwd -Password to use when logging in. - -@item nntp-telnet-parameters -@vindex nntp-telnet-parameters -A list of strings executed as a command after logging in -via @code{telnet}. - -@item nntp-telnet-shell-prompt -@vindex nntp-telnet-shell-prompt -Regexp matching the shell prompt on the remote machine. The default is -@samp{bash\\|\$ *\r?$\\|> *\r?}. - -@item nntp-open-telnet-envuser -@vindex nntp-open-telnet-envuser -If non-@code{nil}, the @code{telnet} session (client and server both) -will support the @code{ENVIRON} option and not prompt for login name. -This works for Solaris @code{telnet}, for instance. - -@end table - -@findex nntp-open-ssl-stream -@item nntp-open-ssl-stream -Opens a connection to a server over a @dfn{secure} channel. To use this -you must have SSLay installed -(@file{ftp://ftp.psy.uq.oz.au/pub/Crypto/SSL}, and you also need -@file{ssl.el} (from the W3 distributeion, for instance). You then -define a server as follows: - -@lisp -;; Type `C-c C-c' after you've finished editing. -;; -;; "snews" is port 563 and is predefined in our /etc/services -;; -(nntp "snews.bar.com" - (nntp-open-connection-function nntp-open-ssl-stream) - (nntp-port-number "snews") - (nntp-address "snews.bar.com")) -@end lisp - -@end table - -@item nntp-end-of-line -@vindex nntp-end-of-line -String to use as end-of-line marker when talking to the @sc{nntp} -server. This is @samp{\r\n} by default, but should be @samp{\n} when -using @code{rlogin} to talk to the server. - -@item nntp-rlogin-user-name -@vindex nntp-rlogin-user-name -User name on the remote system when using the @code{rlogin} connect -function. - -@item nntp-address -@vindex nntp-address -The address of the remote system running the @sc{nntp} server. - -@item nntp-port-number -@vindex nntp-port-number -Port number to connect to when using the @code{nntp-open-network-stream} -connect function. - -@item nntp-buggy-select -@vindex nntp-buggy-select -Set this to non-@code{nil} if your select routine is buggy. - -@item nntp-nov-is-evil -@vindex nntp-nov-is-evil -If the @sc{nntp} server does not support @sc{nov}, you could set this -variable to @code{t}, but @code{nntp} usually checks automatically whether @sc{nov} -can be used. - -@item nntp-xover-commands -@vindex nntp-xover-commands -@cindex nov -@cindex XOVER -List of strings used as commands to fetch @sc{nov} lines from a -server. The default value of this variable is @code{("XOVER" -"XOVERVIEW")}. - -@item nntp-nov-gap -@vindex nntp-nov-gap -@code{nntp} normally sends just one big request for @sc{nov} lines to -the server. The server responds with one huge list of lines. However, -if you have read articles 2-5000 in the group, and only want to read -article 1 and 5001, that means that @code{nntp} will fetch 4999 @sc{nov} -lines that you will not need. This variable says how -big a gap between two consecutive articles is allowed to be before the -@code{XOVER} request is split into several request. Note that if your -network is fast, setting this variable to a really small number means -that fetching will probably be slower. If this variable is @code{nil}, -@code{nntp} will never split requests. The default is 5. - -@item nntp-prepare-server-hook -@vindex nntp-prepare-server-hook -A hook run before attempting to connect to an @sc{nntp} server. - -@item nntp-warn-about-losing-connection -@vindex nntp-warn-about-losing-connection -If this variable is non-@code{nil}, some noise will be made when a -server closes connection. - -@item nntp-record-commands -@vindex nntp-record-commands -If non-@code{nil}, @code{nntp} will log all commands it sends to the -@sc{nntp} server (along with a timestep) in the @samp{*nntp-log*} -buffer. This is useful if you are debugging a Gnus/@sc{nntp} connection -that doesn't seem to work. - -@end table - - -@node News Spool -@subsection News Spool -@cindex nnspool -@cindex news spool - -Subscribing to a foreign group from the local spool is extremely easy, -and might be useful, for instance, to speed up reading groups that -contain very big articles---@samp{alt.binaries.pictures.furniture}, for -instance. - -Anyways, you just specify @code{nnspool} as the method and @code{""} (or -anything else) as the address. - -If you have access to a local spool, you should probably use that as the -native select method (@pxref{Finding the News}). It is normally faster -than using an @code{nntp} select method, but might not be. It depends. -You just have to try to find out what's best at your site. - -@table @code - -@item nnspool-inews-program -@vindex nnspool-inews-program -Program used to post an article. - -@item nnspool-inews-switches -@vindex nnspool-inews-switches -Parameters given to the inews program when posting an article. - -@item nnspool-spool-directory -@vindex nnspool-spool-directory -Where @code{nnspool} looks for the articles. This is normally -@file{/usr/spool/news/}. - -@item nnspool-nov-directory -@vindex nnspool-nov-directory -Where @code{nnspool} will look for @sc{nov} files. This is normally -@file{/usr/spool/news/over.view/}. - -@item nnspool-lib-dir -@vindex nnspool-lib-dir -Where the news lib dir is (@file{/usr/lib/news/} by default). - -@item nnspool-active-file -@vindex nnspool-active-file -The path to the active file. - -@item nnspool-newsgroups-file -@vindex nnspool-newsgroups-file -The path to the group descriptions file. - -@item nnspool-history-file -@vindex nnspool-history-file -The path to the news history file. - -@item nnspool-active-times-file -@vindex nnspool-active-times-file -The path to the active date file. - -@item nnspool-nov-is-evil -@vindex nnspool-nov-is-evil -If non-@code{nil}, @code{nnspool} won't try to use any @sc{nov} files -that it finds. - -@item nnspool-sift-nov-with-sed -@vindex nnspool-sift-nov-with-sed -@cindex sed -If non-@code{nil}, which is the default, use @code{sed} to get the -relevant portion from the overview file. If nil, @code{nnspool} will -load the entire file into a buffer and process it there. - -@end table - - -@node Getting Mail -@section Getting Mail -@cindex reading mail -@cindex mail - -Reading mail with a newsreader---isn't that just plain WeIrD? But of -course. - -@menu -* Getting Started Reading Mail:: A simple cookbook example. -* Splitting Mail:: How to create mail groups. -* Mail Backend Variables:: Variables for customizing mail handling. -* Fancy Mail Splitting:: Gnus can do hairy splitting of incoming mail. -* Mail and Procmail:: Reading mail groups that procmail create. -* Incorporating Old Mail:: What about the old mail you have? -* Expiring Mail:: Getting rid of unwanted mail. -* Washing Mail:: Removing gruft from the mail you get. -* Duplicates:: Dealing with duplicated mail. -* Not Reading Mail:: Using mail backends for reading other files. -* Choosing a Mail Backend:: Gnus can read a variety of mail formats. -@end menu - - -@node Getting Started Reading Mail -@subsection Getting Started Reading Mail - -It's quite easy to use Gnus to read your new mail. You just plonk the -mail backend of your choice into @code{gnus-secondary-select-methods}, -and things will happen automatically. - -For instance, if you want to use @code{nnml} (which is a "one file per -mail" backend), you could put the following in your @file{.gnus} file: - -@lisp -(setq gnus-secondary-select-methods - '((nnml "private"))) -@end lisp - -Now, the next time you start Gnus, this backend will be queried for new -articles, and it will move all the messages in your spool file to its -directory, which is @code{~/Mail/} by default. The new group that will -be created (@samp{mail.misc}) will be subscribed, and you can read it -like any other group. - -You will probably want to split the mail into several groups, though: - -@lisp -(setq nnmail-split-methods - '(("junk" "^From:.*Lars Ingebrigtsen") - ("crazy" "^Subject:.*die\\|^Organization:.*flabby") - ("other" ""))) -@end lisp - -This will result in three new @code{nnml} mail groups being created: -@samp{nnml:junk}, @samp{nnml:crazy}, and @samp{nnml:other}. All the -mail that doesn't fit into the first two groups will be placed in the -last group. - -This should be sufficient for reading mail with Gnus. You might want to -give the other sections in this part of the manual a perusal, though. -Especially @pxref{Choosing a Mail Backend} and @pxref{Expiring Mail}. - - -@node Splitting Mail -@subsection Splitting Mail -@cindex splitting mail -@cindex mail splitting - -@vindex nnmail-split-methods -The @code{nnmail-split-methods} variable says how the incoming mail is -to be split into groups. - -@lisp -(setq nnmail-split-methods - '(("mail.junk" "^From:.*Lars Ingebrigtsen") - ("mail.crazy" "^Subject:.*die\\|^Organization:.*flabby") - ("mail.other" ""))) -@end lisp - -This variable is a list of lists, where the first element of each of -these lists is the name of the mail group (they do not have to be called -something beginning with @samp{mail}, by the way), and the second -element is a regular expression used on the header of each mail to -determine if it belongs in this mail group. The first string may -contain @samp{\\1} forms, like the ones used by @code{replace-match} to -insert sub-expressions from the matched text. For instance: - -@lisp -("list.\\1" "From:.*\\(.*\\)-list@@majordomo.com") -@end lisp - -The second element can also be a function. In that case, it will be -called narrowed to the headers with the first element of the rule as the -argument. It should return a non-@code{nil} value if it thinks that the -mail belongs in that group. - -The last of these groups should always be a general one, and the regular -expression should @emph{always} be @samp{} so that it matches any mails -that haven't been matched by any of the other regexps. (These rules are -processed from the beginning of the alist toward the end. The first -rule to make a match will "win", unless you have crossposting enabled. -In that case, all matching rules will "win".) - -If you like to tinker with this yourself, you can set this variable to a -function of your choice. This function will be called without any -arguments in a buffer narrowed to the headers of an incoming mail -message. The function should return a list of group names that it -thinks should carry this mail message. - -Note that the mail backends are free to maul the poor, innocent, -incoming headers all they want to. They all add @code{Lines} headers; -some add @code{X-Gnus-Group} headers; most rename the Unix mbox -@code{From} line to something else. - -@vindex nnmail-crosspost -The mail backends all support cross-posting. If several regexps match, -the mail will be ``cross-posted'' to all those groups. -@code{nnmail-crosspost} says whether to use this mechanism or not. Note -that no articles are crossposted to the general (@samp{}) group. - -@vindex nnmail-crosspost-link-function -@cindex crosspost -@cindex links -@code{nnmh} and @code{nnml} makes crossposts by creating hard links to -the crossposted articles. However, not all file systems support hard -links. If that's the case for you, set -@code{nnmail-crosspost-link-function} to @code{copy-file}. (This -variable is @code{add-name-to-file} by default.) - -@kindex M-x nnmail-split-history -@kindex nnmail-split-history -If you wish to see where the previous mail split put the messages, you -can use the @kbd{M-x nnmail-split-history} command. - -Gnus gives you all the opportunity you could possibly want for shooting -yourself in the foot. Let's say you create a group that will contain -all the mail you get from your boss. And then you accidentally -unsubscribe from the group. Gnus will still put all the mail from your -boss in the unsubscribed group, and so, when your boss mails you ``Have -that report ready by Monday or you're fired!'', you'll never see it and, -come Tuesday, you'll still believe that you're gainfully employed while -you really should be out collecting empty bottles to save up for next -month's rent money. - - -@node Mail Backend Variables -@subsection Mail Backend Variables - -These variables are (for the most part) pertinent to all the various -mail backends. - -@table @code -@vindex nnmail-read-incoming-hook -@item nnmail-read-incoming-hook -The mail backends all call this hook after reading new mail. You can -use this hook to notify any mail watch programs, if you want to. - -@vindex nnmail-spool-file -@item nnmail-spool-file -@cindex POP mail -@cindex MAILHOST -@cindex movemail -@vindex nnmail-pop-password -@vindex nnmail-pop-password-required -The backends will look for new mail in this file. If this variable is -@code{nil}, the mail backends will never attempt to fetch mail by -themselves. If you are using a POP mail server and your name is -@samp{larsi}, you should set this variable to @samp{po:larsi}. If -your name is not @samp{larsi}, you should probably modify that -slightly, but you may have guessed that already, you smart & handsome -devil! You can also set this variable to @code{pop}, and Gnus will try -to figure out the POP mail string by itself. In any case, Gnus will -call @code{movemail} which will contact the POP server named in the -@code{MAILHOST} environment variable. If the POP server needs a -password, you can either set @code{nnmail-pop-password-required} to -@code{t} and be prompted for the password, or set -@code{nnmail-pop-password} to the password itself. - -@code{nnmail-spool-file} can also be a list of mailboxes. - -Your Emacs has to have been configured with @samp{--with-pop} before -compilation. This is the default, but some installations have it -switched off. - -When you use a mail backend, Gnus will slurp all your mail from your -inbox and plonk it down in your home directory. Gnus doesn't move any -mail if you're not using a mail backend---you have to do a lot of magic -invocations first. At the time when you have finished drawing the -pentagram, lightened the candles, and sacrificed the goat, you really -shouldn't be too surprised when Gnus moves your mail. - -@vindex nnmail-use-procmail -@vindex nnmail-procmail-suffix -@item nnmail-use-procmail -If non-@code{nil}, the mail backends will look in -@code{nnmail-procmail-directory} for incoming mail. All the files in -that directory that have names ending in @code{nnmail-procmail-suffix} -will be considered incoming mailboxes, and will be searched for new -mail. - -@vindex nnmail-crash-box -@item nnmail-crash-box -When a mail backend reads a spool file, mail is first moved to this -file, which is @file{~/.gnus-crash-box} by default. If this file -already exists, it will always be read (and incorporated) before any -other spool files. - -@vindex nnmail-prepare-incoming-hook -@item nnmail-prepare-incoming-hook -This is run in a buffer that holds all the new incoming mail, and can be -used for, well, anything, really. - -@vindex nnmail-split-hook -@item nnmail-split-hook -@findex article-decode-rfc1522 -@findex RFC1522 decoding -Hook run in the buffer where the mail headers of each message is kept -just before the splitting based on these headers is done. The hook is -free to modify the buffer contents in any way it sees fit---the buffer -is discarded after the splitting has been done, and no changes performed -in the buffer will show up in any files. @code{gnus-article-decode-rfc1522} -is one likely function to add to this hook. - -@vindex nnmail-pre-get-new-mail-hook -@vindex nnmail-post-get-new-mail-hook -@item nnmail-pre-get-new-mail-hook -@itemx nnmail-post-get-new-mail-hook -These are two useful hooks executed when treating new incoming -mail---@code{nnmail-pre-get-new-mail-hook} (is called just before -starting to handle the new mail) and -@code{nnmail-post-get-new-mail-hook} (is called when the mail handling -is done). Here's and example of using these two hooks to change the -default file modes the new mail files get: - -@lisp -(add-hook 'gnus-pre-get-new-mail-hook - (lambda () (set-default-file-modes 511))) - -(add-hook 'gnus-post-get-new-mail-hook - (lambda () (set-default-file-modes 551))) -@end lisp - -@item nnmail-tmp-directory -@vindex nnmail-tmp-directory -This variable says where to move incoming mail to -- while processing -it. This is usually done in the same directory that the mail backend -inhabits (e.g., @file{~/Mail/}), but if this variable is non-@code{nil}, -it will be used instead. - -@item nnmail-movemail-program -@vindex nnmail-movemail-program -This program is executed to move mail from the user's inbox to her home -directory. The default is @samp{movemail}. - -This can also be a function. In that case, the function will be called -with two parameters -- the name of the inbox, and the file to be moved -to. - -@item nnmail-delete-incoming -@vindex nnmail-delete-incoming -@cindex incoming mail files -@cindex deleting incoming files -If non-@code{nil}, the mail backends will delete the temporary incoming -file after splitting mail into the proper groups. This is @code{t} by -default. - -@c This is @code{nil} by -@c default for reasons of security. - -@c Since Red Gnus is an alpha release, it is to be expected to lose mail. -(No Gnus release since (ding) Gnus 0.10 (or something like that) have -lost mail, I think, but that's not the point. (Except certain versions -of Red Gnus.)) By not deleting the Incoming* files, one can be sure not -to lose mail -- if Gnus totally whacks out, one can always recover what -was lost. - -You may delete the @file{Incoming*} files at will. - -@item nnmail-use-long-file-names -@vindex nnmail-use-long-file-names -If non-@code{nil}, the mail backends will use long file and directory -names. Groups like @samp{mail.misc} will end up in directories -(assuming use of @code{nnml} backend) or files (assuming use of -@code{nnfolder} backend) like @file{mail.misc}. If it is @code{nil}, -the same group will end up in @file{mail/misc}. - -@item nnmail-delete-file-function -@vindex nnmail-delete-file-function -@findex delete-file -Function called to delete files. It is @code{delete-file} by default. - -@item nnmail-cache-accepted-message-ids -@vindex nnmail-cache-accepted-message-ids -If non-@code{nil}, put the @code{Message-ID}s of articles imported into -the backend (via @code{Gcc}, for instance) into the mail duplication -discovery cache. The default is @code{nil}. - -@end table - - -@node Fancy Mail Splitting -@subsection Fancy Mail Splitting -@cindex mail splitting -@cindex fancy mail splitting - -@vindex nnmail-split-fancy -@findex nnmail-split-fancy -If the rather simple, standard method for specifying how to split mail -doesn't allow you to do what you want, you can set -@code{nnmail-split-methods} to @code{nnmail-split-fancy}. Then you can -play with the @code{nnmail-split-fancy} variable. - -Let's look at an example value of this variable first: - -@lisp -;; Messages from the mailer daemon are not crossposted to any of -;; the ordinary groups. Warnings are put in a separate group -;; from real errors. -(| ("from" mail (| ("subject" "warn.*" "mail.warning") - "mail.misc")) - ;; Non-error messages are crossposted to all relevant - ;; groups, but we don't crosspost between the group for the - ;; (ding) list and the group for other (ding) related mail. - (& (| (any "ding@@ifi\\.uio\\.no" "ding.list") - ("subject" "ding" "ding.misc")) - ;; Other mailing lists... - (any "procmail@@informatik\\.rwth-aachen\\.de" "procmail.list") - (any "SmartList@@informatik\\.rwth-aachen\\.de" "SmartList.list") - ;; People... - (any "larsi@@ifi\\.uio\\.no" "people.Lars_Magne_Ingebrigtsen")) - ;; Unmatched mail goes to the catch all group. - "misc.misc") -@end lisp - -This variable has the format of a @dfn{split}. A split is a (possibly) -recursive structure where each split may contain other splits. Here are -the five possible split syntaxes: - -@enumerate - -@item -@samp{group}: If the split is a string, that will be taken as a group -name. Normal regexp match expansion will be done. See below for -examples. - -@item -@var{(FIELD VALUE SPLIT)}: If the split is a list, the first element of -which is a string, then store the message as specified by SPLIT, if -header FIELD (a regexp) contains VALUE (also a regexp). - -@item -@var{(| SPLIT...)}: If the split is a list, and the first element is -@code{|} (vertical bar), then process each SPLIT until one of them -matches. A SPLIT is said to match if it will cause the mail message to -be stored in one or more groups. - -@item -@var{(& SPLIT...)}: If the split is a list, and the first element is -@code{&}, then process all SPLITs in the list. - -@item -@code{junk}: If the split is the symbol @code{junk}, then don't save -this message. Use with extreme caution. - -@item -@var{(: function arg1 arg2 ...)}: If the split is a list, and the first -element is @code{:}, then the second element will be called as a -function with @var{args} given as arguments. The function should return -a SPLIT. - -@item -@code{nil}: If the split is @code{nil}, it is ignored. - -@end enumerate - -In these splits, @var{FIELD} must match a complete field name. -@var{VALUE} must match a complete word according to the fundamental mode -syntax table. You can use @code{.*} in the regexps to match partial -field names or words. In other words, all @var{VALUE}'s are wrapped in -@samp{\<} and @samp{\>} pairs. - -@vindex nnmail-split-abbrev-alist -@var{FIELD} and @var{VALUE} can also be lisp symbols, in that case they -are expanded as specified by the variable -@code{nnmail-split-abbrev-alist}. This is an alist of cons cells, where -the @code{car} of a cell contains the key, and the @code{cdr} contains the associated -value. - -@vindex nnmail-split-fancy-syntax-table -@code{nnmail-split-fancy-syntax-table} is the syntax table in effect -when all this splitting is performed. - -If you want to have Gnus create groups dynamically based on some -information in the headers (i.e., do @code{replace-match}-like -substitutions in the group names), you can say things like: - -@example -(any "debian-\\b\\(\\w+\\)@@lists.debian.org" "mail.debian.\\1") -@end example - -If the string contains the element @samp{\&}, then the previously -matched string will be substituted. Similarly, the elements @samp{\\1} -up to @samp{\\9} will be substituted with the text matched by the -groupings 1 through 9. - - -@node Mail and Procmail -@subsection Mail and Procmail -@cindex procmail - -@cindex slocal -@cindex elm -Many people use @code{procmail} (or some other mail filter program or -external delivery agent---@code{slocal}, @code{elm}, etc) to split -incoming mail into groups. If you do that, you should set -@code{nnmail-spool-file} to @code{procmail} to ensure that the mail -backends never ever try to fetch mail by themselves. - -If you have a combined @code{procmail}/POP/mailbox setup, you can do -something like the following: - -@vindex nnmail-use-procmail -@lisp -(setq nnmail-use-procmail t) -(setq nnmail-spool-file - '("/usr/spool/mail/my-name" "po:my-name")) -@end lisp - -This also means that you probably don't want to set -@code{nnmail-split-methods} either, which has some, perhaps, unexpected -side effects. - -When a mail backend is queried for what groups it carries, it replies -with the contents of that variable, along with any groups it has figured -out that it carries by other means. None of the backends, except -@code{nnmh}, actually go out to the disk and check what groups actually -exist. (It's not trivial to distinguish between what the user thinks is -a basis for a newsgroup and what is just a plain old file or directory.) - -This means that you have to tell Gnus (and the backends) by hand what -groups exist. - -Let's take the @code{nnmh} backend as an example: - -The folders are located in @code{nnmh-directory}, say, @file{~/Mail/}. -There are three folders, @file{foo}, @file{bar} and @file{mail.baz}. - -Go to the group buffer and type @kbd{G m}. When prompted, answer -@samp{foo} for the name and @samp{nnmh} for the method. Repeat -twice for the two other groups, @samp{bar} and @samp{mail.baz}. Be sure -to include all your mail groups. - -That's it. You are now set to read your mail. An active file for this -method will be created automatically. - -@vindex nnmail-procmail-suffix -@vindex nnmail-procmail-directory -If you use @code{nnfolder} or any other backend that store more than a -single article in each file, you should never have procmail add mails to -the file that Gnus sees. Instead, procmail should put all incoming mail -in @code{nnmail-procmail-directory}. To arrive at the file name to put -the incoming mail in, append @code{nnmail-procmail-suffix} to the group -name. The mail backends will read the mail from these files. - -@vindex nnmail-resplit-incoming -When Gnus reads a file called @file{mail.misc.spool}, this mail will be -put in the @code{mail.misc}, as one would expect. However, if you want -Gnus to split the mail the normal way, you could set -@code{nnmail-resplit-incoming} to @code{t}. - -@vindex nnmail-keep-last-article -If you use @code{procmail} to split things directly into an @code{nnmh} -directory (which you shouldn't do), you should set -@code{nnmail-keep-last-article} to non-@code{nil} to prevent Gnus from -ever expiring the final article (i.e., the article with the highest -article number) in a mail newsgroup. This is quite, quite important. - -Here's an example setup: The incoming spools are located in -@file{~/incoming/} and have @samp{""} as suffixes (i.e., the incoming -spool files have the same names as the equivalent groups). The -@code{nnfolder} backend is to be used as the mail interface, and the -@code{nnfolder} directory is @file{~/fMail/}. - -@lisp -(setq nnfolder-directory "~/fMail/") -(setq nnmail-spool-file 'procmail) -(setq nnmail-procmail-directory "~/incoming/") -(setq gnus-secondary-select-methods '((nnfolder ""))) -(setq nnmail-procmail-suffix "") -@end lisp - - -@node Incorporating Old Mail -@subsection Incorporating Old Mail - -Most people have lots of old mail stored in various file formats. If -you have set up Gnus to read mail using one of the spiffy Gnus mail -backends, you'll probably wish to have that old mail incorporated into -your mail groups. - -Doing so can be quite easy. - -To take an example: You're reading mail using @code{nnml} -(@pxref{Mail Spool}), and have set @code{nnmail-split-methods} to a -satisfactory value (@pxref{Splitting Mail}). You have an old Unix mbox -file filled with important, but old, mail. You want to move it into -your @code{nnml} groups. - -Here's how: - -@enumerate -@item -Go to the group buffer. - -@item -Type `G f' and give the path to the mbox file when prompted to create an -@code{nndoc} group from the mbox file (@pxref{Foreign Groups}). - -@item -Type `SPACE' to enter the newly created group. - -@item -Type `M P b' to process-mark all articles in this group's buffer -(@pxref{Setting Process Marks}). - -@item -Type `B r' to respool all the process-marked articles, and answer -@samp{nnml} when prompted (@pxref{Mail Group Commands}). -@end enumerate - -All the mail messages in the mbox file will now also be spread out over -all your @code{nnml} groups. Try entering them and check whether things -have gone without a glitch. If things look ok, you may consider -deleting the mbox file, but I wouldn't do that unless I was absolutely -sure that all the mail has ended up where it should be. - -Respooling is also a handy thing to do if you're switching from one mail -backend to another. Just respool all the mail in the old mail groups -using the new mail backend. - - -@node Expiring Mail -@subsection Expiring Mail -@cindex article expiry - -Traditional mail readers have a tendency to remove mail articles when -you mark them as read, in some way. Gnus takes a fundamentally -different approach to mail reading. - -Gnus basically considers mail just to be news that has been received in -a rather peculiar manner. It does not think that it has the power to -actually change the mail, or delete any mail messages. If you enter a -mail group, and mark articles as ``read'', or kill them in some other -fashion, the mail articles will still exist on the system. I repeat: -Gnus will not delete your old, read mail. Unless you ask it to, of -course. - -To make Gnus get rid of your unwanted mail, you have to mark the -articles as @dfn{expirable}. This does not mean that the articles will -disappear right away, however. In general, a mail article will be -deleted from your system if, 1) it is marked as expirable, AND 2) it is -more than one week old. If you do not mark an article as expirable, it -will remain on your system until hell freezes over. This bears -repeating one more time, with some spurious capitalizations: IF you do -NOT mark articles as EXPIRABLE, Gnus will NEVER delete those ARTICLES. - -@vindex gnus-auto-expirable-newsgroups -You do not have to mark articles as expirable by hand. Groups that -match the regular expression @code{gnus-auto-expirable-newsgroups} will -have all articles that you read marked as expirable automatically. All -articles marked as expirable have an @samp{E} in the first -column in the summary buffer. - -By default, if you have auto expiry switched on, Gnus will mark all the -articles you read as expirable, no matter if they were read or unread -before. To avoid having articles marked as read marked as expirable -automatically, you can put something like the following in your -@file{.gnus} file: - -@vindex gnus-mark-article-hook -@lisp -(remove-hook 'gnus-mark-article-hook - 'gnus-summary-mark-read-and-unread-as-read) -(add-hook 'gnus-mark-article-hook 'gnus-summary-mark-unread-as-read) -@end lisp - -Note that making a group auto-expirable doesn't mean that all read -articles are expired---only the articles marked as expirable -will be expired. Also note that using the @kbd{d} command won't make -groups expirable---only semi-automatic marking of articles as read will -mark the articles as expirable in auto-expirable groups. - -Let's say you subscribe to a couple of mailing lists, and you want the -articles you have read to disappear after a while: - -@lisp -(setq gnus-auto-expirable-newsgroups - "mail.nonsense-list\\|mail.nice-list") -@end lisp - -Another way to have auto-expiry happen is to have the element -@code{auto-expire} in the group parameters of the group. - -If you use adaptive scoring (@pxref{Adaptive Scoring}) and -auto-expiring, you'll have problems. Auto-expiring and adaptive scoring -don't really mix very well. - -@vindex nnmail-expiry-wait -The @code{nnmail-expiry-wait} variable supplies the default time an -expirable article has to live. Gnus starts counting days from when the -message @emph{arrived}, not from when it was sent. The default is seven -days. - -Gnus also supplies a function that lets you fine-tune how long articles -are to live, based on what group they are in. Let's say you want to -have one month expiry period in the @samp{mail.private} group, a one day -expiry period in the @samp{mail.junk} group, and a six day expiry period -everywhere else: - -@vindex nnmail-expiry-wait-function -@lisp -(setq nnmail-expiry-wait-function - (lambda (group) - (cond ((string= group "mail.private") - 31) - ((string= group "mail.junk") - 1) - ((string= group "important") - 'never) - (t - 6)))) -@end lisp - -The group names this function is fed are ``unadorned'' group -names---no @samp{nnml:} prefixes and the like. - -The @code{nnmail-expiry-wait} variable and -@code{nnmail-expiry-wait-function} function can either be a number (not -necessarily an integer) or one of the symbols @code{immediate} or -@code{never}. - -You can also use the @code{expiry-wait} group parameter to selectively -change the expiry period (@pxref{Group Parameters}). - -@vindex nnmail-keep-last-article -If @code{nnmail-keep-last-article} is non-@code{nil}, Gnus will never -expire the final article in a mail newsgroup. This is to make life -easier for procmail users. - -@vindex gnus-total-expirable-newsgroups -By the way: That line up there, about Gnus never expiring non-expirable -articles, is a lie. If you put @code{total-expire} in the group -parameters, articles will not be marked as expirable, but all read -articles will be put through the expiry process. Use with extreme -caution. Even more dangerous is the -@code{gnus-total-expirable-newsgroups} variable. All groups that match -this regexp will have all read articles put through the expiry process, -which means that @emph{all} old mail articles in the groups in question -will be deleted after a while. Use with extreme caution, and don't come -crying to me when you discover that the regexp you used matched the -wrong group and all your important mail has disappeared. Be a -@emph{man}! Or a @emph{woman}! Whatever you feel more comfortable -with! So there! - -Most people make most of their mail groups total-expirable, though. - - -@node Washing Mail -@subsection Washing Mail -@cindex mail washing -@cindex list server brain damage -@cindex incoming mail treatment - -Mailers and list servers are notorious for doing all sorts of really, -really stupid things with mail. ``Hey, RFC822 doesn't explicitly -prohibit us from adding the string @code{wE aRe ElItE!!!!!1!!} to the -end of all lines passing through our server, so let's do that!!!!1!'' -Yes, but RFC822 wasn't designed to be read by morons. Things that were -considered to be self-evident were not discussed. So. Here we are. - -Case in point: The German version of Microsoft Exchange adds @samp{AW: -} to the subjects of replies instead of @samp{Re: }. I could pretend to -be shocked and dismayed by this, but I haven't got the energy. It is to -laugh. - -Gnus provides a plethora of functions for washing articles while -displaying them, but it might be nicer to do the filtering before -storing the mail to disc. For that purpose, we have three hooks and -various functions that can be put in these hooks. - -@table @code -@item nnmail-prepare-incoming-hook -@vindex nnmail-prepare-incoming-hook -This hook is called before doing anything with the mail and is meant for -grand, sweeping gestures. Functions to be used include: - -@table @code -@item nnheader-ms-strip-cr -@findex nnheader-ms-strip-cr -Remove trailing carriage returns from each line. This is default on -Emacs running on MS machines. - -@end table - -@item nnmail-prepare-incoming-header-hook -@vindex nnmail-prepare-incoming-header-hook -This hook is called narrowed to each header. It can be used when -cleaning up the headers. Functions that can be used include: - -@table @code -@item nnmail-remove-leading-whitespace -@findex nnmail-remove-leading-whitespace -Clear leading white space that ``helpful'' listservs have added to the -headers to make them look nice. Aaah. - -@item nnmail-remove-list-identifiers -@findex nnmail-remove-list-identifiers -Some list servers add an identifier---for example, @samp{(idm)}---to the -beginning of all @code{Subject} headers. I'm sure that's nice for -people who use stone age mail readers. This function will remove -strings that match the @code{nnmail-list-identifiers} regexp, which can -also be a list of regexp. - -For instance, if you want to remove the @samp{(idm)} and the -@samp{nagnagnag} identifiers: - -@lisp -(setq nnmail-list-identifiers - '("(idm)" "nagnagnag")) -@end lisp - -@item nnmail-remove-tabs -@findex nnmail-remove-tabs -Translate all @samp{TAB} characters into @samp{SPACE} characters. - -@end table - -@item nnmail-prepare-incoming-message-hook -@vindex nnmail-prepare-incoming-message-hook -This hook is called narrowed to each message. Functions to be used -include: - -@table @code -@item article-de-quoted-unreadable -@findex article-de-quoted-unreadable -Decode Quoted Readable encoding. - -@end table -@end table - - -@node Duplicates -@subsection Duplicates - -@vindex nnmail-treat-duplicates -@vindex nnmail-message-id-cache-length -@vindex nnmail-message-id-cache-file -@cindex duplicate mails -If you are a member of a couple of mailing lists, you will sometimes -receive two copies of the same mail. This can be quite annoying, so -@code{nnmail} checks for and treats any duplicates it might find. To do -this, it keeps a cache of old @code{Message-ID}s--- -@code{nnmail-message-id-cache-file}, which is @file{~/.nnmail-cache} by -default. The approximate maximum number of @code{Message-ID}s stored -there is controlled by the @code{nnmail-message-id-cache-length} -variable, which is 1000 by default. (So 1000 @code{Message-ID}s will be -stored.) If all this sounds scary to you, you can set -@code{nnmail-treat-duplicates} to @code{warn} (which is what it is by -default), and @code{nnmail} won't delete duplicate mails. Instead it -will insert a warning into the head of the mail saying that it thinks -that this is a duplicate of a different message. - -This variable can also be a function. If that's the case, the function -will be called from a buffer narrowed to the message in question with -the @code{Message-ID} as a parameter. The function must return either -@code{nil}, @code{warn}, or @code{delete}. - -You can turn this feature off completely by setting the variable to -@code{nil}. - -If you want all the duplicate mails to be put into a special -@dfn{duplicates} group, you could do that using the normal mail split -methods: - -@lisp -(setq nnmail-split-fancy - '(| ;; Messages duplicates go to a separate group. - ("gnus-warning" "duplication of message" "duplicate") - ;; Message from daemons, postmaster, and the like to another. - (any mail "mail.misc") - ;; Other rules. - [ ... ] )) -@end lisp - -Or something like: -@lisp -(setq nnmail-split-methods - '(("duplicates" "^Gnus-Warning:") - ;; Other rules. - [...])) -@end lisp - -Here's a neat feature: If you know that the recipient reads her mail -with Gnus, and that she has @code{nnmail-treat-duplicates} set to -@code{delete}, you can send her as many insults as you like, just by -using a @code{Message-ID} of a mail that you know that she's already -received. Think of all the fun! She'll never see any of it! Whee! - - -@node Not Reading Mail -@subsection Not Reading Mail - -If you start using any of the mail backends, they have the annoying -habit of assuming that you want to read mail with them. This might not -be unreasonable, but it might not be what you want. - -If you set @code{nnmail-spool-file} to @code{nil}, none of the backends -will ever attempt to read incoming mail, which should help. - -@vindex nnbabyl-get-new-mail -@vindex nnmbox-get-new-mail -@vindex nnml-get-new-mail -@vindex nnmh-get-new-mail -@vindex nnfolder-get-new-mail -This might be too much, if, for instance, you are reading mail quite -happily with @code{nnml} and just want to peek at some old @sc{rmail} -file you have stashed away with @code{nnbabyl}. All backends have -variables called backend-@code{get-new-mail}. If you want to disable -the @code{nnbabyl} mail reading, you edit the virtual server for the -group to have a setting where @code{nnbabyl-get-new-mail} to @code{nil}. - -All the mail backends will call @code{nn}*@code{-prepare-save-mail-hook} -narrowed to the article to be saved before saving it when reading -incoming mail. - - -@node Choosing a Mail Backend -@subsection Choosing a Mail Backend - -Gnus will read the mail spool when you activate a mail group. The mail -file is first copied to your home directory. What happens after that -depends on what format you want to store your mail in. - -@menu -* Unix Mail Box:: Using the (quite) standard Un*x mbox. -* Rmail Babyl:: Emacs programs use the rmail babyl format. -* Mail Spool:: Store your mail in a private spool? -* MH Spool:: An mhspool-like backend. -* Mail Folders:: Having one file for each group. -@end menu - - -@node Unix Mail Box -@subsubsection Unix Mail Box -@cindex nnmbox -@cindex unix mail box - -@vindex nnmbox-active-file -@vindex nnmbox-mbox-file -The @dfn{nnmbox} backend will use the standard Un*x mbox file to store -mail. @code{nnmbox} will add extra headers to each mail article to say -which group it belongs in. - -Virtual server settings: - -@table @code -@item nnmbox-mbox-file -@vindex nnmbox-mbox-file -The name of the mail box in the user's home directory. - -@item nnmbox-active-file -@vindex nnmbox-active-file -The name of the active file for the mail box. - -@item nnmbox-get-new-mail -@vindex nnmbox-get-new-mail -If non-@code{nil}, @code{nnmbox} will read incoming mail and split it -into groups. -@end table - - -@node Rmail Babyl -@subsubsection Rmail Babyl -@cindex nnbabyl -@cindex rmail mbox - -@vindex nnbabyl-active-file -@vindex nnbabyl-mbox-file -The @dfn{nnbabyl} backend will use a babyl mail box (aka. @dfn{rmail -mbox}) to store mail. @code{nnbabyl} will add extra headers to each mail -article to say which group it belongs in. - -Virtual server settings: - -@table @code -@item nnbabyl-mbox-file -@vindex nnbabyl-mbox-file -The name of the rmail mbox file. - -@item nnbabyl-active-file -@vindex nnbabyl-active-file -The name of the active file for the rmail box. - -@item nnbabyl-get-new-mail -@vindex nnbabyl-get-new-mail -If non-@code{nil}, @code{nnbabyl} will read incoming mail. -@end table - - -@node Mail Spool -@subsubsection Mail Spool -@cindex nnml -@cindex mail @sc{nov} spool - -The @dfn{nnml} spool mail format isn't compatible with any other known -format. It should be used with some caution. - -@vindex nnml-directory -If you use this backend, Gnus will split all incoming mail into files, -one file for each mail, and put the articles into the corresponding -directories under the directory specified by the @code{nnml-directory} -variable. The default value is @file{~/Mail/}. - -You do not have to create any directories beforehand; Gnus will take -care of all that. - -If you have a strict limit as to how many files you are allowed to store -in your account, you should not use this backend. As each mail gets its -own file, you might very well occupy thousands of inodes within a few -weeks. If this is no problem for you, and it isn't a problem for you -having your friendly systems administrator walking around, madly, -shouting ``Who is eating all my inodes?! Who? Who!?!'', then you should -know that this is probably the fastest format to use. You do not have -to trudge through a big mbox file just to read your new mail. - -@code{nnml} is probably the slowest backend when it comes to article -splitting. It has to create lots of files, and it also generates -@sc{nov} databases for the incoming mails. This makes it the fastest -backend when it comes to reading mail. - -Virtual server settings: - -@table @code -@item nnml-directory -@vindex nnml-directory -All @code{nnml} directories will be placed under this directory. - -@item nnml-active-file -@vindex nnml-active-file -The active file for the @code{nnml} server. - -@item nnml-newsgroups-file -@vindex nnml-newsgroups-file -The @code{nnml} group descriptions file. @xref{Newsgroups File -Format}. - -@item nnml-get-new-mail -@vindex nnml-get-new-mail -If non-@code{nil}, @code{nnml} will read incoming mail. - -@item nnml-nov-is-evil -@vindex nnml-nov-is-evil -If non-@code{nil}, this backend will ignore any @sc{nov} files. - -@item nnml-nov-file-name -@vindex nnml-nov-file-name -The name of the @sc{nov} files. The default is @file{.overview}. - -@item nnml-prepare-save-mail-hook -@vindex nnml-prepare-save-mail-hook -Hook run narrowed to an article before saving. - -@end table - -@findex nnml-generate-nov-databases -If your @code{nnml} groups and @sc{nov} files get totally out of whack, -you can do a complete update by typing @kbd{M-x -nnml-generate-nov-databases}. This command will trawl through the -entire @code{nnml} hierarchy, looking at each and every article, so it -might take a while to complete. A better interface to this -functionality can be found in the server buffer (@pxref{Server -Commands}). - - -@node MH Spool -@subsubsection MH Spool -@cindex nnmh -@cindex mh-e mail spool - -@code{nnmh} is just like @code{nnml}, except that is doesn't generate -@sc{nov} databases and it doesn't keep an active file. This makes -@code{nnmh} a @emph{much} slower backend than @code{nnml}, but it also -makes it easier to write procmail scripts for. - -Virtual server settings: - -@table @code -@item nnmh-directory -@vindex nnmh-directory -All @code{nnmh} directories will be located under this directory. - -@item nnmh-get-new-mail -@vindex nnmh-get-new-mail -If non-@code{nil}, @code{nnmh} will read incoming mail. - -@item nnmh-be-safe -@vindex nnmh-be-safe -If non-@code{nil}, @code{nnmh} will go to ridiculous lengths to make -sure that the articles in the folder are actually what Gnus thinks they -are. It will check date stamps and stat everything in sight, so -setting this to @code{t} will mean a serious slow-down. If you never -use anything but Gnus to read the @code{nnmh} articles, you do not have -to set this variable to @code{t}. -@end table - - -@node Mail Folders -@subsubsection Mail Folders -@cindex nnfolder -@cindex mbox folders -@cindex mail folders - -@code{nnfolder} is a backend for storing each mail group in a separate -file. Each file is in the standard Un*x mbox format. @code{nnfolder} -will add extra headers to keep track of article numbers and arrival -dates. - -Virtual server settings: - -@table @code -@item nnfolder-directory -@vindex nnfolder-directory -All the @code{nnfolder} mail boxes will be stored under this directory. - -@item nnfolder-active-file -@vindex nnfolder-active-file -The name of the active file. - -@item nnfolder-newsgroups-file -@vindex nnfolder-newsgroups-file -The name of the group descriptions file. @xref{Newsgroups File Format}. - -@item nnfolder-get-new-mail -@vindex nnfolder-get-new-mail -If non-@code{nil}, @code{nnfolder} will read incoming mail. - -@item nnfolder-save-buffer-hook -@vindex nnfolder-save-buffer-hook -@cindex backup files -Hook run before saving the folders. Note that Emacs does the normal -backup renaming of files even with the @code{nnfolder} buffers. If you -wish to switch this off, you could say something like the following in -your @file{.emacs} file: - -@lisp -(defun turn-off-backup () - (set (make-local-variable 'backup-inhibited) t)) - -(add-hook 'nnfolder-save-buffer-hook 'turn-off-backup) -@end lisp - -@end table - -@findex nnfolder-generate-active-file -@kindex M-x nnfolder-generate-active-file -If you have lots of @code{nnfolder}-like files you'd like to read with -@code{nnfolder}, you can use the @kbd{M-x nnfolder-generate-active-file} -command to make @code{nnfolder} aware of all likely files in -@code{nnfolder-directory}. - - -@node Other Sources -@section Other Sources - -Gnus can do more than just read news or mail. The methods described -below allow Gnus to view directories and files as if they were -newsgroups. - -@menu -* Directory Groups:: You can read a directory as if it was a newsgroup. -* Anything Groups:: Dired? Who needs dired? -* Document Groups:: Single files can be the basis of a group. -* SOUP:: Reading @sc{SOUP} packets ``offline''. -* Web Searches:: Creating groups from articles that match a string. -* Mail-To-News Gateways:: Posting articles via mail-to-news gateways. -@end menu - - -@node Directory Groups -@subsection Directory Groups -@cindex nndir -@cindex directory groups - -If you have a directory that has lots of articles in separate files in -it, you might treat it as a newsgroup. The files have to have numerical -names, of course. - -This might be an opportune moment to mention @code{ange-ftp} (and its -successor @code{efs}), that most wonderful of all wonderful Emacs -packages. When I wrote @code{nndir}, I didn't think much about it---a -backend to read directories. Big deal. - -@code{ange-ftp} changes that picture dramatically. For instance, if you -enter the @code{ange-ftp} file name -@file{/ftp.hpc.uh.edu:/pub/emacs/ding-list/} as the directory name, -@code{ange-ftp} or @code{efs} will actually allow you to read this -directory over at @samp{sina} as a newsgroup. Distributed news ahoy! - -@code{nndir} will use @sc{nov} files if they are present. - -@code{nndir} is a ``read-only'' backend---you can't delete or expire -articles with this method. You can use @code{nnmh} or @code{nnml} for -whatever you use @code{nndir} for, so you could switch to any of those -methods if you feel the need to have a non-read-only @code{nndir}. - - -@node Anything Groups -@subsection Anything Groups -@cindex nneething - -From the @code{nndir} backend (which reads a single spool-like -directory), it's just a hop and a skip to @code{nneething}, which -pretends that any arbitrary directory is a newsgroup. Strange, but -true. - -When @code{nneething} is presented with a directory, it will scan this -directory and assign article numbers to each file. When you enter such -a group, @code{nneething} must create ``headers'' that Gnus can use. -After all, Gnus is a newsreader, in case you're -forgetting. @code{nneething} does this in a two-step process. First, it -snoops each file in question. If the file looks like an article (i.e., -the first few lines look like headers), it will use this as the head. -If this is just some arbitrary file without a head (e.g. a C source -file), @code{nneething} will cobble up a header out of thin air. It -will use file ownership, name and date and do whatever it can with these -elements. - -All this should happen automatically for you, and you will be presented -with something that looks very much like a newsgroup. Totally like a -newsgroup, to be precise. If you select an article, it will be displayed -in the article buffer, just as usual. - -If you select a line that represents a directory, Gnus will pop you into -a new summary buffer for this @code{nneething} group. And so on. You can -traverse the entire disk this way, if you feel like, but remember that -Gnus is not dired, really, and does not intend to be, either. - -There are two overall modes to this action---ephemeral or solid. When -doing the ephemeral thing (i.e., @kbd{G D} from the group buffer), Gnus -will not store information on what files you have read, and what files -are new, and so on. If you create a solid @code{nneething} group the -normal way with @kbd{G m}, Gnus will store a mapping table between -article numbers and file names, and you can treat this group like any -other groups. When you activate a solid @code{nneething} group, you will -be told how many unread articles it contains, etc., etc. - -Some variables: - -@table @code -@item nneething-map-file-directory -@vindex nneething-map-file-directory -All the mapping files for solid @code{nneething} groups will be stored -in this directory, which defaults to @file{~/.nneething/}. - -@item nneething-exclude-files -@vindex nneething-exclude-files -All files that match this regexp will be ignored. Nice to use to exclude -auto-save files and the like, which is what it does by default. - -@item nneething-map-file -@vindex nneething-map-file -Name of the map files. -@end table - - -@node Document Groups -@subsection Document Groups -@cindex nndoc -@cindex documentation group -@cindex help group - -@code{nndoc} is a cute little thing that will let you read a single file -as a newsgroup. Several files types are supported: - -@table @code -@cindex babyl -@cindex rmail mbox - -@item babyl -The babyl (rmail) mail box. -@cindex mbox -@cindex Unix mbox - -@item mbox -The standard Unix mbox file. - -@cindex MMDF mail box -@item mmdf -The MMDF mail box format. - -@item news -Several news articles appended into a file. - -@item rnews -@cindex rnews batch files -The rnews batch transport format. -@cindex forwarded messages - -@item forward -Forwarded articles. - -@item mime-parts -MIME multipart messages, besides digests. - -@item mime-digest -@cindex digest -@cindex MIME digest -@cindex 1153 digest -@cindex RFC 1153 digest -@cindex RFC 341 digest -MIME (RFC 1341) digest format. - -@item standard-digest -The standard (RFC 1153) digest format. - -@item slack-digest -Non-standard digest format---matches most things, but does it badly. -@end table - -You can also use the special ``file type'' @code{guess}, which means -that @code{nndoc} will try to guess what file type it is looking at. -@code{digest} means that @code{nndoc} should guess what digest type the -file is. - -@code{nndoc} will not try to change the file or insert any extra headers into -it---it will simply, like, let you use the file as the basis for a -group. And that's it. - -If you have some old archived articles that you want to insert into your -new & spiffy Gnus mail backend, @code{nndoc} can probably help you with -that. Say you have an old @file{RMAIL} file with mail that you now want -to split into your new @code{nnml} groups. You look at that file using -@code{nndoc} (using the @kbd{G f} command in the group buffer -(@pxref{Foreign Groups})), set the process mark on all the articles in -the buffer (@kbd{M P b}, for instance), and then re-spool (@kbd{B r}) -using @code{nnml}. If all goes well, all the mail in the @file{RMAIL} -file is now also stored in lots of @code{nnml} directories, and you can -delete that pesky @file{RMAIL} file. If you have the guts! - -Virtual server variables: - -@table @code -@item nndoc-article-type -@vindex nndoc-article-type -This should be one of @code{mbox}, @code{babyl}, @code{digest}, -@code{news}, @code{rnews}, @code{mmdf}, @code{forward}, @code{rfc934}, -@code{rfc822-forward}, @code{mime-parts}, @code{mime-digest}, -@code{standard-digest}, @code{slack-digest}, @code{clari-briefs} or -@code{guess}. - -@item nndoc-post-type -@vindex nndoc-post-type -This variable says whether Gnus is to consider the group a news group or -a mail group. There are two valid values: @code{mail} (the default) -and @code{news}. -@end table - -@menu -* Document Server Internals:: How to add your own document types. -@end menu - - -@node Document Server Internals -@subsubsection Document Server Internals - -Adding new document types to be recognized by @code{nndoc} isn't -difficult. You just have to whip up a definition of what the document -looks like, write a predicate function to recognize that document type, -and then hook into @code{nndoc}. - -First, here's an example document type definition: - -@example -(mmdf - (article-begin . "^\^A\^A\^A\^A\n") - (body-end . "^\^A\^A\^A\^A\n")) -@end example - -The definition is simply a unique @dfn{name} followed by a series of -regexp pseudo-variable settings. Below are the possible -variables---don't be daunted by the number of variables; most document -types can be defined with very few settings: - -@table @code -@item first-article -If present, @code{nndoc} will skip past all text until it finds -something that match this regexp. All text before this will be -totally ignored. - -@item article-begin -This setting has to be present in all document type definitions. It -says what the beginning of each article looks like. - -@item head-begin-function -If present, this should be a function that moves point to the head of -the article. - -@item nndoc-head-begin -If present, this should be a regexp that matches the head of the -article. - -@item nndoc-head-end -This should match the end of the head of the article. It defaults to -@samp{^$}---the empty line. - -@item body-begin-function -If present, this function should move point to the beginning of the body -of the article. - -@item body-begin -This should match the beginning of the body of the article. It defaults -to @samp{^\n}. - -@item body-end-function -If present, this function should move point to the end of the body of -the article. - -@item body-end -If present, this should match the end of the body of the article. - -@item file-end -If present, this should match the end of the file. All text after this -regexp will be totally ignored. - -@end table - -So, using these variables @code{nndoc} is able to dissect a document -file into a series of articles, each with a head and a body. However, a -few more variables are needed since not all document types are all that -news-like---variables needed to transform the head or the body into -something that's palatable for Gnus: - -@table @code -@item prepare-body-function -If present, this function will be called when requesting an article. It -will be called with point at the start of the body, and is useful if the -document has encoded some parts of its contents. - -@item article-transform-function -If present, this function is called when requesting an article. It's -meant to be used for more wide-ranging transformation of both head and -body of the article. - -@item generate-head-function -If present, this function is called to generate a head that Gnus can -understand. It is called with the article number as a parameter, and is -expected to generate a nice head for the article in question. It is -called when requesting the headers of all articles. - -@end table - -Let's look at the most complicated example I can come up with---standard -digests: - -@example -(standard-digest - (first-article . ,(concat "^" (make-string 70 ?-) "\n\n+")) - (article-begin . ,(concat "\n\n" (make-string 30 ?-) "\n\n+")) - (prepare-body-function . nndoc-unquote-dashes) - (body-end-function . nndoc-digest-body-end) - (head-end . "^ ?$") - (body-begin . "^ ?\n") - (file-end . "^End of .*digest.*[0-9].*\n\\*\\*\\|^End of.*Digest *$") - (subtype digest guess)) -@end example - -We see that all text before a 70-width line of dashes is ignored; all -text after a line that starts with that @samp{^End of} is also ignored; -each article begins with a 30-width line of dashes; the line separating -the head from the body may contain a single space; and that the body is -run through @code{nndoc-unquote-dashes} before being delivered. - -To hook your own document definition into @code{nndoc}, use the -@code{nndoc-add-type} function. It takes two parameters---the first is -the definition itself and the second (optional) parameter says where in -the document type definition alist to put this definition. The alist is -traversed sequentially, and @code{nndoc-TYPE-type-p} is called for a given type @code{TYPE}. So @code{nndoc-mmdf-type-p} is called to see whether a document -is of @code{mmdf} type, and so on. These type predicates should return -@code{nil} if the document is not of the correct type; @code{t} if it is -of the correct type; and a number if the document might be of the -correct type. A high number means high probability; a low number means -low probability with @samp{0} being the lowest valid number. - - -@node SOUP -@subsection SOUP -@cindex SOUP -@cindex offline - -In the PC world people often talk about ``offline'' newsreaders. These -are thingies that are combined reader/news transport monstrosities. -With built-in modem programs. Yecchh! - -Of course, us Unix Weenie types of human beans use things like -@code{uucp} and, like, @code{nntpd} and set up proper news and mail -transport things like Ghod intended. And then we just use normal -newsreaders. - -However, it can sometimes be convenient to do something a that's a bit -easier on the brain if you have a very slow modem, and you're not really -that interested in doing things properly. - -A file format called @sc{soup} has been developed for transporting news -and mail from servers to home machines and back again. It can be a bit -fiddly. - -First some terminology: - -@table @dfn - -@item server -This is the machine that is connected to the outside world and where you -get news and/or mail from. - -@item home machine -This is the machine that you want to do the actual reading and responding -on. It is typically not connected to the rest of the world in any way. - -@item packet -Something that contains messages and/or commands. There are two kinds -of packets: - -@table @dfn -@item message packets -These are packets made at the server, and typically contain lots of -messages for you to read. These are called @file{SoupoutX.tgz} by -default, where @var{X} is a number. - -@item response packets -These are packets made at the home machine, and typically contains -replies that you've written. These are called @file{SoupinX.tgz} by -default, where @var{X} is a number. - -@end table - -@end table - - -@enumerate - -@item -You log in on the server and create a @sc{soup} packet. You can either -use a dedicated @sc{soup} thingie (like the @code{awk} program), or you -can use Gnus to create the packet with its @sc{soup} commands (@kbd{O -s} and/or @kbd{G s b}; and then @kbd{G s p}) (@pxref{SOUP Commands}). - -@item -You transfer the packet home. Rail, boat, car or modem will do fine. - -@item -You put the packet in your home directory. - -@item -You fire up Gnus on your home machine using the @code{nnsoup} backend as -the native or secondary server. - -@item -You read articles and mail and answer and followup to the things you -want (@pxref{SOUP Replies}). - -@item -You do the @kbd{G s r} command to pack these replies into a @sc{soup} -packet. - -@item -You transfer this packet to the server. - -@item -You use Gnus to mail this packet out with the @kbd{G s s} command. - -@item -You then repeat until you die. - -@end enumerate - -So you basically have a bipartite system---you use @code{nnsoup} for -reading and Gnus for packing/sending these @sc{soup} packets. - -@menu -* SOUP Commands:: Commands for creating and sending @sc{soup} packets -* SOUP Groups:: A backend for reading @sc{soup} packets. -* SOUP Replies:: How to enable @code{nnsoup} to take over mail and news. -@end menu - - -@node SOUP Commands -@subsubsection SOUP Commands - -These are commands for creating and manipulating @sc{soup} packets. - -@table @kbd -@item G s b -@kindex G s b (Group) -@findex gnus-group-brew-soup -Pack all unread articles in the current group -(@code{gnus-group-brew-soup}). This command understands the -process/prefix convention. - -@item G s w -@kindex G s w (Group) -@findex gnus-soup-save-areas -Save all @sc{soup} data files (@code{gnus-soup-save-areas}). - -@item G s s -@kindex G s s (Group) -@findex gnus-soup-send-replies -Send all replies from the replies packet -(@code{gnus-soup-send-replies}). - -@item G s p -@kindex G s p (Group) -@findex gnus-soup-pack-packet -Pack all files into a @sc{soup} packet (@code{gnus-soup-pack-packet}). - -@item G s r -@kindex G s r (Group) -@findex nnsoup-pack-replies -Pack all replies into a replies packet (@code{nnsoup-pack-replies}). - -@item O s -@kindex O s (Summary) -@findex gnus-soup-add-article -This summary-mode command adds the current article to a @sc{soup} packet -(@code{gnus-soup-add-article}). It understands the process/prefix -convention (@pxref{Process/Prefix}). - -@end table - - -There are a few variables to customize where Gnus will put all these -thingies: - -@table @code - -@item gnus-soup-directory -@vindex gnus-soup-directory -Directory where Gnus will save intermediate files while composing -@sc{soup} packets. The default is @file{~/SoupBrew/}. - -@item gnus-soup-replies-directory -@vindex gnus-soup-replies-directory -This is what Gnus will use as a temporary directory while sending our -reply packets. @file{~/SoupBrew/SoupReplies/} is the default. - -@item gnus-soup-prefix-file -@vindex gnus-soup-prefix-file -Name of the file where Gnus stores the last used prefix. The default is -@samp{gnus-prefix}. - -@item gnus-soup-packer -@vindex gnus-soup-packer -A format string command for packing a @sc{soup} packet. The default is -@samp{tar cf - %s | gzip > $HOME/Soupout%d.tgz}. - -@item gnus-soup-unpacker -@vindex gnus-soup-unpacker -Format string command for unpacking a @sc{soup} packet. The default is -@samp{gunzip -c %s | tar xvf -}. - -@item gnus-soup-packet-directory -@vindex gnus-soup-packet-directory -Where Gnus will look for reply packets. The default is @file{~/}. - -@item gnus-soup-packet-regexp -@vindex gnus-soup-packet-regexp -Regular expression matching @sc{soup} reply packets in -@code{gnus-soup-packet-directory}. - -@end table - - -@node SOUP Groups -@subsubsection @sc{soup} Groups -@cindex nnsoup - -@code{nnsoup} is the backend for reading @sc{soup} packets. It will -read incoming packets, unpack them, and put them in a directory where -you can read them at leisure. - -These are the variables you can use to customize its behavior: - -@table @code - -@item nnsoup-tmp-directory -@vindex nnsoup-tmp-directory -When @code{nnsoup} unpacks a @sc{soup} packet, it does it in this -directory. (@file{/tmp/} by default.) - -@item nnsoup-directory -@vindex nnsoup-directory -@code{nnsoup} then moves each message and index file to this directory. -The default is @file{~/SOUP/}. - -@item nnsoup-replies-directory -@vindex nnsoup-replies-directory -All replies will be stored in this directory before being packed into a -reply packet. The default is @file{~/SOUP/replies/"}. - -@item nnsoup-replies-format-type -@vindex nnsoup-replies-format-type -The @sc{soup} format of the replies packets. The default is @samp{?n} -(rnews), and I don't think you should touch that variable. I probably -shouldn't even have documented it. Drats! Too late! - -@item nnsoup-replies-index-type -@vindex nnsoup-replies-index-type -The index type of the replies packet. The default is @samp{?n}, which -means ``none''. Don't fiddle with this one either! - -@item nnsoup-active-file -@vindex nnsoup-active-file -Where @code{nnsoup} stores lots of information. This is not an ``active -file'' in the @code{nntp} sense; it's an Emacs Lisp file. If you lose -this file or mess it up in any way, you're dead. The default is -@file{~/SOUP/active}. - -@item nnsoup-packer -@vindex nnsoup-packer -Format string command for packing a reply @sc{soup} packet. The default -is @samp{tar cf - %s | gzip > $HOME/Soupin%d.tgz}. - -@item nnsoup-unpacker -@vindex nnsoup-unpacker -Format string command for unpacking incoming @sc{soup} packets. The -default is @samp{gunzip -c %s | tar xvf -}. - -@item nnsoup-packet-directory -@vindex nnsoup-packet-directory -Where @code{nnsoup} will look for incoming packets. The default is -@file{~/}. - -@item nnsoup-packet-regexp -@vindex nnsoup-packet-regexp -Regular expression matching incoming @sc{soup} packets. The default is -@samp{Soupout}. - -@item nnsoup-always-save -@vindex nnsoup-always-save -If non-@code{nil}, save the replies buffer after each posted message. - -@end table - - -@node SOUP Replies -@subsubsection SOUP Replies - -Just using @code{nnsoup} won't mean that your postings and mailings end -up in @sc{soup} reply packets automagically. You have to work a bit -more for that to happen. - -@findex nnsoup-set-variables -The @code{nnsoup-set-variables} command will set the appropriate -variables to ensure that all your followups and replies end up in the -@sc{soup} system. - -In specific, this is what it does: - -@lisp -(setq message-send-news-function 'nnsoup-request-post) -(setq message-send-mail-function 'nnsoup-request-mail) -@end lisp - -And that's it, really. If you only want news to go into the @sc{soup} -system you just use the first line. If you only want mail to be -@sc{soup}ed you use the second. - - -@node Web Searches -@subsection Web Searches -@cindex nnweb -@cindex DejaNews -@cindex Alta Vista -@cindex InReference -@cindex Usenet searches -@cindex searching the Usenet - -It's, like, too neat to search the Usenet for articles that match a -string, but it, like, totally @emph{sucks}, like, totally, to use one of -those, like, Web browsers, and you, like, have to, rilly, like, look at -the commercials, so, like, with Gnus you can do @emph{rad}, rilly, -searches without having to use a browser. - -The @code{nnweb} backend allows an easy interface to the mighty search -engine. You create an @code{nnweb} group, enter a search pattern, and -then enter the group and read the articles like you would any normal -group. The @kbd{G w} command in the group buffer (@pxref{Foreign -Groups}) will do this in an easy-to-use fashion. - -@code{nnweb} groups don't really lend themselves to being solid -groups---they have a very fleeting idea of article numbers. In fact, -each time you enter an @code{nnweb} group (not even changing the search -pattern), you are likely to get the articles ordered in a different -manner. Not even using duplicate suppression (@pxref{Duplicate -Suppression}) will help, since @code{nnweb} doesn't even know the -@code{Message-ID} of the articles before reading them using some search -engines (DejaNews, for instance). The only possible way to keep track -of which articles you've read is by scoring on the @code{Date} -header---mark all articles posted before the last date you read the -group as read. - -If the search engine changes its output substantially, @code{nnweb} -won't be able to parse it and will fail. One could hardly fault the Web -providers if they were to do this---their @emph{raison d',Aj(Btre} is to -make money off of advertisements, not to provide services to the -community. Since @code{nnweb} washes the ads off all the articles, one -might think that the providers might be somewhat miffed. We'll see. - -You must have the @code{url} and @code{w3} package installed to be able -to use @code{nnweb}. - -Virtual server variables: - -@table @code -@item nnweb-type -@vindex nnweb-type -What search engine type is being used. The currently supported types -are @code{dejanews}, @code{dejanewsold}, @code{altavista} and -@code{reference}. - -@item nnweb-search -@vindex nnweb-search -The search string to feed to the search engine. - -@item nnweb-max-hits -@vindex nnweb-max-hits -Advisory maximum number of hits per search to display. The default is -100. - -@item nnweb-type-definition -@vindex nnweb-type-definition -Type-to-definition alist. This alist says what @code{nnweb} should do -with the various search engine types. The following elements must be -present: - -@table @code -@item article -Function to decode the article and provide something that Gnus -understands. - -@item map -Function to create an article number to message header and URL alist. - -@item search -Function to send the search string to the search engine. - -@item address -The address the aforementioned function should send the search string -to. - -@item id -Format string URL to fetch an article by @code{Message-ID}. -@end table - -@end table - - - -@node Mail-To-News Gateways -@subsection Mail-To-News Gateways -@cindex mail-to-news gateways -@cindex gateways - -If your local @code{nntp} server doesn't allow posting, for some reason -or other, you can post using one of the numerous mail-to-news gateways. -The @code{nngateway} backend provides the interface. - -Note that you can't read anything from this backend---it can only be -used to post with. - -Server variables: - -@table @code -@item nngateway-address -@vindex nngateway-address -This is the address of the mail-to-news gateway. - -@item nngateway-header-transformation -@vindex nngateway-header-transformation -News headers often have to be transformed in some odd way or other -for the mail-to-news gateway to accept it. This variable says what -transformation should be called, and defaults to -@code{nngateway-simple-header-transformation}. The function is called -narrowed to the headers to be transformed and with one parameter---the -gateway address. - -This default function just inserts a new @code{To} header based on the -@code{Newsgroups} header and the gateway address. -For instance, an article with this @code{Newsgroups} header: - -@example -Newsgroups: alt.religion.emacs -@end example - -will get this @code{From} header inserted: - -@example -To: alt-religion-emacs@@GATEWAY -@end example - -The following pre-defined functions exist: - -@findex nngateway-simple-header-transformation -@table @code - -@item nngateway-simple-header-transformation -Creates a @code{To} header that looks like -@var{newsgroup}@@@code{nngateway-address}. - -@findex nngateway-mail2news-header-transformation - -@item nngateway-mail2news-header-transformation -Creates a @code{To} header that looks like -@code{nngateway-address}. - -Here's an example: - -@lisp -(setq gnus-post-method - '(nngateway "mail2news@@replay.com" - (nngateway-header-transformation - nngateway-mail2news-header-transformation))) -@end lisp - -@end table - - -@end table - -So, to use this, simply say something like: - -@lisp -(setq gnus-post-method '(nngateway "GATEWAY.ADDRESS")) -@end lisp - - -@node Combined Groups -@section Combined Groups - -Gnus allows combining a mixture of all the other group types into bigger -groups. - -@menu -* Virtual Groups:: Combining articles from many groups. -* Kibozed Groups:: Looking through parts of the newsfeed for articles. -@end menu - - -@node Virtual Groups -@subsection Virtual Groups -@cindex nnvirtual -@cindex virtual groups -@cindex merging groups - -An @dfn{nnvirtual group} is really nothing more than a collection of -other groups. - -For instance, if you are tired of reading many small groups, you can -put them all in one big group, and then grow tired of reading one -big, unwieldy group. The joys of computing! - -You specify @code{nnvirtual} as the method. The address should be a -regexp to match component groups. - -All marks in the virtual group will stick to the articles in the -component groups. So if you tick an article in a virtual group, the -article will also be ticked in the component group from whence it came. -(And vice versa---marks from the component groups will also be shown in -the virtual group.) - -Here's an example @code{nnvirtual} method that collects all Andrea Dworkin -newsgroups into one, big, happy newsgroup: - -@lisp -(nnvirtual "^alt\\.fan\\.andrea-dworkin$\\|^rec\\.dworkin.*") -@end lisp - -The component groups can be native or foreign; everything should work -smoothly, but if your computer explodes, it was probably my fault. - -Collecting the same group from several servers might actually be a good -idea if users have set the Distribution header to limit distribution. -If you would like to read @samp{soc.motss} both from a server in Japan -and a server in Norway, you could use the following as the group regexp: - -@example -"^nntp\\+server\\.jp:soc\\.motss$\\|^nntp\\+server\\.no:soc\\.motss$" -@end example - -(Remember, though, that if you're creating the group with @kbd{G m}, you -shouldn't double the backslashes, and you should leave off the quote -characters at the beginning and the end of the string.) - -This should work kinda smoothly---all articles from both groups should -end up in this one, and there should be no duplicates. Threading (and -the rest) will still work as usual, but there might be problems with the -sequence of articles. Sorting on date might be an option here -(@pxref{Selecting a Group}). - -One limitation, however---all groups included in a virtual -group have to be alive (i.e., subscribed or unsubscribed). Killed or -zombie groups can't be component groups for @code{nnvirtual} groups. - -@vindex nnvirtual-always-rescan -If the @code{nnvirtual-always-rescan} is non-@code{nil}, -@code{nnvirtual} will always scan groups for unread articles when -entering a virtual group. If this variable is @code{nil} (which is the -default) and you read articles in a component group after the virtual -group has been activated, the read articles from the component group -will show up when you enter the virtual group. You'll also see this -effect if you have two virtual groups that have a component group in -common. If that's the case, you should set this variable to @code{t}. -Or you can just tap @code{M-g} on the virtual group every time before -you enter it---it'll have much the same effect. - -@code{nnvirtual} can have both mail and news groups as component groups. -When responding to articles in @code{nnvirtual} groups, @code{nnvirtual} -has to ask the backend of the component group the article comes from -whether it is a news or mail backend. However, when you do a @kbd{^}, -there is typically no sure way for the component backend to know this, -and in that case @code{nnvirtual} tells Gnus that the article came from a -not-news backend. (Just to be on the safe side.) - -@kbd{C-c C-t} in the message buffer will insert the @code{Newsgroups} -line from the article you respond to in these cases. - - - -@node Kibozed Groups -@subsection Kibozed Groups -@cindex nnkiboze -@cindex kibozing - -@dfn{Kibozing} is defined by @sc{oed} as ``grepping through (parts of) -the news feed''. @code{nnkiboze} is a backend that will do this for -you. Oh joy! Now you can grind any @sc{nntp} server down to a halt -with useless requests! Oh happiness! - -@kindex G k (Group) -To create a kibozed group, use the @kbd{G k} command in the group -buffer. - -The address field of the @code{nnkiboze} method is, as with -@code{nnvirtual}, a regexp to match groups to be ``included'' in the -@code{nnkiboze} group. That's where most similarities between @code{nnkiboze} -and @code{nnvirtual} end. - -In addition to this regexp detailing component groups, an @code{nnkiboze} group -must have a score file to say what articles are to be included in -the group (@pxref{Scoring}). - -@kindex M-x nnkiboze-generate-groups -@findex nnkiboze-generate-groups -You must run @kbd{M-x nnkiboze-generate-groups} after creating the -@code{nnkiboze} groups you want to have. This command will take time. Lots of -time. Oodles and oodles of time. Gnus has to fetch the headers from -all the articles in all the component groups and run them through the -scoring process to determine if there are any articles in the groups -that are to be part of the @code{nnkiboze} groups. - -Please limit the number of component groups by using restrictive -regexps. Otherwise your sysadmin may become annoyed with you, and the -@sc{nntp} site may throw you off and never let you back in again. -Stranger things have happened. - -@code{nnkiboze} component groups do not have to be alive---they can be dead, -and they can be foreign. No restrictions. - -@vindex nnkiboze-directory -The generation of an @code{nnkiboze} group means writing two files in -@code{nnkiboze-directory}, which is @file{~/News/} by default. One -contains the @sc{nov} header lines for all the articles in the group, -and the other is an additional @file{.newsrc} file to store information -on what groups have been searched through to find component articles. - -Articles marked as read in the @code{nnkiboze} group will have -their @sc{nov} lines removed from the @sc{nov} file. - - -@node Gnus Unplugged -@section Gnus Unplugged -@cindex offline -@cindex unplugged -@cindex Agent -@cindex Gnus Agent -@cindex Gnus Unplugged - -In olden times (ca. February '88), people used to run their newsreaders -on big machines with permanent connections to the net. News transport -was dealt with by news servers, and all the newsreaders had to do was to -read news. Believe it or not. - -Nowadays most people read news and mail at home, and use some sort of -modem to connect to the net. To avoid running up huge phone bills, it -would be nice to have a way to slurp down all the news and mail, hang up -the phone, read for several hours, and then upload any responses you -have to make. And then you repeat the procedure. - -Of course, you can use news servers for doing this as well. I've used -@code{inn} together with @code{slurp}, @code{pop} and @code{sendmail} -for some years, but doing that's a bore. Moving the news server -functionality up to the newsreader makes sense if you're the only person -reading news on a machine. - -Using Gnus as an ``offline'' newsreader is quite simple. - -@itemize @bullet -@item -First, set up Gnus as you would do if you were running it on a machine -that has full connection to the net. Go ahead. I'll still be waiting -here. - -@item -Then, put the following magical incantation at the end of your -@file{.gnus.el} file: - -@lisp -(gnus-agentize) -@end lisp -@end itemize - -That's it. Gnus is now an ``offline'' newsreader. - -Of course, to use it as such, you have to learn a few new commands. - -@menu -* Agent Basics:: How it all is supposed to work. -* Agent Categories:: How to tell the Gnus Agent what to download. -* Agent Commands:: New commands for all the buffers. -* Agent Expiry:: How to make old articles go away. -* Outgoing Messages:: What happens when you post/mail something? -* Agent Variables:: Customizing is fun. -* Example Setup:: An example @file{.gnus.el} file for offline people. -* Batching Agents:: How to fetch news from a @code{cron} job. -@end menu - - -@node Agent Basics -@subsection Agent Basics - -First, let's get some terminology out of the way. - -The Gnus Agent is said to be @dfn{unplugged} when you have severed the -connection to the net (and notified the Agent that this is the case). -When the connection to the net is up again (and Gnus knows this), the -Agent is @dfn{plugged}. - -The @dfn{local} machine is the one you're running on, and which isn't -connected to the net continuously. - -@dfn{Downloading} means fetching things from the net to your local -machine. @dfn{Uploading} is doing the opposite. - -Let's take a typical Gnus session using the Agent. - -@itemize @bullet - -@item -You start Gnus with @code{gnus-unplugged}. This brings up the Gnus -Agent in a disconnected state. You can read all the news that you have -already fetched while in this mode. - -@item -You then decide to see whether any new news has arrived. You connect -your machine to the net (using PPP or whatever), and then hit @kbd{J j} -to make Gnus become @dfn{plugged}. - -@item -You can then read the new news immediately, or you can download the news -onto your local machine. If you want to do the latter, you press @kbd{J -s} to fetch all the eligible articles in all the groups. (To let Gnus -know which articles you want to download, @pxref{Agent Categories}.) - -@item -After fetching the articles, you press @kbd{J j} to make Gnus become -unplugged again, and you shut down the PPP thing (or whatever). And -then you read the news offline. - -@item -And then you go to step 2. -@end itemize - -Here are some things you should do the first time (or so) that you use -the Agent. - -@itemize @bullet - -@item -Decide which servers should be covered by the Agent. If you have a mail -backend, it would probably be nonsensical to have it covered by the -Agent. Go to the server buffer (@kbd{^} in the group buffer) and press -@kbd{J a} the server (or servers) that you wish to have covered by the -Agent (@pxref{Server Agent Commands}). This will typically be only the -primary select method, which is listed on the bottom in the buffer. - -@item -Decide on download policy. @xref{Agent Categories} - -@item -Uhm... that's it. -@end itemize - - -@node Agent Categories -@subsection Agent Categories - -One of the main reasons to integrate the news transport layer into the -newsreader is to allow greater control over what articles to download. -There's not much point in downloading huge amounts of articles, just to -find out that you're not interested in reading any of them. It's better -to be somewhat more conservative in choosing what to download, and then -mark the articles for downloading manually if it should turn out that -you're interested in the articles anyway. - -The main way to control what is to be downloaded is to create a -@dfn{category} and then assign some (or all) groups to this category. -Gnus has its own buffer for creating and managing categories. - -@menu -* Category Syntax:: What a category looks like. -* The Category Buffer:: A buffer for maintaining categories. -* Category Variables:: Customize'r'Us. -@end menu - - -@node Category Syntax -@subsubsection Category Syntax - -A category consists of two things. - -@enumerate -@item -A predicate which (generally) gives a rough outline of which articles -are eligible for downloading; and - -@item -a score rule which (generally) gives you a finer granularity when -deciding what articles to download. (Note that this @dfn{download -score} is wholly unrelated to normal scores.) -@end enumerate - -A predicate consists of predicates with logical operators sprinkled in -between. - -Perhaps some examples are in order. - -Here's a simple predicate. (It's the default predicate, in fact, used -for all groups that don't belong to any other category.) - -@lisp -short -@end lisp - -Quite simple, eh? This predicate is true if and only if the article is -short (for some value of ``short''). - -Here's a more complex predicate: - -@lisp -(or high - (and - (not low) - (not long))) -@end lisp - -This means that an article should be downloaded if it has a high score, -or if the score is not low and the article is not long. You get the -drift. - -The available logical operators are @code{or}, @code{and} and -@code{not}. (If you prefer, you can use the more ``C''-ish operators -@samp{|}, @code{&} and @code{!} instead.) - -The following predicates are pre-defined, but if none of these fit what -you want to do, you can write your own. - -@table @code -@item short -True iff the article is shorter than @code{gnus-agent-short-article} -lines; default 100. - -@item long -True iff the article is longer than @code{gnus-agent-long-article} -lines; default 200. - -@item low -True iff the article has a download score less than -@code{gnus-agent-low-score}; default 0. - -@item high -True iff the article has a download score greater than -@code{gnus-agent-high-score}; default 0. - -@item spam -True iff the Gnus Agent guesses that the article is spam. The -heuristics may change over time, but at present it just computes a -checksum and sees whether articles match. - -@item true -Always true. - -@item false -Always false. -@end table - -If you want to create your own predicate function, here's what you have -to know: The functions are called with no parameters, but the -@code{gnus-headers} and @code{gnus-score} dynamic variables are bound to -useful values. - -Now, the syntax of the download score is the same as the syntax of -normal score files, except that all elements that require actually -seeing the article itself are verboten. This means that only the -following headers can be scored on: @code{From}, @code{Subject}, -@code{Date}, @code{Xref}, @code{Lines}, @code{Chars}, @code{Message-ID}, -and @code{References}. - - -@node The Category Buffer -@subsubsection The Category Buffer - -You'd normally do all category maintenance from the category buffer. -When you enter it for the first time (with the @kbd{J c} command from -the group buffer), you'll only see the @code{default} category. - -The following commands are available in this buffer: - -@table @kbd -@item q -@kindex q (Category) -@findex gnus-category-exit -Return to the group buffer (@code{gnus-category-exit}). - -@item k -@kindex k (Category) -@findex gnus-category-kill -Kill the current category (@code{gnus-category-kill}). - -@item c -@kindex c (Category) -@findex gnus-category-copy -Copy the current category (@code{gnus-category-copy}). - -@item a -@kindex a (Category) -@findex gnus-category-add -Add a new category (@code{gnus-category-add}). - -@item p -@kindex p (Category) -@findex gnus-category-edit-predicate -Edit the predicate of the current category -(@code{gnus-category-edit-predicate}). - -@item g -@kindex g (Category) -@findex gnus-category-edit-groups -Edit the list of groups belonging to the current category -(@code{gnus-category-edit-groups}). - -@item s -@kindex s (Category) -@findex gnus-category-edit-score -Edit the download score rule of the current category -(@code{gnus-category-edit-score}). - -@item l -@kindex l (Category) -@findex gnus-category-list -List all the categories (@code{gnus-category-list}). -@end table - - -@node Category Variables -@subsubsection Category Variables - -@table @code -@item gnus-category-mode-hook -@vindex gnus-category-mode-hook -Hook run in category buffers. - -@item gnus-category-line-format -@vindex gnus-category-line-format -Format of the lines in the category buffer (@pxref{Formatting -Variables}). Valid elements are: - -@table @samp -@item c -The name of the category. - -@item g -The number of groups in the category. -@end table - -@item gnus-category-mode-line-format -@vindex gnus-category-mode-line-format -Format of the category mode line (@pxref{Mode Line Formatting}). - -@item gnus-agent-short-article -@vindex gnus-agent-short-article -Articles that have fewer lines than this are short. Default 100. - -@item gnus-agent-long-article -@vindex gnus-agent-long-article -Articles that have more lines than this are long. Default 200. - -@item gnus-agent-low-score -@vindex gnus-agent-low-score -Articles that have a score lower than this have a low score. Default -0. - -@item gnus-agent-high-score -@vindex gnus-agent-high-score -Articles that have a score higher than this have a high score. Default -0. - -@end table - - -@node Agent Commands -@subsection Agent Commands - -All the Gnus Agent commands are on the @kbd{J} submap. The @kbd{J j} -(@code{gnus-agent-toggle-plugged} command works in all modes, and -toggles the plugged/unplugged state of the Gnus Agent. - - -@menu -* Group Agent Commands:: -* Summary Agent Commands:: -* Server Agent Commands:: -@end menu - -You can run a complete batch fetch from the command line with the -following incantation: - -@cindex gnus-agent-batch-fetch -@example -$ emacs -batch -l ~/.gnus.el -f gnus-agent-batch-fetch -@end example - - - -@node Group Agent Commands -@subsubsection Group Agent Commands - -@table @kbd -@item J u -@kindex J u (Agent Group) -@findex gnus-agent-fetch-groups -Fetch all eligible articles in the current group -(@code{gnus-agent-fetch-groups}). - -@item J c -@kindex J c (Agent Group) -@findex gnus-enter-category-buffer -Enter the Agent category buffer (@code{gnus-enter-category-buffer}). - -@item J s -@kindex J s (Agent Group) -@findex gnus-agent-fetch-session -Fetch all eligible articles in all groups -(@code{gnus-agent-fetch-session}). - -@item J S -@kindex J S (Agent Group) -@findex gnus-group-send-drafts -Send all sendable messages in the draft group -(@code{gnus-agent-send-draft}). @xref{Drafts} - -@item J a -@kindex J a (Agent Group) -@findex gnus-agent-add-group -Add the current group to an Agent category -(@code{gnus-agent-add-group}). - -@end table - - -@node Summary Agent Commands -@subsubsection Summary Agent Commands - -@table @kbd -@item J # -@kindex J # (Agent Summary) -@findex gnus-agent-mark-article -Mark the article for downloading (@code{gnus-agent-mark-article}). - -@item J M-# -@kindex J M-# (Agent Summary) -@findex gnus-agent-unmark-article -Remove the downloading mark from the article -(@code{gnus-agent-unmark-article}). - -@item @@ -@kindex @@ (Agent Summary) -@findex gnus-agent-toggle-mark -Toggle whether to download the article (@code{gnus-agent-toggle-mark}). - -@item J c -@kindex J c (Agent Summary) -@findex gnus-agent-catchup -Mark all undownloaded articles as read (@code{gnus-agent-catchup}). - -@end table - - -@node Server Agent Commands -@subsubsection Server Agent Commands - -@table @kbd -@item J a -@kindex J a (Agent Server) -@findex gnus-agent-add-server -Add the current server to the list of servers covered by the Gnus Agent -(@code{gnus-agent-add-server}). - -@item J r -@kindex J r (Agent Server) -@findex gnus-agent-remove-server -Remove the current server from the list of servers covered by the Gnus -Agent (@code{gnus-agent-remove-server}). - -@end table - - -@node Agent Expiry -@subsection Agent Expiry - -@vindex gnus-agent-expiry-days -@findex gnus-agent-expiry -@kindex M-x gnus-agent-expiry -@cindex Agent expiry -@cindex Gnus Agent expiry -@cindex expiry - -@code{nnagent} doesn't handle expiry. Instead, there's a special -@code{gnus-agent-expiry} command that will expire all read articles that -are older than @code{gnus-agent-expiry-days} days. It can be run -whenever you feel that you're running out of space. It's not -particularly fast or efficient, and it's not a particularly good idea to -interrupt it (with @kbd{C-g} or anything else) once you've started it. - -@vindex gnus-agent-expire-all -if @code{gnus-agent-expire-all} is non-@code{nil}, this command will -expire all articles---unread, read, ticked and dormant. If @code{nil} -(which is the default), only read articles are eligible for expiry, and -unread, ticked and dormant articles will be kept indefinitely. - - -@node Outgoing Messages -@subsection Outgoing Messages - -When Gnus is unplugged, all outgoing messages (both mail and news) are -stored in the draft groups (@pxref{Drafts}). You can view them there -after posting, and edit them at will. - -When Gnus is plugged again, you can send the messages either from the -draft group with the special commands available there, or you can use -the @kbd{J S} command in the group buffer to send all the sendable -messages in the draft group. - - - -@node Agent Variables -@subsection Agent Variables - -@table @code -@item gnus-agent-directory -@vindex gnus-agent-directory -Where the Gnus Agent will store its files. The default is -@file{~/News/agent/}. - -@item gnus-agent-handle-level -@vindex gnus-agent-handle-level -Groups on levels (@pxref{Group Levels}) higher than this variable will -be ignored by the Agent. The default is @code{gnus-level-subscribed}, -which means that only subscribed group will be considered by the Agent -by default. - -@item gnus-agent-plugged-hook -@vindex gnus-agent-plugged-hook -Hook run when connecting to the network. - -@item gnus-agent-unplugged-hook -@vindex gnus-agent-unplugged-hook -Hook run when disconnecting from the network. - -@end table - - -@node Example Setup -@subsection Example Setup - -If you don't want to read this manual, and you have a fairly standard -setup, you may be able to use something like the following as your -@file{.gnus.el} file to get started. - -@lisp -;;; Define how Gnus is to fetch news. We do this over NNTP -;;; from your ISP's server. -(setq gnus-select-method '(nntp "nntp.your-isp.com")) - -;;; Define how Gnus is to read your mail. We read mail from -;;; your ISP's POP server. -(setenv "MAILHOST" "pop.your-isp.com") -(setq nnmail-spool-file "po:username") - -;;; Say how Gnus is to store the mail. We use nnml groups. -(setq gnus-secondary-select-methods '((nnml ""))) - -;;; Make Gnus into an offline newsreader. -(gnus-agentize) -@end lisp - -That should be it, basically. Put that in your @file{~/.gnus.el} file, -edit to suit your needs, start up PPP (or whatever), and type @kbd{M-x -gnus}. - -If this is the first time you've run Gnus, you will be subscribed -automatically to a few default newsgroups. You'll probably want to -subscribe to more groups, and to do that, you have to query the -@sc{nntp} server for a complete list of groups with the @kbd{A A} -command. This usually takes quite a while, but you only have to do it -once. - -After reading and parsing a while, you'll be presented with a list of -groups. Subscribe to the ones you want to read with the @kbd{u} -command. @kbd{l} to make all the killed groups disappear after you've -subscribe to all the groups you want to read. (@kbd{A k} will bring -back all the killed groups.) - -You can now read the groups at once, or you can download the articles -with the @kbd{J s} command. And then read the rest of this manual to -find out which of the other gazillion things you want to customize. - - -@node Batching Agents -@subsection Batching Agents - -Having the Gnus Agent fetch articles (and post whatever messages you've -written) is quite easy once you've gotten things set up properly. The -following shell script will do everything that is necessary: - -@example -#!/bin/sh -emacs -batch -l ~/.emacs -f gnus-agent-batch >/dev/null -@end example - - - -@node Scoring -@chapter Scoring -@cindex scoring - -Other people use @dfn{kill files}, but we here at Gnus Towers like -scoring better than killing, so we'd rather switch than fight. They do -something completely different as well, so sit up straight and pay -attention! - -@vindex gnus-summary-mark-below -All articles have a default score (@code{gnus-summary-default-score}), -which is 0 by default. This score may be raised or lowered either -interactively or by score files. Articles that have a score lower than -@code{gnus-summary-mark-below} are marked as read. - -Gnus will read any @dfn{score files} that apply to the current group -before generating the summary buffer. - -There are several commands in the summary buffer that insert score -entries based on the current article. You can, for instance, ask Gnus to -lower or increase the score of all articles with a certain subject. - -There are two sorts of scoring entries: Permanent and temporary. -Temporary score entries are self-expiring entries. Any entries that are -temporary and have not been used for, say, a week, will be removed -silently to help keep the sizes of the score files down. - -@menu -* Summary Score Commands:: Adding score entries for the current group. -* Group Score Commands:: General score commands. -* Score Variables:: Customize your scoring. (My, what terminology). -* Score File Format:: What a score file may contain. -* Score File Editing:: You can edit score files by hand as well. -* Adaptive Scoring:: Big Sister Gnus knows what you read. -* Home Score File:: How to say where new score entries are to go. -* Followups To Yourself:: Having Gnus notice when people answer you. -* Scoring Tips:: How to score effectively. -* Reverse Scoring:: That problem child of old is not problem. -* Global Score Files:: Earth-spanning, ear-splitting score files. -* Kill Files:: They are still here, but they can be ignored. -* Converting Kill Files:: Translating kill files to score files. -* GroupLens:: Getting predictions on what you like to read. -* Advanced Scoring:: Using logical expressions to build score rules. -* Score Decays:: It can be useful to let scores wither away. -@end menu - - -@node Summary Score Commands -@section Summary Score Commands -@cindex score commands - -The score commands that alter score entries do not actually modify real -score files. That would be too inefficient. Gnus maintains a cache of -previously loaded score files, one of which is considered the -@dfn{current score file alist}. The score commands simply insert -entries into this list, and upon group exit, this list is saved. - -The current score file is by default the group's local score file, even -if no such score file actually exists. To insert score commands into -some other score file (e.g. @file{all.SCORE}), you must first make this -score file the current one. - -General score commands that don't actually change the score file: - -@table @kbd - -@item V s -@kindex V s (Summary) -@findex gnus-summary-set-score -Set the score of the current article (@code{gnus-summary-set-score}). - -@item V S -@kindex V S (Summary) -@findex gnus-summary-current-score -Display the score of the current article -(@code{gnus-summary-current-score}). - -@item V t -@kindex V t (Summary) -@findex gnus-score-find-trace -Display all score rules that have been used on the current article -(@code{gnus-score-find-trace}). - -@item V R -@kindex V R (Summary) -@findex gnus-summary-rescore -Run the current summary through the scoring process -(@code{gnus-summary-rescore}). This might be useful if you're playing -around with your score files behind Gnus' back and want to see the -effect you're having. - -@item V c -@kindex V c (Summary) -@findex gnus-score-change-score-file -Make a different score file the current -(@code{gnus-score-change-score-file}). - -@item V e -@kindex V e (Summary) -@findex gnus-score-edit-current-scores -Edit the current score file (@code{gnus-score-edit-current-scores}). -You will be popped into a @code{gnus-score-mode} buffer (@pxref{Score -File Editing}). - -@item V f -@kindex V f (Summary) -@findex gnus-score-edit-file -Edit a score file and make this score file the current one -(@code{gnus-score-edit-file}). - -@item V F -@kindex V F (Summary) -@findex gnus-score-flush-cache -Flush the score cache (@code{gnus-score-flush-cache}). This is useful -after editing score files. - -@item V C -@kindex V C (Summary) -@findex gnus-score-customize -Customize a score file in a visually pleasing manner -(@code{gnus-score-customize}). - -@end table - -The rest of these commands modify the local score file. - -@table @kbd - -@item V m -@kindex V m (Summary) -@findex gnus-score-set-mark-below -Prompt for a score, and mark all articles with a score below this as -read (@code{gnus-score-set-mark-below}). - -@item V x -@kindex V x (Summary) -@findex gnus-score-set-expunge-below -Prompt for a score, and add a score rule to the current score file to -expunge all articles below this score -(@code{gnus-score-set-expunge-below}). -@end table - -The keystrokes for actually making score entries follow a very regular -pattern, so there's no need to list all the commands. (Hundreds of -them.) - -@findex gnus-summary-increase-score -@findex gnus-summary-lower-score - -@enumerate -@item -The first key is either @kbd{I} (upper case i) for increasing the score -or @kbd{L} for lowering the score. -@item -The second key says what header you want to score on. The following -keys are available: -@table @kbd - -@item a -Score on the author name. - -@item s -Score on the subject line. - -@item x -Score on the Xref line---i.e., the cross-posting line. - -@item r -Score on the References line. - -@item d -Score on the date. - -@item l -Score on the number of lines. - -@item i -Score on the Message-ID. - -@item f -Score on followups. - -@item b -Score on the body. - -@item h -Score on the head. - -@item t -Score on thread. - -@end table - -@item -The third key is the match type. Which match types are valid depends on -what headers you are scoring on. - -@table @code - -@item strings - -@table @kbd - -@item e -Exact matching. - -@item s -Substring matching. - -@item f -Fuzzy matching (@pxref{Fuzzy Matching}). - -@item r -Regexp matching -@end table - -@item date -@table @kbd - -@item b -Before date. - -@item a -After date. - -@item n -This date. -@end table - -@item number -@table @kbd - -@item < -Less than number. - -@item = -Equal to number. - -@item > -Greater than number. -@end table -@end table - -@item -The fourth and final key says whether this is a temporary (i.e., expiring) -score entry, or a permanent (i.e., non-expiring) score entry, or whether -it is to be done immediately, without adding to the score file. -@table @kbd - -@item t -Temporary score entry. - -@item p -Permanent score entry. - -@item i -Immediately scoring. -@end table - -@end enumerate - -So, let's say you want to increase the score on the current author with -exact matching permanently: @kbd{I a e p}. If you want to lower the -score based on the subject line, using substring matching, and make a -temporary score entry: @kbd{L s s t}. Pretty easy. - -To make things a bit more complicated, there are shortcuts. If you use -a capital letter on either the second or third keys, Gnus will use -defaults for the remaining one or two keystrokes. The defaults are -``substring'' and ``temporary''. So @kbd{I A} is the same as @kbd{I a s -t}, and @kbd{I a R} is the same as @kbd{I a r t}. - -These functions take both the numerical prefix and the symbolic prefix -(@pxref{Symbolic Prefixes}). A numerical prefix says how much to lower -(or increase) the score of the article. A symbolic prefix of @code{a} -says to use the @file{all.SCORE} file for the command instead of the -current score file. - -@vindex gnus-score-mimic-keymap -The @code{gnus-score-mimic-keymap} says whether these commands will -pretend they are keymaps or not. - - -@node Group Score Commands -@section Group Score Commands -@cindex group score commands - -There aren't many of these as yet, I'm afraid. - -@table @kbd - -@item W f -@kindex W f (Group) -@findex gnus-score-flush-cache -Gnus maintains a cache of score alists to avoid having to reload them -all the time. This command will flush the cache -(@code{gnus-score-flush-cache}). - -@end table - -You can do scoring from the command line by saying something like: - -@findex gnus-batch-score -@cindex batch scoring -@example -$ emacs -batch -l ~/.emacs -l gnus -f gnus-batch-score -@end example - - -@node Score Variables -@section Score Variables -@cindex score variables - -@table @code - -@item gnus-use-scoring -@vindex gnus-use-scoring -If @code{nil}, Gnus will not check for score files, and will not, in -general, do any score-related work. This is @code{t} by default. - -@item gnus-kill-killed -@vindex gnus-kill-killed -If this variable is @code{nil}, Gnus will never apply score files to -articles that have already been through the kill process. While this -may save you lots of time, it also means that if you apply a kill file -to a group, and then change the kill file and want to run it over you -group again to kill more articles, it won't work. You have to set this -variable to @code{t} to do that. (It is @code{t} by default.) - -@item gnus-kill-files-directory -@vindex gnus-kill-files-directory -All kill and score files will be stored in this directory, which is -initialized from the @code{SAVEDIR} environment variable by default. -This is @file{~/News/} by default. - -@item gnus-score-file-suffix -@vindex gnus-score-file-suffix -Suffix to add to the group name to arrive at the score file name -(@samp{SCORE} by default.) - -@item gnus-score-uncacheable-files -@vindex gnus-score-uncacheable-files -@cindex score cache -All score files are normally cached to avoid excessive re-loading of -score files. However, if this might make you Emacs grow big and -bloated, so this regexp can be used to weed out score files unlikely to be needed again. It would be a bad idea to deny caching of -@file{all.SCORE}, while it might be a good idea to not cache -@file{comp.infosystems.www.authoring.misc.ADAPT}. In fact, this -variable is @samp{ADAPT$} by default, so no adaptive score files will -be cached. - -@item gnus-save-score -@vindex gnus-save-score -If you have really complicated score files, and do lots of batch -scoring, then you might set this variable to @code{t}. This will make -Gnus save the scores into the @file{.newsrc.eld} file. - -@item gnus-score-interactive-default-score -@vindex gnus-score-interactive-default-score -Score used by all the interactive raise/lower commands to raise/lower -score with. Default is 1000, which may seem excessive, but this is to -ensure that the adaptive scoring scheme gets enough room to play with. -We don't want the small changes from the adaptive scoring to overwrite -manually entered data. - -@item gnus-summary-default-score -@vindex gnus-summary-default-score -Default score of an article, which is 0 by default. - -@item gnus-summary-expunge-below -@vindex gnus-summary-expunge-below -Don't display the summary lines of articles that have scores lower than -this variable. This is @code{nil} by default, which means that no -articles will be hidden. This variable is local to the summary buffers, -and has to be set from @code{gnus-summary-mode-hook}. - -@item gnus-score-over-mark -@vindex gnus-score-over-mark -Mark (in the third column) used for articles with a score over the -default. Default is @samp{+}. - -@item gnus-score-below-mark -@vindex gnus-score-below-mark -Mark (in the third column) used for articles with a score below the -default. Default is @samp{-}. - -@item gnus-score-find-score-files-function -@vindex gnus-score-find-score-files-function -Function used to find score files for the current group. This function -is called with the name of the group as the argument. - -Predefined functions available are: -@table @code - -@item gnus-score-find-single -@findex gnus-score-find-single -Only apply the group's own score file. - -@item gnus-score-find-bnews -@findex gnus-score-find-bnews -Apply all score files that match, using bnews syntax. This is the -default. If the current group is @samp{gnu.emacs.gnus}, for instance, -@file{all.emacs.all.SCORE}, @file{not.alt.all.SCORE} and -@file{gnu.all.SCORE} would all apply. In short, the instances of -@samp{all} in the score file names are translated into @samp{.*}, and -then a regexp match is done. - -This means that if you have some score entries that you want to apply to -all groups, then you put those entries in the @file{all.SCORE} file. - -The score files are applied in a semi-random order, although Gnus will -try to apply the more general score files before the more specific score -files. It does this by looking at the number of elements in the score -file names---discarding the @samp{all} elements. - -@item gnus-score-find-hierarchical -@findex gnus-score-find-hierarchical -Apply all score files from all the parent groups. This means that you -can't have score files like @file{all.SCORE}, but you can have -@file{SCORE}, @file{comp.SCORE} and @file{comp.emacs.SCORE}. - -@end table -This variable can also be a list of functions. In that case, all these -functions will be called, and all the returned lists of score files will -be applied. These functions can also return lists of score alists -directly. In that case, the functions that return these non-file score -alists should probably be placed before the ``real'' score file -functions, to ensure that the last score file returned is the local -score file. Phu. - -@item gnus-score-expiry-days -@vindex gnus-score-expiry-days -This variable says how many days should pass before an unused score file -entry is expired. If this variable is @code{nil}, no score file entries -are expired. It's 7 by default. - -@item gnus-update-score-entry-dates -@vindex gnus-update-score-entry-dates -If this variable is non-@code{nil}, matching score entries will have -their dates updated. (This is how Gnus controls expiry---all -non-matching entries will become too old while matching entries will -stay fresh and young.) However, if you set this variable to @code{nil}, -even matching entries will grow old and will have to face that oh-so -grim reaper. - -@item gnus-score-after-write-file-function -@vindex gnus-score-after-write-file-function -Function called with the name of the score file just written. - -@item gnus-score-thread-simplify -@vindex gnus-score-thread-simplify -If this variable is non-@code{nil}, article subjects will be simplified -for subject scoring purposes in the same manner as with -threading---according to the current value of -gnus-simplify-subject-functions. If the scoring entry uses -@code{substring} or @code{exact} matching, the match will also be -simplified in this manner. - -@end table - - -@node Score File Format -@section Score File Format -@cindex score file format - -A score file is an @code{emacs-lisp} file that normally contains just a -single form. Casual users are not expected to edit these files; -everything can be changed from the summary buffer. - -Anyway, if you'd like to dig into it yourself, here's an example: - -@lisp -(("from" - ("Lars Ingebrigtsen" -10000) - ("Per Abrahamsen") - ("larsi\\|lmi" -50000 nil R)) - ("subject" - ("Ding is Badd" nil 728373)) - ("xref" - ("alt.politics" -1000 728372 s)) - ("lines" - (2 -100 nil <)) - (mark 0) - (expunge -1000) - (mark-and-expunge -10) - (read-only nil) - (orphan -10) - (adapt t) - (files "/hom/larsi/News/gnu.SCORE") - (exclude-files "all.SCORE") - (local (gnus-newsgroup-auto-expire t) - (gnus-summary-make-false-root empty)) - (eval (ding))) -@end lisp - -This example demonstrates most score file elements. For a different -approach, see @pxref{Advanced Scoring}. - -Even though this looks much like lisp code, nothing here is actually -@code{eval}ed. The lisp reader is used to read this form, though, so it -has to be valid syntactically, if not semantically. - -Six keys are supported by this alist: - -@table @code - -@item STRING -If the key is a string, it is the name of the header to perform the -match on. Scoring can only be performed on these eight headers: -@code{From}, @code{Subject}, @code{References}, @code{Message-ID}, -@code{Xref}, @code{Lines}, @code{Chars} and @code{Date}. In addition to -these headers, there are three strings to tell Gnus to fetch the entire -article and do the match on larger parts of the article: @code{Body} -will perform the match on the body of the article, @code{Head} will -perform the match on the head of the article, and @code{All} will -perform the match on the entire article. Note that using any of these -last three keys will slow down group entry @emph{considerably}. The -final ``header'' you can score on is @code{Followup}. These score -entries will result in new score entries being added for all follow-ups -to articles that matches these score entries. - -Following this key is a arbitrary number of score entries, where each -score entry has one to four elements. -@enumerate - -@item -The first element is the @dfn{match element}. On most headers this will -be a string, but on the Lines and Chars headers, this must be an -integer. - -@item -If the second element is present, it should be a number---the @dfn{score -element}. This number should be an integer in the neginf to posinf -interval. This number is added to the score of the article if the match -is successful. If this element is not present, the -@code{gnus-score-interactive-default-score} number will be used -instead. This is 1000 by default. - -@item -If the third element is present, it should be a number---the @dfn{date -element}. This date says when the last time this score entry matched, -which provides a mechanism for expiring the score entries. It this -element is not present, the score entry is permanent. The date is -represented by the number of days since December 31, 1 BCE. - -@item -If the fourth element is present, it should be a symbol---the @dfn{type -element}. This element specifies what function should be used to see -whether this score entry matches the article. What match types that can -be used depends on what header you wish to perform the match on. -@table @dfn - -@item From, Subject, References, Xref, Message-ID -For most header types, there are the @code{r} and @code{R} (regexp), as -well as @code{s} and @code{S} (substring) types, and @code{e} and -@code{E} (exact match), and @code{w} (word match) types. If this -element is not present, Gnus will assume that substring matching should -be used. @code{R}, @code{S}, and @code{E} differ from the others in -that the matches will be done in a case-sensitive manner. All these -one-letter types are really just abbreviations for the @code{regexp}, -@code{string}, @code{exact}, and @code{word} types, which you can use -instead, if you feel like. - -@item Lines, Chars -These two headers use different match types: @code{<}, @code{>}, -@code{=}, @code{>=} and @code{<=}. - -These predicates are true if - -@example -(PREDICATE HEADER MATCH) -@end example - -evaluates to non-@code{nil}. For instance, the advanced match -@code{("lines" 4 <)} (@pxref{Advanced Scoring}) will result in the -following form: - -@lisp -(< header-value 4) -@end lisp - -Or to put it another way: When using @code{<} on @code{Lines} with 4 as -the match, we get the score added if the article has less than 4 lines. -(It's easy to get confused and think it's the other way around. But -it's not. I think.) - -When matching on @code{Lines}, be careful because some backends (like -@code{nndir}) do not generate @code{Lines} header, so every article ends -up being marked as having 0 lines. This can lead to strange results if -you happen to lower score of the articles with few lines. - -@item Date -For the Date header we have three kinda silly match types: -@code{before}, @code{at} and @code{after}. I can't really imagine this -ever being useful, but, like, it would feel kinda silly not to provide -this function. Just in case. You never know. Better safe than sorry. -Once burnt, twice shy. Don't judge a book by its cover. Never not have -sex on a first date. (I have been told that at least one person, and I -quote, ``found this function indispensable'', however.) - -@cindex ISO8601 -@cindex date -A more useful match type is @code{regexp}. With it, you can match the -date string using a regular expression. The date is normalized to -ISO8601 compact format first---@var{YYYYMMDD}@code{T}@var{HHMMSS}. If -you want to match all articles that have been posted on April 1st in -every year, you could use @samp{....0401.........} as a match string, -for instance. (Note that the date is kept in its original time zone, so -this will match articles that were posted when it was April 1st where -the article was posted from. Time zones are such wholesome fun for the -whole family, eh?) - -@item Head, Body, All -These three match keys use the same match types as the @code{From} (etc) -header uses. - -@item Followup -This match key is somewhat special, in that it will match the -@code{From} header, and affect the score of not only the matching -articles, but also all followups to the matching articles. This allows -you e.g. increase the score of followups to your own articles, or -decrease the score of followups to the articles of some known -trouble-maker. Uses the same match types as the @code{From} header -uses. (Using this match key will lead to creation of @file{ADAPT} -files.) - -@item Thread -This match key works along the same lines as the @code{Followup} match -key. If you say that you want to score on a (sub-)thread started by an article with a @code{Message-ID} @var{X}, then you add a -@samp{thread} match. This will add a new @samp{thread} match for each -article that has @var{X} in its @code{References} header. (These new -@samp{thread} matches will use the @code{Message-ID}s of these matching -articles.) This will ensure that you can raise/lower the score of an -entire thread, even though some articles in the thread may not have -complete @code{References} headers. Note that using this may lead to -undeterministic scores of the articles in the thread. (Using this match -key will lead to creation of @file{ADAPT} files.) -@end table -@end enumerate - -@cindex Score File Atoms -@item mark -The value of this entry should be a number. Any articles with a score -lower than this number will be marked as read. - -@item expunge -The value of this entry should be a number. Any articles with a score -lower than this number will be removed from the summary buffer. - -@item mark-and-expunge -The value of this entry should be a number. Any articles with a score -lower than this number will be marked as read and removed from the -summary buffer. - -@item thread-mark-and-expunge -The value of this entry should be a number. All articles that belong to -a thread that has a total score below this number will be marked as read -and removed from the summary buffer. @code{gnus-thread-score-function} -says how to compute the total score for a thread. - -@item files -The value of this entry should be any number of file names. These files -are assumed to be score files as well, and will be loaded the same way -this one was. - -@item exclude-files -The clue of this entry should be any number of files. These files will -not be loaded, even though they would normally be so, for some reason or -other. - -@item eval -The value of this entry will be @code{eval}el. This element will be -ignored when handling global score files. - -@item read-only -Read-only score files will not be updated or saved. Global score files -should feature this atom (@pxref{Global Score Files}). (Note: -@dfn{Global} here really means @dfn{global}; not your personal -apply-to-all-groups score files.) - -@item orphan -The value of this entry should be a number. Articles that do not have -parents will get this number added to their scores. Imagine you follow -some high-volume newsgroup, like @samp{comp.lang.c}. Most likely you -will only follow a few of the threads, also want to see any new threads. - -You can do this with the following two score file entries: - -@example - (orphan -500) - (mark-and-expunge -100) -@end example - -When you enter the group the first time, you will only see the new -threads. You then raise the score of the threads that you find -interesting (with @kbd{I T} or @kbd{I S}), and ignore (@kbd{C y}) the -rest. Next time you enter the group, you will see new articles in the -interesting threads, plus any new threads. - -I.e.---the orphan score atom is for high-volume groups where there -exist a few interesting threads which can't be found automatically by -ordinary scoring rules. - -@item adapt -This entry controls the adaptive scoring. If it is @code{t}, the -default adaptive scoring rules will be used. If it is @code{ignore}, no -adaptive scoring will be performed on this group. If it is a list, this -list will be used as the adaptive scoring rules. If it isn't present, -or is something other than @code{t} or @code{ignore}, the default -adaptive scoring rules will be used. If you want to use adaptive -scoring on most groups, you'd set @code{gnus-use-adaptive-scoring} to -@code{t}, and insert an @code{(adapt ignore)} in the groups where you do -not want adaptive scoring. If you only want adaptive scoring in a few -groups, you'd set @code{gnus-use-adaptive-scoring} to @code{nil}, and -insert @code{(adapt t)} in the score files of the groups where you want -it. - -@item adapt-file -All adaptive score entries will go to the file named by this entry. It -will also be applied when entering the group. This atom might be handy -if you want to adapt on several groups at once, using the same adaptive -file for a number of groups. - -@item local -@cindex local variables -The value of this entry should be a list of @code{(VAR VALUE)} pairs. -Each @var{var} will be made buffer-local to the current summary buffer, -and set to the value specified. This is a convenient, if somewhat -strange, way of setting variables in some groups if you don't like hooks -much. Note that the @var{value} won't be evaluated. -@end table - - -@node Score File Editing -@section Score File Editing - -You normally enter all scoring commands from the summary buffer, but you -might feel the urge to edit them by hand as well, so we've supplied you -with a mode for that. - -It's simply a slightly customized @code{emacs-lisp} mode, with these -additional commands: - -@table @kbd - -@item C-c C-c -@kindex C-c C-c (Score) -@findex gnus-score-edit-done -Save the changes you have made and return to the summary buffer -(@code{gnus-score-edit-done}). - -@item C-c C-d -@kindex C-c C-d (Score) -@findex gnus-score-edit-insert-date -Insert the current date in numerical format -(@code{gnus-score-edit-insert-date}). This is really the day number, if -you were wondering. - -@item C-c C-p -@kindex C-c C-p (Score) -@findex gnus-score-pretty-print -The adaptive score files are saved in an unformatted fashion. If you -intend to read one of these files, you want to @dfn{pretty print} it -first. This command (@code{gnus-score-pretty-print}) does that for -you. - -@end table - -Type @kbd{M-x gnus-score-mode} to use this mode. - -@vindex gnus-score-mode-hook -@code{gnus-score-menu-hook} is run in score mode buffers. - -In the summary buffer you can use commands like @kbd{V f} and @kbd{V -e} to begin editing score files. - - -@node Adaptive Scoring -@section Adaptive Scoring -@cindex adaptive scoring - -If all this scoring is getting you down, Gnus has a way of making it all -happen automatically---as if by magic. Or rather, as if by artificial -stupidity, to be precise. - -@vindex gnus-use-adaptive-scoring -When you read an article, or mark an article as read, or kill an -article, you leave marks behind. On exit from the group, Gnus can sniff -these marks and add score elements depending on what marks it finds. -You turn on this ability by setting @code{gnus-use-adaptive-scoring} to -@code{t} or @code{(line)}. If you want score adaptively on separate -words appearing in the subjects, you should set this variable to -@code{(word)}. If you want to use both adaptive methods, set this -variable to @code{(word line)}. - -@vindex gnus-default-adaptive-score-alist -To give you complete control over the scoring process, you can customize -the @code{gnus-default-adaptive-score-alist} variable. For instance, it -might look something like this: - -@lisp -(defvar gnus-default-adaptive-score-alist - '((gnus-unread-mark) - (gnus-ticked-mark (from 4)) - (gnus-dormant-mark (from 5)) - (gnus-del-mark (from -4) (subject -1)) - (gnus-read-mark (from 4) (subject 2)) - (gnus-expirable-mark (from -1) (subject -1)) - (gnus-killed-mark (from -1) (subject -3)) - (gnus-kill-file-mark) - (gnus-ancient-mark) - (gnus-low-score-mark) - (gnus-catchup-mark (from -1) (subject -1)))) -@end lisp - -As you see, each element in this alist has a mark as a key (either a -variable name or a ``real'' mark---a character). Following this key is -a arbitrary number of header/score pairs. If there are no header/score -pairs following the key, no adaptive scoring will be done on articles -that have that key as the article mark. For instance, articles with -@code{gnus-unread-mark} in the example above will not get adaptive score -entries. - -Each article can have only one mark, so just a single of these rules -will be applied to each article. - -To take @code{gnus-del-mark} as an example---this alist says that all -articles that have that mark (i.e., are marked with @samp{D}) will have a -score entry added to lower based on the @code{From} header by -4, and -lowered by @code{Subject} by -1. Change this to fit your prejudices. - -If you have marked 10 articles with the same subject with -@code{gnus-del-mark}, the rule for that mark will be applied ten times. -That means that that subject will get a score of ten times -1, which -should be, unless I'm much mistaken, -10. - -If you have auto-expirable (mail) groups (@pxref{Expiring Mail}), all -the read articles will be marked with the @samp{E} mark. This'll -probably make adaptive scoring slightly impossible, so auto-expiring and -adaptive scoring doesn't really mix very well. - -The headers you can score on are @code{from}, @code{subject}, -@code{message-id}, @code{references}, @code{xref}, @code{lines}, -@code{chars} and @code{date}. In addition, you can score on -@code{followup}, which will create an adaptive score entry that matches -on the @code{References} header using the @code{Message-ID} of the -current article, thereby matching the following thread. - -You can also score on @code{thread}, which will try to score all -articles that appear in a thread. @code{thread} matches uses a -@code{Message-ID} to match on the @code{References} header of the -article. If the match is made, the @code{Message-ID} of the article is -added to the @code{thread} rule. (Think about it. I'd recommend two -aspirins afterwards.) - -If you use this scheme, you should set the score file atom @code{mark} -to something small---like -300, perhaps, to avoid having small random -changes result in articles getting marked as read. - -After using adaptive scoring for a week or so, Gnus should start to -become properly trained and enhance the authors you like best, and kill -the authors you like least, without you having to say so explicitly. - -You can control what groups the adaptive scoring is to be performed on -by using the score files (@pxref{Score File Format}). This will also -let you use different rules in different groups. - -@vindex gnus-adaptive-file-suffix -The adaptive score entries will be put into a file where the name is the -group name with @code{gnus-adaptive-file-suffix} appended. The default -is @samp{ADAPT}. - -@vindex gnus-score-exact-adapt-limit -When doing adaptive scoring, substring or fuzzy matching would probably -give you the best results in most cases. However, if the header one -matches is short, the possibility for false positives is great, so if -the length of the match is less than -@code{gnus-score-exact-adapt-limit}, exact matching will be used. If -this variable is @code{nil}, exact matching will always be used to avoid -this problem. - -@vindex gnus-default-adaptive-word-score-alist -As mentioned above, you can adapt either on individual words or entire -headers. If you adapt on words, the -@code{gnus-default-adaptive-word-score-alist} variable says what score -each instance of a word should add given a mark. - -@lisp -(setq gnus-default-adaptive-word-score-alist - `((,gnus-read-mark . 30) - (,gnus-catchup-mark . -10) - (,gnus-killed-mark . -20) - (,gnus-del-mark . -15))) -@end lisp - -This is the default value. If you have adaption on words enabled, every -word that appears in subjects of articles marked with -@code{gnus-read-mark} will result in a score rule that increase the -score with 30 points. - -@vindex gnus-default-ignored-adaptive-words -@vindex gnus-ignored-adaptive-words -Words that appear in the @code{gnus-default-ignored-adaptive-words} list -will be ignored. If you wish to add more words to be ignored, use the -@code{gnus-ignored-adaptive-words} list instead. - -@vindex gnus-adaptive-word-syntax-table -When the scoring is done, @code{gnus-adaptive-word-syntax-table} is the -syntax table in effect. It is similar to the standard syntax table, but -it considers numbers to be non-word-constituent characters. - -@vindex gnus-adaptive-word-minimum -If @code{gnus-adaptive-word-minimum} is set to a number, the adaptive -word scoring process will never bring down the score of an article to -below this number. The default is @code{nil}. - -After using this scheme for a while, it might be nice to write a -@code{gnus-psychoanalyze-user} command to go through the rules and see -what words you like and what words you don't like. Or perhaps not. - -Note that the adaptive word scoring thing is highly experimental and is -likely to change in the future. Initial impressions seem to indicate -that it's totally useless as it stands. Some more work (involving more -rigorous statistical methods) will have to be done to make this useful. - - -@node Home Score File -@section Home Score File - -The score file where new score file entries will go is called the -@dfn{home score file}. This is normally (and by default) the score file -for the group itself. For instance, the home score file for -@samp{gnu.emacs.gnus} is @file{gnu.emacs.gnus.SCORE}. - -However, this may not be what you want. It is often convenient to share -a common home score file among many groups---all @samp{emacs} groups -could perhaps use the same home score file. - -@vindex gnus-home-score-file -The variable that controls this is @code{gnus-home-score-file}. It can -be: - -@enumerate -@item -A string. Then this file will be used as the home score file for all -groups. - -@item -A function. The result of this function will be used as the home score -file. The function will be called with the name of the group as the -parameter. - -@item -A list. The elements in this list can be: - -@enumerate -@item -@var{(regexp file-name)}. If the @var{regexp} matches the group name, -the @var{file-name} will will be used as the home score file. - -@item -A function. If the function returns non-nil, the result will be used as -the home score file. - -@item -A string. Use the string as the home score file. -@end enumerate - -The list will be traversed from the beginning towards the end looking -for matches. - -@end enumerate - -So, if you want to use just a single score file, you could say: - -@lisp -(setq gnus-home-score-file - "my-total-score-file.SCORE") -@end lisp - -If you want to use @file{gnu.SCORE} for all @samp{gnu} groups and -@file{rec.SCORE} for all @samp{rec} groups (and so on), you can say: - -@findex gnus-hierarchial-home-score-file -@lisp -(setq gnus-home-score-file - 'gnus-hierarchial-home-score-file) -@end lisp - -This is a ready-made function provided for your convenience. -Other functions include - -@table @code -@item gnus-current-home-score-file -@findex gnus-current-home-score-file -Return the ``current'' regular score file. This will make scoring -commands add entry to the ``innermost'' matching score file. - -@end table - -If you want to have one score file for the @samp{emacs} groups and -another for the @samp{comp} groups, while letting all other groups use -their own home score files: - -@lisp -(setq gnus-home-score-file - ;; All groups that match the regexp "\\.emacs" - '(("\\.emacs" "emacs.SCORE") - ;; All the comp groups in one score file - ("^comp" "comp.SCORE"))) -@end lisp - -@vindex gnus-home-adapt-file -@code{gnus-home-adapt-file} works exactly the same way as -@code{gnus-home-score-file}, but says what the home adaptive score file -is instead. All new adaptive file entries will go into the file -specified by this variable, and the same syntax is allowed. - -In addition to using @code{gnus-home-score-file} and -@code{gnus-home-adapt-file}, you can also use group parameters -(@pxref{Group Parameters}) and topic parameters (@pxref{Topic -Parameters}) to achieve much the same. Group and topic parameters take -precedence over this variable. - - -@node Followups To Yourself -@section Followups To Yourself - -Gnus offers two commands for picking out the @code{Message-ID} header in -the current buffer. Gnus will then add a score rule that scores using -this @code{Message-ID} on the @code{References} header of other -articles. This will, in effect, increase the score of all articles that -respond to the article in the current buffer. Quite useful if you want -to easily note when people answer what you've said. - -@table @code - -@item gnus-score-followup-article -@findex gnus-score-followup-article -This will add a score to articles that directly follow up your own -article. - -@item gnus-score-followup-thread -@findex gnus-score-followup-thread -This will add a score to all articles that appear in a thread ``below'' -your own article. -@end table - -@vindex message-sent-hook -These two functions are both primarily meant to be used in hooks like -@code{message-sent-hook}. - -If you look closely at your own @code{Message-ID}, you'll notice that -the first two or three characters are always the same. Here's two of -mine: - -@example - - -@end example - -So ``my'' ident on this machine is @samp{x6}. This can be -exploited---the following rule will raise the score on all followups to -myself: - -@lisp -("references" - ("" - 1000 nil r)) -@end lisp - -Whether it's the first two or first three characters that are ``yours'' -is system-dependent. - - -@node Scoring Tips -@section Scoring Tips -@cindex scoring tips - -@table @dfn - -@item Crossposts -@cindex crossposts -@cindex scoring crossposts -If you want to lower the score of crossposts, the line to match on is -the @code{Xref} header. -@lisp -("xref" (" talk.politics.misc:" -1000)) -@end lisp - -@item Multiple crossposts -If you want to lower the score of articles that have been crossposted to -more than, say, 3 groups: -@lisp -("xref" ("[^:\n]+:[0-9]+ +[^:\n]+:[0-9]+ +[^:\n]+:[0-9]+" -1000 nil r)) -@end lisp - -@item Matching on the body -This is generally not a very good idea---it takes a very long time. -Gnus actually has to fetch each individual article from the server. But -you might want to anyway, I guess. Even though there are three match -keys (@code{Head}, @code{Body} and @code{All}), you should choose one -and stick with it in each score file. If you use any two, each article -will be fetched @emph{twice}. If you want to match a bit on the -@code{Head} and a bit on the @code{Body}, just use @code{All} for all -the matches. - -@item Marking as read -You will probably want to mark articles that has a score below a certain -number as read. This is most easily achieved by putting the following -in your @file{all.SCORE} file: -@lisp -((mark -100)) -@end lisp -You may also consider doing something similar with @code{expunge}. - -@item Negated character classes -If you say stuff like @code{[^abcd]*}, you may get unexpected results. -That will match newlines, which might lead to, well, The Unknown. Say -@code{[^abcd\n]*} instead. -@end table - - -@node Reverse Scoring -@section Reverse Scoring -@cindex reverse scoring - -If you want to keep just articles that have @samp{Sex with Emacs} in the -subject header, and expunge all other articles, you could put something -like this in your score file: - -@lisp -(("subject" - ("Sex with Emacs" 2)) - (mark 1) - (expunge 1)) -@end lisp - -So, you raise all articles that match @samp{Sex with Emacs} and mark the -rest as read, and expunge them to boot. - - -@node Global Score Files -@section Global Score Files -@cindex global score files - -Sure, other newsreaders have ``global kill files''. These are usually -nothing more than a single kill file that applies to all groups, stored -in the user's home directory. Bah! Puny, weak newsreaders! - -What I'm talking about here are Global Score Files. Score files from -all over the world, from users everywhere, uniting all nations in one -big, happy score file union! Ange-score! New and untested! - -@vindex gnus-global-score-files -All you have to do to use other people's score files is to set the -@code{gnus-global-score-files} variable. One entry for each score file, -or each score file directory. Gnus will decide by itself what score -files are applicable to which group. - -Say you want to use the score file -@file{/ftp@@ftp.gnus.org:/pub/larsi/ding/score/soc.motss.SCORE} and -all score files in the @file{/ftp@@ftp.some-where:/pub/score} directory: - -@lisp -(setq gnus-global-score-files - '("/ftp@@ftp.gnus.org:/pub/larsi/ding/score/soc.motss.SCORE" - "/ftp@@ftp.some-where:/pub/score/")) -@end lisp - -@findex gnus-score-search-global-directories -Simple, eh? Directory names must end with a @samp{/}. These -directories are typically scanned only once during each Gnus session. -If you feel the need to manually re-scan the remote directories, you can -use the @code{gnus-score-search-global-directories} command. - -Note that, at present, using this option will slow down group entry -somewhat. (That is---a lot.) - -If you want to start maintaining score files for other people to use, -just put your score file up for anonymous ftp and announce it to the -world. Become a retro-moderator! Participate in the retro-moderator -wars sure to ensue, where retro-moderators battle it out for the -sympathy of the people, luring them to use their score files on false -premises! Yay! The net is saved! - -Here are some tips for the would-be retro-moderator, off the top of my -head: - -@itemize @bullet - -@item -Articles heavily crossposted are probably junk. -@item -To lower a single inappropriate article, lower by @code{Message-ID}. -@item -Particularly brilliant authors can be raised on a permanent basis. -@item -Authors that repeatedly post off-charter for the group can safely be -lowered out of existence. -@item -Set the @code{mark} and @code{expunge} atoms to obliterate the nastiest -articles completely. - -@item -Use expiring score entries to keep the size of the file down. You -should probably have a long expiry period, though, as some sites keep -old articles for a long time. -@end itemize - -... I wonder whether other newsreaders will support global score files -in the future. @emph{Snicker}. Yup, any day now, newsreaders like Blue -Wave, xrn and 1stReader are bound to implement scoring. Should we start -holding our breath yet? - - -@node Kill Files -@section Kill Files -@cindex kill files - -Gnus still supports those pesky old kill files. In fact, the kill file -entries can now be expiring, which is something I wrote before Daniel -Quinlan thought of doing score files, so I've left the code in there. - -In short, kill processing is a lot slower (and I do mean @emph{a lot}) -than score processing, so it might be a good idea to rewrite your kill -files into score files. - -Anyway, a kill file is a normal @code{emacs-lisp} file. You can put any -forms into this file, which means that you can use kill files as some -sort of primitive hook function to be run on group entry, even though -that isn't a very good idea. - -Normal kill files look like this: - -@lisp -(gnus-kill "From" "Lars Ingebrigtsen") -(gnus-kill "Subject" "ding") -(gnus-expunge "X") -@end lisp - -This will mark every article written by me as read, and remove the -marked articles from the summary buffer. Very useful, you'll agree. - -Other programs use a totally different kill file syntax. If Gnus -encounters what looks like a @code{rn} kill file, it will take a stab at -interpreting it. - -Two summary functions for editing a GNUS kill file: - -@table @kbd - -@item M-k -@kindex M-k (Summary) -@findex gnus-summary-edit-local-kill -Edit this group's kill file (@code{gnus-summary-edit-local-kill}). - -@item M-K -@kindex M-K (Summary) -@findex gnus-summary-edit-global-kill -Edit the general kill file (@code{gnus-summary-edit-global-kill}). -@end table - -Two group mode functions for editing the kill files: - -@table @kbd - -@item M-k -@kindex M-k (Group) -@findex gnus-group-edit-local-kill -Edit this group's kill file (@code{gnus-group-edit-local-kill}). - -@item M-K -@kindex M-K (Group) -@findex gnus-group-edit-global-kill -Edit the general kill file (@code{gnus-group-edit-global-kill}). -@end table - -Kill file variables: - -@table @code -@item gnus-kill-file-name -@vindex gnus-kill-file-name -A kill file for the group @samp{soc.motss} is normally called -@file{soc.motss.KILL}. The suffix appended to the group name to get -this file name is detailed by the @code{gnus-kill-file-name} variable. -The ``global'' kill file (not in the score file sense of ``global'', of -course) is just called @file{KILL}. - -@vindex gnus-kill-save-kill-file -@item gnus-kill-save-kill-file -If this variable is non-@code{nil}, Gnus will save the -kill file after processing, which is necessary if you use expiring -kills. - -@item gnus-apply-kill-hook -@vindex gnus-apply-kill-hook -@findex gnus-apply-kill-file-unless-scored -@findex gnus-apply-kill-file -A hook called to apply kill files to a group. It is -@code{(gnus-apply-kill-file)} by default. If you want to ignore the -kill file if you have a score file for the same group, you can set this -hook to @code{(gnus-apply-kill-file-unless-scored)}. If you don't want -kill files to be processed, you should set this variable to @code{nil}. - -@item gnus-kill-file-mode-hook -@vindex gnus-kill-file-mode-hook -A hook called in kill-file mode buffers. - -@end table - - -@node Converting Kill Files -@section Converting Kill Files -@cindex kill files -@cindex converting kill files - -If you have loads of old kill files, you may want to convert them into -score files. If they are ``regular'', you can use -the @file{gnus-kill-to-score.el} package; if not, you'll have to do it -by hand. - -The kill to score conversion package isn't included in Gnus by default. -You can fetch it from -@file{http://www.stud.ifi.uio.no/~larsi/ding-other/gnus-kill-to-score}. - -If your old kill files are very complex---if they contain more -non-@code{gnus-kill} forms than not, you'll have to convert them by -hand. Or just let them be as they are. Gnus will still use them as -before. - - -@node GroupLens -@section GroupLens -@cindex GroupLens - -GroupLens is a collaborative filtering system that helps you work -together with other people to find the quality news articles out of the -huge volume of news articles generated every day. - -To accomplish this the GroupLens system combines your opinions about -articles you have already read with the opinions of others who have done -likewise and gives you a personalized prediction for each unread news -article. Think of GroupLens as a matchmaker. GroupLens watches how you -rate articles, and finds other people that rate articles the same way. -Once it has found some people you agree with it tells you, in the form -of a prediction, what they thought of the article. You can use this -prediction to help you decide whether or not you want to read the -article. - -@menu -* Using GroupLens:: How to make Gnus use GroupLens. -* Rating Articles:: Letting GroupLens know how you rate articles. -* Displaying Predictions:: Displaying predictions given by GroupLens. -* GroupLens Variables:: Customizing GroupLens. -@end menu - - -@node Using GroupLens -@subsection Using GroupLens - -To use GroupLens you must register a pseudonym with your local Better -Bit Bureau (BBB). -@samp{http://www.cs.umn.edu/Research/GroupLens/bbb.html} is the only -better bit in town at the moment. - -Once you have registered you'll need to set a couple of variables. - -@table @code - -@item gnus-use-grouplens -@vindex gnus-use-grouplens -Setting this variable to a non-@code{nil} value will make Gnus hook into -all the relevant GroupLens functions. - -@item grouplens-pseudonym -@vindex grouplens-pseudonym -This variable should be set to the pseudonym you got when registering -with the Better Bit Bureau. - -@item grouplens-newsgroups -@vindex grouplens-newsgroups -A list of groups that you want to get GroupLens predictions for. - -@end table - -That's the minimum of what you need to get up and running with GroupLens. -Once you've registered, GroupLens will start giving you scores for -articles based on the average of what other people think. But, to get -the real benefit of GroupLens you need to start rating articles -yourself. Then the scores GroupLens gives you will be personalized for -you, based on how the people you usually agree with have already rated. - - -@node Rating Articles -@subsection Rating Articles - -In GroupLens, an article is rated on a scale from 1 to 5, inclusive. -Where 1 means something like this article is a waste of bandwidth and 5 -means that the article was really good. The basic question to ask -yourself is, "on a scale from 1 to 5 would I like to see more articles -like this one?" - -There are four ways to enter a rating for an article in GroupLens. - -@table @kbd - -@item r -@kindex r (GroupLens) -@findex bbb-summary-rate-article -This function will prompt you for a rating on a scale of one to five. - -@item k -@kindex k (GroupLens) -@findex grouplens-score-thread -This function will prompt you for a rating, and rate all the articles in -the thread. This is really useful for some of those long running giant -threads in rec.humor. - -@end table - -The next two commands, @kbd{n} and @kbd{,} take a numerical prefix to be -the score of the article you're reading. - -@table @kbd - -@item 1-5 n -@kindex n (GroupLens) -@findex grouplens-next-unread-article -Rate the article and go to the next unread article. - -@item 1-5 , -@kindex , (GroupLens) -@findex grouplens-best-unread-article -Rate the article and go to the next unread article with the highest score. - -@end table - -If you want to give the current article a score of 4 and then go to the -next article, just type @kbd{4 n}. - - -@node Displaying Predictions -@subsection Displaying Predictions - -GroupLens makes a prediction for you about how much you will like a -news article. The predictions from GroupLens are on a scale from 1 to -5, where 1 is the worst and 5 is the best. You can use the predictions -from GroupLens in one of three ways controlled by the variable -@code{gnus-grouplens-override-scoring}. - -@vindex gnus-grouplens-override-scoring -There are three ways to display predictions in grouplens. You may -choose to have the GroupLens scores contribute to, or override the -regular gnus scoring mechanism. override is the default; however, some -people prefer to see the Gnus scores plus the grouplens scores. To get -the separate scoring behavior you need to set -@code{gnus-grouplens-override-scoring} to @code{'separate}. To have the -GroupLens predictions combined with the grouplens scores set it to -@code{'override} and to combine the scores set -@code{gnus-grouplens-override-scoring} to @code{'combine}. When you use -the combine option you will also want to set the values for -@code{grouplens-prediction-offset} and -@code{grouplens-score-scale-factor}. - -@vindex grouplens-prediction-display -In either case, GroupLens gives you a few choices for how you would like -to see your predictions displayed. The display of predictions is -controlled by the @code{grouplens-prediction-display} variable. - -The following are valid values for that variable. - -@table @code -@item prediction-spot -The higher the prediction, the further to the right an @samp{*} is -displayed. - -@item confidence-interval -A numeric confidence interval. - -@item prediction-bar -The higher the prediction, the longer the bar. - -@item confidence-bar -Numerical confidence. - -@item confidence-spot -The spot gets bigger with more confidence. - -@item prediction-num -Plain-old numeric value. - -@item confidence-plus-minus -Prediction +/- confidence. - -@end table - - -@node GroupLens Variables -@subsection GroupLens Variables - -@table @code - -@item gnus-summary-grouplens-line-format -The summary line format used in GroupLens-enhanced summary buffers. It -accepts the same specs as the normal summary line format (@pxref{Summary -Buffer Lines}). The default is @samp{%U%R%z%l%I%(%[%4L: %-20,20n%]%) -%s\n}. - -@item grouplens-bbb-host -Host running the bbbd server. @samp{grouplens.cs.umn.edu} is the -default. - -@item grouplens-bbb-port -Port of the host running the bbbd server. The default is 9000. - -@item grouplens-score-offset -Offset the prediction by this value. In other words, subtract the -prediction value by this number to arrive at the effective score. The -default is 0. - -@item grouplens-score-scale-factor -This variable allows the user to magnify the effect of GroupLens scores. -The scale factor is applied after the offset. The default is 1. - -@end table - - -@node Advanced Scoring -@section Advanced Scoring - -Scoring on Subjects and From headers is nice enough, but what if you're -really interested in what a person has to say only when she's talking -about a particular subject? Or what if you really don't want to -read what person A has to say when she's following up to person B, but -want to read what she says when she's following up to person C? - -By using advanced scoring rules you may create arbitrarily complex -scoring patterns. - -@menu -* Advanced Scoring Syntax:: A definition. -* Advanced Scoring Examples:: What they look like. -* Advanced Scoring Tips:: Getting the most out of it. -@end menu - - -@node Advanced Scoring Syntax -@subsection Advanced Scoring Syntax - -Ordinary scoring rules have a string as the first element in the rule. -Advanced scoring rules have a list as the first element. The second -element is the score to be applied if the first element evaluated to a -non-@code{nil} value. - -These lists may consist of three logical operators, one redirection -operator, and various match operators. - -Logical operators: - -@table @code -@item & -@itemx and -This logical operator will evaluate each of its arguments until it finds -one that evaluates to @code{false}, and then it'll stop. If all arguments -evaluate to @code{true} values, then this operator will return -@code{true}. - -@item | -@itemx or -This logical operator will evaluate each of its arguments until it finds -one that evaluates to @code{true}. If no arguments are @code{true}, -then this operator will return @code{false}. - -@item ! -@itemx not -@itemx ,A,(B -This logical operator only takes a single argument. It returns the -logical negation of the value of its argument. - -@end table - -There is an @dfn{indirection operator} that will make its arguments -apply to the ancestors of the current article being scored. For -instance, @code{1-} will make score rules apply to the parent of the -current article. @code{2-} will make score rules apply to the -grandparent of the current article. Alternatively, you can write -@code{^^}, where the number of @code{^}s (carets) says how far back into -the ancestry you want to go. - -Finally, we have the match operators. These are the ones that do the -real work. Match operators are header name strings followed by a match -and a match type. A typical match operator looks like @samp{("from" -"Lars Ingebrigtsen" s)}. The header names are the same as when using -simple scoring, and the match types are also the same. - - -@node Advanced Scoring Examples -@subsection Advanced Scoring Examples - -Let's say you want to increase the score of articles written by Lars -when he's talking about Gnus: - -@example -((& - ("from" "Lars Ingebrigtsen") - ("subject" "Gnus")) - 1000) -@end example - -Quite simple, huh? - -When he writes long articles, he sometimes has something nice to say: - -@example -((& - ("from" "Lars Ingebrigtsen") - (| - ("subject" "Gnus") - ("lines" 100 >))) - 1000) -@end example - -However, when he responds to things written by Reig Eigil Logge, you -really don't want to read what he's written: - -@example -((& - ("from" "Lars Ingebrigtsen") - (1- ("from" "Reig Eigir Logge"))) - -100000) -@end example - -Everybody that follows up Redmondo when he writes about disappearing -socks should have their scores raised, but only when they talk about -white socks. However, when Lars talks about socks, it's usually not -very interesting: - -@example -((& - (1- - (& - ("from" "redmondo@@.*no" r) - ("body" "disappearing.*socks" t))) - (! ("from" "Lars Ingebrigtsen")) - ("body" "white.*socks")) - 1000) -@end example - -The possibilities are endless. - - -@node Advanced Scoring Tips -@subsection Advanced Scoring Tips - -The @code{&} and @code{|} logical operators do short-circuit logic. -That is, they stop processing their arguments when it's clear what the -result of the operation will be. For instance, if one of the arguments -of an @code{&} evaluates to @code{false}, there's no point in evaluating -the rest of the arguments. This means that you should put slow matches -(@samp{body}, @samp{header}) last and quick matches (@samp{from}, -@samp{subject}) first. - -The indirection arguments (@code{1-} and so on) will make their -arguments work on previous generations of the thread. If you say -something like: - -@example -... -(1- - (1- - ("from" "lars"))) -... -@end example - -Then that means "score on the from header of the grandparent of the -current article". An indirection is quite fast, but it's better to say: - -@example -(1- - (& - ("from" "Lars") - ("subject" "Gnus"))) -@end example - -than it is to say: - -@example -(& - (1- ("from" "Lars")) - (1- ("subject" "Gnus"))) -@end example - - -@node Score Decays -@section Score Decays -@cindex score decays -@cindex decays - -You may find that your scores have a tendency to grow without -bounds, especially if you're using adaptive scoring. If scores get too -big, they lose all meaning---they simply max out and it's difficult to -use them in any sensible way. - -@vindex gnus-decay-scores -@findex gnus-decay-score -@vindex gnus-decay-score-function -Gnus provides a mechanism for decaying scores to help with this problem. -When score files are loaded and @code{gnus-decay-scores} is -non-@code{nil}, Gnus will run the score files through the decaying -mechanism thereby lowering the scores of all non-permanent score rules. -The decay itself if performed by the @code{gnus-decay-score-function} -function, which is @code{gnus-decay-score} by default. Here's the -definition of that function: - -@lisp -(defun gnus-decay-score (score) - "Decay SCORE. -This is done according to `gnus-score-decay-constant' -and `gnus-score-decay-scale'." - (floor - (- score - (* (if (< score 0) 1 -1) - (min (abs score) - (max gnus-score-decay-constant - (* (abs score) - gnus-score-decay-scale))))))) -@end lisp - -@vindex gnus-score-decay-scale -@vindex gnus-score-decay-constant -@code{gnus-score-decay-constant} is 3 by default and -@code{gnus-score-decay-scale} is 0.05. This should cause the following: - -@enumerate -@item -Scores between -3 and 3 will be set to 0 when this function is called. - -@item -Scores with magnitudes between 3 and 60 will be shrunk by 3. - -@item -Scores with magnitudes greater than 60 will be shrunk by 5% of the -score. -@end enumerate - -If you don't like this decay function, write your own. It is called -with the score to be decayed as its only parameter, and it should return -the new score, which should be an integer. - -Gnus will try to decay scores once a day. If you haven't run Gnus for -four days, Gnus will decay the scores four times, for instance. - - -@node Various -@chapter Various - -@menu -* Process/Prefix:: A convention used by many treatment commands. -* Interactive:: Making Gnus ask you many questions. -* Symbolic Prefixes:: How to supply some Gnus functions with options. -* Formatting Variables:: You can specify what buffers should look like. -* Windows Configuration:: Configuring the Gnus buffer windows. -* Faces and Fonts:: How to change how faces look. -* Compilation:: How to speed Gnus up. -* Mode Lines:: Displaying information in the mode lines. -* Highlighting and Menus:: Making buffers look all nice and cozy. -* Buttons:: Get tendonitis in ten easy steps! -* Daemons:: Gnus can do things behind your back. -* NoCeM:: How to avoid spam and other fatty foods. -* Undo:: Some actions can be undone. -* Moderation:: What to do if you're a moderator. -* XEmacs Enhancements:: There are more pictures and stuff under XEmacs. -* Fuzzy Matching:: What's the big fuzz? -* Thwarting Email Spam:: A how-to on avoiding unsolicited commercial email. -* Various Various:: Things that are really various. -@end menu - - -@node Process/Prefix -@section Process/Prefix -@cindex process/prefix convention - -Many functions, among them functions for moving, decoding and saving -articles, use what is known as the @dfn{Process/Prefix convention}. - -This is a method for figuring out what articles the user wants the -command to be performed on. - -It goes like this: - -If the numeric prefix is N, perform the operation on the next N -articles, starting with the current one. If the numeric prefix is -negative, perform the operation on the previous N articles, starting -with the current one. - -@vindex transient-mark-mode -If @code{transient-mark-mode} in non-@code{nil} and the region is -active, all articles in the region will be worked upon. - -If there is no numeric prefix, but some articles are marked with the -process mark, perform the operation on the articles marked with -the process mark. - -If there is neither a numeric prefix nor any articles marked with the -process mark, just perform the operation on the current article. - -Quite simple, really, but it needs to be made clear so that surprises -are avoided. - -Commands that react to the process mark will push the current list of -process marked articles onto a stack and will then clear all process -marked articles. You can restore the previous configuration with the -@kbd{M P y} command (@pxref{Setting Process Marks}). - -@vindex gnus-summary-goto-unread -One thing that seems to shock & horrify lots of people is that, for -instance, @kbd{3 d} does exactly the same as @kbd{d} @kbd{d} @kbd{d}. -Since each @kbd{d} (which marks the current article as read) by default -goes to the next unread article after marking, this means that @kbd{3 d} -will mark the next three unread articles as read, no matter what the -summary buffer looks like. Set @code{gnus-summary-goto-unread} to -@code{nil} for a more straightforward action. - - -@node Interactive -@section Interactive -@cindex interaction - -@table @code - -@item gnus-novice-user -@vindex gnus-novice-user -If this variable is non-@code{nil}, you are either a newcomer to the -World of Usenet, or you are very cautious, which is a nice thing to be, -really. You will be given questions of the type ``Are you sure you want -to do this?'' before doing anything dangerous. This is @code{t} by -default. - -@item gnus-expert-user -@vindex gnus-expert-user -If this variable is non-@code{nil}, you will seldom be asked any -questions by Gnus. It will simply assume you know what you're doing, no -matter how strange. - -@item gnus-interactive-catchup -@vindex gnus-interactive-catchup -Require confirmation before catching up a group if non-@code{nil}. It -is @code{t} by default. - -@item gnus-interactive-exit -@vindex gnus-interactive-exit -Require confirmation before exiting Gnus. This variable is @code{t} by -default. -@end table - - -@node Symbolic Prefixes -@section Symbolic Prefixes -@cindex symbolic prefixes - -Quite a lot of Emacs commands react to the (numeric) prefix. For -instance, @kbd{C-u 4 C-f} moves point four characters forward, and -@kbd{C-u 9 0 0 I s s p} adds a permanent @code{Subject} substring score -rule of 900 to the current article. - -This is all nice and well, but what if you want to give a command some -additional information? Well, what most commands do is interpret the -``raw'' prefix in some special way. @kbd{C-u 0 C-x C-s} means that one -doesn't want a backup file to be created when saving the current buffer, -for instance. But what if you want to save without making a backup -file, and you want Emacs to flash lights and play a nice tune at the -same time? You can't, and you're probably perfectly happy that way. - -@kindex M-i (Summary) -@findex gnus-symbolic-argument -I'm not, so I've added a second prefix---the @dfn{symbolic prefix}. The -prefix key is @kbd{M-i} (@code{gnus-symbolic-argument}), and the next -character typed in is the value. You can stack as many @kbd{M-i} -prefixes as you want. @kbd{M-i a M-C-u} means ``feed the @kbd{M-C-u} -command the symbolic prefix @code{a}''. @kbd{M-i a M-i b M-C-u} means -``feed the @kbd{M-C-u} command the symbolic prefixes @code{a} and -@code{b}''. You get the drift. - -Typing in symbolic prefixes to commands that don't accept them doesn't -hurt, but it doesn't do any good either. Currently not many Gnus -functions make use of the symbolic prefix. - -If you're interested in how Gnus implements this, @pxref{Extended -Interactive}. - - -@node Formatting Variables -@section Formatting Variables -@cindex formatting variables - -Throughout this manual you've probably noticed lots of variables called -things like @code{gnus-group-line-format} and -@code{gnus-summary-mode-line-format}. These control how Gnus is to -output lines in the various buffers. There's quite a lot of them. -Fortunately, they all use the same syntax, so there's not that much to -be annoyed by. - -Here's an example format spec (from the group buffer): @samp{%M%S%5y: -%(%g%)\n}. We see that it is indeed extremely ugly, and that there are -lots of percentages everywhere. - -@menu -* Formatting Basics:: A formatting variable is basically a format string. -* Mode Line Formatting:: Some rules about mode line formatting variables. -* Advanced Formatting:: Modifying output in various ways. -* User-Defined Specs:: Having Gnus call your own functions. -* Formatting Fonts:: Making the formatting look colorful and nice. -@end menu - -Currently Gnus uses the following formatting variables: -@code{gnus-group-line-format}, @code{gnus-summary-line-format}, -@code{gnus-server-line-format}, @code{gnus-topic-line-format}, -@code{gnus-group-mode-line-format}, -@code{gnus-summary-mode-line-format}, -@code{gnus-article-mode-line-format}, -@code{gnus-server-mode-line-format}, and -@code{gnus-summary-pick-line-format}. - -All these format variables can also be arbitrary elisp forms. In that -case, they will be @code{eval}ed to insert the required lines. - -@kindex M-x gnus-update-format -@findex gnus-update-format -Gnus includes a command to help you while creating your own format -specs. @kbd{M-x gnus-update-format} will @code{eval} the current form, -update the spec in question and pop you to a buffer where you can -examine the resulting lisp code to be run to generate the line. - - - -@node Formatting Basics -@subsection Formatting Basics - -Each @samp{%} element will be replaced by some string or other when the -buffer in question is generated. @samp{%5y} means ``insert the @samp{y} -spec, and pad with spaces to get a 5-character field''. - -As with normal C and Emacs Lisp formatting strings, the numerical -modifier between the @samp{%} and the formatting type character will -@dfn{pad} the output so that it is always at least that long. -@samp{%5y} will make the field always (at least) five characters wide by -padding with spaces to the left. If you say @samp{%-5y}, it will pad to -the right instead. - -You may also wish to limit the length of the field to protect against -particularly wide values. For that you can say @samp{%4,6y}, which -means that the field will never be more than 6 characters wide and never -less than 4 characters wide. - - -@node Mode Line Formatting -@subsection Mode Line Formatting - -Mode line formatting variables (e.g., -@code{gnus-summary-mode-line-format}) follow the same rules as other, -buffer line oriented formatting variables (@pxref{Formatting Basics}) -with the following two differences: - -@enumerate - -@item -There must be no newline (@samp{\n}) at the end. - -@item -The special @samp{%%b} spec can be used to display the buffer name. -Well, it's no spec at all, really---@samp{%%} is just a way to quote -@samp{%} to allow it to pass through the formatting machinery unmangled, -so that Emacs receives @samp{%b}, which is something the Emacs mode line -display interprets to mean ``show the buffer name''. For a full list of -mode line specs Emacs understands, see the documentation of the -@code{mode-line-format} variable. - -@end enumerate - - -@node Advanced Formatting -@subsection Advanced Formatting - -It is frequently useful to post-process the fields in some way. -Padding, limiting, cutting off parts and suppressing certain values can -be achieved by using @dfn{tilde modifiers}. A typical tilde spec might -look like @samp{%~(cut 3)~(ignore "0")y}. - -These are the valid modifiers: - -@table @code -@item pad -@itemx pad-left -Pad the field to the left with spaces until it reaches the required -length. - -@item pad-right -Pad the field to the right with spaces until it reaches the required -length. - -@item max -@itemx max-left -Cut off characters from the left until it reaches the specified length. - -@item max-right -Cut off characters from the right until it reaches the specified -length. - -@item cut -@itemx cut-left -Cut off the specified number of characters from the left. - -@item cut-right -Cut off the specified number of characters from the right. - -@item ignore -Return an empty string if the field is equal to the specified value. - -@item form -Use the specified form as the field value when the @samp{@@} spec is -used. -@end table - -Let's take an example. The @samp{%o} spec in the summary mode lines -will return a date in compact ISO8601 format---@samp{19960809T230410}. -This is quite a mouthful, so we want to shave off the century number and -the time, leaving us with a six-character date. That would be -@samp{%~(cut-left 2)~(max-right 6)~(pad 6)o}. (Cutting is done before -maxing, and we need the padding to ensure that the date is never less -than 6 characters to make it look nice in columns.) - -Ignoring is done first; then cutting; then maxing; and then as the very -last operation, padding. - -If you use lots of these advanced thingies, you'll find that Gnus gets -quite slow. This can be helped enormously by running @kbd{M-x -gnus-compile} when you are satisfied with the look of your lines. -@xref{Compilation}. - - -@node User-Defined Specs -@subsection User-Defined Specs - -All the specs allow for inserting user defined specifiers---@samp{u}. -The next character in the format string should be a letter. Gnus -will call the function @code{gnus-user-format-function-}@samp{X}, where -@samp{X} is the letter following @samp{%u}. The function will be passed -a single parameter---what the parameter means depends on what buffer -it's being called from. The function should return a string, which will -be inserted into the buffer just like information from any other -specifier. This function may also be called with dummy values, so it -should protect against that. - -You can also use tilde modifiers (@pxref{Advanced Formatting} to achieve -much the same without defining new functions. Here's an example: -@samp{%~(form (count-lines (point-min) (point)))@@}. The form -given here will be evaluated to yield the current line number, and then -inserted. - - -@node Formatting Fonts -@subsection Formatting Fonts - -There are specs for highlighting, and these are shared by all the format -variables. Text inside the @samp{%(} and @samp{%)} specifiers will get -the special @code{mouse-face} property set, which means that it will be -highlighted (with @code{gnus-mouse-face}) when you put the mouse pointer -over it. - -Text inside the @samp{%@{} and @samp{%@}} specifiers will have their -normal faces set using @code{gnus-face-0}, which is @code{bold} by -default. If you say @samp{%1@{}, you'll get @code{gnus-face-1} instead, -and so on. Create as many faces as you wish. The same goes for the -@code{mouse-face} specs---you can say @samp{%3(hello%)} to have -@samp{hello} mouse-highlighted with @code{gnus-mouse-face-3}. - -Here's an alternative recipe for the group buffer: - -@lisp -;; Create three face types. -(setq gnus-face-1 'bold) -(setq gnus-face-3 'italic) - -;; We want the article count to be in -;; a bold and green face. So we create -;; a new face called `my-green-bold'. -(copy-face 'bold 'my-green-bold) -;; Set the color. -(set-face-foreground 'my-green-bold "ForestGreen") -(setq gnus-face-2 'my-green-bold) - -;; Set the new & fancy format. -(setq gnus-group-line-format - "%M%S%3@{%5y%@}%2[:%] %(%1@{%g%@}%)\n") -@end lisp - -I'm sure you'll be able to use this scheme to create totally unreadable -and extremely vulgar displays. Have fun! - -Note that the @samp{%(} specs (and friends) do not make any sense on the -mode-line variables. - - -@node Windows Configuration -@section Windows Configuration -@cindex windows configuration - -No, there's nothing here about X, so be quiet. - -@vindex gnus-use-full-window -If @code{gnus-use-full-window} non-@code{nil}, Gnus will delete all -other windows and occupy the entire Emacs screen by itself. It is -@code{t} by default. - -@vindex gnus-buffer-configuration -@code{gnus-buffer-configuration} describes how much space each Gnus -buffer should be given. Here's an excerpt of this variable: - -@lisp -((group (vertical 1.0 (group 1.0 point) - (if gnus-carpal (group-carpal 4)))) - (article (vertical 1.0 (summary 0.25 point) - (article 1.0)))) -@end lisp - -This is an alist. The @dfn{key} is a symbol that names some action or -other. For instance, when displaying the group buffer, the window -configuration function will use @code{group} as the key. A full list of -possible names is listed below. - -The @dfn{value} (i.e., the @dfn{split}) says how much space each buffer -should occupy. To take the @code{article} split as an example - - -@lisp -(article (vertical 1.0 (summary 0.25 point) - (article 1.0))) -@end lisp - -This @dfn{split} says that the summary buffer should occupy 25% of upper -half of the screen, and that it is placed over the article buffer. As -you may have noticed, 100% + 25% is actually 125% (yup, I saw y'all -reaching for that calculator there). However, the special number -@code{1.0} is used to signal that this buffer should soak up all the -rest of the space available after the rest of the buffers have taken -whatever they need. There should be only one buffer with the @code{1.0} -size spec per split. - -Point will be put in the buffer that has the optional third element -@code{point}. In a @code{frame} split, the last subsplit having a leaf -split where the tag @code{frame-focus} is a member (i.e. is the third or -fourth element in the list, depending on whether the @code{point} tag is -present) gets focus. - -Here's a more complicated example: - -@lisp -(article (vertical 1.0 (group 4) - (summary 0.25 point) - (if gnus-carpal (summary-carpal 4)) - (article 1.0))) -@end lisp - -If the size spec is an integer instead of a floating point number, -then that number will be used to say how many lines a buffer should -occupy, not a percentage. - -If the @dfn{split} looks like something that can be @code{eval}ed (to be -precise---if the @code{car} of the split is a function or a subr), this -split will be @code{eval}ed. If the result is non-@code{nil}, it will -be used as a split. This means that there will be three buffers if -@code{gnus-carpal} is @code{nil}, and four buffers if @code{gnus-carpal} -is non-@code{nil}. - -Not complicated enough for you? Well, try this on for size: - -@lisp -(article (horizontal 1.0 - (vertical 0.5 - (group 1.0) - (gnus-carpal 4)) - (vertical 1.0 - (summary 0.25 point) - (summary-carpal 4) - (article 1.0)))) -@end lisp - -Whoops. Two buffers with the mystery 100% tag. And what's that -@code{horizontal} thingie? - -If the first element in one of the split is @code{horizontal}, Gnus will -split the window horizontally, giving you two windows side-by-side. -Inside each of these strips you may carry on all you like in the normal -fashion. The number following @code{horizontal} says what percentage of -the screen is to be given to this strip. - -For each split, there @emph{must} be one element that has the 100% tag. -The splitting is never accurate, and this buffer will eat any leftover -lines from the splits. - -To be slightly more formal, here's a definition of what a valid split -may look like: - -@example -split = frame | horizontal | vertical | buffer | form -frame = "(frame " size *split ")" -horizontal = "(horizontal " size *split ")" -vertical = "(vertical " size *split ")" -buffer = "(" buffer-name " " size *[ "point" ] *[ "frame-focus"] ")" -size = number | frame-params -buffer-name = group | article | summary ... -@end example - -The limitations are that the @code{frame} split can only appear as the -top-level split. @var{form} should be an Emacs Lisp form that should -return a valid split. We see that each split is fully recursive, and -may contain any number of @code{vertical} and @code{horizontal} splits. - -@vindex gnus-window-min-width -@vindex gnus-window-min-height -@cindex window height -@cindex window width -Finding the right sizes can be a bit complicated. No window may be less -than @code{gnus-window-min-height} (default 1) characters high, and all -windows must be at least @code{gnus-window-min-width} (default 1) -characters wide. Gnus will try to enforce this before applying the -splits. If you want to use the normal Emacs window width/height limit, -you can just set these two variables to @code{nil}. - -If you're not familiar with Emacs terminology, @code{horizontal} and -@code{vertical} splits may work the opposite way of what you'd expect. -Windows inside a @code{horizontal} split are shown side-by-side, and -windows within a @code{vertical} split are shown above each other. - -@findex gnus-configure-frame -If you want to experiment with window placement, a good tip is to call -@code{gnus-configure-frame} directly with a split. This is the function -that does all the real work when splitting buffers. Below is a pretty -nonsensical configuration with 5 windows; two for the group buffer and -three for the article buffer. (I said it was nonsensical.) If you -@code{eval} the statement below, you can get an idea of how that would -look straight away, without going through the normal Gnus channels. -Play with it until you're satisfied, and then use -@code{gnus-add-configuration} to add your new creation to the buffer -configuration list. - -@lisp -(gnus-configure-frame - '(horizontal 1.0 - (vertical 10 - (group 1.0) - (article 0.3 point)) - (vertical 1.0 - (article 1.0) - (horizontal 4 - (group 1.0) - (article 10))))) -@end lisp - -You might want to have several frames as well. No prob---just use the -@code{frame} split: - -@lisp -(gnus-configure-frame - '(frame 1.0 - (vertical 1.0 - (summary 0.25 point frame-focus) - (article 1.0)) - (vertical ((height . 5) (width . 15) - (user-position . t) - (left . -1) (top . 1)) - (picon 1.0)))) - -@end lisp - -This split will result in the familiar summary/article window -configuration in the first (or ``main'') frame, while a small additional -frame will be created where picons will be shown. As you can see, -instead of the normal @code{1.0} top-level spec, each additional split -should have a frame parameter alist as the size spec. -@xref{Frame Parameters, , Frame Parameters, elisp, The GNU Emacs Lisp -Reference Manual}. Under XEmacs, a frame property list will be -accepted, too---for instance, @code{(height 5 width 15 left -1 top 1)} -is such a plist. - -Here's a list of all possible keys for -@code{gnus-buffer-configuration}: - -@code{group}, @code{summary}, @code{article}, @code{server}, -@code{browse}, @code{message}, @code{pick}, @code{info}, -@code{summary-faq}, @code{edit-group}, @code{edit-server}, -@code{edit-score}, @code{post}, @code{reply}, @code{forward}, -@code{reply-yank}, @code{mail-bounce}, @code{draft}, @code{pipe}, -@code{bug}, @code{compose-bounce}, and @code{score-trace}. - -Note that the @code{message} key is used for both -@code{gnus-group-mail} and @code{gnus-summary-mail-other-window}. If -it is desirable to distinguish between the two, something like this -might be used: - -@lisp -(message (horizontal 1.0 - (vertical 1.0 (message 1.0 point)) - (vertical 0.24 - (if (buffer-live-p gnus-summary-buffer) - '(summary 0.5)) - (group 1.0))))) -@end lisp - -@findex gnus-add-configuration -Since the @code{gnus-buffer-configuration} variable is so long and -complicated, there's a function you can use to ease changing the config -of a single setting: @code{gnus-add-configuration}. If, for instance, -you want to change the @code{article} setting, you could say: - -@lisp -(gnus-add-configuration - '(article (vertical 1.0 - (group 4) - (summary .25 point) - (article 1.0)))) -@end lisp - -You'd typically stick these @code{gnus-add-configuration} calls in your -@file{.gnus.el} file or in some startup hook---they should be run after -Gnus has been loaded. - -@vindex gnus-always-force-window-configuration -If all windows mentioned in the configuration are already visible, Gnus -won't change the window configuration. If you always want to force the -``right'' window configuration, you can set -@code{gnus-always-force-window-configuration} to non-@code{nil}. - - -@node Faces and Fonts -@section Faces and Fonts -@cindex faces -@cindex fonts -@cindex colors - -Fiddling with fonts and faces used to be very difficult, but these days -it is very simple. You simply say @kbd{M-x customize-face}, pick out -the face you want to alter, and alter it via the standard Customize -interface. - - -@node Compilation -@section Compilation -@cindex compilation -@cindex byte-compilation - -@findex gnus-compile - -Remember all those line format specification variables? -@code{gnus-summary-line-format}, @code{gnus-group-line-format}, and so -on. Now, Gnus will of course heed whatever these variables are, but, -unfortunately, changing them will mean a quite significant slow-down. -(The default values of these variables have byte-compiled functions -associated with them, while the user-generated versions do not, of -course.) - -To help with this, you can run @kbd{M-x gnus-compile} after you've -fiddled around with the variables and feel that you're (kind of) -satisfied. This will result in the new specs being byte-compiled, and -you'll get top speed again. Gnus will save these compiled specs in the -@file{.newsrc.eld} file. (User-defined functions aren't compiled by -this function, though---you should compile them yourself by sticking -them into the @code{.gnus.el} file and byte-compiling that file.) - - -@node Mode Lines -@section Mode Lines -@cindex mode lines - -@vindex gnus-updated-mode-lines -@code{gnus-updated-mode-lines} says what buffers should keep their mode -lines updated. It is a list of symbols. Supported symbols include -@code{group}, @code{article}, @code{summary}, @code{server}, -@code{browse}, and @code{tree}. If the corresponding symbol is present, -Gnus will keep that mode line updated with information that may be -pertinent. If this variable is @code{nil}, screen refresh may be -quicker. - -@cindex display-time - -@vindex gnus-mode-non-string-length -By default, Gnus displays information on the current article in the mode -lines of the summary and article buffers. The information Gnus wishes -to display (e.g. the subject of the article) is often longer than the -mode lines, and therefore have to be cut off at some point. The -@code{gnus-mode-non-string-length} variable says how long the other -elements on the line is (i.e., the non-info part). If you put -additional elements on the mode line (e.g. a clock), you should modify -this variable: - -@c Hook written by Francesco Potorti` -@lisp -(add-hook 'display-time-hook - (lambda () (setq gnus-mode-non-string-length - (+ 21 - (if line-number-mode 5 0) - (if column-number-mode 4 0) - (length display-time-string))))) -@end lisp - -If this variable is @code{nil} (which is the default), the mode line -strings won't be chopped off, and they won't be padded either. Note -that the default is unlikely to be desirable, as even the percentage -complete in the buffer may be crowded off the mode line; the user should -configure this variable appropriately for her configuration. - - -@node Highlighting and Menus -@section Highlighting and Menus -@cindex visual -@cindex highlighting -@cindex menus - -@vindex gnus-visual -The @code{gnus-visual} variable controls most of the Gnus-prettifying -aspects. If @code{nil}, Gnus won't attempt to create menus or use fancy -colors or fonts. This will also inhibit loading the @file{gnus-vis.el} -file. - -This variable can be a list of visual properties that are enabled. The -following elements are valid, and are all included by default: - -@table @code -@item group-highlight -Do highlights in the group buffer. -@item summary-highlight -Do highlights in the summary buffer. -@item article-highlight -Do highlights in the article buffer. -@item highlight -Turn on highlighting in all buffers. -@item group-menu -Create menus in the group buffer. -@item summary-menu -Create menus in the summary buffers. -@item article-menu -Create menus in the article buffer. -@item browse-menu -Create menus in the browse buffer. -@item server-menu -Create menus in the server buffer. -@item score-menu -Create menus in the score buffers. -@item menu -Create menus in all buffers. -@end table - -So if you only want highlighting in the article buffer and menus in all -buffers, you could say something like: - -@lisp -(setq gnus-visual '(article-highlight menu)) -@end lisp - -If you want highlighting only and no menus whatsoever, you'd say: - -@lisp -(setq gnus-visual '(highlight)) -@end lisp - -If @code{gnus-visual} is @code{t}, highlighting and menus will be used -in all Gnus buffers. - -Other general variables that influence the look of all buffers include: - -@table @code -@item gnus-mouse-face -@vindex gnus-mouse-face -This is the face (i.e., font) used for mouse highlighting in Gnus. No -mouse highlights will be done if @code{gnus-visual} is @code{nil}. - -@end table - -There are hooks associated with the creation of all the different menus: - -@table @code - -@item gnus-article-menu-hook -@vindex gnus-article-menu-hook -Hook called after creating the article mode menu. - -@item gnus-group-menu-hook -@vindex gnus-group-menu-hook -Hook called after creating the group mode menu. - -@item gnus-summary-menu-hook -@vindex gnus-summary-menu-hook -Hook called after creating the summary mode menu. - -@item gnus-server-menu-hook -@vindex gnus-server-menu-hook -Hook called after creating the server mode menu. - -@item gnus-browse-menu-hook -@vindex gnus-browse-menu-hook -Hook called after creating the browse mode menu. - -@item gnus-score-menu-hook -@vindex gnus-score-menu-hook -Hook called after creating the score mode menu. - -@end table - - -@node Buttons -@section Buttons -@cindex buttons -@cindex mouse -@cindex click - -Those new-fangled @dfn{mouse} contraptions is very popular with the -young, hep kids who don't want to learn the proper way to do things -these days. Why, I remember way back in the summer of '89, when I was -using Emacs on a Tops 20 system. Three hundred users on one single -machine, and every user was running Simula compilers. Bah! - -Right. - -@vindex gnus-carpal -Well, you can make Gnus display bufferfuls of buttons you can click to -do anything by setting @code{gnus-carpal} to @code{t}. Pretty simple, -really. Tell the chiropractor I sent you. - - -@table @code - -@item gnus-carpal-mode-hook -@vindex gnus-carpal-mode-hook -Hook run in all carpal mode buffers. - -@item gnus-carpal-button-face -@vindex gnus-carpal-button-face -Face used on buttons. - -@item gnus-carpal-header-face -@vindex gnus-carpal-header-face -Face used on carpal buffer headers. - -@item gnus-carpal-group-buffer-buttons -@vindex gnus-carpal-group-buffer-buttons -Buttons in the group buffer. - -@item gnus-carpal-summary-buffer-buttons -@vindex gnus-carpal-summary-buffer-buttons -Buttons in the summary buffer. - -@item gnus-carpal-server-buffer-buttons -@vindex gnus-carpal-server-buffer-buttons -Buttons in the server buffer. - -@item gnus-carpal-browse-buffer-buttons -@vindex gnus-carpal-browse-buffer-buttons -Buttons in the browse buffer. -@end table - -All the @code{buttons} variables are lists. The elements in these list -are either cons cells where the @code{car} contains a text to be displayed and -the @code{cdr} contains a function symbol, or a simple string. - - -@node Daemons -@section Daemons -@cindex demons -@cindex daemons - -Gnus, being larger than any program ever written (allegedly), does lots -of strange stuff that you may wish to have done while you're not -present. For instance, you may want it to check for new mail once in a -while. Or you may want it to close down all connections to all servers -when you leave Emacs idle. And stuff like that. - -Gnus will let you do stuff like that by defining various -@dfn{handlers}. Each handler consists of three elements: A -@var{function}, a @var{time}, and an @var{idle} parameter. - -Here's an example of a handler that closes connections when Emacs has -been idle for thirty minutes: - -@lisp -(gnus-demon-close-connections nil 30) -@end lisp - -Here's a handler that scans for PGP headers every hour when Emacs is -idle: - -@lisp -(gnus-demon-scan-pgp 60 t) -@end lisp - -This @var{time} parameter and than @var{idle} parameter work together -in a strange, but wonderful fashion. Basically, if @var{idle} is -@code{nil}, then the function will be called every @var{time} minutes. - -If @var{idle} is @code{t}, then the function will be called after -@var{time} minutes only if Emacs is idle. So if Emacs is never idle, -the function will never be called. But once Emacs goes idle, the -function will be called every @var{time} minutes. - -If @var{idle} is a number and @var{time} is a number, the function will -be called every @var{time} minutes only when Emacs has been idle for -@var{idle} minutes. - -If @var{idle} is a number and @var{time} is @code{nil}, the function -will be called once every time Emacs has been idle for @var{idle} -minutes. - -And if @var{time} is a string, it should look like @samp{07:31}, and -the function will then be called once every day somewhere near that -time. Modified by the @var{idle} parameter, of course. - -@vindex gnus-demon-timestep -(When I say ``minute'' here, I really mean @code{gnus-demon-timestep} -seconds. This is 60 by default. If you change that variable, -all the timings in the handlers will be affected.) - -@vindex gnus-use-demon -To set the whole thing in motion, though, you have to set -@code{gnus-use-demon} to @code{t}. - -So, if you want to add a handler, you could put something like this in -your @file{.gnus} file: - -@findex gnus-demon-add-handler -@lisp -(gnus-demon-add-handler 'gnus-demon-close-connections 30 t) -@end lisp - -@findex gnus-demon-add-nocem -@findex gnus-demon-add-scanmail -@findex gnus-demon-add-rescan -@findex gnus-demon-add-scan-timestamps -@findex gnus-demon-add-disconnection -Some ready-made functions to do this have been created: -@code{gnus-demon-add-nocem}, @code{gnus-demon-add-disconnection}, -@code{gnus-demon-add-nntp-close-connection}, -@code{gnus-demon-add-scan-timestamps}, @code{gnus-demon-add-rescan}, and -@code{gnus-demon-add-scanmail}. Just put those functions in your -@file{.gnus} if you want those abilities. - -@findex gnus-demon-init -@findex gnus-demon-cancel -@vindex gnus-demon-handlers -If you add handlers to @code{gnus-demon-handlers} directly, you should -run @code{gnus-demon-init} to make the changes take hold. To cancel all -daemons, you can use the @code{gnus-demon-cancel} function. - -Note that adding daemons can be pretty naughty if you over do it. Adding -functions that scan all news and mail from all servers every two seconds -is a sure-fire way of getting booted off any respectable system. So -behave. - - -@node NoCeM -@section NoCeM -@cindex nocem -@cindex spam - -@dfn{Spamming} is posting the same article lots and lots of times. -Spamming is bad. Spamming is evil. - -Spamming is usually canceled within a day or so by various anti-spamming -agencies. These agencies usually also send out @dfn{NoCeM} messages. -NoCeM is pronounced ``no see-'em'', and means what the name -implies---these are messages that make the offending articles, like, go -away. - -What use are these NoCeM messages if the articles are canceled anyway? -Some sites do not honor cancel messages and some sites just honor cancels -from a select few people. Then you may wish to make use of the NoCeM -messages, which are distributed in the @samp{alt.nocem.misc} newsgroup. - -Gnus can read and parse the messages in this group automatically, and -this will make spam disappear. - -There are some variables to customize, of course: - -@table @code -@item gnus-use-nocem -@vindex gnus-use-nocem -Set this variable to @code{t} to set the ball rolling. It is @code{nil} -by default. - -@item gnus-nocem-groups -@vindex gnus-nocem-groups -Gnus will look for NoCeM messages in the groups in this list. The -default is @code{("news.lists.filters" "news.admin.net-abuse.bulletins" -"alt.nocem.misc" "news.admin.net-abuse.announce")}. - -@item gnus-nocem-issuers -@vindex gnus-nocem-issuers -There are many people issuing NoCeM messages. This list says what -people you want to listen to. The default is @code{("Automoose-1" -"rbraver@@ohww.norman.ok.us" "clewis@@ferret.ocunix.on.ca" -"jem@@xpat.com" "snowhare@@xmission.com" "red@@redpoll.mrfs.oh.us -(Richard E. Depew)")}; fine, upstanding citizens all of them. - -Known despammers that you can put in this list include: - -@table @samp -@item clewis@@ferret.ocunix.on.ca; -@cindex Chris Lewis -Chris Lewis---Major Canadian despammer who has probably canceled more -usenet abuse than anybody else. - -@item Automoose-1 -@cindex CancelMoose[tm] -The CancelMoose[tm] on autopilot. The CancelMoose[tm] is reputed to be -Norwegian, and was the person(s) who invented NoCeM. - -@item jem@@xpat.com; -@cindex Jem -John Milburn---despammer located in Korea who is getting very busy these -days. - -@item red@@redpoll.mrfs.oh.us (Richard E. Depew) -Richard E. Depew---lone American despammer. He mostly cancels binary -postings to non-binary groups and removes spews (regurgitated articles). -@end table - -You do not have to heed NoCeM messages from all these people---just the -ones you want to listen to. You also don't have to accept all NoCeM -messages from the people you like. Each NoCeM message has a @dfn{type} -header that gives the message a (more or less, usually less) rigorous -definition. Common types are @samp{spam}, @samp{spew}, @samp{mmf}, -@samp{binary}, and @samp{troll}. To specify this, you have to use -@var{(issuer conditions ...)} elements in the list. Each condition is -either a string (which is a regexp that matches types you want to use) -or a list on the form @code{(not STRING)}, where @var{string} is a -regexp that matches types you don't want to use. - -For instance, if you want all NoCeM messages from Chris Lewis except his -@samp{troll} messages, you'd say: - -@lisp -("clewis@@ferret.ocunix.on.ca" ".*" (not "troll")) -@end lisp - -On the other hand, if you just want nothing but his @samp{spam} and -@samp{spew} messages, you'd say: - -@lisp -("clewis@@ferret.ocunix.on.ca" (not ".*") "spew" "spam") -@end lisp - -The specs are applied left-to-right. - - -@item gnus-nocem-verifyer -@vindex gnus-nocem-verifyer -@findex mc-verify -This should be a function for verifying that the NoCeM issuer is who she -says she is. The default is @code{mc-verify}, which is a Mailcrypt -function. If this is too slow and you don't care for verification -(which may be dangerous), you can set this variable to @code{nil}. - -If you want signed NoCeM messages to be verified and unsigned messages -not to be verified (but used anyway), you could do something like: - -@lisp -(setq gnus-nocem-verifyer 'my-gnus-mc-verify) - -(defun my-gnus-mc-verify () - (not (eq 'forged - (ignore-errors - (if (mc-verify) - t - 'forged))))) -@end lisp - -This might be dangerous, though. - -@item gnus-nocem-directory -@vindex gnus-nocem-directory -This is where Gnus will store its NoCeM cache files. The default is -@file{~/News/NoCeM/}. - -@item gnus-nocem-expiry-wait -@vindex gnus-nocem-expiry-wait -The number of days before removing old NoCeM entries from the cache. -The default is 15. If you make it shorter Gnus will be faster, but you -might then see old spam. - -@end table - -Using NoCeM could potentially be a memory hog. If you have many living -(i. e., subscribed or unsubscribed groups), your Emacs process will grow -big. If this is a problem, you should kill off all (or most) of your -unsubscribed groups (@pxref{Subscription Commands}). - - -@node Undo -@section Undo -@cindex undo - -It is very useful to be able to undo actions one has done. In normal -Emacs buffers, it's easy enough---you just push the @code{undo} button. -In Gnus buffers, however, it isn't that simple. - -The things Gnus displays in its buffer is of no value whatsoever to -Gnus---it's all just data designed to look nice to the user. -Killing a group in the group buffer with @kbd{C-k} makes the line -disappear, but that's just a side-effect of the real action---the -removal of the group in question from the internal Gnus structures. -Undoing something like that can't be done by the normal Emacs -@code{undo} function. - -Gnus tries to remedy this somewhat by keeping track of what the user -does and coming up with actions that would reverse the actions the user -takes. When the user then presses the @code{undo} key, Gnus will run -the code to reverse the previous action, or the previous actions. -However, not all actions are easily reversible, so Gnus currently offers -a few key functions to be undoable. These include killing groups, -yanking groups, and changing the list of read articles of groups. -That's it, really. More functions may be added in the future, but each -added function means an increase in data to be stored, so Gnus will -never be totally undoable. - -@findex gnus-undo-mode -@vindex gnus-use-undo -@findex gnus-undo -The undoability is provided by the @code{gnus-undo-mode} minor mode. It -is used if @code{gnus-use-undo} is non-@code{nil}, which is the -default. The @kbd{M-C-_} key performs the @code{gnus-undo} command -command, which should feel kinda like the normal Emacs @code{undo} -command. - - -@node Moderation -@section Moderation -@cindex moderation - -If you are a moderator, you can use the @file{gnus-mdrtn.el} package. -It is not included in the standard Gnus package. Write a mail to -@samp{larsi@@gnus.org} and state what group you moderate, and you'll -get a copy. - -The moderation package is implemented as a minor mode for summary -buffers. Put - -@lisp -(add-hook 'gnus-summary-mode-hook 'gnus-moderate) -@end lisp - -in your @file{.gnus.el} file. - -If you are the moderator of @samp{rec.zoofle}, this is how it's -supposed to work: - -@enumerate -@item -You split your incoming mail by matching on -@samp{Newsgroups:.*rec.zoofle}, which will put all the to-be-posted -articles in some mail group---for instance, @samp{nnml:rec.zoofle}. - -@item -You enter that group once in a while and post articles using the @kbd{e} -(edit-and-post) or @kbd{s} (just send unedited) commands. - -@item -If, while reading the @samp{rec.zoofle} newsgroup, you happen upon some -articles that weren't approved by you, you can cancel them with the -@kbd{c} command. -@end enumerate - -To use moderation mode in these two groups, say: - -@lisp -(setq gnus-moderated-list - "^nnml:rec.zoofle$\\|^rec.zoofle$") -@end lisp - - -@node XEmacs Enhancements -@section XEmacs Enhancements -@cindex XEmacs - -XEmacs is able to display pictures and stuff, so Gnus has taken -advantage of that. - -@menu -* Picons:: How to display pictures of what your reading. -* Smileys:: Show all those happy faces the way they were meant to be shown. -* Toolbar:: Click'n'drool. -* XVarious:: Other XEmacsy Gnusey variables. -@end menu - - -@node Picons -@subsection Picons - -@iftex -@iflatex -\include{picons} -@end iflatex -@end iftex - -So... You want to slow down your news reader even more! This is a -good way to do so. Its also a great way to impress people staring -over your shoulder as you read news. - -@menu -* Picon Basics:: What are picons and How do I get them. -* Picon Requirements:: Don't go further if you aren't using XEmacs. -* Easy Picons:: Displaying Picons---the easy way. -* Hard Picons:: The way you should do it. You'll learn something. -* Picon Useless Configuration:: Other variables you can trash/tweak/munge/play with. -@end menu - - -@node Picon Basics -@subsubsection Picon Basics - -What are Picons? To quote directly from the Picons Web site: - -@iftex -@iflatex -\margindex{} -@end iflatex -@end iftex - -@quotation -@dfn{Picons} is short for ``personal icons''. They're small, -constrained images used to represent users and domains on the net, -organized into databases so that the appropriate image for a given -e-mail address can be found. Besides users and domains, there are picon -databases for Usenet newsgroups and weather forecasts. The picons are -in either monochrome @code{XBM} format or color @code{XPM} and -@code{GIF} formats. -@end quotation - -@vindex gnus-picons-piconsearch-url -If you have a permanent connection to the Internet you can use Steve -Kinzler's Picons Search engine by setting -@code{gnus-picons-piconsearch-url} to the string @* -@file{http://www.cs.indiana.edu/picons/search.html}. - -@vindex gnus-picons-database -Otherwise you need a local copy of his database. For instructions on -obtaining and installing the picons databases, point your Web browser at @* -@file{http://www.cs.indiana.edu/picons/ftp/index.html}. Gnus expects -picons to be installed into a location pointed to by -@code{gnus-picons-database}. - - -@node Picon Requirements -@subsubsection Picon Requirements - -To have Gnus display Picons for you, you must be running XEmacs -19.13 or greater since all other versions of Emacs aren't yet able to -display images. - -Additionally, you must have @code{x} support compiled into XEmacs. To -display color picons which are much nicer than the black & white one, -you also need one of @code{xpm} or @code{gif} compiled into XEmacs. - -@vindex gnus-picons-convert-x-face -If you want to display faces from @code{X-Face} headers, you should have -the @code{xface} support compiled into XEmacs. Otherwise you must have -the @code{netpbm} utilities installed, or munge the -@code{gnus-picons-convert-x-face} variable to use something else. - - -@node Easy Picons -@subsubsection Easy Picons - -To enable displaying picons, simply put the following line in your -@file{~/.gnus} file and start Gnus. - -@lisp -(setq gnus-use-picons t) -(add-hook 'gnus-article-display-hook - 'gnus-article-display-picons t) -(add-hook 'gnus-article-display-hook - 'gnus-picons-article-display-x-face) -@end lisp - -and make sure @code{gnus-picons-database} points to the directory -containing the Picons databases. - -Alternatively if you want to use the web piconsearch engine add this: - -@lisp -(setq gnus-picons-piconsearch-url - "http://www.cs.indiana.edu:800/piconsearch") -@end lisp - - -@node Hard Picons -@subsubsection Hard Picons - -@iftex -@iflatex -\margindex{} -@end iflatex -@end iftex - -Gnus can display picons for you as you enter and leave groups and -articles. It knows how to interact with three sections of the picons -database. Namely, it can display the picons newsgroup pictures, -author's face picture(s), and the authors domain. To enable this -feature, you need to select where to get the picons from, and where to -display them. - -@table @code - -@item gnus-picons-database -@vindex gnus-picons-database -The location of the picons database. Should point to a directory -containing the @file{news}, @file{domains}, @file{users} (and so on) -subdirectories. This is only useful if -@code{gnus-picons-piconsearch-url} is @code{nil}. Defaults to -@file{/usr/local/faces/}. - -@item gnus-picons-piconsearch-url -@vindex gnus-picons-piconsearch-url -The URL for the web picons search engine. The only currently known -engine is @file{http://www.cs.indiana.edu:800/piconsearch}. To -workaround network delays, icons will be fetched in the background. If -this is @code{nil} 'the default), then picons are fetched from local -database indicated by @code{gnus-picons-database}. - -@item gnus-picons-display-where -@vindex gnus-picons-display-where -Where the picon images should be displayed. It is @code{picons} by -default (which by default maps to the buffer @samp{*Picons*}). Other -valid places could be @code{article}, @code{summary}, or -@samp{*scratch*} for all I care. Just make sure that you've made the -buffer visible using the standard Gnus window configuration -routines---@pxref{Windows Configuration}. - -@item gnus-picons-group-excluded-groups -@vindex gnus-picons-group-excluded-groups -Groups that are matched by this regexp won't have their group icons -displayed. - -@end table - -Note: If you set @code{gnus-use-picons} to @code{t}, it will set up your -window configuration for you to include the @code{picons} buffer. - -Now that you've made those decision, you need to add the following -functions to the appropriate hooks so these pictures will get displayed -at the right time. - -@vindex gnus-article-display-hook -@vindex gnus-picons-display-where -@table @code -@item gnus-article-display-picons -@findex gnus-article-display-picons -Looks up and displays the picons for the author and the author's domain -in the @code{gnus-picons-display-where} buffer. Should be added to the -@code{gnus-article-display-hook}. - -@item gnus-picons-article-display-x-face -@findex gnus-article-display-picons -Decodes and displays the X-Face header if present. This function -should be added to @code{gnus-article-display-hook}. - -@end table - -Note: You must append them to the hook, so make sure to specify 't' -for the append flag of @code{add-hook}: - -@lisp -(add-hook 'gnus-article-display-hook 'gnus-article-display-picons t) -@end lisp - - -@node Picon Useless Configuration -@subsubsection Picon Useless Configuration - -@iftex -@iflatex -\margindex{} -@end iflatex -@end iftex - -The following variables offer further control over how things are -done, where things are located, and other useless stuff you really -don't need to worry about. - -@table @code - -@item gnus-picons-news-directories -@vindex gnus-picons-news-directories -List of subdirectories to search in @code{gnus-picons-database} for -newsgroups faces. @code{("news")} is the default. - -@item gnus-picons-user-directories -@vindex gnus-picons-user-directories -List of subdirectories to search in @code{gnus-picons-database} for user -faces. @code{("local" "users" "usenix" "misc")} is the default. - -@item gnus-picons-domain-directories -@vindex gnus-picons-domain-directories -List of subdirectories to search in @code{gnus-picons-database} for -domain name faces. Defaults to @code{("domains")}. Some people may -want to add @samp{"unknown"} to this list. - -@item gnus-picons-convert-x-face -@vindex gnus-picons-convert-x-face -If you don't have @code{xface} support builtin XEmacs, this is the -command to use to convert the @code{X-Face} header to an X bitmap -(@code{xbm}). Defaults to @code{(format "@{ echo '/* Width=48, -Height=48 */'; uncompface; @} | icontopbm | pbmtoxbm > %s" -gnus-picons-x-face-file-name)} - -@item gnus-picons-x-face-file-name -@vindex gnus-picons-x-face-file-name -Names a temporary file to store the @code{X-Face} bitmap in. Defaults -to @code{(format "/tmp/picon-xface.%s.xbm" (user-login-name))}. - -@item gnus-picons-has-modeline-p -@vindex gnus-picons-has-modeline-p -If you have set @code{gnus-picons-display-where} to @code{picons}, your -XEmacs frame will become really cluttered. To alleviate this a bit you -can set @code{gnus-picons-has-modeline-p} to @code{nil}; this will -remove the mode line from the Picons buffer. This is only useful if -@code{gnus-picons-display-where} is @code{picons}. - -@item gnus-picons-refresh-before-display -@vindex gnus-picons-refresh-before-display -If non-nil, display the article buffer before computing the picons. -Defaults to @code{nil}. - -@item gnus-picons-display-as-address -@vindex gnus-picons-display-as-address -If @code{t} display textual email addresses along with pictures. -Defaults to @code{t}. - -@item gnus-picons-file-suffixes -@vindex gnus-picons-file-suffixes -Ordered list of suffixes on picon file names to try. Defaults to -@code{("xpm" "gif" "xbm")} minus those not builtin your XEmacs. - -@item gnus-picons-display-article-move-p -@vindex gnus-picons-display-article-move-p -Whether to move point to first empty line when displaying picons. This -has only an effect if `gnus-picons-display-where' has value `article'. - -@item gnus-picons-clear-cache-on-shutdown -@vindex gnus-picons-clear-cache-on-shutdown -Whether to clear the picons cache when exiting gnus. Gnus caches every -picons it finds while it is running. This saves some time in the search -process but eats some memory. If this variable is set to @code{nil}, -Gnus will never clear the cache itself; you will have to manually call -@code{gnus-picons-clear-cache} to clear it. Otherwise the cache will be -cleared every time you exit Gnus. Defaults to @code{t}. - -@iftex -@iflatex -\margindex{} -@end iflatex -@end iftex - -@end table - -@node Smileys -@subsection Smileys -@cindex smileys - -@iftex -@iflatex -\gnusfig{-3cm}{0.5cm}{\epsfig{figure=tmp/BigFace.ps,height=20cm}} -\input{smiley} -@end iflatex -@end iftex - -@dfn{Smiley} is a package separate from Gnus, but since Gnus is -currently the only package that uses Smiley, it is documented here. - -In short---to use Smiley in Gnus, put the following in your -@file{.gnus.el} file: - -@lisp -(add-hook 'gnus-article-display-hook 'gnus-smiley-display t) -@end lisp - -Smiley maps text smiley faces---@samp{:-)}, @samp{:-=}, @samp{:-(} and -the like---to pictures and displays those instead of the text smiley -faces. The conversion is controlled by a list of regexps that matches -text and maps that to file names. - -@vindex smiley-nosey-regexp-alist -@vindex smiley-deformed-regexp-alist -Smiley supplies two example conversion alists by default: -@code{smiley-deformed-regexp-alist} (which matches @samp{:)}, @samp{:(} -and so on), and @code{smiley-nosey-regexp-alist} (which matches -@samp{:-)}, @samp{:-(} and so on). - -The alist used is specified by the @code{smiley-regexp-alist} variable, -which defaults to the value of @code{smiley-deformed-regexp-alist}. - -The first item in each element is the regexp to be matched; the second -element is the regexp match group that is to be replaced by the picture; -and the third element is the name of the file to be displayed. - -The following variables customize where Smiley will look for these -files, as well as the color to be used and stuff: - -@table @code - -@item smiley-data-directory -@vindex smiley-data-directory -Where Smiley will look for smiley faces files. - -@item smiley-flesh-color -@vindex smiley-flesh-color -Skin color. The default is @samp{yellow}, which is really racist. - -@item smiley-features-color -@vindex smiley-features-color -Color of the features of the face. The default is @samp{black}. - -@item smiley-tongue-color -@vindex smiley-tongue-color -Color of the tongue. The default is @samp{red}. - -@item smiley-circle-color -@vindex smiley-circle-color -Color of the circle around the face. The default is @samp{black}. - -@item smiley-mouse-face -@vindex smiley-mouse-face -Face used for mouse highlighting over the smiley face. - -@end table - - -@node Toolbar -@subsection Toolbar - -@table @code - -@iftex -@iflatex -\margindex{} -@end iflatex -@end iftex - -@item gnus-use-toolbar -@vindex gnus-use-toolbar -If @code{nil}, don't display toolbars. If non-@code{nil}, it should be -one of @code{default-toolbar}, @code{top-toolbar}, @code{bottom-toolbar}, -@code{right-toolbar}, or @code{left-toolbar}. - -@item gnus-group-toolbar -@vindex gnus-group-toolbar -The toolbar in the group buffer. - -@item gnus-summary-toolbar -@vindex gnus-summary-toolbar -The toolbar in the summary buffer. - -@item gnus-summary-mail-toolbar -@vindex gnus-summary-mail-toolbar -The toolbar in the summary buffer of mail groups. - -@end table - - -@node XVarious -@subsection Various XEmacs Variables - -@table @code -@item gnus-xmas-glyph-directory -@vindex gnus-xmas-glyph-directory -This is where Gnus will look for pictures. Gnus will normally -auto-detect this directory, but you may set it manually if you have an -unusual directory structure. - -@item gnus-xmas-logo-color-alist -@vindex gnus-xmas-logo-color-alist -This is an alist where the key is a type symbol and the values are the -foreground and background color of the splash page glyph. - -@item gnus-xmas-logo-color-style -@vindex gnus-xmas-logo-color-style -This is the key used to look up the color in the alist described above. -Valid values include @code{flame}, @code{pine}, @code{moss}, -@code{irish}, @code{sky}, @code{tin}, @code{velvet}, @code{grape}, -@code{labia}, @code{berry}, @code{neutral}, and @code{september}. - -@item gnus-xmas-modeline-glyph -@vindex gnus-xmas-modeline-glyph -A glyph displayed in all Gnus mode lines. It is a tiny gnu head by -default. - -@iftex -@iflatex -\margindex{} -@end iflatex -@end iftex - -@end table - - - - -@node Fuzzy Matching -@section Fuzzy Matching -@cindex fuzzy matching - -Gnus provides @dfn{fuzzy matching} of @code{Subject} lines when doing -things like scoring, thread gathering and thread comparison. - -As opposed to regular expression matching, fuzzy matching is very fuzzy. -It's so fuzzy that there's not even a definition of what @dfn{fuzziness} -means, and the implementation has changed over time. - -Basically, it tries to remove all noise from lines before comparing. -@samp{Re: }, parenthetical remarks, white space, and so on, are filtered -out of the strings before comparing the results. This often leads to -adequate results---even when faced with strings generated by text -manglers masquerading as newsreaders. - - -@node Thwarting Email Spam -@section Thwarting Email Spam -@cindex email spam -@cindex spam -@cindex UCE -@cindex unsolicited commercial email - -In these last days of the Usenet, commercial vultures are hanging about -and grepping through news like crazy to find email addresses they can -foist off their scams and products to. As a reaction to this, many -people have started putting nonsense addresses into their @code{From} -lines. I think this is counterproductive---it makes it difficult for -people to send you legitimate mail in response to things you write, as -well as making it difficult to see who wrote what. This rewriting may -perhaps be a bigger menace than the unsolicited commercial email itself -in the end. - -The biggest problem I have with email spam is that it comes in under -false pretenses. I press @kbd{g} and Gnus merrily informs me that I -have 10 new emails. I say ``Golly gee! Happy is me!'' and select the -mail group, only to find two pyramid schemes, seven advertisements -(``New! Miracle tonic for growing full, lustrous hair on your toes!'') -and one mail asking me to repent and find some god. - -This is annoying. - -The way to deal with this is having Gnus split out all spam into a -@samp{spam} mail group (@pxref{Splitting Mail}). - -First, pick one (1) valid mail address that you can be reached at, and -put it in your @code{From} header of all your news articles. (I've -chosen @samp{larsi@@trym.ifi.uio.no}, but for many addresses on the form -@samp{larsi+usenet@@ifi.uio.no} will be a better choice. Ask your -sysadm whether your sendmail installation accepts keywords in the local -part of the mail address.) - -@lisp -(setq message-default-news-headers - "From: Lars Magne Ingebrigtsen \n") -@end lisp - -Then put the following split rule in @code{nnmail-split-fancy} -(@pxref{Fancy Mail Splitting}): - -@lisp -( - ... - (to "larsi@@trym.ifi.uio.no" - (| ("subject" "re:.*" "misc") - ("references" ".*@@.*" "misc") - "spam")) - ... -) -@end lisp - -This says that all mail to this address is suspect, but if it has a -@code{Subject} that starts with a @samp{Re:} or has a @code{References} -header, it's probably ok. All the rest goes to the @samp{spam} group. -(This idea probably comes from Tim Pierce.) - -In addition, many mail spammers talk directly to your @code{smtp} server -and do not include your email address explicitly in the @code{To} -header. Why they do this is unknown---perhaps it's to thwart this -thwarting scheme? In any case, this is trivial to deal with---you just -put anything not addressed to you in the @samp{spam} group by ending -your fancy split rule in this way: - -@lisp -( - ... - (to "larsi" "misc") - "spam") -@end lisp - -In my experience, this will sort virtually everything into the right -group. You still have to check the @samp{spam} group from time to time to -check for legitimate mail, though. If you feel like being a good net -citizen, you can even send off complaints to the proper authorities on -each unsolicited commercial email---at your leisure. - -If you are also a lazy net citizen, you will probably prefer complaining -automatically with the @file{gnus-junk.el} package, available FOR FREE -at @* @file{}. -Since most e-mail spam is sent automatically, this may reconcile the -cosmic balance somewhat. - -This works for me. It allows people an easy way to contact me (they can -just press @kbd{r} in the usual way), and I'm not bothered at all with -spam. It's a win-win situation. Forging @code{From} headers to point -to non-existent domains is yucky, in my opinion. - - -@node Various Various -@section Various Various -@cindex mode lines -@cindex highlights - -@table @code - -@item gnus-home-directory -All Gnus path variables will be initialized from this variable, which -defaults to @file{~/}. - -@item gnus-directory -@vindex gnus-directory -Most Gnus storage path variables will be initialized from this variable, -which defaults to the @samp{SAVEDIR} environment variable, or -@file{~/News/} if that variable isn't set. - -Note that gnus is mostly loaded when the @file{.gnus.el} file is read. -This means that other directory variables that are initialized from this -variable won't be set properly if you set this variable in -@file{.gnus.el}. Set this variable in @file{.emacs} instead. - -@item gnus-default-directory -@vindex gnus-default-directory -Not related to the above variable at all---this variable says what the -default directory of all Gnus buffers should be. If you issue commands -like @kbd{C-x C-f}, the prompt you'll get starts in the current buffer's -default directory. If this variable is @code{nil} (which is the -default), the default directory will be the default directory of the -buffer you were in when you started Gnus. - -@item gnus-verbose -@vindex gnus-verbose -This variable is an integer between zero and ten. The higher the value, -the more messages will be displayed. If this variable is zero, Gnus -will never flash any messages, if it is seven (which is the default), -most important messages will be shown, and if it is ten, Gnus won't ever -shut up, but will flash so many messages it will make your head swim. - -@item gnus-verbose-backends -@vindex gnus-verbose-backends -This variable works the same way as @code{gnus-verbose}, but it applies -to the Gnus backends instead of Gnus proper. - -@item nnheader-max-head-length -@vindex nnheader-max-head-length -When the backends read straight heads of articles, they all try to read -as little as possible. This variable (default 4096) specifies -the absolute max length the backends will try to read before giving up -on finding a separator line between the head and the body. If this -variable is @code{nil}, there is no upper read bound. If it is -@code{t}, the backends won't try to read the articles piece by piece, -but read the entire articles. This makes sense with some versions of -@code{ange-ftp} or @code{efs}. - -@item nnheader-head-chop-length -@vindex nnheader-head-chop-length -This variable (default 2048) says how big a piece of each article to -read when doing the operation described above. - -@item nnheader-file-name-translation-alist -@vindex nnheader-file-name-translation-alist -@cindex file names -@cindex invalid characters in file names -@cindex characters in file names -This is an alist that says how to translate characters in file names. -For instance, if @samp{:} is invalid as a file character in file names -on your system (you OS/2 user you), you could say something like: - -@lisp -(setq nnheader-file-name-translation-alist - '((?: . ?_))) -@end lisp - -In fact, this is the default value for this variable on OS/2 and MS -Windows (phooey) systems. - -@item gnus-hidden-properties -@vindex gnus-hidden-properties -This is a list of properties to use to hide ``invisible'' text. It is -@code{(invisible t intangible t)} by default on most systems, which -makes invisible text invisible and intangible. - -@item gnus-parse-headers-hook -@vindex gnus-parse-headers-hook -A hook called before parsing headers. It can be used, for instance, to -gather statistics on the headers fetched, or perhaps you'd like to prune -some headers. I don't see why you'd want that, though. - -@item gnus-shell-command-separator -@vindex gnus-shell-command-separator -String used to separate two shell commands. The default is @samp{;}. - - -@end table - - -@node The End -@chapter The End - -Well, that's the manual---you can get on with your life now. Keep in -touch. Say hello to your cats from me. - -My @strong{ghod}---I just can't stand goodbyes. Sniffle. - -Ol' Charles Reznikoff said it pretty well, so I leave the floor to him: - -@quotation -@strong{Te Deum} - -@sp 1 -Not because of victories @* -I sing,@* -having none,@* -but for the common sunshine,@* -the breeze,@* -the largess of the spring. - -@sp 1 -Not for victory@* -but for the day's work done@* -as well as I was able;@* -not for a seat upon the dais@* -but at the common table.@* -@end quotation - - -@node Appendices -@chapter Appendices - -@menu -* History:: How Gnus got where it is today. -* Terminology:: We use really difficult, like, words here. -* Customization:: Tailoring Gnus to your needs. -* Troubleshooting:: What you might try if things do not work. -* A Programmers Guide to Gnus:: Rilly, rilly technical stuff. -* Emacs for Heathens:: A short introduction to Emacsian terms. -* Frequently Asked Questions:: A question-and-answer session. -@end menu - - -@node History -@section History - -@cindex history -@sc{gnus} was written by Masanobu @sc{Umeda}. When autumn crept up in -'94, Lars Magne Ingebrigtsen grew bored and decided to rewrite Gnus. - -If you want to investigate the person responsible for this outrage, you -can point your (feh!) web browser to -@file{http://www.stud.ifi.uio.no/~larsi/}. This is also the primary -distribution point for the new and spiffy versions of Gnus, and is known -as The Site That Destroys Newsrcs And Drives People Mad. - -During the first extended alpha period of development, the new Gnus was -called ``(ding) Gnus''. @dfn{(ding)} is, of course, short for -@dfn{ding is not Gnus}, which is a total and utter lie, but who cares? -(Besides, the ``Gnus'' in this abbreviation should probably be -pronounced ``news'' as @sc{Umeda} intended, which makes it a more -appropriate name, don't you think?) - -In any case, after spending all that energy on coming up with a new and -spunky name, we decided that the name was @emph{too} spunky, so we -renamed it back again to ``Gnus''. But in mixed case. ``Gnus'' vs. -``@sc{gnus}''. New vs. old. - -The first ``proper'' release of Gnus 5 was done in November 1995 when it -was included in the Emacs 19.30 distribution (132 (ding) Gnus releases -plus 15 Gnus 5.0 releases). - -In May 1996 the next Gnus generation (aka. ``September Gnus'' (after 99 -releases)) was released under the name ``Gnus 5.2'' (40 releases). - -On July 28th 1996 work on Red Gnus was begun, and it was released on -January 25th 1997 (after 84 releases) as ``Gnus 5.4'' (67 releases). - -On September 13th 1997, Quassia Gnus was started and lasted 37 -releases. If was released as ``Gnus 5.6 on March 8th 1998. - -If you happen upon a version of Gnus that has a prefixed name -- -``(ding) Gnus'', ``September Gnus'', ``Red Gnus'', ``Quassia Gnus'' -- -don't panic. Don't let it know that you're frightened. Back away. -Slowly. Whatever you do, don't run. Walk away, calmly, until you're -out of its reach. Find a proper released version of Gnus and snuggle up -to that instead. - -@menu -* Why?:: What's the point of Gnus? -* Compatibility:: Just how compatible is Gnus with @sc{gnus}? -* Conformity:: Gnus tries to conform to all standards. -* Emacsen:: Gnus can be run on a few modern Emacsen. -* Contributors:: Oodles of people. -* New Features:: Pointers to some of the new stuff in Gnus. -* Newest Features:: Features so new that they haven't been written yet. -@end menu - - -@node Why? -@subsection Why? - -What's the point of Gnus? - -I want to provide a ``rad'', ``happening'', ``way cool'' and ``hep'' -newsreader, that lets you do anything you can think of. That was my -original motivation, but while working on Gnus, it has become clear to -me that this generation of newsreaders really belong in the stone age. -Newsreaders haven't developed much since the infancy of the net. If the -volume continues to rise with the current rate of increase, all current -newsreaders will be pretty much useless. How do you deal with -newsgroups that have thousands of new articles each day? How do you -keep track of millions of people who post? - -Gnus offers no real solutions to these questions, but I would very much -like to see Gnus being used as a testing ground for new methods of -reading and fetching news. Expanding on @sc{Umeda}-san's wise decision -to separate the newsreader from the backends, Gnus now offers a simple -interface for anybody who wants to write new backends for fetching mail -and news from different sources. I have added hooks for customizations -everywhere I could imagine it being useful. By doing so, I'm inviting -every one of you to explore and invent. - -May Gnus never be complete. @kbd{C-u 100 M-x all-hail-emacs} and -@kbd{C-u 100 M-x all-hail-xemacs}. - - -@node Compatibility -@subsection Compatibility - -@cindex compatibility -Gnus was designed to be fully compatible with @sc{gnus}. Almost all key -bindings have been kept. More key bindings have been added, of course, -but only in one or two obscure cases have old bindings been changed. - -Our motto is: -@quotation -@cartouche -@center In a cloud bones of steel. -@end cartouche -@end quotation - -All commands have kept their names. Some internal functions have changed -their names. - -The @code{gnus-uu} package has changed drastically. @xref{Decoding -Articles}. - -One major compatibility question is the presence of several summary -buffers. All variables relevant while reading a group are -buffer-local to the summary buffer they belong in. Although many -important variables have their values copied into their global -counterparts whenever a command is executed in the summary buffer, this -change might lead to incorrect values being used unless you are careful. - -All code that relies on knowledge of @sc{gnus} internals will probably -fail. To take two examples: Sorting @code{gnus-newsrc-alist} (or -changing it in any way, as a matter of fact) is strictly verboten. Gnus -maintains a hash table that points to the entries in this alist (which -speeds up many functions), and changing the alist directly will lead to -peculiar results. - -@cindex hilit19 -@cindex highlighting -Old hilit19 code does not work at all. In fact, you should probably -remove all hilit code from all Gnus hooks -(@code{gnus-group-prepare-hook} and @code{gnus-summary-prepare-hook}). -Gnus provides various integrated functions for highlighting. These are -faster and more accurate. To make life easier for everybody, Gnus will -by default remove all hilit calls from all hilit hooks. Uncleanliness! -Away! - -Packages like @code{expire-kill} will no longer work. As a matter of -fact, you should probably remove all old @sc{gnus} packages (and other -code) when you start using Gnus. More likely than not, Gnus already -does what you have written code to make @sc{gnus} do. (Snicker.) - -Even though old methods of doing things are still supported, only the -new methods are documented in this manual. If you detect a new method of -doing something while reading this manual, that does not mean you have -to stop doing it the old way. - -Gnus understands all @sc{gnus} startup files. - -@kindex M-x gnus-bug -@findex gnus-bug -@cindex reporting bugs -@cindex bugs -Overall, a casual user who hasn't written much code that depends on -@sc{gnus} internals should suffer no problems. If problems occur, -please let me know by issuing that magic command @kbd{M-x gnus-bug}. - -@vindex gnus-bug-create-help-buffer -If you are in the habit of sending bug reports @emph{very} often, you -may find the helpful help buffer annoying after a while. If so, set -@code{gnus-bug-create-help-buffer} to @code{nil} to avoid having it pop -up at you. - - -@node Conformity -@subsection Conformity - -No rebels without a clue here, ma'am. We conform to all standards known -to (wo)man. Except for those standards and/or conventions we disagree -with, of course. - -@table @strong - -@item RFC 822 -@cindex RFC 822 -There are no known breaches of this standard. - -@item RFC 1036 -@cindex RFC 1036 -There are no known breaches of this standard, either. - -@item Son-of-RFC 1036 -@cindex Son-of-RFC 1036 -We do have some breaches to this one. - -@table @emph - -@item MIME -Gnus does no MIME handling, and this standard-to-be seems to think that -MIME is the bees' knees, so we have major breakage here. - -@item X-Newsreader -This is considered to be a ``vanity header'', while I consider it to be -consumer information. After seeing so many badly formatted articles -coming from @code{tin} and @code{Netscape} I know not to use either of -those for posting articles. I would not have known that if it wasn't -for the @code{X-Newsreader} header. -@end table - -@end table - -If you ever notice Gnus acting non-compliant with regards to the texts -mentioned above, don't hesitate to drop a note to Gnus Towers and let us -know. - - -@node Emacsen -@subsection Emacsen -@cindex Emacsen -@cindex XEmacs -@cindex Mule -@cindex Emacs - -Gnus should work on : - -@itemize @bullet - -@item -Emacs 19.32 and up. - -@item -XEmacs 19.14 and up. - -@item -Mule versions based on Emacs 19.32 and up. - -@end itemize - -Gnus will absolutely not work on any Emacsen older than that. Not -reliably, at least. - -There are some vague differences between Gnus on the various -platforms---XEmacs features more graphics (a logo and a toolbar)---but -other than that, things should look pretty much the same under all -Emacsen. - - -@node Contributors -@subsection Contributors -@cindex contributors - -The new Gnus version couldn't have been done without the help of all the -people on the (ding) mailing list. Every day for over a year I have -gotten billions of nice bug reports from them, filling me with joy, -every single one of them. Smooches. The people on the list have been -tried beyond endurance, what with my ``oh, that's a neat idea , yup, I'll release it right away no wait, that doesn't -work at all , yup, I'll ship that one off right away no, wait, that absolutely does not work'' policy for releases. -Micro$oft---bah. Amateurs. I'm @emph{much} worse. (Or is that -``worser''? ``much worser''? ``worsest''?) - -I would like to take this opportunity to thank the Academy for... oops, -wrong show. - -@itemize @bullet - -@item -Masanobu @sc{Umeda}---the writer of the original @sc{gnus}. - -@item -Per Abrahamsen---custom, scoring, highlighting and @sc{soup} code (as -well as numerous other things). - -@item -Luis Fernandes---design and graphics. - -@item -Erik Naggum---help, ideas, support, code and stuff. - -@item -Wes Hardaker---@file{gnus-picon.el} and the manual section on -@dfn{picons} (@pxref{Picons}). - -@item -Kim-Minh Kaplan---further work on the picon code. - -@item -Brad Miller---@file{gnus-gl.el} and the GroupLens manual section -(@pxref{GroupLens}). - -@item -Sudish Joseph---innumerable bug fixes. - -@item -Ilja Weis---@file{gnus-topic.el}. - -@item -Steven L. Baur---lots and lots and lots of bugs detections and fixes. - -@item -Vladimir Alexiev---the refcard and reference booklets. - -@item -Felix Lee & Jamie Zawinski---I stole some pieces from the XGnus -distribution by Felix Lee and JWZ. - -@item -Scott Byer---@file{nnfolder.el} enhancements & rewrite. - -@item -Peter Mutsaers---orphan article scoring code. - -@item -Ken Raeburn---POP mail support. - -@item -Hallvard B Furuseth---various bits and pieces, especially dealing with -.newsrc files. - -@item -Brian Edmonds---@file{gnus-bbdb.el}. - -@item -David Moore---rewrite of @file{nnvirtual.el} and many other things. - -@item -Kevin Davidson---came up with the name @dfn{ding}, so blame him. - -@item -Fran,Ag(Bois Pinard---many, many interesting and thorough bug reports, as -well as autoconf support. - -@end itemize - -This manual was proof-read by Adrian Aichner, with Ricardo Nassif, Mark -Borges, and Jost Krieger proof-reading parts of the manual. - -The following people have contributed many patches and suggestions: - -Christopher Davis, -Andrew Eskilsson, -Kai Grossjohann, -David K,Ae(Bgedal, -Richard Pieri, -Fabrice Popineau, -Daniel Quinlan, -Jason L. Tibbitts, III, -and -Jack Vinson. - -Also thanks to the following for patches and stuff: - -Jari Aalto, -Adrian Aichner, -Vladimir Alexiev, -Russ Allbery, -Peter Arius, -Matt Armstrong, -Marc Auslander, -Frank Bennett, -Robert Bihlmeyer, -Chris Bone, -Mark Borges, -Mark Boyns, -Lance A. Brown, -Kees de Bruin, -Martin Buchholz, -Joe Buehler, -Kevin Buhr, -Alastair Burt, -Joao Cachopo, -Zlatko Calusic, -Massimo Campostrini, -Castor, -David Charlap, -Dan Christensen, -Kevin Christian, -Michael R. Cook, -Glenn Coombs, -Frank D. Cringle, -Geoffrey T. Dairiki, -Andre Deparade, -Ulrik Dickow, -Dave Disser, -Rui-Tao Dong, @c ? -Joev Dubach, -Michael Welsh Duggan, -Dave Edmondson, -Paul Eggert, -Enami Tsugutomo, @c Enami -Michael Ernst, -Luc Van Eycken, -Sam Falkner, -Nelson Jose dos Santos Ferreira, -Sigbjorn Finne, -Decklin Foster, -Gary D. Foster, -Paul Franklin, -Guy Geens, -Arne Georg Gleditsch, -David S. Goldberg, -Michelangelo Grigni, -D. Hall, -Magnus Hammerin, -Kenichi Handa, @c Handa -Raja R. Harinath, -Yoshiki Hayashi, @c ? -P. E. Jareth Hein, -Hisashige Kenji, @c Hisashige -Marc Horowitz, -Gunnar Horrigmo, -Richard Hoskins, -Brad Howes, -Fran,Ag(Bois Felix Ingrand, -Ishikawa Ichiro, @c Ishikawa -Lee Iverson, -Iwamuro Motonori, @c Iwamuro -Rajappa Iyer, -Andreas Jaeger, -Randell Jesup, -Fred Johansen, -Gareth Jones, -Simon Josefsson, -Greg Klanderman, -Karl Kleinpaste, -Peter Skov Knudsen, -Shuhei Kobayashi, @c Kobayashi -Koseki Yoshinori, @c Koseki -Thor Kristoffersen, -Jens Lautenbacher, -Martin Larose, -Seokchan Lee, @c Lee -Carsten Leonhardt, -James LewisMoss, -Christian Limpach, -Markus Linnala, -Dave Love, -Mike McEwan, -Tonny Madsen, -Shlomo Mahlab, -Nat Makarevitch, -Istvan Marko, -David Martin, -Jason R. Mastaler, -Gordon Matzigkeit, -Timo Metzemakers, -Richard Mlynarik, -Lantz Moore, -Morioka Tomohiko, @c Morioka -Erik Toubro Nielsen, -Hrvoje Niksic, -Andy Norman, -Fred Oberhauser, -C. R. Oldham, -Alexandre Oliva, -Ken Olstad, -Masaharu Onishi, @c Onishi -Hideki Ono, @c Ono -William Perry, -Stephen Peters, -Jens-Ulrik Holger Petersen, -Ulrich Pfeifer, -Matt Pharr, -John McClary Prevost, -Bill Pringlemeir, -Mike Pullen, -Jim Radford, -Colin Rafferty, -Lasse Rasinen, -Lars Balker Rasmussen, -Joe Reiss, -Renaud Rioboo, -Roland B. Roberts, -Bart Robinson, -Christian von Roques, -Jason Rumney, -Wolfgang Rupprecht, -Jay Sachs, -Dewey M. Sasser, -Loren Schall, -Dan Schmidt, -Ralph Schleicher, -Philippe Schnoebelen, -Andreas Schwab, -Randal L. Schwartz, -Justin Sheehy, -Danny Siu, -Matt Simmons, -Paul D. Smith, -Jeff Sparkes, -Toby Speight, -Michael Sperber, -Darren Stalder, -Richard Stallman, -Greg Stark, -Sam Steingold, -Paul Stodghill, -Kurt Swanson, -Samuel Tardieu, -Teddy, -Chuck Thompson, -Philippe Troin, -James Troup, -Trung Tran-Duc, -Aaron M. Ucko, -Aki Vehtari, -Didier Verna, -Jan Vroonhof, -Stefan Waldherr, -Pete Ware, -Barry A. Warsaw, -Christoph Wedler, -Joe Wells, -Katsumi Yamaoka, @c Yamaoka -and -Shenghuo Zhu. @c Zhu - -For a full overview of what each person has done, the ChangeLogs -included in the Gnus alpha distributions should give ample reading -(550kB and counting). - -Apologies to everybody that I've forgotten, of which there are many, I'm -sure. - -Gee, that's quite a list of people. I guess that must mean that there -actually are people who are using Gnus. Who'd'a thunk it! - - -@node New Features -@subsection New Features -@cindex new features - -@menu -* ding Gnus:: New things in Gnus 5.0/5.1, the first new Gnus. -* September Gnus:: The Thing Formally Known As Gnus 5.3/5.3. -* Red Gnus:: Third time best---Gnus 5.4/5.5. -* Quassia Gnus:: Two times two is four, or Gnus 5.6/5.7. -@end menu - -These lists are, of course, just @emph{short} overviews of the -@emph{most} important new features. No, really. There are tons more. -Yes, we have feeping creaturism in full effect. - - -@node ding Gnus -@subsubsection (ding) Gnus - -New features in Gnus 5.0/5.1: - -@itemize @bullet - -@item -The look of all buffers can be changed by setting format-like variables -(@pxref{Group Buffer Format} and @pxref{Summary Buffer Format}). - -@item -Local spool and several @sc{nntp} servers can be used at once -(@pxref{Select Methods}). - -@item -You can combine groups into virtual groups (@pxref{Virtual Groups}). - -@item -You can read a number of different mail formats (@pxref{Getting Mail}). -All the mail backends implement a convenient mail expiry scheme -(@pxref{Expiring Mail}). - -@item -Gnus can use various strategies for gathering threads that have lost -their roots (thereby gathering loose sub-threads into one thread) or it -can go back and retrieve enough headers to build a complete thread -(@pxref{Customizing Threading}). - -@item -Killed groups can be displayed in the group buffer, and you can read -them as well (@pxref{Listing Groups}). - -@item -Gnus can do partial group updates---you do not have to retrieve the -entire active file just to check for new articles in a few groups -(@pxref{The Active File}). - -@item -Gnus implements a sliding scale of subscribedness to groups -(@pxref{Group Levels}). - -@item -You can score articles according to any number of criteria -(@pxref{Scoring}). You can even get Gnus to find out how to score -articles for you (@pxref{Adaptive Scoring}). - -@item -Gnus maintains a dribble buffer that is auto-saved the normal Emacs -manner, so it should be difficult to lose much data on what you have -read if your machine should go down (@pxref{Auto Save}). - -@item -Gnus now has its own startup file (@file{.gnus}) to avoid cluttering up -the @file{.emacs} file. - -@item -You can set the process mark on both groups and articles and perform -operations on all the marked items (@pxref{Process/Prefix}). - -@item -You can grep through a subset of groups and create a group from the -results (@pxref{Kibozed Groups}). - -@item -You can list subsets of groups according to, well, anything -(@pxref{Listing Groups}). - -@item -You can browse foreign servers and subscribe to groups from those -servers (@pxref{Browse Foreign Server}). - -@item -Gnus can fetch articles, asynchronously, on a second connection to the -server (@pxref{Asynchronous Fetching}). - -@item -You can cache articles locally (@pxref{Article Caching}). - -@item -The uudecode functions have been expanded and generalized -(@pxref{Decoding Articles}). - -@item -You can still post uuencoded articles, which was a little-known feature -of @sc{gnus}' past (@pxref{Uuencoding and Posting}). - -@item -Fetching parents (and other articles) now actually works without -glitches (@pxref{Finding the Parent}). - -@item -Gnus can fetch FAQs and group descriptions (@pxref{Group Information}). - -@item -Digests (and other files) can be used as the basis for groups -(@pxref{Document Groups}). - -@item -Articles can be highlighted and customized (@pxref{Customizing -Articles}). - -@item -URLs and other external references can be buttonized (@pxref{Article -Buttons}). - -@item -You can do lots of strange stuff with the Gnus window & frame -configuration (@pxref{Windows Configuration}). - -@item -You can click on buttons instead of using the keyboard -(@pxref{Buttons}). - -@end itemize - - -@node September Gnus -@subsubsection September Gnus - -@iftex -@iflatex -\gnusfig{-28cm}{0cm}{\epsfig{figure=tmp/september.ps,height=20cm}} -@end iflatex -@end iftex - -New features in Gnus 5.2/5.3: - -@itemize @bullet - -@item -A new message composition mode is used. All old customization variables -for @code{mail-mode}, @code{rnews-reply-mode} and @code{gnus-msg} are -now obsolete. - -@item -Gnus is now able to generate @dfn{sparse} threads---threads where -missing articles are represented by empty nodes (@pxref{Customizing -Threading}). - -@lisp -(setq gnus-build-sparse-threads 'some) -@end lisp - -@item -Outgoing articles are stored on a special archive server -(@pxref{Archived Messages}). - -@item -Partial thread regeneration now happens when articles are -referred. - -@item -Gnus can make use of GroupLens predictions (@pxref{GroupLens}). - -@item -Picons (personal icons) can be displayed under XEmacs (@pxref{Picons}). - -@item -A @code{trn}-like tree buffer can be displayed (@pxref{Tree Display}). - -@lisp -(setq gnus-use-trees t) -@end lisp - -@item -An @code{nn}-like pick-and-read minor mode is available for the summary -buffers (@pxref{Pick and Read}). - -@lisp -(add-hook 'gnus-summary-mode-hook 'gnus-pick-mode) -@end lisp - -@item -In binary groups you can use a special binary minor mode (@pxref{Binary -Groups}). - -@item -Groups can be grouped in a folding topic hierarchy (@pxref{Group -Topics}). - -@lisp -(add-hook 'gnus-group-mode-hook 'gnus-topic-mode) -@end lisp - -@item -Gnus can re-send and bounce mail (@pxref{Summary Mail Commands}). - -@item -Groups can now have a score, and bubbling based on entry frequency -is possible (@pxref{Group Score}). - -@lisp -(add-hook 'gnus-summary-exit-hook 'gnus-summary-bubble-group) -@end lisp - -@item -Groups can be process-marked, and commands can be performed on -groups of groups (@pxref{Marking Groups}). - -@item -Caching is possible in virtual groups. - -@item -@code{nndoc} now understands all kinds of digests, mail boxes, rnews -news batches, ClariNet briefs collections, and just about everything -else (@pxref{Document Groups}). - -@item -Gnus has a new backend (@code{nnsoup}) to create/read SOUP packets -(@pxref{SOUP}). - -@item -The Gnus cache is much faster. - -@item -Groups can be sorted according to many criteria (@pxref{Sorting -Groups}). - -@item -New group parameters have been introduced to set list-addresses and -expiry times (@pxref{Group Parameters}). - -@item -All formatting specs allow specifying faces to be used -(@pxref{Formatting Fonts}). - -@item -There are several more commands for setting/removing/acting on process -marked articles on the @kbd{M P} submap (@pxref{Setting Process Marks}). - -@item -The summary buffer can be limited to show parts of the available -articles based on a wide range of criteria. These commands have been -bound to keys on the @kbd{/} submap (@pxref{Limiting}). - -@item -Articles can be made persistent with the @kbd{*} command -(@pxref{Persistent Articles}). - -@item -All functions for hiding article elements are now toggles. - -@item -Article headers can be buttonized (@pxref{Article Washing}). - -@lisp -(add-hook 'gnus-article-display-hook - 'gnus-article-add-buttons-to-head) -@end lisp - -@item -All mail backends support fetching articles by @code{Message-ID}. - -@item -Duplicate mail can now be treated properly (@pxref{Duplicates}). - -@item -All summary mode commands are available directly from the article -buffer (@pxref{Article Keymap}). - -@item -Frames can be part of @code{gnus-buffer-configuration} (@pxref{Windows -Configuration}). - -@item -Mail can be re-scanned by a daemonic process (@pxref{Daemons}). -@iftex -@iflatex -\marginpar[\mbox{}\hfill\epsfig{figure=tmp/fseptember.ps,height=5cm}]{\epsfig{figure=tmp/fseptember.ps,height=5cm}} -@end iflatex -@end iftex - -@item -Gnus can make use of NoCeM files to weed out spam (@pxref{NoCeM}). - -@lisp -(setq gnus-use-nocem t) -@end lisp - -@item -Groups can be made permanently visible (@pxref{Listing Groups}). - -@lisp -(setq gnus-permanently-visible-groups "^nnml:") -@end lisp - -@item -Many new hooks have been introduced to make customizing easier. - -@item -Gnus respects the @code{Mail-Copies-To} header. - -@item -Threads can be gathered by looking at the @code{References} header -(@pxref{Customizing Threading}). - -@lisp -(setq gnus-summary-thread-gathering-function - 'gnus-gather-threads-by-references) -@end lisp - -@item -Read articles can be stored in a special backlog buffer to avoid -refetching (@pxref{Article Backlog}). - -@lisp -(setq gnus-keep-backlog 50) -@end lisp - -@item -A clean copy of the current article is always stored in a separate -buffer to allow easier treatment. - -@item -Gnus can suggest where to save articles (@pxref{Saving Articles}). - -@item -Gnus doesn't have to do as much prompting when saving (@pxref{Saving -Articles}). - -@lisp -(setq gnus-prompt-before-saving t) -@end lisp - -@item -@code{gnus-uu} can view decoded files asynchronously while fetching -articles (@pxref{Other Decode Variables}). - -@lisp -(setq gnus-uu-grabbed-file-functions 'gnus-uu-grab-view) -@end lisp - -@item -Filling in the article buffer now works properly on cited text -(@pxref{Article Washing}). - -@item -Hiding cited text adds buttons to toggle hiding, and how much -cited text to hide is now customizable (@pxref{Article Hiding}). - -@lisp -(setq gnus-cited-lines-visible 2) -@end lisp - -@item -Boring headers can be hidden (@pxref{Article Hiding}). - -@lisp -(add-hook 'gnus-article-display-hook - 'gnus-article-hide-boring-headers t) -@end lisp - -@item -Default scoring values can now be set from the menu bar. - -@item -Further syntax checking of outgoing articles have been added. - -@end itemize - - -@node Red Gnus -@subsubsection Red Gnus - -New features in Gnus 5.4/5.5: - -@iftex -@iflatex -\gnusfig{-5.5cm}{-4cm}{\epsfig{figure=tmp/red.ps,height=20cm}} -@end iflatex -@end iftex - -@itemize @bullet - -@item -@file{nntp.el} has been totally rewritten in an asynchronous fashion. - -@item -Article prefetching functionality has been moved up into -Gnus (@pxref{Asynchronous Fetching}). - -@item -Scoring can now be performed with logical operators like @code{and}, -@code{or}, @code{not}, and parent redirection (@pxref{Advanced -Scoring}). - -@item -Article washing status can be displayed in the -article mode line (@pxref{Misc Article}). - -@item -@file{gnus.el} has been split into many smaller files. - -@item -Suppression of duplicate articles based on Message-ID can be done -(@pxref{Duplicate Suppression}). - -@lisp -(setq gnus-suppress-duplicates t) -@end lisp - -@item -New variables for specifying what score and adapt files are to be -considered home score and adapt files (@pxref{Home Score File}) have -been added. - -@item -@code{nndoc} was rewritten to be easily extendable (@pxref{Document -Server Internals}). - -@item -Groups can inherit group parameters from parent topics (@pxref{Topic -Parameters}). - -@item -Article editing has been revamped and is now actually usable. - -@item -Signatures can be recognized in more intelligent fashions -(@pxref{Article Signature}). - -@item -Summary pick mode has been made to look more @code{nn}-like. Line -numbers are displayed and the @kbd{.} command can be used to pick -articles (@code{Pick and Read}). - -@item -Commands for moving the @file{.newsrc.eld} from one server to -another have been added (@pxref{Changing Servers}). - -@item -There's a way now to specify that ``uninteresting'' fields be suppressed -when generating lines in buffers (@pxref{Advanced Formatting}). - -@item -Several commands in the group buffer can be undone with @kbd{M-C-_} -(@pxref{Undo}). - -@item -Scoring can be done on words using the new score type @code{w} -(@pxref{Score File Format}). - -@item -Adaptive scoring can be done on a Subject word-by-word basis -(@pxref{Adaptive Scoring}). - -@lisp -(setq gnus-use-adaptive-scoring '(word)) -@end lisp - -@item -Scores can be decayed (@pxref{Score Decays}). - -@lisp -(setq gnus-decay-scores t) -@end lisp - -@item -Scoring can be performed using a regexp on the Date header. The Date is -normalized to compact ISO 8601 format first (@pxref{Score File Format}). - -@item -A new command has been added to remove all data on articles from -the native server (@pxref{Changing Servers}). - -@item -A new command for reading collections of documents -(@code{nndoc} with @code{nnvirtual} on top) has been added---@kbd{M-C-d} -(@pxref{Really Various Summary Commands}). - -@item -Process mark sets can be pushed and popped (@pxref{Setting Process -Marks}). - -@item -A new mail-to-news backend makes it possible to post even when the NNTP -server doesn't allow posting (@pxref{Mail-To-News Gateways}). - -@item -A new backend for reading searches from Web search engines -(@dfn{DejaNews}, @dfn{Alta Vista}, @dfn{InReference}) has been added -(@pxref{Web Searches}). - -@item -Groups inside topics can now be sorted using the standard sorting -functions, and each topic can be sorted independently (@pxref{Topic -Sorting}). - -@item -Subsets of the groups can be sorted independently (@code{Sorting -Groups}). - -@item -Cached articles can be pulled into the groups (@pxref{Summary Generation -Commands}). -@iftex -@iflatex -\marginpar[\mbox{}\hfill\epsfig{figure=tmp/fred.ps,width=3cm}]{\epsfig{figure=tmp/fred.ps,width=3cm}} -@end iflatex -@end iftex - -@item -Score files are now applied in a more reliable order (@pxref{Score -Variables}). - -@item -Reports on where mail messages end up can be generated (@pxref{Splitting -Mail}). - -@item -More hooks and functions have been added to remove junk from incoming -mail before saving the mail (@pxref{Washing Mail}). - -@item -Emphasized text can be properly fontisized: - -@lisp -(add-hook 'gnus-article-display-hook - 'gnus-article-emphasize) -@end lisp - -@end itemize - - -@node Quassia Gnus -@subsubsection Quassia Gnus - -New features in Gnus 5.6: - -@itemize @bullet - -@item -New functionality for using Gnus as an offline newsreader has been -added. A plethora of new commands and modes have been added. See -@pxref{Gnus Unplugged} for the full story. - -@item - The @code{nndraft} backend has returned, but works differently than -before. All Message buffers are now also articles in the @code{nndraft} -group, which is created automatically. - -@item -@code{gnus-alter-header-function} can now be used to alter header -values. - -@item - @code{gnus-summary-goto-article} now accept Message-ID's. - -@item - A new Message command for deleting text in the body of a message -outside the region: @kbd{C-c C-v}. - -@item - You can now post to component group in @code{nnvirtual} groups with -@kbd{C-u C-c C-c}. - -@item - @code{nntp-rlogin-program}---new variable to ease customization. - -@item - @code{C-u C-c C-c} in @code{gnus-article-edit-mode} will now inhibit -re-highlighting of the article buffer. - -@item - New element in @code{gnus-boring-article-headers}---@code{long-to}. - -@item - @kbd{M-i} symbolic prefix command. See the section "Symbolic -Prefixes" in the Gnus manual for details. - -@item - @kbd{L} and @kbd{I} in the summary buffer now take the symbolic prefix -@kbd{a} to add the score rule to the "all.SCORE" file. - -@item - @code{gnus-simplify-subject-functions} variable to allow greater -control over simplification. - -@item - @kbd{A T}---new command for fetching the current thread. - -@item - @kbd{/ T}---new command for including the current thread in the -limit. - -@item - @kbd{M-RET} is a new Message command for breaking cited text. - -@item - @samp{\\1}-expressions are now valid in @code{nnmail-split-methods}. - -@item - The @code{custom-face-lookup} function has been removed. -If you used this function in your initialization files, you must -rewrite them to use @code{face-spec-set} instead. - -@item - Canceling now uses the current select method. Symbolic prefix -@kbd{a} forces normal posting method. - -@item - New command to translate M******** sm*rtq**t*s into proper -text---@kbd{W d}. - -@item - For easier debugging of @code{nntp}, you can set -@code{nntp-record-commands} to a non-@code{nil} value. - -@item - @code{nntp} now uses @file{~/.authinfo}, a @file{.netrc}-like file, for -controlling where and how to send @sc{authinfo} to @sc{nntp} servers. - -@item - A command for editing group parameters from the summary buffer -has been added. - -@item - A history of where mails have been split is available. - -@item - A new article date command has been added---@code{article-date-iso8601}. - -@item - Subjects can be simplified when threading by setting -@code{gnus-score-thread-simplify}. - -@item - A new function for citing in Message has been -added---@code{message-cite-original-without-signature}. - -@item - @code{article-strip-all-blank-lines}---new article command. - -@item - A new Message command to kill to the end of the article has -been added. - -@item - A minimum adaptive score can be specified by using the -@code{gnus-adaptive-word-minimum} variable. - -@item - The "lapsed date" article header can be kept continually -updated by the @code{gnus-start-date-timer} command. - -@item - Web listserv archives can be read with the @code{nnlistserv} backend. - -@item - Old dejanews archives can now be read by @code{nnweb}. - -@end itemize - - -@node Newest Features -@subsection Newest Features -@cindex todo - -Also known as the @dfn{todo list}. Sure to be implemented before the -next millennium. - -Be afraid. Be very afraid. - -(That a feature appears in this list doesn't necessarily mean that I've -decided to actually implement it. It just means that I think it sounds -interesting.) - -(Yes, this is the actual, up-to-the-second todo list.) - -@itemize @bullet - -@item -Native @sc{mime} support is something that should be done. - -@item -Really do unbinhexing. - -@item - I would like the zombie-page to contain an URL to the source of the -latest version of gnus or some explanation on where to find it. - -@item - A way to continue editing the latest Message composition. - -@item - http://www.sonicnet.com/feature/ari3/ - -@item - facep is not declared. - -@item - Include a section in the manual on why the number of articles -isn't the same in the group buffer and on the SPC prompt. - -@item - Interacting with rmail fcc isn't easy. - -@item -@example - Hypermail: - - - - -http://www.uwsg.indiana.edu/hypermail/linux/kernel/9610/index.html - -http://www.miranova.com/gnus-list/ - -@end example - -@item -@samp{^-- } is made into - in LaTeX. - -@item - gnus-kill is much slower than it was in GNUS 4.1.3. - -@item - when expunging articles on low score, the sparse nodes keep hanging on? -@item - starting the first time seems to hang Gnus on some systems. Does -NEWGROUPS answer too fast? -@item - nndir doesn't read gzipped files. -@item - FAQ doesn't have an up node? -@item - when moving mail from a procmail spool to the crash-box, -the crash-box is only appropriate to one specific group. -@item - `t' `t' makes X-Faces disappear. -@item - nnmh-be-safe means that crossposted articles will -be marked as unread. -@item - Orphan score entries don't show on "V t" score trace -@item - when clearing out data, the cache data should also be reset. -@item - rewrite gnus-summary-limit-children to be non-recursive -to avoid exceeding lisp nesting on huge groups. -@item - expunged articles are counted when computing scores. -@item - implement gnus-batch-brew-soup -@item - ticked articles aren't easy to read in pick mode -- `n' and -stuff just skips past them. Read articles are the same. -@item - topics that contain just groups with ticked -articles aren't displayed. -@item - nndoc should always allocate unique Message-IDs. -@item - If there are mail groups the first time you use Gnus, Gnus'll -make the mail groups killed. -@item - no "no news is good news" when using topics. -@item - when doing crosspost marking, the cache has to be consulted -and articles have to be removed. -@item - nnweb should fetch complete articles when they are split into several -parts. -@item - scoring on head immediate doesn't work. -@item - finding short score file names takes forever. -@item - canceling articles in foreign groups. -@item - nntp-open-rlogin no longer works. -@item - C-u C-x C-s (Summary) switches to the group buffer. -@item - move nnmail-split-history out to the backends. -@item - nnweb doesn't work properly. -@item - using a virtual server name as `gnus-select-method' doesn't work? -@item - when killing/yanking a group from one topic to another in a slave, the -master will yank it first to one topic and then add it to another. -Perhaps. - -@item - warn user about `=' redirection of a group in the active file? -@item - really unbinhex binhex files. -@item - take over the XEmacs menubar and offer a toggle between the XEmacs -bar and the Gnus bar. -@item -@example - push active file and NOV file parsing down into C code. -`(canonize-message-id id)' -`(mail-parent-message-id references n)' -`(parse-news-nov-line &optional dependency-hashtb)' -`(parse-news-nov-region beg end &optional dependency-hashtb fullp)' -`(parse-news-active-region beg end hashtb)' - -@end example - -@item - nnml .overview directory with splits. -@item - asynchronous cache -@item - postponed commands. -@item - the selected article show have its Subject displayed in its summary line. -@item - when entering groups, get the real number of unread articles from -the server? -@item - sort after gathering threads -- make false roots have the -headers of the oldest orphan with a 0 article number? -@item - nndoc groups should inherit the score files of their parents? Also -inherit copy prompts and save files. -@item - command to start up Gnus (if not running) and enter a mail mode buffer. -@item - allow editing the group description from the group buffer -for backends that support that. -@item -gnus-hide,show-all-topics -@item - groups and sub-topics should be allowed to mingle inside each topic, -and not just list all subtopics at the end. -@item - a command to remove all read articles that are not needed to connect -threads -- `gnus-summary-limit-to-sparse-unread'? -@item - a variable to turn off limiting/cutting of threads in the tree buffer. -@item - a variable to limit how many files are uudecoded. -@item - add zombie groups to a special "New Groups" topic. -@item - server mode command: close/open all connections -@item - put a file date in gnus-score-alist and check whether the file -has been changed before using it. -@item - on exit from a digest group, go to the next article in the parent group. -@item - hide (sub)threads with low score. -@item - when expiring, remove all marks from expired articles. -@item - gnus-summary-limit-to-body -@item - a regexp alist that says what level groups are to be subscribed -on. Eg. -- `(("nnml:" . 1))'. -@item - easier interface to nnkiboze to create ephemeral groups that -contain groups that match a regexp. -@item - allow newlines in urls, but remove them before using -the URL. -@item - If there is no From line, the mail backends should fudge one from the -"From " line. -@item - fuzzy simplifying should strip all non-alpha-numerical info -from subject lines. -@item - gnus-soup-brew-soup-with-high-scores. -@item - nntp-ping-before-connect -@item - command to check whether NOV is evil. "list overview.fmt". -@item - when entering a group, Gnus should look through the score -files very early for `local' atoms and set those local variables. -@item - message annotations. -@item - topics are always yanked before groups, and that's not good. -@item - (set-extent-property extent 'help-echo "String to display in minibuf") -to display help in the minibuffer on buttons under XEmacs. -@item - allow group line format spec to say how many articles there -are in the cache. -@item - AUTHINFO GENERIC -@item - support qmail maildir spools -@item - `run-with-idle-timer' in gnus-demon. -@item - stop using invisible text properties and start using overlays instead -@item - C-c C-f C-e to add an Expires header. -@item - go from one group to the next; everything is expunged; go to the -next group instead of going to the group buffer. -@item - gnus-renumber-cache -- to renumber the cache using "low" numbers. -@item - record topic changes in the dribble buffer. -@item - `nnfolder-generate-active-file' should look at the folders it -finds and generate proper active ranges. -@item - nneething-look-in-files-for-article-heads variable to control -whether nneething should sniff all files in the directories. -@item - gnus-fetch-article -- start Gnus, enter group, display article -@item - gnus-dont-move-articles-to-same-group variable when respooling. -@item - when messages are crossposted between several auto-expirable groups, -articles aren't properly marked as expirable. -@item - nneething should allow deletion/moving. -@item - TAB on the last button should go to the first button. -@item - if the car of an element in `mail-split-methods' is a function, -and the function returns non-nil, use that as the name of the group(s) to -save mail in. -@item - command for listing all score files that have been applied. -@item - a command in the article buffer to return to `summary' config. -@item - `gnus-always-post-using-current-server' -- variable to override -`C-c C-c' when posting. -@item - nnmail-group-spool-alist -- says where each group should use -as a spool file. -@item - when an article is crossposted to an auto-expirable group, the article -should be marker as expirable. -@item - article mode command/menu for "send region as URL to browser". -@item - on errors, jump to info nodes that explain the error. For instance, -on invalid From headers, or on error messages from the nntp server. -@item - when gathering threads, make the article that has no "Re: " the parent. -Also consult Date headers. -@item - a token in splits to call shrink-window-if-larger-than-buffer -@item - `1 0 A M' to do matches on the active hashtb. -@item - duplicates -- command to remove Gnus-Warning header, use the read -Message-ID, delete the "original". -@item - when replying to several messages at once, put the "other" message-ids -into a See-Also header. -@item - support setext: URL:http://www.bsdi.com/setext/ -@item - support ProleText: -@item - when browsing a foreign server, the groups that are already subscribed -should be listed as such and not as "K". -@item - generate font names dynamically. -@item - score file mode auto-alist. -@item - allow nndoc to change/add/delete things from documents. Implement -methods for each format for adding an article to the document. -@item - `gnus-fetch-old-headers' `all' value to incorporate -absolutely all headers there is. -@item - function like `|', but concatenate all marked articles -and pipe them to the process. -@item - cache the list of killed (or active) groups in a separate file. Update -the file whenever we read the active file or the list -of killed groups in the .eld file reaches a certain length. -@item - function for starting to edit a file to put into -the current mail group. -@item - score-find-trace should display the total score of the article. -@item - "ghettozie" -- score on Xref header and nix it out after using it -to avoid marking as read in other groups it has been crossposted to. -@item - look at procmail splitting. The backends should create -the groups automatically if a spool file exists for that group. -@item - function for backends to register themselves with Gnus. -@item - when replying to several process-marked articles, -have all the From end up in Cc headers? Variable to toggle. -@item - command to delete a crossposted mail article from all -groups it has been mailed to. -@item - `B c' and `B m' should be crosspost aware. -@item - hide-pgp should also hide PGP public key blocks. -@item - Command in the group buffer to respool process-marked groups. -@item - `gnus-summary-find-matching' should accept -pseudo-"headers" like "body", "head" and "all" -@item - When buttifying things, all white space (including -newlines) should be ignored. -@item - Process-marking all groups in a topic should process-mark -groups in subtopics as well. -@item - Add non-native groups to the list of killed groups when killing them. -@item - nntp-suggest-kewl-config to probe the nntp server and suggest -variable settings. -@item - add edit and forward secondary marks. -@item - nnml shouldn't visit its .overview files. -@item - allow customizing sorting within gathered threads. -@item - `B q' shouldn't select the current article. -@item - nnmbox should support a newsgroups file for descriptions. -@item - allow fetching mail from several pop servers. -@item - Be able to specify whether the saving commands save the original -or the formatted article. -@item - a command to reparent with the child process-marked (cf. `T ^'.). -@item - I think the possibility to send a password with nntp-open-rlogin -should be a feature in Red Gnus. -@item - The `Z n' command should be possible to execute from a mouse click. -@item - more limiting functions -- date, etc. -@item - be able to limit on a random header; on body; using reverse matches. -@item - a group parameter (`absofucking-total-expiry') that will make Gnus expire -even unread articles. -@item - a command to print the article buffer as postscript. -@item - variable to disable password fetching when opening by nntp-open-telnet. -@item - manual: more example servers -- nntp with rlogin, telnet -@item - checking for bogus groups should clean topic alists as well. -@item - canceling articles in foreign groups. -@item - article number in folded topics isn't properly updated by -Xref handling. -@item - Movement in the group buffer to the next unread group should go to the -next closed topic with unread messages if no group can be found. -@item - Extensive info pages generated on the fly with help everywhere -- -in the "*Gnus edit*" buffers, for instance. -@item - Topic movement commands -- like thread movement. Up, down, forward, next. -@item - a way to tick/mark as read Gcc'd articles. -@item - a way to say that all groups within a specific topic comes -from a particular server? Hm. -@item - `gnus-article-fill-if-long-lines' -- a function to fill -the article buffer if there are any looong lines there. -@item - `T h' should jump to the parent topic and fold it. -@item - a command to create an ephemeral nndoc group out of a file, -and then splitting it/moving it to some other group/backend. -@item - a group parameter for nnkiboze groups that says that -all kibozed articles should be entered into the cache. -@item - It should also probably be possible to delimit what -`gnus-jog-cache' does -- for instance, work on just some groups, or on -some levels, and entering just articles that have a score higher than -a certain number. -@item - nnfolder should append to the folder instead of re-writing -the entire folder to disk when accepting new messages. -@item - allow all backends to do the proper thing with .gz files. -@item - a backend for reading collections of babyl files nnbabylfolder? -@item - a command for making the native groups into foreign groups. -@item - server mode command for clearing read marks from all groups -from a server. -@item - when following up multiple articles, include all To, Cc, etc headers -from all articles. -@item - a command for deciding what the total score of the current -thread is. Also a way to highlight based on this. -@item - command to show and edit group scores -@item - a gnus-tree-minimize-horizontal to minimize tree buffers -horizontally. -@item - command to generate nnml overview file for one group. -@item - `C-u C-u a' -- prompt for many crossposted groups. -@item - keep track of which mail groups have received new articles (in this session). -Be able to generate a report and perhaps do some marking in the group -buffer. -@item - gnus-build-sparse-threads to a number -- build only sparse threads -that are of that length. -@item - have nnmh respect mh's unseen sequence in .mh_profile. -@item - cache the newsgroups descriptions locally. -@item - asynchronous posting under nntp. -@item - be able to control word adaptive scoring from the score files. -@item - a variable to make `C-c C-c' post using the "current" select method. -@item - `limit-exclude-low-scored-articles'. -@item - if `gnus-summary-show-thread' is a number, hide threads that have -a score lower than this number. -@item - split newsgroup subscription variable up into "order" and "method". -@item - buttonize ange-ftp file names. -@item - a command to make a duplicate copy of the current article -so that each copy can be edited separately. -@item - nnweb should allow fetching from the local nntp server. -@item - record the sorting done in the summary buffer so that -it can be repeated when limiting/regenerating the buffer. -@item - nnml-generate-nov-databses should generate for -all nnml servers. -@item - when the user does commands in the group buffer, check -the modification time of the .newsrc.eld file and use -ask-user-about-supersession-threat. Also warn when trying -to save .newsrc.eld and it has changed. -@item - M-g on a topic will display all groups with 0 articles in -the topic. -@item - command to remove all topic stuff. -@item - allow exploding incoming digests when reading incoming mail -and splitting the resulting digests. -@item - nnsoup shouldn't set the `message-' variables. -@item - command to nix out all nnoo state information. -@item - nnmail-process-alist that calls functions if group names -matches an alist -- before saving. -@item - use buffer-invisibility-spec everywhere for hiding text. -@item - variable to activate each group before entering them -to get the (new) number of articles. `gnus-activate-before-entering'. -@item - command to fetch a Message-ID from any buffer, even -starting Gnus first if necessary. -@item - when posting and checking whether a group exists or not, just -ask the nntp server instead of relying on the active hashtb. -@item - buttonize the output of `C-c C-a' in an apropos-like way. -@item - `G p' should understand process/prefix, and allow editing -of several groups at once. -@item - command to create an ephemeral nnvirtual group that -matches some regexp(s). -@item - nndoc should understand "Content-Type: message/rfc822" forwarded messages. -@item - it should be possible to score "thread" on the From header. -@item - hitting RET on a "gnus-uu-archive" pseudo article should unpack it. -@item - `B i' should display the article at once in the summary buffer. -@item - remove the "*" mark at once when unticking an article. -@item - `M-s' should highlight the matching text. -@item - when checking for duplicated mails, use Resent-Message-ID if present. -@item - killing and yanking groups in topics should be better. If killing one copy -of a group that exists in multiple topics, only that copy should -be removed. Yanking should insert the copy, and yanking topics -should be possible to be interspersed with the other yankings. -@item - command for enter a group just to read the cached articles. A way to say -"ignore the nntp connection; just read from the cache." -@item - `X u' should decode base64 articles. -@item - a way to hide all "inner" cited text, leaving just the most -recently cited text. -@item - nnvirtual should be asynchronous. -@item - after editing an article, gnus-original-article-buffer should -be invalidated. -@item - there should probably be a way to make Gnus not connect to the -server and just read the articles in the server -@item - allow a `set-default' (or something) to change the default -value of nnoo variables. -@item - a command to import group infos from a .newsrc.eld file. -@item - groups from secondary servers have the entire select method -listed in each group info. -@item - a command for just switching from the summary buffer to the group -buffer. -@item - a way to specify that some incoming mail washing functions -should only be applied to some groups. -@item - Message `C-f C-t' should ask the user whether to heed -mail-copies-to: never. -@item - new group parameter -- `post-to-server' that says to post -using the current server. Also a variable to do the same. -@item - the slave dribble files should autosave to the slave file names. -@item - a group parameter that says what articles to display on group entry, based -on article marks. -@item - a way to visually distinguish slave Gnusae from masters. (Whip instead -of normal logo?) -@item - Use DJ Bernstein "From " quoting/dequoting, where applicable. -@item - Why is hide-citation-maybe and hide-citation different? Also -clear up info. -@item - group user-defined meta-parameters. - - - -From: John Griffith -@item - I like the option for trying to retrieve the FAQ for a group and I was -thinking it would be great if for those newsgroups that had archives -you could also try to read the archive for that group. Part of the -problem is that archives are spread all over the net, unlike FAQs. -What would be best I suppose is to find the one closest to your site. - -In any case, there is a list of general news group archives at @* -ftp://ftp.neosoft.com/pub/users/claird/news.lists/newsgroup_archives.html - - - - -@item -@example -From: Jason L Tibbitts III -(add-hook 'gnus-select-group-hook - (lambda () - (gnus-group-add-parameter group - (cons 'gnus-group-date-last-entered (list (current-time-string)))))) - -(defun gnus-user-format-function-d (headers) - "Return the date the group was last read." - (cond ((car (gnus-group-get-parameter gnus-tmp-group 'gnus-group-date-last-entered))) - (t ""))) -@end example - -@item - tanken var at n,Ae(Br du bruker `gnus-startup-file' som prefix (FOO) til ilete -opp en fil FOO-SERVER, FOO-SERVER.el, FOO-SERVER.eld, kan du la den v,Af(Bre en -liste hvor du bruker hvert element i listen som FOO, istedet. da kunne man -hatt forskjellige serveres startup-filer forskjellige steder. - - -@item -LMI> Well, nnbabyl could alter the group info to heed labels like -LMI> answered and read, I guess. - -It could also keep them updated (the same for the Status: header of -unix mbox files). - -They could be used like this: - - -@example -`M l RET' add label to current message. -`M u RET' remove label from current message. -`/ l RET' limit summary buffer according to . - - would be a boolean expression on the labels, e.g. - -`/ l bug & !fixed RET' -@end example - -would show all the messages which are labeled `bug' but not labeled -`fixed'. - -One could also imagine the labels being used for highlighting, or -affect the summary line format. - - -@item -Sender: abraham@@dina.kvl.dk - -I'd like a gnus-find-file which work like find file, except that it -would recognize things that looks like messages or folders: - -- If it is a directory containing numbered files, create an nndir -summary buffer. - -- For other directories, create a nneething summary buffer. - -- For files matching "\\`From ", create a nndoc/mbox summary. - -- For files matching "\\`BABYL OPTIONS:", create a nndoc/baby summary. - -- For files matching "\\`[^ \t\n]+:", create an *Article* buffer. - -- For other files, just find them normally. - -I'd like `nneething' to use this function, so it would work on a -directory potentially containing mboxes or babyl files. - -@item -Please send a mail to bwarsaw@@cnri.reston.va.us (Barry A. Warsaw) and -tell him what you are doing. - -@item -Currently, I get prompted: - -decend into sci? -- type y -decend into sci.something ? -- type n -decend into ucd? - -The problem above is that since there is really only one subsection of -science, shouldn't it prompt you for only descending sci.something? If -there was a sci.somethingelse group or section, then it should prompt -for sci? first the sci.something? then sci.somethingelse?... - -@item -Ja, det burde v,Af(Bre en m,Ae(Bte ,Ae(B si slikt. Kanskje en ny variabel? -`gnus-use-few-score-files'? S,Ae(B kunne score-regler legges til den -"mest" lokale score-fila. F. eks. ville no-gruppene betjenes av -"no.all.SCORE", osv. - -@item -What i want is for Gnus to treat any sequence or combination of the following -as a single spoiler warning and hide it all, replacing it with a "Next Page" -button: - - -^L's - -more than n blank lines - -more than m identical lines -(which should be replaced with button to show them) - -any whitespace surrounding any of the above - - -@item -Well, we could allow a new value to `gnus-thread-ignore-subject' -- -`spaces', or something. (We could even default to that.) And then -subjects that differ in white space only could be considered the -"same" subject for threading purposes. - -@item -Modes to preprocess the contents (e.g. jka-compr) use the second form -"(REGEXP FUNCTION NON-NIL)" while ordinary modes (e.g. tex) use the first -form "(REGEXP . FUNCTION)", so you could use it to distinguish between -those two types of modes. (auto-modes-alist, insert-file-contents-literally.) - -@item - Under XEmacs -- do funny article marks: -tick - thumb tack -killed - skull -soup - bowl of soup -score below - dim light bulb -score over - bright light bulb - -@item -Yes. I think the algorithm is as follows: - -@example -Group-mode - - show-list-of-articles-in-group - if (key-pressed == SPACE) - if (no-more-articles-in-group-to-select) - if (articles-selected) - start-reading-selected-articles; - junk-unread-articles; - next-group; - else - show-next-page; - - else if (key-pressed = '.') - if (consolidated-menus) # same as hide-thread in Gnus - select-thread-under-cursor; - else - select-article-under-cursor; - - -Article-mode - if (key-pressed == SPACE) - if (more-pages-in-article) - next-page; - else if (more-selected-articles-to-read) - next-article; - else - next-group; -@end example - -@item -My precise need here would have been to limit files to Incoming*. -One could think of some `nneething-only-files' variable, but I guess -it would have been unacceptable if one was using many unrelated such -nneething groups. - -A more useful approach would be to, in response to the `G D' prompt, be -allowed to say something like: `~/.mail/Incoming*', somewhat limiting -the top-level directory only (in case directories would be matched by -the wildcard expression). - -@item -It would be nice if it also handled - - - -which should correspond to `B nntp RET sunsite.auc.dk' in *Group*. - - -@item - - Take a look at w3-menu.el in the Emacs-W3 distribution - this works out -really well. Each menu is 'named' by a symbol that would be on a -gnus-*-menus (where * would be whatever, but at least group, summary, and -article versions) variable. - - So for gnus-summary-menus, I would set to '(sort mark dispose ...) - - A value of '1' would just put _all_ the menus in a single 'GNUS' menu in -the main menubar. This approach works really well for Emacs-W3 and VM. - - -@item - nndoc should take care to create unique Message-IDs for all its -articles. -@item - gnus-score-followup-article only works when you have a summary buffer -active. Make it work when posting from the group buffer as well. -(message-sent-hook). -@item - rewrite gnus-demon to use run-with-idle-timers. - -@item - * Enhancements to Gnus: - - Add two commands: - - * gnus-servers (gnus-start-server-buffer?)--enters Gnus and goes - straight to the server buffer, without opening any connections to - servers first. - - * gnus-server-read-server-newsrc--produces a buffer very similar to - the group buffer, but with only groups from that server listed; - quitting this buffer returns to the server buffer. - -@item - add a command to check the integrity of an nnfolder folder -- -go through the article numbers and see that there are no duplicates, -and stuff. - -@item - `unsmileyfy-buffer' to undo smileification. - -@item - a command to give all relevant info on an article, including all -secondary marks. - -@item - when doing `-request-accept-article', the backends should do -the nnmail duplicate checking. - -@item - allow `message-signature-file' to be a function to return the -value of the signature file. - -@item - In addition, I would love it if I could configure message-tab so that it -could call `bbdb-complete-name' in other headers. So, some sort of -interface like - -(setq message-tab-alist - '((message-header-regexp message-expand-group) - ("^\\(To\\|[cC]c\\|[bB]cc\\)" bbdb-complete-name))) - -then you could run the relevant function to complete the information in -the header - -@item - cache the newsgroups file locally to avoid reloading it all the time. - -@item - a command to import a buffer into a group. - -@item - nnweb should allow fetching by Message-ID from servers. - -@item - point in the article buffer doesn't always go to the -beginning of the buffer when selecting new articles. - -@item - a command to process mark all unread articles. - -@item - `gnus-gather-threads-by-references-and-subject' -- first -do gathering by references, and then go through the dummy roots and -do more gathering by subject. - -@item - gnus-uu-mark-in-numerical-order -- process mark articles in -article numerical order. - -@item - (gnus-thread-total-score - (gnus-id-to-thread (mail-header-id (gnus-summary-article-header)))) -bind to a key. - -@item - sorting by score is wrong when using sparse threads. - -@item - a command to fetch an arbitrary article -- without having to be -in the summary buffer. - -@item - a new nncvs backend. Each group would show an article, using -version branches as threading, checkin date as the date, etc. - -@item - http://www.dejanews.com/forms/dnsetfilter_exp.html ? -This filter allows one to construct advance queries on the Dejanews -database such as specifying start and end dates, subject, author, -and/or newsgroup name. - -@item - new Date header scoring type -- older, newer - -@item - use the summary toolbar in the article buffer. - -@item - a command to fetch all articles that are less than X days old. - -@item - in pick mode, `q' should save the list of selected articles in the -group info. The next time the group is selected, these articles -will automatically get the process mark. - -@item - Isn't it possible to (also?) allow M-^ to automatically try the -default server if it fails on the current server? (controlled by a -user variable, (nil, t, 'ask)). - -@item - make it possible to cancel articles using the select method for the -current group. - -@item - `gnus-summary-select-article-on-entry' or something. It'll default -to t and will select whatever article decided by `gnus-auto-select-first'. - -@item - a new variable to control which selection commands should be unselecting. -`first', `best', `next', `prev', `next-unread', `prev-unread' are -candidates. - -@item - be able to select groups that have no articles in them -to be able to post in them (using the current select method). - -@item - be able to post via DejaNews. - -@item - `x' should retain any sortings that have been performed. - -@item - allow the user to specify the precedence of the secondary marks. Also -allow them to be displayed separately. - -@item - gnus-summary-save-in-pipe should concatenate the results from -the processes when doing a process marked pipe. - -@item - a new match type, like Followup, but which adds Thread matches on all -articles that match a certain From header. - -@item - a function that can be read from kill-emacs-query-functions to offer -saving living summary buffers. - -@item - a function for selecting a particular group which will contain -the articles listed in a list of article numbers/id's. - -@item - a battery of character translation functions to translate common -Mac, MS (etc) characters into ISO 8859-1. - -@example -(defun article-fix-m$word () - "Fix M$Word smartquotes in an article." - (interactive) - (save-excursion - (let ((buffer-read-only nil)) - (goto-char (point-min)) - (while (search-forward "\221" nil t) - (replace-match "`" t t)) - (goto-char (point-min)) - (while (search-forward "\222" nil t) - (replace-match "'" t t)) - (goto-char (point-min)) - (while (search-forward "\223" nil t) - (replace-match "\"" t t)) - (goto-char (point-min)) - (while (search-forward "\224" nil t) - (replace-match "\"" t t))))) -@end example - -@item -@example - (add-hook 'gnus-exit-query-functions -'(lambda () - (if (and (file-exists-p nnmail-spool-file) - (> (nnheader-file-size nnmail-spool-file) 0)) - (yes-or-no-p "New mail has arrived. Quit Gnus anyways? ") - (y-or-n-p "Are you sure you want to quit Gnus? ")))) -@end example - -@item - allow message-default-headers to be a function. - -@item - new Date score match types -- < > = (etc) that take floating point -numbers and match on the age of the article. - -@item -@example -> > > If so, I've got one gripe: It seems that when I fire up gnus 5.2.25 -> > > under xemacs-19.14, it's creating a new frame, but is erasing the -> > > buffer in the frame that it was called from =:-O -> -> > Hm. How do you start up Gnus? From the toolbar or with -> > `M-x gnus-other-frame'? -> -> I normally start it up from the toolbar; at -> least that's the way I've caught it doing the -> deed before. -@end example - -@item - all commands that react to the process mark should push -the current process mark set onto the stack. - -@item - gnus-article-hide-pgp -Selv ville jeg nok ha valgt islette den dersom teksten matcher -@example -"\\(This\s+\\)?[^ ]+ has been automatically signed by" -@end example -og det er maks hundre tegn mellom match-end og ----linja. Men -det- -er min type heuristikk og langt fra alles. - -@item - `gnus-subscribe-sorted' -- insert new groups where they would have been -sorted to if `gnus-group-sort-function' were run. - -@item - gnus-(group,summary)-highlight should respect any `face' text props set -on the lines. - -@item - use run-with-idle-timer for gnus-demon instead of the -home-brewed stuff for better reliability. - -@item - add a way to select which NoCeM type to apply -- spam, troll, etc. - -@item - nndraft-request-group should tally autosave files. - -@item - implement nntp-retry-on-break and nntp-command-timeout. - -@item - gnus-article-highlight-limit that says when not to highlight (long) -articles. - -@item - (nnoo-set SERVER VARIABLE VALUE) - -@item - nn*-spool-methods - -@item - interrupitng agent fetching of articles should save articles. - -@item - command to open a digest group, and copy all the articles there to the -current group. - -@item - a variable to disable article body highlights if there's more than -X characters in the body. - -@item - handle 480/381 authinfo requests separately. - -@item - include the texi/dir file in the distribution. - -@item - format spec to "tab" to a position. - -@item - Move all prompting to the new `M-n' default style. - -@item - command to display all dormant articles. - -@item - gnus-auto-select-next makeover -- list of things it should do. - -@item - a score match type that adds scores matching on From if From has replied -to something someone else has said. - -@item - Read Netscape discussion groups: -snews://secnews.netscape.com/netscape.communicator.unix - -@item -One command to edit the original version if an article, and one to edit -the displayed version. - -@item -@kbd{T v} -- make all process-marked articles the children of the -current article. - -@item -Switch from initial text to the new default text mechanism. - -@item -How about making it possible to expire local articles? Will it be -possible to make various constraints on when an article can be -expired, e.g. (read), (age > 14 days), or the more interesting (read -& age > 14 days)? - -@item -New limit command---limit to articles that have a certain string -in the head or body. - -@item -Allow breaking lengthy NNTP commands. - -@item -gnus-article-highlight-limit, to disable highlighting in big articles. - -@item -Editing an article should put the article to be edited -in a special, unique buffer. - -@item -A command to send a mail to the admin-address group param. - -@item -A Date scoring type that will match if the article -is less than a certain number of days old. - -@item -New spec: %~(tab 56) to put point on column 56 - -@item -Allow Gnus Agent scoring to use normal score files. - -@item -Rething the Agent active file thing. `M-g' doesn't update the active -file, for instance. - -@item -With dummy roots, `^' and then selecing the first article -in any other dummy thread will make gnus highlight the -dummy root instead of the first article. - -@item -Propagate all group properties (marks, article numbers, etc) up to the -topics for displaying. - -@item -`n' in the group buffer with topics should go to the next group -with unread articles, even if that group is hidden in a topic. - -@item -gnus-posting-styles doesn't work in drafts. - -@item -gnus-summary-limit-include-cached is slow when there are -many articles in the cache, since it regenerates big parts of the -summary buffer for each article. - -@item -Implement gnus-batch-brew-soup. - -@item -Group parameters and summary commands for un/subscribing to mailing -lists. - -@item -Introduce nnmail-home-directory. - -@item -gnus-fetch-group and friends should exit Gnus when the user -exits the group. - -@item -Solve the halting problem. - -@c TODO -@end itemize - -@iftex - -@page -@node The Manual -@section The Manual -@cindex colophon -@cindex manual - -This manual was generated from a TeXinfo file and then run through -either @code{texi2dvi} -@iflatex -or my own home-brewed TeXinfo to \LaTeX\ transformer, -and then run through @code{latex} and @code{dvips} -@end iflatex -to get what you hold in your hands now. - -The following conventions have been used: - -@enumerate - -@item -This is a @samp{string} - -@item -This is a @kbd{keystroke} - -@item -This is a @file{file} - -@item -This is a @code{symbol} - -@end enumerate - -So if I were to say ``set @code{flargnoze} to @samp{yes}'', that would -mean: - -@lisp -(setq flargnoze "yes") -@end lisp - -If I say ``set @code{flumphel} to @code{yes}'', that would mean: - -@lisp -(setq flumphel 'yes) -@end lisp - -@samp{yes} and @code{yes} are two @emph{very} different things---don't -ever get them confused. - -@iflatex -@c @head -Of course, everything in this manual is of vital interest, so you should -read it all. Several times. However, if you feel like skimming the -manual, look for that gnu head you should see in the margin over -there---it means that what's being discussed is of more importance than -the rest of the stuff. (On the other hand, if everything is infinitely -important, how can anything be more important than that? Just one more -of the mysteries of this world, I guess.) -@end iflatex - -@end iftex - - -@page -@node Terminology -@section Terminology - -@cindex terminology -@table @dfn - -@item news -@cindex news -This is what you are supposed to use this thing for---reading news. -News is generally fetched from a nearby @sc{nntp} server, and is -generally publicly available to everybody. If you post news, the entire -world is likely to read just what you have written, and they'll all -snigger mischievously. Behind your back. - -@item mail -@cindex mail -Everything that's delivered to you personally is mail. Some news/mail -readers (like Gnus) blur the distinction between mail and news, but -there is a difference. Mail is private. News is public. Mailing is -not posting, and replying is not following up. - -@item reply -@cindex reply -Send a mail to the person who has written what you are reading. - -@item follow up -@cindex follow up -Post an article to the current newsgroup responding to the article you -are reading. - -@item backend -@cindex backend -Gnus gets fed articles from a number of backends, both news and mail -backends. Gnus does not handle the underlying media, so to speak---this -is all done by the backends. - -@item native -@cindex native -Gnus will always use one method (and backend) as the @dfn{native}, or -default, way of getting news. - -@item foreign -@cindex foreign -You can also have any number of foreign groups active at the same time. -These are groups that use non-native non-secondary backends for getting -news. - -@item secondary -@cindex secondary -Secondary backends are somewhere half-way between being native and being -foreign, but they mostly act like they are native. - -@item article -@cindex article -A message that has been posted as news. - -@item mail message -@cindex mail message -A message that has been mailed. - -@item message -@cindex message -A mail message or news article - -@item head -@cindex head -The top part of a message, where administrative information (etc.) is -put. - -@item body -@cindex body -The rest of an article. Everything not in the head is in the -body. - -@item header -@cindex header -A line from the head of an article. - -@item headers -@cindex headers -A collection of such lines, or a collection of heads. Or even a -collection of @sc{nov} lines. - -@item @sc{nov} -@cindex nov -When Gnus enters a group, it asks the backend for the headers of all -unread articles in the group. Most servers support the News OverView -format, which is more compact and much faster to read and parse than the -normal @sc{head} format. - -@item level -@cindex levels -Each group is subscribed at some @dfn{level} or other (1-9). The ones -that have a lower level are ``more'' subscribed than the groups with a -higher level. In fact, groups on levels 1-5 are considered -@dfn{subscribed}; 6-7 are @dfn{unsubscribed}; 8 are @dfn{zombies}; and 9 -are @dfn{killed}. Commands for listing groups and scanning for new -articles will all use the numeric prefix as @dfn{working level}. - -@item killed groups -@cindex killed groups -No information on killed groups is stored or updated, which makes killed -groups much easier to handle than subscribed groups. - -@item zombie groups -@cindex zombie groups -Just like killed groups, only slightly less dead. - -@item active file -@cindex active file -The news server has to keep track of what articles it carries, and what -groups exist. All this information in stored in the active file, which -is rather large, as you might surmise. - -@item bogus groups -@cindex bogus groups -A group that exists in the @file{.newsrc} file, but isn't known to the -server (i.e., it isn't in the active file), is a @emph{bogus group}. -This means that the group probably doesn't exist (any more). - -@item activating -@cindex activating groups -The act of asking the server for info on a group and computing the -number of unread articles is called @dfn{activating the group}. -Un-activated groups are listed with @samp{*} in the group buffer. - -@item server -@cindex server -A machine one can connect to and get news (or mail) from. - -@item select method -@cindex select method -A structure that specifies the backend, the server and the virtual -server settings. - -@item virtual server -@cindex virtual server -A named select method. Since a select method defines all there is to -know about connecting to a (physical) server, taking the thing as a -whole is a virtual server. - -@item washing -@cindex washing -Taking a buffer and running it through a filter of some sort. The -result will (more often than not) be cleaner and more pleasing than the -original. - -@item ephemeral groups -@cindex ephemeral groups -Most groups store data on what articles you have read. @dfn{Ephemeral} -groups are groups that will have no data stored---when you exit the -group, it'll disappear into the aether. - -@item solid groups -@cindex solid groups -This is the opposite of ephemeral groups. All groups listed in the -group buffer are solid groups. - -@item sparse articles -@cindex sparse articles -These are article placeholders shown in the summary buffer when -@code{gnus-build-sparse-threads} has been switched on. - -@item threading -@cindex threading -To put responses to articles directly after the articles they respond -to---in a hierarchical fashion. - -@item root -@cindex root -@cindex thread root -The first article in a thread is the root. It is the ancestor of all -articles in the thread. - -@item parent -@cindex parent -An article that has responses. - -@item child -@cindex child -An article that responds to a different article---its parent. - -@item digest -@cindex digest -A collection of messages in one file. The most common digest format is -specified by RFC1153. - -@end table - - -@page -@node Customization -@section Customization -@cindex general customization - -All variables are properly documented elsewhere in this manual. This -section is designed to give general pointers on how to customize Gnus -for some quite common situations. - -@menu -* Slow/Expensive Connection:: You run a local Emacs and get the news elsewhere. -* Slow Terminal Connection:: You run a remote Emacs. -* Little Disk Space:: You feel that having large setup files is icky. -* Slow Machine:: You feel like buying a faster machine. -@end menu - - -@node Slow/Expensive Connection -@subsection Slow/Expensive @sc{nntp} Connection - -If you run Emacs on a machine locally, and get your news from a machine -over some very thin strings, you want to cut down on the amount of data -Gnus has to get from the @sc{nntp} server. - -@table @code - -@item gnus-read-active-file -Set this to @code{nil}, which will inhibit Gnus from requesting the -entire active file from the server. This file is often v. large. You -also have to set @code{gnus-check-new-newsgroups} and -@code{gnus-check-bogus-newsgroups} to @code{nil} to make sure that Gnus -doesn't suddenly decide to fetch the active file anyway. - -@item gnus-nov-is-evil -This one has to be @code{nil}. If not, grabbing article headers from -the @sc{nntp} server will not be very fast. Not all @sc{nntp} servers -support @sc{xover}; Gnus will detect this by itself. -@end table - - -@node Slow Terminal Connection -@subsection Slow Terminal Connection - -Let's say you use your home computer for dialing up the system that runs -Emacs and Gnus. If your modem is slow, you want to reduce (as much as -possible) the amount of data sent over the wires. - -@table @code - -@item gnus-auto-center-summary -Set this to @code{nil} to inhibit Gnus from re-centering the summary -buffer all the time. If it is @code{vertical}, do only vertical -re-centering. If it is neither @code{nil} nor @code{vertical}, do both -horizontal and vertical recentering. - -@item gnus-visible-headers -Cut down on the headers included in the articles to the -minimum. You can, in fact, make do without them altogether---most of the -useful data is in the summary buffer, anyway. Set this variable to -@samp{^NEVVVVER} or @samp{From:}, or whatever you feel you need. - -@item gnus-article-display-hook -Set this hook to all the available hiding commands: -@lisp -(setq gnus-article-display-hook - '(gnus-article-hide-headers - gnus-article-hide-signature - gnus-article-hide-citation)) -@end lisp - -@item gnus-use-full-window -By setting this to @code{nil}, you can make all the windows smaller. -While this doesn't really cut down much generally, it means that you -have to see smaller portions of articles before deciding that you didn't -want to read them anyway. - -@item gnus-thread-hide-subtree -If this is non-@code{nil}, all threads in the summary buffer will be -hidden initially. - -@item gnus-updated-mode-lines -If this is @code{nil}, Gnus will not put information in the buffer mode -lines, which might save some time. -@end table - - -@node Little Disk Space -@subsection Little Disk Space -@cindex disk space - -The startup files can get rather large, so you may want to cut their -sizes a bit if you are running out of space. - -@table @code - -@item gnus-save-newsrc-file -If this is @code{nil}, Gnus will never save @file{.newsrc}---it will -only save @file{.newsrc.eld}. This means that you will not be able to -use any other newsreaders than Gnus. This variable is @code{t} by -default. - -@item gnus-save-killed-list -If this is @code{nil}, Gnus will not save the list of dead groups. You -should also set @code{gnus-check-new-newsgroups} to @code{ask-server} -and @code{gnus-check-bogus-newsgroups} to @code{nil} if you set this -variable to @code{nil}. This variable is @code{t} by default. - -@end table - - -@node Slow Machine -@subsection Slow Machine -@cindex slow machine - -If you have a slow machine, or are just really impatient, there are a -few things you can do to make Gnus run faster. - -Set @code{gnus-check-new-newsgroups} and -@code{gnus-check-bogus-newsgroups} to @code{nil} to make startup faster. - -Set @code{gnus-show-threads}, @code{gnus-use-cross-reference} and -@code{gnus-nov-is-evil} to @code{nil} to make entering and exiting the -summary buffer faster. - -Set @code{gnus-article-display-hook} to @code{nil} to make article -processing a bit faster. - - -@page -@node Troubleshooting -@section Troubleshooting -@cindex troubleshooting - -Gnus works @emph{so} well straight out of the box---I can't imagine any -problems, really. - -Ahem. - -@enumerate - -@item -Make sure your computer is switched on. - -@item -Make sure that you really load the current Gnus version. If you have -been running @sc{gnus}, you need to exit Emacs and start it up again before -Gnus will work. - -@item -Try doing an @kbd{M-x gnus-version}. If you get something that looks -like @samp{Gnus v5.46; nntp 4.0} you have the right files loaded. If, -on the other hand, you get something like @samp{NNTP 3.x} or @samp{nntp -flee}, you have some old @file{.el} files lying around. Delete these. - -@item -Read the help group (@kbd{G h} in the group buffer) for a FAQ and a -how-to. - -@item -@vindex max-lisp-eval-depth -Gnus works on many recursive structures, and in some extreme (and very -rare) cases Gnus may recurse down ``too deeply'' and Emacs will beep at -you. If this happens to you, set @code{max-lisp-eval-depth} to 500 or -something like that. -@end enumerate - -If all else fails, report the problem as a bug. - -@cindex bugs -@cindex reporting bugs - -@kindex M-x gnus-bug -@findex gnus-bug -If you find a bug in Gnus, you can report it with the @kbd{M-x gnus-bug} -command. @kbd{M-x set-variable RET debug-on-error RET t RET}, and send -me the backtrace. I will fix bugs, but I can only fix them if you send -me a precise description as to how to reproduce the bug. - -You really can never be too detailed in a bug report. Always use the -@kbd{M-x gnus-bug} command when you make bug reports, even if it creates -a 10Kb mail each time you use it, and even if you have sent me your -environment 500 times before. I don't care. I want the full info each -time. - -It is also important to remember that I have no memory whatsoever. If -you send a bug report, and I send you a reply, and then you just send -back ``No, it's not! Moron!'', I will have no idea what you are -insulting me about. Always over-explain everything. It's much easier -for all of us---if I don't have all the information I need, I will just -mail you and ask for more info, and everything takes more time. - -If the problem you're seeing is very visual, and you can't quite explain -it, copy the Emacs window to a file (with @code{xwd}, for instance), put -it somewhere it can be reached, and include the URL of the picture in -the bug report. - -If you just need help, you are better off asking on -@samp{gnu.emacs.gnus}. I'm not very helpful. - -@cindex gnu.emacs.gnus -@cindex ding mailing list -You can also ask on the ding mailing list---@samp{ding@@gnus.org}. -Write to @samp{ding-request@@gnus.org} to subscribe. - - -@page -@node A Programmers Guide to Gnus -@section A Programmer@'s Guide to Gnus - -It is my hope that other people will figure out smart stuff that Gnus -can do, and that other people will write those smart things as well. To -facilitate that I thought it would be a good idea to describe the inner -workings of Gnus. And some of the not-so-inner workings, while I'm at -it. - -You can never expect the internals of a program not to change, but I -will be defining (in some details) the interface between Gnus and its -backends (this is written in stone), the format of the score files -(ditto), data structures (some are less likely to change than others) -and general methods of operation. - -@menu -* Gnus Utility Functions:: Common functions and variable to use. -* Backend Interface:: How Gnus communicates with the servers. -* Score File Syntax:: A BNF definition of the score file standard. -* Headers:: How Gnus stores headers internally. -* Ranges:: A handy format for storing mucho numbers. -* Group Info:: The group info format. -* Extended Interactive:: Symbolic prefixes and stuff. -* Emacs/XEmacs Code:: Gnus can be run under all modern Emacsen. -* Various File Formats:: Formats of files that Gnus use. -@end menu - - -@node Gnus Utility Functions -@subsection Gnus Utility Functions -@cindex Gnus utility functions -@cindex utility functions -@cindex functions -@cindex internal variables - -When writing small functions to be run from hooks (and stuff), it's -vital to have access to the Gnus internal functions and variables. -Below is a list of the most common ones. - -@table @code - -@item gnus-newsgroup-name -@vindex gnus-newsgroup-name -This variable holds the name of the current newsgroup. - -@item gnus-find-method-for-group -@findex gnus-find-method-for-group -A function that returns the select method for @var{group}. - -@item gnus-group-real-name -@findex gnus-group-real-name -Takes a full (prefixed) Gnus group name, and returns the unprefixed -name. - -@item gnus-group-prefixed-name -@findex gnus-group-prefixed-name -Takes an unprefixed group name and a select method, and returns the full -(prefixed) Gnus group name. - -@item gnus-get-info -@findex gnus-get-info -Returns the group info list for @var{group}. - -@item gnus-group-unread -@findex gnus-group-unread -The number of unread articles in @var{group}, or @code{t} if that is -unknown. - -@item gnus-active -@findex gnus-active -The active entry for @var{group}. - -@item gnus-set-active -@findex gnus-set-active -Set the active entry for @var{group}. - -@item gnus-add-current-to-buffer-list -@findex gnus-add-current-to-buffer-list -Adds the current buffer to the list of buffers to be killed on Gnus -exit. - -@item gnus-continuum-version -@findex gnus-continuum-version -Takes a Gnus version string as a parameter and returns a floating point -number. Earlier versions will always get a lower number than later -versions. - -@item gnus-group-read-only-p -@findex gnus-group-read-only-p -Says whether @var{group} is read-only or not. - -@item gnus-news-group-p -@findex gnus-news-group-p -Says whether @var{group} came from a news backend. - -@item gnus-ephemeral-group-p -@findex gnus-ephemeral-group-p -Says whether @var{group} is ephemeral or not. - -@item gnus-server-to-method -@findex gnus-server-to-method -Returns the select method corresponding to @var{server}. - -@item gnus-server-equal -@findex gnus-server-equal -Says whether two virtual servers are equal. - -@item gnus-group-native-p -@findex gnus-group-native-p -Says whether @var{group} is native or not. - -@item gnus-group-secondary-p -@findex gnus-group-secondary-p -Says whether @var{group} is secondary or not. - -@item gnus-group-foreign-p -@findex gnus-group-foreign-p -Says whether @var{group} is foreign or not. - -@item group-group-find-parameter -@findex group-group-find-parameter -Returns the parameter list of @var{group}. If given a second parameter, -returns the value of that parameter for @var{group}. - -@item gnus-group-set-parameter -@findex gnus-group-set-parameter -Takes three parameters; @var{group}, @var{parameter} and @var{value}. - -@item gnus-narrow-to-body -@findex gnus-narrow-to-body -Narrows the current buffer to the body of the article. - -@item gnus-check-backend-function -@findex gnus-check-backend-function -Takes two parameters, @var{function} and @var{group}. If the backend -@var{group} comes from supports @var{function}, return non-@code{nil}. - -@lisp -(gnus-check-backend-function "request-scan" "nnml:misc") -=> t -@end lisp - -@item gnus-read-method -@findex gnus-read-method -Prompts the user for a select method. - -@end table - - -@node Backend Interface -@subsection Backend Interface - -Gnus doesn't know anything about @sc{nntp}, spools, mail or virtual -groups. It only knows how to talk to @dfn{virtual servers}. A virtual -server is a @dfn{backend} and some @dfn{backend variables}. As examples -of the first, we have @code{nntp}, @code{nnspool} and @code{nnmbox}. As -examples of the latter we have @code{nntp-port-number} and -@code{nnmbox-directory}. - -When Gnus asks for information from a backend---say @code{nntp}---on -something, it will normally include a virtual server name in the -function parameters. (If not, the backend should use the ``current'' -virtual server.) For instance, @code{nntp-request-list} takes a virtual -server as its only (optional) parameter. If this virtual server hasn't -been opened, the function should fail. - -Note that a virtual server name has no relation to some physical server -name. Take this example: - -@lisp -(nntp "odd-one" - (nntp-address "ifi.uio.no") - (nntp-port-number 4324)) -@end lisp - -Here the virtual server name is @samp{odd-one} while the name of -the physical server is @samp{ifi.uio.no}. - -The backends should be able to switch between several virtual servers. -The standard backends implement this by keeping an alist of virtual -server environments that they pull down/push up when needed. - -There are two groups of interface functions: @dfn{required functions}, -which must be present, and @dfn{optional functions}, which Gnus will -always check for presence before attempting to call 'em. - -All these functions are expected to return data in the buffer -@code{nntp-server-buffer} (@samp{ *nntpd*}), which is somewhat -unfortunately named, but we'll have to live with it. When I talk about -@dfn{resulting data}, I always refer to the data in that buffer. When I -talk about @dfn{return value}, I talk about the function value returned by -the function call. Functions that fail should return @code{nil} as the -return value. - -Some backends could be said to be @dfn{server-forming} backends, and -some might be said not to be. The latter are backends that generally -only operate on one group at a time, and have no concept of ``server'' --- they have a group, and they deliver info on that group and nothing -more. - -In the examples and definitions I will refer to the imaginary backend -@code{nnchoke}. - -@cindex @code{nnchoke} - -@menu -* Required Backend Functions:: Functions that must be implemented. -* Optional Backend Functions:: Functions that need not be implemented. -* Error Messaging:: How to get messages and report errors. -* Writing New Backends:: Extending old backends. -* Hooking New Backends Into Gnus:: What has to be done on the Gnus end. -* Mail-like Backends:: Some tips on mail backends. -@end menu - - -@node Required Backend Functions -@subsubsection Required Backend Functions - -@table @code - -@item (nnchoke-retrieve-headers ARTICLES &optional GROUP SERVER FETCH-OLD) - -@var{articles} is either a range of article numbers or a list of -@code{Message-ID}s. Current backends do not fully support either---only -sequences (lists) of article numbers, and most backends do not support -retrieval of @code{Message-ID}s. But they should try for both. - -The result data should either be HEADs or NOV lines, and the result -value should either be @code{headers} or @code{nov} to reflect this. -This might later be expanded to @code{various}, which will be a mixture -of HEADs and NOV lines, but this is currently not supported by Gnus. - -If @var{fetch-old} is non-@code{nil} it says to try fetching "extra -headers", in some meaning of the word. This is generally done by -fetching (at most) @var{fetch-old} extra headers less than the smallest -article number in @code{articles}, and filling the gaps as well. The -presence of this parameter can be ignored if the backend finds it -cumbersome to follow the request. If this is non-@code{nil} and not a -number, do maximum fetches. - -Here's an example HEAD: - -@example -221 1056 Article retrieved. -Path: ifi.uio.no!sturles -From: sturles@@ifi.uio.no (Sturle Sunde) -Newsgroups: ifi.discussion -Subject: Re: Something very droll -Date: 27 Oct 1994 14:02:57 +0100 -Organization: Dept. of Informatics, University of Oslo, Norway -Lines: 26 -Message-ID: <38o8e1$a0o@@holmenkollen.ifi.uio.no> -References: <38jdmq$4qu@@visbur.ifi.uio.no> -NNTP-Posting-Host: holmenkollen.ifi.uio.no -. -@end example - -So a @code{headers} return value would imply that there's a number of -these in the data buffer. - -Here's a BNF definition of such a buffer: - -@example -headers = *head -head = error / valid-head -error-message = [ "4" / "5" ] 2number " " eol -valid-head = valid-message *header "." eol -valid-message = "221 " " Article retrieved." eol -header = eol -@end example - -If the return value is @code{nov}, the data buffer should contain -@dfn{network overview database} lines. These are basically fields -separated by tabs. - -@example -nov-buffer = *nov-line -nov-line = 8*9 [ field ] eol -field = -@end example - -For a closer look at what should be in those fields, -@pxref{Headers}. - - -@item (nnchoke-open-server SERVER &optional DEFINITIONS) - -@var{server} is here the virtual server name. @var{definitions} is a -list of @code{(VARIABLE VALUE)} pairs that define this virtual server. - -If the server can't be opened, no error should be signaled. The backend -may then choose to refuse further attempts at connecting to this -server. In fact, it should do so. - -If the server is opened already, this function should return a -non-@code{nil} value. There should be no data returned. - - -@item (nnchoke-close-server &optional SERVER) - -Close connection to @var{server} and free all resources connected -to it. Return @code{nil} if the server couldn't be closed for some -reason. - -There should be no data returned. - - -@item (nnchoke-request-close) - -Close connection to all servers and free all resources that the backend -have reserved. All buffers that have been created by that backend -should be killed. (Not the @code{nntp-server-buffer}, though.) This -function is generally only called when Gnus is shutting down. - -There should be no data returned. - - -@item (nnchoke-server-opened &optional SERVER) - -If @var{server} is the current virtual server, and the connection to the -physical server is alive, then this function should return a -non-@code{nil} vlue. This function should under no circumstances -attempt to reconnect to a server we have lost connection to. - -There should be no data returned. - - -@item (nnchoke-status-message &optional SERVER) - -This function should return the last error message from @var{server}. - -There should be no data returned. - - -@item (nnchoke-request-article ARTICLE &optional GROUP SERVER TO-BUFFER) - -The result data from this function should be the article specified by -@var{article}. This might either be a @code{Message-ID} or a number. -It is optional whether to implement retrieval by @code{Message-ID}, but -it would be nice if that were possible. - -If @var{to-buffer} is non-@code{nil}, the result data should be returned -in this buffer instead of the normal data buffer. This is to make it -possible to avoid copying large amounts of data from one buffer to -another, while Gnus mainly requests articles to be inserted directly -into its article buffer. - -If it is at all possible, this function should return a cons cell where -the @code{car} is the group name the article was fetched from, and the @code{cdr} is -the article number. This will enable Gnus to find out what the real -group and article numbers are when fetching articles by -@code{Message-ID}. If this isn't possible, @code{t} should be returned -on successful article retrieval. - - -@item (nnchoke-request-group GROUP &optional SERVER FAST) - -Get data on @var{group}. This function also has the side effect of -making @var{group} the current group. - -If @var{FAST}, don't bother to return useful data, just make @var{group} -the current group. - -Here's an example of some result data and a definition of the same: - -@example -211 56 1000 1059 ifi.discussion -@end example - -The first number is the status, which should be 211. Next is the -total number of articles in the group, the lowest article number, the -highest article number, and finally the group name. Note that the total -number of articles may be less than one might think while just -considering the highest and lowest article numbers, but some articles -may have been canceled. Gnus just discards the total-number, so -whether one should take the bother to generate it properly (if that is a -problem) is left as an exercise to the reader. - -@example -group-status = [ error / info ] eol -error = [ "4" / "5" ] 2 " " -info = "211 " 3* [ " " ] -@end example - - -@item (nnchoke-close-group GROUP &optional SERVER) - -Close @var{group} and free any resources connected to it. This will be -a no-op on most backends. - -There should be no data returned. - - -@item (nnchoke-request-list &optional SERVER) - -Return a list of all groups available on @var{server}. And that means -@emph{all}. - -Here's an example from a server that only carries two groups: - -@example -ifi.test 0000002200 0000002000 y -ifi.discussion 3324 3300 n -@end example - -On each line we have a group name, then the highest article number in -that group, the lowest article number, and finally a flag. - -@example -active-file = *active-line -active-line = name " " " " " " flags eol -name = -flags = "n" / "y" / "m" / "x" / "j" / "=" name -@end example - -The flag says whether the group is read-only (@samp{n}), is moderated -(@samp{m}), is dead (@samp{x}), is aliased to some other group -(@samp{=other-group}) or none of the above (@samp{y}). - - -@item (nnchoke-request-post &optional SERVER) - -This function should post the current buffer. It might return whether -the posting was successful or not, but that's not required. If, for -instance, the posting is done asynchronously, it has generally not been -completed by the time this function concludes. In that case, this -function should set up some kind of sentinel to beep the user loud and -clear if the posting could not be completed. - -There should be no result data from this function. - -@end table - - -@node Optional Backend Functions -@subsubsection Optional Backend Functions - -@table @code - -@item (nnchoke-retrieve-groups GROUPS &optional SERVER) - -@var{groups} is a list of groups, and this function should request data -on all those groups. How it does it is of no concern to Gnus, but it -should attempt to do this in a speedy fashion. - -The return value of this function can be either @code{active} or -@code{group}, which says what the format of the result data is. The -former is in the same format as the data from -@code{nnchoke-request-list}, while the latter is a buffer full of lines -in the same format as @code{nnchoke-request-group} gives. - -@example -group-buffer = *active-line / *group-status -@end example - - -@item (nnchoke-request-update-info GROUP INFO &optional SERVER) - -A Gnus group info (@pxref{Group Info}) is handed to the backend for -alterations. This comes in handy if the backend really carries all the -information (as is the case with virtual and imap groups). This -function should destructively alter the info to suit its needs, and -should return the (altered) group info. - -There should be no result data from this function. - - -@item (nnchoke-request-type GROUP &optional ARTICLE) - -When the user issues commands for ``sending news'' (@kbd{F} in the -summary buffer, for instance), Gnus has to know whether the article the -user is following up on is news or mail. This function should return -@code{news} if @var{article} in @var{group} is news, @code{mail} if it -is mail and @code{unknown} if the type can't be decided. (The -@var{article} parameter is necessary in @code{nnvirtual} groups which -might very well combine mail groups and news groups.) Both @var{group} -and @var{article} may be @code{nil}. - -There should be no result data from this function. - - -@item (nnchoke-request-update-mark GROUP ARTICLE MARK) - -If the user tries to set a mark that the backend doesn't like, this -function may change the mark. Gnus will use whatever this function -returns as the mark for @var{article} instead of the original -@var{mark}. If the backend doesn't care, it must return the original -@var{mark}, and not @code{nil} or any other type of garbage. - -The only use for this I can see is what @code{nnvirtual} does with -it---if a component group is auto-expirable, marking an article as read -in the virtual group should result in the article being marked as -expirable. - -There should be no result data from this function. - - -@item (nnchoke-request-scan &optional GROUP SERVER) - -This function may be called at any time (by Gnus or anything else) to -request that the backend check for incoming articles, in one way or -another. A mail backend will typically read the spool file or query the -POP server when this function is invoked. The @var{group} doesn't have -to be heeded---if the backend decides that it is too much work just -scanning for a single group, it may do a total scan of all groups. It -would be nice, however, to keep things local if that's practical. - -There should be no result data from this function. - - -@item (nnchoke-request-group-description GROUP &optional SERVER) - -The result data from this function should be a description of -@var{group}. - -@example -description-line = name description eol -name = -description = -@end example - -@item (nnchoke-request-list-newsgroups &optional SERVER) - -The result data from this function should be the description of all -groups available on the server. - -@example -description-buffer = *description-line -@end example - - -@item (nnchoke-request-newgroups DATE &optional SERVER) - -The result data from this function should be all groups that were -created after @samp{date}, which is in normal human-readable date -format. The data should be in the active buffer format. - - -@item (nnchoke-request-create-group GROUP &optional SERVER) - -This function should create an empty group with name @var{group}. - -There should be no return data. - - -@item (nnchoke-request-expire-articles ARTICLES &optional GROUP SERVER FORCE) - -This function should run the expiry process on all articles in the -@var{articles} range (which is currently a simple list of article -numbers.) It is left up to the backend to decide how old articles -should be before they are removed by this function. If @var{force} is -non-@code{nil}, all @var{articles} should be deleted, no matter how new -they are. - -This function should return a list of articles that it did not/was not -able to delete. - -There should be no result data returned. - - -@item (nnchoke-request-move-article ARTICLE GROUP SERVER ACCEPT-FORM -&optional LAST) - -This function should move @var{article} (which is a number) from -@var{group} by calling @var{accept-form}. - -This function should ready the article in question for moving by -removing any header lines it has added to the article, and generally -should ``tidy up'' the article. Then it should @code{eval} -@var{accept-form} in the buffer where the ``tidy'' article is. This -will do the actual copying. If this @code{eval} returns a -non-@code{nil} value, the article should be removed. - -If @var{last} is @code{nil}, that means that there is a high likelihood -that there will be more requests issued shortly, so that allows some -optimizations. - -The function should return a cons where the @code{car} is the group name and -the @code{cdr} is the article number that the article was entered as. - -There should be no data returned. - - -@item (nnchoke-request-accept-article GROUP &optional SERVER LAST) - -This function takes the current buffer and inserts it into @var{group}. -If @var{last} in @code{nil}, that means that there will be more calls to -this function in short order. - -The function should return a cons where the @code{car} is the group name and -the @code{cdr} is the article number that the article was entered as. - -There should be no data returned. - - -@item (nnchoke-request-replace-article ARTICLE GROUP BUFFER) - -This function should remove @var{article} (which is a number) from -@var{group} and insert @var{buffer} there instead. - -There should be no data returned. - - -@item (nnchoke-request-delete-group GROUP FORCE &optional SERVER) - -This function should delete @var{group}. If @var{force}, it should -really delete all the articles in the group, and then delete the group -itself. (If there is such a thing as ``the group itself''.) - -There should be no data returned. - - -@item (nnchoke-request-rename-group GROUP NEW-NAME &optional SERVER) - -This function should rename @var{group} into @var{new-name}. All -articles in @var{group} should move to @var{new-name}. - -There should be no data returned. - -@end table - - -@node Error Messaging -@subsubsection Error Messaging - -@findex nnheader-report -@findex nnheader-get-report -The backends should use the function @code{nnheader-report} to report -error conditions---they should not raise errors when they aren't able to -perform a request. The first argument to this function is the backend -symbol, and the rest are interpreted as arguments to @code{format} if -there are multiple of them, or just a string if there is one of them. -This function must always returns @code{nil}. - -@lisp -(nnheader-report 'nnchoke "You did something totally bogus") - -(nnheader-report 'nnchoke "Could not request group %s" group) -@end lisp - -Gnus, in turn, will call @code{nnheader-get-report} when it gets a -@code{nil} back from a server, and this function returns the most -recently reported message for the backend in question. This function -takes one argument---the server symbol. - -Internally, these functions access @var{backend}@code{-status-string}, -so the @code{nnchoke} backend will have its error message stored in -@code{nnchoke-status-string}. - - -@node Writing New Backends -@subsubsection Writing New Backends - -Many backends are quite similar. @code{nnml} is just like -@code{nnspool}, but it allows you to edit the articles on the server. -@code{nnmh} is just like @code{nnml}, but it doesn't use an active file, -and it doesn't maintain overview databases. @code{nndir} is just like -@code{nnml}, but it has no concept of ``groups'', and it doesn't allow -editing articles. - -It would make sense if it were possible to ``inherit'' functions from -backends when writing new backends. And, indeed, you can do that if you -want to. (You don't have to if you don't want to, of course.) - -All the backends declare their public variables and functions by using a -package called @code{nnoo}. - -To inherit functions from other backends (and allow other backends to -inherit functions from the current backend), you should use the -following macros: - -@table @code - -@item nnoo-declare -This macro declares the first parameter to be a child of the subsequent -parameters. For instance: - -@lisp -(nnoo-declare nndir - nnml nnmh) -@end lisp - -@code{nndir} has declared here that it intends to inherit functions from -both @code{nnml} and @code{nnmh}. - -@item defvoo -This macro is equivalent to @code{defvar}, but registers the variable as -a public server variable. Most state-oriented variables should be -declared with @code{defvoo} instead of @code{defvar}. - -In addition to the normal @code{defvar} parameters, it takes a list of -variables in the parent backends to map the variable to when executing -a function in those backends. - -@lisp -(defvoo nndir-directory nil - "Where nndir will look for groups." - nnml-current-directory nnmh-current-directory) -@end lisp - -This means that @code{nnml-current-directory} will be set to -@code{nndir-directory} when an @code{nnml} function is called on behalf -of @code{nndir}. (The same with @code{nnmh}.) - -@item nnoo-define-basics -This macro defines some common functions that almost all backends should -have. - -@example -(nnoo-define-basics nndir) -@end example - -@item deffoo -This macro is just like @code{defun} and takes the same parameters. In -addition to doing the normal @code{defun} things, it registers the -function as being public so that other backends can inherit it. - -@item nnoo-map-functions -This macro allows mapping of functions from the current backend to -functions from the parent backends. - -@example -(nnoo-map-functions nndir - (nnml-retrieve-headers 0 nndir-current-group 0 0) - (nnmh-request-article 0 nndir-current-group 0 0)) -@end example - -This means that when @code{nndir-retrieve-headers} is called, the first, -third, and fourth parameters will be passed on to -@code{nnml-retrieve-headers}, while the second parameter is set to the -value of @code{nndir-current-group}. - -@item nnoo-import -This macro allows importing functions from backends. It should be the -last thing in the source file, since it will only define functions that -haven't already been defined. - -@example -(nnoo-import nndir - (nnmh - nnmh-request-list - nnmh-request-newgroups) - (nnml)) -@end example - -This means that calls to @code{nndir-request-list} should just be passed -on to @code{nnmh-request-list}, while all public functions from -@code{nnml} that haven't been defined in @code{nndir} yet should be -defined now. - -@end table - -Below is a slightly shortened version of the @code{nndir} backend. - -@lisp -;;; nndir.el --- single directory newsgroup access for Gnus -;; Copyright (C) 1995,96 Free Software Foundation, Inc. - -;;; Code: - -(require 'nnheader) -(require 'nnmh) -(require 'nnml) -(require 'nnoo) -(eval-when-compile (require 'cl)) - -(nnoo-declare nndir - nnml nnmh) - -(defvoo nndir-directory nil - "Where nndir will look for groups." - nnml-current-directory nnmh-current-directory) - -(defvoo nndir-nov-is-evil nil - "*Non-nil means that nndir will never retrieve NOV headers." - nnml-nov-is-evil) - -(defvoo nndir-current-group "" nil nnml-current-group nnmh-current-group) -(defvoo nndir-top-directory nil nil nnml-directory nnmh-directory) -(defvoo nndir-get-new-mail nil nil nnml-get-new-mail nnmh-get-new-mail) - -(defvoo nndir-status-string "" nil nnmh-status-string) -(defconst nndir-version "nndir 1.0") - -;;; Interface functions. - -(nnoo-define-basics nndir) - -(deffoo nndir-open-server (server &optional defs) - (setq nndir-directory - (or (cadr (assq 'nndir-directory defs)) - server)) - (unless (assq 'nndir-directory defs) - (push `(nndir-directory ,server) defs)) - (push `(nndir-current-group - ,(file-name-nondirectory (directory-file-name nndir-directory))) - defs) - (push `(nndir-top-directory - ,(file-name-directory (directory-file-name nndir-directory))) - defs) - (nnoo-change-server 'nndir server defs)) - -(nnoo-map-functions nndir - (nnml-retrieve-headers 0 nndir-current-group 0 0) - (nnmh-request-article 0 nndir-current-group 0 0) - (nnmh-request-group nndir-current-group 0 0) - (nnmh-close-group nndir-current-group 0)) - -(nnoo-import nndir - (nnmh - nnmh-status-message - nnmh-request-list - nnmh-request-newgroups)) - -(provide 'nndir) -@end lisp - - -@node Hooking New Backends Into Gnus -@subsubsection Hooking New Backends Into Gnus - -@vindex gnus-valid-select-methods -Having Gnus start using your new backend is rather easy---you just -declare it with the @code{gnus-declare-backend} functions. This will -enter the backend into the @code{gnus-valid-select-methods} variable. - -@code{gnus-declare-backend} takes two parameters---the backend name and -an arbitrary number of @dfn{abilities}. - -Here's an example: - -@lisp -(gnus-declare-backend "nnchoke" 'mail 'respool 'address) -@end lisp - -The abilities can be: - -@table @code -@item mail -This is a mailish backend---followups should (probably) go via mail. -@item post -This is a newsish backend---followups should (probably) go via news. -@item post-mail -This backend supports both mail and news. -@item none -This is neither a post nor mail backend---it's something completely -different. -@item respool -It supports respooling---or rather, it is able to modify its source -articles and groups. -@item address -The name of the server should be in the virtual server name. This is -true for almost all backends. -@item prompt-address -The user should be prompted for an address when doing commands like -@kbd{B} in the group buffer. This is true for backends like -@code{nntp}, but not @code{nnmbox}, for instance. -@end table - - -@node Mail-like Backends -@subsubsection Mail-like Backends - -One of the things that separate the mail backends from the rest of the -backends is the heavy dependence by the mail backends on common -functions in @file{nnmail.el}. For instance, here's the definition of -@code{nnml-request-scan}: - -@lisp -(deffoo nnml-request-scan (&optional group server) - (setq nnml-article-file-alist nil) - (nnmail-get-new-mail 'nnml 'nnml-save-nov nnml-directory group)) -@end lisp - -It simply calls @code{nnmail-get-new-mail} with a few parameters, -and @code{nnmail} takes care of all the moving and splitting of the -mail. - -This function takes four parameters. - -@table @var -@item method -This should be a symbol to designate which backend is responsible for -the call. - -@item exit-function -This function should be called after the splitting has been performed. - -@item temp-directory -Where the temporary files should be stored. - -@item group -This optional argument should be a group name if the splitting is to be -performed for one group only. -@end table - -@code{nnmail-get-new-mail} will call @var{backend}@code{-save-mail} to -save each article. @var{backend}@code{-active-number} will be called to -find the article number assigned to this article. - -The function also uses the following variables: -@var{backend}@code{-get-new-mail} (to see whether to get new mail for -this backend); and @var{backend}@code{-group-alist} and -@var{backend}@code{-active-file} to generate the new active file. -@var{backend}@code{-group-alist} should be a group-active alist, like -this: - -@example -(("a-group" (1 . 10)) - ("some-group" (34 . 39))) -@end example - - -@node Score File Syntax -@subsection Score File Syntax - -Score files are meant to be easily parseable, but yet extremely -mallable. It was decided that something that had the same read syntax -as an Emacs Lisp list would fit that spec. - -Here's a typical score file: - -@lisp -(("summary" - ("win95" -10000 nil s) - ("Gnus")) - ("from" - ("Lars" -1000)) - (mark -100)) -@end lisp - -BNF definition of a score file: - -@example -score-file = "" / "(" *element ")" -element = rule / atom -rule = string-rule / number-rule / date-rule -string-rule = "(" quote string-header quote space *string-match ")" -number-rule = "(" quote number-header quote space *number-match ")" -date-rule = "(" quote date-header quote space *date-match ")" -quote = -string-header = "subject" / "from" / "references" / "message-id" / - "xref" / "body" / "head" / "all" / "followup" -number-header = "lines" / "chars" -date-header = "date" -string-match = "(" quote quote [ "" / [ space score [ "" / - space date [ "" / [ space string-match-t ] ] ] ] ] ")" -score = "nil" / -date = "nil" / -string-match-t = "nil" / "s" / "substring" / "S" / "Substring" / - "r" / "regex" / "R" / "Regex" / - "e" / "exact" / "E" / "Exact" / - "f" / "fuzzy" / "F" / "Fuzzy" -number-match = "(" [ "" / [ space score [ "" / - space date [ "" / [ space number-match-t ] ] ] ] ] ")" -number-match-t = "nil" / "=" / "<" / ">" / ">=" / "<=" -date-match = "(" quote quote [ "" / [ space score [ "" / - space date [ "" / [ space date-match-t ] ] ] ] ")" -date-match-t = "nil" / "at" / "before" / "after" -atom = "(" [ required-atom / optional-atom ] ")" -required-atom = mark / expunge / mark-and-expunge / files / - exclude-files / read-only / touched -optional-atom = adapt / local / eval -mark = "mark" space nil-or-number -nil-or-number = "nil" / -expunge = "expunge" space nil-or-number -mark-and-expunge = "mark-and-expunge" space nil-or-number -files = "files" *[ space ] -exclude-files = "exclude-files" *[ space ] -read-only = "read-only" [ space "nil" / space "t" ] -adapt = "adapt" [ space "ignore" / space "t" / space adapt-rule ] -adapt-rule = "(" *[ *[ "(" ")" ] ")" -local = "local" *[ space "(" space ")" ] -eval = "eval" space -space = *[ " " / / ] -@end example - -Any unrecognized elements in a score file should be ignored, but not -discarded. - -As you can see, white space is needed, but the type and amount of white -space is irrelevant. This means that formatting of the score file is -left up to the programmer---if it's simpler to just spew it all out on -one looong line, then that's ok. - -The meaning of the various atoms are explained elsewhere in this -manual (@pxref{Score File Format}). - - -@node Headers -@subsection Headers - -Internally Gnus uses a format for storing article headers that -corresponds to the @sc{nov} format in a mysterious fashion. One could -almost suspect that the author looked at the @sc{nov} specification and -just shamelessly @emph{stole} the entire thing, and one would be right. - -@dfn{Header} is a severely overloaded term. ``Header'' is used in -RFC1036 to talk about lines in the head of an article (e.g., -@code{From}). It is used by many people as a synonym for -``head''---``the header and the body''. (That should be avoided, in my -opinion.) And Gnus uses a format internally that it calls ``header'', -which is what I'm talking about here. This is a 9-element vector, -basically, with each header (ouch) having one slot. - -These slots are, in order: @code{number}, @code{subject}, @code{from}, -@code{date}, @code{id}, @code{references}, @code{chars}, @code{lines}, -@code{xref}. There are macros for accessing and setting these -slots---they all have predictable names beginning with -@code{mail-header-} and @code{mail-header-set-}, respectively. - -The @code{xref} slot is really a @code{misc} slot. Any extra info will -be put in there. - - -@node Ranges -@subsection Ranges - -@sc{gnus} introduced a concept that I found so useful that I've started -using it a lot and have elaborated on it greatly. - -The question is simple: If you have a large amount of objects that are -identified by numbers (say, articles, to take a @emph{wild} example) -that you want to qualify as being ``included'', a normal sequence isn't -very useful. (A 200,000 length sequence is a bit long-winded.) - -The solution is as simple as the question: You just collapse the -sequence. - -@example -(1 2 3 4 5 6 10 11 12) -@end example - -is transformed into - -@example -((1 . 6) (10 . 12)) -@end example - -To avoid having those nasty @samp{(13 . 13)} elements to denote a -lonesome object, a @samp{13} is a valid element: - -@example -((1 . 6) 7 (10 . 12)) -@end example - -This means that comparing two ranges to find out whether they are equal -is slightly tricky: - -@example -((1 . 5) 7 8 (10 . 12)) -@end example - -and - -@example -((1 . 5) (7 . 8) (10 . 12)) -@end example - -are equal. In fact, any non-descending list is a range: - -@example -(1 2 3 4 5) -@end example - -is a perfectly valid range, although a pretty long-winded one. This is -also valid: - -@example -(1 . 5) -@end example - -and is equal to the previous range. - -Here's a BNF definition of ranges. Of course, one must remember the -semantic requirement that the numbers are non-descending. (Any number -of repetition of the same number is allowed, but apt to disappear in -range handling.) - -@example -range = simple-range / normal-range -simple-range = "(" number " . " number ")" -normal-range = "(" start-contents ")" -contents = "" / simple-range *[ " " contents ] / - number *[ " " contents ] -@end example - -Gnus currently uses ranges to keep track of read articles and article -marks. I plan on implementing a number of range operators in C if The -Powers That Be are willing to let me. (I haven't asked yet, because I -need to do some more thinking on what operators I need to make life -totally range-based without ever having to convert back to normal -sequences.) - - -@node Group Info -@subsection Group Info - -Gnus stores all permanent info on groups in a @dfn{group info} list. -This list is from three to six elements (or more) long and exhaustively -describes the group. - -Here are two example group infos; one is a very simple group while the -second is a more complex one: - -@example -("no.group" 5 (1 . 54324)) - -("nnml:my.mail" 3 ((1 . 5) 9 (20 . 55)) - ((tick (15 . 19)) (replied 3 6 (19 . 3))) - (nnml "") - ((auto-expire . t) (to-address . "ding@@gnus.org"))) -@end example - -The first element is the @dfn{group name}---as Gnus knows the group, -anyway. The second element is the @dfn{subscription level}, which -normally is a small integer. (It can also be the @dfn{rank}, which is a -cons cell where the @code{car} is the level and the @code{cdr} is the -score.) The third element is a list of ranges of read articles. The -fourth element is a list of lists of article marks of various kinds. -The fifth element is the select method (or virtual server, if you like). -The sixth element is a list of @dfn{group parameters}, which is what -this section is about. - -Any of the last three elements may be missing if they are not required. -In fact, the vast majority of groups will normally only have the first -three elements, which saves quite a lot of cons cells. - -Here's a BNF definition of the group info format: - -@example -info = "(" group space ralevel space read - [ "" / [ space marks-list [ "" / [ space method [ "" / - space parameters ] ] ] ] ] ")" -group = quote quote -ralevel = rank / level -level = -rank = "(" level "." score ")" -score = -read = range -marks-lists = nil / "(" *marks ")" -marks = "(" range ")" -method = "(" *elisp-forms ")" -parameters = "(" *elisp-forms ")" -@end example - -Actually that @samp{marks} rule is a fib. A @samp{marks} is a -@samp{} consed on to a @samp{range}, but that's a bitch to say -in pseudo-BNF. - -If you have a Gnus info and want to access the elements, Gnus offers a -series of macros for getting/setting these elements. - -@table @code -@item gnus-info-group -@itemx gnus-info-set-group -@findex gnus-info-group -@findex gnus-info-set-group -Get/set the group name. - -@item gnus-info-rank -@itemx gnus-info-set-rank -@findex gnus-info-rank -@findex gnus-info-set-rank -Get/set the group rank (@pxref{Group Score}). - -@item gnus-info-level -@itemx gnus-info-set-level -@findex gnus-info-level -@findex gnus-info-set-level -Get/set the group level. - -@item gnus-info-score -@itemx gnus-info-set-score -@findex gnus-info-score -@findex gnus-info-set-score -Get/set the group score (@pxref{Group Score}). - -@item gnus-info-read -@itemx gnus-info-set-read -@findex gnus-info-read -@findex gnus-info-set-read -Get/set the ranges of read articles. - -@item gnus-info-marks -@itemx gnus-info-set-marks -@findex gnus-info-marks -@findex gnus-info-set-marks -Get/set the lists of ranges of marked articles. - -@item gnus-info-method -@itemx gnus-info-set-method -@findex gnus-info-method -@findex gnus-info-set-method -Get/set the group select method. - -@item gnus-info-params -@itemx gnus-info-set-params -@findex gnus-info-params -@findex gnus-info-set-params -Get/set the group parameters. -@end table - -All the getter functions take one parameter---the info list. The setter -functions take two parameters---the info list and the new value. - -The last three elements in the group info aren't mandatory, so it may be -necessary to extend the group info before setting the element. If this -is necessary, you can just pass on a non-@code{nil} third parameter to -the three final setter functions to have this happen automatically. - - -@node Extended Interactive -@subsection Extended Interactive -@cindex interactive -@findex gnus-interactive - -Gnus extends the standard Emacs @code{interactive} specification -slightly to allow easy use of the symbolic prefix (@pxref{Symbolic -Prefixes}). Here's an example of how this is used: - -@lisp -(defun gnus-summary-increase-score (&optional score symp) - (interactive (gnus-interactive "P\ny")) - ... - ) -@end lisp - -The best thing to do would have been to implement -@code{gnus-interactive} as a macro which would have returned an -@code{interactive} form, but this isn't possible since Emacs checks -whether a function is interactive or not by simply doing an @code{assq} -on the lambda form. So, instead we have @code{gnus-interactive} -function that takes a string and returns values that are usable to -@code{interactive}. - -This function accepts (almost) all normal @code{interactive} specs, but -adds a few more. - -@table @samp -@item y -@vindex gnus-current-prefix-symbol -The current symbolic prefix---the @code{gnus-current-prefix-symbol} -variable. - -@item Y -@vindex gnus-current-prefix-symbols -A list of the current symbolic prefixes---the -@code{gnus-current-prefix-symbol} variable. - -@item A -The current article number---the @code{gnus-summary-article-number} -function. - -@item H -The current article header---the @code{gnus-summary-article-header} -function. - -@item g -The current group name---the @code{gnus-group-group-name} -function. - -@end table - - -@node Emacs/XEmacs Code -@subsection Emacs/XEmacs Code -@cindex XEmacs -@cindex Emacsen - -While Gnus runs under Emacs, XEmacs and Mule, I decided that one of the -platforms must be the primary one. I chose Emacs. Not because I don't -like XEmacs or Mule, but because it comes first alphabetically. - -This means that Gnus will byte-compile under Emacs with nary a warning, -while XEmacs will pump out gigabytes of warnings while byte-compiling. -As I use byte-compilation warnings to help me root out trivial errors in -Gnus, that's very useful. - -I've also consistently used Emacs function interfaces, but have used -Gnusey aliases for the functions. To take an example: Emacs defines a -@code{run-at-time} function while XEmacs defines a @code{start-itimer} -function. I then define a function called @code{gnus-run-at-time} that -takes the same parameters as the Emacs @code{run-at-time}. When running -Gnus under Emacs, the former function is just an alias for the latter. -However, when running under XEmacs, the former is an alias for the -following function: - -@lisp -(defun gnus-xmas-run-at-time (time repeat function &rest args) - (start-itimer - "gnus-run-at-time" - `(lambda () - (,function ,@@args)) - time repeat)) -@end lisp - -This sort of thing has been done for bunches of functions. Gnus does -not redefine any native Emacs functions while running under XEmacs---it -does this @code{defalias} thing with Gnus equivalents instead. Cleaner -all over. - -In the cases where the XEmacs function interface was obviously cleaner, -I used it instead. For example @code{gnus-region-active-p} is an alias -for @code{region-active-p} in XEmacs, whereas in Emacs it is a function. - -Of course, I could have chosen XEmacs as my native platform and done -mapping functions the other way around. But I didn't. The performance -hit these indirections impose on Gnus under XEmacs should be slight. - - -@node Various File Formats -@subsection Various File Formats - -@menu -* Active File Format:: Information on articles and groups available. -* Newsgroups File Format:: Group descriptions. -@end menu - - -@node Active File Format -@subsubsection Active File Format - -The active file lists all groups available on the server in -question. It also lists the highest and lowest current article numbers -in each group. - -Here's an excerpt from a typical active file: - -@example -soc.motss 296030 293865 y -alt.binaries.pictures.fractals 3922 3913 n -comp.sources.unix 1605 1593 m -comp.binaries.ibm.pc 5097 5089 y -no.general 1000 900 y -@end example - -Here's a pseudo-BNF definition of this file: - -@example -active = *group-line -group-line = group space high-number space low-number space flag -group = -space = " " -high-number = -low-number = -flag = "y" / "n" / "m" / "j" / "x" / "=" group -@end example - -For a full description of this file, see the manual pages for -@samp{innd}, in particular @samp{active(5)}. - - -@node Newsgroups File Format -@subsubsection Newsgroups File Format - -The newsgroups file lists groups along with their descriptions. Not all -groups on the server have to be listed, and not all groups in the file -have to exist on the server. The file is meant purely as information to -the user. - -The format is quite simple; a group name, a tab, and the description. -Here's the definition: - -@example -newsgroups = *line -line = group tab description -group = -tab = -description = -@end example - - -@page -@node Emacs for Heathens -@section Emacs for Heathens - -Believe it or not, but some people who use Gnus haven't really used -Emacs much before they embarked on their journey on the Gnus Love Boat. -If you are one of those unfortunates whom ``@kbd{M-C-a}'', ``kill the -region'', and ``set @code{gnus-flargblossen} to an alist where the key -is a regexp that is used for matching on the group name'' are magical -phrases with little or no meaning, then this appendix is for you. If -you are already familiar with Emacs, just ignore this and go fondle your -cat instead. - -@menu -* Keystrokes:: Entering text and executing commands. -* Emacs Lisp:: The built-in Emacs programming language. -@end menu - - -@node Keystrokes -@subsection Keystrokes - -@itemize @bullet -@item -Q: What is an experienced Emacs user? - -@item -A: A person who wishes that the terminal had pedals. -@end itemize - -Yes, when you use Emacs, you are apt to use the control key, the shift -key and the meta key a lot. This is very annoying to some people -(notably @code{vi}le users), and the rest of us just love the hell out -of it. Just give up and submit. Emacs really does stand for -``Escape-Meta-Alt-Control-Shift'', and not ``Editing Macros'', as you -may have heard from other disreputable sources (like the Emacs author). - -The shift keys are normally located near your pinky fingers, and are -normally used to get capital letters and stuff. You probably use it all -the time. The control key is normally marked ``CTRL'' or something like -that. The meta key is, funnily enough, never marked as such on any -keyboard. The one I'm currently at has a key that's marked ``Alt'', -which is the meta key on this keyboard. It's usually located somewhere -to the left hand side of the keyboard, usually on the bottom row. - -Now, us Emacs people don't say ``press the meta-control-m key'', -because that's just too inconvenient. We say ``press the @kbd{M-C-m} -key''. @kbd{M-} is the prefix that means ``meta'' and ``C-'' is the -prefix that means ``control''. So ``press @kbd{C-k}'' means ``press -down the control key, and hold it down while you press @kbd{k}''. -``Press @kbd{M-C-k}'' means ``press down and hold down the meta key and -the control key and then press @kbd{k}''. Simple, ay? - -This is somewhat complicated by the fact that not all keyboards have a -meta key. In that case you can use the ``escape'' key. Then @kbd{M-k} -means ``press escape, release escape, press @kbd{k}''. That's much more -work than if you have a meta key, so if that's the case, I respectfully -suggest you get a real keyboard with a meta key. You can't live without -it. - - - -@node Emacs Lisp -@subsection Emacs Lisp - -Emacs is the King of Editors because it's really a Lisp interpreter. -Each and every key you tap runs some Emacs Lisp code snippet, and since -Emacs Lisp is an interpreted language, that means that you can configure -any key to run any arbitrary code. You just, like, do it. - -Gnus is written in Emacs Lisp, and is run as a bunch of interpreted -functions. (These are byte-compiled for speed, but it's still -interpreted.) If you decide that you don't like the way Gnus does -certain things, it's trivial to have it do something a different way. -(Well, at least if you know how to write Lisp code.) However, that's -beyond the scope of this manual, so we are simply going to talk about -some common constructs that you normally use in your @file{.emacs} file -to customize Gnus. - -If you want to set the variable @code{gnus-florgbnize} to four (4), you -write the following: - -@lisp -(setq gnus-florgbnize 4) -@end lisp - -This function (really ``special form'') @code{setq} is the one that can -set a variable to some value. This is really all you need to know. Now -you can go and fill your @code{.emacs} file with lots of these to change -how Gnus works. - -If you have put that thing in your @code{.emacs} file, it will be read -and @code{eval}ed (which is lisp-ese for ``run'') the next time you -start Emacs. If you want to change the variable right away, simply say -@kbd{C-x C-e} after the closing parenthesis. That will @code{eval} the -previous ``form'', which is a simple @code{setq} statement here. - -Go ahead---just try it, if you're located at your Emacs. After you -@kbd{C-x C-e}, you will see @samp{4} appear in the echo area, which -is the return value of the form you @code{eval}ed. - -Some pitfalls: - -If the manual says ``set @code{gnus-read-active-file} to @code{some}'', -that means: - -@lisp -(setq gnus-read-active-file 'some) -@end lisp - -On the other hand, if the manual says ``set @code{gnus-nntp-server} to -@samp{nntp.ifi.uio.no}'', that means: - -@lisp -(setq gnus-nntp-server "nntp.ifi.uio.no") -@end lisp - -So be careful not to mix up strings (the latter) with symbols (the -former). The manual is unambiguous, but it can be confusing. - -@page -@include gnus-faq.texi - -@node Index -@chapter Index -@printindex cp - -@node Key Index -@chapter Key Index -@printindex ky - -@summarycontents -@contents -@bye - -@iftex -@iflatex -\end{document} -@end iflatex -@end iftex - -@c End: - diff --git a/texi/gnuslogo.refcard b/texi/gnuslogo.refcard deleted file mode 100644 index aacf40e..0000000 --- a/texi/gnuslogo.refcard +++ /dev/null @@ -1,243 +0,0 @@ -%!PS-Adobe-2.0 EPSF-1.2 -%%Creator: Adobe Illustrator 88(TM) format generated by CorelTRACE Version 2.0C -%%Title: /home/menja/c/larsi/gnus.eps -%%BoundingBox: 0 0 924.5 907.2 -%%CreationDate: Tue Feb 20 01:51:37 1996 -%%DocumentFonts: -%%ColorUsage: B & W -%%TileBox: 0 0 924.5 907.2 -%%EndComments -%%BeginProcSet:Adobe_Illustrator_1.1 0 0 -% Copyright 1992 Corel Corporation. - -% All rights reserved. -.15 .15 scale - -/wPSMDict 150 dict def -wPSMDict begin -/bd {bind def} bind def -/ld {load def} bd -/xd {exch def} bd -/_ null def -/$c 0 def -/$m 0 def -/$y 0 def -/$k 0 def -/$t 1 def -/$n _ def -/$o 0 def -/$C 0 def -/$M 0 def -/$Y 0 def -/$K 0 def -/$T 1 def -/$N _ def -/$O 0 def -/$h false def -/$al 0 def -/$tr 0 def -/$le 0 def -/$lx 0 def -/$ly 0 def -/$ctm matrix currentmatrix def -/@cp /closepath ld -/@gs /gsave ld -/@gr /grestore ld -/@MN {2 copy le{pop}{exch pop}ifelse}bd -/setcmykcolor where {pop}{/setcmykcolor{4 1 roll -3 {3 index add 1 @MN 1 exch sub 3 1 roll} repeat -setrgbcolor -pop}bd}ifelse -/@tc{dup 1 ge{pop}{4 {dup -6 -1 roll -mul -exch}repeat -pop}ifelse}bd -/@scc{$c $m $y $k $t @tc setcmykcolor true}bd -/@SCC{$C $M $Y $K $T @tc setcmykcolor true}bd -/@sm{/$ctm $ctm currentmatrix def}bd -/x {/$t xd /$n xd -/$k xd /$y xd /$m xd /$c xd}bd -/X {/$T xd /$N xd -/$K xd /$Y xd /$M xd /$C xd}bd -/g {1 exch sub 0 0 0 -4 -1 roll -_ 1 x}bd -/G {1 exch sub 0 0 0 -4 -1 roll -_ 1 X}bd -/k {_ 1 x}bd -/K {_ 1 X}bd -/d /setdash ld -/i {dup 0 ne {setflat} {pop} ifelse}bd -/j /setlinejoin ld -/J /setlinecap ld -/M /setmiterlimit ld -/w /setlinewidth ld -/O {/$o xd}bd -/R {/$O xd}bd -/c /curveto ld -/C /c ld -/l /lineto ld -/L /l ld -/m /moveto ld -/n /newpath ld -/N /newpath ld -/F {@scc{eofill}if n} bd -/f {@cp F}bd -/S {@SCC{stroke}if n} bd -/s {@cp -S}bd -/B {@gs F @gr -S}bd -/b {@cp B }bd -/u {}bd -/U {}bd -%%EndProlog -%%BeginSetup -%%EndSetup -1 i -2 J -0 j -4 M -[]0 d - -%%Note: traced as Normal_Outline -0 g -259.2 78.2 m -327.3 178.5 L -327.8 179.0 328.3 180.0 329.7 180.4 C -373.4 241.9 L -388.8 263.5 L -389.2 264.0 390.7 264.4 391.6 265.4 C -413.7 298.0 453.6 351.8 468.0 404.6 C -467.5 405.6 467.5 407.0 467.5 407.0 C -442.0 367.6 411.3 319.2 379.2 279.3 C -372.0 267.3 366.7 265.9 361.9 254.8 C -333.1 216.0 L -323.5 207.3 311.0 185.2 302.8 175.6 C -298.0 165.6 293.2 164.1 288.9 154.0 C -282.2 147.8 282.2 139.6 276.4 132.4 C -258.2 77.7 L -258.2 77.7 259.2 78.2 259.2 78.2 C -f -0 g -470.8 211.6 m -470.8 211.6 472.3 212.1 472.3 212.1 C -518.8 305.2 L -531.3 317.2 L -537.6 314.8 539.0 300.9 548.6 301.9 C -555.8 301.9 554.8 302.8 561.6 306.2 C -595.2 357.1 L -595.6 358.0 597.6 358.5 598.5 360.0 C -615.8 398.4 650.8 450.7 657.6 483.8 C -658.0 486.2 658.0 488.1 658.0 489.6 C -654.2 489.1 656.1 485.2 650.4 479.5 C -634.5 446.8 611.5 402.2 592.8 377.2 C -588.0 370.0 581.7 365.7 577.4 358.5 C -570.2 355.6 568.3 351.3 560.1 356.6 C -554.8 360.0 553.9 364.8 550.0 370.0 C -548.1 371.5 550.0 370.5 547.2 371.0 C -541.4 365.2 L -511.2 319.6 484.3 276.0 471.8 220.3 C -470.8 215.5 471.3 215.5 469.4 212.1 C -469.4 212.1 470.8 211.6 470.8 211.6 C -f -0 g -731.0 292.8 m -756.0 351.3 751.6 407.0 771.3 468.0 C -783.3 520.8 809.7 582.2 822.2 635.0 C -829.4 684.4 855.8 732.0 825.1 789.1 C -811.6 797.7 799.6 805.4 784.8 802.0 C -757.9 792.0 732.9 743.0 726.2 712.8 C -727.6 708.4 727.2 707.0 730.0 704.6 C -731.0 704.1 732.9 704.1 734.4 704.6 C -737.2 709.9 L -754.0 747.3 L -758.8 755.0 771.8 754.0 781.9 751.2 C -788.1 748.3 791.5 745.9 797.7 744.0 C -831.8 680.1 800.6 611.0 784.3 542.8 C -765.6 478.5 748.3 431.5 739.2 370.5 C -733.9 347.5 729.1 318.7 730.0 292.8 C -730.0 292.8 731.0 292.8 731.0 292.8 C -f -0 g -434.4 462.7 m -460.3 496.8 462.2 532.8 458.4 575.5 C -456.4 588.0 451.2 599.0 445.4 609.1 C -435.3 620.1 435.3 622.5 421.9 630.7 C -411.8 619.6 398.4 604.8 391.6 586.0 C -393.6 581.7 396.4 584.1 401.7 577.9 C -403.2 577.4 404.6 576.9 404.6 576.9 C -407.0 574.5 406.0 573.6 410.4 571.2 C -414.2 564.0 418.5 558.2 424.3 545.7 C -437.2 526.5 428.1 489.6 433.9 462.2 C -433.9 462.2 434.4 462.7 434.4 462.7 C -f -0 g -226.0 482.4 m -281.7 485.7 311.0 531.3 357.1 565.9 C -362.8 572.1 364.8 574.0 368.6 580.3 C -368.6 581.7 369.1 582.7 369.6 584.6 C -370.0 585.6 371.5 587.0 372.9 588.0 C -381.6 606.2 L -377.2 605.2 374.8 602.8 371.0 597.6 C -346.0 576.4 316.8 552.0 289.9 536.1 C -288.9 535.2 288.0 534.2 288.0 534.2 C -273.6 528.0 263.5 527.5 247.6 530.8 C -242.4 535.2 239.0 536.1 238.0 544.3 C -239.5 572.1 266.8 600.0 281.2 624.9 C -293.7 637.9 300.4 650.4 311.5 668.1 C -312.0 669.1 313.9 669.6 314.8 671.0 C -319.6 679.6 L -319.6 680.1 319.6 681.6 319.2 682.0 C -285.6 649.4 258.7 601.4 229.9 555.8 C -216.4 529.9 205.4 511.2 210.2 491.0 C -212.6 483.8 218.8 484.8 226.0 482.4 C -f -0 g -624.9 600.4 m -645.1 606.2 L -676.3 622.5 694.5 658.0 710.8 698.4 C -710.4 704.1 711.3 704.6 712.3 709.4 C -696.9 685.9 693.6 667.6 662.4 653.7 C -654.7 651.3 649.4 650.4 639.3 650.8 C -633.1 654.2 625.4 659.0 621.6 670.5 C -597.6 620.6 L -600.9 612.4 604.3 607.2 613.4 603.8 C -617.2 603.3 621.1 601.4 624.9 600.4 C -f -0 g -528.4 619.2 m -548.6 617.2 564.9 629.2 578.8 645.6 C -584.1 651.8 586.5 662.8 591.8 671.0 C -593.2 681.6 603.8 690.2 601.9 704.1 C -598.5 705.1 599.0 698.8 594.7 694.0 C -581.7 679.6 L -569.7 668.6 545.7 663.8 532.8 673.9 C -487.2 697.9 467.5 754.5 413.2 772.8 C -393.1 778.0 387.3 771.8 367.2 760.3 C -360.9 755.5 357.6 744.9 351.3 740.6 C -347.0 740.6 349.9 743.5 344.6 747.3 C -344.1 748.8 343.6 750.2 343.6 750.2 C -322.5 770.8 L -312.9 775.2 300.9 784.3 287.0 779.0 C -283.6 777.1 281.7 776.1 279.3 775.2 C -250.0 750.7 229.4 705.6 181.4 697.4 C -165.6 705.1 160.3 715.2 150.7 733.9 C -130.5 685.4 L -142.5 663.3 L -147.3 661.9 147.3 660.4 151.2 655.6 C -160.8 650.4 169.9 649.4 182.8 655.2 C -212.1 676.8 L -213.1 677.7 214.0 678.7 216.0 679.2 C -238.5 695.5 250.5 727.6 279.3 735.3 C -296.1 727.2 312.4 715.6 326.8 695.5 C -330.2 688.3 331.6 684.9 335.5 681.1 C -345.1 694.5 352.8 717.6 372.9 721.9 C -423.3 726.7 453.6 670.5 498.2 631.6 C -510.7 624.4 517.4 621.1 528.4 619.2 C -f -%%Trailer -end -showpage diff --git a/texi/gnusref.tex b/texi/gnusref.tex deleted file mode 100644 index da186fe..0000000 --- a/texi/gnusref.tex +++ /dev/null @@ -1,687 +0,0 @@ -% include file for the Gnus refcard and booklet -\def\progver{5.0}\def\refver{5.0} % program and refcard versions -\def\date{16 September 1995} -\def\author{Vladimir Alexiev $<$vladimir@cs.ualberta.ca$>$} -\raggedbottom\raggedright -\newlength{\logowidth}\setlength{\logowidth}{6.861in} -\newlength{\logoheight}\setlength{\logoheight}{7.013in} -\newlength{\keycolwidth} -\newenvironment{keys}[1]% #1 is the widest key - {\nopagebreak%\noindent% - \settowidth{\keycolwidth}{#1}% - \addtolength{\keycolwidth}{\tabcolsep}% - \addtolength{\keycolwidth}{-\columnwidth}% - \begin{tabular}{@{}l@{\hspace{\tabcolsep}}p{-\keycolwidth}@{}}}% - {\end{tabular}\\} -\catcode`\^=12 % allow ^ to be typed literally -\newcommand{\B}[1]{{\bf#1})} % bold l)etter - -\def\Title{ -\begin{center} -{\bf\LARGE Gnus \progver\ Reference \Guide\\} -%{\normalsize \Guide\ version \refver} -\end{center} -} - -\newcommand\Logo[1]{\centerline{ -\makebox[\logoscale\logowidth][l]{\vbox to \logoscale\logoheight -{\vfill\special{psfile=gnuslogo.#1}}\vspace{-\baselineskip}}}} - -\def\CopyRight{ -\begin{center} -Copyright \copyright\ 1995 Free Software Foundation, Inc.\\* -Copyright \copyright\ 1995 \author.\\* -Created from the Gnus manual Copyright \copyright\ 1994 Lars Magne -Ingebrigtsen.\\* -and the Emacs Help Bindings feature (C-h b).\\* -Gnus logo copyright \copyright\ 1995 Luis Fernandes.\\* -\end{center} - -Permission is granted to make and distribute copies of this reference -\guide{} provided the copyright notice and this permission are preserved on -all copies. Please send corrections, additions and suggestions to the -above email address. \Guide{} last edited on \date. -} - -\def\Notes{ -\subsec{Notes} -{\samepage -Gnus is complex. Currently it has some 346 interactive (user-callable) -functions. Of these 279 are in the two major modes (Group and -Summary/Article). Many of these functions have more than one binding, some -have 3 or even 4 bindings. The total number of keybindings is 389. So in -order to save 40\% space, every function is listed only once on this -\guide, under the ``more logical'' binding. Alternative bindings are given -in parentheses in the beginning of the description. - -Many Gnus commands are affected by the numeric prefix. Normally you enter a -prefix by holding the Meta key and typing a number, but in most Gnus modes -you don't need to use Meta since the digits are not self-inserting. The -prefixed behavior of commands is given in [brackets]. Often the prefix is -used to specify: - -\quad [distance] How many objects to move the point over. - -\quad [scope] How many objects to operate on (including the current one). - -\quad [p/p] The ``Process/Prefix Convention'': If a prefix is given then it -determines how many objects to operate on. Else if there are some objects -marked with the process mark \#, these are operated on. Else only the -current object is affected. - -\quad [level] A group subscribedness level. Only groups with a lower or -equal level will be affected by the operation. If no prefix is given, -`gnus-group-default-list-level' is used. If -`gnus-group-use-permanent-levels', then a prefix to the `g' and `l' -commands will also set the default level. - -\quad [score] An article score. If no prefix is given, -`gnus-summary-default-score' is used. -%Some functions were not yet documented at the time of creating this -%\guide and are clearly indicated as such. -\\*[\baselineskip] -\begin{keys}{C-c C-i} -C-c C-i & Go to the Gnus online {\bf info}.\\ -C-c C-b & Send a Gnus {\bf bug} report.\\ -\end{keys} -}} - -\def\GroupLevels{ -\subsec{Group Subscribedness Levels} -The table below assumes that you use the default Gnus levels. -Fill your user-specific levels in the blank cells.\\[1\baselineskip] - -\begin{tabular}{|c|l|l|} -\hline -Level & Groups & Status \\ -\hline -1 & mail groups & \\ -2 & mail groups & \\ -3 & & subscribed \\ -4 & & \\ -5 & default list level & \\ -\hline -6 & & unsubscribed \\ -7 & & \\ -\hline -8 & & zombies \\ -\hline -9 & & killed \\ -\hline -\end{tabular} -} - -\def\Marks{ -\subsec{Mark Indication Characters} -{\samepage If a command directly sets a mark, it is shown in parentheses.\\* -\newlength{\markcolwidth} -\settowidth{\markcolwidth}{` '}% widest character -\addtolength{\markcolwidth}{4\tabcolsep} -\addtolength{\markcolwidth}{-\columnwidth} -\newlength{\markdblcolwidth} -\setlength{\markdblcolwidth}{\columnwidth} -\addtolength{\markdblcolwidth}{-2\tabcolsep} -\begin{tabular}{|c|p{-\markcolwidth}|} -\hline -\multicolumn{2}{|p{\markdblcolwidth}|}{{\bf ``Read'' Marks.} - All these marks appear in the first column of the summary line, and so - are mutually exclusive.}\\ -\hline -` ' & (M-u, M SPC, M c) Not read.\\ -! & (!, M !, M t) Ticked (interesting).\\ -? & (?, M ?) Dormant (only followups are interesting).\\ -C & (C, S c) {\bf Canceled} (only for your own articles).\\ -E & (E, M e, M x) {\bf Expirable}. Only has effect in mail groups.\\ -\hline\hline -\multicolumn{2}{|p{\markdblcolwidth}|}{The marks below mean that the article - is read (killed, uninteresting), and have more or less the same effect. - Some commands however explicitly differentiate between them (e.g.\ M - M-C-r, adaptive scoring).}\\ -\hline -r & (d, M d, M r) Deleted (marked as {\bf read}).\\ -C & (M C; M C-c; M H; c, Z c; Z n; Z C) Killed by {\bf catch-up}.\\ -O & {\bf Old} (marked read in a previous session).\\ -K & (k, M k; C-k, M K) {\bf Killed}.\\ -R & {\bf Read} (viewed in actuality).\\ -X & Killed by a kill file.\\ -Y & Killed due to low score.\\ -\hline\multicolumn{2}{c}{\vspace{1ex}}\\\hline -\multicolumn{2}{|p{\markdblcolwidth}|}{{\bf Other marks}}\\ -\hline -\# & (\#, M \#, M P p) Processable (will be affected by the next operation).\\ -A & {\bf Answered} (followed-up or replied).\\ -+ & Over default score.\\ -$-$ & Under default score.\\ -= & Has children (thread underneath it). Add `\%e' to - `gnus-summary-line-format'.\\ -\hline -\end{tabular} -}} - -\def\GroupMode{ -\sec{Group Mode} -\begin{keys}{C-c M-C-x} -RET & (=) Select this group. [Prefix: how many (read) articles to fetch. -Positive: newest articles, negative: oldest ones.]\\ -SPC & Select this group and display the first unread article. [Same -prefix as above.]\\ -? & Give a very short help message.\\ -$<$ & Go to the beginning of the Group buffer.\\ -$>$ & Go to the end of the Group buffer.\\ -, & Jump to the lowest-level group with unread articles.\\ -. & Jump to the first group with unread articles.\\ -^ & Enter the Server buffer mode.\\ -a & Post an {\bf article} to a group.\\ -b & Find {\bf bogus} groups and delete them.\\ -c & Mark all unticked articles in this group as read ({\bf catch-up}). -[p/p]\\ -g & Check the server for new articles ({\bf get}). [level]\\ -j & {\bf Jump} to a group.\\ -m & {\bf Mail} a message to someone.\\ -n & Go to the {\bf next} group with unread articles. [distance]\\ -p & (DEL) Go to the {\bf previous} group with unread articles. -[distance]\\ -q & {\bf Quit} Gnus.\\ -r & Read the init file ({\bf reset}).\\ -s & {\bf Save} the `.newsrc.eld' file (and `.newsrc' if -`gnus-save-newsrc-file').\\ -z & Suspend (kill all buffers of) Gnus.\\ -B & {\bf Browse} a foreign server.\\ -C & Mark all articles in this group as read ({\bf Catch-up}). [p/p]\\ -F & {\bf Find} new groups and process them.\\ -N & Go to the {\bf next} group. [distance]\\ -P & Go to the {\bf previous} group. [distance]\\ -Q & {\bf Quit} Gnus without saving any startup (.newsrc) files.\\ -R & {\bf Restart} Gnus.\\ -V & Display the Gnus {\bf version} number.\\ -Z & Clear the dribble buffer.\\ -C-c C-d & Show the {\bf description} of this group. [Prefix: re-read it -from the server.]\\ -C-c C-s & {\bf Sort} the groups by name, number of unread articles, or level -(depending on `gnus-group-sort-function').\\ -C-c C-x & Run all expirable articles in this group through the {\bf expiry} -process.\\ -C-c M-C-x & Run all articles in all groups through the {\bf expiry} process.\\ -C-x C-t & {\bf Transpose} two groups.\\ -M-d & {\bf Describe} ALL groups. [Prefix: re-read the description from the -server.]\\ -M-f & Fetch this group's {\bf FAQ} (using ange-ftp).\\ -M-g & Check the server for new articles in this group ({\bf get}). [p/p]\\ -M-n & Go to the {\bf previous} unread group on the same or lower level. -[distance]\\ -M-p & Go to the {\bf next} unread group on the same or lower level. -[distance]\\ -\end{keys} -} - -\def\GroupCommands{ -\subsec{List Groups} -{\samepage -\begin{keys}{A m} -A a & (C-c C-a) List all groups whose names match a regexp ({\bf -apropos}).\\ -A d & List all groups whose names or {\bf descriptions} match a regexp.\\ -A k & (C-c C-l) List all {\bf killed} groups.\\ -A m & List groups that {\bf match} a regexp and have unread articles. -[level]\\ -A s & (l) List {\bf subscribed} groups with unread articles. [level]\\ -A u & (L) List all groups (including {\bf unsubscribed}). [If no prefix -is given, level 7 is the default]\\ -A z & List the {\bf zombie} groups.\\ -A M & List groups that {\bf match} a regexp.\\ -\end{keys} -} - -\subsec{Create/Edit Foreign Groups} -{\samepage -The select methods are indicated in parentheses.\\* -\begin{keys}{G m} -G a & Make the Gnus list {\bf archive} group. (nndir over ange-ftp)\\ -G d & Make a {\bf directory} group (every file must be a posting and files -must have numeric names). (nndir)\\ -G e & (M-e) {\bf Edit} this group's select method.\\ -G f & Make a group based on a {\bf file}. (nndoc)\\ -G h & Make the Gnus {\bf help} (documentation) group. (nndoc)\\ -G k & Make a {\bf kiboze} group. (nnkiboze)\\ -G m & {\bf Make} a new group.\\ -G p & Edit this group's {\bf parameters}.\\ -G v & Add this group to a {\bf virtual} group. [p/p]\\ -G D & Enter a {\bf directory} as a (temporary) group. (nneething without -recording articles read.)\\ -G E & {\bf Edit} this group's info (select method, articles read, etc).\\ -G V & Make a new empty {\bf virtual} group. (nnvirtual)\\ -\end{keys} -You can also create mail-groups and read your mail with Gnus (very useful -if you are subscribed to any mailing lists), using one of the methods -nnmbox, nnbabyl, nnml, nnmh, or nnfolder. Read about it in the online info -(C-c C-i g Reading Mail RET). -} - -%\subsubsec{Soup Commands} -%\begin{keys}{G s w} -%G s b & gnus-group-brew-soup: not documented.\\ -%G s p & gnus-soup-pack-packet: not documented.\\ -%G s r & nnsoup-pack-replies: not documented.\\ -%G s s & gnus-soup-send-replies: not documented.\\ -%G s w & gnus-soup-save-areas: not documented.\\ -%\end{keys} - -\subsec{Mark Groups} -\begin{keys}{M m} -M m & (\#) Set the process {\bf mark} on this group. [scope]\\ -M u & (M-\#) Remove the process mark from this group ({\bf unmark}). -[scope]\\ -M w & Mark all groups in the current region.\\ -\end{keys} - -\subsec{Unsubscribe, Kill and Yank Groups} -\begin{keys}{S w} -S k & (C-k) {\bf Kill} this group.\\ -S l & Set the {\bf level} of this group. [p/p]\\ -S s & (U) Prompt for a group and toggle its {\bf subscription}.\\ -S t & (u) {\bf Toggle} subscription to this group. [p/p]\\ -S w & (C-w) Kill all groups in the region.\\ -S y & (C-y) {\bf Yank} the last killed group.\\ -S z & Kill all {\bf zombie} groups.\\ -\end{keys} -} - -\def\SummaryMode{ -\sec{Summary Mode} %{Summary and Article Modes} -\begin{keys}{SPC} -SPC & (A SPC, A n) Select an article, scroll it one page, move to the -next one.\\ -DEL & (A DEL, A p, b) Scroll this article one page back. [distance]\\ -RET & Scroll this article one line forward. [distance]\\ -= & Expand the Summary window. [Prefix: shrink it to display the -Article window]\\ -$<$ & (A $<$, A b) Scroll to the beginning of this article.\\ -$>$ & (A $>$, A e) Scroll to the end of this article.\\ -\& & Execute a command on all articles matching a regexp. -[Prefix: move backwards.]\\ -j & (G g) Ask for an article number and then {\bf jump} to that summary -line.\\ -C-t & Toggle {\bf truncation} of summary lines.\\ -M-\& & Execute a command on all articles having the process mark.\\ -M-k & Edit this group's {\bf kill} file.\\ -M-n & (G M-n) Go to the {\bf next} summary line of an unread article. -[distance]\\ -M-p & (G M-p) Go to the {\bf previous} summary line of an unread article. -[distance]\\ -M-r & Search through all previous articles for a regexp.\\ -M-s & {\bf Search} through all subsequent articles for a regexp.\\ -M-K & Edit the general {\bf kill} file.\\ -\end{keys} -} - -\def\SortSummary{ -\subsec{Sort the Summary Buffer} -\begin{keys}{C-c C-s C-a} -C-c C-s C-a & Sort the summary by {\bf author}.\\ -C-c C-s C-d & Sort the summary by {\bf date}.\\ -C-c C-s C-i & Sort the summary by article score.\\ -C-c C-s C-n & Sort the summary by article {\bf number}.\\ -C-c C-s C-s & Sort the summary by {\bf subject}.\\ -\end{keys} -} - -\def\Asubmap{ -\subsec{Article Buffer Commands} -\begin{keys}{A m} -A g & (g) (Re)fetch this article ({\bf get}). [Prefix: just show the -article.]\\ -A r & (^, A ^) Go to the parent of this article (the {\bf References} -header).\\ -M-^ & Fetch the article with a given Message-ID.\\ -A s & (s) Perform an i{\bf search} in the article buffer.\\ -A D & (C-d) Un{\bf digestify} this article into a separate group.\\ -\end{keys} -} - -\def\Bsubmap{ -\subsec{Mail-Group Commands} -{\samepage -These commands (except `B c') are only valid in a mail group.\\* -\begin{keys}{B M-C-e} -B DEL & {\bf Delete} the mail article from disk (!). [p/p]\\ -B c & {\bf Copy} this article from any group to a mail group. [p/p]\\ -B e & {\bf Expire} all expirable articles in this group. [p/p]\\ -B i & {\bf Import} a random file into this group.\\ -B m & {\bf Move} the article from one mail group to another. [p/p]\\ -B q & {\bf Query} where will the article go during fancy splitting\\ -B r & {\bf Respool} this mail article. [p/p]\\ -B w & (e) Edit this article.\\ -B M-C-e & {\bf Expunge} (delete from disk) all expirable articles in this group -(!). [p/p]\\ -\end{keys} -}} - -\def\Gsubmap{ -\subsec{Select Articles} -{\samepage -These commands select the target article. They do not understand the prefix.\\* -\begin{keys}{G C-n} -G b & (,) Go to the {\bf best} article (the one with highest score).\\ -G f & (.) Go to the {\bf first} unread article.\\ -G l & (l) Go to the {\bf last} article read.\\ -G n & (n) Go to the {\bf next} unread article.\\ -p & Go to the {\bf previous} unread article.\\ -G p & {\bf Pop} an article off the summary history and go to it.\\ -G N & (N) Go to {\bf the} next article.\\ -G P & (P) Go to the {\bf previous} article.\\ -G C-n & (M-C-n) Go to the {\bf next} article with the same subject.\\ -G C-p & (M-C-p) Go to the {\bf previous} article with the same subject.\\ -\end{keys} -}} - -\def\Hsubmap{ -\subsec{Help Commands} -\begin{keys}{H d} -H d & (C-c C-d) {\bf Describe} this group. [Prefix: re-read the description -from the server.]\\ -H f & Try to fetch the {\bf FAQ} for this group using ange-ftp.\\ -H h & Give a very short {\bf help} message.\\ -H i & (C-c C-i) Go to the Gnus online {\bf info}.\\ -H v & Display the Gnus {\bf version} number.\\ -\end{keys} -} - -\def\Msubmap{ -\subsec{Mark Articles} -\begin{keys}{M M-C-r} -d & (M d, M r) Mark this article as read and move to the next one. -[scope]\\ -D & Mark this article as read and move to the previous one. [scope]\\ -u & (!, M !, M t) Tick this article (mark it as interesting) and move -to the next one. [scope]\\ -U & Tick this article and move to the previous one. [scope]\\ -M-u & (M SPC, M c) Clear all marks from this article and move to the next -one. [scope]\\ -M-U & Clear all marks from this article and move to the previous one. -[scope]\\ -M ? & (?) Mark this article as dormant (only followups are -interesting). [scope]\\ -M b & Set a {\bf bookmark} in this article.\\ -M e & (E, M x) Mark this article as {\bf expirable}. [scope]\\ -M k & (k) {\bf Kill} all articles with the same subject then select the -next one.\\ -M B & Remove the {\bf bookmark} from this article.\\ -M C & {\bf Catch-up} the articles that are not ticked.\\ -M D & Show all {\bf dormant} articles (normally they are hidden unless they -have any followups).\\ -M H & Catch-up (mark read) this group to point ({\bf here}).\\ -M K & (C-k) {\bf Kill} all articles with the same subject as this one.\\ -C-w & Mark all articles between point and mark as read.\\ -M S & (C-c M-C-s) {\bf Show} all expunged articles.\\ -M C-c & {\bf Catch-up} all articles in this group.\\ -M M-r & (x) Expunge all {\bf read} articles from this group.\\ -M M-D & Hide all {\bf dormant} articles.\\ -M M-C-r & Expunge all articles having a given mark.\\ -\end{keys} - -\subsubsec{Mark Based on Score} -\begin{keys}{M s m} -M V c & {\bf Clear} all marks from all high-scored articles. [score]\\ -M V k & {\bf Kill} all low-scored articles. [score]\\ -M V m & Mark all high-scored articles with a given {\bf mark}. [score]\\ -M V u & Mark all high-scored articles as interesting (tick them). [score]\\ -\end{keys} - -\subsubsec{The Process Mark} -{\samepage -These commands set and remove the process mark \#. You only need to use -it if the set of articles you want to operate on is non-contiguous. Else -use a numeric prefix.\\* -\begin{keys}{M P R} -M P a & Mark {\bf all} articles (in series order).\\ -M P p & (\#, M \#) Mark this article.\\ -M P r & Mark all articles in the {\bf region}.\\ -M P s & Mark all articles in the current {\bf series}.\\ -M P t & Mark all articles in this (sub){\bf thread}.\\ -M P u & (M-\#, M M-\#) {\bf Unmark} this article.\\ -M P R & Mark all articles matching a {\bf regexp}.\\ -M P S & Mark all {\bf series} that already contain a marked article.\\ -M P U & {\bf Unmark} all articles.\\ -\end{keys} -}} - -\def\Osubmap{ -\subsec{Output Articles} -\begin{keys}{O m} -O f & Save this article in plain {\bf file} format. [p/p]\\ -O h & Save this article in {\bf mh} folder format. [p/p]\\ -O m & Save this article in {\bf mail} format. [p/p]\\ -O o & (o, C-o) Save this article using the default article saver. [p/p]\\ -O p & ($\mid$) Pipe this article to a shell command. [p/p]\\ -O r & Save this article in {\bf rmail} format. [p/p]\\ -O v & Save this article in {\bf vm} format. [p/p]\\ -\end{keys} -} - -\def\Ssubmap{ -\subsec{Post, Followup, Reply, Forward, Cancel} -{\samepage -These commands put you in a separate post or mail buffer. After -editing the article, send it by pressing C-c C-c. If you are in a -foreign group and want to post the article using the foreign server, give -a prefix to C-c C-c.\\* -\begin{keys}{S O m} -S b & {\bf Both} post a followup to this article, and send a reply.\\ -S c & (C) {\bf Cancel} this article (only works if it is your own).\\ -S f & (f) Post a {\bf followup} to this article.\\ -S m & (m) Send {\bf a} mail to some other person.\\ -S o m & (C-c C-f) Forward this article by {\bf mail} to a person.\\ -S o p & Forward this article as a {\bf post} to a newsgroup.\\ -S p & (a) {\bf Post} an article to this group.\\ -S r & (r) Mail a {\bf reply} to the author of this article.\\ -S s & {\bf Supersede} this article with a new one (only for own -articles).\\ -S u & {\bf Uuencode} a file and post it as a series.\\ -S B & {\bf Both} post a followup, send a reply, and include the -original. [p/p]\\ -S F & (F) Post a {\bf followup} and include the original. [p/p]\\ -S O m & Digest these series and forward by {\bf mail}. [p/p]\\ -S O p & Digest these series and forward as a {\bf post} to a newsgroup. -[p/p]\\ -S R & (R) Mail a {\bf reply} and include the original. [p/p]\\ -\end{keys} -If you want to cancel or supersede an article you just posted (before it -has appeared on the server), go to the *post-news* buffer, change -`Message-ID' to `Cancel' or `Supersedes' and send it again with C-c C-c. -}} - -\def\Tsubmap{ -\subsec{Thread Commands} -\begin{keys}{T \#} -T \# & Mark this thread with the process mark.\\ -T d & Move to the next article in this thread ({\bf down}). [distance]\\ -T h & {\bf Hide} this (sub)thread.\\ -T i & {\bf Increase} the score of this thread.\\ -T k & (M-C-k) {\bf Kill} the current (sub)thread. [Negative prefix: -tick it, positive prefix: unmark it.]\\ -T l & (M-C-l) {\bf Lower} the score of this thread.\\ -T n & (M-C-f) Go to the {\bf next} thread. [distance]\\ -T p & (M-C-b) Go to the {\bf previous} thread. [distance]\\ -T s & {\bf Show} the thread hidden under this article.\\ -T u & Move to the previous article in this thread ({\bf up}). [distance]\\ -T H & {\bf Hide} all threads.\\ -T S & {\bf Show} all hidden threads.\\ -T T & (M-C-t) {\bf Toggle} threading.\\ -\end{keys} -} - -\def\Vsubmap{ -\subsec{Score (Value) Commands} -{\samepage -Read about Adaptive Scoring in the online info.\\* -\begin{keys}{\bf A p m l} -V a & {\bf Add} a new score entry, specifying all elements.\\ -V c & Specify a new score file as {\bf current}.\\ -V e & {\bf Edit} the current score alist.\\ -V f & Edit a score {\bf file} and make it the current one.\\ -V m & {\bf Mark} all articles below a given score as read.\\ -V s & Set the {\bf score} of this article.\\ -V t & Display all score rules applied to this article ({\bf track}).\\ -V x & {\bf Expunge} all low-scored articles. [score]\\ -V C & {\bf Customize} the current score file through a user-friendly -interface.\\ -V S & Display the {\bf score} of this article.\\ -\bf A p m l& Make a scoring entry based on this article.\\ -\end{keys} - -The four letters stand for:\\* -\quad \B{A}ction: I)ncrease, L)ower;\\* -\quad \B{p}art: a)utor (from), s)ubject, x)refs (cross-posting), d)ate, l)ines, -message-i)d, t)references (parent), f)ollowup, b)ody, h)ead (all headers);\\* -\quad \B{m}atch type:\\* -\qquad string: s)ubstring, e)xact, r)egexp, f)uzzy,\\* -\qquad date: b)efore, a)t, n)this,\\* -\qquad number: $<$, =, $>$;\\* -\quad \B{l}ifetime: t)emporary, p)ermanent, i)mmediate. - -If you type the second letter in uppercase, the remaining two are assumed -to be s)ubstring and t)emporary. -If you type the third letter in uppercase, the last one is assumed to be -t)emporary. - -\quad Extra keys for manual editing of a score file:\\* -\begin{keys}{C-c C-c} -C-c C-c & Finish editing the score file.\\ -C-c C-d & Insert the current {\bf date} as number of days.\\ -\end{keys} -}} - -\def\Wsubmap{ -\subsec{Wash the Article Buffer} -\begin{keys}{W C-c} -W b & Make Message-IDs and URLs in the article to mouse-clickable {\bf - buttons}.\\ -W c & Remove extra {\bf CRs} (^M) from the article.\\ -W f & Look for and display any X-{\bf Face} headers.\\ -W l & (w) Remove page breaks ({\bf^L}) from the article.\\ -W m & Toggle {\bf MIME} processing.\\ -W o & Treat {\bf overstrike} or underline (^H\_) in the article.\\ -W q & Treat {\bf quoted}-printable in the article.\\ -W r & (C-c C-r) Do a Caesar {\bf rotate} (rot13) on the article.\\ -W t & (t) {\bf Toggle} the displaying of all headers.\\ -v & Toggle permanent {\bf verbose} displaying of all headers.\\ -W w & Do word {\bf wrap} in the article.\\ -W T e & Convert the article timestamp to time {\bf elapsed} since sent.\\ -W T l & Convert the article timestamp to the {\bf local} timezone.\\ -W T u & (W T z) Convert the article timestamp to {\bf UTC} ({\bf Zulu}, -GMT).\\ -\end{keys} - -\subsubsec{Hide/Highlight Parts of the Article} -\begin{keys}{W W C-c} -W W a & Hide {\bf all} unwanted parts. Calls W W h, W W s, W W C-c.\\ -W W c & Hide article {\bf citation}.\\ -W W h & Hide article {\bf headers}.\\ -W W s & Hide article {\bf signature}.\\ -W W C-c & Hide article {\bf citation} using a more intelligent algorithm.\\ -%\end{keys} -% -%\subsubsec{Highlight Parts of the Article} -%\begin{keys}{W H A} -W H a & Highlight {\bf all} parts. Calls W b, W H c, W H h, W H s.\\ -W H c & Highlight article {\bf citation}.\\ -W H h & Highlight article {\bf headers}.\\ -W H s & Highlight article {\bf signature}.\\ -\end{keys} -} - -\def\Xsubmap{ -\subsec{Extract Series (Uudecode etc)} -{\samepage -Gnus recognizes if the current article is part of a series (multipart -posting whose parts are identified by numbers in their subjects, e.g.{} -1/10\dots10/10) and processes the series accordingly. You can mark and -process more than one series at a time. If the posting contains any -archives, they are expanded and gathered in a new group.\\* -\begin{keys}{X p} -X b & Un-{\bf binhex} these series. [p/p]\\ -X o & Simply {\bf output} these series (no decoding). [p/p]\\ -X p & Unpack these {\bf postscript} series. [p/p]\\ -X s & Un-{\bf shar} these series. [p/p]\\ -X u & {\bf Uudecode} these series. [p/p]\\ -\end{keys} - -Each one of these commands has four variants:\\* -\begin{keys}{X v \bf Z} -X \bf z & Decode these series. [p/p]\\ -X \bf Z & Decode and save these series. [p/p]\\ -X v \bf z & Decode and view these series. [p/p]\\ -X v \bf Z & Decode, save and view these series. [p/p]\\ -\end{keys} -where {\bf z} or {\bf Z} identifies the decoding method (b, o, p, s, u). - -An alternative binding for the most-often used of these commands is\\* -\begin{keys}{C-c C-v C-v} -C-c C-v C-v & (X v u) Uudecode and view these series. [p/p]\\ -\end{keys} -}} - -\def\Zsubmap{ -\subsec{Exit the Current Group} -\begin{keys}{Z G} -Z c & (c) Mark all unticked articles as read ({\bf catch-up}) and exit.\\ -Z n & Mark all articles as read and go to the {\bf next} group.\\ -Z C & Mark all articles as read ({\bf catch-up}) and exit.\\ -Z E & (Q) {\bf Exit} without updating the group information.\\ -Z G & (M-g) Check for new articles in this group ({\bf get}).\\ -Z N & Exit and go to {\bf the} next group.\\ -Z P & Exit and go to the {\bf previous} group.\\ -Z R & Exit this group, and then enter it again ({\bf reenter}). -[Prefix: select all articles, read and unread.]\\ -Z Z & (q, Z Q) Exit this group.\\ -\end{keys} -} - -\def\ArticleMode{ -\sec{Article Mode} -{\samepage -% All keys for Summary mode also work in Article mode. -The normal navigation keys work in Article mode. -Some additional keys are:\\* -\begin{keys}{C-c C-m} -RET & (middle mouse button) Activate the button at point to follow -an URL or Message-ID.\\ -TAB & Move the point to the next button.\\ -h & (s) Go to the {\bf header} line of the article in the {\bf -summary} buffer.\\ -C-c ^ & Get the article with the Message-ID near point.\\ -C-c C-m & {\bf Mail} reply to the address near point (prefix: include the -original).\\ -\end{keys} -}} - -\def\ServerMode{ -\sec{Server Mode} -{\samepage -To enter this mode, press `^' while in Group mode.\\* -\begin{keys}{SPC} -SPC & (RET) Browse this server.\\ -a & {\bf Add} a new server.\\ -c & {\bf Copy} this server.\\ -e & {\bf Edit} a server.\\ -k & {\bf Kill} this server. [scope]\\ -l & {\bf List} all servers.\\ -q & Return to the group buffer ({\bf quit}).\\ -y & {\bf Yank} the previously killed server.\\ -\end{keys} -}} - -\def\BrowseServer{ -\sec{Browse Server Mode} -{\samepage -To enter this mode, press `B' while in Group mode.\\* -\begin{keys}{RET} -RET & Enter the current group.\\ -SPC & Enter the current group and display the first article.\\ -? & Give a very short help message.\\ -n & Go to the {\bf next} group. [distance]\\ -p & Go to the {\bf previous} group. [distance]\\ -q & (l) {\bf Quit} browse mode.\\ -u & Subscribe to the current group. [scope]\\ -\end{keys} -}} diff --git a/texi/message-ja.texi b/texi/message-ja.texi deleted file mode 100644 index 3a152d3..0000000 --- a/texi/message-ja.texi +++ /dev/null @@ -1,1314 +0,0 @@ -\input texinfo @c -*-texinfo-*- - -@setfilename message-ja -@settitle Message 5.6.33 Manual -@synindex fn cp -@synindex vr cp -@synindex pg cp -@c @direntry -@c * Message: (message). Mail and news composition mode that goes with Gnus. -@c @end direntry -@iftex -@finalout -@end iftex -@setchapternewpage odd - -@ifinfo - -This file documents Message, the Emacs message composition mode. - -$B$3$N%U%!%$%k$O(B Emacs $B$N%a%C%;!<%8:n@.%b!<%I$G$"$k(B Message $B$K4X$9$k@bL@J8(B -$B=q$G$9!#(B - -Copyright (C) 1996 Free Software Foundation, Inc. - -Permission is granted to make and distribute verbatim copies of -this manual provided the copyright notice and this permission notice -are preserved on all copies. - -$BCx:n8"I=<($H$3$N5v2DJ8$,$9$Y$F$NJ#@=$KB8:_$9$k8B$j!"$3$N@bL@=q$N$^$C$?$/(B -$BF10l$NJ#@=$r:n$j!"G[I[$9$k$3$H$r5v2D$9$k!#(B - -@ignore -Permission is granted to process this file through Tex and print the -results, provided the printed document carries copying permission -notice identical to this one except for the removal of this paragraph -(this paragraph not being relevant to the printed manual). - -$B$3$NCJMn$,H$5$l$^$;$s(B)$B!#(B - -@end ignore -Permission is granted to copy and distribute modified versions of this -manual under the conditions for verbatim copying, provided also that the -entire resulting derived work is distributed under the terms of a -permission notice identical to this one. - -$BF10lJ#@=$N>r7o$N2<$G!"$=$l$K$h$C$FF@$i$l$?7k2L$b$3$N5v2DJ8$NI=<($HF10l$N(B -$B>r7o$N$b$H$GG[I[$9$k8B$j!"$3$N@bL@=q$N=$@5HG$NJ#@=$r$7!"G[I[$9$k$3$H$r5v(B -$B2D$9$k!#(B - -Permission is granted to copy and distribute translations of this manual -into another language, under the above conditions for modified versions. - -$B>e5-$N=$@5HG$K4X$9$k>r7o$N2<$G!"$3$N@bL@=q$NK]Lu$NJ#@=$r:n$j!"G[I[$9$k$3(B -$B$H$r5v2D$9$k!#(B - -@end ifinfo - -@tex - -@titlepage -@title Message 5.6.22 Manual - -@author by Lars Magne Ingebrigtsen -@translated by members of Semi-gnus mailing-list -@page - -@vskip 0pt plus 1filll -Copyright @copyright{} 1996 Free Software Foundation, Inc. - -Permission is granted to make and distribute verbatim copies of -this manual provided the copyright notice and this permission notice -are preserved on all copies. - -$BCx:n8"I=<($H$3$N5v2DJ8$,$9$Y$F$NJ#@=$KB8:_$9$k8B$j!"$3$N@bL@=q$N$^$C$?$/(B -$BF10l$NJ#@=$r:n$j!"G[I[$9$k$3$H$r5v2D$9$k!#(B - -Permission is granted to copy and distribute modified versions of this -manual under the conditions for verbatim copying, provided that the -entire resulting derived work is distributed under the terms of a -permission notice identical to this one. - -$BF10lJ#@=$N>r7o$N2<$G!"$=$l$K$h$C$FF@$i$l$?7k2L$r$3$N5v2DJ8$NI=<($HF10l$N(B -$B>r7o$N$b$H$GG[I[$9$k8B$j!"$3$N@bL@=q$N=$@5HG$NJ#@=$r$7!"G[I[$9$k$3$H$r5v(B -$B2D$9$k!#(B - -Permission is granted to copy and distribute translations of this manual -into another language, under the above conditions for modified versions. - -$B>e5-$N=$@5HG$K4X$9$k>r7o$N2<$G!"$3$N@bL@=q$NK]Lu$NJ#@=$r:n$j!"G[I[$9$k$3(B -$B$H$r5v2D$9$k!#(B - -@end titlepage -@page - -@end tex - -@node Top -@top Message - -Gnus $B$NA4$F$N%a%C%;!<%8$N:n@.(B ($B%a!<%k$H%K%e!<%9$NN>J}(B) $B$O%a%C%;!<%8%b!<(B -$B%I%P%C%U%!$G9T$o$l$^$9!#(B - -@menu -* Interface:: $B%a%C%;!<%8%P%C%U%!$r@_Dj$9$k!#(B -* Commands:: $B%a%C%;!<%8%b!<%I%P%C%U%!$GAw!"C$7(B -- $B$=$N%W%m%0%i%`(B ($B$b$7$/$O?M(B) $B$O%a%C%;!<%8$,$"$k%P%C(B -$B%U%!$K%]%$%s%H$rF~$l$FI,MW$JL?Na$r8F$S=P$9$@$1$GNI$$$Y$-$G$9!#$=$&$9$k$H(B -@code{Message} $B$O?7$7$$(B @code{message} $B%b!<%I%P%C%U%!$rE,@Z$J%X%C%@!<$r(B -$BF~$l$F:n$j=P$7!"MxMQC$9!#(B -* Superseding:: $B%a%C%;!<%8$NBeBX!#(B -* Forwarding:: $B%a%C%;!<%8$r%K%e!<%9$b$7$/$O%a!<%k$GE>Aw$9$k!#(B -* Resending:: $B%a!<%k%a%C%;!<%8$r:FAw$9$k!#(B -* Bouncing:: $B%a!<%k%a%C%;!<%8$N<:GT$r:FAw$9$k!#(B -@end menu - - -@node New Mail Message -@section $B?7$7$$%a!<%k%a%C%;!<%8(B - -@findex message-mail -@code{message-mail} $BL?Na$O?7$7$$%P%C%U%!$r:n$jI=<($7$^$9!#(B - -2$B$D$NA*Br<+M3$J0z?t$,l9g$O!"$=$l$>$l$NMWAG$O(B -cons $B%;%k$G$"$k$Y$-$G!"$=$l$N(B car $B$O%X%C%@!<$NL>A0(B ($BNc(B @code{Cc}) $B$G!"(B -cdr $B$,%X%C%@!<$NCM(B ($BNc(B @samp{larsi@@ifi.uio.no}) $B$G$"$k$Y$-$G$9!#A4$F$N(B -$B$3$l$i$N%X%C%@!<$O=P$F9T$/%a!<%k$N%X%C%@!<$KA^F~$5$l$^$9!#(B - - -@node Wide Reply -@section $B9-$/JVEz(B - -@findex message-wide-reply -@code{message-wide-reply} $B$O8=:_$N%P%C%U%!$N%a%C%;!<%8$X$N9-$$JVEz$N%a%C(B -$B%;!<%8%P%C%U%!$r:n$C$FI=<($7$^$9!#(B@dfn{$B9-$$JVEz(B} $B$O(B @code{To}$B!"(B -@code{From}$B!"(B($B$b$7$/$O(B @code{Reply-to}) $B$H(B @code{Cc} $B%X%C%@!<$K5s$2$i$l(B -$B$F$$$kA4$F$N?M!9$KFO$/JVEz$G$9!#(B - -@vindex message-wide-reply-to-function -Message $B$OJVEz$,2?=h$K9T$/$+$r7hDj$9$k$?$a$KIaDL$NJ}K!$r;H$$$^$9$,!"(B -@code{message-wide-reply} $B$rO.$k;v$G!"?6$kIq$$$r$"$J$?$NMW5a$K9g$&$h$&$K(B -$BJQ99$9$k;v$,$G$-$^$9!#$=$l$O(B @code{message-reply-to-function} $B$HF1$8$h$&(B -$B$K;H$o$l$^$9(B (@pxref{Reply})$B!#(B - - -@findex rmail-dont-reply-to-names -$B@55,I=8=(B @code{rmail-dont-reply-to-names} $B$K9gCW$9$k%"%I%l%9$O(B @code{Cc} -$B%X%C%@!<$+$iC$9(B - -@findex message-cancel-news -$BL?Na(B @code{message-cancel-news} $B$O8=:_$N%P%C%U%!$N5-;v$rC$7$^$9!#(B - - -@node Superseding -@section $BBeBX(B - -@findex message-supersede -$BL?Na(B @code{message-supersede} $B$O8=:_$N%P%C%U%!$N%a%C%;!<%8$rBeBX$9$k%a%C(B -$B%;!<%8%P%C%U%!$r:n$jI=<($7$^$9!#(B - -@vindex message-ignored-supersede-headers -@code{message-ignored-supersedes-headers} $B$K9gCW$9$k%X%C%@!<$O?7$7$$%a%C(B -$B%;!<%8%P%C%U%!$r:n$j>e$2$kA0$KAw(B - -@findex message-forward -$BL?Na(B @code{message-forward} $B$O8=:_$N%P%C%U%!$N%a%C%;!<%8$rE>Aw$9$k$?$a$N(B -$B%a%C%;!<%8%P%C%U%!$r:n$jI=<($7$^$9!#$b$7@\F,0z?t$rM?$($i$l$k$H!"E>Aw$O(B -$B%K%e!<%9$r;H$$$^$9!#(B - -@table @code -@item message-forward-state-separator -@vindex message-forward-start-separator -$BE>Aw$5$l$k%a%C%;!<%8$NA0$KA^F~$5$l$k6h@Z$j$G$9!#=i4|CM$O(B @* -@samp{------- Start of forwarded message -------\n} $B$G$9!#(B - -@vindex message-forward-end-separator -@item message-forward-end-separator -$BE>Aw$5$l$k%a%C%;!<%8$N8e$KA^F~$5$l$k6h@Z$j$G$9!#=i4|CM$O(B @* -@samp{------- End of forwarded message -------\n} $B$G$9!#(B - -@item message-signature-before-forwarded-message -@vindex message-signature-before-forwarded-message -$B$b$7$3$NJQ?t$,(B @code{t} $B$G$"$k$H!"$=$l$,=i4|CM$G$9$,!"$"$J$?$N8D?ME*$J=p(B -$BL>$,E>Aw$5$l$k%a%C%;!<%8$NA0$KA^F~$5$l$^$9!#$b$7$=$&$G$J$1$l$P!"E>Aw$5$l(B -$B$k%a%C%;!<%8$O?7$7$$%a!<%k$N:G=i$KA^F~$5$l$^$9!#(B - -@item message-included-forward-headers -@vindex message-included-forward-headers -$B$3$l$O@55,I=8=$G!"$=$l$OE>Aw$5$l$k%a%C%;!<%8$K4^$^$l$k%X%C%@!<9T$K9gCW$9(B -$B$k$b$N$G$9!#(B - -@end table - - -@node Resending -@section $B:FAw(B - -@findex message-resend -$BL?Na(B @code{message-resend} $B$OMxMQpJs$re$2$kA0$K$r;H$&$+!#(B -@end menu - - -@node Header Commands -@section $B%X%C%@!$K0\F0$7$^$9(B (@code{message-goto-signature})$B!#(B - -@end table - - -@node Insertion -@section $BA^F~(B - -@table @kbd - -@item C-c C-y -@kindex C-c C-y -@findex message-yank-original -$B%P%C%U%!(B @code{gnus-article-copy} $B$K$"$k%a%C%;!<%8$r%a%C%;!<%8%P%C%U%!$K(B -$BE=$jIU$1$^$9!#IaDL$O(B @code{gnus-article-copy} $B$O$"$J$?$,JVEz$7$h$&$H$7$F(B -$B$$$k%a%C%;!<%8$G$9(B (@code{messsage-yank-original})$B!#(B - -@item C-c C-q -@kindex C-c C-q -@findex message-fill-yanked-message -$BE=$jIU$1$i$l$?%a%C%;!<%8$r@^$jJV$7$^$9(B -(@code{message-fill-yanked-message})$B!#7Y9p(B: $B$b$7!"0zMQ$N=,47$,JQ$G$"$k$J(B -$B$i!"E=$jIU$1$i$l$?J8>O$r$R$I$/$0$A$c$0$A$c$K$7$F$7$^$&$+$b$7$l$^$;$s!#$=(B -$B$l$,0BA4$G$"$k$HCN$k$H!"$9$0$K?M?4CO$D$/$G$7$g$&$,!#$H$K$+$/!"(B@kbd{C-x -u} (@code{undo}) $B$,;HMQ2DG=$G!"Bg>fIW$G$"$k$H8@$&;v$r3P$($F$*$$$F2<$5$$!#(B - - -@item C-c C-w -@kindex C-c C-w -@findex message-insert-signature -$B%P%C%U%!$N:G8e$K=pL>$rA^F~$7$^$9(B (@code{message-insert-signature})$B!#(B - -@end table - -@table @code -@item message-ignored-cited-headers -$B$3$N@55,I=8=$K9gCW$9$kA4$F$N%X%C%@!<$OE=$jIU$1$i$l$?%a%C%;!<%8$+$i writes: -@end example - -$B$3$N4X?t$,8F$P$l$?$H$-!"%]%$%s%H$O%a%C%;!<%8$NK\BN$N@hF,$K$"$k$G$7$g$&!#(B - -@item message-yank-prefix -@vindex message-yank-prefix -@cindex yanking -@cindex quoting -$B$"$J$?$,5-;v$KJVEz$+%U%)%m!<%"%C%W$r$7$F$$$k$H$-$O!"IaDL$O$"$J$?$,1~Ez$7(B -$B$F$$$k?M$N$b$N$K0zMQId$rIU$1$?$$$G$7$g$&!#0zMQJ8$NA^F~$O(B @dfn{$BE=$jIU$1(B} -$B$K$h$C$F$J$5$l!"$=$l$>$l$NE=$jIU$1$i$l$?0zMQ9T$O$=$NA0$K(B -@code{message-yank-prefix} $B$rIU$1$i$l$^$9!#=i4|CM$O(B @samp{> } $B$G$9!#$b$7(B -$B$=$l$,(B @code{nil} $B$G$"$l$P!"%a%C%;!<%8$N;z2<$2$@$1$r$7$^$9!#(B - -@item message-indentation-spaces -@vindex message-indentation-spaces -$BE=$jIU$1$i$l$?%a%C%;!<%8$r;z2<$2$9$k$?$a$N6uGr$N?t$G$9!#(B - -@item message-cite-function -@vindex message-cite-function -@findex message-cite-original -@findex sc-cite-original -@findex message-cite-original-without-signature -@cindex Supercite -$BK\5-;v$r0zMQ$9$k$?$a$N4X?t$G$9!#=i4|CM$O(B @code{message-cite-original} $B$G!"(B -$B$3$l$OC1=c$K$b$H$N%a%C%;!<%8$rA^F~$7!"$=$l$>$l$N9T$NF,$K(B @samp{> } $B$r$/$C(B -$B$D$1$^$9!#(B@code{message-cite-original-without-signature} $B$OF1MM$N;v$r$7(B -$B$^$9$,!"=pL>$O>J$-$^$9!#(BSupercite $B$r;H$&$?$a$K!"$=$l$r(B -@code{sc-cite-original} $B$K@_Dj$9$k;v$b$G$-$^$9!#(B - -@item message-indent-citation-function -@vindex message-indent-citation-function -$B$A$g$&$I%a!<%k%P%C%U%!$KA^F~$5$l$?0zMQJ8$r=$@5$9$k$?$a$N4X?t$G$9!#$3$l$O(B -$B4X?t$N%j%9%H$G$"$k;v$b$G$-$^$9!#$=$l$>$l$N4X?t$O(B @code{(point)} $B$H(B -@code{(mark t)} $B$N4V$G0zMQ$rH/8+$9$k;v$,$G$-$^$9!#$=$7$F!"$=$l$>$l$N4X?t(B -$B$O0zMQJ8$,=$@5$5$l$k$H!"$=$N<~$j$K%]%$%s%H$H%^!<%/$r;D$5$J$1$l$P$J$j$^$;(B -$B$s!#(B - -@item message-signature -@vindex message-signature -$B%a%C%;!<%8%P%C%U%!$N:G8e$KA^F~$5$l$kJ8;zNs$G$9!#$b$7(B @code{t} ($B$3$l$,=i(B -$B4|@_Dj$G$9(B) $B$G$"$l$P!"%U%!%$%k(B @code{message-signature-file} $B$,Be$o$j$K(B -$BA^F~$5$l$^$9!#$b$74X?t$G$"$l$P!"4X?t$N7k2L$,Be$o$j$K;H$o$l$^$9!#$b$7<0$G(B -$B$"$l$P!"<0$N7k2L$,JQ$o$j$K;H$o$l$^$9!#$3$NJQ?t$,(B @code{nil} $B$G$"$l$P!"=p(B -$BL>$OA4$/A^F~$5$l$^$;$s!#(B - -@item messsage-signature-file -@vindex message-signature-file -$B%P%C%U%!$N:G8e$KA^F~$5$l$k=pL>$NF~$C$F$$$k%U%!%$%k$G$9!#=i4|CM$O(B -@samp{~/.signature} $B$G$9!#(B - -@end table - -RFC1036bis $B$O!"=pL>$O$=$NA0$K(B @samp{-- } $B$N(B3$BJ8;z$@$1$N9T$,$"$k$Y$-$G$"$k(B -$B$H8@$C$F$$$k;v$KCm0U$7$F2<$5$$!#$3$l$O$rG'<1$7$F!"=h(B -$BM}$r$9$k;v$r4JC1$K$9$k$?$a$G$9!#$G$9$+$i!"$"$J$?$NH~$7$$%G%6%$%s$r$=$l$,!"(B -$B$"$N!"40A4$KGK2u$7$F$$$k$H46$8$F$b$=$l$i$NJ8;z$r$O(B4$B9T$h$jB?$/$J$k$Y$-$G$OL5$$$H8@$&;v$bCm0U$7$F2<$5$$!#(BASCII $B$N3($r(B -$BF~$l$k;v$O!"3'$K$"$J$?$,GO(B rot13) $B$7$^$9(B -(@code{message-caesar-buffer-body})$B!#$b$7HO0O8BDj$,$5$;$k(B -$B$+$r;XDj$7$^$9!#=i4|CM$O(B 13 $B$G$9!#(B - -@item C-c C-e -@kindex C-c C-e -@findex message-elide-region -$B%]%$%s%H$H%^!<%/$N4V$NJ8$r>J$-$^$9(B (@code{message-elide-region})$B!#J8>O$O(B -$B@Z$i$l$F(B (killed) $B>JN,Id9f(B (@samp{[...]} $B$,$=$N>l=j$KA^F~$5$l$^$9!#(B - -@item C-c C-z -@kindex C-c C-x -@findex message-kill-to-signature -$B=pL>$^$G$+!"$=$l$,L5$1$l$P5-;v$N:G8e$^$G$NA4$F$NJ8$r@Z$j$^$9(B -(@code{message-kill-to-signature})$B!#(B - -@item C-c C-v -@kindex C-c C-v -@findex message-delete-not-region -$B%a%C%;!<%8$NK\BN$N%j!<%8%g%s$N30$NA4$F$NJ8$r>C5n$7$^$9(B -(@code{message-delete-not-region})$B!#(B - -@item M-RET -@kindex M-RET -@kindex message-newline-and-format -4$B$D$N?7$7$$9T$rA^F~$7!"$b$7%]%$%s%H$,0zMQJ8$N4V$K$"$k$J$i$P!":F@07A$7$^(B -$B$9!#(B - -$B$3$l$ONc$G$9(B: - -@example -> $B$3$l$O2?$+$N0zMQJ8$G$9!#(B $B$=$7$F!"$3$3$K$O$b$C$H0zMQJ8$,$"$j$^$9!#(B -@end example - -$B$b$7!"%]%$%s%H$,(B @samp{$B$=$7$F(B} $B$NA0$K$"$j!"(B@kbd{M-RET} $B$r2!$7$?$J$i!"0J(B -$B2<$N$h$&$J$b$N$rF@$^$9(B: - -@example -> $B$3$l$O2?$+$N0zMQJ8$G$9!#(B - -* - -> $B$=$7$F!"$3$3$K$O$b$C$H0zMQJ8$,$"$j$^$9!#(B -@end example - -@samp{*} $B$O%]%$%s%H$,CV$+$l$F$$$k>l=j$G$9!#(B - -@item C-c C-t -@kindex C-c C-t -@findex message-insert-to -$B%U%)%m!<%"%C%W$7$h$&$H$9$k%a%C%;!<%8$N(B @code{Reply-To} $B$b$7$/$O(B -@code{From} $B%X%C%@!<$r4^$`(B @code{To} $B%X%C%@!<$rA^F~$7$^$9(B -(@code{message-insert-to})$B!#(B - -@item C-c C-n -@kindex C-c C-n -@findex message-insert-newsgroups -$BJVEz$7$F$$$k5-;v$N(B @code{Followup-To} $B$b$7$/$O!"(B@code{Nesgroups} $B%X%C%@!<(B -$B$rH?1G$7$?(B @code{Newsgroups} $B%X%C%@!<$rA^F~$7$^$9(B -(@code{message-insert-newsgroups})$B!#(B - -@item C-c M-r -@kindex C-c M-r -@findex message-rename-buffer -$B%P%C%U%!$NL>A0$rJQ99$7$^$9(B (@code{message-rename-buffer})$B!#@\F,0z?t$rM?(B -$B$($i$l$l$P!"?7$7$$%P%C%U%!L>$NF~NO$rB%?J$7$^$9!#(B - -@end table - - -@node Sending -@section $BAw?.(B - -@table @kbd -@item C-c C-c -@kindex C-c C-c -@findex message-send-and-exit -$B%a%C%;!<%8$rAw?.$7!"8=:_$N%P%C%U%!$rKd$a$^$9(B -(@code{message-send-and-exit})$B!#(B - -@item C-c C-s -@kindex C-c C-s -@findex message-send -$B%a%C%;!<%8$rAw?.$7$^$9(B (@code{message-send})$B!#(B - -@item C-c C-d -@kindex C-c C-d -@findex message-dong-send -$B%a%C%;!<%8%P%C%U%!$rKd$a$F=*N;$7$^$9(B (@code{message-dont-send})$B!#(B - -@item C-c C-k -@kindex C-c C-k -@findex message-kill-buffer -$B%a%C%;!<%8%P%C%U%!$r@Z$C$F=*N;$7$^$9(B (@code{message-kill-buffer})$B!#(B - -@end table - - - -@node Mail Aliases -@section $B%a!<%kJLL>(B -@cindex mail aliases -@cindex aliases - -@vindex message-mail-alias-type -$BJQ?t(B @code{message-mail-alias-type} $B$O$I$N$h$&$J7?$N%a!<%kJLL>(B (mail -alias) $B?-D%$r;H$&$+$r@)8f$7$^$9!#8=:_$G$O!"0l$D$NMM<0$@$1$,;HMQ2DG=$G$9(B--- -Message $B$O%a!<%kJLL>$r07$&$?$a$K(B @code{mailabbrev} $B$r;H$$$^$9!#$b$7$3$N(B -$BJQ?t$,(B @code{nil} $B$G$"$k$J$i!"%a!<%kJLL>?-D%$O" -alias ding "ding@@ifi.uio.no (ding mailing list)" -@end example - -$B$3$N$h$&$J9T$r$"$J$?$N(B @file{~/.mailrc} $B%U%!%$%k$KDI2C$7$?8e$G!"(B -@code{To} $B$d(B @code{Cc} ($BEy$J$I(B) $B$N%X%C%@!<$G(B @samp{lmi} $B$H=q$$$F!"(B -@kbd{SPC} $B$r2!$9$@$1$GJLL>$r?-D%$7$^$9!#(B - -$B%a%C%;!<%8$rAw$k$H$-$K$O?-D%$O9T$o$l$^$;$s(B---$BA4$F$N?-D%$OL@<(E*$K9T$o$l(B -$B$J$/$F$O$J$j$^$;$s!#(B - - - -@node Variables -@chapter $BJQ?t(B - -@menu -* Message Headers:: $B0lHLE*$J%a%C%;!<%8%X%C%@!<$N$h$&$J$b$N!#(B -* Mail Headers:: $B%a!<%k%X%C%@!<$r%+%9%?%^%$%:$9$k!#(B -* Mail Variables:: $BB>$N%a!<%kJQ?t!#(B -* News Headers:: $B%K%e!<%9%X%C%@!<$r%+%9%?%^%$%:$9$k!#(B -* News Variables:: $BB>$N%K%e!<%9JQ?t!#(B -* Various Message Variables:: $BB>$N%a%C%;!<%8JQ?t!#(B -* Sending Variables:: $BAw?.$9$k$?$a$NJQ?t!#(B -* Message Buffers:: Message $B$,$=$N%P%C%U%!$NL>A0$rIU$1$kJ}K!!#(B -* Message Actions:: $B=*N;$9$k$H$-$Ko$K@Q6KE*$G$9!#$=$l$O}. - -@item default -$B$=$l$,0zMQId9f$rMW5a$7$J$1$l$P(B @code{angles} $B$N$h$&$K8+$(!"$b$70zMQId9f(B -$B$,MW5a$5$l$k>l9g$O(B @code{parens} $B$N$h$&$K8+$($^$9!#(B@code{parens} $B$,0zMQ(B -$BId9f$rMW5a$7$?$H$7$F$b!"$H$K$+$/(B @code{angles} $B$r;H$$$^$9!#(B - -@end table - -@item message-deletable-headers -@vindex message-deletable-headers -$B$3$N%j%9%H$K$"$k!"0JA0$K(B Message $B$K$h$j:n@.$5$l$?%X%C%@!<$OEj9F$9$kA0$K(B -$B:o=|$5$l$^$9!#5-;v$rEj9F$9$k$H$7$^$7$g$&!#$=$l$+$i!"$o$s$Q$/K7$N%0%k!<%W$K:F$SEj9F$9$k;v$K7hDj$7$?$N$G!"(B -@code{*post-buf*} $B%P%C%U%!$KLa$j!"(B@code{Newsgroups} $B9T$rJT=8$7!":F$SAw$j(B -$B=P$7$?$H$7$^$9!#=i4|@_Dj$G$O!"$3$NJQ?t$OA0$K:n@.$5$l$?8E$$(B -@code{Message-ID} $B$,l9g$O$3$NJQ?t$r$3$l$i$N@\F,8l(B -$B$K9g$&$h$&$J@55,I=8=$K@_Dj$9$k$G$7$g$&!#;d<+?H$O!"$=$N$h$&$J5,3J$K=>$o$J(B -$B$$%a!<%k$O$?$@H$7$F2<$5$$!#$=$l(B -$B$N=i4|CM$O(B @code{(From Date Subject (optional . In-Reply-To) Message-ID -Lines (optional . X-Mailer))} $B$G$9!#(B - -@item message-ignored-mail-headers -@vindex message-ignored-mail-headers -$B%a!<%k$r=P$9A0$Kl9g$OF~NO$rB%?J$5$l$^$9!#(B - -@item Newsgroups -@cindex Newsgroups -$B$3$NI,MW$J%X%C%@!<$O$I$N%K%e!<%9%0%k!<%W$K5-;v$,Ej9F$5$l$k;v$K$J$k$+$r;X(B -$BDj$7$^$9!#$b$7$^$@B8:_$7$F$$$J$$$J$i!"F~NO$rB%?J$5$l$^$9!#(B - -@item Organization -@cindex organization -$B$3$NA*BrG$0U$J%X%C%@!<$OJQ?t(B @code{message-user-organization} $B$K0MB8$7$F(B -$B:n@.$5$l$^$9!#$b$7$3$NJQ?t$,(B @code{t} $B$G$"$l$P!"(B -@code{message-user-organization-file} $B$,;H$o$l$^$9!#$3$NJQ?t$OJ8;zNs$G$"(B -$B$k;v$b$G$-(B ($B$=$N>l9g$O$=$NJ8;zNs$,;H$o$l$^$9(B)$B!"4X?t$G$"$k;v$b$G$-$^$9(B -($B$=$N4X?t$O0z?tL5$7$G8F$P$l!";H$o$l$kJ8;zNs$rJV$9I,MW$,$"$j$^$9(B)$B!#(B - -@item Lines -@cindex Lines -$B$3$NA*BrG$0U$J%X%C%@!<$O(B Message $B$K$h$j7W;;$5$l$^$9!#(B - -@item Message-ID -@cindex Message-ID -@vindex mail-host-address -@findex system-name -@cindex Sun -$B$3$NI,MW$J%X%C%@!<$O(B Message $B$K$h$j:n@.$5$l$^$9!#F|IU!";~4V!"MxMQ!"(B -$B%7%9%F%`L>$K4p$E$$$?B>$KL5$$(B ID $B$,:n@.$5$l$^$9!#(BMessage $B$O(B -@code{mail-host-address} $B$,Dj5A$5$l$F$$$l$P!"$=$l$r(B fully qualified -domain name (FQDN) ($B40A4$K>r7o$rK~$?$7$?%I%a%$%sL>(B) $B$H$7$F;H$$$^$9!#$b$7(B -$B$=$&$G$J$1$l$P!"$=$l$O(B @code{system-name} $B$r;H$$!"$=$l$O$$$/$D$+$N%^%7%s(B --- $Bl9g0J30$O!"%m!<%+%kJQ?t(B @code{message-mailer} $B$K$7$?$,$C$F:n$i$l$^$9!#(B - -@item In-Reply-To -$B$3$NA*Br<+M3$J%X%C%@!<$OJVEz$7$F$$$k5-;v$N(B @code{Date} $B$H(B @code{From} $B%X%C(B -$B%@!<$r;H$C$F:n$i$l$^$9!#(B - -@item Expires -@cindex Expires -$B$3$NHs>o$KA*Br<+M3$J%X%C%@!<$OJQ?t(B @code{message-expires} $B$K$7$?$,$C$FA^(B -$BF~$5$l$^$9!#$3$l$O<+J,$,2?$r$7$F$$$k$+$rCN$i$J$$8B$j!";HMQ$OA4$/4+$a$i$l(B -$B$^$;$s!#(B - -@item Distribution -@cindex Distribution -$B$3$NA*Br<+M3$J%X%C%@!<$OJQ?t(B @code{message-distribution-function} $B$K$7$?(B -$B$,$C$F:n$i$l$^$9!#$=$l$OHs?d>)$G!"Hs>o$K8m2r$5$l$?%X%C%@!<$G$9!#(B - -@item Path -@cindex path -$B$3$NHs>o$KA*Br<+M3$J%X%C%@!<$O$*$=$i$/7h$7$F;H$o$l$F$O$J$i$J$$$G$7$g$&!#(B -$B$7$+$7$$$/$D$+$N(B @emph{$B$H$F$b(B} $B8E$$%5!<%P!<$O$3$N%X%C%@!<$,B8:_$9$k;v$r(B -$BMW5a$7$^$9!#(B@code{message-user-path} $B$,$3$N(B @code{Path} $B%X%C%@!<$,$I$N$h(B -$B$&$K8+$($k$+$r$5$i$K@)8f$7$^$9!#$b$7$=$l$,(B @code{nil} $B$G$"$l$P!"%5!<%P!<(B -$BL>$r(B leaf $B@a$H$7$F;H$$$^$9!#$b$7$=$l$,J8;zNs$G$"$l$P!"$=$NJ8;zNs$r;H$$$^(B -$B$9!#$b$7$=$l$,J8;zNs$G$b(B @code{nil} $B$G$b$J$1$l$P!"MxMQA0$@$1$r;H$$(B -$B$^$9!#$7$+$7!"2?$i$+$N7A$G$3$NJQ?t$rO.$i$J$1$l$P$J$i$J$$I,MW@-$OHs>o$K>/(B -$B$J$$$G$7$g$&!#(B -@end table - -@findex yow -@cindex Mime-Version -$B2C$($F!"$"$J$?$O(B cons $B$r%j%9%H$KF~$l$k;v$,$G$-$^$9!#(Bcons $B$N(B car $B$O%7%s%\(B -$B%k$G$"$k$Y$-$G$9!#$3$N%7%s%\%kL>$O%X%C%@!$G!"(Bcdr $B$O$3$N%X%C%@!<$NCM$H(B -$B$7$F$=$N$^$^F~$l$i$l$k$3$H$K$J$kJ8;zNs$+!"8F$P$l$k4X?t$N$I$A$i$+$G$"$k;v(B -$B$,$G$-$^$9!#Nc$($P!"$b$7(B @code{Mime-Version: 1.0} $B$rA^F~$7$?$$$J$i!"(B -@code{(Mime-Version . "1.0")} $B$r%j%9%H$KF~$l$k$Y$-$G$7$g$&!#$b$7$*$b$7$m(B -$B$$0zMQ$rA^F~$7$?$$$J$i!"(B@code{(X-Yow . yow)} $B$N$h$&$J$b$N$r%j%9%H$KF~$l(B -$B$k;v$,$G$-$k$G$7$g$&!#4X?t(B @code{yow} $B$O$=$N8e$G0z?tL5$7$G8F$P$l$^$9!#(B - -$B$b$7%j%9%H$,(B cons $B$N(B car $B$,(B @code{optional} $B$G$"$k(B cons $B$r4^$s$G$$$k$J$i!"(B -$B$3$N(B cons $B$N(B cdr $B$O(B @code{nil} $B$G$J$$$H$-$@$1A^F~$5$l$^$9!#(B - -$B=P$F9T$/%K%e!<%95-;v$r%+%9%?%^%$%:$9$k$?$a$NB>$NJQ?t(B: - -@table @code - -@item message-syntax-checks -@vindex message-syntax-checks -@code{nil} $B$G$J$1$l$P!"(BMessage $B$OEj9F$NA0$K!"%X%C%@!<$HB>$N$b$N$N9gK!@-(B -$B$rD4$Y$^$9!#$3$N%j%9%H$KMWAG$rIU$12C$($?$jfIW$+$I$&$+D4$Y$^$9!#(B -@item from -@code{From} $B%X%C%@!<$,$h$/8+$($k$+$I$&$+$rD4$Y$^$9!#(B -@item long-lines -$B$"$^$j$KD9$$9T$rD4$Y$^$9!#(B -@item control-chars -$BHs9gK!J8;z$rD4$Y$^$9!#(B -@item size -$B2a>j$JBg$-$5$rD4$Y$^$9!#(B -@item new-text -$B%a%C%;!<%8$K?7$7$$J8$,$"$k$+$I$&$+$rD4$Y$^$9!#(B -@item signature -$B=pL>$ND9$5$rD4$Y$^$9!#(B -@item approved -@cindex approved -$B5-;v$,(B @code{Approved} $B%X%C%@!<$r;}$C$F$$$k$+$I$&$+$rD4$Y$^$9!#$=$l$O;J(B -$B2q(B -$B$,L5$$$+$rD4$Y$^$9!#(B -@item shorten-followup-to -$BEj9F$9$k%0%k!<%W$N?t$r(B @code{Followup-to} $B%X%C%@!<$rIU$12C$($k;v$G>/$J$/(B -$B$9$k$+$rD4$Y$^$9!#(B -@end table - -$B$3$l$iA4$F$N>uBV$O=i4|@_Dj$G$OD4$Y$i$l$^$9!#(B - -@item message-ignored-news-headers -@vindex message-ignored-news-headers -$BEj9F$9$kA0$K\:Y$O(B gnus $B%^%K%e%"%k$r8+$F2<$5$$(B) $B$G$9!#(B - -@end table - - -@node Various Message Variables -@section $B$$$m$$$m$J%a%C%;!<%8JQ?t(B - -@table @code -@item message-signature-separator -@vindex message-signature-separator -$B=pL>J,N%$K9gCW$9$k@55,I=8=$G$9!#=i4|CM$O(B @samp{^-- *$} $B$G$9!#(B - -@item mail-header-separator -@vindex mail-header-separator -$B%X%C%@!<$rK\BN$+$iJ,$1$k$N$K;H$o$l$kJ8;zNs$G$9!#=i4|CM$O(B @samp{--text -follows this line--} $B$G$9!#(B - -@item message-directory -@vindex message-directory -$BB?$/$N%a!<%k$N$b$N$+$i;H$o$l$k%G%#%l%/%H%j!<$G$9!#=i4|CM$O(B -@file{~/Mail/} $B$G$9!#(B - -@item message-signature-setup-hook -@vindex message-signature-setup-hook -$B%a%C%;!<%8%P%C%U%!$r=i4|2=$9$k$H$-$K$,A^F~$5$l$kA0$KO$,A^(B -$BF~$5$l$kA0$Kl9g$O%X%C%@!<$r2C$($^$;$s!#(B - -@item message-send-mail-hook -@vindex message-send-mail-hook -$B%a!<%k%a%C%;!<%8$rAw$kA0$K$l$NMWAG$O$H6&$K8F$P$l$^$9!#=i4|@_Dj$N4X?t$O(B @code{message-output} -$B$G!"$=$l$O(B Unix mailbox $BMM<0$GJ]B8$7$^$9!#(B - -@item message-courtesy-message -@vindex messsage-courtesy-messsage -$BJ#9g%a%C%;!<%8$rAw$k$H$-$O!"$3$NJ8;zNs$O%a!<%k$GAw$i$l$?J#@=$NJ}$N:G=i$K(B -$BA^F~$5$l$^$9!#$b$7$=$NJ8;zNs$,=qK!;EMM;XDj(B @samp{%s} $B$r4^$s$G$$$l$P!"5-(B -$B;v$,Ej9F$5$l$?%K%e!<%9%0%k!<%W$,$=$3$KA^F~$5$l$^$9!#$b$7$3$NJQ?t$,(B -@code{nil} $B$G$"$l$P!"$=$N$h$&$J?F@Z%a%C%;!<%8$O2C$($i$l$^$;$s!#=i4|CM$O(B -@samp{"The following message is a courtesy copy of an article\nthat has -been posted to %s as well.\n\n"} $B$G$9!#(B - -@end table - - -@node Message Buffers -@section $B%a%C%;!<%8%P%C%U%!(B - -Message $B$O$"$J$?$,%a%C%;!<%8%P%C%U%!$rMW5a$7$?$H$-$K!"B>$KL5$$M#0l$N%P%C(B -$B%U%!L>$G?7$7$$%P%C%U%!$r$D$/$j$^$9!#%a%C%;!<%8$rAw$C$?$H$-$K!"%P%C%U%!$O(B -$BIaDL$O:o=|$5$l$^$;$s!#$=$NL>A0$OJQ99$5$l$F!"FCDj$N?t$N8E$$%a%C%;!<%8%P%C(B -$B%U%!$O@8$-$?$^$^$K$J$j$^$9!#(B - -@table @code -@item message-generate-new-buffers -@vindex message-generate-new-buffers -@code{nil} $B$G$J$1$l$P!"?7$7$$%P%C%U%!$r:n@.$7$^$9!#=i4|CM$O(B @code{t} $B$G(B -$B$9!#$b$7$3$l$,4X?t$J$i!"$=$N4X?t$r(B3$B$D$N0z?t$H6&$K8F$S$^$9(B: $B7?!"Aw$j@h%"(B -$B%I%l%9!"%0%k!<%WL>(B $B$G$9!#(B ($B$3$l$i$N$I$l$G$b(B @code{nil} $B$G$"$k$+$b$7$l$^(B -$B$;$s!#(B) $B4X?t$O?7$7$$%P%C%U%!L>$rJV$9$Y$-$G$9!#(B - -@item message-use-multi-frames -@vindex message-use-multi-frames -@code{nil} $B$G$J$1$l$P!"?7$7$$%U%l!<%`$r:n@.$7$^$9!#=i4|CM$O(B @code{nil} -$B$G$9!#(B - -@item message-delete-frame-on-exit -@vindex messgae-delete-frame-on-exit -$BJQ?t(B @code{message-delete-frame-on-exit} $B$O%a%C%;!<%8$rAw?.$7$?$H$-$H!"(B -$B%P%C%U%!$r@Z$C$?$H$-$K%U%l!<%`$r>C5n$9$k$+$r7hDj$7$^$9!#(B@code{nil} $B$G$"(B -$B$l$P!"(B($B$3$l$,=i4|@_Dj$G$9$,(B) $B%U%l!<%`$r>C5n$7$^$;$s!#(B@code{ask} $B$G$"$l$P!"(B -$B>C5n$9$k$+$I$&$+$rMxMQo$K>C5n$7$^$9!#(B - -@item message-max-buffers -@vindex message-max-buffers -$B#k$NJQ?t$O$I$N$/$i$$8E$$%a%C%;!<%8%P%C%U%!$rJ]$C$F$*$/$+$r;XDj$7$^$9!#$3(B -$B$l$h$jB?$$%a%C%;!<%8%P%C%U%!$,$"$l$P!"0lHV8E$$%P%C%U%!$,:o=|$5$l$^$9!#=i(B -$B4|CM$O(B10$B$G$9!#$3$NJQ?t$,(B @code{nil} $B$G$"$k$H!"8E$$%a%C%;!<%8%P%C%U%!$O:o(B -$B=|$5$l$^$;$s!#(B - -@item message-send-rename-function -@vindex message-send-rename-function -$B%a%C%;!<%8$rAw$C$?8e$G!"%P%C%U%!$NL>A0$O!"Nc$($P!"(B@samp{*reply to Lars*} -$B$+$i(B @samp{*sent reply to Lars*} $B$KJQ99$5$l$^$9!#$b$7$3$l$r9%$^$J$$$J$i!"(B -$B$3$NJQ?t$r$"$J$?$N9%$-$JJ}K!$G%P%C%U%!$NL>A0$rJQ99$9$k4X?t$K@_Dj$7$F2<$5(B -$B$$!#$=$b$=$b%P%C%U%!L>$rJQ99$9$k;v$r9%$^$J$$$N$G$"$l$P!"$N2D(B -$BG=@-$K$O(B @kbd{C-c C-s} $B$,$"$j!"$3$l$O%a%C%;!<%8$rAw$k$@$1$G$"$j!"(B -@kbd{C-c C-d} $B$O%a%C%;!<%8$NJT=8$r@h$K1d$P$7$F%a%C%;!<%8%P%C%U%!$rKd$a!"(B -@kbd{C-c C-k} $B$O%a%C%;!<%8%P%C%U%!$r:o=|$7$^$9!#$3$l$i$NF0:n$O$=$l$>$l$=(B -$B$l$H4XO"IU$1$i$l$?%j%9%H$r;}$C$F$$$F!"$=$l$O2A(B} $B$5$l$k<0$G$9!#(B - - -@node Compatibility -@chapter $B8_49@-(B -@cindex compatibility - -Message $B$O;ve!"$=$l<+?H$NJQ?t$7$+;H$$$^$;$s(B---$B8E$$(B @code{mail-} $B$NJQ(B -$B?t$O9MN8$5$l$^$;$s!#(BMessage $B$K$3$l$i$NJQ?t$r7W;;$KF~$l$5$;$?$$$N$G$"$l$P!"(B -$B0J2<$N$b$N$r$"$J$?$N(B @code{.emacs} $B%U%!%$%k$KF~$l$k;v$,$G$-$^$9(B: - -@lisp -(require 'messcompat) -@end lisp - -$B$3$l$OB?$/$N(B Message $BJQ?t$rBP1~$9$k%a!<%kJQ?t$+$i=i4|2=$7$^$9!#(B - - -@node Appendices -@chapter $BIU5-(B - -@menu -* Responses:: $B1~Ez$,2?=h$K9T$/$+$r7hDj$9$kI8=`$NK!B'!#(B -@end menu - -@node Responses -@section $B1~Ez(B - -$B%a%C%;!<%8$,2?=h$K9T$/$+$r7hDj$9$k$?$a$K!"=i4|@_Dj$G$O0J2<$N%"%k%4%j%:%`(B -$B$,;H$o$l$^$9!#(B - -@table @dfn -@item reply -@dfn{$BJVEz(B} (reply) $B$O%a%C%;!<%8$rAw$C$??M(B @emph{$B$@$1(B} $B$K%a!<%k$G1~Ez$7$?(B -$B$$$H$-$N$b$N$G$9!#l9g$O$=$l$,Be$o$j(B -$B$K;H$o$l$^$9(B)$B!#(B - -@item Cc - -@item To -@end table - -@code{Mail-Copies-To} $B%X%C%@!<$,B8:_$7$F$$$k$H!"$=$l$b%a!<%k%\%C%/%9$N%j(B -$B%9%H$K2C$($i$l$k$G$7$g$&!#$3$N%X%C%@!<$,(B @samp{never} $B$G$"$l$P!"$=$l$O(B -@code{From} ($B$b$7$/$O(B @code{Reply-To}) $B%a!<%k%\%C%/%9$,M^@)$5$l$k$H8@$&(B -$B;v$G$9!#(B - - -@item followup -@dfn{$B%U%)%m!<%"%C%W(B} (followup) $B$O%K%e!<%9$K$h$k1~Ez$G$9!#0J2<$N%X%C%@!<(B -($BM%@h=g0L$N9b$$$b$N$+$i5s$2$i$l$F$$$^$9(B) $B$,2?=h$K1~Ez$,Aw$i$l$k$+$r7hDj(B -$B$7$^$9(B: - -@table @code - -@item Followup-To - -@item Newsgroups - -@end table - -$B$b$7(B @code{Mail-Copies-To} $B%X%C%@!<$,B8:_$9$k$H!"$=$l$,(B @samp{never} $B$G(B -$B$J$1$l$P!"?7$7$$(B @code{Cc} $B%X%C%@!<$N4p$H$7$F;H$o$l!"$^$9!#(B - -@end table - - - -@node Index -@chapter Index -@printindex cp - -@node Key Index -@chapter Key Index -@printindex ky - -@summarycontents -@contents -@bye - -@c End: - diff --git a/texi/message.texi b/texi/message.texi deleted file mode 100644 index cc37033..0000000 --- a/texi/message.texi +++ /dev/null @@ -1,1325 +0,0 @@ -\input texinfo @c -*-texinfo-*- - -@setfilename message -@settitle Message 5.6.44 Manual -@synindex fn cp -@synindex vr cp -@synindex pg cp -@c @direntry -@c * Message: (message). Mail and news composition mode that goes with Gnus. -@c @end direntry -@iftex -@finalout -@end iftex -@setchapternewpage odd - -@ifinfo - -This file documents Message, the Emacs message composition mode. - -Copyright (C) 1996 Free Software Foundation, Inc. - -Permission is granted to make and distribute verbatim copies of -this manual provided the copyright notice and this permission notice -are preserved on all copies. - -@ignore -Permission is granted to process this file through Tex and print the -results, provided the printed document carries copying permission -notice identical to this one except for the removal of this paragraph -(this paragraph not being relevant to the printed manual). - -@end ignore -Permission is granted to copy and distribute modified versions of this -manual under the conditions for verbatim copying, provided also that the -entire resulting derived work is distributed under the terms of a -permission notice identical to this one. - -Permission is granted to copy and distribute translations of this manual -into another language, under the above conditions for modified versions. -@end ifinfo - -@tex - -@titlepage -@title Message 5.6.44 Manual - -@author by Lars Magne Ingebrigtsen -@page - -@vskip 0pt plus 1filll -Copyright @copyright{} 1996 Free Software Foundation, Inc. - -Permission is granted to make and distribute verbatim copies of -this manual provided the copyright notice and this permission notice -are preserved on all copies. - -Permission is granted to copy and distribute modified versions of this -manual under the conditions for verbatim copying, provided that the -entire resulting derived work is distributed under the terms of a -permission notice identical to this one. - -Permission is granted to copy and distribute translations of this manual -into another language, under the above conditions for modified versions. - -@end titlepage -@page - -@end tex - -@node Top -@top Message - -All message composition from Gnus (both mail and news) takes place in -Message mode buffers. - -@menu -* Interface:: Setting up message buffers. -* Commands:: Commands you can execute in message mode buffers. -* Variables:: Customizing the message buffers. -* Compatibility:: Making Message backwards compatible. -* Appendices:: More technical things. -* Index:: Variable, function and concept index. -* Key Index:: List of Message mode keys. -@end menu - -This manual corresponds to Message 5.6.44. Message is distributed with -the Gnus distribution bearing the same version number as this manual -has. - - -@node Interface -@chapter Interface - -When a program (or a person) wants to respond to a message -- reply, -follow up, forward, cancel -- the program (or person) should just put -point in the buffer where the message is and call the required command. -@code{Message} will then pop up a new @code{message} mode buffer with -appropriate headers filled out, and the user can edit the message before -sending it. - -@menu -* New Mail Message:: Editing a brand new mail message. -* New News Message:: Editing a brand new news message. -* Reply:: Replying via mail. -* Wide Reply:: Responding to all people via mail. -* Followup:: Following up via news. -* Canceling News:: Canceling a news article. -* Superseding:: Superseding a message. -* Forwarding:: Forwarding a message via news or mail. -* Resending:: Resending a mail message. -* Bouncing:: Bouncing a mail message. -@end menu - - -@node New Mail Message -@section New Mail Message - -@findex message-mail -The @code{message-mail} command pops up a new message buffer. - -Two optional parameters are accepted: The first will be used as the -@code{To} header and the second as the @code{Subject} header. If these -are @code{nil}, those two headers will be empty. - - -@node New News Message -@section New News Message - -@findex message-news -The @code{message-news} command pops up a new message buffer. - -This function accepts two optional parameters. The first will be used -as the @code{Newsgroups} header and the second as the @code{Subject} -header. If these are @code{nil}, those two headers will be empty. - - -@node Reply -@section Reply - -@findex message-reply -The @code{message-reply} function pops up a message buffer that's a -reply to the message in the current buffer. - -@vindex message-reply-to-function -Message uses the normal methods to determine where replies are to go -(@pxref{Responses}), but you can change the behavior to suit your needs -by fiddling with the @code{message-reply-to-function} variable. - -If you want the replies to go to the @code{Sender} instead of the -@code{From}, you could do something like this: - -@lisp -(setq message-reply-to-function - (lambda () - (cond ((equal (mail-fetch-field "from") "somebody") - (mail-fetch-field "sender")) - (t - nil)))) -@end lisp - -This function will be called narrowed to the head of the article that is -being replied to. - -As you can see, this function should return a string if it has an -opinion as to what the To header should be. If it does not, it should -just return @code{nil}, and the normal methods for determining the To -header will be used. - -This function can also return a list. In that case, each list element -should be a cons, where the car should be the name of an header -(eg. @code{Cc}) and the cdr should be the header value -(eg. @samp{larsi@@ifi.uio.no}). All these headers will be inserted into -the head of the outgoing mail. - - -@node Wide Reply -@section Wide Reply - -@findex message-wide-reply -The @code{message-wide-reply} pops up a message buffer that's a wide -reply to the message in the current buffer. A @dfn{wide reply} is a -reply that goes out to all people listed in the @code{To}, @code{From} -(or @code{Reply-to}) and @code{Cc} headers. - -@vindex message-wide-reply-to-function -Message uses the normal methods to determine where wide replies are to go, -but you can change the behavior to suit your needs by fiddling with the -@code{message-wide-reply-to-function}. It is used in the same way as -@code{message-reply-to-function} (@pxref{Reply}). - -@findex rmail-dont-reply-to-names -Addresses that match the @code{rmail-dont-reply-to-names} regular -expression will be removed from the @code{Cc} header. - - -@node Followup -@section Followup - -@findex message-followup -The @code{message-followup} command pops up a message buffer that's a -followup to the message in the current buffer. - -@vindex message-followup-to-function -Message uses the normal methods to determine where followups are to go, -but you can change the behavior to suit your needs by fiddling with the -@code{message-followup-to-function}. It is used in the same way as -@code{message-reply-to-function} (@pxref{Reply}). - -@vindex message-use-followup-to -The @code{message-use-followup-to} variable says what to do about -@code{Followup-To} headers. If it is @code{use}, always use the value. -If it is @code{ask} (which is the default), ask whether to use the -value. If it is @code{t}, use the value unless it is @samp{poster}. If -it is @code{nil}, don't use the value. - - -@node Canceling News -@section Canceling News - -@findex message-cancel-news -The @code{message-cancel-news} command cancels the article in the -current buffer. - - -@node Superseding -@section Superseding - -@findex message-supersede -The @code{message-supersede} command pops up a message buffer that will -supersede the message in the current buffer. - -@vindex message-ignored-supersedes-headers -Headers matching the @code{message-ignored-supersedes-headers} are -removed before popping up the new message buffer. The default is@* -@samp{^Path:\\|^Date\\|^NNTP-Posting-Host:\\|^Xref:\\|^Lines:\\|@* -^Received:\\|^X-From-Line:\\|Return-Path:\\|^Supersedes:}. - - - -@node Forwarding -@section Forwarding - -@findex message-forward -The @code{message-forward} command pops up a message buffer to forward -the message in the current buffer. If given a prefix, forward using -news. - -@table @code -@item message-forward-start-separator -@vindex message-forward-start-separator -Delimiter inserted before forwarded messages. The default is@* -@samp{------- Start of forwarded message -------\n}. - -@vindex message-forward-end-separator -@item message-forward-end-separator -@vindex message-forward-end-separator -Delimiter inserted after forwarded messages. The default is@* -@samp{------- End of forwarded message -------\n}. - -@item message-signature-before-forwarded-message -@vindex message-signature-before-forwarded-message -If this variable is @code{t}, which it is by default, your personal -signature will be inserted before the forwarded message. If not, the -forwarded message will be inserted first in the new mail. - -@item message-included-forward-headers -@vindex message-included-forward-headers -Regexp matching header lines to be included in forwarded messages. - -@item message-make-forward-subject-function -@vindex message-make-forward-subject-function -A list of functions that are called to generate a subject header for -forwarded messages. The subject generated by the previous function is -passed into each successive function. - -The provided functions are: - -@table @code -@item message-forward-subject-author-subject -@findex message-forward-subject-author-subject -Source of article (author or newsgroup), in brackets followed by the -subject. - -@item message-forward-subject-fwd -Subject of article with @samp{Fwd:} prepended to it. -@end table - -@item message-wash-forwarded-subjects -@vindex message-wash-forwarded-subjects -If this variable is @code{t}, the subjects of forwarded messages have -the evidence of previous forwards (such as @samp{Fwd:}, @samp{Re:}, -@samp{(fwd)}) removed before the new subject is -constructed. The default value is @code{nil}. - -@end table - - -@node Resending -@section Resending - -@findex message-resend -The @code{message-resend} command will prompt the user for an address -and resend the message in the current buffer to that address. - -@vindex message-ignored-resent-headers -Headers that match the @code{message-ignored-resent-headers} regexp will -be removed before sending the message. The default is -@samp{^Return-receipt}. - - -@node Bouncing -@section Bouncing - -@findex message-bounce -The @code{message-bounce} command will, if the current buffer contains a -bounced mail message, pop up a message buffer stripped of the bounce -information. A @dfn{bounced message} is typically a mail you've sent -out that has been returned by some @code{mailer-daemon} as -undeliverable. - -@vindex message-ignored-bounced-headers -Headers that match the @code{message-ignored-bounced-headers} regexp -will be removed before popping up the buffer. The default is -@samp{^\\(Received\\|Return-Path\\):}. - - -@node Commands -@chapter Commands - -@menu -* Header Commands:: Commands for moving to headers. -* Movement:: Moving around in message buffers. -* Insertion:: Inserting things into message buffers. -* Various Commands:: Various things. -* Sending:: Actually sending the message. -* Mail Aliases:: How to use mail aliases. -@end menu - - -@node Header Commands -@section Header Commands - -All these commands move to the header in question. If it doesn't exist, -it will be inserted. - -@table @kbd - -@item C-c ? -@kindex C-c ? -@findex message-goto-to -Describe the message mode. - -@item C-c C-f C-t -@kindex C-c C-f C-t -@findex message-goto-to -Go to the @code{To} header (@code{message-goto-to}). - -@item C-c C-f C-b -@kindex C-c C-f C-b -@findex message-goto-bcc -Go to the @code{Bcc} header (@code{message-goto-bcc}). - -@item C-c C-f C-f -@kindex C-c C-f C-f -@findex message-goto-fcc -Go to the @code{Fcc} header (@code{message-goto-fcc}). - -@item C-c C-f C-c -@kindex C-c C-f C-c -@findex message-goto-cc -Go to the @code{Cc} header (@code{message-goto-cc}). - -@item C-c C-f C-s -@kindex C-c C-f C-s -@findex message-goto-subject -Go to the @code{Subject} header (@code{message-goto-subject}). - -@item C-c C-f C-r -@kindex C-c C-f C-r -@findex message-goto-reply-to -Go to the @code{Reply-To} header (@code{message-goto-reply-to}). - -@item C-c C-f C-n -@kindex C-c C-f C-n -@findex message-goto-newsgroups -Go to the @code{Newsgroups} header (@code{message-goto-newsgroups}). - -@item C-c C-f C-d -@kindex C-c C-f C-d -@findex message-goto-distribution -Go to the @code{Distribution} header (@code{message-goto-distribution}). - -@item C-c C-f C-o -@kindex C-c C-f C-o -@findex message-goto-followup-to -Go to the @code{Followup-To} header (@code{message-goto-followup-to}). - -@item C-c C-f C-k -@kindex C-c C-f C-k -@findex message-goto-keywords -Go to the @code{Keywords} header (@code{message-goto-keywords}). - -@item C-c C-f C-u -@kindex C-c C-f C-u -@findex message-goto-summary -Go to the @code{Summary} header (@code{message-goto-summary}). - -@end table - - -@node Movement -@section Movement - -@table @kbd -@item C-c C-b -@kindex C-c C-b -@findex message-goto-body -Move to the beginning of the body of the message -(@code{message-goto-body}). - -@item C-c C-i -@kindex C-c C-i -@findex message-goto-signature -Move to the signature of the message (@code{message-goto-signature}). - -@end table - - -@node Insertion -@section Insertion - -@table @kbd - -@item C-c C-y -@kindex C-c C-y -@findex message-yank-original -Yank the message that's being replied to into the message buffer -(@code{message-yank-original}). - -@item C-c C-q -@kindex C-c C-q -@findex message-fill-yanked-message -Fill the yanked message (@code{message-fill-yanked-message}). Warning: -Can severely mess up the yanked text if its quoting conventions are -strange. You'll quickly get a feel for when it's safe, though. Anyway, -just remember that @kbd{C-x u} (@code{undo}) is available and you'll be -all right. - - -@item C-c C-w -@kindex C-c C-w -@findex message-insert-signature -Insert a signature at the end of the buffer -(@code{message-insert-signature}). - -@end table - -@table @code -@item message-ignored-cited-headers -@vindex message-ignored-cited-headers -All headers that match this regexp will be removed from yanked -messages. The default is @samp{.}, which means that all headers will be -removed. - -@item message-citation-line-function -@vindex message-citation-line-function -Function called to insert the citation line. The default is -@code{message-insert-citation-line}, which will lead to citation lines -that look like: - -@example -Hallvard B Furuseth writes: -@end example - -Point will be at the beginning of the body of the message when this -function is called. - -@item message-yank-prefix -@vindex message-yank-prefix -@cindex yanking -@cindex quoting -When you are replying to or following up an article, you normally want -to quote the person you are answering. Inserting quoted text is done by -@dfn{yanking}, and each quoted line you yank will have -@code{message-yank-prefix} prepended to it. The default is @samp{> }. -If it is @code{nil}, just indent the message. - -@item message-indentation-spaces -@vindex message-indentation-spaces -Number of spaces to indent yanked messages. - -@item message-cite-function -@vindex message-cite-function -@findex message-cite-original -@findex sc-cite-original -@findex message-cite-original-without-signature -@cindex Supercite -Function for citing an original message. The default is -@code{message-cite-original}, which simply inserts the original message -and prepends @samp{> } to each line. -@code{message-cite-original-without-signature} does the same, but elides -the signature. You can also set it to @code{sc-cite-original} to use -Supercite. - -@item message-indent-citation-function -@vindex message-indent-citation-function -Function for modifying a citation just inserted in the mail buffer. -This can also be a list of functions. Each function can find the -citation between @code{(point)} and @code{(mark t)}. And each function -should leave point and mark around the citation text as modified. - -@item message-signature -@vindex message-signature -String to be inserted at the end of the message buffer. If @code{t} -(which is the default), the @code{message-signature-file} file will be -inserted instead. If a function, the result from the function will be -used instead. If a form, the result from the form will be used instead. -If this variable is @code{nil}, no signature will be inserted at all. - -@item message-signature-file -@vindex message-signature-file -File containing the signature to be inserted at the end of the buffer. -The default is @samp{~/.signature}. - -@end table - -Note that RFC1036bis says that a signature should be preceded by the three -characters @samp{-- } on a line by themselves. This is to make it -easier for the recipient to automatically recognize and process the -signature. So don't remove those characters, even though you might feel -that they ruin your beautiful design, like, totally. - -Also note that no signature should be more than four lines long. -Including ASCII graphics is an efficient way to get everybody to believe -that you are silly and have nothing important to say. - - - -@node Various Commands -@section Various Commands - -@table @kbd - -@item C-c C-r -@kindex C-c C-r -@findex message-caesar-buffer-body -Caesar rotate (aka. rot13) the current message -(@code{message-caesar-buffer-body}). If narrowing is in effect, just -rotate the visible portion of the buffer. A numerical prefix says how -many places to rotate the text. The default is 13. - -@item C-c C-e -@kindex C-c C-e -@findex message-elide-region -Elide the text between point and mark (@code{message-elide-region}). -The text is killed and an ellipsis (@samp{[...]}) will be inserted in -its place. - -@item C-c C-z -@kindex C-c C-x -@findex message-kill-to-signature -Kill all the text up to the signature, or if that's missing, up to the -end of the message (@code{message-kill-to-signature}). - -@item C-c C-v -@kindex C-c C-v -@findex message-delete-not-region -Delete all text in the body of the message that is outside the region -(@code{message-delete-not-region}). - -@item M-RET -@kindex M-RET -@kindex message-newline-and-reformat -Insert four newlines, and then reformat if inside quoted text. - -Here's an example: - -@example -> This is some quoted text. And here's more quoted text. -@end example - -If point is before @samp{And} and you press @kbd{M-RET}, you'll get: - -@example -> This is some quoted text. - -* - -> And here's more quoted text. -@end example - -@samp{*} says where point will be placed. - -@item C-c C-t -@kindex C-c C-t -@findex message-insert-to -Insert a @code{To} header that contains the @code{Reply-To} or -@code{From} header of the message you're following up -(@code{message-insert-to}). - -@item C-c C-n -@kindex C-c C-n -@findex message-insert-newsgroups -Insert a @code{Newsgroups} header that reflects the @code{Followup-To} -or @code{Newsgroups} header of the article you're replying to -(@code{message-insert-newsgroups}). - -@item C-c M-r -@kindex C-c M-r -@findex message-rename-buffer -Rename the buffer (@code{message-rename-buffer}). If given a prefix, -prompt for a new buffer name. - -@end table - - -@node Sending -@section Sending - -@table @kbd -@item C-c C-c -@kindex C-c C-c -@findex message-send-and-exit -Send the message and bury the current buffer -(@code{message-send-and-exit}). - -@item C-c C-s -@kindex C-c C-s -@findex message-send -Send the message (@code{message-send}). - -@item C-c C-d -@kindex C-c C-d -@findex message-dont-send -Bury the message buffer and exit (@code{message-dont-send}). - -@item C-c C-k -@kindex C-c C-k -@findex message-kill-buffer -Kill the message buffer and exit (@code{message-kill-buffer}). - -@end table - - - -@node Mail Aliases -@section Mail Aliases -@cindex mail aliases -@cindex aliases - -@vindex message-mail-alias-type -The @code{message-mail-alias-type} variable controls what type of mail -alias expansion to use. Currently only one form is supported---Message -uses @code{mailabbrev} to handle mail aliases. If this variable is -@code{nil}, no mail alias expansion will be performed. - -@code{mailabbrev} works by parsing the @file{/etc/mailrc} and -@file{~/.mailrc} files. These files look like: - -@example -alias lmi "Lars Magne Ingebrigtsen " -alias ding "ding@@ifi.uio.no (ding mailing list)" -@end example - -After adding lines like this to your @file{~/.mailrc} file, you should -be able to just write @samp{lmi} in the @code{To} or @code{Cc} (and so -on) headers and press @kbd{SPC} to expand the alias. - -No expansion will be performed upon sending of the message---all -expansions have to be done explicitly. - - - -@node Variables -@chapter Variables - -@menu -* Message Headers:: General message header stuff. -* Mail Headers:: Customizing mail headers. -* Mail Variables:: Other mail variables. -* News Headers:: Customizing news headers. -* News Variables:: Other news variables. -* Various Message Variables:: Other message variables. -* Sending Variables:: Variables for sending. -* Message Buffers:: How Message names its buffers. -* Message Actions:: Actions to be performed when exiting. -@end menu - - -@node Message Headers -@section Message Headers - -Message is quite aggressive on the message generation front. It has to -be -- it's a combined news and mail agent. To be able to send combined -messages, it has to generate all headers itself (instead of letting the -mail/news system do it) to ensure that mail and news copies of messages -look sufficiently similar. - -@table @code - -@item message-generate-headers-first -@vindex message-generate-headers-first -If non-@code{nil}, generate all headers before starting to compose the -message. - -@item message-from-style -@vindex message-from-style -Specifies how @code{From} headers should look. There are four valid -values: - -@table @code -@item nil -Just the address -- @samp{king@@grassland.com}. - -@item parens -@samp{king@@grassland.com (Elvis Parsley)}. - -@item angles -@samp{Elvis Parsley }. - -@item default -Look like @code{angles} if that doesn't require quoting, and -@code{parens} if it does. If even @code{parens} requires quoting, use -@code{angles} anyway. - -@end table - -@item message-deletable-headers -@vindex message-deletable-headers -Headers in this list that were previously generated by Message will be -deleted before posting. Let's say you post an article. Then you decide -to post it again to some other group, you naughty boy, so you jump back -to the @code{*post-buf*} buffer, edit the @code{Newsgroups} line, and -ship it off again. By default, this variable makes sure that the old -generated @code{Message-ID} is deleted, and a new one generated. If -this isn't done, the entire empire would probably crumble, anarchy would -prevail, and cats would start walking on two legs and rule the world. -Allegedly. - -@item message-default-headers -@vindex message-default-headers -This string is inserted at the end of the headers in all message -buffers. - -@item message-subject-re-regexp -@vindex message-subject-re-regexp -Responses to messages have subjects that start with @samp{Re: }. This -is @emph{not} an abbreviation of the English word ``response'', but in -Latin, and means ``in response to''. Some illiterate nincompoops have -failed to grasp this fact, and have ``internationalized'' their software -to use abonimations like @samp{Aw: } (``antwort'') or @samp{Sv: } -(``svar'') instead, which is meaningless and evil. However, you may -have to deal with users that use these evil tools, in which case you may -set this variable to a regexp that matches these prefixes. Myself, I -just throw away non-compliant mail. - -@end table - - -@node Mail Headers -@section Mail Headers - -@table @code -@item message-required-mail-headers -@vindex message-required-mail-headers -@xref{News Headers}, for the syntax of this variable. It is -@code{(From Date Subject (optional . In-Reply-To) Message-ID Lines -(optional . X-Mailer))} by default. - -@item message-ignored-mail-headers -@vindex message-ignored-mail-headers -Regexp of headers to be removed before mailing. The default is -@samp{^[GF]cc:\\|^Resent-Fcc:}. - -@item message-default-mail-headers -@vindex message-default-mail-headers -This string is inserted at the end of the headers in all message -buffers that are initialized as mail. - -@end table - - -@node Mail Variables -@section Mail Variables - -@table @code -@item message-send-mail-function -@vindex message-send-mail-function -Function used to send the current buffer as mail. The default is -@code{message-send-mail-with-sendmail}. If you prefer using MH -instead, set this variable to @code{message-send-mail-with-mh}. - -@item message-mh-deletable-headers -@vindex message-mh-deletable-headers -Most versions of MH doesn't like being fed messages that contain the -headers in this variable. If this variable is non-@code{nil} (which is -the default), these headers will be removed before mailing when sending -messages via MH. Set it to @code{nil} if your MH can handle these -headers. - -@end table - - -@node News Headers -@section News Headers - -@vindex message-required-news-headers -@code{message-required-news-headers} a list of header symbols. These -headers will either be automatically generated, or, if that's -impossible, they will be prompted for. The following symbols are valid: - -@table @code - -@item From -@cindex From -@findex user-full-name -@findex user-mail-address -This required header will be filled out with the result of the -@code{message-make-from} function, which depends on the -@code{message-from-style}, @code{user-full-name}, -@code{user-mail-address} variables. - -@item Subject -@cindex Subject -This required header will be prompted for if not present already. - -@item Newsgroups -@cindex Newsgroups -This required header says which newsgroups the article is to be posted -to. If it isn't present already, it will be prompted for. - -@item Organization -@cindex organization -This optional header will be filled out depending on the -@code{message-user-organization} variable. -@code{message-user-organization-file} will be used if this variable is -@code{t}. This variable can also be a string (in which case this string -will be used), or it can be a function (which will be called with no -parameters and should return a string to be used). - -@item Lines -@cindex Lines -This optional header will be computed by Message. - -@item Message-ID -@cindex Message-ID -@vindex mail-host-address -@findex system-name -@cindex Sun -This required header will be generated by Message. A unique ID will be -created based on the date, time, user name and system name. Message will -use @code{mail-host-address} as the fully qualified domain name (FQDN) -of the machine if that variable is defined. If not, it will use -@code{system-name}, which doesn't report a FQDN on some machines -- -notably Suns. - -@item X-Newsreader -@cindex X-Newsreader -This optional header will be filled out according to the -@code{message-newsreader} local variable. - -@item X-Mailer -This optional header will be filled out according to the -@code{message-mailer} local variable, unless there already is an -@code{X-Newsreader} header present. - -@item In-Reply-To -This optional header is filled out using the @code{Date} and @code{From} -header of the article being replied to. - -@item Expires -@cindex Expires -This extremely optional header will be inserted according to the -@code{message-expires} variable. It is highly deprecated and shouldn't -be used unless you know what you're doing. - -@item Distribution -@cindex Distribution -This optional header is filled out according to the -@code{message-distribution-function} variable. It is a deprecated and -much misunderstood header. - -@item Path -@cindex path -This extremely optional header should probably never be used. -However, some @emph{very} old servers require that this header is -present. @code{message-user-path} further controls how this -@code{Path} header is to look. If it is @code{nil}, use the server name -as the leaf node. If it is a string, use the string. If it is neither -a string nor @code{nil}, use the user name only. However, it is highly -unlikely that you should need to fiddle with this variable at all. -@end table - -@findex yow -@cindex Mime-Version -In addition, you can enter conses into this list. The car of this cons -should be a symbol. This symbol's name is the name of the header, and -the cdr can either be a string to be entered verbatim as the value of -this header, or it can be a function to be called. This function should -return a string to be inserted. For instance, if you want to insert -@code{Mime-Version: 1.0}, you should enter @code{(Mime-Version . "1.0")} -into the list. If you want to insert a funny quote, you could enter -something like @code{(X-Yow . yow)} into the list. The function -@code{yow} will then be called without any arguments. - -If the list contains a cons where the car of the cons is -@code{optional}, the cdr of this cons will only be inserted if it is -non-@code{nil}. - -Other variables for customizing outgoing news articles: - -@table @code - -@item message-syntax-checks -@vindex message-syntax-checks -Controls what syntax checks should not be performed on outgoing posts. -To disable checking of long signatures, for instance, add - -@lisp -(signature . disabled) -@end lisp - -to this list. - -Valid checks are: - -@table @code -@item subject-cmsg -Check the subject for commands. -@item sender -@cindex Sender -Insert a new @code{Sender} header if the @code{From} header looks odd. -@item multiple-headers -Check for the existence of multiple equal headers. -@item sendsys -@cindex sendsys -Check for the existence of version and sendsys commands. -@item message-id -Check whether the @code{Message-ID} looks ok. -@item from -Check whether the @code{From} header seems nice. -@item long-lines -@cindex long lines -Check for too long lines. -@item control-chars -Check for invalid characters. -@item size -Check for excessive size. -@item new-text -Check whether there is any new text in the messages. -@item signature -Check the length of the signature. -@item approved -@cindex approved -Check whether the article has an @code{Approved} header, which is -something only moderators should include. -@item empty -Check whether the article is empty. -@item empty-headers -Check whether any of the headers are empty. -@item existing-newsgroups -Check whether the newsgroups mentioned in the @code{Newsgroups} and -@code{Followup-To} headers exist. -@item valid-newsgroups -Check whether the @code{Newsgroups} and @code{Followup-to} headers -are valid syntactically. -@item repeated-newsgroups -Check whether the @code{Newsgroups} and @code{Followup-to} headers -contains repeated group names. -@item shorten-followup-to -Check whether to add a @code{Followup-to} header to shorten the number -of groups to post to. -@end table - -All these conditions are checked by default. - -@item message-ignored-news-headers -@vindex message-ignored-news-headers -Regexp of headers to be removed before posting. The default is@* -@samp{^NNTP-Posting-Host:\\|^Xref:\\|^[BGF]cc:\\|^Resent-Fcc:}. - -@item message-default-news-headers -@vindex message-default-news-headers -This string is inserted at the end of the headers in all message -buffers that are initialized as news. - -@end table - - -@node News Variables -@section News Variables - -@table @code -@item message-send-news-function -@vindex message-send-news-function -Function used to send the current buffer as news. The default is -@code{message-send-news}. - -@item message-post-method -@vindex message-post-method -Gnusish @dfn{select method} (see the Gnus manual for details) used for -posting a prepared news message. - -@end table - - -@node Various Message Variables -@section Various Message Variables - -@table @code -@item message-signature-separator -@vindex message-signature-separator -Regexp matching the signature separator. It is @samp{^-- *$} by -default. - -@item mail-header-separator -@vindex mail-header-separator -String used to separate the headers from the body. It is @samp{--text -follows this line--} by default. - -@item message-directory -@vindex message-directory -Directory used by many mailey things. The default is @file{~/Mail/}. - -@item message-signature-setup-hook -@vindex message-signature-setup-hook -Hook run when initializing the message buffer. It is run after the -headers have been inserted but before the signature has been inserted. - -@item message-setup-hook -@vindex message-setup-hook -Hook run as the last thing when the message buffer has been initialized, -but before yanked text is inserted. - -@item message-header-setup-hook -@vindex message-header-setup-hook -Hook called narrowed to the headers after initializing the headers. - -For instance, if you're running Gnus and wish to insert a -@samp{Mail-Copies-To} header in all your news articles and all messages -you send to mailing lists, you could do something like the following: - -@lisp -(defun my-message-header-setup-hook () - (let ((group (or gnus-newsgroup-name ""))) - (when (or (message-fetch-field "newsgroups") - (gnus-group-find-parameter group 'to-address) - (gnus-group-find-parameter group 'to-list)) - (insert "Mail-Copies-To: never\n")))) - -(add-hook 'message-header-setup-hook - 'my-message-header-setup-hook) -@end lisp - -@item message-send-hook -@vindex message-send-hook -Hook run before sending messages. - -If you want to add certain headers before sending, you can use the -@code{message-add-header} function in this hook. For instance: -@findex message-add-header - -@lisp -(add-hook 'message-send-hook 'my-message-add-content) -(defun my-message-add-content () - (message-add-header - "Mime-Version: 1.0" - "Content-Type: text/plain" - "Content-Transfer-Encoding: 7bit")) -@end lisp - -This function won't add the header if the header is already present. - -@item message-send-mail-hook -@vindex message-send-mail-hook -Hook run before sending mail messages. - -@item message-send-news-hook -@vindex message-send-news-hook -Hook run before sending news messages. - -@item message-sent-hook -@vindex message-sent-hook -Hook run after sending messages. - -@item message-mode-syntax-table -@vindex message-mode-syntax-table -Syntax table used in message mode buffers. - -@item message-send-method-alist -@vindex message-send-method-alist - -Alist of ways to send outgoing messages. Each element has the form - -@lisp -(TYPE PREDICATE FUNCTION) -@end lisp - -@table @var -@item type -A symbol that names the method. - -@item predicate -A function called without any parameters to determine whether the -message is a message of type @var{type}. - -@item function -A function to be called if @var{predicate} returns non-@code{nil}. -@var{function} is called with one parameter -- the prefix. -@end table - -@lisp -((news message-news-p message-send-via-news) - (mail message-mail-p message-send-via-mail)) -@end lisp - - - -@end table - - - -@node Sending Variables -@section Sending Variables - -@table @code - -@item message-fcc-handler-function -@vindex message-fcc-handler-function -A function called to save outgoing articles. This function will be -called with the name of the file to store the article in. The default -function is @code{message-output} which saves in Unix mailbox format. - -@item message-courtesy-message -@vindex message-courtesy-message -When sending combined messages, this string is inserted at the start of -the mailed copy. If the string contains the format spec @samp{%s}, the -newsgroups the article has been posted to will be inserted there. If -this variable is @code{nil}, no such courtesy message will be added. -The default value is @samp{"The following message is a courtesy copy of -an article\nthat has been posted to %s as well.\n\n"}. - -@end table - - -@node Message Buffers -@section Message Buffers - -Message will generate new buffers with unique buffer names when you -request a message buffer. When you send the message, the buffer isn't -normally killed off. Its name is changed and a certain number of old -message buffers are kept alive. - -@table @code -@item message-generate-new-buffers -@vindex message-generate-new-buffers -If non-@code{nil}, generate new buffers. The default is @code{t}. If -this is a function, call that function with three parameters: The type, -the to address and the group name. (Any of these may be @code{nil}.) -The function should return the new buffer name. - -@item message-max-buffers -@vindex message-max-buffers -This variable says how many old message buffers to keep. If there are -more message buffers than this, the oldest buffer will be killed. The -default is 10. If this variable is @code{nil}, no old message buffers -will ever be killed. - -@item message-send-rename-function -@vindex message-send-rename-function -After sending a message, the buffer is renamed from, for instance, -@samp{*reply to Lars*} to @samp{*sent reply to Lars*}. If you don't -like this, set this variable to a function that renames the buffer in a -manner you like. If you don't want to rename the buffer at all, you can -say: - -@lisp -(setq message-send-rename-function 'ignore) -@end lisp - -@item message-kill-buffer-on-exit -@findex message-kill-buffer-on-exit -If non-@code{nil}, kill the buffer immediately on exit. - -@end table - - -@node Message Actions -@section Message Actions - -When Message is being used from a news/mail reader, the reader is likely -to want to perform some task after the message has been sent. Perhaps -return to the previous window configuration or mark an article as -replied. - -@vindex message-kill-actions -@vindex message-postpone-actions -@vindex message-exit-actions -@vindex message-send-actions -The user may exit from the message buffer in various ways. The most -common is @kbd{C-c C-c}, which sends the message and exits. Other -possibilities are @kbd{C-c C-s} which just sends the message, @kbd{C-c -C-d} which postpones the message editing and buries the message buffer, -and @kbd{C-c C-k} which kills the message buffer. Each of these actions -have lists associated with them that contains actions to be executed: -@code{message-send-actions}, @code{message-exit-actions}, -@code{message-postpone-actions}, and @code{message-kill-actions}. - -Message provides a function to interface with these lists: -@code{message-add-action}. The first parameter is the action to be -added, and the rest of the arguments are which lists to add this action -to. Here's an example from Gnus: - -@lisp - (message-add-action - `(set-window-configuration ,(current-window-configuration)) - 'exit 'postpone 'kill) -@end lisp - -This restores the Gnus window configuration when the message buffer is -killed, postponed or exited. - -An @dfn{action} can be either: a normal function, or a list where the -@code{car} is a function and the @code{cdr} is the list of arguments, or -a form to be @code{eval}ed. - - -@node Compatibility -@chapter Compatibility -@cindex compatibility - -Message uses virtually only its own variables---older @code{mail-} -variables aren't consulted. To force Message to take those variables -into account, you can put the following in your @code{.emacs} file: - -@lisp -(require 'messcompat) -@end lisp - -This will initialize many Message variables from the values in the -corresponding mail variables. - - -@node Appendices -@chapter Appendices - -@menu -* Responses:: Standard rules for determining where responses go. -@end menu - - -@node Responses -@section Responses - -To determine where a message is to go, the following algorithm is used -by default. - -@table @dfn -@item reply -A @dfn{reply} is when you want to respond @emph{just} to the person who -sent the message via mail. There will only be one recipient. To -determine who the recipient will be, the following headers are -consulted, in turn: - -@table @code -@item Reply-To - -@item From -@end table - - -@item wide reply -A @dfn{wide reply} is a mail response that includes @emph{all} entities -mentioned in the message you are responded to. All mailboxes from the -following headers will be concatenated to form the outgoing -@code{To}/@code{Cc} headers: - -@table @code -@item From -(unless there's a @code{Reply-To}, in which case that is used instead). - -@item Cc - -@item To -@end table - -If a @code{Mail-Copies-To} header is present, it will also be included -in the list of mailboxes. If this header is @samp{never}, that means -that the @code{From} (or @code{Reply-To}) mailbox will be suppressed. - - -@item followup -A @dfn{followup} is a response sent via news. The following headers -(listed in order of precedence) determine where the response is to be -sent: - -@table @code - -@item Followup-To - -@item Newsgroups - -@end table - -If a @code{Mail-Copies-To} header is present, it will be used as the -basis of the new @code{Cc} header, except if this header is -@samp{never}. - -@end table - - - -@node Index -@chapter Index -@printindex cp - -@node Key Index -@chapter Key Index -@printindex ky - -@summarycontents -@contents -@bye - -@c End: diff --git a/texi/postamble.tex b/texi/postamble.tex deleted file mode 100644 index 3b5f803..0000000 --- a/texi/postamble.tex +++ /dev/null @@ -1,49 +0,0 @@ -\gnuscleardoublepage - -\pagestyle{gnusindex} - -\renewcommand\indexname{Key Index} -\renewcommand{\gnuschaptername}{Key Index} -\input{gnus.kind} -\gnuscleardoublepage - -\renewcommand\indexname{Function and Variable Index} -\renewcommand{\gnuschaptername}{Function and Variable Index} -\input{gnus.gind} -\gnuscleardoublepage -\thispagestyle{empty} - -\renewcommand\indexname{Concept Index} -\renewcommand{\gnuschaptername}{Concept Index} -\input{gnus.cind} - -\mbox{} -%\thispagestyle{empty}\mbox{}\clearpage\thispagestyle{empty}\mbox{}\clearpage -\ifodd\count0\else\thispagestyle{empty}\clearpage\fi -\mbox{} -\thispagestyle{empty} -\vfill - -\begin{picture}(10,10) -\put(90,-10){\makebox(0,0)[tr]{\epsfig{figure=tmp/larsi.ps,height=3cm}}} -\end{picture} - -\hspace*{4cm}\parbox[t]{10cm}{ -This manual was written by Lars Magne Ingebrigtsen (b. 1968) who -resides in Oslo, Norway and poses as a student, but doesn't get much -studying done, for some strange reason or other. When not worshipping -at the altar of Emacs, he can often be found slouching on his couch -reading while bopping his head gently to some obscure music. He does -not have a cat. - -Graphics by Luis Fernandes. Set in Bembo and Futura. -} - -\clearpage -\mbox{} -\thispagestyle{empty} -\begin{picture}(500,500)(0,0) -\put(-35,325){\makebox(480,350)[tr]{\epsfig{figure=tmp/new-herd-section.ps}}} -\end{picture} - -\end{document} diff --git a/texi/refcard.tex b/texi/refcard.tex deleted file mode 100644 index a701cd4..0000000 --- a/texi/refcard.tex +++ /dev/null @@ -1,65 +0,0 @@ -% Reference Card for (ding) Gnus, 3 twocolumn pages. -% To be processed with latex 2.09 -\def\Guide{Card}\def\guide{card} -\def\logoscale{0.25} -\def\sec{\section*} -\def\subsec{\subsection*} -\def\subsubsec{\subsubsection*} -\documentstyle{article} -\textwidth 7.26in \textheight 10in \topmargin -1.0in -% the same settings work for A4, although there is a bit of space at the -% top and bottom of the page. -\oddsidemargin -0.5in \evensidemargin -0.5in -\begin{document} -\twocolumn\scriptsize\pagestyle{empty} -\input{gnusref} - -% page 1, left column -\Title -\par -\vspace{0.5\baselineskip} -\Logo{refcard} -\vspace*{\fill} -\GroupLevels -\GroupMode -\pagebreak - -% page 1, right column -\Notes -\vspace*{\fill} -\GroupCommands -\pagebreak - -% page 2, left column -\SummaryMode -\Asubmap -\Bsubmap -\Gsubmap -\Hsubmap -\Tsubmap -\pagebreak - -% page 2, right column -\Msubmap -\Marks -\pagebreak - -% page 3 -\Osubmap -\Ssubmap -\Xsubmap -\Vsubmap -\SortSummary -\Wsubmap -\Zsubmap -\ArticleMode -\ServerMode - -% page 4 -\BrowseServer -\pagebreak -\onecolumn -\vspace*{\fill} -\CopyRight - -\end{document}