diff --exclude=*.elc --exclude=*~ --exclude=*-[0-9] --exclude=gnus --exclude=readme --context --recursive pub/dgnus/lisp/ChangeLog dgnus/lisp/ChangeLog *** pub/dgnus/lisp/ChangeLog Sun Apr 2 12:57:38 1995 --- dgnus/lisp/ChangeLog Fri Apr 14 02:11:57 1995 *************** *** 1,4 **** --- 1,146 ---- + Fri Apr 14 00:29:43 1995 Lars Magne Ingebrigtsen + + * gnus.el (gnus-list-active-group): New function. + (gnus-browse-server-mode-map): New keystrokes: `l' and + `L', which both return to the group buffer. + + * nntp.el (nntp-list-active-group): New function. + + * gnus.el: New spec for current score file. + (gnus-simplify-subject-fuzzy): Made fuzzier on white space. + (gnus-summary-cancel-article): Heade headers after replying, etc. + (gnus-user-mail-address): New variable. + (gnus-score-orphans): Orphan functions added. + + Wed Apr 12 23:13:17 1995 Lars Ingebrigtsen + + * gnus.el (gnus-score-body): New function. + (gnus-summary-raise-by-body): All the raise/lower functions and + keystrokes are added. + + Wed Apr 12 17:23:32 1995 Lars Magne Ingebrigtsen + + * gnus.el (gnus-mail-reply-using-mail): Allow reply-to function to + return a list of headers to insert. + (gnus-summary-save-article): Don't re-request articles before + saving. + (gnus-summary-read-group): If all articles have been expunged on + accound of low scores, display all articles. + (gnus-score-check-syntax): Don't choke on empty score entries. + + Wed Apr 12 00:23:01 1995 Lars Ingebrigtsen + + * gnus.el: Doc fix. + (gnus-score-integer): New function. + (gnus-score-date): New function. + + * nntp.el (nntp-accept-response): Give a better error message. + + * nnvirtual.el (nnvirtual-update-marked): Removal of article marks + now propagates to the source groups. + + * gnus.el (gnus-select-newsgroup): Adjust marked lists after + really entering group. + + Tue Apr 11 23:08:25 1995 Lars Ingebrigtsen + + * gnus.el (gnus-summary-catchup-and-goto-next-group): New command + and keystroke. + (gnus-summary-toggle-header): Set point at the start up the buffer + when toggling the header. + (gnus-score-transform-old-to-new): Would rewrite 'files atoms + incorrectly. + + * nnmail.el (nnmail-request-post-buffer): Bind buffer-read-only to + nil before attempting to change the buffer. + + * gnus-uu.el (gnus-uu-save-files): Don't choke on non-existing + files. + + * gnus.el (gnus-score-save): Make sure that the directory that the + score file is written to actually exists. + + * gnus-kill.el (gnus-kill-file-raise-followups-to-author): + Misleading message. + + * gnus.el (gnus-summary-save-article): Remove any X-Gnus header + lines before saving. + + Tue Apr 11 00:03:35 1995 Lars Magne Ingebrigtsen + + * gnus.el (gnus-summary-number-of-articles-in-thread): New + function. + (gnus-summary-score-entry): A slightly more elaborate prompt. + (gnus-group-first-unread-group): New function and keystroke. + + Mon Apr 10 20:41:55 1995 Lars Magne Ingebrigtsen + + * gnus.el (gnus-summary-mark-as-read-forward): Overwrite E marks. + (gnus-group-jump-to-group): Allow jumping to groups not in the + active file. + (gnus-summary-line-format-alist): New spec: number of articles in + the current subthread. + + * nnml.el (nnml-possibly-create-directory): Create directories on + the fly instead of creating all possible directories at startup. + + * nnmail.el (nnmail-article-group): Allow nnmail-split-methods to + be a function to be called. + + * gnus.el (gnus-nov-parse-line): Allow articles without + message-ids to pass through. Fudge temporary ids. + + * nnml.el (nnml-make-nov-line): Create dummy message-ids for + articles that do not have them. + + * gnus.el (gnus-group-make-group): Refuse to create groups that + already exist. + (gnus-group-change-level): Don't enter foreign groups into killed + lists. + (gnus-parse-n-options): Handle options -n lines as the were + supposed to - sequentially. + (gnus-newsrc-options-n-yes, gnus-newsrc-options-n-no): Obsolete + variables. + (gnus-newsrc-options-n): New variable. + (gnus-matches-options-n): New function. + (gnus-summary-next-group): Kill summary buffer even when C-g'ing + while choosing the next group after n'ing. + (gnus-summary-mode-line-format-alist): New format spec added. + (gnus-short-group-name): New function. + (gnus-mail-forward-using-mail): Use From line instead of grup name + in the Subject header when forwarding. + (gnus-summary-mode-line-format-alist): Added user-defined spec to + the mode line alists. + (gnus-score-save): Would set `gnus-score-cache' to nil. + + * gnus-uu.el (gnus-uu-mark-sparse): Did not create hashtb before + using it. + + * gnus.el (gnus-mail-other-window-using-mail): Used lisp keymap. + + Mon Apr 10 20:29:26 1995 Lars Magne Ingebrigtsen + + * gnus.el (gnus-summary-move-article): Didn't remove articles from + list of unreads. + + Mon Apr 10 14:59:49 1995 Lars Magne Ingebrigtsen + + * gnus.el, gnus-uu.el: Changed all instances of + mail-header-separator to use regexp-quote and anchors. + + * gnus.el (gnus-nov-parse-line): Don't choke on malformed NOV + lines. + + Sun Apr 2 13:16:03 1995 Lars Magne Ingebrigtsen + + * gnus.el (gnus-inews-insert-headers): Didn't check new + -gather-limit correctly. + (gnus-summary-prepare-threads): Print subjects if `fuzzy' was + used, but subjects aren't equal. + Sun Apr 2 12:11:17 1995 Lars Magne Ingebrigtsen + + * gnus.el: 0.47 & 0.48 is released. * nnmh.el (nnmh-article-pathname): Wouldn't find groups that were located in directories that had "." in the directory names. diff --exclude=*.elc --exclude=*~ --exclude=*-[0-9] --exclude=gnus --exclude=readme --context --recursive pub/dgnus/lisp/gnus-kill.el dgnus/lisp/gnus-kill.el *** pub/dgnus/lisp/gnus-kill.el Sun Apr 2 12:57:34 1995 --- dgnus/lisp/gnus-kill.el Tue Apr 11 23:27:46 1995 *************** *** 243,249 **** "From" name level)) (insert string) (gnus-kill-file-apply-string string)) ! (message "Added permanent score file entry for followups to %s." name))) (defun gnus-kill-file-apply-buffer () "Apply current buffer to current newsgroup." --- 243,249 ---- "From" name level)) (insert string) (gnus-kill-file-apply-string string)) ! (message "Added temporary score file entry for followups to %s." name))) (defun gnus-kill-file-apply-buffer () "Apply current buffer to current newsgroup." diff --exclude=*.elc --exclude=*~ --exclude=*-[0-9] --exclude=gnus --exclude=readme --context --recursive pub/dgnus/lisp/gnus-uu.el dgnus/lisp/gnus-uu.el *** pub/dgnus/lisp/gnus-uu.el Sun Apr 2 12:57:34 1995 --- dgnus/lisp/gnus-uu.el Tue Apr 11 23:27:29 1995 *************** *** 424,436 **** (setq gnus-newsgroup-processable nil) (save-excursion (while marked ! (setq subject (header-subject ! (gnus-gethash ! (int-to-string (car marked)) ! gnus-newsgroup-headers-hashtb-by-number))) ! (setq articles (gnus-uu-find-articles-matching ! (gnus-uu-reginize-string subject))) ! (setq total (nconc total articles)) (while articles (gnus-summary-set-process-mark (car articles)) (setcdr marked (delq (car articles) (cdr marked))) --- 424,433 ---- (setq gnus-newsgroup-processable nil) (save-excursion (while marked ! (setq subject (header-subject (gnus-get-header-by-number (car marked))) ! 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))) *************** *** 472,481 **** file) (while files (setq file (cdr (assq 'name (car files)))) ! (copy-file file (if (file-directory-p dir) ! (concat dir (file-name-nondirectory file)) ! dir) ! t) (setq files (cdr files))) (message "Saved %d file%s" len (if (> len 1) "s" "")))) --- 469,478 ---- file) (while files (setq file (cdr (assq 'name (car files)))) ! (and (file-exists-p file) ! (copy-file file (if (file-directory-p dir) ! (concat dir (file-name-nondirectory file)) dir) ! 1 t)) (setq files (cdr files))) (message "Saved %d file%s" len (if (> len 1) "s" "")))) *************** *** 1510,1519 **** (setq mode-name "Gnus UU News") (make-local-variable 'paragraph-separate) (make-local-variable 'paragraph-start) ! (setq paragraph-start (concat "^" mail-header-separator "$\\|" ! paragraph-start)) ! (setq paragraph-separate (concat "^" mail-header-separator "$\\|" ! paragraph-separate)) (run-hooks 'text-mode-hook 'gnus-uu-post-reply-mode-hook)) (defun gnus-uu-post-news () --- 1507,1516 ---- (setq mode-name "Gnus UU News") (make-local-variable 'paragraph-separate) (make-local-variable 'paragraph-start) ! (setq paragraph-start (concat "^" (regexp-quote mail-header-separator) ! "$\\|" paragraph-start)) ! (setq paragraph-separate (concat "^" (regexp-quote mail-header-separator) ! "$\\|" paragraph-separate)) (run-hooks 'text-mode-hook 'gnus-uu-post-reply-mode-hook)) (defun gnus-uu-post-news () *************** *** 1571,1577 **** (save-restriction (set-buffer gnus-post-news-buffer) (goto-char 1) ! (re-search-forward mail-header-separator) (beginning-of-line) (forward-line -1) (narrow-to-region 1 (point)) --- 1568,1574 ---- (save-restriction (set-buffer gnus-post-news-buffer) (goto-char 1) ! (re-search-forward (regexp-quote mail-header-separator)) (beginning-of-line) (forward-line -1) (narrow-to-region 1 (point)) *************** *** 1673,1679 **** (if (not (re-search-forward (if gnus-uu-post-separate-description gnus-uu-post-binary-separator ! mail-header-separator) nil t)) (error "Internal error: No binary/header separator")) (beginning-of-line) (forward-line 1) --- 1670,1676 ---- (if (not (re-search-forward (if gnus-uu-post-separate-description 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) *************** *** 1695,1701 **** (kill-region (point) (point-max)) (goto-char 1) ! (search-forward mail-header-separator nil t) (beginning-of-line) (setq header (buffer-substring 1 (point))) --- 1692,1699 ---- (kill-region (point) (point-max)) (goto-char 1) ! (re-search-forward ! (concat "^" (regexp-quote mail-header-separator) "$") nil t) (beginning-of-line) (setq header (buffer-substring 1 (point))) *************** *** 1757,1763 **** (setq beg end) (setq i (1+ i)) (goto-char 1) ! (re-search-forward mail-header-separator nil t) (beginning-of-line) (forward-line 2) (if (re-search-forward gnus-uu-post-binary-separator nil t) --- 1755,1762 ---- (setq beg end) (setq i (1+ i)) (goto-char 1) ! (re-search-forward ! (concat "^" (regexp-quote mail-header-separator) "$") nil t) (beginning-of-line) (forward-line 2) (if (re-search-forward gnus-uu-post-binary-separator nil t) diff --exclude=*.elc --exclude=*~ --exclude=*-[0-9] --exclude=gnus --exclude=readme --context --recursive pub/dgnus/lisp/gnus-visual.el dgnus/lisp/gnus-visual.el *** pub/dgnus/lisp/gnus-visual.el Sun Apr 2 12:57:34 1995 --- dgnus/lisp/gnus-visual.el Fri Apr 14 01:44:28 1995 *************** *** 28,34 **** (require 'easymenu) (defvar gnus-summary-selected-face 'underline ! "Face used for highlighting the current article in the Summary buffer.") (defvar gnus-visual-summary-highlight '(((> score default) . bold) --- 28,34 ---- (require 'easymenu) (defvar gnus-summary-selected-face 'underline ! "Face used for highlighting the current article in the summary buffer.") (defvar gnus-visual-summary-highlight '(((> score default) . bold) *************** *** 264,270 **** ["Sort by date" gnus-summary-sort-by-date t]) ["Fetch group FAQ" gnus-summary-fetch-faq t] ["Filter articles" gnus-summary-execute-command t] ! ["Mark all read and exit" gnus-summary-catchup-and-exit t] ["Toggle line truncation" gnus-summary-toggle-truncation t] ["Expire expirable articles" gnus-summary-expire-articles t] ["Show dormant articles" gnus-summary-show-all-dormant t] --- 264,271 ---- ["Sort by date" gnus-summary-sort-by-date t]) ["Fetch group FAQ" gnus-summary-fetch-faq t] ["Filter articles" gnus-summary-execute-command t] ! ["Catchup and exit" gnus-summary-catchup-and-exit t] ! ["Catchup and goto next" gnus-summary-catchup-and-goto-next-group t] ["Toggle line truncation" gnus-summary-toggle-truncation t] ["Expire expirable articles" gnus-summary-expire-articles t] ["Show dormant articles" gnus-summary-show-all-dormant t] *************** *** 383,390 **** (save-excursion (let* ((beg (progn (beginning-of-line) (point))) (end (progn (end-of-line) (point))) ! (to (previous-single-property-change end 'mouse-face nil beg)) ! (from (previous-single-property-change to 'mouse-face nil beg))) (if gnus-newsgroup-selected-overlay (move-overlay gnus-newsgroup-selected-overlay from to (current-buffer)) --- 384,393 ---- (save-excursion (let* ((beg (progn (beginning-of-line) (point))) (end (progn (end-of-line) (point))) ! (to (1- (previous-single-property-change ! end 'mouse-face nil beg))) ! (from (1+ (previous-single-property-change ! to 'mouse-face nil beg)))) (if gnus-newsgroup-selected-overlay (move-overlay gnus-newsgroup-selected-overlay from to (current-buffer)) *************** *** 392,417 **** (overlay-put gnus-newsgroup-selected-overlay 'face gnus-summary-selected-face)))))) (defun gnus-visual-summary-highlight-line () "Highlight current line according to `gnus-visual-summary-highlight'." ! (let ((list gnus-visual-summary-highlight) ! (score (gnus-summary-article-score)) ! (default gnus-summary-default-score) ! (inhibit-read-only t)) ! (save-excursion ! (beginning-of-line) ! (while (and list (not (eval (car (car list))))) ! (setq list (cdr list))) ! (let ((face (and list (cdr (car list))))) ! (save-excursion ! ;; BUG! For some reason the text properties of the first ! ;; characters get mangled. ! (forward-char 10) ! (if (eq face (get-text-property (point) 'face)) ! () ! (put-text-property (save-excursion (beginning-of-line 1) (point)) ! (save-excursion (end-of-line 1) (point)) ! 'face face))))))) (provide 'gnus-visual) --- 395,423 ---- (overlay-put gnus-newsgroup-selected-overlay 'face gnus-summary-selected-face)))))) + ;; New implementation by Christian Limpach . (defun gnus-visual-summary-highlight-line () "Highlight current line according to `gnus-visual-summary-highlight'." ! (let* ((list gnus-visual-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))) ! (score (or (cdr (assq (or (get-text-property beg 'gnus-number) ! gnus-current-article) ! gnus-newsgroup-scored)) ! gnus-summary-default-score 0)) ! (default gnus-summary-default-score) ! (mark (get-text-property beg 'gnus-mark)) ! (inhibit-read-only t)) ! (while (and list (not (eval (car (car list))))) ! (setq list (cdr list))) ! (let ((face (and list (cdr (car list))))) ! ;; BUG! For some reason the text properties of the first ! ;; characters get mangled. ! (or (eq face (get-text-property (+ beg 10) 'face)) ! (put-text-property beg end 'face face))) ! (goto-char p))) (provide 'gnus-visual) diff --exclude=*.elc --exclude=*~ --exclude=*-[0-9] --exclude=gnus --exclude=readme --context --recursive pub/dgnus/lisp/gnus.el dgnus/lisp/gnus.el *** pub/dgnus/lisp/gnus.el Sun Apr 2 12:57:35 1995 --- dgnus/lisp/gnus.el Fri Apr 14 03:52:21 1995 *************** *** 93,99 **** If, for instance, you want to read your mail with the nnml backend, you could set this variable: ! (setq gnus-secondary-select-methods '((nnml ""))") (defvar gnus-secondary-servers nil "List of NNTP servers that the user can choose between interactively. --- 93,99 ---- If, for instance, you want to read your mail with the nnml backend, you could set this variable: ! (setq gnus-secondary-select-methods '((nnml \"\"))") (defvar gnus-secondary-servers nil "List of NNTP servers that the user can choose between interactively. *************** *** 198,204 **** (defvar gnus-reply-to-function nil "A variable that contains a function that returns a reply address. See the `gnus-followup-to-function' variable for an explanation of how ! this variable is used.") (defvar gnus-large-newsgroup 200 "The number of articles which indicates a large newsgroup. --- 198,210 ---- (defvar gnus-reply-to-function nil "A variable that contains a function that returns a reply address. See the `gnus-followup-to-function' variable for an explanation of how ! this variable is used. ! ! This function should return a string that will be used to fill in the ! header. This function may also return a list. In that case, every ! list element should be a cons where the first car should be a string ! with the header name, and the cdr should be a string with the header ! value.") (defvar gnus-large-newsgroup 200 "The number of articles which indicates a large newsgroup. *************** *** 387,393 **** (defvar gnus-read-active-file t "Non-nil means that Gnus will read the entire active file at startup. ! If this variable is nil, Gnus will only read parts of the active file.") (defvar gnus-activate-foreign-newsgroups nil "If nil, Gnus will not check foreign newsgroups at startup. --- 393,405 ---- (defvar gnus-read-active-file t "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 you set this variable to nil, 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.") (defvar gnus-activate-foreign-newsgroups nil "If nil, Gnus will not check foreign newsgroups at startup. *************** *** 472,477 **** --- 484,504 ---- "The full name of the user. Got from the NAME environment variable if undefined.") + (defvar gnus-user-from-line nil + "Your full, complete e-mail address. + Overrides the other Gnus variables if it is non-nil. + + Here are two example values of this variable: + + \"Lars Magne Ingebrigtsen \" + + and + + \"larsi@ifi.uio.no (Lars Magne Ingebrigtsen)\" + + The first version is recommended, but the name has to be quoted if it + contains non-alphanumerical characters.") + (defvar gnus-show-mime nil "*If non-ni, do mime processing of articles. The articles will simply be fed to the function given by *************** *** 785,790 **** --- 812,818 ---- %< Spaces of length (- 20 thread-level) (string) %i Article score (number) %z Article zcore (character) + %t Number of articles under the current thread. %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 *************** *** 860,865 **** --- 888,896 ---- This variable is local to each summary buffer and usually set by the score file.") + (defvar gnus-orphan-score nil + "All orphans get this score added. Set in the score file.") + (defvar 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. *************** *** 1114,1119 **** --- 1145,1152 ---- (defvar gnus-internal-global-score-files nil) (defvar gnus-current-score-file nil) + (defvar gnus-current-move-group nil) + (defvar gnus-score-alist nil "Alist containing score information. The keys can be symbols or strings. The following symbols are defined. *************** *** 1185,1190 **** --- 1218,1224 ---- (list ?i 'score ?s) (list ?z 'score-char ?c) (list ?U 'unread ?c) + (list ?t '(gnus-summary-number-of-articles-in-thread thread) ?d) (list ?u 'user-defined ?s)) "An alist of format specifications that can appear in summary lines, and what variables they correspond with, along with the type of the *************** *** 1192,1218 **** (defconst gnus-summary-dummy-line-format-alist (list (list ?S 'subject ?s) ! (list ?N 'number ?d))) (defconst gnus-summary-mode-line-format-alist (list (list ?G 'group-name ?s) (list ?A 'article-number ?d) (list ?Z 'unread-and-unselected ?s) (list ?V 'gnus-version ?s) (list ?U 'unread ?d) (list ?S 'subject ?s) ! (list ?u 'unselected ?d))) (defconst gnus-group-mode-line-format-alist (list (list ?S 'news-server ?s) ! (list ?M 'news-method ?s))) (defvar gnus-have-read-active-file nil) (defconst gnus-maintainer "Lars Magne Ingebrigtsen " "The mail address of the Gnus maintainer.") ! (defconst gnus-version "(ding) Gnus v0.48" "Version number for this version of Gnus.") (defvar gnus-info-nodes --- 1226,1257 ---- (defconst gnus-summary-dummy-line-format-alist (list (list ?S 'subject ?s) ! (list ?N 'number ?d) ! (list ?u 'user-defined ?s))) (defconst gnus-summary-mode-line-format-alist (list (list ?G 'group-name ?s) + (list ?g '(gnus-short-group-name group-name)) (list ?A 'article-number ?d) (list ?Z 'unread-and-unselected ?s) (list ?V 'gnus-version ?s) (list ?U 'unread ?d) (list ?S 'subject ?s) ! (list ?e 'unselected ?d) ! (list ?u 'user-defined ?s) ! (list ?s 'gnus-current-score-file ?s))) (defconst gnus-group-mode-line-format-alist (list (list ?S 'news-server ?s) ! (list ?M 'news-method ?s) ! (list ?u 'user-defined ?s))) (defvar gnus-have-read-active-file nil) (defconst gnus-maintainer "Lars Magne Ingebrigtsen " "The mail address of the Gnus maintainer.") ! (defconst gnus-version "(ding) Gnus v0.49" "Version number for this version of Gnus.") (defvar gnus-info-nodes *************** *** 1232,1239 **** "Gnus buffers that should be killed on exit.") (defvar gnus-variable-list ! '(gnus-newsrc-options ! gnus-newsrc-options-n-yes gnus-newsrc-options-n-no gnus-newsrc-last-checked-date gnus-newsrc-assoc gnus-killed-list gnus-zombie-list) "Gnus variables saved in the quick startup file.") --- 1271,1277 ---- "Gnus buffers that should be killed on exit.") (defvar gnus-variable-list ! '(gnus-newsrc-options gnus-newsrc-options-n gnus-newsrc-last-checked-date gnus-newsrc-assoc gnus-killed-list gnus-zombie-list) "Gnus variables saved in the quick startup file.") *************** *** 1247,1257 **** (defvar gnus-newsrc-options nil "Options line in the .newsrc file.") ! (defvar gnus-newsrc-options-n-yes nil ! "Regexp representing groups to be subscribed to unconditionally.") ! ! (defvar gnus-newsrc-options-n-no nil ! "Regexp representing group to be ignored unconditionally.") (defvar gnus-newsrc-last-checked-date nil "Date Gnus last asked server for new newsgroups.") --- 1285,1292 ---- (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.") *************** *** 1951,1961 **** (concat osubject (substring subject beg (match-beginning 0)) " ") beg (match-end 0))) ! (setq osubject (concat osubject (substring subject beg)))))) (defun gnus-add-current-to-buffer-list () (setq gnus-buffer-list (cons (current-buffer) gnus-buffer-list))) ;; Functions accessing headers. ;; Functions are more convenient than macros in some cases. --- 1986,2003 ---- (concat osubject (substring subject beg (match-beginning 0)) " ") beg (match-end 0))) ! (setq osubject (concat osubject (substring subject beg))) ! (and (string-match " \\'" osubject) ! (setq osubject (substring osubject 0 (match-beginning 0)))) ! osubject))) (defun gnus-add-current-to-buffer-list () (setq gnus-buffer-list (cons (current-buffer) gnus-buffer-list))) + (defun gnus-string> (s1 s2) + (not (or (string< s1 s2) + (string= s1 s2)))) + ;; Functions accessing headers. ;; Functions are more convenient than macros in some cases. *************** *** 2180,2186 **** (erase-buffer) (mail-setup gnus-maintainer "[Gnus Bug Report] " nil nil nil nil) (goto-char (point-min)) ! (search-forward mail-header-separator) (forward-line 1) (insert (format "%s\n%s\n\n" (gnus-version) (emacs-version))) (gnus-debug) --- 2222,2228 ---- (erase-buffer) (mail-setup gnus-maintainer "[Gnus Bug Report] " nil nil nil nil) (goto-char (point-min)) ! (re-search-forward (concat "^" (regexp-quote mail-header-separator) "$")) (forward-line 1) (insert (format "%s\n%s\n\n" (gnus-version) (emacs-version))) (gnus-debug) *************** *** 2594,2599 **** --- 2636,2642 ---- (define-key gnus-group-mode-map "\M-n" 'gnus-group-next-unread-group-same-level) (define-key gnus-group-mode-map "\M-p" 'gnus-group-prev-unread-group-same-level) (define-key gnus-group-mode-map "," 'gnus-group-best-unread-group) + (define-key gnus-group-mode-map "." 'gnus-group-first-unread-group) (define-key gnus-group-mode-map "u" 'gnus-group-unsubscribe-current-group) (define-key gnus-group-mode-map "U" 'gnus-group-unsubscribe-group) (define-key gnus-group-mode-map "c" 'gnus-group-catchup-current) *************** *** 3185,3192 **** (defun gnus-group-jump-to-group (group) "Jump to newsgroup GROUP." (interactive (list ! (completing-read "Group: " gnus-active-hashtb nil t))) (let (b) ;; Either go to the line in the group buffer... (or (and (setq b (text-property-any (point-min) (point-max) --- 3228,3243 ---- (defun gnus-group-jump-to-group (group) "Jump to newsgroup GROUP." (interactive + ;; Fix by Hallvard B Furuseth . (list ! (if gnus-read-active-file ! (completing-read "Group: " gnus-active-hashtb nil t) ! (let ((group (completing-read "Group: " gnus-active-hashtb))) ! (or (intern-soft group gnus-active-hashtb) ! (equal group "") ! (gnus-get-new-news-in-group group) ! (error "%s error: %s" group (gnus-status-message group))) ! group)))) (let (b) ;; Either go to the line in the group buffer... (or (and (setq b (text-property-any (point-min) (point-max) *************** *** 3279,3284 **** --- 3330,3341 ---- (gnus-summary-position-cursor) (and best-point (gnus-group-group-name)))) + (defun gnus-group-first-unread-group () + "Go to the first group with unread articles." + (interactive) + (goto-char (point-min)) + (gnus-group-next-unread-group 1)) + (defun gnus-group-make-group (name method address) "Add a new newsgroup. The user will be prompted for a NAME, for a select METHOD, and an *************** *** 3296,3301 **** --- 3353,3360 ---- ""))))) (let ((nname (gnus-group-prefixed-name name (list (intern method) address))) info) + (and (gnus-gethash nname gnus-active-hashtb) + (error "Group %s already exists" nname)) (gnus-group-change-level (setq info (list t nname 3 nil nil (list (intern method) address))) 3 9 (gnus-gethash (or (gnus-group-group-name) "dummy.group") *************** *** 4036,4041 **** --- 4095,4102 ---- (define-key gnus-browse-server-mode-map "\M-p" 'gnus-browse-prev-group) (define-key gnus-browse-server-mode-map "\r" 'gnus-browse-read-group) (define-key gnus-browse-server-mode-map "u" 'gnus-browse-unsubscribe-current-group) + (define-key gnus-browse-server-mode-map "l" 'gnus-browse-exit) + (define-key gnus-browse-server-mode-map "L" 'gnus-browse-exit) (define-key gnus-browse-server-mode-map "q" 'gnus-browse-exit) (define-key gnus-browse-server-mode-map "Q" 'gnus-browse-exit) (define-key gnus-browse-server-mode-map "\C-c\C-c" 'gnus-browse-exit) *************** *** 4200,4205 **** --- 4261,4267 ---- (defvar gnus-summary-increase-map nil) (defvar gnus-summary-inc-subject-map nil) (defvar gnus-summary-inc-author-map nil) + (defvar gnus-summary-inc-body-map nil) (defvar gnus-summary-inc-id-map nil) (defvar gnus-summary-inc-xref-map nil) (defvar gnus-summary-inc-thread-map nil) *************** *** 4207,4212 **** --- 4269,4275 ---- (defvar gnus-summary-lower-map nil) (defvar gnus-summary-low-subject-map nil) (defvar gnus-summary-low-author-map nil) + (defvar gnus-summary-low-body-map nil) (defvar gnus-summary-low-id-map nil) (defvar gnus-summary-low-xref-map nil) (defvar gnus-summary-low-thread-map nil) *************** *** 4303,4309 **** (define-key gnus-summary-mode-map "g" 'gnus-summary-show-article) ; (define-key gnus-summary-mode-map "?" 'gnus-summary-describe-briefly) (define-key gnus-summary-mode-map "l" 'gnus-summary-goto-last-article) ! (define-key gnus-summary-mode-map "\C-c\C-v\C-v" 'gnus-uu-decode-uu) (define-key gnus-summary-mode-map "\C-d" 'gnus-summary-enter-digest-group) --- 4366,4372 ---- (define-key gnus-summary-mode-map "g" 'gnus-summary-show-article) ; (define-key gnus-summary-mode-map "?" 'gnus-summary-describe-briefly) (define-key gnus-summary-mode-map "l" 'gnus-summary-goto-last-article) ! (define-key gnus-summary-mode-map "\C-c\C-v\C-v" 'gnus-uu-decode-uu-view) (define-key gnus-summary-mode-map "\C-d" 'gnus-summary-enter-digest-group) *************** *** 4412,4417 **** --- 4475,4481 ---- (define-key gnus-summary-exit-map "E" 'gnus-summary-exit-no-update) (define-key gnus-summary-exit-map "Q" 'gnus-summary-exit) (define-key gnus-summary-exit-map "Z" 'gnus-summary-exit) + (define-key gnus-summary-exit-map "n" 'gnus-summary-catchup-and-goto-next-group) (define-prefix-command 'gnus-summary-article-map) *************** *** 4545,4550 **** --- 4609,4622 ---- (define-key gnus-summary-inc-author-map "t" 'gnus-summary-temporarily-raise-by-author) (define-key gnus-summary-inc-author-map "p" 'gnus-summary-raise-by-author) + (define-prefix-command 'gnus-summary-inc-body-map) + (define-key gnus-summary-increase-map "b" 'gnus-summary-inc-body-map) + (define-key gnus-summary-increase-map "B" 'gnus-summary-temporarily-raise-by-body) + (define-key gnus-summary-inc-body-map "b" 'gnus-summary-temporarily-raise-by-body) + (define-key gnus-summary-inc-body-map "B" 'gnus-summary-raise-by-body) + (define-key gnus-summary-inc-body-map "t" 'gnus-summary-temporarily-raise-by-body) + (define-key gnus-summary-inc-body-map "p" 'gnus-summary-raise-by-body) + (define-prefix-command 'gnus-summary-inc-id-map) (define-key gnus-summary-increase-map "i" 'gnus-summary-inc-id-map) (define-key gnus-summary-increase-map "I" 'gnus-summary-temporarily-raise-by-id) *************** *** 4591,4596 **** --- 4663,4676 ---- (define-key gnus-summary-low-subject-map "t" 'gnus-summary-temporarily-lower-by-subject) (define-key gnus-summary-low-subject-map "p" 'gnus-summary-lower-by-subject) + (define-prefix-command 'gnus-summary-low-body-map) + (define-key gnus-summary-lower-map "b" 'gnus-summary-low-body-map) + (define-key gnus-summary-lower-map "B" 'gnus-summary-temporarily-lower-by-body) + (define-key gnus-summary-low-body-map "b" 'gnus-summary-temporarily-lower-by-body) + (define-key gnus-summary-low-body-map "B" 'gnus-summary-lower-by-body) + (define-key gnus-summary-low-body-map "t" 'gnus-summary-temporarily-lower-by-body) + (define-key gnus-summary-low-body-map "p" 'gnus-summary-lower-by-body) + (define-prefix-command 'gnus-summary-low-author-map) (define-key gnus-summary-lower-map "a" 'gnus-summary-low-author-map) (define-key gnus-summary-lower-map "A" 'gnus-summary-temporarily-lower-by-author) *************** *** 4800,4805 **** --- 4880,4891 ---- (gnus-summary-update-line) (forward-line 1))))) + (defun gnus-summary-number-of-articles-in-thread (thread) + ;; Sum up all elements (and sub-elements) in a list. + (if (listp thread) + (apply '+ (mapcar 'gnus-summary-number-of-articles-in-thread thread)) + 1)) + (defun gnus-summary-read-group (group &optional show-all no-article kill-buffer) "Start reading news in newsgroup GROUP. If SHOW-ALL is non-nil, already read articles are also listed. *************** *** 4808,4813 **** --- 4894,4900 ---- (gnus-summary-setup-buffer group) (if (gnus-select-newsgroup group show-all) (progn + (gnus-set-global-variables) ;; You can change the subjects in this hook. (run-hooks 'gnus-select-group-hook) ;; Do Score Processing. *************** *** 4815,4824 **** ;; Update the format specifiers. (gnus-update-format-specifications) (gnus-summary-prepare) ! (if (and (zerop (buffer-size)) ! gnus-newsgroup-dormant) ! (gnus-summary-show-all-dormant)) ! (gnus-set-global-variables) ;; Function `gnus-apply-kill-file' must be called in this hook. (run-hooks 'gnus-apply-kill-hook) (if (zerop (buffer-size)) --- 4902,4912 ---- ;; Update the format specifiers. (gnus-update-format-specifications) (gnus-summary-prepare) ! (if (zerop (buffer-size)) ! (cond (gnus-newsgroup-dormant ! (gnus-summary-show-all-dormant)) ! ((and gnus-newsgroup-scored show-all) ! (gnus-summary-show-all-expunged)))) ;; Function `gnus-apply-kill-file' must be called in this hook. (run-hooks 'gnus-apply-kill-hook) (if (zerop (buffer-size)) *************** *** 5250,5256 **** (gnus-summary-prepare-threads (list (car (cdr thread))) 0) (setq thread (cdr (cdr thread))) (while thread ! (gnus-summary-prepare-threads (list (car thread)) 0 nil t) (setq thread (cdr thread)))) (t ;; We do not make a root for the gathered --- 5338,5350 ---- (gnus-summary-prepare-threads (list (car (cdr thread))) 0) (setq thread (cdr (cdr thread))) (while thread ! (gnus-summary-prepare-threads ! (list (car thread)) 0 nil ! (not (and (eq gnus-summary-gather-subject-limit 'fuzzy) ! (not (string= ! (gnus-simplify-subject-re ! (header-subject (car (car thread)))) ! (gnus-simplify-subject-re header)))))) (setq thread (cdr thread)))) (t ;; We do not make a root for the gathered *************** *** 5272,5278 **** (t gnus-ancient-mark)) (memq number gnus-newsgroup-replied) (memq number gnus-newsgroup-expirable) ! (if no-subject gnus-summary-same-subject (if (or (zerop level) (and gnus-thread-ignore-subject (not (string= --- 5366,5373 ---- (t gnus-ancient-mark)) (memq number gnus-newsgroup-replied) (memq number gnus-newsgroup-expirable) ! (if no-subject ! gnus-summary-same-subject (if (or (zerop level) (and gnus-thread-ignore-subject (not (string= *************** *** 5311,5329 **** (setq gnus-newsgroup-unselected nil) (setq gnus-newsgroup-unreads (gnus-list-of-unread-articles group)) - (and info - (let (marked) - (gnus-adjust-marked-articles info) - (setq gnus-newsgroup-marked - (cdr (assq 'tick (setq marked (nth 3 info))))) - (setq gnus-newsgroup-replied (cdr (assq 'reply marked))) - (setq gnus-newsgroup-expirable (cdr (assq 'expire marked))) - (setq gnus-newsgroup-killed (cdr (assq 'killed marked))) - (setq gnus-newsgroup-bookmarks (cdr (assq 'bookmark marked))) - (setq gnus-newsgroup-dormant (cdr (assq 'dormant marked))) - (setq gnus-newsgroup-scored (cdr (assq 'score marked))) - (setq gnus-newsgroup-processable nil))) - (if (not (setq articles (gnus-articles-to-read group read-all))) nil ;; Init the dependencies hash table. --- 5406,5411 ---- *************** *** 5354,5359 **** --- 5436,5454 ---- gnus-newsgroup-unreads (mapcar (lambda (headers) (header-number headers)) gnus-newsgroup-headers))) + ;; Adjust and set lists of article marks. + (and info + (let (marked) + (gnus-adjust-marked-articles info) + (setq gnus-newsgroup-marked + (cdr (assq 'tick (setq marked (nth 3 info))))) + (setq gnus-newsgroup-replied (cdr (assq 'reply marked))) + (setq gnus-newsgroup-expirable (cdr (assq 'expire marked))) + (setq gnus-newsgroup-killed (cdr (assq 'killed marked))) + (setq gnus-newsgroup-bookmarks (cdr (assq 'bookmark marked))) + (setq gnus-newsgroup-dormant (cdr (assq 'dormant marked))) + (setq gnus-newsgroup-scored (cdr (assq 'score marked))) + (setq gnus-newsgroup-processable nil))) ;; Check whether auto-expire is to be done in this group. (setq gnus-newsgroup-auto-expire (or (and (stringp gnus-auto-expirable-newsgroups) *************** *** 5903,5958 **** (setq eol (point))) (forward-char) ;; overview: [num subject from date id refs chars lines misc] ! (setq header ! (vector ! number ; number ! (gnus-nov-field) ; subject ! (gnus-nov-field) ; from ! (gnus-nov-field) ; date ! (setq id (gnus-nov-field)) ; id ! (progn ! (save-excursion ! (let ((beg (point))) ! (search-forward "\t" eol) ! (if (search-backward ">" beg t) ! (setq ref ! (downcase ! (buffer-substring ! (1+ (point)) ! (progn ! (search-backward "<" beg t) ! (point))))) ! (setq ref nil)))) ! (gnus-nov-field)) ; refs ! (read (current-buffer)) ; chars ! (read (current-buffer)) ; lines ! (if (/= (following-char) ?\t) ! nil ! (forward-char 1) ! (gnus-nov-field)) ; misc ! )) ;; We build the thread tree. ! (if (boundp ! (setq dep ! (intern ! (downcase ! (or id (concat "none+" ! (int-to-string ! (setq none (1+ none)))))) ! dependencies))) ! (if (car (symbol-value dep)) ! ;; An article with this Message-ID has already been seen, ! ;; so we ignore this one, except we add any additional ! ;; Xrefs (in case the two articles came from different ! ;; servers. ! (progn ! (header-set-xref ! (car (symbol-value dep)) ! (concat (or (header-xref (car (symbol-value dep))) "") ! (or (header-xref header) ""))) ! (setq header nil)) ! (setcar (symbol-value dep) header)) ! (set dep (list header))) (if header (progn (if (boundp (setq dep (intern (or ref "none") --- 5998,6056 ---- (setq eol (point))) (forward-char) ;; overview: [num subject from date id refs chars lines misc] ! (save-restriction ! (narrow-to-region (point) eol) ! (condition-case nil ! (setq header ! (vector ! number ; number ! (gnus-nov-field) ; subject ! (gnus-nov-field) ; from ! (gnus-nov-field) ; date ! (setq id (or (gnus-nov-field) ! (concat "none+" ! (int-to-string ! (setq none (1+ none)))))) ; id ! (progn ! (save-excursion ! (let ((beg (point))) ! (search-forward "\t" eol) ! (if (search-backward ">" beg t) ! (setq ref ! (downcase ! (buffer-substring ! (1+ (point)) ! (progn ! (search-backward "<" beg t) ! (point))))) ! (setq ref nil)))) ! (gnus-nov-field)) ; refs ! (read (current-buffer)) ; chars ! (read (current-buffer)) ; lines ! (if (/= (following-char) ?\t) ! nil ! (forward-char 1) ! (gnus-nov-field)) ; misc ! )) ! (error (progn ! (setq header nil) ! (goto-char eol))))) ;; We build the thread tree. ! (and header ! (if (boundp (setq dep (intern (downcase id) dependencies))) ! (if (car (symbol-value dep)) ! ;; An article with this Message-ID has already been seen, ! ;; so we ignore this one, except we add any additional ! ;; Xrefs (in case the two articles came from different ! ;; servers. ! (progn ! (header-set-xref ! (car (symbol-value dep)) ! (concat (or (header-xref (car (symbol-value dep))) "") ! (or (header-xref header) ""))) ! (setq header nil)) ! (setcar (symbol-value dep) header)) ! (set dep (list header)))) (if header (progn (if (boundp (setq dep (intern (or ref "none") *************** *** 6139,6168 **** "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." ! (let ((number (get-text-property (save-excursion (beginning-of-line) (point)) ! 'gnus-number))) (if number-or-nil number (or number gnus-current-article)))) (defun gnus-summary-thread-level () "The thread level of the article on the current line." ! (or (get-text-property (save-excursion (beginning-of-line) (point)) ! 'gnus-thread) 0)) (defun gnus-summary-pseudo-article () "The thread level of the article on the current line." ! (get-text-property (save-excursion (beginning-of-line) (point)) ! 'gnus-pseudo)) (defun gnus-summary-article-mark () "The mark on the current line." ! (get-text-property (save-excursion (beginning-of-line) (point)) ! 'gnus-mark)) (defun gnus-summary-subject-string () "Return current subject string or nil if nothing." ! (get-text-property (save-excursion (beginning-of-line) (point)) ! 'gnus-subject)) (defalias 'gnus-summary-score 'gnus-summary-article-score) (make-obsolete 'gnus-summary-score 'gnus-summary-article-score) --- 6237,6267 ---- "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." ! (let* ((p (point)) ! (number (get-text-property ! (progn (beginning-of-line) (prog1 (point) (goto-char p))) ! 'gnus-number))) (if number-or-nil number (or number gnus-current-article)))) (defun gnus-summary-thread-level () "The thread level of the article on the current line." ! (or (get-text-property ! (save-excursion (beginning-of-line) (point)) 'gnus-thread) 0)) (defun gnus-summary-pseudo-article () "The thread level of the article on the current line." ! (get-text-property ! (save-excursion (beginning-of-line) (point)) 'gnus-pseudo)) (defun gnus-summary-article-mark () "The mark on the current line." ! (get-text-property (save-excursion (beginning-of-line) (point)) 'gnus-mark)) (defun gnus-summary-subject-string () "Return current subject string or nil if nothing." ! (get-text-property ! (save-excursion (beginning-of-line) (point)) 'gnus-subject)) (defalias 'gnus-summary-score 'gnus-summary-article-score) (make-obsolete 'gnus-summary-score 'gnus-summary-article-score) *************** *** 6192,6197 **** --- 6291,6312 ---- (get-buffer-window (current-buffer)) (save-excursion (forward-line (- top)) (point)))))) + ;; Function written by Stainless Steel Rat . + (defun gnus-short-group-name (newsgroup) + "Convert a long group name to an initialized form. + The last part of the name is left intact: \"rec.arts.anime\" becomes + \"r.a.anime\"." + (let ((name "")) + (while newsgroup + (if (string-match "\\." newsgroup) + (progn + (setq name (concat name (substring newsgroup 0 1)) + newsgroup (substring newsgroup (match-end 0)) + name (concat name "."))) + (setq name (concat name newsgroup) + newsgroup nil))) + name)) + (defun gnus-summary-jump-to-group (newsgroup) "Move point to NEWSGROUP in group mode buffer." ;; Keep update point of group mode buffer if visible. *************** *** 6272,6280 **** (> (prefix-numeric-value arg) 0))) (redraw-display)) ! (defun gnus-summary-reselect-current-group (show-all) "Once exit and then reselect the current newsgroup. ! Prefix argument SHOW-ALL means to select all articles." (interactive "P") (gnus-set-global-variables) (let ((current-subject (gnus-summary-article-number))) --- 6387,6395 ---- (> (prefix-numeric-value arg) 0))) (redraw-display)) ! (defun gnus-summary-reselect-current-group (all) "Once exit and then reselect the current newsgroup. ! The prefix argument ALL means to select all articles." (interactive "P") (gnus-set-global-variables) (let ((current-subject (gnus-summary-article-number))) *************** *** 6283,6289 **** ;; current point was moved to the next unread newsgroup by ;; exiting. (gnus-summary-jump-to-group gnus-newsgroup-name) ! (gnus-group-read-group show-all t) (gnus-summary-goto-subject current-subject))) (defun gnus-summary-rescan-group (all) --- 6398,6404 ---- ;; current point was moved to the next unread newsgroup by ;; exiting. (gnus-summary-jump-to-group gnus-newsgroup-name) ! (gnus-group-read-group all t) (gnus-summary-goto-subject current-subject))) (defun gnus-summary-rescan-group (all) *************** *** 6459,6465 **** (gnus-summary-read-group group nil no-article buf) (and (string= gnus-newsgroup-name ingroup) (progn ! (set-buffer sumbuf) (gnus-summary-exit-no-update t)))))))) (defun gnus-summary-prev-group (no-article) --- 6574,6580 ---- (gnus-summary-read-group group nil no-article buf) (and (string= gnus-newsgroup-name ingroup) (progn ! (set-buffer (setq gnus-summary-buffer sumbuf)) (gnus-summary-exit-no-update t)))))))) (defun gnus-summary-prev-group (no-article) *************** *** 6568,6574 **** (gnus-summary-update-line) t)) ! (defun gnus-summary-select-article (&optional all-headers force pseudo) "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 --- 6683,6689 ---- (gnus-summary-update-line) t)) ! (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 *************** *** 6576,6582 **** be displayed." (and (not pseudo) (gnus-summary-pseudo-article) (error "This is a pseudo-article.")) ! (let ((article (gnus-summary-article-number)) (all-headers (not (not all-headers)))) ;Must be T or NIL. (if (or (null gnus-current-article) (null gnus-article-current) --- 6691,6697 ---- be displayed." (and (not pseudo) (gnus-summary-pseudo-article) (error "This is a pseudo-article.")) ! (let ((article (or article (gnus-summary-article-number))) (all-headers (not (not all-headers)))) ;Must be T or NIL. (if (or (null gnus-current-article) (null gnus-article-current) *************** *** 7063,7069 **** (if (text-property-any 1 (point-max) 'invisible t) (remove-text-properties 1 (point-max) '(invisible t)) (let ((gnus-have-all-headers nil)) ! (run-hooks 'gnus-article-display-hook))))))) (defun gnus-summary-show-all-headers () "Make all header lines visible." --- 7178,7185 ---- (if (text-property-any 1 (point-max) 'invisible t) (remove-text-properties 1 (point-max) '(invisible t)) (let ((gnus-have-all-headers nil)) ! (run-hooks 'gnus-article-display-hook)))) ! (set-window-point (get-buffer-window (current-buffer)) 1)))) (defun gnus-summary-show-all-headers () "Make all header lines visible." *************** *** 7128,7139 **** (if (and (not to-newsgroup) (not select-method)) (setq to-newsgroup (completing-read ! (format "Where do you want to move %s? " (if (> (length articles) 1) (format "these %d articles" (length articles)) ! "this article")) ! gnus-active-hashtb nil t (gnus-group-real-prefix gnus-newsgroup-name)))) (or (gnus-check-backend-function 'request-accept-article (or select-method to-newsgroup)) (error "%s does not support article moving" to-newsgroup)) --- 7244,7263 ---- (if (and (not to-newsgroup) (not select-method)) (setq to-newsgroup (completing-read ! (format "Where do you want to move %s? %s" (if (> (length articles) 1) (format "these %d articles" (length articles)) ! "this article") ! (if gnus-current-move-group ! (format "(%s default) " gnus-current-move-group) ! "")) ! gnus-active-hashtb nil nil (gnus-group-real-prefix gnus-newsgroup-name)))) + (if (string= to-newsgroup "") + (setq to-newsgroup (or gnus-current-move-group ""))) + (or (gnus-gethash to-newsgroup gnus-active-hashtb) + (error "No such group: %s" to-newsgroup)) + (setq gnus-current-move-group to-newsgroup) (or (gnus-check-backend-function 'request-accept-article (or select-method to-newsgroup)) (error "%s does not support article moving" to-newsgroup)) *************** *** 7185,7190 **** --- 7309,7315 ---- (car info) (car (car marks)) (list to-article) info)) (setq marks (cdr marks)))) (setq gnus-newsgroup-marked (delq article gnus-newsgroup-marked)) + (setq gnus-newsgroup-unreads (delq article gnus-newsgroup-unreads)) (setq gnus-newsgroup-dormant (delq article gnus-newsgroup-dormant))) (message "Couldn't move article %s" (car articles))) *************** *** 7234,7245 **** (if (and (not to-newsgroup) (not select-method)) (setq to-newsgroup (completing-read ! (format "Where do you want to copy %s? " (if (> (length articles) 1) (format "these %d articles" (length articles)) ! "this article")) ! gnus-active-hashtb nil t (gnus-group-real-prefix gnus-newsgroup-name)))) (or (gnus-check-backend-function 'request-accept-article (or select-method to-newsgroup)) (error "%s does not support article copying" to-newsgroup)) --- 7359,7378 ---- (if (and (not to-newsgroup) (not select-method)) (setq to-newsgroup (completing-read ! (format "Where do you want to copy %s? %s" (if (> (length articles) 1) (format "these %d articles" (length articles)) ! "this article") ! (if gnus-current-move-group ! (format "(%s default) " gnus-current-move-group) ! "")) ! gnus-active-hashtb nil nil (gnus-group-real-prefix gnus-newsgroup-name)))) + (if (string= to-newsgroup "") + (setq to-newsgroup (or gnus-current-move-group ""))) + (or (gnus-gethash to-newsgroup gnus-active-hashtb) + (error "No such group: %s" to-newsgroup)) + (setq gnus-current-move-group to-newsgroup) (or (gnus-check-backend-function 'request-accept-article (or select-method to-newsgroup)) (error "%s does not support article copying" to-newsgroup)) *************** *** 7633,7639 **** (gnus-summary-update-mark gnus-replied-mark 'replied)) t)))) ! (defun gnus-summary-mark-forward (n &optional mark) "Mark N articles as read forwards. If N is negative, mark backwards instead. Mark with MARK. If MARK is ? , ?! or ??, articles will be --- 7766,7772 ---- (gnus-summary-update-mark gnus-replied-mark 'replied)) t)))) ! (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. If MARK is ? , ?! or ??, articles will be *************** *** 7646,7652 **** (n (abs n)) (mark (or mark gnus-dread-mark))) (while (and (> n 0) ! (gnus-summary-mark-article nil mark) (zerop (gnus-summary-next-subject (if backward -1 1) gnus-summary-goto-unread))) (setq n (1- n))) --- 7779,7785 ---- (n (abs n)) (mark (or mark gnus-dread-mark))) (while (and (> n 0) ! (gnus-summary-mark-article nil mark no-expire) (zerop (gnus-summary-next-subject (if backward -1 1) gnus-summary-goto-unread))) (setq n (1- n))) *************** *** 7654,7660 **** (gnus-set-mode-line 'summary) n)) ! (defun gnus-summary-mark-article (&optional article mark) "Mark ARTICLE with MARK. MARK can be any character. Five MARK strings are reserved: ? (unread), --- 7787,7793 ---- (gnus-set-mode-line 'summary) n)) ! (defun gnus-summary-mark-article (&optional article mark no-expire) "Mark ARTICLE with MARK. MARK can be any character. Five MARK strings are reserved: ? (unread), *************** *** 7663,7675 **** If ARTICLE is nil, then the article on the current line will be marked." ;; If no mark is given, then we check auto-expiring. ! (and (or (not mark) (and (numberp mark) (or (= mark gnus-killed-mark) (= mark gnus-dread-mark) (= mark gnus-catchup-mark) (= mark gnus-low-score-mark) (= mark gnus-read-mark)))) - gnus-newsgroup-auto-expire (setq mark gnus-expirable-mark)) (let* ((buffer-read-only nil) (mark (or (and (stringp mark) (aref mark 0)) mark gnus-dread-mark)) --- 7796,7809 ---- If ARTICLE is nil, then the article on the current line will be marked." ;; If no mark is given, then we check auto-expiring. ! (and (not no-expire) ! gnus-newsgroup-auto-expire ! (or (not mark) (and (numberp mark) (or (= mark gnus-killed-mark) (= mark gnus-dread-mark) (= mark gnus-catchup-mark) (= mark gnus-low-score-mark) (= mark gnus-read-mark)))) (setq mark gnus-expirable-mark)) (let* ((buffer-read-only nil) (mark (or (and (stringp mark) (aref mark 0)) mark gnus-dread-mark)) *************** *** 7775,7794 **** The difference between N and the actual number of articles marked is returned." (interactive "p") ! (gnus-summary-mark-forward n)) (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))) (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. ! Any kind of string (length 1) except for a space and `-' is ok." (gnus-summary-mark-article article mark)) (defun gnus-summary-clear-mark-forward (n) --- 7909,7927 ---- The difference between N and the actual number of articles marked is returned." (interactive "p") ! (gnus-summary-mark-forward n gnus-dread-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-dread-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) *************** *** 8015,8020 **** --- 8148,8162 ---- (interactive) (gnus-summary-catchup-and-exit t quietly)) + ;; Suggested by "Arne Eofsson" . + (defun gnus-summary-catchup-and-goto-next-group (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") + (gnus-summary-catchup all) + (gnus-summary-next-group)) + ;; Thread-based commands. (defun gnus-summary-toggle-threads (arg) *************** *** 8314,8322 **** gnus-newsgroup-headers-hashtb-by-number))) (if (vectorp header) (progn ! (gnus-summary-display-article (car articles) t) ! (if (not gnus-save-all-headers) (gnus-article-hide-headers t)) (if gnus-default-article-saver (funcall gnus-default-article-saver) (error "No default saver is defined."))) --- 8456,8476 ---- gnus-newsgroup-headers-hashtb-by-number))) (if (vectorp header) (progn ! (gnus-summary-select-article t nil nil (car articles)) ! (or gnus-save-all-headers (gnus-article-hide-headers t)) + ;; Remove any X-Gnus lines. + (save-excursion + (save-restriction + (set-buffer gnus-article-buffer) + (let ((buffer-read-only nil)) + (goto-char (point-min)) + (narrow-to-region (point) (or (search-forward "\n\n" nil t) + (point-max))) + (while (re-search-forward "^X-Gnus" nil t) + (delete-region (progn (beginning-of-line) (point)) + (progn (forward-line 1) (point)))) + (widen)))) (if gnus-default-article-saver (funcall gnus-default-article-saver) (error "No default saver is defined."))) *************** *** 8576,8584 **** (if (y-or-n-p "Expire kill? ") (current-time-string) nil))) ! (and prompt (setq match (read-string "Match: " match))) ! (let ((score (gnus-score-default score))) ! (gnus-summary-score-effect header match type score) (and (= score gnus-score-interactive-default-score) (setq score nil)) (let ((new (cond (type --- 8730,8745 ---- (if (y-or-n-p "Expire kill? ") (current-time-string) nil))) ! (let ((score (gnus-score-default score)) ! (header (downcase header))) ! (and prompt (setq match (read-string ! (format "Match %s on %s, %s: " ! (if date "temp" "permanent") ! header ! (if (< score 0) "lower" "raise")) ! match))) ! (and (>= (nth 1 (assoc header gnus-header-index)) 0) ! (gnus-summary-score-effect header match type score)) (and (= score gnus-score-interactive-default-score) (setq score nil)) (let ((new (cond (type *************** *** 8657,8662 **** --- 8818,8830 ---- "from" (gnus-summary-header "from") nil (- (gnus-score-default level)) (current-time-string) t)) + (defun gnus-summary-temporarily-lower-by-body (level) + "Temporarily lower score by LEVEL for a match on the body of the article. + See `gnus-score-expiry-days'." + (interactive "P") + (gnus-summary-score-entry + "body" "" nil (- (gnus-score-default level)) (current-time-string) t)) + (defun gnus-summary-temporarily-lower-by-id (level) "Temporarily lower score by LEVEL for current message-id. See `gnus-score-expiry-days'." *************** *** 8696,8701 **** --- 8864,8875 ---- "from" (gnus-summary-header "from") nil (- (gnus-score-default level)) nil t)) + (defun gnus-summary-lower-by-body (level) + "Lower score by LEVEL for a match on the body of the article." + (interactive "P") + (gnus-summary-score-entry + "body" "" nil (- (gnus-score-default level)) nil t)) + (defun gnus-summary-lower-by-id (level) "Lower score by LEVEL for current message-id." (interactive "P") *************** *** 8729,8734 **** --- 8903,8914 ---- (gnus-summary-score-entry "from" (gnus-summary-header "from") nil level (current-time-string) t)) + (defun gnus-summary-temporarily-raise-by-body (level) + "Temporarily raise score by LEVEL for a match on the body of the article. + See `gnus-score-expiry-days'." + (interactive "P") + (gnus-summary-score-entry "body" "" nil level (current-time-string) t)) + (defun gnus-summary-temporarily-raise-by-id (level) "Temporarily raise score by LEVEL for current message-id. See `gnus-score-expiry-days'." *************** *** 8764,8769 **** --- 8944,8954 ---- (gnus-summary-score-entry "from" (gnus-summary-header "from") nil level nil t)) + (defun gnus-summary-raise-by-body (level) + "Raise score by LEVEL for a match on the body of the article." + (interactive "P") + (gnus-summary-score-entry "body" "" nil level nil t)) + (defun gnus-summary-raise-by-id (level) "Raise score by LEVEL for current message-id." (interactive "P") *************** *** 9751,9756 **** --- 9936,9942 ---- (car (gnus-score-get 'mark-and-expunge alist))) (read-only (gnus-score-get 'read-only alist)) (files (gnus-score-get 'files alist)) + (orphan (gnus-score-get 'orphan alist)) (eval (gnus-score-get 'eval alist))) ;; We do not respect eval and files atoms from global score ;; files. *************** *** 9760,9765 **** --- 9946,9952 ---- (gnus-score-load-file file)) files)))) (and eval (not global) (eval eval)) + (if orphan (setq gnus-orphan-score (car orphan))) (setq gnus-summary-mark-below (or mark mark-and-expunge gnus-summary-mark-below)) (setq gnus-summary-expunge-below *************** *** 9776,9788 **** (setq gnus-score-alist nil) (gnus-score-load-score-alist file) (or gnus-score-alist ! (setq gnus-score-alist (copy-alist '((touched . nil))))) (setq gnus-score-cache (cons (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) (let (alist) --- 9963,9975 ---- (setq gnus-score-alist nil) (gnus-score-load-score-alist file) (or gnus-score-alist ! (setq gnus-score-alist (copy-alist '((touched nil))))) (setq gnus-score-cache (cons (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) (let (alist) *************** *** 9828,9834 **** (message "Illegal score element: %s" (car a)) (setq err t)) ((and (stringp (car (car a))) ! (not (consp (nth 1 (car a))))) (message "Illegal header match: %s" (nth 1 (car a))) (setq err t)) (t --- 10015,10021 ---- (message "Illegal score element: %s" (car a)) (setq err t)) ((and (stringp (car (car a))) ! (not (listp (nth 1 (car a))))) (message "Illegal header match: %s" (nth 1 (car a))) (setq err t)) (t *************** *** 9856,9872 **** (gnus-day-number (nth 3 (car scor)))) (if (nth 1 (car scor)) 'r 's))) (setq scor (cdr scor)))) ! (setq out (cons (list (car entry) (cdr entry)) out))) (setq alist (cdr alist))) (cons (list 'touched t) (nreverse out)))) (defun gnus-score-save () ;; Save all SCORE information. ! (let (cache) ! (save-excursion ! (set-buffer gnus-summary-buffer) ! (setq cache gnus-score-cache ! gnus-score-cache nil)) (save-excursion (setq gnus-score-alist nil) (set-buffer (get-buffer-create "*Score*")) --- 10043,10058 ---- (gnus-day-number (nth 3 (car scor)))) (if (nth 1 (car scor)) 'r 's))) (setq scor (cdr scor)))) ! (setq out (cons (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)) (save-excursion (setq gnus-score-alist nil) (set-buffer (get-buffer-create "*Score*")) *************** *** 9885,9891 **** (erase-buffer) (let (emacs-lisp-mode-hook) (pp score (current-buffer))) ! (make-directory (file-name-directory file) t) (write-region (point-min) (point-max) file nil 'silent)))) (kill-buffer (current-buffer))))) --- 10071,10077 ---- (erase-buffer) (let (emacs-lisp-mode-hook) (pp score (current-buffer))) ! (gnus-make-directory (file-name-directory file)) (write-region (point-min) (point-max) file nil 'silent)))) (kill-buffer (current-buffer))))) *************** *** 9896,9901 **** --- 10082,10089 ---- (funcall gnus-score-find-score-files-function gnus-newsgroup-name))) scores) + ;; PLM: probably this is not the best place to clear orphan-score + (setq gnus-orphan-score nil) ;; Load the SCORE files. (while score-files (setq scores (nconc (gnus-score-load-file (car score-files)) scores)) *************** *** 9922,9931 **** (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 (get-buffer-create "*Headers*")) (buffer-disable-undo (current-buffer)) ;; Run each header through the score process. (while entries (setq entry (car entries) --- 10110,10125 ---- (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 (get-buffer-create "*Headers*")) (buffer-disable-undo (current-buffer)) + ;; score orphans + (if gnus-orphan-score + (progn + (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 (car entries) *************** *** 9952,9962 **** (message "Scoring...done"))))) - ;;(defun gnus-score-integer (scores header now expire) - ;; ) ! ;;(defun gnus-score-date (scores header now expire) ! ;; ) (defun gnus-score-string (scores header now expire) ;; Score ARTICLES according to HEADER in SCORES. --- 10146,10400 ---- (message "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)) ! (if (string-equal tref "") ;no references line ! (setq id-list (cons 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)) ! (index (nth 1 (assoc "references" gnus-header-index))) ! 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) ! (if (not (string= this "")) ! (if (equal last this) ! ;; O(N*H) cons-cells used here, where H is the number of ! ;; headers. ! (setq alike (cons art alike)) ! (if last ! (progn ! ;; Insert the line, with a text property on the ! ;; terminating newline refering to the articles with ! ;; this line. ! (insert last ?\n) ! (put-text-property (1- (point)) (point) 'articles alike))) ! (setq alike (list art) ! last this)))) ! (and last ; Bwadr, duplicate code. ! (progn ! (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 ! (progn ! (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) ! (let ((gnus-score-index (nth 1 (assoc header gnus-header-index))) ! alike last this art entries alist articles) ! ! ;; 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) ! arts art) ! ;; 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 ! (and (funcall match-func match ! (or (aref (car (car articles)) gnus-score-index) 0)) ! (progn ! (setq found t) ! (setcdr (car articles) (+ score (cdr (car articles)))))) ! (setq articles (cdr articles))) ! ;; Update expire date ! (cond ((null date)) ;Permanent entry. ! (found ;Match, update date. ! (gnus-score-set 'touched '(t) alist) ! (setcar (nthcdr 2 kill) now)) ! ((< date expire) ;Old entry, remove. ! (gnus-score-set 'touched '(t) alist) ! (setcdr entries (cdr rest)) ! (setq rest entries))) ! (setq entries rest)))))) ! ! (defun gnus-score-date (scores header now expire) ! (let ((gnus-score-index (nth 1 (assoc header gnus-header-index))) ! alike last this art entries alist articles) ! ! ;; 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 (timezone-make-date-sortable (nth 0 kill))) ! (type (or (nth 3 kill) 'before)) ! (score (or (nth 1 kill) gnus-score-interactive-default-score)) ! (date (nth 2 kill)) ! (found nil) ! (match-func ! (cond ((eq type 'after) 'string<) ! ((eq type 'before) 'gnus-string>) ! ((eq type 'at) 'string=) ! (t (error "Illegal match type: %s" type)))) ! (articles gnus-scores-articles) ! arts art l) ! ;; 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 ! (and ! (setq l (aref (car (car articles)) gnus-score-index)) ! (funcall match-func match (timezone-make-date-sortable l)) ! (progn ! (setq found t) ! (setcdr (car articles) (+ score (cdr (car articles)))))) ! (setq articles (cdr articles))) ! ;; Update expire date ! (cond ((null date)) ;Permanent entry. ! (found ;Match, update date. ! (gnus-score-set 'touched '(t) alist) ! (setcar (nthcdr 2 kill) now)) ! ((< date expire) ;Old entry, remove. ! (gnus-score-set 'touched '(t) alist) ! (setcdr entries (cdr rest)) ! (setq rest entries))) ! (setq entries rest)))))) ! ! (defun gnus-score-body (scores header now expire) ! (save-excursion ! (set-buffer nntp-server-buffer) ! (save-restriction ! (let* ((buffer-read-only nil) ! (articles gnus-scores-articles) ! (all-scores scores) ! (request-func (cond ((string= "head" (downcase header)) ! 'gnus-request-head) ! ((string= "body" (downcase header)) ! 'gnus-request-body) ! (t 'gnus-request-article))) ! alike last this art entries alist ofunc article) ! ;; Not all backends support partial fetching. In that case, ! ;; we just fetch the entire article. ! (or (gnus-check-backend-function request-func gnus-newsgroup-name) ! (progn ! (setq ofunc request-func) ! (setq request-func 'gnus-request-article))) ! (while articles ! (setq article (header-number (car (car articles)))) ! (message "Scoring on article %s..." article) ! (if (not (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. ! (if 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 (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) ! (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)))) ! arts art) ! (goto-char (point-min)) ! (if (funcall search-func match nil t) ! ;; Found a match, update scores. ! (progn ! (setcdr (car articles) (+ score (cdr (car articles)))) ! (setq found t))) ! ;; Update expire date ! (cond ((null date)) ;Permanent entry. ! (found ;Match, update date. ! (gnus-score-set 'touched '(t) alist) ! (setcar (nthcdr 2 kill) now)) ! ((< 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))))))) (defun gnus-score-string (scores header now expire) ;; Score ARTICLES according to HEADER in SCORES. *************** *** 10013,10025 **** (score (or (nth 1 kill) gnus-score-interactive-default-score)) (date (nth 2 kill)) (found nil) ! (case-fold-search t) arts art) (goto-char (point-min)) ! (while (cond ((eq type 'r) ! (re-search-forward match nil t)) ! ((eq type 's) ! (search-forward match nil t))) (end-of-line 1) (setq found t arts (get-text-property (point) 'articles)) --- 10451,10470 ---- (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)))) arts art) (goto-char (point-min)) ! (while (funcall search-func match nil t) (end-of-line 1) (setq found t arts (get-text-property (point) 'articles)) *************** *** 10059,10065 **** ("references" 5 gnus-score-string) ("chars" 6 gnus-score-integer) ("lines" 7 gnus-score-integer) ! ("xref" 8 gnus-score-string))) (defun gnus-score-file-name (newsgroup) "Return the name of a score file for NEWSGROUP." --- 10504,10513 ---- ("references" 5 gnus-score-string) ("chars" 6 gnus-score-integer) ("lines" 7 gnus-score-integer) ! ("xref" 8 gnus-score-string) ! ("head" -1 gnus-score-body) ! ("body" -1 gnus-score-body) ! ("all" -1 gnus-score-body))) (defun gnus-score-file-name (newsgroup) "Return the name of a score file for NEWSGROUP." *************** *** 10336,10342 **** (and gnus-winconf-post-news (set-window-configuration gnus-winconf-post-news)))) ;; We don't want to return to article buffer later. ! (bury-buffer gnus-article-buffer)))) (defun gnus-summary-followup-with-original () "Compose a followup to an article and include the original article." --- 10784,10791 ---- (and gnus-winconf-post-news (set-window-configuration gnus-winconf-post-news)))) ;; We don't want to return to article buffer later. ! (bury-buffer gnus-article-buffer))) ! (gnus-article-hide-headers-if-wanted)) (defun gnus-summary-followup-with-original () "Compose a followup to an article and include the original article." *************** *** 10360,10367 **** (interactive) (gnus-set-global-variables) (gnus-summary-select-article t) ! (gnus-eval-in-buffer-window gnus-article-buffer ! (gnus-cancel-news))) (defun gnus-summary-supersede-article () "Compose an article that will supersede a previous article. --- 10809,10816 ---- (interactive) (gnus-set-global-variables) (gnus-summary-select-article t) ! (gnus-eval-in-buffer-window gnus-article-buffer (gnus-cancel-news)) ! (gnus-article-hide-headers-if-wanted)) (defun gnus-summary-supersede-article () "Compose an article that will supersede a previous article. *************** *** 10492,10499 **** (re-search-forward "^Subject:" nil t) (end-of-line)) (t ! (search-forward (concat "\n" mail-header-separator "\n")))) ! (search-forward (concat "\n" mail-header-separator "\n")) (if yank (save-excursion (run-hooks 'news-reply-header-hook) --- 10941,10952 ---- (re-search-forward "^Subject:" nil t) (end-of-line)) (t ! (re-search-forward ! (concat "^" (regexp-quote mail-header-separator) "$")) ! (forward-line 1))) ! (re-search-forward ! (concat "^" (regexp-quote mail-header-separator) "$")) ! (forward-line 1) (if yank (save-excursion (run-hooks 'news-reply-header-hook) *************** *** 10530,10537 **** (point-min) (progn (goto-char (point-min)) ! (search-forward (concat "\n" mail-header-separator "\n")) ! (point))) ;; Correct newsgroups field: change sequence of spaces to comma and ;; eliminate spaces around commas. Eliminate imbedded line breaks. --- 10983,10990 ---- (point-min) (progn (goto-char (point-min)) ! (re-search-forward ! (concat "^" (regexp-quote mail-header-separator) "$")))) ;; Correct newsgroups field: change sequence of spaces to comma and ;; eliminate spaces around commas. Eliminate imbedded line breaks. *************** *** 10601,10607 **** (progn ;; Insert "courtesy" mail message. (goto-char 1) ! (re-search-forward mail-header-separator) (forward-line 1) (insert gnus-mail-courtesy-message) (funcall gnus-mail-send-method) --- 11054,11062 ---- (progn ;; Insert "courtesy" mail message. (goto-char 1) ! (re-search-forward ! (concat "^" (regexp-quote ! mail-header-separator) "$")) (forward-line 1) (insert gnus-mail-courtesy-message) (funcall gnus-mail-send-method) *************** *** 10614,10620 **** (goto-char 1) (narrow-to-region ! 1 (re-search-forward mail-header-separator)) (goto-char 1) (delete-matching-lines "BCC:.*"))) (ding) --- 11069,11077 ---- (goto-char 1) (narrow-to-region ! 1 (re-search-forward ! (concat "^" (regexp-quote ! mail-header-separator) "$"))) (goto-char 1) (delete-matching-lines "BCC:.*"))) (ding) *************** *** 10659,10665 **** (save-excursion (save-restriction (goto-char (point-min)) ! (narrow-to-region (point) (search-forward mail-header-separator)) (if (string-match "^cmsg " (mail-fetch-field "subject")) (gnus-y-or-n-p "The control code \"cmsg \" is in the subject. Really post? ") --- 11116,11125 ---- (save-excursion (save-restriction (goto-char (point-min)) ! (narrow-to-region ! (point) ! (re-search-forward ! (concat "^" (regexp-quote mail-header-separator) "$"))) (if (string-match "^cmsg " (mail-fetch-field "subject")) (gnus-y-or-n-p "The control code \"cmsg \" is in the subject. Really post? ") *************** *** 10675,10681 **** (save-excursion (save-restriction (goto-char (point-min)) ! (narrow-to-region (point) (search-forward mail-header-separator)) (goto-char (point-min)) (while (and (not found) (re-search-forward "^[^ \t:]+: " nil t)) (save-excursion --- 11135,11144 ---- (save-excursion (save-restriction (goto-char (point-min)) ! (narrow-to-region ! (point) ! (re-search-forward ! (concat "^" (regexp-quote mail-header-separator) "$"))) (goto-char (point-min)) (while (and (not found) (re-search-forward "^[^ \t:]+: " nil t)) (save-excursion *************** *** 10693,10699 **** (save-excursion (save-restriction (goto-char (point-min)) ! (narrow-to-region (point) (search-forward mail-header-separator)) (if (re-search-backward "^Sendsys:\\|^Version:" nil t) (gnus-yes-or-no-p (format "The article contains a %s command. Really post? " --- 11156,11165 ---- (save-excursion (save-restriction (goto-char (point-min)) ! (narrow-to-region ! (point) ! (re-search-forward ! (concat "^" (regexp-quote mail-header-separator) "$"))) (if (re-search-backward "^Sendsys:\\|^Version:" nil t) (gnus-yes-or-no-p (format "The article contains a %s command. Really post? " *************** *** 10703,10709 **** (save-excursion (save-restriction (goto-char (point-min)) ! (narrow-to-region (point) (search-forward mail-header-separator)) (let* ((case-fold-search t) (from (mail-fetch-field "from"))) (if (and from --- 11169,11178 ---- (save-excursion (save-restriction (goto-char (point-min)) ! (narrow-to-region ! (point) ! (re-search-forward ! (concat "^" (regexp-quote mail-header-separator) "$"))) (let* ((case-fold-search t) (from (mail-fetch-field "from"))) (if (and from *************** *** 10717,10723 **** (save-excursion (save-restriction (goto-char (point-min)) ! (narrow-to-region (point) (search-forward mail-header-separator)) (while (and (progn --- 11186,11195 ---- (save-excursion (save-restriction (goto-char (point-min)) ! (narrow-to-region ! (point) ! (re-search-forward ! (concat "^" (regexp-quote mail-header-separator) "$"))) (while (and (progn *************** *** 10807,10813 **** (narrow-to-region (point-min) (save-excursion ! (search-forward (concat "\n" mail-header-separator "\n")) (forward-line -1) (point))) (gnus-inews-insert-headers) --- 11279,11286 ---- (narrow-to-region (point-min) (save-excursion ! (re-search-forward ! (concat "^" (regexp-quote mail-header-separator) "$")) (forward-line -1) (point))) (gnus-inews-insert-headers) *************** *** 10820,10826 **** (insert-buffer-substring artbuf) ;; Remove the header separator. (goto-char (point-min)) ! (search-forward (concat "\n" mail-header-separator "\n")) (replace-match "\n\n") ;; This hook may insert a signature. (run-hooks 'gnus-prepare-article-hook) --- 11293,11300 ---- (insert-buffer-substring artbuf) ;; Remove the header separator. (goto-char (point-min)) ! (re-search-forward ! (concat "^" (regexp-quote mail-header-separator) "$")) (replace-match "\n\n") ;; This hook may insert a signature. (run-hooks 'gnus-prepare-article-hook) *************** *** 10890,10895 **** --- 11364,11370 ---- (if (setq subject (mail-fetch-field "subject")) (progn (and gnus-summary-gather-subject-limit + (numberp gnus-summary-gather-subject-limit) (> (length subject) gnus-summary-gather-subject-limit) (setq subject (substring subject 0 *************** *** 11035,11051 **** (defun gnus-inews-user-name () "Return user's network address as \"NAME@DOMAIN (FULL-NAME)\"." (let ((full-name (gnus-inews-full-name))) ! (concat (if (or gnus-user-login-name gnus-use-generic-from ! gnus-local-domain (getenv "DOMAINNAME")) ! (concat (gnus-inews-login-name) "@" ! (gnus-inews-domain-name gnus-use-generic-from)) ! user-mail-address) ! ;; User's full name. ! (cond ((string-equal full-name "") "") ! ((string-equal full-name "&") ;Unix hack. ! (concat " (" (user-login-name) ")")) ! (t ! (concat " (" full-name ")")))))) (defun gnus-inews-login-name () "Return login name." --- 11510,11527 ---- (defun gnus-inews-user-name () "Return user's network address as \"NAME@DOMAIN (FULL-NAME)\"." (let ((full-name (gnus-inews-full-name))) ! (or gnus-user-from-line ! (concat (if (or gnus-user-login-name gnus-use-generic-from ! gnus-local-domain (getenv "DOMAINNAME")) ! (concat (gnus-inews-login-name) "@" ! (gnus-inews-domain-name gnus-use-generic-from)) ! user-mail-address) ! ;; User's full name. ! (cond ((string-equal full-name "") "") ! ((string-equal full-name "&") ;Unix hack. ! (concat " (" (user-login-name) ")")) ! (t ! (concat " (" full-name ")"))))))) (defun gnus-inews-login-name () "Return login name." *************** *** 11176,11182 **** (setq gnus-winconf-post-news (current-window-configuration)) (let ((gnus-newsgroup-name gnus-newsgroup-name)) (bury-buffer gnus-article-buffer) ! (funcall gnus-mail-reply-method yank))) (defun gnus-summary-reply-with-original () "Reply mail to news author with original article. --- 11652,11659 ---- (setq gnus-winconf-post-news (current-window-configuration)) (let ((gnus-newsgroup-name gnus-newsgroup-name)) (bury-buffer gnus-article-buffer) ! (funcall gnus-mail-reply-method yank)) ! (gnus-article-hide-headers-if-wanted)) (defun gnus-summary-reply-with-original () "Reply mail to news author with original article. *************** *** 11192,11198 **** (setq gnus-winconf-post-news (current-window-configuration)) (set-buffer gnus-article-buffer) (let ((gnus-newsgroup-name gnus-newsgroup-name)) ! (funcall gnus-mail-forward-method))) (defun gnus-summary-mail-other-window () "Compose mail in other window. --- 11669,11676 ---- (setq gnus-winconf-post-news (current-window-configuration)) (set-buffer gnus-article-buffer) (let ((gnus-newsgroup-name gnus-newsgroup-name)) ! (funcall gnus-mail-forward-method)) ! (gnus-article-hide-headers-if-wanted)) (defun gnus-summary-mail-other-window () "Compose mail in other window. *************** *** 11256,11263 **** (widen)) (setq news-reply-yank-from from) (setq news-reply-yank-message-id message-id) ! (mail-setup (or to-address follow-to reply-to from sender "") subject message-of nil gnus-article-buffer nil) ;; Fold long references line to follow RFC1036. (mail-position-on-field "References") (let ((begin (- (point) (length "References: "))) --- 11734,11749 ---- (widen)) (setq news-reply-yank-from from) (setq news-reply-yank-message-id message-id) ! (mail-setup (or to-address ! (if (and follow-to (not (stringp follow-to))) "" ! (or follow-to reply-to from sender ""))) subject message-of nil gnus-article-buffer nil) + (if (and follow-to (listp follow-to)) + (progn + (goto-char (point-min)) + (while follow-to + (insert (car (car follow-to)) ": " (cdr (car follow-to)) "\n") + (setq follow-to (cdr follow-to))))) ;; Fold long references line to follow RFC1036. (mail-position-on-field "References") (let ((begin (- (point) (length "References: "))) *************** *** 11270,11276 **** ;; without inserting extra newline. (fill-region-as-paragraph begin (1+ (point)))) (goto-char (point-min)) ! (search-forward (concat "\n" mail-header-separator "\n")) (if yank (let ((last (point))) (run-hooks 'news-reply-header-hook) --- 11756,11764 ---- ;; without inserting extra newline. (fill-region-as-paragraph begin (1+ (point)))) (goto-char (point-min)) ! (re-search-forward ! (concat "^" (regexp-quote mail-header-separator) "$")) ! (forward-line 1) (if yank (let ((last (point))) (run-hooks 'news-reply-header-hook) *************** *** 11314,11321 **** ;; This is almost a carbon copy of rmail-forward in rmail.el. (let ((forward-buffer (current-buffer)) (subject ! (concat "[" gnus-newsgroup-name "] " ! (or (gnus-fetch-field "Subject") ""))) beg) ;; If only one window, use it for the mail buffer. ;; Otherwise, use another window for the mail buffer --- 11802,11814 ---- ;; This is almost a carbon copy of rmail-forward in rmail.el. (let ((forward-buffer (current-buffer)) (subject ! (concat "[" (if (memq 'mail (assoc (symbol-name ! (car (gnus-find-method-for-group ! gnus-newsgroup-name))) ! gnus-valid-select-methods)) ! (gnus-fetch-field "From") ! gnus-newsgroup-name) ! "] " (or (gnus-fetch-field "Subject") ""))) beg) ;; If only one window, use it for the mail buffer. ;; Otherwise, use another window for the mail buffer *************** *** 11345,11351 **** (defun gnus-mail-other-window-using-mail () "Compose mail other window using mail." (mail-other-window nil nil nil nil nil (get-buffer gnus-article-buffer)) ! (use-local-map (copy-keymap emacs-lisp-mode-map)) (local-set-key "\C-c\C-c" 'gnus-mail-send-and-exit)) --- 11838,11844 ---- (defun gnus-mail-other-window-using-mail () "Compose mail other window using mail." (mail-other-window nil nil nil nil nil (get-buffer gnus-article-buffer)) ! (use-local-map (copy-keymap (current-local-map))) (local-set-key "\C-c\C-c" 'gnus-mail-send-and-exit)) *************** *** 11674,11679 **** --- 12167,12179 ---- (funcall (gnus-get-function method 'request-group) (gnus-group-real-name group) (nth 1 method) dont-check))) + (defun gnus-list-active-group (group) + (let ((method (gnus-find-method-for-group group)) + (func 'list-active-group)) + (and (gnus-check-backend-function func group) + (funcall (gnus-get-function method func) + (gnus-group-real-name group) (nth 1 method))))) + (defun gnus-request-group-description (group) (let ((method (gnus-find-method-for-group group)) (func 'request-group-description)) *************** *** 11691,11697 **** (funcall (gnus-get-function method 'retrieve-headers) articles (gnus-group-real-name group) (nth 1 method)))) ! (defun gnus-request-article (article group buffer) (let ((method (gnus-find-method-for-group group))) (funcall (gnus-get-function method 'request-article) article (gnus-group-real-name group) (nth 1 method) buffer))) --- 12191,12197 ---- (funcall (gnus-get-function method 'retrieve-headers) articles (gnus-group-real-name group) (nth 1 method)))) ! (defun gnus-request-article (article group &optional buffer) (let ((method (gnus-find-method-for-group group))) (funcall (gnus-get-function method 'request-article) article (gnus-group-real-name group) (nth 1 method) buffer))) *************** *** 11871,11891 **** (if (or (gnus-gethash group gnus-killed-hashtb) (gnus-gethash group gnus-newsrc-hashtb)) () ! (if (and gnus-newsrc-options-n-yes ! (string-match gnus-newsrc-options-n-yes group)) ! (progn ! (setq groups (1+ groups)) ! (gnus-sethash group group gnus-killed-hashtb) ! (funcall gnus-subscribe-options-newsgroup-method group)) ! (if (or (null gnus-newsrc-options-n-no) ! (not (string-match gnus-newsrc-options-n-no group))) ! ;; Add this group. ! (progn ! (setq groups (1+ groups)) ! (gnus-sethash group group gnus-killed-hashtb) ! (if gnus-subscribe-hierarchical-interactive ! (setq new-newsgroups (cons group new-newsgroups)) ! (funcall gnus-subscribe-newsgroup-method group))))))) gnus-active-hashtb) (if new-newsgroups (gnus-subscribe-hierarchical-interactive new-newsgroups)) --- 12371,12390 ---- (if (or (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 ! (setq new-newsgroups (cons group new-newsgroups)) ! (funcall gnus-subscribe-newsgroup-method group))))))) gnus-active-hashtb) (if new-newsgroups (gnus-subscribe-hierarchical-interactive new-newsgroups)) *************** *** 11894,11899 **** --- 12393,12422 ---- (message "%d new newsgroup%s arrived." groups (if (> groups 1) "s have" " has"))))))) + (defun gnus-matches-options-n (group) + ;; Returns `subscribe' if the group is to be uncoditionally + ;; 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-not-subscribe + (string-match gnus-options-not-subscribe group)) + 'subscribe) + ((and gnus-options-subscribe + (string-match gnus-options-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 (car (car gnus-newsrc-options-n)) group))) + (setq regs (cdr regs))) + (and regs (cdr (car regs))))))) + (defun gnus-ask-server-for-new-groups () (let* ((date (or gnus-newsrc-last-checked-date (current-time-string))) (methods (cons gnus-select-method *************** *** 11927,11945 **** ;; The group is already known. () (gnus-sethash group (symbol-value group-sym) gnus-active-hashtb) ! (if (and gnus-newsrc-options-n-yes ! (string-match gnus-newsrc-options-n-yes group)) ! (progn ! (setq groups (1+ groups)) ! (funcall gnus-subscribe-options-newsgroup-method group)) ! (if (or (null gnus-newsrc-options-n-no) ! (not (string-match gnus-newsrc-options-n-no group))) ! ;; Add this group. ! (progn ! (setq groups (1+ groups)) ! (if gnus-subscribe-hierarchical-interactive ! (setq new-newsgroups (cons group new-newsgroups)) ! (funcall gnus-subscribe-newsgroup-method group))))))) hashtb) (if new-newsgroups (gnus-subscribe-hierarchical-interactive new-newsgroups)) --- 12450,12469 ---- ;; The group is already known. () (gnus-sethash group (symbol-value group-sym) gnus-active-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 ! (setq new-newsgroups (cons group new-newsgroups)) ! (funcall gnus-subscribe-newsgroup-method group))))))) hashtb) (if new-newsgroups (gnus-subscribe-hierarchical-interactive new-newsgroups)) *************** *** 11966,11977 **** (mapatoms (lambda (sym) (setq group (symbol-name sym)) ! (if (and gnus-newsrc-options-n-yes ! (string-match gnus-newsrc-options-n-yes group)) ! (funcall gnus-subscribe-options-newsgroup-method group) ! (and (or (null gnus-newsrc-options-n-no) ! (not (string-match gnus-newsrc-options-n-no group))) ! (setq gnus-killed-list (cons group gnus-killed-list))))) gnus-active-hashtb) (while groups (if (gnus-gethash (car groups) gnus-active-hashtb) --- 12490,12504 ---- (mapatoms (lambda (sym) (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 ! (setq gnus-killed-list (cons group gnus-killed-list)))))) gnus-active-hashtb) (while groups (if (gnus-gethash (car groups) gnus-active-hashtb) *************** *** 12043,12051 **** ;; go, and change the subscription level. If it is to be killed, ;; we enter it into the killed or zombie list. (cond ((>= level 8) ! (if (= level 8) ! (setq gnus-zombie-list (cons group gnus-zombie-list)) ! (setq gnus-killed-list (cons 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 --- 12570,12579 ---- ;; go, and change the subscription level. If it is to be killed, ;; we enter it into the killed or zombie list. (cond ((>= level 8) ! (and (string= group (gnus-group-real-name group)) ! (if (= level 8) ! (setq gnus-zombie-list (cons group gnus-zombie-list)) ! (setq gnus-killed-list (cons 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 *************** *** 12619,12626 **** ;; gnus-killed-list) because the quick startup file may contain bogus ;; values. (setq gnus-newsrc-options nil) ! (setq gnus-newsrc-options-n-yes nil) ! (setq gnus-newsrc-options-n-no nil) (gnus-parse-options-lines) (gnus-parse-newsrc-body)) --- 13147,13153 ---- ;; gnus-killed-list) because the quick startup file may contain bogus ;; values. (setq gnus-newsrc-options nil) ! (setq gnus-newsrc-options-n nil) (gnus-parse-options-lines) (gnus-parse-newsrc-body)) *************** *** 12670,12684 **** (substring gnus-newsrc-options (match-beginning 1) (match-end 1)))))) ! (let ((yes-and-no (and result (gnus-parse-n-options result)))) ! (and (or gnus-options-subscribe (car yes-and-no)) ! (setq gnus-newsrc-options-n-yes ! (concat (or gnus-options-subscribe "") ! (or (car yes-and-no) "")))) ! (and (or gnus-options-not-subscribe (cdr yes-and-no)) ! (setq gnus-newsrc-options-n-no ! (concat (or gnus-options-not-subscribe "") ! (or (cdr yes-and-no) ""))))) nil)) (defun gnus-parse-newsrc-body () --- 13197,13203 ---- (substring gnus-newsrc-options (match-beginning 1) (match-end 1)))))) ! (gnus-parse-n-options result) nil)) (defun gnus-parse-newsrc-body () *************** *** 12785,12794 **** (defun gnus-parse-n-options (options) "Parse -n NEWSGROUPS options and return a cons of YES and NO regexps." ! (let ((yes nil) ! (no nil) ! (yes-or-no nil) ;`!' or not. ! (newsgroup nil)) ;; Parse each newsgroup description such as "comp.all". Commas ;; and white spaces can be a newsgroup separator. (while --- 13304,13310 ---- (defun gnus-parse-n-options (options) "Parse -n NEWSGROUPS options and return a cons of YES and NO regexps." ! (let (yes no yes-or-no out newsgroup) ;; Parse each newsgroup description such as "comp.all". Commas ;; and white spaces can be a newsgroup separator. (while *************** *** 12808,12839 **** ".+" (substring newsgroup (match-beginning 2))))) ;; It is yes or no. ! (cond ((string-equal yes-or-no "!") ! (setq no (cons newsgroup no))) ! ((string-equal newsgroup ".+")) ;Ignore `all'. ! (t ! (setq yes (cons newsgroup yes))))) ! ;; Make a cons of regexps from parsing result. ! ;; We have to append \(\.\|$\) to prevent matching substring of ! ;; newsgroup. For example, "jp.net" should not match with ! ;; "jp.network". ! ;; Fixes for large regexp problems are from yonezu@nak.math.keio.ac.jp. ! (cons (if yes ! (concat "^\\(" ! (apply (function concat) ! (mapcar ! (lambda (newsgroup) ! (concat newsgroup "\\|")) ! (cdr yes))) ! (car yes) "\\)\\(\\.\\|$\\)")) ! (if no ! (concat "^\\(" ! (apply (function concat) ! (mapcar ! (lambda (newsgroup) ! (concat newsgroup "\\|")) ! (cdr no))) ! (car no) "\\)\\(\\.\\|$\\)"))))) (defun gnus-save-newsrc-file () "Save .newsrc file." --- 13324,13333 ---- ".+" (substring newsgroup (match-beginning 2))))) ;; It is yes or no. ! (setq out (cons (cons (if (string= yes-or-no "!") 'ignore 'subscribe) ! (concat "^" newsgroup "$")) ! out))) ! (setq gnus-newsrc-options-n out))) (defun gnus-save-newsrc-file () "Save .newsrc file." diff --exclude=*.elc --exclude=*~ --exclude=*-[0-9] --exclude=gnus --exclude=readme --context --recursive pub/dgnus/lisp/nnmail.el dgnus/lisp/nnmail.el *** pub/dgnus/lisp/nnmail.el Sun Apr 2 12:57:35 1995 --- dgnus/lisp/nnmail.el Wed Apr 12 18:25:41 1995 *************** *** 151,157 **** (goto-char (point-min)) (narrow-to-region (point-min) (progn (search-forward "\n\n") (point))) ! (set-text-properties (point-min) (point-max) nil) (setq from (header-from header)) (setq date (header-date header)) (and from --- 151,158 ---- (goto-char (point-min)) (narrow-to-region (point-min) (progn (search-forward "\n\n") (point))) ! (let ((buffer-read-only nil)) ! (set-text-properties (point-min) (point-max) nil)) (setq from (header-from header)) (setq date (header-date header)) (and from *************** *** 172,182 **** (widen)) (setq news-reply-yank-from from) (setq news-reply-yank-message-id message-id) ! (mail-setup (or follow-to method-address ! (concat (or sender reply-to from "") ! (if to (concat ", " to) "") ! (if cc (concat ", " cc) ""))) subject message-of nil article-buffer nil) ;; Fold long references line to follow RFC1036. (mail-position-on-field "References") (let ((begin (- (point) (length "References: "))) --- 173,191 ---- (widen)) (setq news-reply-yank-from from) (setq news-reply-yank-message-id message-id) ! (mail-setup (if (and follow-to (listp follow-to)) "" ! (or method-address ! (concat (or sender reply-to from "") ! (if to (concat ", " to) "") ! (if cc (concat ", " cc) "")))) subject message-of nil article-buffer nil) + (if (and follow-to (listp follow-to)) + (progn + (goto-char (point-min)) + (while follow-to + (insert + (car (car follow-to)) ": " (cdr (car follow-to)) "\n") + (setq follow-to (cdr follow-to))))) ;; Fold long references line to follow RFC1036. (mail-position-on-field "References") (let ((begin (- (point) (length "References: "))) *************** *** 327,333 **** (match-end 2))))) group-assoc)))) ;; In addition, add all groups mentioned in `nnmail-split-methods'. ! (let ((methods nnmail-split-methods)) (while methods (if (not (assoc (car (car methods)) group-assoc)) (setq group-assoc --- 336,343 ---- (match-end 2))))) group-assoc)))) ;; In addition, add all groups mentioned in `nnmail-split-methods'. ! (let ((methods (and (not (symbolp nnmail-split-methods)) ! nnmail-split-methods))) (while methods (if (not (assoc (car (car methods)) group-assoc)) (setq group-assoc *************** *** 404,432 **** (goto-char (point-min)) (while (re-search-forward "\\(\r?\n[ \t]+\\)+" nil t) (replace-match " " t t)) ! ;; Go throught the split methods to find a match. ! (while (and methods (or nnmail-crosspost (not group-art))) ! (goto-char (point-max)) ! (if (or (cdr methods) ! (not (equal "" (nth 1 (car methods))))) ! (if (and (condition-case () ! (if (stringp (nth 1 (car methods))) ! (re-search-backward ! (car (cdr (car methods))) nil t) ! ;; Suggested by Brian Edmonds . ! (funcall (nth 1 (car methods)) (car (car methods)))) ! (error nil)) ! ;; Don't enter the article into the same group twice. ! (not (assoc (car (car methods)) group-art))) ! (setq group-art ! (cons (cons (car (car methods)) ! (funcall func (car (car methods)))) ! group-art))) ! (or group-art ! (setq group-art ! (list (cons (car (car methods)) ! (funcall func (car (car methods)))))))) ! (setq methods (cdr methods))) (kill-buffer (current-buffer)) group-art))) --- 414,449 ---- (goto-char (point-min)) (while (re-search-forward "\\(\r?\n[ \t]+\\)+" nil t) (replace-match " " t t)) ! (if (and (symbolp nnmail-split-methods) ! (fboundp nnmail-split-methods)) ! (setq group-art ! (mapcar ! (lambda (group) (cons group (funcall func group))) ! (funcall nnmail-split-methods))) ! ;; Go throught the split methods to find a match. ! (while (and methods (or nnmail-crosspost (not group-art))) ! (goto-char (point-max)) ! (if (or (cdr methods) ! (not (equal "" (nth 1 (car methods))))) ! (if (and (condition-case () ! (if (stringp (nth 1 (car methods))) ! (re-search-backward ! (car (cdr (car methods))) nil t) ! ;; Suggested by Brian Edmonds . ! (funcall (nth 1 (car methods)) ! (car (car methods)))) ! (error nil)) ! ;; Don't enter the article into the same group twice. ! (not (assoc (car (car methods)) group-art))) ! (setq group-art ! (cons (cons (car (car methods)) ! (funcall func (car (car methods)))) ! group-art))) ! (or group-art ! (setq group-art ! (list (cons (car (car methods)) ! (funcall func (car (car methods)))))))) ! (setq methods (cdr methods)))) (kill-buffer (current-buffer)) group-art))) diff --exclude=*.elc --exclude=*~ --exclude=*-[0-9] --exclude=gnus --exclude=readme --context --recursive pub/dgnus/lisp/nnmh.el dgnus/lisp/nnmh.el *** pub/dgnus/lisp/nnmh.el Sun Apr 2 12:57:35 1995 --- dgnus/lisp/nnmh.el Tue Apr 11 00:35:20 1995 *************** *** 268,273 **** --- 268,274 ---- (nnmh-possibly-change-directory group) (save-excursion (set-buffer buffer) + (nnmh-possibly-create-directory group) (condition-case () (progn (write-region (point-min) (point-max) *************** *** 286,306 **** (setq nnmh-current-directory pathname) (error "No such newsgroup: %s" newsgroup))))) ! (defun nnmh-create-directories () ! (let ((methods nnmail-split-methods) ! dir dirs) ! (while methods ! (setq dir (nnmh-article-pathname (car (car methods)) nnmh-directory)) ! (while (not (file-directory-p dir)) ! (setq dirs (cons dir dirs)) ! (setq dir (file-name-directory (directory-file-name dir)))) ! (while dirs ! (if (make-directory (directory-file-name (car dirs))) ! (error "Could not create directory %s" (car dirs))) ! (message "Creating mail directory %s" (car dirs)) ! (setq dirs (cdr dirs))) ! (setq methods (cdr methods))))) ! (defun nnmh-save-mail () "Called narrowed to an article." (let ((group-art (nreverse (nnmail-article-group 'nnmh-active-number))) --- 287,305 ---- (setq nnmh-current-directory pathname) (error "No such newsgroup: %s" newsgroup))))) ! (defun nnmh-possibly-create-directory (group) ! (let (dir dirs) ! (setq dir (nnmail-article-pathname group nnmh-directory)) ! (while (not (file-directory-p dir)) ! (setq dirs (cons dir dirs)) ! (setq dir (file-name-directory (directory-file-name dir)))) ! (while dirs ! (if (make-directory (directory-file-name (car dirs))) ! (error "Could not create directory %s" (car dirs))) ! (and gnus-verbose-backends ! (message "Creating mail directory %s" (car dirs))) ! (setq dirs (cdr dirs))))) ! (defun nnmh-save-mail () "Called narrowed to an article." (let ((group-art (nreverse (nnmail-article-group 'nnmh-active-number))) *************** *** 315,320 **** --- 314,320 ---- (let ((ga group-art) first) (while ga + (nnmh-possibly-create-directory (car (car ga))) (let ((file (concat (nnmh-article-pathname (car (car ga)) nnmh-directory) (int-to-string (cdr (car ga)))))) *************** *** 354,360 **** (> (nth 7 (file-attributes nnmail-spool-file)) 0)) (progn (message "nnmh: Reading incoming mail...") - (nnmh-create-directories) (setq incoming (nnmail-move-inbox nnmail-spool-file (concat nnmh-directory "Incoming"))) --- 354,359 ---- diff --exclude=*.elc --exclude=*~ --exclude=*-[0-9] --exclude=gnus --exclude=readme --context --recursive pub/dgnus/lisp/nnml.el dgnus/lisp/nnml.el *** pub/dgnus/lisp/nnml.el Sun Apr 2 12:57:35 1995 --- dgnus/lisp/nnml.el Fri Apr 14 03:19:04 1995 *************** *** 183,189 **** (let (active) (setq nnml-group-alist (cons (list group (setq active (cons 0 0))) nnml-group-alist)) ! (nnml-create-directories) (nnml-possibly-change-directory group) (let ((articles (mapcar (lambda (file) --- 183,189 ---- (let (active) (setq nnml-group-alist (cons (list group (setq active (cons 0 0))) nnml-group-alist)) ! (nnml-possibly-create-directory group) (nnml-possibly-change-directory group) (let ((articles (mapcar (lambda (file) *************** *** 302,307 **** --- 302,308 ---- (nnml-possibly-change-directory group) (save-excursion (set-buffer buffer) + (nnml-possibly-create-directory group) (if (not (condition-case () (progn (write-region (point-min) (point-max) *************** *** 361,383 **** (and (or force (file-directory-p pathname)) (setq nnml-current-directory pathname))) t)) - - (defun nnml-create-directories () - (let ((methods (append nnmail-split-methods nnml-group-alist)) - dir dirs) - (while methods - (setq dir (nnmail-article-pathname (car (car methods)) nnml-directory)) - (while (not (file-directory-p dir)) - (setq dirs (cons dir dirs)) - (setq dir (file-name-directory (directory-file-name dir)))) - (while dirs - (if (make-directory (directory-file-name (car dirs))) - (error "Could not create directory %s" (car dirs))) - (and gnus-verbose-backends - (message "Creating mail directory %s" (car dirs))) - (setq dirs (cdr dirs))) - (setq methods (cdr methods))))) (defun nnml-save-mail () "Called narrowed to an article." (let ((group-art (nreverse (nnmail-article-group 'nnml-active-number))) --- 362,381 ---- (and (or force (file-directory-p pathname)) (setq nnml-current-directory pathname))) t)) + (defun nnml-possibly-create-directory (group) + (let (dir dirs) + (setq dir (nnmail-article-pathname group nnml-directory)) + (while (not (file-directory-p dir)) + (setq dirs (cons dir dirs)) + (setq dir (file-name-directory (directory-file-name dir)))) + (while dirs + (if (make-directory (directory-file-name (car dirs))) + (error "Could not create directory %s" (car dirs))) + (and gnus-verbose-backends + (message "Creating mail directory %s" (car dirs))) + (setq dirs (cdr dirs))))) + (defun nnml-save-mail () "Called narrowed to an article." (let ((group-art (nreverse (nnmail-article-group 'nnml-active-number))) *************** *** 392,397 **** --- 390,396 ---- (let ((ga group-art) first) (while ga + (nnml-possibly-create-directory (car (car ga))) (let ((file (concat (nnmail-article-pathname (car (car ga)) nnml-directory) (int-to-string (cdr (car ga)))))) *************** *** 433,439 **** (file-exists-p nnmail-spool-file) (> (nth 7 (file-attributes nnmail-spool-file)) 0)) (progn - (nnml-create-directories) (and gnus-verbose-backends (message "nnml: Reading incoming mail...")) (setq incoming --- 432,437 ---- *************** *** 516,522 **** (format "\t%s\t%s\t%s\t%s\t%s\t%d\t%s\t%s\t\n" (or subject "(none)") (or from "(nobody)") (or date "") ! (or id "") (or references "") (or chars 0) (or lines "0") (or xref "")))))) (defun nnml-open-nov (group) --- 514,524 ---- (format "\t%s\t%s\t%s\t%s\t%s\t%d\t%s\t%s\t\n" (or subject "(none)") (or from "(nobody)") (or date "") ! (or id (concat "nnml-dummy-id-" ! (mapconcat ! (lambda (time) (int-to-string time)) ! (current-time) "-"))) ! (or references "") (or chars 0) (or lines "0") (or xref "")))))) (defun nnml-open-nov (group) *************** *** 598,608 **** (setq chars (- (point-max) (point))) (point))) ! (setq nov-line (nnml-make-nov-line chars)) ! (save-excursion ! (set-buffer nov-buffer) ! (goto-char (point-max)) ! (insert (int-to-string (car files)) nov-line)) (widen) (setq files (cdr files))) (save-excursion --- 600,612 ---- (setq chars (- (point-max) (point))) (point))) ! (if (not (= 0 chars)) ; none of them empty files... ! (progn ! (setq nov-line (nnml-make-nov-line chars)) ! (save-excursion ! (set-buffer nov-buffer) ! (goto-char (point-max)) ! (insert (int-to-string (car files)) nov-line)))) (widen) (setq files (cdr files))) (save-excursion diff --exclude=*.elc --exclude=*~ --exclude=*-[0-9] --exclude=gnus --exclude=readme --context --recursive pub/dgnus/lisp/nntp.el dgnus/lisp/nntp.el *** pub/dgnus/lisp/nntp.el Sun Apr 2 12:57:35 1995 --- dgnus/lisp/nntp.el Fri Apr 14 02:11:58 1995 *************** *** 294,299 **** --- 294,302 ---- (if (nntp-possibly-change-server nil server) (nntp-send-command "^.*\r$" "GROUP" group))) + (defun nntp-list-active-group (group &optional server) + (nntp-send-command "^.*\r$" "LIST ACTIVE" group)) + (defun nntp-request-group-description (group &optional server) "Get description of GROUP." (if (nntp-possibly-change-server nil server) *************** *** 418,424 **** (widen)) (setq news-reply-yank-from from) (setq news-reply-yank-message-id message-id) ! (news-setup to subject message-of newsgroups article-buffer) ;; Fold long references line to follow RFC1036. (mail-position-on-field "References") (let ((begin (- (point) (length "References: "))) --- 421,436 ---- (widen)) (setq news-reply-yank-from from) (setq news-reply-yank-message-id message-id) ! (news-setup to subject message-of ! (if (stringp newsgroups) newsgroups "") ! article-buffer) ! (if (and newsgroups (listp newsgroups)) ! (progn ! (goto-char (point-min)) ! (while newsgroups ! (insert (car (car newsgroups)) ": " ! (cdr (car newsgroups)) "\n") ! (setq newsgroups (cdr newsgroups))))) ;; Fold long references line to follow RFC1036. (mail-position-on-field "References") (let ((begin (- (point) (length "References: "))) *************** *** 730,736 **** ;; This is a copy of `nntp-default-sentinel'. (if (or (not nntp-server-process) (not (memq (process-status nntp-server-process) '(open run)))) ! (error (format "nntp: Process connection closed")) (if nntp-buggy-select (progn ;; We cannot use `accept-process-output'. --- 742,748 ---- ;; This is a copy of `nntp-default-sentinel'. (if (or (not nntp-server-process) (not (memq (process-status nntp-server-process) '(open run)))) ! (error "nntp: Process connection closed; %s" (nntp-status-message)) (if nntp-buggy-select (progn ;; We cannot use `accept-process-output'. diff --exclude=*.elc --exclude=*~ --exclude=*-[0-9] --exclude=gnus --exclude=readme --context --recursive pub/dgnus/texi/gnus.texi dgnus/texi/gnus.texi *** pub/dgnus/texi/gnus.texi Sun Apr 2 12:57:38 1995 --- dgnus/texi/gnus.texi Fri Apr 14 03:33:22 1995 *************** *** 316,327 **** --- 316,329 ---- @cindex terminology @itemize @bullet @item news + @cindex news This is what you are supposed to use this thing for - reading news. News is generally fetched from a nearby 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 *************** *** 342,357 **** --- 344,363 ---- You can also have any number of foreign groups at the same time. These are groups that use different backends for getting news. @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 for all the unread articles in the group. Most servers support the News OverView format, which is much smaller and much faster to read than the normal 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 *************** *** 873,879 **** (@code{gnus-group-prev-unread-group-same-level}). @end table ! Two commands for jumping to groups: @table @kbd @item j --- 879,885 ---- (@code{gnus-group-prev-unread-group-same-level}). @end table ! Three commands for jumping to groups: @table @kbd @item j *************** *** 887,892 **** --- 893,903 ---- @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 @node Selecting a Group *************** *** 1445,1450 **** --- 1456,1465 ---- variable is @code{nil}, the mail backends will never attempt to fetch mail by themselves. + @vindex nnmail-prepare-incoming-hook + @code{nnmail-prepare-incoming-hook} is run in a buffer that holds all + the new incoming mail, and can be used for, well, anything, really. + @vindex nnmail-tmp-directory @code{nnmail-tmp-directory} says where to move the incoming mail to while processing it. This is usually done in the same directory that *************** *** 1500,1505 **** --- 1515,1526 ---- expression should @emph{always} be @samp{""} so that it matches any mails that haven't been matched by any of the other regexps. + 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 groups names that it + thinks should carry this mail message. + @vindex nnmail-crosspost The mail backends all support cross-posting. If several regexps match, the mail will be "cross-posted" to all those groups. *************** *** 1530,1547 **** exist by hand. Let's take the @code{nnfolder} backend as an example. (This backend ! features one file as the basis of each group.) The folders are located in @code{nnfolder-directory}, say, @file{~/Mail/}. There are three folders, @file{foo}, @file{bar} and @file{mail.baz}. Go to the group buffer and type @kbd{M m}. When prompted, answer ! @samp{foo} for the name, @samp{nnfolder} for the method and @samp{""} ! for the address. Repeat twice for the two other groups, @samp{bar} and ! @code{mail.baz}. Be sure to include all your mail groups. ! That's it. You are now set to read your mail. @node Expiring Old Mail Articles @subsubsection Expiring Old Mail Articles --- 1551,1569 ---- exist by hand. Let's take the @code{nnfolder} backend as an example. (This backend ! uses one file as the basis of each group.) The folders are located in @code{nnfolder-directory}, say, @file{~/Mail/}. There are three folders, @file{foo}, @file{bar} and @file{mail.baz}. Go to the group buffer and type @kbd{M m}. When prompted, answer ! @samp{foo} for the name and @samp{nnfolder} for the method. Repeat ! twice for the two other groups, @samp{bar} and @code{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. @node Expiring Old Mail Articles @subsubsection Expiring Old Mail Articles *************** *** 2110,2115 **** --- 2132,2139 ---- Message-ID @item r References + @item t + Number of articles in the current subthread. @item x Xref @item u *************** *** 2154,2166 **** Gnus version @item U Number of unread articles in this group ! @item u Number of unselected articles in this group @item Z A string with the number of unread and unselected articles represented either as @samp{<%U(+%u) more>} if there are both unselected articles, and just as @samp{<%U more>} if there are just unread articles and no unselected ones. @end table --- 2178,2199 ---- Gnus version @item U Number of unread articles in this group ! @item e Number of unselected articles in this group @item Z A string with the number of unread and unselected articles represented either as @samp{<%U(+%u) more>} if there are both 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 + Used-defined spec. + @item s + Name of the current score file. @end table *************** *** 2322,2327 **** --- 2355,2376 ---- @vindex gnus-visual-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) that is used to + highlight the current article in the summary buffer. + @item gnus-visual-summary-highlight + @vindex gnus-visual-summary-highlight + Summary lines are highlighted according to this variable, which is a + list where the elements are on the format @code{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-nil value, + @var{FACE} will be applied to the line. @end table @node Paging the Article *************** *** 2439,2446 **** nil)))) @end lisp ! This functions will be called from the buffer of the article that is ! being replied to. @item gnus-mail-send-method @vindex gnus-mail-send-method --- 2488,2506 ---- nil)))) @end lisp ! This function will be called narrow to the headers 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 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. @samp{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. @item gnus-mail-send-method @vindex gnus-mail-send-method *************** *** 2647,2655 **** When you yank a message, you do not want to include any headers from this message, so @code{(setq mail-yank-ignored-headers ":")}. @item mail-default-headers @vindex mail-default-headers ! This is a string that will be inserted into the heade of all outgoing mail messages and news articles. Convenient to use to insert standard headers. --- 2707,2733 ---- When you yank a message, you do not want to include any headers from this message, so @code{(setq mail-yank-ignored-headers ":")}. + @item user-mail-address + @vindex user-mail-address + If all of @code{gnus-user-login-name}, @code{gnus-use-generic-from} and + @code{gnus-local-domain} are nil, Gnus will use @code{user-mail-address} + as the address part of the From header. + + @item gnus-user-from-line + @vindex gnus-user-from-line + Your full, complete e-mail address. This variable overrides the other + Gnus variables if it is non-nil. + + Here are two example values of this variable: + @samp{"Lars Magne Ingebrigtsen "} + and @samp{"larsi@@ifi.uio.no (Lars Magne Ingebrigtsen)"}. + The first version is recommended, but the name has to be quoted if it + contains non-alphanumerical characters - @samp{"\"Lars M. Ingebrigtsen\" + "}. + @item mail-default-headers @vindex mail-default-headers ! This is a string that will be inserted into the header of all outgoing mail messages and news articles. Convenient to use to insert standard headers. *************** *** 3226,3231 **** --- 3304,3314 ---- @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}). @end table @vindex gnus-exit-group-hook *************** *** 3813,3819 **** support fetching by Message-ID very well (like @code{nnspool}), you can set @code{gnus-refer-article-method} to an NNTP method. It would, perhaps, be best if the NNTP server you consult is the same as the one ! that keeps the spool you are erading from updated, but that's not really necessary. @node Score Files --- 3896,3902 ---- support fetching by Message-ID very well (like @code{nnspool}), you can set @code{gnus-refer-article-method} to an NNTP method. It would, perhaps, be best if the NNTP server you consult is the same as the one ! that keeps the spool you are reading from updated, but that's not really necessary. @node Score Files *************** *** 3850,3856 **** --- 3933,3941 ---- * Score File Format:: What a score file may contain. * Score File Editing:: You can edit score files by hand as well. * 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. @end menu @node Summary Score Commands *************** *** 3941,3946 **** --- 4026,4042 ---- @findex gnus-summary-raise-by-author Increase the current author permanently (@code{gnus-summary-raise-by-author}). + @item I b t + @kindex I b t (Summary) + @findex gnus-summary-temporarily-raise-by-body + Increase based on a match on the body of an article temporarily + (@code{gnus-summary-temporarily-raise-by-body}). This is a very slow + operation. + @item I b p + @kindex I b p (Summary) + @findex gnus-summary-raise-by-body + Increase based on a match on the body of an article + (@code{gnus-summary-raise-by-body}). This is a very slow operation @item I i t @kindex I i t (Summary) @findex gnus-summary-temporarily-raise-by-id *************** *** 4006,4018 **** @findex gnus-summary-lower-by-author Lower the current author permanently (@code{gnus-summary-lower-by-author}). @item L i t @kindex L i t (Summary) @findex gnus-summary-temporarily-lower-by-id Lower the current message-id temporarily (@code{gnus-summary-temporarily-lower-by-id}). ! @item L a p ! @kindex L a p (Summary) @findex gnus-summary-lower-by-id Lower the current message-id permanently (@code{gnus-summary-lower-by-id}). --- 4102,4125 ---- @findex gnus-summary-lower-by-author Lower the current author permanently (@code{gnus-summary-lower-by-author}). + @item L b t + @kindex L b t (Summary) + @findex gnus-summary-temporarily-lower-by-body + Lower based on a match on the article body + (@code{gnus-summary-temporarily-lower-by-body}). This is a very slow + operation. + @item L b p + @kindex L b p (Summary) + @findex gnus-summary-lower-by-body + Lower bsed on a match on the article body + (@code{gnus-summary-lower-by-body}). This is a very slow operation. @item L i t @kindex L i t (Summary) @findex gnus-summary-temporarily-lower-by-id Lower the current message-id temporarily (@code{gnus-summary-temporarily-lower-by-id}). ! @item L i p ! @kindex L i p (Summary) @findex gnus-summary-lower-by-id Lower the current message-id permanently (@code{gnus-summary-lower-by-id}). *************** *** 4128,4142 **** (("from" ("Lars Ingebrigtsen" -10000) ("Per Abrahamsen") ! ("larsi\\|lmi" -50000 nil r)) ("subject" ("Ding is Badd" nil 728373)) ("xref" ("alt.politics" -1000 728372 s)) (mark 0) (expunge -1000) (mark-and-expunge -10) ! (read-only t) (files "/hom/larsi/News/gnu.SCORE") (eval (ding))) @end lisp --- 4235,4252 ---- (("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) (files "/hom/larsi/News/gnu.SCORE") (eval (ding))) @end lisp *************** *** 4151,4162 **** @table @code @item STRING ! If the key is a string, it is a header name to perform the scoring on. Following this key is a random number of element score entries, where ! each score entry have one to four elements. @enumerate @item ! The first element is always a string - the @dfn{match element}. @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 --- 4261,4284 ---- @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: ! @samp{From}, @samp{Subject}, @samp{References}, @samp{Message-ID}, ! @samp{Xref}, @samp{Lines}, @samp{Chars} and @samp{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: @samp{Body} ! will perform the match on the body of the article, @samp{Head} will ! perform the match on the head of the article, and @samp{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}. ! Following this key is a random number of element score entries, where ! each score entry have 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 *************** *** 4170,4178 **** represented by the number of days since December 31, 1 CE. @item If the fourth element is present, it should be a symbol - the @dfn{type ! element}. Currently supported are the @code{r} (regexp) and @code{s} ! (substring) types. If this element is not present, Gnus will assume ! that substring matching should be used. @end enumerate @item mark --- 4292,4322 ---- represented by the number of days since December 31, 1 CE. @item If the fourth element is present, it should be a symbol - the @dfn{type ! element}. This element specifies what function should be performed 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. ! @itemize @bullet ! @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. If this element is not ! present, Gnus will assume that substring matching should be used. ! @code{R} and @code{S} differ from the other two 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} and @code{string} 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{<=}. ! @item Date ! For the Date header we have three 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. ! @item Head, Body, All ! These three match keys use the same match types as the From (etc) header ! uses. ! @end itemize @end enumerate @item mark *************** *** 4195,4200 **** --- 4339,4347 ---- @item read-only Read-only score files will not be updated or saved. Global score files should feature this atom (@pxref{Global 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. @end table @node Score File Editing *************** *** 4238,4245 **** --- 4385,4427 ---- @lisp ("xref" (" +[^ ]+:[0-9]+ +[^ ]+:[0-9]+ +[^ ]+:[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}. @end itemize + @node Reverse Scoring + @subsection 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 @subsection Global Score Files @cindex global score files *************** *** 4311,4316 **** --- 4493,4539 ---- Wave, xrn and 1stReader are bound to implement scoring. Should we start holding our breath yet? + @node Kill Files + @subsection Kill Files + @cindex kill files + + (ding) Gnus still supports those pesky old kill files. In fact, the + kill file netries can now be expiring, which is something I wrote before + Per thought of doing score files, so I've left the code 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 elisp 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 + really 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 them from + the summary buffer. Very useful, you'll agree. + + Two functions for entering kill file editing: + + @table @kbd + @item V k + @kindex V k (Summary) + @findex gnus-summary-edit-local-kill + Edit this group's kill file (@code{gnus-summary-edit-local-kill}). + @item V K + @kindex V K (Summary) + @findex gnus-summary-edit-global-kill + Edit the general kill file (@code{gnus-summary-edit-local-kill}). + @end table + @node Mail Group Commands @section Mail Group Commands @cindex mail group commands *************** *** 4451,4472 **** @kindex V S (Summary) @findex gnus-summary-reselect-current-group Exit this group, and then enter it again ! (@code{gnus-summary-reselect-current-group}). @item V g @item M-g @kindex V g (Summary) @kindex M-g (Summary) @findex gnus-summary-rescan-group Exit group, check for new articles in the group, and select the group ! (@code{gnus-summary-rescan-group}). ! @item V k ! @kindex V k (Summary) ! @findex gnus-summary-edit-local-kill ! Edit this group's kill file (@code{gnus-summary-edit-local-kill}). ! @item V K ! @kindex V K (Summary) ! @findex gnus-summary-edit-global-kill ! Edit the general kill file (@code{gnus-summary-edit-local-kill}). @end table @node The Article Buffer --- 4674,4689 ---- @kindex V S (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 V g @item M-g @kindex V g (Summary) @kindex M-g (Summary) @findex gnus-summary-rescan-group Exit 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. @end table @node The Article Buffer *************** *** 4904,4909 **** --- 5121,5135 ---- @code{gnus-check-bogus-newsgroups} to @code{nil} if you set this variable to @code{nil}. @end table + + @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 called just @file{KILL}. + + In short: avoid killing. Scoring is more fun. @node Slow Machine @section Slow Machine