diff --exclude=*.elc --exclude=*~ --exclude=*-[0-9] --exclude=gnus --context --recursive pub/dgnus/lisp/ChangeLog dgnus/lisp/ChangeLog *** pub/dgnus/lisp/ChangeLog Thu Mar 23 13:31:02 1995 --- dgnus/lisp/ChangeLog Sat Mar 25 08:51:08 1995 *************** *** 1,3 **** --- 1,86 ---- + Sat Mar 25 05:05:26 1995 Lars Ingebrigtsen + + * gnus.el (gnus-compress-newsrc-assoc, + gnus-uncompress-newsrc-assoc): Compress lists of marked articles + before writing them to the .newsrc.eld file. + (gnus-select-newsgroup): auto-expire match on full name. + (gnus-select-newsgroup): New element in select methods: + auto-expire. + (gnus-save-scores): New variable. + (gnus-summary-exit): Use it. + (gnus-newsrc-to-gnus-format): If .newsrc was newer than + .newsrc.eld, all foreign groups would be hosed. + + * gnus.el: All range functions have changed to allow an extended + syntax. + + Fri Mar 24 07:17:20 1995 Lars Ingebrigtsen + + * gnus.el (gnus-summary-move-article): Copy marks when moving + articles. + (gnus-set-sorted-intersection): Would compute incorrect + intersection. + + * nndoc.el (nndoc-retrieve-headers): Insert Lines header. + * nnmh.el (nnmh-retrieve-headers): Ditto. + (nndigest-retrieve-headers): Ditto. + + * nndigest.el (nndigest-narrow-to-article): Don't include the + closing digest separator in an article. + + * gnus.el (gnus-group-change-level): When subscribing to + non-existant groups, would claim that there was one unread article + in the group. + (gnus-summary-delete-article): Remove process mark after deleting + articles. + (gnus-score-load-file): 'files was not properly handled, and edits + would end up with the wrong alist as the current one. + (gnus-score-edit-alist): Name change from -file. + (gnus-score-edit-file): New function and keystroke. + + * nntp.el (nntp-request-newgroups): Would bug out due to a `let' + instead of a `let*'. + + * gnus.el (gnus-score-save): Score files would not be saved. + (gnus-summary-update-line): Would mark as read-below even when + attempting to remove the mark. + + Thu Mar 23 08:29:56 1995 Lars Ingebrigtsen + + * gnus.el (gnus-summary-save-article-file, + gnus-summary-save-article-folder, + gnus-summary-save-article-rmail): New commands and keystrokes. + (gnus-summary-sort): All sort commands now also work when + threading is used. + (gnus-summary-mode-map): Several key changes. + + * nnml.el (nnml-request-expire-articles): Update active file as + well. + * nnbabyl.el (nnbabyl-request-expire-articles): Ditto. + * nnfolder.el (nnfolder-request-expire-articles): Ditto. + * nnmbox.el (nnmbox-request-expire-articles): Ditto. + + * nnmail.el (nnmail-tmp-directory): New variable. + (nnmail-move-inbox): Use it. + + * nnvirtual.el (nnvirtual-update-marked): Would insert non-visible + component groups into the group buffer. + + * nnmh.el (nnmh-get-new-mail): Don't create directories unless + mail reading is wanted. + + * nnfolder.el (nnfolder-read-folder): Insert number of lines in + the article. + + * gnus.el (gnus-group-unsubscribe-group): Would refuse to + subscribe to groups not in active file. + + Thu Mar 23 13:23:45 1995 Lars Magne Ingebrigtsen + + * gnus.el: Remove two calls to `debug'. + + * gnus.el: 0.40 is released. + Thu Mar 23 06:29:03 1995 Lars Magne Ingebrigtsen * gnus.el: 0.39 is released. diff --exclude=*.elc --exclude=*~ --exclude=*-[0-9] --exclude=gnus --context --recursive pub/dgnus/lisp/gnus-visual.el dgnus/lisp/gnus-visual.el *** pub/dgnus/lisp/gnus-visual.el Thu Mar 23 13:31:00 1995 --- dgnus/lisp/gnus-visual.el Fri Mar 24 08:51:57 1995 *************** *** 276,281 **** --- 276,283 ---- ["Describe group" gnus-summary-describe-group t] ["Exit group" gnus-summary-exit t] ["Exit group without updating" gnus-summary-quit t] + ["Edit local kill file" gnus-summary-edit-local-kill t] + ["Edit global kill file" gnus-summary-edit-global-kill t] )) (easy-menu-define *************** *** 302,312 **** gnus-summary-kill-menu gnus-summary-mode-map "" ! '("Kill" ! ["Edit local kill file" gnus-summary-edit-local-kill t] ! ["Edit global kill file" gnus-summary-edit-global-kill t] ! ["Expunge with score below..." gnus-score-set-expunge-below t] ! ["Set mark with score below..." gnus-score-set-mark-below t] ["Raise score with current subject" gnus-summary-temporarily-raise-by-subject t] ["Raise score with current author" --- 304,316 ---- gnus-summary-kill-menu gnus-summary-mode-map "" ! '("Score" ! ("Score file" ! ["Switch current score file" gnus-score-change-score-file t] ! ["Set mark below" gnus-score-set-mark-below t] ! ["Set expunge below" gnus-score-set-expunge-below t] ! ["Edit current score file" gnus-score-edit-alist t] ! ["Edit score file" gnus-score-edit-file t]) ["Raise score with current subject" gnus-summary-temporarily-raise-by-subject t] ["Raise score with current author" diff --exclude=*.elc --exclude=*~ --exclude=*-[0-9] --exclude=gnus --context --recursive pub/dgnus/lisp/gnus.el dgnus/lisp/gnus.el *** pub/dgnus/lisp/gnus.el Thu Mar 23 13:31:01 1995 --- dgnus/lisp/gnus.el Sat Mar 25 15:30:44 1995 *************** *** 268,276 **** "A function generating a file name to save articles in article format. The function is called with NEWSGROUP, HEADERS, and optional LAST-FILE.") - (defvar gnus-kill-file-name "KILL" - "Suffix of the kill files.") - (defvar gnus-score-file-suffix "SCORE" "Suffix of the score files.") --- 268,273 ---- *************** *** 434,439 **** --- 431,439 ---- (defvar gnus-score-interactive-default-score 1000 "Scoring commands will raise/lower the score with this number as the default.") + (defvar gnus-save-score nil + "If non-nil, save group scoring info.") + (defvar gnus-global-score-files nil "List of global score files and directories. Set this variable if you want to use people's score files. One entry *************** *** 913,921 **** (defvar gnus-article-mode-hook nil "A hook for Gnus article mode.") - (defvar gnus-kill-file-mode-hook nil - "A hook for Gnus kill file mode.") - (defvar gnus-open-server-hook nil "A hook called just before opening connection to the news server.") --- 913,918 ---- *************** *** 1203,1209 **** (defconst gnus-maintainer "Lars Magne Ingebrigtsen " "The mail address of the Gnus maintainer.") ! (defconst gnus-version "(ding) Gnus v0.40" "Version number for this version of Gnus.") (defvar gnus-info-nodes --- 1200,1206 ---- (defconst gnus-maintainer "Lars Magne Ingebrigtsen " "The mail address of the Gnus maintainer.") ! (defconst gnus-version "(ding) Gnus v0.41" "Version number for this version of Gnus.") (defvar gnus-info-nodes *************** *** 1348,1354 **** (defvar gnus-current-kill-article nil) ;; Save window configuration. - (defvar gnus-winconf-kill-file nil) (defvar gnus-winconf-edit-group nil) (defvar gnus-winconf-edit-score nil) --- 1345,1350 ---- *************** *** 1383,1389 **** gnus-newsgroup-dependencies gnus-newsgroup-selected-overlay gnus-newsgroup-scored gnus-newsgroup-kill-headers gnus-score-alist gnus-current-score-file gnus-summary-expunge-below ! (gnus-summary-mark-below . gnus-summary-default-score) gnus-newsgroup-history gnus-newsgroup-ancient) "Variables that are buffer-local to the summary buffers.") --- 1379,1385 ---- gnus-newsgroup-dependencies gnus-newsgroup-selected-overlay gnus-newsgroup-scored gnus-newsgroup-kill-headers gnus-score-alist gnus-current-score-file gnus-summary-expunge-below ! gnus-summary-mark-below gnus-newsgroup-history gnus-newsgroup-ancient) "Variables that are buffer-local to the summary buffers.") *************** *** 1439,1444 **** --- 1435,1446 ---- (autoload 'gnus-uu-decode-save-view "gnus-uu") (autoload 'gnus-uu-decode-binhex-view "gnus-uu") + (autoload 'gnus-kill "gnus-kill") + (autoload 'gnus-apply-kill-file-internal "gnus-kill") + (autoload 'gnus-kill-file-edit-file "gnus-kill") + (autoload 'gnus-kill-file-raise-followups-to-author "gnus-kill") + (autoload 'gnus-execute "gnus-kill") + (autoload 'pp "pp") (autoload 'pp-to-string "pp") (autoload 'mail-extract-address-components "mail-extr") *************** *** 2344,2351 **** (setcdr prev (cdr list1)) (setq list1 (cdr list1))) (t - (setcdr prev (cdr list1)) (setq list2 (cdr list2))))) (cdr top))) (defun gnus-compress-sequence (numbers &optional always-list) --- 2346,2353 ---- (setcdr prev (cdr list1)) (setq list1 (cdr list1))) (t (setq list2 (cdr list2))))) + (setcdr prev nil) (cdr top))) (defun gnus-compress-sequence (numbers &optional always-list) *************** *** 2362,2401 **** ((= (1+ last) (car numbers)) ;Still in sequence (setq last (car numbers))) (t ;End of one sequence ! (setq result (cons (cons first last) result)) (setq first (car numbers)) (setq last (car numbers)))) (setq numbers (cdr numbers))) (if (and (not always-list) (null result)) ! (cons first last) ! (nreverse (cons (cons first last) result)))))) ! (defun gnus-uncompress-sequence (ranges) "Expand a list of ranges into a list of numbers. RANGES is either a single range on the form `(num . num)' or a list of these ranges." (let (first last result) ! (if (null ranges) ! nil ! (if (atom (car ranges)) ! (progn ! (setq first (car ranges)) ! (setq last (cdr ranges)) ! (while (<= first last) ! (setq result (cons first result)) ! (setq first (1+ first)))) ! (while ranges (setq first (car (car ranges))) (setq last (cdr (car ranges))) (while (<= first last) (setq result (cons first result)) ! (setq first (1+ first))) ! (setq ranges (cdr ranges)))) ! (nreverse result)))) (defun gnus-add-to-range (ranges list) "Return a list of ranges that has all articles from both RANGES and LIST. Note: LIST has to be sorted over `<'." (let* ((ranges (if (and ranges (atom (car ranges))) (list ranges) ranges)) (inrange ranges) did-one --- 2364,2475 ---- ((= (1+ last) (car numbers)) ;Still in sequence (setq last (car numbers))) (t ;End of one sequence ! (setq result ! (cons (if (= first last) first (cons first last)) result)) (setq first (car numbers)) (setq last (car numbers)))) (setq numbers (cdr numbers))) (if (and (not always-list) (null result)) ! (if (= first last) first (cons first last)) ! (nreverse (cons (if (= first last) first (cons first last)) ! result)))))) ! (defalias 'gnus-uncompress-sequence 'gnus-uncompress-range) ! (defun gnus-uncompress-range (ranges) "Expand a list of ranges into a list of numbers. RANGES is either a single range on the form `(num . num)' or a list of these ranges." (let (first last result) ! (cond ! ((null ranges) ! nil) ! ((not (listp (cdr ranges))) ! (setq first (car ranges)) ! (setq last (cdr ranges)) ! (while (<= first last) ! (setq result (cons first result)) ! (setq first (1+ first))) ! (nreverse result)) ! (t ! (while ranges ! (if (atom (car ranges)) ! (if (numberp (car ranges)) ! (setq result (cons (car ranges) result))) (setq first (car (car ranges))) (setq last (cdr (car ranges))) (while (<= first last) (setq result (cons first result)) ! (setq first (1+ first)))) ! (setq ranges (cdr ranges))) ! (nreverse result))))) (defun gnus-add-to-range (ranges list) "Return a list of ranges that has all articles from both RANGES and LIST. Note: LIST has to be sorted over `<'." + (if (not ranges) + (gnus-compress-sequence list t) + (setq list (copy-sequence list)) + (or (listp (cdr ranges)) + (setq ranges (list ranges))) + (let ((out ranges) + ilist lowest highest temp) + (while (and ranges list) + (setq ilist list) + (setq lowest (or (and (atom (car ranges)) (car ranges)) + (car (car ranges)))) + (while (and list (cdr list) (< (car (cdr list)) lowest)) + (setq list (cdr list))) + (if (< (car ilist) lowest) + (progn + (setq temp list) + (setq list (cdr list)) + (setcdr temp nil) + (setq out (nconc (gnus-compress-sequence ilist t) out)))) + (setq highest (or (and (atom (car ranges)) (car ranges)) + (cdr (car ranges)))) + (while (and list (<= (car list) highest)) + (setq list (cdr list))) + (setq ranges (cdr ranges))) + (if list + (setq out (nconc (gnus-compress-sequence list t) out))) + (setq out (sort out (lambda (r1 r2) + (< (or (and (atom r1) r1) (car r1)) + (or (and (atom r2) r2) (car r2)))))) + (setq ranges out) + (while ranges + (if (atom (car ranges)) + (if (cdr ranges) + (if (atom (car (cdr ranges))) + (if (= (1+ (car ranges)) (car (cdr ranges))) + (progn + (setcar ranges (cons (car ranges) + (car (cdr ranges)))) + (setcdr ranges (cdr (cdr ranges))))) + (if (= (1+ (car ranges)) (car (car (cdr ranges)))) + (progn + (setcar (car (cdr ranges)) (car ranges)) + (setcar ranges (car (cdr ranges))) + (setcdr ranges (cdr (cdr ranges))))))) + (if (cdr ranges) + (if (atom (car (cdr ranges))) + (if (= (1+ (cdr (car ranges))) (car (cdr ranges))) + (progn + (setcdr (car ranges) (car (cdr ranges))) + (setcdr ranges (cdr (cdr ranges))))) + (if (= (1+ (cdr (car ranges))) (car (car (cdr ranges)))) + (progn + (setcdr (car ranges) (cdr (car (cdr ranges)))) + (setcdr ranges (cdr (cdr ranges)))))))) + (setq ranges (cdr ranges))) + out))) + + (defun gnus-add-to-range-new (ranges list) + (gnus-compress-sequence + (sort (nconc (gnus-uncompress-range ranges) list) '<))) + + (defun gnus-add-to-range-old (ranges list) + "Return a list of ranges that has all articles from both RANGES and LIST. + Note: LIST has to be sorted over `<'." (let* ((ranges (if (and ranges (atom (car ranges))) (list ranges) ranges)) (inrange ranges) did-one *************** *** 2446,2461 **** ;; !!! This function shouldn't look like this, but I've got a headache. (gnus-compress-sequence (gnus-sorted-complement ! (gnus-uncompress-sequence ranges) list))) (defun gnus-member-of-range (number ranges) ! (if (not (listp (car ranges))) (and (>= number (car ranges)) (<= number (cdr ranges))) (let ((not-stop t)) ! (while (and ranges (>= number (car (car ranges))) not-stop) ! (if (and (>= number (car (car ranges))) ! (<= number (cdr (car ranges)))) (setq not-stop nil)) (setq ranges (cdr ranges))) (not not-stop)))) --- 2520,2541 ---- ;; !!! This function shouldn't look like this, but I've got a headache. (gnus-compress-sequence (gnus-sorted-complement ! (gnus-uncompress-range ranges) list))) (defun gnus-member-of-range (number ranges) ! (if (not (listp (cdr ranges))) (and (>= number (car ranges)) (<= number (cdr ranges))) (let ((not-stop t)) ! (while (and ranges ! (if (numberp (car ranges)) ! (>= number (car ranges)) ! (>= number (car (car ranges)))) ! not-stop) ! (if (if (numberp (car ranges)) ! (= number (car ranges)) ! (and (>= number (car (car ranges))) ! (<= number (cdr (car ranges))))) (setq not-stop nil)) (setq ranges (cdr ranges))) (not not-stop)))) *************** *** 2549,2555 **** --- 2629,2646 ---- (defun gnus-group-mode () "Major mode for reading news. + All normal editing commands are switched off. + \\ + The group buffer lists (some of) the groups available. For instance, + `\\[gnus-group-list-groups]' will list all subscribed groups with unread articles, while `\\[gnus-group-list-zombies]' + lists all zombie groups. + + Groups that are displayed can be entered with `\\[gnus-group-read-group]'. To subscribe + to a group not displayed, type `\\[gnus-group-unsubscribe-group]'. + + For more in-depth information on this mode, read the manual (`\\[gnus-info-find-node]'). + The following commands are available: \\{gnus-group-mode-map}" *************** *** 2794,2799 **** --- 2885,2900 ---- (defun gnus-group-set-info (info) (let ((entry (gnus-gethash (car info) gnus-newsrc-hashtb))) + (let (marked) + (if (not (setq marked (nth 3 info))) + () + (while marked + (or (eq 'score (car (car marked))) + (not (or (atom (cdr (cdr (car marked)))) + (not (atom (car (cdr (car marked))))))) + (setcdr (car marked) + (gnus-uncompress-range (cdr (car marked))))) + (setq marked (cdr marked))))) (if entry () (save-excursion *************** *** 2853,2859 **** (setq active (gnus-gethash group gnus-active-hashtb)) (gnus-group-insert-group-line nil group (if (member group gnus-zombie-list) 8 9) ! nil (- (1+ (cdr active)) (car active)) nil)))) (defun gnus-group-insert-group-line (gformat group level marked number method) (let* ((gformat (or gformat gnus-group-line-format-spec)) --- 2954,2960 ---- (setq active (gnus-gethash group gnus-active-hashtb)) (gnus-group-insert-group-line nil group (if (member group gnus-zombie-list) 8 9) ! nil (if active (- (1+ (cdr active)) (car active)) 0) nil)))) (defun gnus-group-insert-group-line (gformat group level marked number method) (let* ((gformat (or gformat gnus-group-line-format-spec)) *************** *** 3169,3178 **** (concat "(gnus-group-set-info '" (prin1-to-string (cdr info)) ")")) (gnus-group-insert-group-line-info nname))) ! (defun gnus-group-edit-group () ! (interactive) ! (let ((group (gnus-group-group-name)) ! info) (if group (setq info (nth 2 (gnus-gethash group gnus-newsrc-hashtb))) (error "No group on current line")) (setq gnus-winconf-edit-group (current-window-configuration)) --- 3270,3278 ---- (concat "(gnus-group-set-info '" (prin1-to-string (cdr info)) ")")) (gnus-group-insert-group-line-info nname))) ! (defun gnus-group-edit-group (group) ! (interactive (list (gnus-group-group-name))) ! (let (info) (if group (setq info (nth 2 (gnus-gethash group gnus-newsrc-hashtb))) (error "No group on current line")) (setq gnus-winconf-edit-group (current-window-configuration)) *************** *** 3184,3190 **** (local-set-key "\C-c\C-c" 'gnus-group-edit-group-done) (erase-buffer) (insert ";; Type `C-c C-c' after you have edited the newsgroup entry.\n\n") ! (insert (pp-to-string (list 'gnus-group-set-info (list 'quote info)))))) (defun gnus-group-edit-group-done () (interactive) --- 3284,3300 ---- (local-set-key "\C-c\C-c" 'gnus-group-edit-group-done) (erase-buffer) (insert ";; Type `C-c C-c' after you have edited the newsgroup entry.\n\n") ! (let ((cinfo (gnus-copy-sequence info)) ! marked) ! (if (not (setq marked (nth 3 cinfo))) ! () ! (while marked ! (or (eq 'score (car (car marked))) ! (setcdr (car marked) ! (gnus-compress-sequence (sort (cdr (car marked)) '<) t))) ! (setq marked (cdr marked)))) ! (insert (pp-to-string (list 'gnus-group-set-info ! (list 'quote cinfo))))))) (defun gnus-group-edit-group-done () (interactive) *************** *** 3404,3417 **** newsrc (if level level (if (< (nth 1 (nth 2 newsrc)) 6) 6 4))) (gnus-group-update-group group)) ((and (stringp group) ! (gnus-gethash group gnus-active-hashtb)) ;; Add new newsgroup. (gnus-group-change-level group (if level level 3) ! (or (nth 2 (nth 2 (gnus-gethash group gnus-newsrc-hashtb))) ! (and (member group gnus-zombie-list) 8) ! 9) (or (and (gnus-group-group-name) (gnus-gethash (gnus-group-group-name) gnus-newsrc-hashtb)) (gnus-gethash (car (car gnus-newsrc-assoc)) --- 3514,3526 ---- newsrc (if level level (if (< (nth 1 (nth 2 newsrc)) 6) 6 4))) (gnus-group-update-group group)) ((and (stringp group) ! (or (not gnus-have-read-active-file) ! (gnus-gethash group gnus-active-hashtb))) ;; Add new newsgroup. (gnus-group-change-level group (if level level 3) ! (or (and (member group gnus-zombie-list) 8) 9) (or (and (gnus-group-group-name) (gnus-gethash (gnus-group-group-name) gnus-newsrc-hashtb)) (gnus-gethash (car (car gnus-newsrc-assoc)) *************** *** 4038,4044 **** (defvar gnus-summary-score-map nil) (defvar gnus-summary-sort-map nil) (defvar gnus-summary-mgroup-map nil) ! (defvar gnus-summary-vkill-map nil) (defvar gnus-summary-increase-map nil) (defvar gnus-summary-inc-subject-map nil) (defvar gnus-summary-inc-author-map nil) --- 4147,4153 ---- (defvar gnus-summary-score-map nil) (defvar gnus-summary-sort-map nil) (defvar gnus-summary-mgroup-map nil) ! (defvar gnus-summary-vsave-map nil) (defvar gnus-summary-increase-map nil) (defvar gnus-summary-inc-subject-map nil) (defvar gnus-summary-inc-author-map nil) *************** *** 4133,4139 **** (define-key gnus-summary-mode-map "V" 'gnus-version) (define-key gnus-summary-mode-map "\C-c\C-d" 'gnus-summary-describe-group) (define-key gnus-summary-mode-map "q" 'gnus-summary-exit) ! (define-key gnus-summary-mode-map "Q" 'gnus-summary-quit) (define-key gnus-summary-mode-map "\C-c\C-i" 'gnus-info-find-node) (define-key gnus-summary-mode-map [mouse-2] 'gnus-mouse-pick-article) (define-key gnus-summary-mode-map "m" 'gnus-summary-mail-other-window) --- 4242,4248 ---- (define-key gnus-summary-mode-map "V" 'gnus-version) (define-key gnus-summary-mode-map "\C-c\C-d" 'gnus-summary-describe-group) (define-key gnus-summary-mode-map "q" 'gnus-summary-exit) ! (define-key gnus-summary-mode-map "Q" 'gnus-summary-exit-no-update) (define-key gnus-summary-mode-map "\C-c\C-i" 'gnus-info-find-node) (define-key gnus-summary-mode-map [mouse-2] 'gnus-mouse-pick-article) (define-key gnus-summary-mode-map "m" 'gnus-summary-mail-other-window) *************** *** 4146,4151 **** --- 4255,4261 ---- ; (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) ;; Sort of orthogonal keymap *************** *** 4172,4177 **** --- 4282,4289 ---- (define-key gnus-summary-mark-map "C" 'gnus-summary-catchup) (define-key gnus-summary-mark-map "H" 'gnus-summary-catchup-to-here) (define-key gnus-summary-mark-map "\C-c" 'gnus-summary-catchup-all) + (define-key gnus-summary-mark-map "k" 'gnus-summary-kill-same-subject-and-select) + (define-key gnus-summary-mark-map "K" 'gnus-summary-kill-same-subject) (define-prefix-command 'gnus-summary-mscore-map) (define-key gnus-summary-mark-map "s" 'gnus-summary-mscore-map) *************** *** 4245,4257 **** (define-prefix-command 'gnus-summary-exit-map) ! (define-key gnus-summary-mode-map "\M-e" 'gnus-summary-exit-map) (define-key gnus-summary-exit-map "c" 'gnus-summary-catchup-and-exit) ! (define-key gnus-summary-exit-map "\C-c" 'gnus-summary-catchup-all-and-exit) ! (define-key gnus-summary-exit-map "q" 'gnus-summary-exit) ! (define-key gnus-summary-exit-map "e" 'gnus-summary-exit) ! (define-key gnus-summary-exit-map "Q" 'gnus-summary-quit) ! (define-key gnus-summary-exit-map "E" 'gnus-summary-quit) (define-prefix-command 'gnus-summary-article-map) --- 4357,4368 ---- (define-prefix-command 'gnus-summary-exit-map) ! (define-key gnus-summary-mode-map "Z" 'gnus-summary-exit-map) (define-key gnus-summary-exit-map "c" 'gnus-summary-catchup-and-exit) ! (define-key gnus-summary-exit-map "C" 'gnus-summary-catchup-all-and-exit) ! (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-prefix-command 'gnus-summary-article-map) *************** *** 4318,4340 **** (define-key gnus-summary-various-map "e" 'gnus-summary-expand-window) (define-key gnus-summary-various-map "S" 'gnus-summary-reselect-current-group) (define-key gnus-summary-various-map "g" 'gnus-summary-rescan-group) - (define-key gnus-summary-various-map "o" 'gnus-summary-save-article) - (define-key gnus-summary-various-map "\C-o" 'gnus-summary-save-article-mail) - (define-key gnus-summary-various-map "|" 'gnus-summary-pipe-output) (define-key gnus-summary-various-map "V" 'gnus-version) (define-key gnus-summary-various-map "f" 'gnus-summary-fetch-faq) (define-key gnus-summary-various-map "d" 'gnus-summary-describe-group) (define-key gnus-summary-various-map "?" 'gnus-summary-describe-briefly) (define-key gnus-summary-various-map "i" 'gnus-info-find-node) (define-key gnus-summary-various-map "D" 'gnus-summary-enter-digest-group) (define-prefix-command 'gnus-summary-score-map) (define-key gnus-summary-various-map "S" 'gnus-summary-score-map) (define-key gnus-summary-score-map "s" 'gnus-summary-set-score) (define-key gnus-summary-score-map "c" 'gnus-score-change-score-file) (define-key gnus-summary-score-map "m" 'gnus-score-set-mark-below) ! (define-key gnus-summary-score-map "E" 'gnus-score-set-expunge-below) ! (define-key gnus-summary-score-map "e" 'gnus-score-edit-file) (define-prefix-command 'gnus-summary-sort-map) (define-key gnus-summary-various-map "s" 'gnus-summary-sort-map) --- 4429,4460 ---- (define-key gnus-summary-various-map "e" 'gnus-summary-expand-window) (define-key gnus-summary-various-map "S" 'gnus-summary-reselect-current-group) (define-key gnus-summary-various-map "g" 'gnus-summary-rescan-group) (define-key gnus-summary-various-map "V" 'gnus-version) (define-key gnus-summary-various-map "f" 'gnus-summary-fetch-faq) (define-key gnus-summary-various-map "d" 'gnus-summary-describe-group) (define-key gnus-summary-various-map "?" 'gnus-summary-describe-briefly) (define-key gnus-summary-various-map "i" 'gnus-info-find-node) (define-key gnus-summary-various-map "D" 'gnus-summary-enter-digest-group) + (define-key gnus-summary-various-map "k" 'gnus-summary-edit-local-kill) + (define-key gnus-summary-various-map "K" 'gnus-summary-edit-global-kill) + + (define-prefix-command 'gnus-summary-vsave-map) + (define-key gnus-summary-various-map "o" 'gnus-summary-vsave-map) + (define-key gnus-summary-vsave-map "o" 'gnus-summary-save-article) + (define-key gnus-summary-vsave-map "m" 'gnus-summary-save-article-mail) + (define-key gnus-summary-vsave-map "r" 'gnus-summary-save-article-rmail) + (define-key gnus-summary-vsave-map "f" 'gnus-summary-save-article-file) + (define-key gnus-summary-vsave-map "h" 'gnus-summary-save-article-folder) + (define-key gnus-summary-vsave-map "p" 'gnus-summary-pipe-output) (define-prefix-command 'gnus-summary-score-map) (define-key gnus-summary-various-map "S" 'gnus-summary-score-map) (define-key gnus-summary-score-map "s" 'gnus-summary-set-score) (define-key gnus-summary-score-map "c" 'gnus-score-change-score-file) (define-key gnus-summary-score-map "m" 'gnus-score-set-mark-below) ! (define-key gnus-summary-score-map "x" 'gnus-score-set-expunge-below) ! (define-key gnus-summary-score-map "e" 'gnus-score-edit-alist) ! (define-key gnus-summary-score-map "f" 'gnus-score-edit-file) (define-prefix-command 'gnus-summary-sort-map) (define-key gnus-summary-various-map "s" 'gnus-summary-sort-map) *************** *** 4353,4365 **** (define-key gnus-summary-mgroup-map "w" 'gnus-summary-edit-article) (define-key gnus-summary-mgroup-map "c" 'gnus-summary-copy-article) - (define-prefix-command 'gnus-summary-vkill-map) - (define-key gnus-summary-various-map "k" 'gnus-summary-vkill-map) - (define-key gnus-summary-vkill-map "k" 'gnus-summary-kill-same-subject-and-select) - (define-key gnus-summary-vkill-map "K" 'gnus-summary-kill-same-subject) - (define-key gnus-summary-vkill-map "\M-k" 'gnus-summary-edit-local-kill) - (define-key gnus-summary-vkill-map "\M-K" 'gnus-summary-edit-global-kill) - (define-prefix-command 'gnus-summary-increase-map) (define-key gnus-summary-mode-map "I" 'gnus-summary-increase-map) --- 4473,4478 ---- *************** *** 4475,4481 **** --- 4588,4608 ---- (defun gnus-summary-mode () "Major mode for reading articles. + All normal editing commands are switched off. + \\ + Each line in this buffer represents one article. To read an + article, you can, for instance, type `\\[gnus-summary-next-page]'. To move forwards + and backwards while displaying articles, type `\\[gnus-summary-next-unread-article]' and `\\[gnus-summary-prev-unread-article]', + respectively. + + You can also post articles and send mail from this buffer. To + follow up an article, type `\\[gnus-summary-followup]'. To mail a reply to the author + of an article, type `\\[gnus-summary-reply]'. + + There are approx. one gazillion commands you can execute in this + buffer; read the info pages for more information (`\\[gnus-info-find-node]'). + The following commands are available: \\{gnus-summary-mode-map}" *************** *** 4605,4613 **** (progn (or dont-update (if (and gnus-summary-mark-below ! (< (gnus-summary-article-score) gnus-summary-mark-below)) ! (and (not (memq (gnus-summary-article-mark) ! gnus-newsgroup-unreads)) (gnus-summary-mark-article nil gnus-low-score-mark)) (and (eq (gnus-summary-article-mark) gnus-low-score-mark) (gnus-summary-mark-article nil gnus-unread-mark)))) --- 4732,4741 ---- (progn (or dont-update (if (and gnus-summary-mark-below ! (< (gnus-summary-article-score) ! gnus-summary-mark-below)) ! (and (not (memq (gnus-summary-article-number) ! gnus-newsgroup-marked)) (gnus-summary-mark-article nil gnus-low-score-mark)) (and (eq (gnus-summary-article-mark) gnus-low-score-mark) (gnus-summary-mark-article nil gnus-unread-mark)))) *************** *** 5143,5149 **** nil ;; Init the dependencies hash table. (setq gnus-newsgroup-dependencies ! (gnus-make-hashtable (length gnus-newsgroup-unreads))) ;; Retrieve the headers and read them in. (setq gnus-newsgroup-headers (if (eq 'nov (setq gnus-headers-retrieved-by --- 5271,5277 ---- nil ;; Init the dependencies hash table. (setq gnus-newsgroup-dependencies ! (gnus-make-hashtable (length articles))) ;; Retrieve the headers and read them in. (setq gnus-newsgroup-headers (if (eq 'nov (setq gnus-headers-retrieved-by *************** *** 5171,5179 **** gnus-newsgroup-headers))) ;; Check whether auto-expire is to be done in this group. (setq gnus-newsgroup-auto-expire ! (and (stringp gnus-auto-expirable-newsgroups) ! (string-match gnus-auto-expirable-newsgroups ! (gnus-group-real-name group)))) ;; First and last article in this newsgroup. (and gnus-newsgroup-headers (setq gnus-newsgroup-begin --- 5299,5307 ---- gnus-newsgroup-headers))) ;; Check whether auto-expire is to be done in this group. (setq gnus-newsgroup-auto-expire ! (or (and (stringp gnus-auto-expirable-newsgroups) ! (string-match gnus-auto-expirable-newsgroups group)) ! (memq 'auto-expire gnus-current-select-method))) ;; First and last article in this newsgroup. (and gnus-newsgroup-headers (setq gnus-newsgroup-begin *************** *** 5192,5198 **** (if (or read-all (= (length gnus-newsgroup-unreads) (length gnus-newsgroup-dormant))) ! (gnus-uncompress-sequence (gnus-gethash group gnus-active-hashtb)) gnus-newsgroup-unreads)) (scored-list (gnus-killed-articles gnus-newsgroup-killed articles)) --- 5320,5326 ---- (if (or read-all (= (length gnus-newsgroup-unreads) (length gnus-newsgroup-dormant))) ! (gnus-uncompress-range (gnus-gethash group gnus-active-hashtb)) gnus-newsgroup-unreads)) (scored-list (gnus-killed-articles gnus-newsgroup-killed articles)) *************** *** 5352,5358 **** (defun gnus-add-marked-articles (group type articles &optional info force) ;; Add ARTICLES of TYPE to the info of GROUP. ;; If INFO is non-nil, use that info. If FORCE is non-nil, don't ! ;; add, but replace this marked articles of TYPE with ARTICLES. (let ((info (or info (nth 2 (gnus-gethash group gnus-newsrc-hashtb)))) marked m) (or (not info) --- 5480,5486 ---- (defun gnus-add-marked-articles (group type articles &optional info force) ;; Add ARTICLES of TYPE to the info of GROUP. ;; If INFO is non-nil, use that info. If FORCE is non-nil, don't ! ;; add, but replace marked articles of TYPE with ARTICLES. (let ((info (or info (nth 2 (gnus-gethash group gnus-newsrc-hashtb)))) marked m) (or (not info) *************** *** 5503,5517 **** ;; articles there are in this group. (if active (progn ! (if (atom (car range)) (if (not range) (setq num (- (1+ (cdr active)) (car active))) (setq num (- (cdr active) (- (1+ (cdr range)) (car range))))) (while range ! (setq num (+ num (- (1+ (cdr (car range))) ! (car (car range))))) (setq range (cdr range))) (setq num (- (cdr active) num))) ;; Update the number of unread articles. --- 5631,5645 ---- ;; articles there are in this group. (if active (progn ! (if (atom (cdr range)) (if (not range) (setq num (- (1+ (cdr active)) (car active))) (setq num (- (cdr active) (- (1+ (cdr range)) (car range))))) (while range ! (setq num (+ num (- (1+ (or (and (numberp (car range)) (car range)) (cdr (car range)))) ! (or (and (numberp (car range)) (car range)) (car (car range)))))) (setq range (cdr range))) (setq num (- (cdr active) num))) ;; Update the number of unread articles. *************** *** 6037,6044 **** (while (< first nlast) (setq unread (cons first unread)) (setq first (1+ first)))) ! (setq first (1+ (cdr (car read)))) ! (setq nlast (car (car (cdr read)))) (setq read (cdr read))))) ;; And add the last unread articles. (while (<= first last) --- 6165,6174 ---- (while (< first nlast) (setq unread (cons first unread)) (setq first (1+ first)))) ! (setq first (1+ (if (atom (car read)) (car read) (cdr (car read))))) ! (setq nlast (if (atom (car (cdr read))) ! (car (cdr read)) ! (car (car (cdr read))))) (setq read (cdr read))))) ;; And add the last unread articles. (while (<= first last) *************** *** 6119,6125 **** (gnus-compress-sequence (nconc (gnus-set-sorted-intersection ! (gnus-uncompress-sequence gnus-newsgroup-killed) (setq gnus-newsgroup-unselected (sort gnus-newsgroup-unselected '<))) (setq gnus-newsgroup-unreads --- 6249,6255 ---- (gnus-compress-sequence (nconc (gnus-set-sorted-intersection ! (gnus-uncompress-range gnus-newsgroup-killed) (setq gnus-newsgroup-unselected (sort gnus-newsgroup-unselected '<))) (setq gnus-newsgroup-unreads *************** *** 6136,6142 **** gnus-newsgroup-marked t gnus-newsgroup-replied gnus-newsgroup-expirable gnus-newsgroup-killed gnus-newsgroup-dormant ! gnus-newsgroup-bookmarks gnus-newsgroup-scored) (and gnus-use-cross-reference (gnus-mark-xrefs-as-read group headers gnus-newsgroup-unreads gnus-newsgroup-expirable)) --- 6266,6273 ---- gnus-newsgroup-marked t gnus-newsgroup-replied gnus-newsgroup-expirable gnus-newsgroup-killed gnus-newsgroup-dormant ! gnus-newsgroup-bookmarks ! (and gnus-save-score gnus-newsgroup-scored)) (and gnus-use-cross-reference (gnus-mark-xrefs-as-read group headers gnus-newsgroup-unreads gnus-newsgroup-expirable)) *************** *** 6178,6184 **** (gnus-set-global-variables) (gnus-configure-windows 'summary)))))) ! (defun gnus-summary-quit (&optional no-questions) "Quit reading current newsgroup without updating read article info." (interactive) (let* ((group gnus-newsgroup-name) --- 6309,6316 ---- (gnus-set-global-variables) (gnus-configure-windows 'summary)))))) ! (defalias 'gnus-summary-quit 'gnus-summary-exit-no-update) ! (defun gnus-summary-exit-no-update (&optional no-questions) "Quit reading current newsgroup without updating read article info." (interactive) (let* ((group gnus-newsgroup-name) *************** *** 6250,6256 **** (let ((group (or group (gnus-summary-search-group backward))) (buf gnus-summary-buffer)) (if (null group) ! (gnus-summary-quit t) (message "Selecting %s..." group) ;; We are now in group mode buffer. ;; Make sure group mode buffer point is on GROUP. --- 6382,6388 ---- (let ((group (or group (gnus-summary-search-group backward))) (buf gnus-summary-buffer)) (if (null group) ! (gnus-summary-exit-no-update t) (message "Selecting %s..." group) ;; We are now in group mode buffer. ;; Make sure group mode buffer point is on GROUP. *************** *** 6260,6266 **** (and (string= gnus-newsgroup-name ingroup) (progn (set-buffer sumbuf) ! (gnus-summary-quit t)))))))) (defun gnus-summary-prev-group (no-article) "Exit current newsgroup and then select previous unread newsgroup. --- 6392,6398 ---- (and (string= gnus-newsgroup-name ingroup) (progn (set-buffer sumbuf) ! (gnus-summary-exit-no-update t)))))))) (defun gnus-summary-prev-group (no-article) "Exit current newsgroup and then select previous unread newsgroup. *************** *** 6794,6821 **** ;; Return T if found such article. found)) ! (defun gnus-summary-execute-command (field regexp command &optional backward) ! "If FIELD of article header matches REGEXP, execute a COMMAND string. ! If FIELD is an empty string (or nil), entire article body is searched for. ! If optional (prefix) argument BACKWARD is non-nil, do backward instead." (interactive (list (let ((completion-ignore-case t)) ! (completing-read "Field name: " ! '(("Number")("Subject")("From") ! ("Lines")("Date")("Message-ID") ! ("Xref")("References")) ! nil 'require-match)) (read-string "Regexp: ") (read-key-sequence "Command: ") current-prefix-arg)) ! ;; Hidden thread subtrees must be searched for ,too. (gnus-summary-show-all-threads) ;; We don't want to change current point nor window configuration. (save-excursion (save-window-excursion (message "Executing %s..." (key-description command)) ;; We'd like to execute COMMAND interactively so as to give arguments. ! (gnus-execute field regexp (` (lambda () (call-interactively '(, (key-binding command))))) backward) --- 6926,6954 ---- ;; Return T if found such article. found)) ! (defun gnus-summary-execute-command (header regexp command &optional backward) ! "Search forward for an article whose HEADER matches REGEXP and execute COMMAND. ! If HEADER is an empty string (or nil), the match is done on the entire ! article. If BACKWARD (the prefix) is non-nil, search backward instead." (interactive (list (let ((completion-ignore-case t)) ! (completing-read ! "Header name: " ! (mapcar (string) (list string) ! '("Number" "Subject" "From" "Lines" "Date" ! "Message-ID" "Xref" "References") ! nil 'require-match))) (read-string "Regexp: ") (read-key-sequence "Command: ") current-prefix-arg)) ! ;; Hidden thread subtrees must be searched as well. (gnus-summary-show-all-threads) ;; We don't want to change current point nor window configuration. (save-excursion (save-window-excursion (message "Executing %s..." (key-description command)) ;; We'd like to execute COMMAND interactively so as to give arguments. ! (gnus-execute header regexp (` (lambda () (call-interactively '(, (key-binding command))))) backward) *************** *** 6969,6977 **** (setcar (cdr (cdr info)) (gnus-add-to-range (nth 2 info) (list (cdr art-group))))) ! ;; !!! Here one should copy all the marks over to the new ! ;; newsgroup, but I couldn't be bothered. nth on that! ! ) (message "Couldn't move article %s" (car articles))) (gnus-summary-remove-process-mark (car articles)) (setq articles (cdr articles))))) --- 7102,7120 ---- (setcar (cdr (cdr info)) (gnus-add-to-range (nth 2 info) (list (cdr art-group))))) ! ;; Copy any marks over to the new group. ! (let ((marks '((tick . gnus-newsgroup-marked) ! (dormant . gnus-newsgroup-dormant) ! (expire . gnus-newsgroup-expirable) ! (bookmark . gnus-newsgroup-bookmarks) ! ; (score . gnus-newsgroup-scored) ! (reply . gnus-newsgroup-replied))) ! (to-article (cdr art-group))) ! (while marks ! (if (memq article (symbol-value (cdr (car marks)))) ! (gnus-add-marked-articles ! (car info) (car (car marks)) (list to-article) info)) ! (setq marks (cdr marks))))) (message "Couldn't move article %s" (car articles))) (gnus-summary-remove-process-mark (car articles)) (setq articles (cdr articles))))) *************** *** 7054,7067 **** (setcar (cdr (cdr info)) (gnus-add-to-range (nth 2 info) (list (cdr art-group))))) ! ;; !!! Here one should copy all the marks over to the new ! ;; newsgroup, but I couldn't be bothered. nth on that! ! ) (message "Couldn't copy article %s" (car articles))) (gnus-summary-remove-process-mark (car articles)) (setq articles (cdr articles))) (kill-buffer copy-buf))) ! ;; Summary score commands. --- 7197,7299 ---- (setcar (cdr (cdr info)) (gnus-add-to-range (nth 2 info) (list (cdr art-group))))) ! ;; Copy any marks over to the new group. ! (let ((marks '((tick . gnus-newsgroup-marked) ! (dormant . gnus-newsgroup-dormant) ! (expire . gnus-newsgroup-expirable) ! (bookmark . gnus-newsgroup-bookmarks) ! ; (score . gnus-newsgroup-scored) ! (reply . gnus-newsgroup-replied))) ! (to-article (cdr art-group))) ! (while marks ! (if (memq article (symbol-value (cdr (car marks)))) ! (gnus-add-marked-articles ! (car info) (car (car marks)) (list to-article) info)) ! (setq marks (cdr marks))))) (message "Couldn't copy article %s" (car articles))) (gnus-summary-remove-process-mark (car articles)) (setq articles (cdr articles))) (kill-buffer copy-buf))) ! ! (defun gnus-summary-expire-articles () ! "Expire all articles that are marked as expirable in the current group." ! (interactive) ! (if (and gnus-newsgroup-expirable ! (gnus-check-backend-function ! 'request-expire-articles gnus-newsgroup-name)) ! (let ((expirable gnus-newsgroup-expirable)) ! ;; The list of articles that weren't expired is returned. ! (setq gnus-newsgroup-expirable ! (gnus-request-expire-articles gnus-newsgroup-expirable ! gnus-newsgroup-name)) ! ;; We go through the old list of expirable, and mark all ! ;; really expired articles as non-existant. ! (while expirable ! (or (memq (car expirable) gnus-newsgroup-expirable) ! (gnus-summary-mark-as-read (car expirable) "%")) ! (setq expirable (cdr expirable)))))) ! ! ;; Suggested by Jack Vinson . ! (defun gnus-summary-delete-article (n) ! "Delete the N next (mail) articles. ! This command actually deletes articles. This is not a marking ! command. The article will disappear forever from you life, never to ! return. ! If N is negative, delete backwards. ! If N is nil and articles have been marked with the process mark, ! delete these instead." ! (interactive "P") ! (or (gnus-check-backend-function 'request-expire-articles ! gnus-newsgroup-name) ! (error "The current newsgroup does not support article deletion.")) ! ;; Compute the list of articles to delete. ! (let ((articles (gnus-summary-work-articles n))) ! (if (and gnus-novice-user ! (not (gnus-y-or-n-p ! (format "Do you really want to delete %s forever? " ! (if (> (length articles) 1) "these articles" ! "this article"))))) ! () ! ;; Delete the articles. ! (setq gnus-newsgroup-expirable ! (gnus-request-expire-articles ! articles gnus-newsgroup-name 'force)) ! (while articles ! (gnus-summary-remove-process-mark (car articles)) ! ;; The backend might not have been able to delete the article ! ;; after all. ! (or (memq (car articles) gnus-newsgroup-expirable) ! (gnus-summary-mark-as-read (car articles) gnus-canceled-mark)) ! (setq articles (cdr articles)))))) ! ! (defun gnus-summary-edit-article () ! "Enter into a buffer and edit the current article. ! This will have permanent effect only in mail groups." ! (interactive) ! (or (gnus-check-backend-function ! 'request-replace-article gnus-newsgroup-name) ! (error "The current newsgroup does not support article editing.")) ! (gnus-summary-select-article t) ! (other-window 1) ! (message "C-c C-c to end edits") ! (setq buffer-read-only nil) ! (text-mode) ! (use-local-map (copy-keymap (current-local-map))) ! (local-set-key "\C-c\C-c" 'gnus-summary-edit-article-done) ! (goto-char 1) ! (search-forward "\n\n" nil t)) ! ! (defun gnus-summary-edit-article-done () ! "Make edits to the current article permanent." ! (interactive) ! (if (not (gnus-request-replace-article ! (cdr gnus-article-current) (car gnus-article-current) ! (current-buffer))) ! (error "Couldn't replace article.") ! (gnus-article-mode) ! (use-local-map gnus-article-mode-map) ! (setq buffer-read-only t) ! (pop-to-buffer gnus-summary-buffer))) ;; Summary score commands. *************** *** 7096,7109 **** (cons (cons article n) gnus-newsgroup-scored)))) (gnus-summary-update-line))) - (defmacro gnus-raise (field expression level) - (` (gnus-kill (, field) (, expression) - (function (gnus-summary-raise-score (, level))) t))) - - (defmacro gnus-lower (field expression level) - (` (gnus-kill (, field) (, expression) - (function (gnus-summary-raise-score (- (, level)))) t))) - ;; Summary marking commands. (defun gnus-summary-raise-same-subject-and-select (score) --- 7328,7333 ---- *************** *** 7257,7351 **** (interactive "p") (gnus-summary-mark-forward n gnus-expirable-mark)) - (defun gnus-summary-expire-articles () - "Expire all articles that are marked as expirable in the current group." - (interactive) - (if (and gnus-newsgroup-expirable - (gnus-check-backend-function - 'request-expire-articles gnus-newsgroup-name)) - (let ((expirable gnus-newsgroup-expirable)) - ;; The list of articles that weren't expired is returned. - (setq gnus-newsgroup-expirable - (gnus-request-expire-articles gnus-newsgroup-expirable - gnus-newsgroup-name)) - ;; We go through the old list of expirable, and mark all - ;; really expired articles as non-existant. - (while expirable - (or (memq (car expirable) gnus-newsgroup-expirable) - (gnus-summary-mark-as-read (car expirable) "%")) - (setq expirable (cdr expirable)))))) - - ;; Suggested by Jack Vinson . - (defun gnus-summary-delete-article (n) - "Delete the N next (mail) articles. - This command actually deletes articles. This is not a marking - command. The article will disappear forever from you life, never to - return. - If N is negative, delete backwards. - If N is nil and articles have been marked with the process mark, - delete these instead." - (interactive "P") - (or (gnus-check-backend-function 'request-expire-articles - gnus-newsgroup-name) - (error "The current newsgroup does not support article deletion.")) - ;; Compute the list of articles to delete. - (let (articles) - (if (and n (numberp n)) - (let ((backward (< n 0)) - (n (abs n))) - (save-excursion - (while (and (> n 0) - (setq articles (cons (gnus-summary-article-number) - articles)) - (gnus-summary-search-forward nil nil backward)) - (setq n (1- n)))) - (setq articles (sort articles (function <)))) - (setq articles (or (setq gnus-newsgroup-processable - (sort gnus-newsgroup-processable (function <))) - (list (gnus-summary-article-number))))) - (if (and gnus-novice-user - (not (gnus-y-or-n-p - (format "Do you really want to delete %s forever? " - (if (> (length articles) 1) "these articles" - "this article"))))) - () - ;; Delete the articles. - (setq gnus-newsgroup-expirable - (gnus-request-expire-articles - articles gnus-newsgroup-name 'force)) - (while articles - (gnus-summary-mark-as-read (car articles) gnus-canceled-mark) - (setq articles (cdr articles)))))) - - (defun gnus-summary-edit-article () - "Enter into a buffer and edit the current article. - This will have permanent effect only in mail groups." - (interactive) - (or (gnus-check-backend-function - 'request-replace-article gnus-newsgroup-name) - (error "The current newsgroup does not support article editing.")) - (gnus-summary-select-article t) - (other-window 1) - (message "C-c C-c to end edits") - (setq buffer-read-only nil) - (text-mode) - (use-local-map (copy-keymap (current-local-map))) - (local-set-key "\C-c\C-c" 'gnus-summary-edit-article-done) - (goto-char 1) - (search-forward "\n\n" nil t)) - - (defun gnus-summary-edit-article-done () - "Make edits to the current article permanent." - (interactive) - (if (not (gnus-request-replace-article - (cdr gnus-article-current) (car gnus-article-current) - (current-buffer))) - (error "Couldn't replace article.") - (gnus-article-mode) - (use-local-map gnus-article-mode-map) - (setq buffer-read-only t) - (pop-to-buffer gnus-summary-buffer))) - (defun gnus-summary-mark-article-as-replied (article) "Mark ARTICLE replied and update the summary line." (setq gnus-newsgroup-replied (cons article gnus-newsgroup-replied)) --- 7481,7486 ---- *************** *** 7995,8001 **** "Sort summary buffer by article number. Argument REVERSE means reverse order." (interactive "P") ! (gnus-summary-sort 'gnus-summary-article-number reverse)) (defun gnus-summary-sort-by-author (reverse) "Sort summary buffer by author name alphabetically. --- 8130,8137 ---- "Sort summary buffer by article number. Argument REVERSE means reverse order." (interactive "P") ! (gnus-summary-sort ! (cons 'gnus-summary-article-number 'gnus-thread-sort-by-number) reverse)) (defun gnus-summary-sort-by-author (reverse) "Sort summary buffer by author name alphabetically. *************** *** 8003,8014 **** Argument REVERSE means reverse order." (interactive "P") (gnus-summary-sort ! (lambda () ! (let ((extract (funcall ! gnus-extract-address-components ! (header-from (gnus-get-header-by-number ! (gnus-summary-article-number)))))) ! (or (car extract) (cdr extract)))) reverse)) (defun gnus-summary-sort-by-subject (reverse) --- 8139,8152 ---- Argument REVERSE means reverse order." (interactive "P") (gnus-summary-sort ! (cons ! (lambda () ! (let ((extract (funcall ! gnus-extract-address-components ! (header-from (gnus-get-header-by-number ! (gnus-summary-article-number)))))) ! (or (car extract) (cdr extract)))) ! 'gnus-thread-sort-by-author) reverse)) (defun gnus-summary-sort-by-subject (reverse) *************** *** 8017,8024 **** Argument REVERSE means reverse order." (interactive "P") (gnus-summary-sort ! (lambda () ! (downcase (gnus-simplify-subject (gnus-summary-subject-string)))) reverse)) (defun gnus-summary-sort-by-date (reverse) --- 8155,8164 ---- Argument REVERSE means reverse order." (interactive "P") (gnus-summary-sort ! (cons ! (lambda () ! (downcase (gnus-simplify-subject (gnus-summary-subject-string)))) ! 'gnus-thread-sort-by-subject) reverse)) (defun gnus-summary-sort-by-date (reverse) *************** *** 8026,8047 **** Argument REVERSE means reverse order." (interactive "P") (gnus-summary-sort ! (lambda () ! (gnus-sortable-date ! (header-date (gnus-get-header-by-number (gnus-summary-article-number))))) reverse)) (defun gnus-summary-sort-by-score (reverse) "Sort summary buffer by score. Argument REVERSE means reverse order." (interactive "P") ! (gnus-summary-sort 'gnus-summary-article-score (not reverse))) (defun gnus-summary-sort (predicate reverse) ;; Sort summary buffer by PREDICATE. REVERSE means reverse order. (let (buffer-read-only) ! (goto-char (point-min)) ! (sort-subr reverse 'forward-line 'end-of-line predicate))) (defun gnus-sortable-date (date) "Make sortable string by string-lessp from DATE. --- 8166,8196 ---- Argument REVERSE means reverse order." (interactive "P") (gnus-summary-sort ! (cons ! (lambda () ! (gnus-sortable-date ! (header-date ! (gnus-get-header-by-number (gnus-summary-article-number))))) ! 'gnus-thread-sort-by-date) reverse)) (defun gnus-summary-sort-by-score (reverse) "Sort summary buffer by score. Argument REVERSE means reverse order." (interactive "P") ! (gnus-summary-sort ! (cons 'gnus-summary-article-score 'gnus-thread-sort-by-score) ! (not reverse))) (defun gnus-summary-sort (predicate reverse) ;; Sort summary buffer by PREDICATE. REVERSE means reverse order. (let (buffer-read-only) ! (if (not gnus-show-threads) ! (progn ! (goto-char (point-min)) ! (sort-subr reverse 'forward-line 'end-of-line (car predicate))) ! (let ((gnus-thread-sort-functions (list (cdr predicate)))) ! (gnus-summary-prepare))))) (defun gnus-sortable-date (date) "Make sortable string by string-lessp from DATE. *************** *** 8125,8130 **** --- 8274,8309 ---- (let ((gnus-default-article-saver 'gnus-summary-save-in-mail)) (gnus-summary-save-article arg))) + (defun gnus-summary-save-article-rmail (arg) + "Append the current article to an rmail file. + If N is a positive number, save the N next articles. + If N is a negative number, save the N previous articles. + If N is nil and any articles have been marked with the process mark, + save those articles instead." + (interactive "P") + (let ((gnus-default-article-saver 'gnus-summary-save-in-rmail)) + (gnus-summary-save-article arg))) + + (defun gnus-summary-save-article-file (arg) + "Append the current article to a file. + If N is a positive number, save the N next articles. + If N is a negative number, save the N previous articles. + If N is nil and any articles have been marked with the process mark, + save those articles instead." + (interactive "P") + (let ((gnus-default-article-saver 'gnus-summary-save-in-file)) + (gnus-summary-save-article arg))) + + (defun gnus-summary-save-article-folder (arg) + "Append the current article to an mh folder. + If N is a positive number, save the N next articles. + If N is a negative number, save the N previous articles. + If N is nil and any articles have been marked with the process mark, + save those articles instead." + (interactive "P") + (let ((gnus-default-article-saver 'gnus-summary-save-in-folder)) + (gnus-summary-save-article arg))) + (defun gnus-summary-save-in-rmail (&optional filename) "Append this article to Rmail file. Optional argument FILENAME specifies file name. *************** *** 8579,8586 **** (defun gnus-article-mode () ! "Major mode for reading an article. All normal editing commands are switched off. The following commands are available: \\ --- 8758,8767 ---- (defun gnus-article-mode () ! "Major mode for displaying an article. ! All normal editing commands are switched off. + The following commands are available: \\ *************** *** 9268,9535 **** (insert str))))) - ;;; - ;;; Gnus Kill File Mode - ;;; - - (defvar gnus-kill-file-mode-map nil) - - (if gnus-kill-file-mode-map - nil - (setq gnus-kill-file-mode-map (copy-keymap emacs-lisp-mode-map)) - (define-key gnus-kill-file-mode-map - "\C-c\C-k\C-s" 'gnus-kill-file-kill-by-subject) - (define-key gnus-kill-file-mode-map - "\C-c\C-k\C-a" 'gnus-kill-file-kill-by-author) - (define-key gnus-kill-file-mode-map - "\C-c\C-k\C-a" 'gnus-kill-file-kill-by-thread) - (define-key gnus-kill-file-mode-map - "\C-c\C-k\C-a" 'gnus-kill-file-kill-by-xref) - (define-key gnus-kill-file-mode-map - "\C-c\C-a" 'gnus-kill-file-apply-buffer) - (define-key gnus-kill-file-mode-map - "\C-c\C-e" 'gnus-kill-file-apply-last-sexp) - (define-key gnus-kill-file-mode-map - "\C-c\C-c" 'gnus-kill-file-exit)) - - (defun gnus-kill-file-mode () - "Major mode for editing kill files. - - If you are using this mode - you probably shouldn't. Kill files - perform badly and paint with a pretty broad brush. Score files, on - the other hand, are vastly faster (40x speedup) and give you more - control over what to do. - - In addition to Emacs-Lisp Mode, the following commands are available: - - \\{gnus-kill-file-mode-map} - - A kill file contains Lisp expressions to be applied to a selected - newsgroup. The purpose is to mark articles as read on the basis of - some set of regexps. A global kill file is applied to every newsgroup, - and a local kill file is applied to a specified newsgroup. Since a - global kill file is applied to every newsgroup, for better performance - use a local one. - - A kill file can contain any kind of Emacs Lisp expressions expected - to be evaluated in the Summary buffer. Writing Lisp programs for this - purpose is not so easy because the internal working of Gnus must be - well-known. For this reason, Gnus provides a general function which - does this easily for non-Lisp programmers. - - The `gnus-kill' function executes commands available in Summary Mode - by their key sequences. `gnus-kill' should be called with FIELD, - REGEXP and optional COMMAND and ALL. FIELD is a string representing - the header field or an empty string. If FIELD is an empty string, the - entire article body is searched for. REGEXP is a string which is - compared with FIELD value. COMMAND is a string representing a valid - key sequence in Summary mode or Lisp expression. COMMAND defaults to - '(gnus-summary-mark-as-read nil \"X\"). Make sure that COMMAND is - executed in the Summary buffer. If the second optional argument ALL - is non-nil, the COMMAND is applied to articles which are already - marked as read or unread. Articles which are marked are skipped over - by default. - - For example, if you want to mark articles of which subjects contain - the string `AI' as read, a possible kill file may look like: - - (gnus-kill \"Subject\" \"AI\") - - If you want to mark articles with `D' instead of `X', you can use - the following expression: - - (gnus-kill \"Subject\" \"AI\" \"d\") - - In this example it is assumed that the command - `gnus-summary-mark-as-read-forward' is assigned to `d' in Summary Mode. - - It is possible to delete unnecessary headers which are marked with - `X' in a kill file as follows: - - (gnus-expunge \"X\") - - If the Summary buffer is empty after applying kill files, Gnus will - exit the selected newsgroup normally. If headers which are marked - with `D' are deleted in a kill file, it is impossible to read articles - which are marked as read in the previous Gnus sessions. Marks other - than `D' should be used for articles which should really be deleted. - - Entry to this mode calls emacs-lisp-mode-hook and - gnus-kill-file-mode-hook with no arguments, if that value is non-nil." - (interactive) - (kill-all-local-variables) - (use-local-map gnus-kill-file-mode-map) - (set-syntax-table emacs-lisp-mode-syntax-table) - (setq major-mode 'gnus-kill-file-mode) - (setq mode-name "Kill") - (lisp-mode-variables nil) - (run-hooks 'emacs-lisp-mode-hook 'gnus-kill-file-mode-hook)) - - (defun gnus-kill-file-edit-file (newsgroup) - "Begin editing a kill file for NEWSGROUP. - If NEWSGROUP is nil, the global kill file is selected." - (interactive "sNewsgroup: ") - (let ((file (gnus-newsgroup-kill-file newsgroup))) - (gnus-make-directory (file-name-directory file)) - ;; Save current window configuration if this is first invocation. - (or (and (get-file-buffer file) - (get-buffer-window (get-file-buffer file))) - (setq gnus-winconf-kill-file (current-window-configuration))) - ;; Hack windows. - (let ((buffer (find-file-noselect file))) - (cond ((get-buffer-window buffer) - (pop-to-buffer buffer)) - ((eq major-mode 'gnus-group-mode) - (gnus-configure-windows '(1 0 0)) ;Take all windows. - (pop-to-buffer gnus-group-buffer) - ;; Fix by sachs@SLINKY.CS.NYU.EDU (Jay Sachs). - (let ((gnus-summary-buffer buffer)) - (gnus-configure-windows '(1 1 0))) ;Split into two. - (pop-to-buffer buffer)) - ((eq major-mode 'gnus-summary-mode) - (gnus-configure-windows 'article) - (pop-to-buffer gnus-article-buffer) - (bury-buffer gnus-article-buffer) - (switch-to-buffer buffer)) - (t ;No good rules. - (find-file-other-window file)))) - (gnus-kill-file-mode))) - - ;; Fix by Sudish Joseph . - (defun gnus-kill-set-kill-buffer () - (let* ((file (gnus-newsgroup-kill-file gnus-newsgroup-name)) - (buffer (find-file-noselect file))) - (set-buffer buffer) - (gnus-kill-file-mode) - (bury-buffer buffer))) - - (defun gnus-kill-save-kill-buffer () - (save-excursion - (let ((file (gnus-newsgroup-kill-file gnus-newsgroup-name))) - (if (get-file-buffer file) - (progn - (set-buffer (get-file-buffer file)) - (and (buffer-modified-p) (save-buffer)) - (kill-buffer (current-buffer))))))) - - (defun gnus-kill-file-enter-kill (field regexp) - ;; Enter kill file entry. - ;; FIELD: String containing the name of the header field to kill. - ;; REGEXP: The string to kill. - (save-excursion - (let (string) - (gnus-kill-set-kill-buffer) - (goto-char (point-max)) - (insert (setq string (format "(gnus-kill %S %S)\n" field regexp))) - (gnus-kill-file-apply-string string)))) - - (defun gnus-kill-file-kill-by-subject () - "Kill by subject." - (interactive) - (gnus-kill-file-enter-kill - "Subject" - (regexp-quote - (gnus-simplify-subject (header-subject gnus-current-headers))))) - - (defun gnus-kill-file-kill-by-author () - "Kill by author." - (interactive) - (gnus-kill-file-enter-kill - "From" (regexp-quote (header-from gnus-current-headers)))) - - (defun gnus-kill-file-kill-by-thread () - "Kill by author." - (interactive "p") - (gnus-kill-file-enter-kill - "References" (regexp-quote (header-id gnus-current-headers)))) - - (defun gnus-kill-file-kill-by-xref () - "Kill by Xref." - (interactive) - (let ((xref (header-xref gnus-current-headers)) - (start 0) - group) - (if xref - (while (string-match " \\([^ \t]+\\):" xref start) - (setq start (match-end 0)) - (if (not (string= - (setq group - (substring xref (match-beginning 1) (match-end 1))) - gnus-newsgroup-name)) - (gnus-kill-file-enter-kill - "Xref" (concat " " (regexp-quote group) ":")))) - (gnus-kill-file-enter-kill "Xref" "")))) - - (defun gnus-kill-file-raise-followups-to-author (level) - "Raise score for all followups to the current author." - (interactive "p") - (let ((name (header-from gnus-current-headers)) - string) - (save-excursion - (gnus-kill-set-kill-buffer) - (goto-char (point-min)) - (setq name (read-string (concat "Add " level - " to followup articles to: ") - (regexp-quote name))) - (setq - string - (format - "(gnus-kill %S %S '(gnus-summary-temporarily-raise-by-thread %S))\n" - "From" name level)) - (insert string) - (gnus-kill-file-apply-string string)) - (message "Added permanent score file entry for followups to %s." name))) - - (defun gnus-kill-file-apply-buffer () - "Apply current buffer to current newsgroup." - (interactive) - (if (and gnus-current-kill-article - (get-buffer gnus-summary-buffer)) - ;; Assume newsgroup is selected. - (gnus-kill-file-apply-string (buffer-string)) - (ding) (message "No newsgroup is selected."))) - - (defun gnus-kill-file-apply-string (string) - "Apply STRING to current newsgroup." - (interactive) - (let ((string (concat "(progn \n" string "\n)"))) - (save-excursion - (save-window-excursion - (pop-to-buffer gnus-summary-buffer) - (eval (car (read-from-string string))))))) - - (defun gnus-kill-file-apply-last-sexp () - "Apply sexp before point in current buffer to current newsgroup." - (interactive) - (if (and gnus-current-kill-article - (get-buffer gnus-summary-buffer)) - ;; Assume newsgroup is selected. - (let ((string - (buffer-substring - (save-excursion (forward-sexp -1) (point)) (point)))) - (save-excursion - (save-window-excursion - (pop-to-buffer gnus-summary-buffer) - (eval (car (read-from-string string)))))) - (ding) (message "No newsgroup is selected."))) - - (defun gnus-kill-file-exit () - "Save a kill file, then return to the previous buffer." - (interactive) - (save-buffer) - (let ((killbuf (current-buffer))) - ;; We don't want to return to article buffer. - (and (get-buffer gnus-article-buffer) - (bury-buffer gnus-article-buffer)) - ;; Delete the KILL file windows. - (delete-windows-on killbuf) - ;; Restore last window configuration if available. - (and gnus-winconf-kill-file - (set-window-configuration gnus-winconf-kill-file)) - (setq gnus-winconf-kill-file nil) - ;; Kill the KILL file buffer. Suggested by tale@pawl.rpi.edu. - (kill-buffer killbuf))) - ;; Basic ideas by emv@math.lsa.umich.edu (Edward Vielmetti) ;;;###autoload --- 9449,9454 ---- *************** *** 9579,9604 **** (switch-to-buffer gnus-group-buffer) (gnus-group-save-newsrc))) ! ;; For kill files ! (defun gnus-Newsgroup-kill-file (newsgroup) ! "Return the name of a kill file for NEWSGROUP. ! If NEWSGROUP is nil, return the global kill file instead." ! (cond ((or (null newsgroup) ! (string-equal newsgroup "")) ! ;; The global kill file is placed at top of the directory. ! (expand-file-name gnus-kill-file-name ! (or gnus-kill-files-directory "~/News"))) ! (gnus-use-long-file-name ! ;; Append ".KILL" to capitalized newsgroup name. ! (expand-file-name (concat (gnus-capitalize-newsgroup newsgroup) ! "." gnus-kill-file-name) ! (or gnus-kill-files-directory "~/News"))) ! (t ! ;; Place "KILL" under the hierarchical directory. ! (expand-file-name (concat (gnus-newsgroup-directory-form newsgroup) ! "/" gnus-kill-file-name) ! (or gnus-kill-files-directory "~/News"))))) (defun gnus-newsgroup-kill-file (newsgroup) "Return the name of a kill file name for NEWSGROUP. --- 9498,9522 ---- (switch-to-buffer gnus-group-buffer) (gnus-group-save-newsrc))) ! (defun gnus-apply-kill-file () ! "Apply a kill file to the current newsgroup. ! Returns the number of articles marked as read." ! (if (or (file-exists-p (gnus-newsgroup-kill-file nil)) ! (file-exists-p (gnus-newsgroup-kill-file gnus-newsgroup-name))) ! (gnus-apply-kill-file-internal) ! 0)) ! (defun gnus-kill-save-kill-buffer () ! (save-excursion ! (let ((file (gnus-newsgroup-kill-file gnus-newsgroup-name))) ! (if (get-file-buffer file) ! (progn ! (set-buffer (get-file-buffer file)) ! (and (buffer-modified-p) (save-buffer)) ! (kill-buffer (current-buffer))))))) ! ! (defvar gnus-kill-file-name "KILL" ! "Suffix of the kill files.") (defun gnus-newsgroup-kill-file (newsgroup) "Return the name of a kill file name for NEWSGROUP. *************** *** 9618,9851 **** "/" gnus-kill-file-name) (or gnus-kill-files-directory "~/News"))))) - (defalias 'gnus-expunge 'gnus-summary-remove-lines-marked-with) - - (defun gnus-apply-kill-file () - "Apply a kill file to the current newsgroup. - Returns the number of articles marked as read." - (let* ((kill-files (list (gnus-newsgroup-kill-file nil) - (gnus-newsgroup-kill-file gnus-newsgroup-name))) - (unreads (length gnus-newsgroup-unreads)) - (gnus-summary-inhibit-highlight t) - (mark-below (or gnus-summary-mark-below gnus-summary-default-score 0)) - (expunge-below gnus-summary-expunge-below) - form beg) - (setq gnus-newsgroup-kill-headers nil) - (or gnus-newsgroup-headers-hashtb-by-number - (gnus-make-headers-hashtable-by-number)) - ;; If there are any previously scored articles, we remove these - ;; from the `gnus-newsgroup-headers' list that the score functions - ;; will see. This is probably pretty wasteful when it comes to - ;; conses, but is, I think, faster than having to assq in every - ;; single score funtion. - (let ((files kill-files)) - (while files - (if (file-exists-p (car files)) - (let ((headers gnus-newsgroup-headers)) - (if gnus-kill-killed - (setq gnus-newsgroup-kill-headers - (mapcar (lambda (header) (header-number header)) - headers)) - (while headers - (or (gnus-member-of-range - (header-number (car headers)) - gnus-newsgroup-killed) - (setq gnus-newsgroup-kill-headers - (cons (header-number (car headers)) - gnus-newsgroup-kill-headers))) - (setq headers (cdr headers)))) - (setq files nil)) - (setq files (cdr files))))) - (if gnus-newsgroup-kill-headers - (save-excursion - (while kill-files - (if (file-exists-p (car kill-files)) - (progn - (message "Processing kill file %s..." (car kill-files)) - (find-file (car kill-files)) - (goto-char (point-min)) - (while (progn - (setq beg (point)) - (setq form (condition-case nil - (read (current-buffer)) - (error nil)))) - (if (or (eq (car form) 'gnus-kill) - (eq (car form) 'gnus-raise) - (eq (car form) 'gnus-lower)) - (progn - (delete-region beg (point)) - (insert (or (eval form) ""))) - (condition-case () - (eval form) - (error nil)))) - (and (buffer-modified-p) (save-buffer)) - (message "Processing kill file %s...done" (car kill-files)))) - (setq kill-files (cdr kill-files))))) - (if beg - (let ((nunreads (- unreads (length gnus-newsgroup-unreads)))) - (or (eq nunreads 0) - (message "Marked %d articles as read" nunreads)) - nunreads) - 0))) - - ;; Kill changes and new format by suggested by JWZ and Sudish Joseph - ;; . - (defun gnus-kill (field regexp &optional exe-command all) - "If FIELD of an article matches REGEXP, execute COMMAND. - Optional 1st argument COMMAND is default to - (gnus-summary-mark-as-read nil \"X\"). - If optional 2nd argument ALL is non-nil, articles marked are also applied to. - If FIELD is an empty string (or nil), entire article body is searched for. - COMMAND must be a lisp expression or a string representing a key sequence." - ;; We don't want to change current point nor window configuration. - (save-excursion - (save-window-excursion - ;; Selected window must be summary buffer to execute keyboard - ;; macros correctly. See command_loop_1. - (switch-to-buffer gnus-summary-buffer 'norecord) - (goto-char (point-min)) ;From the beginning. - (let ((kill-list regexp) - (date (current-time-string)) - (command (or exe-command '(gnus-summary-mark-as-read - nil gnus-kill-file-mark))) - kill kdate prev) - (if (listp kill-list) - ;; It is a list. - (if (not (consp (cdr kill-list))) - ;; It's on the form (regexp . date). - (if (zerop (gnus-execute field (car kill-list) - command nil (not all))) - (if (> (gnus-days-between date (cdr kill-list)) - gnus-score-expiry-days) - (setq regexp nil)) - (setcdr kill-list date)) - (while (setq kill (car kill-list)) - (if (consp kill) - ;; It's a temporary kill. - (progn - (setq kdate (cdr kill)) - (if (zerop (gnus-execute - field (car kill) command nil (not all))) - (if (> (gnus-days-between date kdate) - gnus-score-expiry-days) - ;; Time limit has been exceeded, so we - ;; remove the match. - (if prev - (setcdr prev (cdr kill-list)) - (setq regexp (cdr regexp)))) - ;; Successful kill. Set the date to today. - (setcdr kill date))) - ;; It's a permanent kill. - (gnus-execute field kill command nil (not all))) - (setq prev kill-list) - (setq kill-list (cdr kill-list)))) - (gnus-execute field kill-list command nil (not all)))))) - (if (and (eq major-mode 'gnus-kill-file-mode) regexp) - (gnus-pp-gnus-kill - (nconc (list 'gnus-kill field - (if (consp regexp) (list 'quote regexp) regexp)) - (if (or exe-command all) (list (list 'quote exe-command))) - (if all (list t) nil))))) - - (defun gnus-pp-gnus-kill (object) - (if (or (not (consp (nth 2 object))) - (not (consp (cdr (nth 2 object)))) - (and (eq 'quote (car (nth 2 object))) - (not (consp (cdr (car (cdr (nth 2 object)))))))) - (concat "\n" (prin1-to-string object)) - (save-excursion - (set-buffer (get-buffer-create "*Gnus PP*")) - (buffer-disable-undo (current-buffer)) - (erase-buffer) - (insert (format "\n(%S %S\n '(" (nth 0 object) (nth 1 object))) - (let ((klist (car (cdr (nth 2 object)))) - (first t)) - (while klist - (insert (if first (progn (setq first nil) "") "\n ") - (prin1-to-string (car klist))) - (setq klist (cdr klist)))) - (insert ")") - (and (nth 3 object) - (insert "\n " - (if (and (consp (nth 3 object)) - (not (eq 'quote (car (nth 3 object))))) - "'" "") - (prin1-to-string (nth 3 object)))) - (and (nth 4 object) - (insert "\n t")) - (insert ")") - (prog1 - (buffer-substring (point-min) (point-max)) - (kill-buffer (current-buffer)))))) - - (defun gnus-execute-1 (function regexp form header) - (save-excursion - (let (did-kill) - (if (null header) - nil ;Nothing to do. - (if function - ;; Compare with header field. - (let (value) - (and header - (progn - (setq value (funcall function header)) - ;; Number (Lines:) or symbol must be converted to string. - (or (stringp value) - (setq value (prin1-to-string value))) - (setq did-kill (string-match regexp value))) - (if (stringp form) ;Keyboard macro. - (execute-kbd-macro form) - (funcall form)))) - ;; Search article body. - (let ((gnus-current-article nil) ;Save article pointer. - (gnus-last-article nil) - (gnus-break-pages nil) ;No need to break pages. - (gnus-mark-article-hook nil)) ;Inhibit marking as read. - (message "Searching for article: %d..." (header-number header)) - (gnus-article-setup-buffer) - (gnus-article-prepare (header-number header) t) - (if (save-excursion - (set-buffer gnus-article-buffer) - (goto-char (point-min)) - (setq did-kill (re-search-forward regexp nil t))) - (if (stringp form) ;Keyboard macro. - (execute-kbd-macro form) - (eval form)))))) - did-kill))) - - (defun gnus-execute (field regexp form &optional backward ignore-marked) - "If FIELD of article header matches REGEXP, execute lisp FORM (or a string). - If FIELD is an empty string (or nil), entire article body is searched for. - If optional 1st argument BACKWARD is non-nil, do backward instead. - If optional 2nd argument IGNORE-MARKED is non-nil, articles which are - marked as read or ticked are ignored." - (save-excursion - (let ((killed-no 0) - function header article) - (if (or (null field) (string-equal field "")) - (setq function nil) - ;; Get access function of header filed. - (setq function (intern-soft (concat "gnus-header-" (downcase field)))) - (if (and function (fboundp function)) - (setq function (symbol-function function)) - (error "Unknown header field: \"%s\"" field)) - ;; Make FORM funcallable. - (if (and (listp form) (not (eq (car form) 'lambda))) - (setq form (list 'lambda nil form)))) - ;; Starting from the current article. - (while (or (and (not article) - (setq article (gnus-summary-article-number)) - t) - (setq article - (gnus-summary-search-subject - backward (not ignore-marked)))) - (and (or (null gnus-newsgroup-kill-headers) - (memq article gnus-newsgroup-kill-headers)) - (gnus-execute-1 function regexp form - (gnus-get-header-by-number article)) - (setq killed-no (1+ killed-no)))) - killed-no))) - ;;; ;;; Gnus Score Files --- 9536,9541 ---- *************** *** 9869,9875 **** "Automatically expunge articles with score below SCORE." (interactive (list (or (and current-prefix-arg (prefix-numeric-value current-prefix-arg)) ! (string-to-int (read-string "Mark below: "))))) (setq score (or score gnus-summary-default-score 0)) (gnus-score-set 'expunge (list score)) (gnus-score-set 'touched '(t))) --- 9559,9565 ---- "Automatically expunge articles with score below SCORE." (interactive (list (or (and current-prefix-arg (prefix-numeric-value current-prefix-arg)) ! (string-to-int (read-string "Expunge below: "))))) (setq score (or score gnus-summary-default-score 0)) (gnus-score-set 'expunge (list score)) (gnus-score-set 'touched '(t))) *************** *** 9915,9922 **** (setq gnus-current-score-file file) (gnus-score-load-file file)) ! (defun gnus-score-edit-file (file) ! "Edit score file." (interactive (list gnus-current-score-file)) (and (buffer-name gnus-summary-buffer) (gnus-score-save)) (setq gnus-winconf-edit-score (current-window-configuration)) --- 9605,9612 ---- (setq gnus-current-score-file file) (gnus-score-load-file file)) ! (defun gnus-score-edit-alist (file) ! "Edit the current score alist." (interactive (list gnus-current-score-file)) (and (buffer-name gnus-summary-buffer) (gnus-score-save)) (setq gnus-winconf-edit-score (current-window-configuration)) *************** *** 9926,9942 **** "\\\\[gnus-score-edit-done] to save edits")) (gnus-score-mode)) (defun gnus-score-load-file (file) ;; Load score file FILE. Returns a list a retrieved score-alists. ! (let ((cached (assoc file gnus-score-cache)) ! (global (member file gnus-internal-global-score-files)) ! lists) (if cached ;; The score file was already loaded. (setq gnus-score-alist (cdr cached)) ;; We load the score file. (setq gnus-score-alist nil) ! (gnus-score-load-score-alist file) ;; We add '(touched) to the alist to signify that it hasn't been ;; touched (yet). (if (not (assq 'touched gnus-score-alist)) --- 9616,9646 ---- "\\\\[gnus-score-edit-done] to save edits")) (gnus-score-mode)) + (defun gnus-score-edit-file (file) + "Edit a score file." + (interactive + (list (read-file-name "Edit score file: " gnus-kill-files-directory))) + (and (buffer-name gnus-summary-buffer) (gnus-score-save)) + (setq gnus-winconf-edit-score (current-window-configuration)) + (gnus-configure-windows 'article) + (pop-to-buffer (find-file-noselect file)) + (message (substitute-command-keys + "\\\\[gnus-score-edit-done] to save edits")) + (gnus-score-mode)) + (defun gnus-score-load-file (file) ;; Load score file FILE. Returns a list a retrieved score-alists. ! (let* ((file (expand-file-name (or (and (string-match "^/" file) file) ! (concat gnus-kill-files-directory file)))) ! (cached (assoc file gnus-score-cache)) ! (global (member file gnus-internal-global-score-files)) ! lists alist) (if cached ;; The score file was already loaded. (setq gnus-score-alist (cdr cached)) ;; We load the score file. (setq gnus-score-alist nil) ! (setq alist (gnus-score-load-score-alist file)) ;; We add '(touched) to the alist to signify that it hasn't been ;; touched (yet). (if (not (assq 'touched gnus-score-alist)) *************** *** 9970,9979 **** (gnus-score-load-file file)) files)))) (and eval (not global) (eval eval)) ! (setq gnus-summary-mark-below (or mark mark-and-expunge ! gnus-summary-default-score)) (setq gnus-summary-expunge-below (or expunge mark-and-expunge))) (setq gnus-current-score-file file) lists)) (defun gnus-score-load (file) --- 9674,9683 ---- (gnus-score-load-file file)) files)))) (and eval (not global) (eval eval)) ! (setq gnus-summary-mark-below (or mark mark-and-expunge)) (setq gnus-summary-expunge-below (or expunge mark-and-expunge))) (setq gnus-current-score-file file) + (setq gnus-score-alist alist) lists)) (defun gnus-score-load (file) *************** *** 10053,10059 **** cache (cdr cache) file (car entry) score (cdr entry)) ! (if (or (not (eq (gnus-score-get 'touched score) '(t))) (gnus-score-get 'read-only score) (not (file-writable-p file))) () --- 9757,9763 ---- cache (cdr cache) file (car entry) score (cdr entry)) ! (if (or (not (equal (gnus-score-get 'touched score) '(t))) (gnus-score-get 'read-only score) (not (file-writable-p file))) () *************** *** 12196,12204 **** (progn (setq info (cdr entry)) (setq num (car entry))) ! (setq active (or (gnus-gethash group gnus-active-hashtb) ! '(0 . 0))) ! (setq num (- (1+ (cdr active)) (car active))) ;; Check whether the group is foreign. If so, the ;; foreign select method has to be entered into the ;; info. --- 11900,11907 ---- (progn (setq info (cdr entry)) (setq num (car entry))) ! (setq active (gnus-gethash group gnus-active-hashtb)) ! (setq num (if active (- (1+ (cdr active)) (car active)) t)) ;; Check whether the group is foreign. If so, the ;; foreign select method has to be entered into the ;; info. *************** *** 12376,12401 **** (t ;; The read list is a list of ranges. Fix them according to ;; the active hash table. ! (while (and (cdr range) (>= (car active) (car (car (cdr range))))) (setcdr (car range) (cdr (car (cdr range)))) (setcdr range (cdr (cdr range)))) ! (if (< (cdr (car range)) (car active)) (setcdr (car range) (car active))) (let ((srange range)) (while (and (cdr srange) ! (<= (car (car (cdr srange))) (cdr active))) (setq srange (cdr srange))) (if (cdr srange) ! (progn ! (setcdr srange nil) ! (if (> (cdr (car srange)) (cdr active)) ! (setcdr (car srange) (cdr active))))) ! (if (and srange (> (cdr (car srange)) (cdr active))) (setcdr (car srange) (cdr active)))) ;; Compute the number of unread articles. (while range ! (setq num (+ num (- (1+ (cdr (car range))) ! (car (car range))))) (setq range (cdr range))) (setq num (max 0 (- (cdr active) num))))) (and info --- 12079,12119 ---- (t ;; The read list is a list of ranges. Fix them according to ;; the active hash table. ! ;; First peel off any elements that are below the lower ! ;; active limit. ! (while (and (cdr range) ! (>= (car active) ! (or (and (atom (car (cdr range))) (car (cdr range))) ! (car (car (cdr range)))))) (setcdr (car range) (cdr (car (cdr range)))) (setcdr range (cdr (cdr range)))) ! ;; Adjust the first element to be the same as the lower limit. ! (if (and (not (atom (car range))) ! (< (cdr (car range)) (car active))) (setcdr (car range) (car active))) + ;; Then we want to peel off any elements that are higher + ;; than the upper active limit. (let ((srange range)) + ;; Go past all legal elements. (while (and (cdr srange) ! (<= (or (and (atom (car (cdr srange))) ! (car (cdr srange))) ! (car (car (cdr srange)))) (cdr active))) (setq srange (cdr srange))) (if (cdr srange) ! ;; Nuke all remaining illegal elements. ! (setcdr srange nil)) ! ! ;; Adjust the final element. ! (if (and (not (atom (car srange))) ! (> (cdr (car srange)) (cdr active))) (setcdr (car srange) (cdr active)))) ;; Compute the number of unread articles. (while range ! (setq num (+ num (- (1+ (or (and (atom (car range)) (car range)) ! (cdr (car range)))) ! (or (and (atom (car range)) (car range)) ! (car (car range)))))) (setq range (cdr range))) (setq num (max 0 (- (cdr active) num))))) (and info *************** *** 12472,12478 **** ;; unread articles. (while unread (if (/= (car unread) prev) ! (setq read (cons (cons prev (1- (car unread))) read))) (setq prev (1+ (car unread))) (setq unread (cdr unread))) (if (<= prev (cdr active)) --- 12190,12197 ---- ;; unread articles. (while unread (if (/= (car unread) prev) ! (setq read (cons (if (= prev (1- (car unread))) prev ! (cons prev (1- (car unread)))) read))) (setq prev (1+ (car unread))) (setq unread (cdr unread))) (if (<= prev (cdr active)) *************** *** 12634,12639 **** --- 12353,12359 ---- (condition-case nil (load ding-file t t t) (error nil)) + (gnus-uncompress-newsrc-assoc) (gnus-make-hashtable-from-newsrc-alist) (if (not (file-newer-than-file-p file ding-file)) () *************** *** 12688,12699 **** (if (file-exists-p real-file) real-file file))) ! ;; jwz: rewrote this function to be much more efficient, and not be subject ! ;; to regexp overflow errors when it encounters very long lines -- the old ! ;; behavior was to blow off the rest of the *file* when a line was encountered ! ;; that was too long to match!! Now it uses only simple looking-at calls, and ! ;; doesn't create as many temporary strings. It also now handles multiple ! ;; consecutive options lines (before it only handled the first.) ;; Tiny rewrite by lmi. (defun gnus-newsrc-to-gnus-format () "Parse current buffer as .newsrc file." --- 12408,12447 ---- (if (file-exists-p real-file) real-file file))) ! (defun gnus-uncompress-newsrc-assoc () ! ;; Uncompress all lists of marked articles in the newsrc assoc. ! (let ((newsrc gnus-newsrc-assoc) ! marked) ! (while newsrc ! (if (not (setq marked (nth 3 (car newsrc)))) ! () ! (while marked ! (or (eq 'score (car (car marked))) ! (setcdr (car marked) (gnus-uncompress-range (cdr (car marked))))) ! (setq marked (cdr marked)))) ! (setq newsrc (cdr newsrc))))) ! ! (defun gnus-compress-newsrc-assoc () ! ;; Compress all lists of marked articles in the newsrc assoc. ! (let ((newsrc gnus-newsrc-assoc) ! marked) ! (while newsrc ! (if (not (setq marked (nth 3 (car newsrc)))) ! () ! (while marked ! (or (eq 'score (car (car marked))) ! (setcdr (car marked) ! (gnus-compress-sequence (sort (cdr (car marked)) '<) t))) ! (setq marked (cdr marked)))) ! (setq newsrc (cdr newsrc))))) ! ! ;; jwz: rewrote this function to be much more efficient, and not be ! ;; subject to regexp overflow errors when it encounters very long ! ;; lines -- the old behavior was to blow off the rest of the *file* ! ;; when a line was encountered that was too long to match!! Now it ! ;; uses only simple looking-at calls, and doesn't create as many ! ;; temporary strings. It also now handles multiple consecutive ! ;; options lines (before it only handled the first.) ;; Tiny rewrite by lmi. (defun gnus-newsrc-to-gnus-format () "Parse current buffer as .newsrc file." *************** *** 12703,12709 **** (setq gnus-newsrc-options nil) (setq gnus-newsrc-options-n-yes nil) (setq gnus-newsrc-options-n-no nil) - (setq gnus-newsrc-assoc nil) (gnus-parse-options-lines) (gnus-parse-newsrc-body)) --- 12451,12456 ---- *************** *** 12855,12869 **** (if info (progn (setcar (nthcdr 2 info) (nreverse read-list)) ! (setcar (cdr info) (if subscribe 3 (if read-list 6 7))) ! (setq gnus-newsrc-assoc (cons info gnus-newsrc-assoc))) (setq gnus-newsrc-assoc (cons (list newsgroup (if subscribe 3 (if read-list 6 7)) (nreverse read-list)) gnus-newsrc-assoc)))))) (setq line (1+ line)) (forward-line 1)))) ! (setq gnus-newsrc-assoc (nreverse gnus-newsrc-assoc)) (gnus-make-hashtable-from-newsrc-alist) nil) --- 12602,12615 ---- (if info (progn (setcar (nthcdr 2 info) (nreverse read-list)) ! (setcar (cdr info) (if subscribe 3 (if read-list 6 7)))) (setq gnus-newsrc-assoc (cons (list newsgroup (if subscribe 3 (if read-list 6 7)) (nreverse read-list)) gnus-newsrc-assoc)))))) (setq line (1+ line)) (forward-line 1)))) ! (setq gnus-newsrc-assoc (cdr gnus-newsrc-assoc)) (gnus-make-hashtable-from-newsrc-alist) nil) *************** *** 12969,12974 **** --- 12715,12721 ---- (gnus-newsrc-assoc (cdr gnus-newsrc-assoc)) variable) ;; insert lisp expressions. + (gnus-compress-newsrc-assoc) (while variables (setq variable (car variables)) (and (boundp variable) *************** *** 12977,12983 **** (insert "(setq " (symbol-name variable) " '" (prin1-to-string (symbol-value variable)) ")\n")) ! (setq variables (cdr variables))))) (defun gnus-gnus-to-newsrc-format () ;; Generate and save the .newsrc file. --- 12724,12732 ---- (insert "(setq " (symbol-name variable) " '" (prin1-to-string (symbol-value variable)) ")\n")) ! (setq variables (cdr variables))) ! (gnus-uncompress-newsrc-assoc))) ! (defun gnus-gnus-to-newsrc-format () ;; Generate and save the .newsrc file. *************** *** 12998,13004 **** (if (setq ranges (nth 2 info)) (progn (insert " ") ! (if (atom (car ranges)) (if (= (car ranges) (cdr ranges)) (insert (int-to-string (car ranges))) (insert (int-to-string (car ranges)) "-" --- 12747,12753 ---- (if (setq ranges (nth 2 info)) (progn (insert " ") ! (if (not (listp (cdr ranges))) (if (= (car ranges) (cdr ranges)) (insert (int-to-string (car ranges))) (insert (int-to-string (car ranges)) "-" *************** *** 13006,13013 **** (while ranges (setq range (car ranges) ranges (cdr ranges)) ! (if (= (car range) (cdr range)) ! (insert (int-to-string (car range))) (insert (int-to-string (car range)) "-" (int-to-string (cdr range)))) (if ranges (insert ",")))))) --- 12755,12764 ---- (while ranges (setq range (car ranges) ranges (cdr ranges)) ! (if (or (atom range) (= (car range) (cdr range))) ! (insert (int-to-string ! (or (and (atom range) range) ! (car range)))) (insert (int-to-string (car range)) "-" (int-to-string (cdr range)))) (if ranges (insert ",")))))) diff --exclude=*.elc --exclude=*~ --exclude=*-[0-9] --exclude=gnus --context --recursive pub/dgnus/lisp/nnbabyl.el dgnus/lisp/nnbabyl.el *** pub/dgnus/lisp/nnbabyl.el Thu Mar 23 13:31:01 1995 --- dgnus/lisp/nnbabyl.el Fri Mar 24 12:13:46 1995 *************** *** 23,28 **** --- 23,31 ---- ;;; Commentary: + ;; For an overview of what the interface functions do, please see the + ;; Gnus sources. + ;;; Code: (require 'nnheader) *************** *** 57,64 **** ;;; Interface functions (defun nnbabyl-retrieve-headers (sequence &optional newsgroup server) - "Retrieve the headers for the articles in SEQUENCE. - Newsgroup must be selected before calling this function." (save-excursion (set-buffer nntp-server-buffer) (erase-buffer) --- 60,65 ---- *************** *** 111,137 **** 'headers))) (defun nnbabyl-open-server (host &optional service) - "Open mbox backend." (setq nnbabyl-status-string "") (setq nnbabyl-group-alist nil) (nnheader-init-server-buffer)) (defun nnbabyl-close-server (&optional server) - "Close news server." t) (defun nnbabyl-server-opened (&optional server) - "Return server process status, T or NIL. - If the stream is opened, return T, otherwise return NIL." (and nntp-server-buffer (get-buffer nntp-server-buffer))) (defun nnbabyl-status-message (&optional server) - "Return server status response as string." nnbabyl-status-string) (defun nnbabyl-request-article (article &optional newsgroup server buffer) - "Select ARTICLE by number." (nnbabyl-possibly-change-newsgroup newsgroup) (if (stringp article) nil --- 112,132 ---- *************** *** 162,168 **** t)))))) (defun nnbabyl-request-group (group &optional server dont-check) - "Select news GROUP." (save-excursion (if (nnbabyl-possibly-change-newsgroup group) (if dont-check --- 157,162 ---- *************** *** 184,214 **** t) (defun nnbabyl-request-list (&optional server) - "List active newsgoups." (if server (nnbabyl-get-new-mail)) (nnmail-find-file nnbabyl-active-file)) (defun nnbabyl-request-newgroups (date &optional server) - "List groups created after DATE." (nnbabyl-request-list server)) (defun nnbabyl-request-list-newsgroups (&optional server) - "List newsgroups (defined in NNTP2)." (setq nnbabyl-status-string "nnbabyl: LIST NEWSGROUPS is not implemented.") nil) (defun nnbabyl-request-post (&optional server) - "Post a new news in current buffer." (mail-send-and-exit nil)) (fset 'nnbabyl-request-post-buffer 'nnmail-request-post-buffer) (defun nnbabyl-request-expire-articles (articles newsgroup &optional server force) - "Expire all articles in the ARTICLES list in group GROUP. - The list of unexpired articles will be returned (ie. all articles that - were too fresh to be expired). - If FORCE is non-nil, the ARTICLES will be deleted without looking at - the date." (nnbabyl-possibly-change-newsgroup newsgroup) (let* ((days (or (and nnmail-expiry-wait-function (funcall nnmail-expiry-wait-function newsgroup)) --- 178,199 ---- *************** *** 232,237 **** --- 217,230 ---- (setq rest (cons (car articles) rest)))) (setq articles (cdr articles))) (save-buffer) + ;; Find the lowest active article in this group. + (let ((active (nth 1 (assoc newsgroup nnbabyl-group-alist)))) + (goto-char (point-min)) + (while (not (search-forward + (nnbabyl-article-string (car active)) nil t)) + (setcar (car active) (1+ (car active))) + (goto-char (point-min)))) + (nnmail-save-active nnbabyl-group-alist nnbabyl-active-file) rest))) (defun nnbabyl-request-move-article *************** *** 300,309 **** ;;; Low-Level Interface (defun nnbabyl-delete-mail (&optional force leave-delim) - "If FORCE, delete article no matter how many X-Gnus-Newsgroup - headers there are. If LEAVE-DELIM, don't delete the Unix mbox - delimeter line." ;; Delete the current X-Gnus-Newsgroup line. (or force (delete-region --- 293,302 ---- ;;; Low-Level Interface + ;; If FORCE, delete article no matter how many X-Gnus-Newsgroup + ;; headers there are. If LEAVE-DELIM, don't delete the Unix mbox + ;; delimeter line. (defun nnbabyl-delete-mail (&optional force leave-delim) ;; Delete the current X-Gnus-Newsgroup line. (or force (delete-region *************** *** 348,354 **** (int-to-string article))) (defun nnbabyl-save-mail () ! "Called narrowed to an article." (let ((group-art (nreverse (nnmail-article-group 'nnbabyl-active-number)))) (nnmail-insert-lines) (nnmail-insert-xref group-art) --- 341,347 ---- (int-to-string article))) (defun nnbabyl-save-mail () ! ;; Called narrowed to an article. (let ((group-art (nreverse (nnmail-article-group 'nnbabyl-active-number)))) (nnmail-insert-lines) (nnmail-insert-xref group-art) *************** *** 372,378 **** (setq group-art (cdr group-art))))))) (defun nnbabyl-active-number (group) ! "Find the next article number in GROUP." (let ((active (car (cdr (assoc group nnbabyl-group-alist))))) (setcdr active (1+ (cdr active))) (cdr active))) --- 365,371 ---- (setq group-art (cdr group-art))))))) (defun nnbabyl-active-number (group) ! ;; Find the next article number in GROUP. (let ((active (car (cdr (assoc group nnbabyl-group-alist))))) (setcdr active (1+ (cdr active))) (cdr active))) diff --exclude=*.elc --exclude=*~ --exclude=*-[0-9] --exclude=gnus --context --recursive pub/dgnus/lisp/nndigest.el dgnus/lisp/nndigest.el *** pub/dgnus/lisp/nndigest.el Thu Mar 23 13:31:01 1995 --- dgnus/lisp/nndigest.el Fri Mar 24 12:13:59 1995 *************** *** 69,74 **** --- 69,75 ---- (forward-char -1) (goto-char (point-max)) (insert "\n\n")) + (insert (format "Lines: %d\n" (count-lines (point) (point-max)))) (insert ".\n") (delete-region (point) (point-max)))) (setq sequence (cdr sequence))) *************** *** 194,202 **** (narrow-to-region (point) (or (and (re-search-forward nndigest-separator nil t) ! (progn ! (beginning-of-line) ! (point))) (point-max))) (cons (point-min) (point-max))) nil))) --- 195,201 ---- (narrow-to-region (point) (or (and (re-search-forward nndigest-separator nil t) ! (match-beginning 0)) (point-max))) (cons (point-min) (point-max))) nil))) diff --exclude=*.elc --exclude=*~ --exclude=*-[0-9] --exclude=gnus --context --recursive pub/dgnus/lisp/nndoc.el dgnus/lisp/nndoc.el *** pub/dgnus/lisp/nndoc.el Thu Mar 23 13:31:01 1995 --- dgnus/lisp/nndoc.el Fri Mar 24 12:13:57 1995 *************** *** 52,58 **** (let ((file nil) (number (length sequence)) (count 0) ! beg article art-string start stop) (nndoc-possibly-change-buffer newsgroup server) (while sequence (setq article (car sequence)) --- 52,58 ---- (let ((file nil) (number (length sequence)) (count 0) ! beg article art-string start stop lines) (nndoc-possibly-change-buffer newsgroup server) (while sequence (setq article (car sequence)) *************** *** 66,77 **** --- 66,85 ---- (concat "^" rmail-unix-mail-delimiter) nil t) (point-min)))) (search-forward "\n\n" nil t) + (setq lines (count-lines + (point) + (or + (save-excursion + (re-search-forward + (concat "^" rmail-unix-mail-delimiter) nil t)) + (point-max)))) (setq stop (1- (point))) (set-buffer nntp-server-buffer) (insert (format "221 %d Article retrieved.\n" article)) (setq beg (point)) (insert-buffer-substring nndoc-current-buffer start stop) (goto-char (point-max)) + (insert (format "Lines: %d\n" lines)) (insert ".\n"))) (setq sequence (cdr sequence))) diff --exclude=*.elc --exclude=*~ --exclude=*-[0-9] --exclude=gnus --context --recursive pub/dgnus/lisp/nnfolder.el dgnus/lisp/nnfolder.el *** pub/dgnus/lisp/nnfolder.el Thu Mar 23 13:31:01 1995 --- dgnus/lisp/nnfolder.el Fri Mar 24 12:13:46 1995 *************** *** 23,28 **** --- 23,31 ---- ;;; Commentary: + ;; For an overview of what the interface functions do, please see the + ;; Gnus sources. + ;;; Code: (require 'nnheader) *************** *** 55,62 **** ;;; Interface functions (defun nnfolder-retrieve-headers (sequence &optional newsgroup server) - "Retrieve the headers for the articles in SEQUENCE. - Newsgroup must be selected before calling this function." (save-excursion (set-buffer nntp-server-buffer) (erase-buffer) --- 58,63 ---- *************** *** 94,120 **** 'headers))) (defun nnfolder-open-server (host &optional service) - "Open mbox backend." (setq nnfolder-status-string "") (setq nnfolder-group-alist nil) (nnheader-init-server-buffer)) (defun nnfolder-close-server (&optional server) - "Close news server." t) (defun nnfolder-server-opened (&optional server) - "Return server process status, T or NIL. - If the stream is opened, return T, otherwise return NIL." (and nntp-server-buffer (buffer-name nntp-server-buffer))) (defun nnfolder-status-message (&optional server) - "Return server status response as string." nnfolder-status-string) (defun nnfolder-request-article (article &optional newsgroup server buffer) - "Select ARTICLE by number." (nnfolder-possibly-change-group newsgroup) (if (stringp article) nil --- 95,115 ---- *************** *** 143,149 **** t)))))) (defun nnfolder-request-group (group &optional server dont-check) - "Select news GROUP." (save-excursion (nnfolder-possibly-change-group group) (and (assoc group nnfolder-group-alist) --- 138,143 ---- *************** *** 166,172 **** t) (defun nnfolder-request-list (&optional server) - "List active newsgoups." (if server (nnfolder-get-new-mail)) (or (nnmail-find-file nnfolder-active-file) (progn --- 160,165 ---- *************** *** 175,199 **** (nnmail-find-file nnfolder-active-file)))) (defun nnfolder-request-newgroups (date &optional server) - "List groups created after DATE." (nnfolder-request-list server)) (defun nnfolder-request-list-newsgroups (&optional server) - "List newsgroups (defined in NNTP2)." (nnmail-find-file nnfolder-newsgroups-file)) (defun nnfolder-request-post (&optional server) - "Post a new news in current buffer." (mail-send-and-exit nil)) (fset 'nnfolder-request-post-buffer 'nnmail-request-post-buffer) (defun nnfolder-request-expire-articles (articles newsgroup &optional server force) - "Expire all articles in the ARTICLES list in group GROUP. - The list of unexpired articles will be returned (ie. all articles that - were too fresh to be expired). - If FORCE is non-nil, the ARTICLES will be deleted without looking at - the date." (nnfolder-possibly-change-group newsgroup) (let* ((days (or (and nnmail-expiry-wait-function (funcall nnmail-expiry-wait-function newsgroup)) --- 168,184 ---- *************** *** 217,222 **** --- 202,215 ---- (setq rest (cons (car articles) rest)))) (setq articles (cdr articles))) (save-buffer) + ;; Find the lowest active article in this group. + (let ((active (nth 1 (assoc newsgroup nnfolder-group-alist)))) + (goto-char (point-min)) + (while (not (search-forward + (nnfolder-article-string (car active)) nil t)) + (setcar (car active) (1+ (car active))) + (goto-char (point-min)))) + (nnmail-save-active nnfolder-group-alist nnfolder-active-file) rest))) (defun nnfolder-request-move-article *************** *** 253,259 **** (nnfolder-possibly-change-group group) (let ((buf (current-buffer)) result beg) - (debug (current-buffer)) (goto-char (point-min)) (if (looking-at "X-From-Line: ") (replace-match "From ") --- 246,251 ---- *************** *** 293,301 **** ;;; Internal functions. (defun nnfolder-delete-mail (&optional force leave-delim) - "If FORCE, delete article no matter how many X-Gnus-Newsgroup - headers there are. If LEAVE-DELIM, don't delete the Unix mbox - delimeter line." ;; Beginning of the article. (save-excursion (save-restriction --- 285,290 ---- *************** *** 388,394 **** (cdr group-art) (current-time-string))))))) (defun nnfolder-active-number (group) - "Find the next article number in GROUP." (let ((active (car (cdr (assoc group nnfolder-group-alist))))) (setcdr active (1+ (cdr active))) (cdr active))) --- 377,382 ---- *************** *** 418,423 **** --- 406,412 ---- (save-excursion (save-restriction (narrow-to-region start end) + (nnmail-insert-lines) (nnfolder-insert-newsgroup-line (cons nil (nnfolder-active-number nnfolder-current-group)))))) (goto-char end))) diff --exclude=*.elc --exclude=*~ --exclude=*-[0-9] --exclude=gnus --context --recursive pub/dgnus/lisp/nnheader.el dgnus/lisp/nnheader.el *** pub/dgnus/lisp/nnheader.el Thu Mar 23 13:31:01 1995 --- dgnus/lisp/nnheader.el Fri Mar 24 13:21:39 1995 *************** *** 136,141 **** --- 136,143 ---- (defvar news-reply-yank-from nil) (defvar news-reply-yank-message-id nil) + ;; All backends use this function, so I moved it to this file. + (defun nnheader-init-server-buffer () (save-excursion (setq nntp-server-buffer (get-buffer-create " *nntpd*")) diff --exclude=*.elc --exclude=*~ --exclude=*-[0-9] --exclude=gnus --context --recursive pub/dgnus/lisp/nnmail.el dgnus/lisp/nnmail.el *** pub/dgnus/lisp/nnmail.el Thu Mar 23 13:31:01 1995 --- dgnus/lisp/nnmail.el Thu Mar 23 14:52:51 1995 *************** *** 78,93 **** Eg.: (setq nnmail-expiry-wait-function ! (function ! (lambda (newsgroup) ! (cond ((string-match \"private\" newsgroup) 31) ! ((string-match \"junk\" newsgroup) 1) ! (t 7)))))") (defvar nnmail-spool-file (or (getenv "MAIL") (concat "/usr/spool/mail/" (user-login-name))) "Where the mail backends will look for incoming mail. If this variable is nil, no mail backends will read incoming mail.") (defvar nnmail-read-incoming-hook nil --- 78,93 ---- Eg.: (setq nnmail-expiry-wait-function ! (lambda (newsgroup) ! (cond ((string-match \"private\" newsgroup) 31) ! ((string-match \"junk\" newsgroup) 1) ! (t 7))))") (defvar nnmail-spool-file (or (getenv "MAIL") (concat "/usr/spool/mail/" (user-login-name))) "Where the mail backends will look for incoming mail. + This variable is \"/usr/spool/mail/$user\" by default. If this variable is nil, no mail backends will read incoming mail.") (defvar nnmail-read-incoming-hook nil *************** *** 101,116 **** Eg. (add-hook 'nnmail-read-incoming-hook - (function (lambda () (start-process \"mailsend\" nil ! \"/local/bin/mailsend\" \"read\" \"mbox\"))))") ;; Suggested by Erik Selberg . (defvar nnmail-prepare-incoming-hook nil "Hook called before treating incoming mail. The hook is run in a buffer with all the new, incoming mail.") (defvar nnmail-large-newsgroup 50 "The number of the articles which indicates a large newsgroup. If the number of the articles is greater than the value, verbose --- 101,119 ---- Eg. (add-hook 'nnmail-read-incoming-hook (lambda () (start-process \"mailsend\" nil ! \"/local/bin/mailsend\" \"read\" \"mbox\")))") ;; Suggested by Erik Selberg . (defvar nnmail-prepare-incoming-hook nil "Hook called before treating incoming mail. The hook is run in a buffer with all the new, incoming mail.") + ;; Suggested by Mejia Pablo J . + (defvar nnmail-tmp-directory nil + "If non-nil, use this directory for temporary storage when reading incoming mail.") + (defvar nnmail-large-newsgroup 50 "The number of the articles which indicates a large newsgroup. If the number of the articles is greater than the value, verbose *************** *** 229,234 **** --- 232,241 ---- (expand-file-name (substitute-in-file-name inbox)))) (tofile (make-temp-name (expand-file-name tofile))) movemail popmail errors) + ;; Check whether the inbox is to be moved to the special tmp dir. + (if nnmail-tmp-directory + (setq tofile (concat (file-name-as-directory nnmail-tmp-directory) + (file-name-nondirectory tofile)))) ;; If getting from mail spool directory, ;; use movemail to move rather than just renaming, ;; so as to interlock with the mailer. diff --exclude=*.elc --exclude=*~ --exclude=*-[0-9] --exclude=gnus --context --recursive pub/dgnus/lisp/nnmbox.el dgnus/lisp/nnmbox.el *** pub/dgnus/lisp/nnmbox.el Thu Mar 23 13:31:01 1995 --- dgnus/lisp/nnmbox.el Fri Mar 24 12:13:47 1995 *************** *** 23,28 **** --- 23,31 ---- ;;; Commentary: + ;; For an overview of what the interface functions do, please see the + ;; Gnus sources. + ;;; Code: (require 'nnheader) *************** *** 55,62 **** ;;; Interface functions (defun nnmbox-retrieve-headers (sequence &optional newsgroup server) - "Retrieve the headers for the articles in SEQUENCE. - Newsgroup must be selected before calling this function." (save-excursion (set-buffer nntp-server-buffer) (erase-buffer) --- 58,63 ---- *************** *** 107,133 **** 'headers))) (defun nnmbox-open-server (host &optional service) - "Open mbox backend." (setq nnmbox-status-string "") (setq nnmbox-group-alist nil) (nnheader-init-server-buffer)) (defun nnmbox-close-server (&optional server) - "Close news server." t) (defun nnmbox-server-opened (&optional server) - "Return server process status, T or NIL. - If the stream is opened, return T, otherwise return NIL." (and nntp-server-buffer (get-buffer nntp-server-buffer))) (defun nnmbox-status-message (&optional server) - "Return server status response as string." nnmbox-status-string) (defun nnmbox-request-article (article &optional newsgroup server buffer) - "Select ARTICLE by number." (nnmbox-possibly-change-newsgroup newsgroup) (if (stringp article) nil --- 108,128 ---- *************** *** 156,162 **** t)))))) (defun nnmbox-request-group (group &optional server dont-check) - "Select news GROUP." (save-excursion (if (nnmbox-possibly-change-newsgroup group) (if dont-check --- 151,156 ---- *************** *** 178,184 **** t) (defun nnmbox-request-list (&optional server) - "List active newsgoups." (if server (nnmbox-get-new-mail)) (or (nnmail-find-file nnmbox-active-file) (progn --- 172,177 ---- *************** *** 187,212 **** (nnmail-find-file nnmbox-active-file)))) (defun nnmbox-request-newgroups (date &optional server) - "List groups created after DATE." (nnmbox-request-list server)) (defun nnmbox-request-list-newsgroups (&optional server) - "List newsgroups (defined in NNTP2)." (setq nnmbox-status-string "nnmbox: LIST NEWSGROUPS is not implemented.") nil) (defun nnmbox-request-post (&optional server) - "Post a new news in current buffer." (mail-send-and-exit nil)) (fset 'nnmbox-request-post-buffer 'nnmail-request-post-buffer) ! (defun nnmbox-request-expire-articles (articles newsgroup &optional server force) ! "Expire all articles in the ARTICLES list in group GROUP. ! The list of unexpired articles will be returned (ie. all articles that ! were too fresh to be expired). ! If FORCE is non-nil, the ARTICLES will be deleted without looking at ! the date." (nnmbox-possibly-change-newsgroup newsgroup) (let* ((days (or (and nnmail-expiry-wait-function (funcall nnmail-expiry-wait-function newsgroup)) --- 180,198 ---- (nnmail-find-file nnmbox-active-file)))) (defun nnmbox-request-newgroups (date &optional server) (nnmbox-request-list server)) (defun nnmbox-request-list-newsgroups (&optional server) (setq nnmbox-status-string "nnmbox: LIST NEWSGROUPS is not implemented.") nil) (defun nnmbox-request-post (&optional server) (mail-send-and-exit nil)) (fset 'nnmbox-request-post-buffer 'nnmail-request-post-buffer) ! (defun nnmbox-request-expire-articles ! (articles newsgroup &optional server force) (nnmbox-possibly-change-newsgroup newsgroup) (let* ((days (or (and nnmail-expiry-wait-function (funcall nnmail-expiry-wait-function newsgroup)) *************** *** 230,235 **** --- 216,229 ---- (setq rest (cons (car articles) rest)))) (setq articles (cdr articles))) (save-buffer) + ;; Find the lowest active article in this group. + (let ((active (nth 1 (assoc newsgroup nnmbox-group-alist)))) + (goto-char (point-min)) + (while (not (search-forward + (nnmbox-article-string (car active)) nil t)) + (setcar (car active) (1+ (car active))) + (goto-char (point-min)))) + (nnmail-save-active nnmbox-group-alist nnmbox-active-file) rest))) (defun nnmbox-request-move-article *************** *** 264,270 **** (defun nnmbox-request-accept-article (group &optional last) (let ((buf (current-buffer)) result beg) - (debug (current-buffer)) (goto-char (point-min)) (if (looking-at "X-From-Line: ") (replace-match "From ") --- 258,263 ---- *************** *** 303,312 **** ;;; Internal functions. (defun nnmbox-delete-mail (&optional force leave-delim) - "If FORCE, delete article no matter how many X-Gnus-Newsgroup - headers there are. If LEAVE-DELIM, don't delete the Unix mbox - delimeter line." ;; Delete the current X-Gnus-Newsgroup line. (or force (delete-region --- 296,305 ---- ;;; Internal functions. + ;; If FORCE, delete article no matter how many X-Gnus-Newsgroup + ;; headers there are. If LEAVE-DELIM, don't delete the Unix mbox + ;; delimeter line. (defun nnmbox-delete-mail (&optional force leave-delim) ;; Delete the current X-Gnus-Newsgroup line. (or force (delete-region diff --exclude=*.elc --exclude=*~ --exclude=*-[0-9] --exclude=gnus --context --recursive pub/dgnus/lisp/nnmh.el dgnus/lisp/nnmh.el *** pub/dgnus/lisp/nnmh.el Thu Mar 23 13:31:01 1995 --- dgnus/lisp/nnmh.el Fri Mar 24 12:13:50 1995 *************** *** 24,29 **** --- 24,31 ---- ;;; Commentary: ;; Based on nnspool.el by Masanobu UMEDA . + ;; For an overview of what the interface functions do, please see the + ;; Gnus sources. ;;; Code: *************** *** 55,62 **** ;;; Interface functions. (defun nnmh-retrieve-headers (sequence &optional newsgroup server) - "Retrieve the headers for the articles in SEQUENCE. - Newsgroup must be selected before calling this function." (save-excursion (set-buffer nntp-server-buffer) (erase-buffer) --- 57,62 ---- *************** *** 80,85 **** --- 80,86 ---- (forward-char -1) (goto-char (point-max)) (insert "\n\n")) + (insert (format "Lines: %d\n" (count-lines (point) (point-max)))) (insert ".\n") (delete-region (point) (point-max)))) (setq sequence (cdr sequence)) *************** *** 101,126 **** 'headers))) (defun nnmh-open-server (host &optional service) - "Open nnmh mail backend." (setq nnmh-status-string "") (nnheader-init-server-buffer)) (defun nnmh-close-server (&optional server) - "Close news server." t) (defun nnmh-server-opened (&optional server) - "Return server process status, T or NIL. - If the stream is opened, return T, otherwise return NIL." (and nntp-server-buffer (get-buffer nntp-server-buffer))) (defun nnmh-status-message (&optional server) - "Return server status response as string." nnmh-status-string) (defun nnmh-request-article (id &optional newsgroup server buffer) - "Select article by message ID (or number)." (nnmh-possibly-change-directory newsgroup) (let ((file (if (stringp id) nil --- 102,121 ---- *************** *** 133,139 **** (nnmail-find-file file))))) (defun nnmh-request-group (group &optional server dont-check) - "Select news GROUP." (and nnmh-get-new-mail (or dont-check (nnmh-get-new-mail))) (let ((pathname (nnmail-article-pathname group nnmh-directory)) dir) --- 128,133 ---- *************** *** 165,171 **** t)))) (defun nnmh-request-list (&optional server dir) - "Get list of active articles in all newsgroups." (and server nnmh-get-new-mail (nnmh-get-new-mail)) (or dir (save-excursion --- 159,164 ---- *************** *** 200,219 **** t) (defun nnmh-request-newgroups (date &optional server) - "List groups created after DATE." (nnmh-request-list server)) (defun nnmh-request-post (&optional server) - "Post a new news in current buffer." (mail-send-and-exit nil)) (fset 'nnmh-request-post-buffer 'nnmail-request-post-buffer) (defun nnmh-request-expire-articles (articles newsgroup &optional server force) - "Expire all articles in the ARTICLES list in group GROUP. - The list of unexpired articles will be returned (ie. all articles that - were too fresh to be expired). - If FORCE is non-nil, ARTICLES will be deleted whether they are old or not." (nnmh-possibly-change-directory newsgroup) (let* ((days (or (and nnmail-expiry-wait-function (funcall nnmail-expiry-wait-function newsgroup)) --- 193,206 ---- *************** *** 355,366 **** (defun nnmh-get-new-mail () "Read new incoming mail." (let (incoming) - (nnmh-create-directories) (if (and nnmh-get-new-mail nnmail-spool-file (file-exists-p nnmail-spool-file) (> (nth 7 (file-attributes nnmail-spool-file)) 0)) (progn (message "nnmh: Reading incoming mail...") (setq incoming (nnmail-move-inbox nnmail-spool-file (concat nnmh-directory "Incoming"))) --- 342,353 ---- (defun nnmh-get-new-mail () "Read new incoming mail." (let (incoming) (if (and nnmh-get-new-mail nnmail-spool-file (file-exists-p nnmail-spool-file) (> (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"))) diff --exclude=*.elc --exclude=*~ --exclude=*-[0-9] --exclude=gnus --context --recursive pub/dgnus/lisp/nnml.el dgnus/lisp/nnml.el *** pub/dgnus/lisp/nnml.el Thu Mar 23 13:31:01 1995 --- dgnus/lisp/nnml.el Fri Mar 24 12:13:51 1995 *************** *** 24,29 **** --- 24,31 ---- ;;; Commentary: ;; Based on nnspool.el by Masanobu UMEDA . + ;; For an overview of what the interface functions do, please see the + ;; Gnus sources. ;;; Code: *************** *** 71,78 **** ;;; Interface functions. (defun nnml-retrieve-headers (sequence &optional newsgroup server) - "Retrieve the headers for the articles in SEQUENCE. - Newsgroup must be selected before calling this function." (save-excursion (set-buffer nntp-server-buffer) (erase-buffer) --- 73,78 ---- *************** *** 125,145 **** (nnheader-init-server-buffer)) (defun nnml-close-server (&optional server) - "Close news server." t) (defun nnml-server-opened (&optional server) - "Return server process status, T or NIL. - If the stream is opened, return T, otherwise return NIL." (and nntp-server-buffer (get-buffer nntp-server-buffer))) (defun nnml-status-message (&optional server) - "Return server status response as string." nnml-status-string) (defun nnml-request-article (id &optional newsgroup server buffer) - "Select article by message ID (or number)." (nnml-possibly-change-directory newsgroup) (let ((file (if (stringp id) nil --- 125,140 ---- *************** *** 152,158 **** (nnmail-find-file file))))) (defun nnml-request-group (group &optional server dont-check) - "Select news GROUP." (if (not (nnml-possibly-change-directory group)) (progn (setq nnml-status-string "Invalid group (no such directory)") --- 147,152 ---- *************** *** 183,240 **** t) (defun nnml-request-list (&optional server) - "List active newsgoups." (if server (nnml-get-new-mail)) (save-excursion (nnmail-find-file nnml-active-file))) (defun nnml-request-newgroups (date &optional server) - "List groups created after DATE." (nnml-request-list server)) (defun nnml-request-list-newsgroups (&optional server) - "List newsgroups (defined in NNTP2)." (save-excursion (nnmail-find-file nnml-newsgroups-file))) (defun nnml-request-post (&optional server) - "Post a new news in current buffer." (mail-send-and-exit nil)) (fset 'nnml-request-post-buffer 'nnmail-request-post-buffer) (defun nnml-request-expire-articles (articles newsgroup &optional server force) - "Expire all articles in the ARTICLES list in group GROUP. - The list of unexpired articles will be returned (ie. all articles that - were too fresh to be expired). - If FORCE is non-nil, ARTICLES will be deleted whether they are old or not." (nnml-possibly-change-directory newsgroup) (let* ((days (or (and nnmail-expiry-wait-function (funcall nnmail-expiry-wait-function newsgroup)) nnmail-expiry-wait)) article rest mod-time) - (if nnmail-keep-last-article - (progn - (setq articles (sort articles '>)) - (setq rest (cons (car articles) rest)) - (setq articles (cdr articles)))) (while articles (setq article (concat nnml-current-directory (int-to-string (car articles)))) (if (setq mod-time (nth 5 (file-attributes article))) ! (if (or force ! (> (nnmail-days-between ! (current-time-string) ! (current-time-string mod-time)) ! days)) (progn (and gnus-verbose-backends (message "Deleting %s..." article)) (condition-case () (delete-file article) (file-error nil)) (nnml-nov-delete-article newsgroup (car articles))) (setq rest (cons (car articles) rest)))) (setq articles (cdr articles))) (nnml-save-nov) rest)) --- 177,234 ---- t) (defun nnml-request-list (&optional server) (if server (nnml-get-new-mail)) (save-excursion (nnmail-find-file nnml-active-file))) (defun nnml-request-newgroups (date &optional server) (nnml-request-list server)) (defun nnml-request-list-newsgroups (&optional server) (save-excursion (nnmail-find-file nnml-newsgroups-file))) (defun nnml-request-post (&optional server) (mail-send-and-exit nil)) (fset 'nnml-request-post-buffer 'nnmail-request-post-buffer) (defun nnml-request-expire-articles (articles newsgroup &optional server force) (nnml-possibly-change-directory newsgroup) (let* ((days (or (and nnmail-expiry-wait-function (funcall nnmail-expiry-wait-function newsgroup)) nnmail-expiry-wait)) + (active-articles + (mapcar + (function + (lambda (name) + (string-to-int name))) + (directory-files nnml-current-directory nil "^[0-9]+$" t))) + (max-article (max active-articles)) article rest mod-time) (while articles (setq article (concat nnml-current-directory (int-to-string (car articles)))) (if (setq mod-time (nth 5 (file-attributes article))) ! (if (and (or (not nnmail-keep-last-article) ! (not (= (car articles) max-article))) ! (or force ! (> (nnmail-days-between ! (current-time-string) ! (current-time-string mod-time)) ! days))) (progn (and gnus-verbose-backends (message "Deleting %s..." article)) (condition-case () (delete-file article) (file-error nil)) + (setq active-articles (delq (car articles) active-articles)) (nnml-nov-delete-article newsgroup (car articles))) (setq rest (cons (car articles) rest)))) (setq articles (cdr articles))) + (let ((active (nth 1 (assoc newsgroup nnml-group-alist)))) + (setcar active (min active-articles)) + (nnmail-save-active nnml-group-alist nnml-active-file)) (nnml-save-nov) rest)) diff --exclude=*.elc --exclude=*~ --exclude=*-[0-9] --exclude=gnus --context --recursive pub/dgnus/lisp/nntp.el dgnus/lisp/nntp.el *** pub/dgnus/lisp/nntp.el Thu Mar 23 13:31:01 1995 --- dgnus/lisp/nntp.el Fri Mar 24 13:21:26 1995 *************** *** 185,193 **** 'headers)))) (defun nntp-open-server (server &optional service) ! "Open news server on SERVER. If SERVER is nil, use value of environment variable `NNTPSERVER'. ! If optional argument SERVICE is non-nil, open by the service name." (let ((server (or server (getenv "NNTPSERVER"))) (status nil) (timer --- 185,193 ---- 'headers)))) (defun nntp-open-server (server &optional service) ! "Open SERVER. If SERVER is nil, use value of environment variable `NNTPSERVER'. ! If SERVICE, this this as the port number." (let ((server (or server (getenv "NNTPSERVER"))) (status nil) (timer *************** *** 215,221 **** status)) (defun nntp-close-server (&optional server) ! "Close news server." (nntp-possibly-change-server nil server) (unwind-protect (progn --- 215,221 ---- status)) (defun nntp-close-server (&optional server) ! "Close connection to SERVER." (nntp-possibly-change-server nil server) (unwind-protect (progn *************** *** 232,239 **** (fset 'nntp-request-quit (symbol-function 'nntp-close-server)) (defun nntp-server-opened (&optional server) ! "Return server process status. ! If the stream is opened, return non-nil, otherwise return nil." (if (or server nntp-current-server) (let ((process (nth 1 (assoc (or server nntp-current-server) nntp-server-alist)))) --- 232,238 ---- (fset 'nntp-request-quit (symbol-function 'nntp-close-server)) (defun nntp-server-opened (&optional server) ! "Say whether a connection to SERVER has been opened." (if (or server nntp-current-server) (let ((process (nth 1 (assoc (or server nntp-current-server) nntp-server-alist)))) *************** *** 241,247 **** (memq (process-status process) '(open run)))))) (defun nntp-status-message (&optional server) ! "Return server status response as string." (if (and nntp-status-string ;; NNN MESSAGE (string-match "[0-9][0-9][0-9][ \t]+\\([^\r]*\\).*$" --- 240,246 ---- (memq (process-status process) '(open run)))))) (defun nntp-status-message (&optional server) ! "Return server status as a string." (if (and nntp-status-string ;; NNN MESSAGE (string-match "[0-9][0-9][0-9][ \t]+\\([^\r]*\\).*$" *************** *** 251,257 **** nntp-status-string)) (defun nntp-request-article (id &optional newsgroup server buffer) ! "Select article by message ID (or number)." (nntp-possibly-change-server newsgroup server) (unwind-protect (progn --- 250,256 ---- nntp-status-string)) (defun nntp-request-article (id &optional newsgroup server buffer) ! "Request article ID (message-id or number)." (nntp-possibly-change-server newsgroup server) (unwind-protect (progn *************** *** 264,270 **** (if buffer (set-process-buffer nntp-server-process nntp-server-buffer)))) (defun nntp-request-body (id &optional newsgroup server) ! "Select article body by message ID (or number)." (nntp-possibly-change-server newsgroup server) (prog1 ;; If NEmacs, end of message may look like: "\256\215" (".^M") --- 263,269 ---- (if buffer (set-process-buffer nntp-server-process nntp-server-buffer)))) (defun nntp-request-body (id &optional newsgroup server) ! "Request body of article ID (message-id or number)." (nntp-possibly-change-server newsgroup server) (prog1 ;; If NEmacs, end of message may look like: "\256\215" (".^M") *************** *** 272,348 **** (nntp-decode-text))) (defun nntp-request-head (id &optional newsgroup server) ! "Select article head by message ID (or number)." (nntp-possibly-change-server newsgroup server) (prog1 (nntp-send-command "^\\.\r$" "HEAD" id) (nntp-decode-text))) (defun nntp-request-stat (id &optional newsgroup server) ! "Select article by message ID (or number)." (nntp-possibly-change-server newsgroup server) (nntp-send-command "^[23].*\r$" "STAT" id)) (defun nntp-request-group (group &optional server dont-check) ! "Select news GROUP." (if (nntp-possibly-change-server nil server) (nntp-send-command "^.*\r$" "GROUP" group))) (defun nntp-request-group-description (group &optional server) ! "Select news GROUP." (if (nntp-possibly-change-server nil server) ! (nntp-send-command "^.*\r$" "XGTITLE" group))) (defun nntp-close-group (group &optional server) t) (defun nntp-request-list (&optional server) ! "List active newsgroups." (nntp-possibly-change-server nil server) (prog1 (nntp-send-command "^\\.\r$" "LIST") (nntp-decode-text))) (defun nntp-request-list-newsgroups (&optional server) ! "List newsgroups (defined in NNTP2)." (nntp-possibly-change-server nil server) (prog1 (nntp-send-command "^\\.\r$" "LIST NEWSGROUPS") (nntp-decode-text))) (defun nntp-request-newgroups (date &optional server) ! "List new groups (defined in NNTP2)." (nntp-possibly-change-server nil server) ! (let ((date (timezone-parse-date date)) ! (time-string ! (format "%s%02d%02d %s%s%s" ! (substring (aref date 0) 2) (string-to-int (aref date 1)) ! (string-to-int (aref date 2)) (substring (aref date 3) 0 2) ! (substring (aref date 3) 3 5) (substring (aref date 3) 6 8)))) (prog1 (nntp-send-command "^\\.\r$" "NEWGROUPS" time-string) (nntp-decode-text)))) (defun nntp-request-list-distributions (&optional server) ! "List distributions (defined in NNTP2)." (nntp-possibly-change-server nil server) (prog1 (nntp-send-command "^\\.\r$" "LIST DISTRIBUTIONS") (nntp-decode-text))) (defun nntp-request-last (&optional newsgroup server) ! "Set current article pointer to the previous article ! in the current news group." (nntp-possibly-change-server newsgroup server) (nntp-send-command "^[23].*\r$" "LAST")) (defun nntp-request-next (&optional newsgroup server) ! "Advance current article pointer." (nntp-possibly-change-server newsgroup server) (nntp-send-command "^[23].*\r$" "NEXT")) (defun nntp-request-post (&optional server) ! "Post a new news in current buffer." (nntp-possibly-change-server nil server) (if (nntp-send-command "^[23].*\r$" "POST") (progn --- 271,349 ---- (nntp-decode-text))) (defun nntp-request-head (id &optional newsgroup server) ! "Request head of article ID (message-id or number)." (nntp-possibly-change-server newsgroup server) (prog1 (nntp-send-command "^\\.\r$" "HEAD" id) (nntp-decode-text))) (defun nntp-request-stat (id &optional newsgroup server) ! "Request STAT of article ID (message-id or number)." (nntp-possibly-change-server newsgroup server) (nntp-send-command "^[23].*\r$" "STAT" id)) (defun nntp-request-group (group &optional server dont-check) ! "Select GROUP." (if (nntp-possibly-change-server nil server) (nntp-send-command "^.*\r$" "GROUP" group))) (defun nntp-request-group-description (group &optional server) ! "Get description of GROUP." (if (nntp-possibly-change-server nil server) ! (prog1 ! (nntp-send-command "^.*\r$" "XGTITLE" group) ! (nntp-decode-text)))) (defun nntp-close-group (group &optional server) t) (defun nntp-request-list (&optional server) ! "List active groups." (nntp-possibly-change-server nil server) (prog1 (nntp-send-command "^\\.\r$" "LIST") (nntp-decode-text))) (defun nntp-request-list-newsgroups (&optional server) ! "List groups." (nntp-possibly-change-server nil server) (prog1 (nntp-send-command "^\\.\r$" "LIST NEWSGROUPS") (nntp-decode-text))) (defun nntp-request-newgroups (date &optional server) ! "List new groups." (nntp-possibly-change-server nil server) ! (let* ((date (timezone-parse-date date)) ! (time-string ! (format "%s%02d%02d %s%s%s" ! (substring (aref date 0) 2) (string-to-int (aref date 1)) ! (string-to-int (aref date 2)) (substring (aref date 3) 0 2) ! (substring ! (aref date 3) 3 5) (substring (aref date 3) 6 8)))) (prog1 (nntp-send-command "^\\.\r$" "NEWGROUPS" time-string) (nntp-decode-text)))) (defun nntp-request-list-distributions (&optional server) ! "List distributions." (nntp-possibly-change-server nil server) (prog1 (nntp-send-command "^\\.\r$" "LIST DISTRIBUTIONS") (nntp-decode-text))) (defun nntp-request-last (&optional newsgroup server) ! "Decrease the current article pointer." (nntp-possibly-change-server newsgroup server) (nntp-send-command "^[23].*\r$" "LAST")) (defun nntp-request-next (&optional newsgroup server) ! "Advance the current article pointer." (nntp-possibly-change-server newsgroup server) (nntp-send-command "^[23].*\r$" "NEXT")) (defun nntp-request-post (&optional server) ! "Post the current buffer." (nntp-possibly-change-server nil server) (if (nntp-send-command "^[23].*\r$" "POST") (progn *************** *** 353,360 **** (nntp-wait-for-response "^[23].*$")))) (defun nntp-request-post-buffer ! (post group subject header article-buffer info follow-to ! respect-poster) (if (assq 'to-address (nth 4 info)) (nnmail-request-post-buffer post group subject header article-buffer info follow-to respect-poster) --- 354,367 ---- (nntp-wait-for-response "^[23].*$")))) (defun nntp-request-post-buffer ! (post group subject header article-buffer info follow-to respect-poster) ! "Request a buffer suitable for composing an article. ! If POST, this is an original article; otherwise it's a followup. ! GROUP is the group to be posted to, the article should have subject ! SUBJECT. HEADER is a Gnus header vector. ARTICLE-BUFFER contains the ! article being followed up. INFO is a Gnus info list. If FOLLOW-TO, ! post to this group instead. If RESPECT-POSTER, heed the special ! \"poster\" value of the Followup-to header." (if (assq 'to-address (nth 4 info)) (nnmail-request-post-buffer post group subject header article-buffer info follow-to respect-poster) *************** *** 427,433 **** (defun nntp-send-mode-reader () "Send the MODE READER command to the nntp server. This function is supposed to be called from `nntp-server-opened-hook'. ! It will make innd servers enter nnrpd mode to allow actual article reading." (nntp-send-command "^.*\r$" "MODE READER")) --- 434,440 ---- (defun nntp-send-mode-reader () "Send the MODE READER command to the nntp server. This function is supposed to be called from `nntp-server-opened-hook'. ! It will make innd servers spawn an nnrpd process to allow actual article reading." (nntp-send-command "^.*\r$" "MODE READER")) *************** *** 471,491 **** (set-buffer nntp-server-buffer) ;; Insert newline at end of buffer. (goto-char (point-max)) ! (if (not (bolp)) ! (insert "\n")) ;; Delete status line. (goto-char (point-min)) (delete-region (point) (progn (forward-line 1) (point))) ! ;; Delete `^M' at end of line. ! ;; (replace-regexp "\r$" "") (while (not (eobp)) (end-of-line) ! (if (= (preceding-char) ?\r) ! (delete-char -1)) (forward-line 1)) ! ;; Delete `.' at end of buffer (end of text mark). (goto-char (point-max)) ! (forward-line -1) ;(beginning-of-line) (if (looking-at "^\\.$") (delete-region (point) (progn (forward-line 1) (point)))) ;; Replace `..' at beginning of line with `.'. --- 478,496 ---- (set-buffer nntp-server-buffer) ;; Insert newline at end of buffer. (goto-char (point-max)) ! (or (bolp) (insert "\n")) ;; Delete status line. (goto-char (point-min)) (delete-region (point) (progn (forward-line 1) (point))) ! ;; Delete `^M' at the end of lines. (while (not (eobp)) (end-of-line) ! (and (= (preceding-char) ?\r) ! (delete-char -1)) (forward-line 1)) ! ;; Delete `.' at end of the buffer (end of text mark). (goto-char (point-max)) ! (forward-line -1) (if (looking-at "^\\.$") (delete-region (point) (progn (forward-line 1) (point)))) ;; Replace `..' at beginning of line with `.'. *************** *** 501,508 **** (save-excursion ;; Insert newline at end of buffer. (goto-char (point-max)) ! (if (not (bolp)) ! (insert "\n")) ;; Replace `.' at beginning of line with `..'. (goto-char (point-min)) ;; (replace-regexp "^\\." "..") --- 506,512 ---- (save-excursion ;; Insert newline at end of buffer. (goto-char (point-max)) ! (or (bolp) (insert "\n")) ;; Replace `.' at beginning of line with `..'. (goto-char (point-min)) ;; (replace-regexp "^\\." "..") diff --exclude=*.elc --exclude=*~ --exclude=*-[0-9] --exclude=gnus --context --recursive pub/dgnus/lisp/nnvirtual.el dgnus/lisp/nnvirtual.el *** pub/dgnus/lisp/nnvirtual.el Thu Mar 23 13:31:01 1995 --- dgnus/lisp/nnvirtual.el Thu Mar 23 09:18:22 1995 *************** *** 383,389 **** (gnus-add-marked-articles (car (car group-alist)) (cdr (car mark-lists)) (cdr (car group-alist)) nil t) ! (gnus-group-update-group (car (car group-alist))) (setq group-alist (cdr group-alist))) (setq mark-lists (cdr mark-lists))))) --- 383,389 ---- (gnus-add-marked-articles (car (car group-alist)) (cdr (car mark-lists)) (cdr (car group-alist)) nil t) ! (gnus-group-update-group (car (car group-alist)) t) (setq group-alist (cdr group-alist))) (setq mark-lists (cdr mark-lists))))) diff --exclude=*.elc --exclude=*~ --exclude=*-[0-9] --exclude=gnus --context --recursive pub/dgnus/readme dgnus/readme *** pub/dgnus/readme Sat Dec 31 23:46:40 1994 --- dgnus/readme Mon Dec 12 13:20:49 1994 *************** *** 1,67 **** ! This package contains a pre-release of (ding) Gnus, version 0.5. The ! lisp directory contains the source lisp files, and the texi directory ! contains an early draft of the Gnus info pages. ! ! IMPORTANT NOTE FOR NNML USERS: If you have used an earlier version of ! this package, you have to do the following: ! ! ESC ESC (load "nnml") ! M-x nnml-generate-nov-databases ! ! nnml will chew on your mail for a while, and then you can use Gnus ! again. Do not attempt to start Gnus before you have done this. ! ! (This note only applies to people who use nnml as a mail backedn.) ! ! ! Gnus is meant to be totally compatible with GNUS. But, alas, it ! probably isn't, which is one of the reasons for this pre-release. ! ! To use (ding) Gnus you first have to unpack the files, which you've ! obviously done, because you are reading this. ! ! You should definitely byte-compile the source files. To do that, you ! can simply say "make" in this directory. ! ! Then you have to tell Emacs where Gnus is. You might put something ! like ! ! (setq load-path (cons (expand-file-name "~/dgnus/lisp") load-path)) ! ! in your .emacs file, or wherever you keep such things. ! ! Note that (ding) Gnus and GNUS can not coexist in a single Emacs. They ! both use the same function and variable names. If you have been ! running GNUS in your Emacs, you should probably exit that Emacs and ! start a new one to fire up Gnus. ! ! Then you do a `M-x gnus', and everything should... uhm... it should ! work, but it might not. Set `debug-on-error' to t, and mail me the ! backtraces, or, better yet, find out why Gnus does something wrong, ! fix it, and send me the diffs. :-) ! ! There are three main things I want your help and input on: ! ! 1) Startup. Does eveything go smoothly, and why not? ! ! 2) Any errors while you read news normally? ! ! 3) Any errors if you do anything abnormal? ! ! 4) Features you do not like, or do like, but would like to tweak a ! bit, and features you would like to see. ! ! You do not have to send me typo corrections for the info pages. They ! are a very rough first draft - I haven't even read through it, ! although they should document all of Gnus, I think. ! ! I think I have implemented most of the deep-going changes that I'm ! going to. Things that will probably come in the future, but I haven't ! gotten around to yet is asynchronous posting/pre-fetch of headers and ! articles, better digest handling, a hierarchal Newsgroup buffer, ! allowing the user to provide Newsgroup headers from a function, and a ! few other things that I can't think of at the moment. Oh, and the ! mhspool backend doesn't work at all yet. ! ! Send any comments and all your bug fixes/complaints to ! `larsi@ifi.uio.no'. --- 1,3 ---- ! Ting som ligger under denne katalogen burde du ikke se så veldig mye ! på. Den nyeste (pre-)releasen av (ding) Gnus finner du under ! «~larsi/pub/dgnus». diff --exclude=*.elc --exclude=*~ --exclude=*-[0-9] --exclude=gnus --context --recursive pub/dgnus/texi/gnus.texi dgnus/texi/gnus.texi *** pub/dgnus/texi/gnus.texi Thu Mar 23 13:31:03 1995 --- dgnus/texi/gnus.texi Sat Mar 25 05:53:09 1995 *************** *** 1,7 **** \input texinfo @c -*-texinfo-*- @comment %**start of header (This is for running Texinfo on a region.) @setfilename gnus ! @settitle (ding) Gnus 0.1 Manual @synindex fn cp @synindex vr cp @synindex pg cp --- 1,7 ---- \input texinfo @c -*-texinfo-*- @comment %**start of header (This is for running Texinfo on a region.) @setfilename gnus ! @settitle (ding) Gnus 0.41 Manual @synindex fn cp @synindex vr cp @synindex pg cp *************** *** 89,96 **** * Key Index:: Key Index. @end menu ! Note: This is a work of fiction. Any similarity between this manual and ! real programs is purely coincidental. @node History @chapter History --- 89,96 ---- * Key Index:: Key Index. @end menu ! This manual hasn't been prperly proff-read yet, so typos abound, and ! misleading information is sure to exist. @node History @chapter History *************** *** 110,117 **** responsibility of the author, even though you might like to strangle him for the stupid idea. ! If you want to take a look at the person responsible for this outrage, ! you can point your (feh!) web browser to @file{http://www.ifi.uio.no/~larsi/}. This is also the primary distribution point for the new and spiffy versions of Gnus, also know as The Site That Destroys Newsrcs And Drives People Mad. --- 110,117 ---- responsibility of the author, even though you might like to strangle him for the stupid idea. ! If you want to investigate the person responsible for this outrage, you ! can point your (feh!) web browser to @file{http://www.ifi.uio.no/~larsi/}. This is also the primary distribution point for the new and spiffy versions of Gnus, also know as The Site That Destroys Newsrcs And Drives People Mad. *************** *** 122,129 **** which makes it a more appropriate name, don't you think?) @menu ! * Compatibility:: Just how compatible is (ding) Gnus with @sc{GNUS}? ! * New Features:: A short description of all the new stuff in Gnus. @end menu @node Compatibility --- 122,130 ---- which makes it a more appropriate name, don't you think?) @menu ! * Compatibility:: Just how compatible is (ding) Gnus with @sc{GNUS}? ! * New Features:: A short description of all the new stuff in Gnus. ! * Newest Features:: Features so new that they haven't been written yet. @end menu @node Compatibility *************** *** 213,223 **** The approach to killing has been changed. Instead of simply killing or not, you can score articles for easier reading. @node Terminology @chapter Terminology @cindex terminology ! @table @samp @item 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 --- 214,268 ---- The approach to killing has been changed. Instead of simply killing or not, you can score articles for easier reading. + @node Newest Features + @section Newest Features + @cindex todo + + Also known as the @dfn{todo list}. Sure to be implemented before the + next millennium. + + @itemize @bullet + @item + Asynchronous article and header fetching would be very nice. Pleasant. + Even useful. I might even have come up with an idea as to how to + implement it (two connections, a bit @code{run-at-time}, and lots of + glue), but this will probably not be implemented within the next few + months. In fact, I would put money on it not being implemented before + (ding) is released, so this is more for Gnus 6.0. Asynchronous posting, + however, could possibly be included much sooner, as it is a separate + issue. + @item + Native @sc{MIME} support is something that should be done. I was hoping + I could steal code from @code{Mew}, the @sc{MIME} mail reader for Emacs, + but I'm not quite sure what the status of that project is. (ding) might + support @sc{MIME} quite soon, and it might not. + @item + Some form of caching would come in handy. Not only for those with + extremely slow @sc{NNTP} connections, but as a more general way of + saving articles in a simple fashion. (You'd basically just mark is as + @dfn{cached}, Gnus would put it in some local directory, and each time + you request that article from that group, Gnus would fetch the local + copy instead.) Lots of quite interesting stuff to be considered + (caching @sc{nov} headers or not?) before jumping into it. It would + require much twiddling of Gnus internals to make it work transparently. + @item + Gnus could detect what articles in a newsgroup you read and which + articles you kill, and then employ some adaptive scoring scheme. That + could potentially be quite interesting, and it's easy enough to + implement. + @item + When the user references the parent of an article, some sort of + re-threading should be done to build a proper tree. The same goes for + article expunging. However, as it stands, it's not a trivial issue to + re-generate parts of the summary buffer. Generating the entire buffer + is very easy, but slow. + @end itemize + @node Terminology @chapter Terminology @cindex terminology ! @itemize @bullet @item 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 *************** *** 248,260 **** A line from the head of an article. @item headers A collection of such lines, or a collection of heads. Or even a ! collection of NOV lines. ! @item 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. ! @end table @node Starting Up @chapter Starting Gnus --- 293,312 ---- A line from the head of an article. @item headers A collection of such lines, or a collection of heads. Or even a ! collection of @sc{NOV} lines. ! @item @sc{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 ! 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 ! "subscribed"; 6-7 are "unsubscribed"; 8 are zombies; and 9 are killed. ! Commands for listing groups and scanning for new articles will all use ! the numeric prefix as @dfn{working level}. ! @end itemize @node Starting Up @chapter Starting Gnus *************** *** 363,370 **** You'll also be subscribed to the Gnus documentation group, which should help you with most common problems. ! If @code{gnus-default-subscribed-newsgroups} is @code{t}, Gnus will just use ! the normal functions for handling new groups, and not do anything special. @node The Server is Down --- 415,422 ---- You'll also be subscribed to the Gnus documentation group, which should help you with most common problems. ! If @code{gnus-default-subscribed-newsgroups} is @code{t}, Gnus will just ! use the normal functions for handling new groups, and not do anything special. @node The Server is Down *************** *** 514,521 **** @vindex gnus-startup-file The @code{gnus-startup-file} variable says where the startup files are. ! The default value is @file{"~/.newsrc"}, with the Gnus (El Dingo) ! startup file being whatever that one is with a @samp{".eld"} appended. @vindex gnus-save-newsrc-hook @code{gnus-save-newsrc-hook} is called before saving the @file{.newsrc} --- 566,573 ---- @vindex gnus-startup-file The @code{gnus-startup-file} variable says where the startup files are. ! The default value is @file{~/.newsrc}, with the Gnus (El Dingo) startup ! file being whatever that one is with a @samp{".eld"} appended. @vindex gnus-save-newsrc-hook @code{gnus-save-newsrc-hook} is called before saving the @file{.newsrc} *************** *** 998,1011 **** The different methods all have their peculiarities, of course. @menu ! * nntp:: Reading news from a different NNTP server. ! * nnspool:: Reading news from the local spool. ! * nnvirtual:: Combining articles from many groups. ! * nnkiboze:: Looking through parts of the newsfeed for articles. ! * nndir:: You can read a directory as if it was a newsgroup. ! * nndoc:: Single files can be the basis of a group. ! * nndigest:: Digests can be undigested and treated as a group. ! * Mail:: Reading your personal mail with Gnus. @end menu @vindex gnus-activate-foreign-newsgroups --- 1050,1063 ---- The different methods all have their peculiarities, of course. @menu ! * nntp:: Reading news from a different NNTP server. ! * nnspool:: Reading news from the local spool. ! * nnvirtual:: Combining articles from many groups. ! * nnkiboze:: Looking through parts of the newsfeed for articles. ! * nndir:: You can read a directory as if it was a newsgroup. ! * nndoc:: Single files can be the basis of a group. ! * nndigest:: Digests can be undigested and treated as a group. ! * Reading Mail:: Reading your personal mail with Gnus. @end menu @vindex gnus-activate-foreign-newsgroups *************** *** 1056,1062 **** The two first entries in this method should, of course, be the same as @code{gnus-select-method}. ! Quite simple, eh? *Ouch*. Let's take time out for a poem by Reznikoff: --- 1108,1114 ---- The two first entries in this method should, of course, be the same as @code{gnus-select-method}. ! Quite simple, eh? @strong{Ouch}. Let's take time out for a poem by Reznikoff: *************** *** 1094,1108 **** fact, you can subscribe to the same group from as many different servers you feel like. There will be no name collisions. @vindex nntp-server-opened-hook @code{nntp-server-opened-hook} is run after a connection has been made. ! It can be used to send initial commands to the NNTP server, like ! @samp{(nntp-send-command "MODE" "READER")} (which is what this hook does ! by default) or to send the @code{AUTHINFO} command, if the server ! requires that. @vindex nntp-maximum-request ! If the NNTP server doesn't support NOV headers, this backend will collect headers by sending a series of @code{HEAD} commands. To speed things up, the backend sends lots of these commands, without waiting for reply, and then reads all the replies. This is controlled by the --- 1146,1165 ---- fact, you can subscribe to the same group from as many different servers you feel like. There will be no name collisions. + @cindex @sc{MODE READER} + @cindex authinfo + @findex nntp-send-authinfo + @findex nntp-send-mode-reader @vindex nntp-server-opened-hook @code{nntp-server-opened-hook} is run after a connection has been made. ! It can be used to send commands to the NNTP server after it has been ! contacted. By default is sends the command @samp{MODE READER} to the ! server with the @code{nntp-send-mode-reader} function. Another popular ! function for sending the @sc{authinfo} command to the server is ! @code{nntp-send-authinfo}. @vindex nntp-maximum-request ! If the NNTP server doesn't support @sc{NOV} headers, this backend will collect headers by sending a series of @code{HEAD} commands. To speed things up, the backend sends lots of these commands, without waiting for reply, and then reads all the replies. This is controlled by the *************** *** 1140,1146 **** Where nnspool looks for the articles. This is normally @file{/usr/spool/news/}. @item nnspool-nov-directory ! Where nnspool will look for NOV files. This is normally @file{/usr/spool/news/over.view/}. @item nnspool-lib-dir Where the news lib dir is (@file{/usr/lib/news/} by default). --- 1197,1203 ---- Where nnspool looks for the articles. This is normally @file{/usr/spool/news/}. @item nnspool-nov-directory ! Where nnspool will look for @sc{NOV} files. This is normally @file{/usr/spool/news/over.view/}. @item nnspool-lib-dir Where the news lib dir is (@file{/usr/lib/news/} by default). *************** *** 1231,1242 **** @vindex nnkiboze-directory The generation of an nnkiboze group means writing two files in @code{nnkiboze-directory}, which is @file{~/News/} by default. One ! contains the NOV header lines for all the articles in the group, and the other is an additional @file{.newsrc} to store information on what groups that have been searched through to find component articles. Articles that are marked as read in the nnkiboze group will have their ! NOV lines removed from the NOV file. @node nndir @subsection nndir --- 1288,1299 ---- @vindex nnkiboze-directory The generation of an nnkiboze group means writing two files in @code{nnkiboze-directory}, which is @file{~/News/} by default. One ! contains the @sc{NOV} header lines for all the articles in the group, and the other is an additional @file{.newsrc} to store information on what groups that have been searched through to find component articles. Articles that are marked as read in the nnkiboze group will have their ! @sc{NOV} lines removed from the @sc{NOV} file. @node nndir @subsection nndir *************** *** 1256,1262 **** allow you to read this directory over at amanda as a newsgroup. Distributed news ahoy! ! nndir supports, and will use, NOV files if they are present. @node nndoc @subsection nndoc --- 1313,1319 ---- allow you to read this directory over at amanda as a newsgroup. Distributed news ahoy! ! nndir supports, and will use, @sc{NOV} files if they are present. @node nndoc @subsection nndoc *************** *** 1289,1296 **** Odd all over, as you can see, but somewhat useful. ! @node Mail ! @subsection Mail @cindex reading mail @cindex mail --- 1346,1353 ---- Odd all over, as you can see, but somewhat useful. ! @node Reading Mail ! @subsection Reading Mail @cindex reading mail @cindex mail *************** *** 1301,1306 **** --- 1358,1364 ---- * Creating Mail Groups:: How to create mail groups. * Mail & Procmail:: Reading mail groups that procmail create. * Expiring Old Mail Articles:: Getting rid of unwanted mail. + * Not Reading Mail:: Using mail backends for reading other files. @end menu Gnus will read the mail spool when you activate a mail group. The mail *************** *** 1325,1338 **** variable is @code{nil}, the mail backends will never attempt to fetch mail by themselves. ! Gnus gives you all the opportunity you want for shooting yourself in ! your foot. Let's say you create a group that will contain all the mail ! you get from your boss. And then you accidentally unsubscribe from the ! group. Gnus will still put all the mail from your boss in the ! unsubscribed group, and so, when your boss mails you "Have that report ! ready by Monday or you're fired!", you'll never see it and, come ! Tuesday, you'll still believe that you're gainfully unemplyed while you ! really should be out collecting empty bottles to save up for next month's rent money. @node Creating Mail Groups --- 1383,1402 ---- variable is @code{nil}, the mail backends will never attempt to fetch mail by themselves. ! @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 ! the mail backend habitates (ie. @file{~/Mail/}), but if this variable is ! non-nil, it will be used instead. ! ! Gnus gives you all the opportunity you could possibly want for shooting ! yourself in the foot. Let's say you create a group that will contain ! all the mail you get from your boss. And then you accidentally ! unsubscribe from the group. Gnus will still put all the mail from your ! boss in the unsubscribed group, and so, when your boss mails you "Have ! that report ready by Monday or you're fired!", you'll never see it and, ! come Tuesday, you'll still believe that you're gainfully employed while ! you really should be out collecting empty bottles to save up for next month's rent money. @node Creating Mail Groups *************** *** 1371,1378 **** mail belongs in that group. The last of these groups should always be a general one, and the regular ! expression should *always* be @samp{""} so that it matches any mails ! that haven't been matched by any of the other regexps. @vindex nnmail-crosspost The mail backends all support cross-posting. If several regexps match, --- 1435,1442 ---- mail belongs in that group. The last of these groups should always be a general one, and the regular ! expression should @emph{always} be @samp{""} so that it matches any ! mails that haven't been matched by any of the other regexps. @vindex nnmail-crosspost The mail backends all support cross-posting. If several regexps match, *************** *** 1439,1452 **** deleted from your system if, 1) it is marked as expirable, AND 2) it is more than one week old. If you do not mark an article as expirable, it will remain on your system until hell freezes over. This bears ! repeating one more time, with some spurious capitalization: IF you do NOT mark articles as EXPIRABLE, Gnus will NEVER delete those ARTICLES. @vindex gnus-auto-expirable-newsgroups You do not have to mark articles as expirable by hand. Groups that match the regular expression @code{gnus-auto-expirable-newsgroups} will have all articles that you read marked as expirable automatically. All ! articles that are marked as expirable have an @samp{X} in the third column in the summary buffer. Let's say you subscribe to a couple of mailing lists, and you want the --- 1503,1516 ---- deleted from your system if, 1) it is marked as expirable, AND 2) it is more than one week old. If you do not mark an article as expirable, it will remain on your system until hell freezes over. This bears ! repeating one more time, with some spurious capitalizations: IF you do NOT mark articles as EXPIRABLE, Gnus will NEVER delete those ARTICLES. @vindex gnus-auto-expirable-newsgroups You do not have to mark articles as expirable by hand. Groups that match the regular expression @code{gnus-auto-expirable-newsgroups} will have all articles that you read marked as expirable automatically. All ! articles that are marked as expirable have an @samp{E} in the first column in the summary buffer. Let's say you subscribe to a couple of mailing lists, and you want the *************** *** 1457,1462 **** --- 1521,1529 ---- "^mail.nonsense-list\\|^mail.nice-list") @end lisp + Another way to have auto-expiry happen is to have the element + @code{auto-expire} in the select method of the group. + @vindex nnmail-expiry-wait The @code{nnmail-expiry-wait} variable supplies the default time an expirable article has to live. The default is seven days. *************** *** 1469,1481 **** @lisp (setq nnmail-expiry-wait-function ! '(lambda (group) ! (cond ((string= group "mail.private") ! 31) ! ((string= group "mail.junk") ! 1) ! (t ! 6)))) @end lisp @vindex nnmail-keep-last-article --- 1536,1548 ---- @lisp (setq nnmail-expiry-wait-function ! (lambda (group) ! (cond ((string= group "mail.private") ! 31) ! ((string= group "mail.junk") ! 1) ! (t ! 6)))) @end lisp @vindex nnmail-keep-last-article *************** *** 1483,1488 **** --- 1550,1577 ---- expire the final article in a mail newsgroup. This is to make life easier for procmail users. + @node Not Reading Mail + @subsubsection Not Reading Mail + + If you start using any of the mail backends, they have the annoying + habit of assuming that you want to read mail with them. This might not + be unreasonable, but it might not be what you want. + + If you set @code{nnmail-spool-file} to nil, none of the backends will + ever attempt to read incoming mail, which should help. + + @vindex nnbabyl-get-new-mail + @vindex nnmbox-get-new-mail + @vindex nnml-get-new-mail + @vindex nnmh-get-new-mail + @vindex nnfolder-get-new-mail + This might be too much, if, for instance, you are reading mail quite + happily with @code{nnml} and just want to peek at some old @sc{RMAIL} + file you have stashed away with @code{nnbabyl}. All backends have + variables called backend-@code{get-new-mail}. If you want to disable + the @code{nnbabyl} mail reading, you just set + @code{nnbabyl-get-new-mail} to @code{nil}. + @node nnmbox @subsubsection nnmbox @cindex nnmbox *************** *** 1518,1524 **** @node nnml @subsubsection nnml @cindex nnml ! @cindex mail nov spool The spool mail format (@code{nnml}) isn't compatible with any other known format. It should be used with some caution. --- 1607,1613 ---- @node nnml @subsubsection nnml @cindex nnml ! @cindex mail @sc{nov} spool The spool mail format (@code{nnml}) isn't compatible with any other known format. It should be used with some caution. *************** *** 1542,1554 **** to trudge through a big mbox file just to read your new mail. @code{nnml} is probably the slowest backend when it comes to article ! splitting. It has to create lots of files, and it also generates NOV ! databases for the incoming mails. This makes is the fastest backend ! when it comes to reading mail. @findex nnml-generate-nov-databases ! If your @code{nnml} groups and nov files get totally out of whack, you ! can do a complete update by typing @kbd{M-x nnml-generate-nov-databases}. This command will trawl through the entire @code{nnml} hierarchy, looking at each and every article, so it might take a while to finish. --- 1631,1643 ---- to trudge through a big mbox file just to read your new mail. @code{nnml} is probably the slowest backend when it comes to article ! splitting. It has to create lots of files, and it also generates ! @sc{NOV} databases for the incoming mails. This makes is the fastest ! backend when it comes to reading mail. @findex nnml-generate-nov-databases ! If your @code{nnml} groups and @sc{nov} files get totally out of whack, ! you can do a complete update by typing @kbd{M-x nnml-generate-nov-databases}. This command will trawl through the entire @code{nnml} hierarchy, looking at each and every article, so it might take a while to finish. *************** *** 1559,1567 **** @cindex mh-e mail spool @code{nnmh} is just like @code{nnml}, except that is doesn't generate ! NOV databases and it doesn't keep an active file. This makes ! @code{nnmh} a *much* slower backend than @code{nnml}, but it also makes ! it easier to write procmail scripts for. @node nnfolder @subsubsection nnfolder --- 1648,1656 ---- @cindex mh-e mail spool @code{nnmh} is just like @code{nnml}, except that is doesn't generate ! @sc{NOV} databases and it doesn't keep an active file. This makes ! @code{nnmh} a @emph{much} slower backend than @code{nnml}, but it also ! makes it easier to write procmail scripts for. @node nnfolder @subsubsection nnfolder *************** *** 1772,1778 **** @kindex M-f (Group) @findex gnus-group-fetch-faq Try to fetch the FAQ for the current group ! (@code{gnus-group-fetch-faq}). @item R @kindex R (Group) @findex gnus-group-restart --- 1861,1869 ---- @kindex M-f (Group) @findex gnus-group-fetch-faq Try to fetch the FAQ for the current group ! (@code{gnus-group-fetch-faq}). Gnus will try to get the FAQ from ! @code{gnus-group-faq-directory}, which is usually a directory on a ! remote machine. ange-ftp will be used for fetching the file. @item R @kindex R (Group) @findex gnus-group-restart *************** *** 1961,1983 **** Xref @item u User defined specifier. The next character in the format string should ! be a letter. @sc{GNUS} will call the function gnus-user-format-function-X, ! where X is the letter following %u. The function will be passed the ! current header as argument. The function should return a string, which ! will be inserted into the summary just like information from any other ! summary specifier. ! @end table ! ! Text between %( and %) will be highlighted with `gnus-mouse-face' ! when the mouse point is placed inside the area. There can only be one ! such area. ! ! The %U (status), %R (replied) and %z (zcore) specs have to be handled ! with care. For reasons of efficiency, Gnus will compute what column ! these characters will end up in, and "hard-code" that. This means that ! it is illegal to have these specs after a variable-length spec. Well, ! you might not be arrested, but your summary buffer will look strange, ! which is bad enough. The smart choice is to have these specs as far to the left as possible. (Isn't that the case with everything, though? But I digress.) --- 2052,2074 ---- Xref @item u User defined specifier. The next character in the format string should ! be a letter. @sc{GNUS} will call the function ! gnus-user-format-function-X, where X is the letter following @samp{%u}. ! The function will be passed the current header as argument. The ! function should return a string, which will be inserted into the summary ! just like information from any other summary specifier. ! @end table ! ! Text between @samp{%(} and @samp{%)} will be highlighted with ! @code{gnus-mouse-face} when the mouse point is placed inside the area. ! There can only be one such area. ! ! The @samp{%U} (status), @samp{%R} (replied) and @samp{%z} (zcore) specs ! have to be handled with care. For reasons of efficiency, Gnus will ! compute what column these characters will end up in, and "hard-code" ! that. This means that it is illegal to have these specs after a ! variable-length spec. Well, you might not be arrested, but your summary ! buffer will look strange, which is bad enough. The smart choice is to have these specs as far to the left as possible. (Isn't that the case with everything, though? But I digress.) *************** *** 2191,2205 **** @findex gnus-summary-scroll-up Scroll the current article one line forward (@code{gnus-summary-scroll-up}). - @item < @item A < @kindex < (Summary) @kindex A < (Summary) @findex gnus-summary-beginning-of-article Scroll to the beginning of the article (@code{gnus-summary-beginning-of-article}). - @item > @item A > @kindex > (Summary) @kindex A > (Summary) @findex gnus-summary-end-of-article --- 2282,2296 ---- @findex gnus-summary-scroll-up Scroll the current article one line forward (@code{gnus-summary-scroll-up}). @item A < + @item < @kindex < (Summary) @kindex A < (Summary) @findex gnus-summary-beginning-of-article Scroll to the beginning of the article (@code{gnus-summary-beginning-of-article}). @item A > + @item > @kindex > (Summary) @kindex A > (Summary) @findex gnus-summary-end-of-article *************** *** 2220,2275 **** a prefix to @kbd{C-c C-c} to make Gnus try to post using the foreign server. @table @kbd ! @item a ! @kindex a (Summary) ! @findex gnus-summary-post-news ! Post an article to the current group ! (@code{gnus-summary-post-news}). ! @item f ! @kindex f (Summary) ! @findex gnus-summary-followup ! Post a followup to the current article (@code{gnus-summary-followup}). ! @item F ! @kindex F (Summary) ! @findex gnus-summary-followup-with-original ! Post a followup to the current article and include the original message ! (@code{gnus-summary-followup-with-original}). @item r @kindex r (Summary) @findex gnus-summary-reply Mail a reply to the author of the current article (@code{gnus-summary-reply}). @item R @kindex R (Summary) @findex gnus-summary-reply-with-original Mail a reply to the author of the current article and include the original message (@code{gnus-summary-reply-with-original}). ! @item b ! @kindex b (Summary) ! @findex gnus-summary-followup-and-reply ! Post a followup and send a reply to the current article ! (@code{gnus-summary-followup-and-reply}). ! @item B ! @kindex N (Summary) ! @findex gnus-summary-followup-and-reply-with-original ! Post a followup and send a reply to the current article and include the ! original message (@code{gnus-summary-followup-and-reply-with-original}). ! @item C-c C-f ! @kindex C-c C-f (Summary) @findex gnus-summary-mail-forward Forward the current article to some other person (@code{gnus-summary-mail-forward}). @item m @kindex m (Summary) @findex gnus-summary-mail-other-window Send a mail to some other person ! (@code{gnus-summary-mail-other-window}). @item S M-f @kindex S M-f (Summary) @findex gnus-uu-digest-and-forward Digest the current series and forward the result using mail (@code{gnus-uu-digest-and-forward}). @item S u @kindex S u (Summary) @findex gnus-uu-post-news --- 2311,2418 ---- a prefix to @kbd{C-c C-c} to make Gnus try to post using the foreign server. + @menu + * Mail:: Mailing & replying. + * Post:: Posting and following up. + * Mail & Post:: Mailing and posting at the same time. + @end menu + + @node Mail + @subsection Mail + + Commands for composing a mail message: + @table @kbd ! @item S r @item r + @kindex S r (Summary) @kindex r (Summary) @findex gnus-summary-reply Mail a reply to the author of the current article (@code{gnus-summary-reply}). + @item S R @item R @kindex R (Summary) + @kindex S R (Summary) @findex gnus-summary-reply-with-original Mail a reply to the author of the current article and include the original message (@code{gnus-summary-reply-with-original}). ! @item S C-f ! @kindex S C-f (Summary) @findex gnus-summary-mail-forward Forward the current article to some other person (@code{gnus-summary-mail-forward}). + @item S m @item m @kindex m (Summary) + @kindex S m (Summary) @findex gnus-summary-mail-other-window Send a mail to some other person ! (@code{gnus-summary-mail-other-window}). @item S M-f @kindex S M-f (Summary) @findex gnus-uu-digest-and-forward Digest the current series and forward the result using mail (@code{gnus-uu-digest-and-forward}). + @end table + + Variables for customizing outgoing mail: + + @table @code + @item gnus-reply-to-function + @vindex gnus-reply-to-function + Gnus uses the normal methods to determine where replies are to go, but + you can change the behaviour to suit your needs by fiddling with the + @code{gnus-reply-to-function} variable. + + If you want the replies to go to the "sender" instead of the "from" in + the group "mail.stupid-list", you could do something like this: + + @lisp + (setq gnus-reply-to-function + (lambda (group) + (cond ((string= group "mail.stupid-list") + (mail-fetch-field "sender")) + (t + 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 + This variable says how a mail should be mailed. It uses the function in + the @code{send-mail-function} variable as the default. + @end table + + + @node Post + @subsection Post + + Commands for posting an article: + + @table @kbd + @item S p + @item a + @kindex a (Summary) + @kindex S p (Summary) + @findex gnus-summary-post-news + Post an article to the current group + (@code{gnus-summary-post-news}). + @item S f + @item f + @kindex f (Summary) + @kindex S f (Summary) + @findex gnus-summary-followup + Post a followup to the current article (@code{gnus-summary-followup}). + @item S F + @item F + @kindex S F (Summary) + @kindex F (Summary) + @findex gnus-summary-followup-with-original + Post a followup to the current article and include the original message + (@code{gnus-summary-followup-with-original}). @item S u @kindex S u (Summary) @findex gnus-uu-post-news *************** *** 2277,2282 **** --- 2420,2427 ---- (@code{gnus-uu-post-news}). @end table + Variables for customizing outgoing articles: + @table @code @item gnus-required-headers @vindex gnus-required-headers *************** *** 2284,2293 **** --- 2429,2440 ---- consulting the this variable. All headers mentioned in this list will either be generated automatically or prompted for before an article is posted. + @item gnus-post-method @vindex gnus-post-method If non-@code{nil}, Gnus will use this method instead of the default select method when posting. + @item gnus-use-followup-to @vindex gnus-use-followup-to If @code{nil}, always ignore the Followup-To header. If it is @code{t}, *************** *** 2295,2324 **** send the followup as a reply mail to the person you are responding to. If it is neither @code{nil} nor @code{t}, always use the Followup-To value. @item gnus-followup-to-function - @item gnus-reply-to-function - @vindex gnus-reply-to-function @vindex gnus-followup-to-function ! Gnus uses the normal methods to determine where replys and follow-ups ! are to go, but you can change the behaviour to suit your need by ! fiddling with the @code{gnus-reply-to-function} and ! @code{gnus-followup-to-function} variables. ! ! To take "reply" as an example: If you want the replies to go to the ! "sender" instead of the "from" in the group "mail.stupid-list", you ! could do something like this: @lisp ! (setq gnus-reply-to-function ! '(lambda (group) ! (cond ((string= group "mail.stupid-list") ! (mail-fetch-field "sender")) ! (t ! nil)))) @end lisp ! These functions will be called with point in the buffer of the article ! that is being replied to (or followed up). @item gnus-signature-function @vindex gnus-signature-function If non-@code{nil}, this variable should be a function that returns a --- 2442,2469 ---- send the followup as a reply mail to the person you are responding to. If it is neither @code{nil} nor @code{t}, always use the Followup-To value. + @item gnus-followup-to-function @vindex gnus-followup-to-function ! Gnus uses the normal methods to determine where follow-ups are to go, ! but you can change the behaviour to suit your needs by fiddling with ! this variable. ! ! If you want the followups to go to the "sender" instead of the "from" in ! the group "mail.stupid-list", you could do something like this: @lisp ! (setq gnus-followup-to-function ! (lambda (group) ! (cond ((string= group "mail.stupid-list") ! (mail-fetch-field "sender")) ! (t ! nil)))) @end lisp ! This functions will be called from the buffer of the article that is ! being followed up. ! @item gnus-signature-function @vindex gnus-signature-function If non-@code{nil}, this variable should be a function that returns a *************** *** 2327,2378 **** correspond to a file, the string itself is inserted. If the function returns @code{nil}, the @code{gnus-signature-file} variable will be used instead. - @item gnus-signature-file - @item mail-signature - @vindex mail-signature - @vindex gnus-signature-file - If non-@code{nil}, this variable should be the name of a file containing - a signature (@samp{~/.signature} by default). This signature will be - appended to all outgoing post. Most people find it more convenient to - use @code{mail-signature}, which does the same, but inserts the - signature into the buffer before you start editing the post (or mail). - So - if you have both of these variables set, you will get two - signatures. - - Note that RFC1036 says that a signature should be preceded by the three - characters @samp{-- } on a line by themselves. This is to make it - easier for the recipient to automatically filter the signature away. So - don't remove those characters, even though you might feel that they ruin - you beautiful design, like, totally. - Also note that no signature should be more than four lines long. - Including ASCII graphics is an efficient way to get everybody to believe - that you are silly and have nothing important to say. @item gnus-post-prepare-function @vindex gnus-post-prepare-function This function is called with the name of the current group after the post buffer has been initialized, and can be used for inserting a signature. Nice if you use different signatures in different groups. ! @item gnus-auto-mail-to-author ! @vindex gnus-auto-mail-to-author ! If non-@code{nil}, Gnus will send a mail with a copy of all follow-ups ! to the authors of the articles you follow up. It's nice in one way - ! you make sure that the person you are responding to gets your response. ! Other people loathe this method and will hate you dearly for it, because ! it means that they will first get a mail, and then have to read the same ! article later when they read the news. It is @code{nil} by default. ! @item gnus-mail-send-method ! @vindex gnus-mail-send-method ! This variable says how a mail should be mailed. It uses the function in ! the @code{send-mail-function} variable as the default. @item gnus-prepare-article-hook @vindex gnus-prepare-article-hook This hook is called before the headers have been prepared. By default it inserts the signature specified by @code{gnus-signature-file}. @item gnus-inews-article-hook @vindex gnus-inews-article-hook This hook is called right before the article is posted. By default it handles FCC processing (ie. saving the article to a file.) @item gnus-inews-article-header-hook @vindex gnus-inews-article-header-hook This hook is called after inserting the required headers in an article --- 2472,2520 ---- correspond to a file, the string itself is inserted. If the function returns @code{nil}, the @code{gnus-signature-file} variable will be used instead. @item gnus-post-prepare-function @vindex gnus-post-prepare-function This function is called with the name of the current group after the post buffer has been initialized, and can be used for inserting a signature. Nice if you use different signatures in different groups. ! ! @item news-reply-header-hook ! @vindex news-reply-header-hook ! A related variable when following up and replying is this variable, ! which inserts the @dfn{quote line}. The default value is: ! ! @lisp ! (defvar news-reply-header-hook ! (lambda () ! (insert "In article " news-reply-yank-message-id ! " " news-reply-yank-from " writes:\n\n"))) ! @end lisp ! ! This will create lines like: ! ! @example ! In article Lars Mars writes: ! @end example ! ! Having the Message-Id in this line is probably overkill, so I would ! suggest this hook instead: ! ! @lisp ! (setq news-reply-header-hook ! (lambda () (insert news-reply-yank-from " writes:\n\n"))) ! @end lisp ! @item gnus-prepare-article-hook @vindex gnus-prepare-article-hook This hook is called before the headers have been prepared. By default it inserts the signature specified by @code{gnus-signature-file}. + @item gnus-inews-article-hook @vindex gnus-inews-article-hook This hook is called right before the article is posted. By default it handles FCC processing (ie. saving the article to a file.) + @item gnus-inews-article-header-hook @vindex gnus-inews-article-header-hook This hook is called after inserting the required headers in an article *************** *** 2381,2386 **** --- 2523,2609 ---- insert additional headers, or just change headers in some way. @end table + + @node Mail & Post + @subsection Mail & Post + + Commands for sending mail and post at the same time: + + @table @kbd + @item S b + @kindex S b (Summary) + @findex gnus-summary-followup-and-reply + Post a followup and send a reply to the current article + (@code{gnus-summary-followup-and-reply}). + @item S B + @kindex S B (Summary) + @findex gnus-summary-followup-and-reply-with-original + Post a followup and send a reply to the current article and include the + original message (@code{gnus-summary-followup-and-reply-with-original}). + @end table + + Here's a list of variables that are relevant for both mailing and + posting: + + @table @code + @item gnus-signature-file + @item mail-signature + @vindex mail-signature + @vindex gnus-signature-file + If @code{gnus-signature-file} is non-@code{nil}, it should be the name + of a file containing a signature (@samp{~/.signature} by default). This + signature will be appended to all outgoing post. Most people find it + more convenient to use @code{mail-signature}, which does the same, but + inserts the signature into the buffer before you start editing the post + (or mail). So - if you have both of these variables set, you will get + two signatures. + + Note that RFC1036 says that a signature should be preceded by the three + characters @samp{-- } on a line by themselves. This is to make it + easier for the recipient to automatically filter the signature away. So + don't remove those characters, even though you might feel that they ruin + you beautiful design, like, totally. + + Also note that no signature should be more than four lines long. + Including ASCII graphics is an efficient way to get everybody to believe + that you are silly and have nothing important to say. + + @item mail-yank-prefix + @vindex mail-yank-prefix + @cindex yanking + @cindex quoting + When you are replying or following up an article, you normally want to + quote the person you are replying to. Inserting quoted text is done by + @dfn{yanking}, and each quoted line you yank will have + @code{mail-yank-prefix} prepended to it. This is @samp{ } by default, + which isn't very pretty. Most everybody prefers that lines are + prepended with @samp{> }, so @code{(setq mail-yank-prefix "> ")} in your + @file{.emacs} file. + + @item mail-yank-ignored-headers + @vindex mail-yank-ignored-headers + 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. + + @item gnus-auto-mail-to-author + @vindex gnus-auto-mail-to-author + If @code{ask}, you will be prompted for whether you want to send a mail + copy to the author of the article you are following up. If + non-@code{nil} and not @code{ask}, Gnus will send a mail with a copy of + all follow-ups to the authors of the articles you follow up. It's nice + in one way - you make sure that the person you are responding to gets + your response. Other people loathe this method and will hate you dearly + for it, because it means that they will first get a mail, and then have + to read the same article later when they read the news. It is + @code{nil} by default. + @end table + @node Cancelling and Superseding @section Cancelling Articles @cindex cancelling articles *************** *** 2394,2401 **** @findex gnus-summary-cancel-article @kindex C (Summary) Find the article you wish to cancel (you can only cancel your own ! articles, so don't try any funny stuff). Then press @kbd{C} ! (@code{gnus-summary-cancel-article}). Your article will be cancelled. Be aware, however, that not all sites honor cancels, so your article may live on in some parts of the world, while most sites will delete the --- 2617,2625 ---- @findex gnus-summary-cancel-article @kindex C (Summary) Find the article you wish to cancel (you can only cancel your own ! articles, so don't try any funny stuff). Then press @kbd{C} or @kbd{S ! c} (@code{gnus-summary-cancel-article}). Your article will be ! cancelled. Be aware, however, that not all sites honor cancels, so your article may live on in some parts of the world, while most sites will delete the *************** *** 2407,2413 **** @findex gnus-summary-supersede-article @kindex S (Summary) ! Go to the original article and press @kbd{S} (@code{gnus-summary-supersede-article}). You will be put in a buffer where you can edit the article all you want before sending it off the usual way. --- 2631,2637 ---- @findex gnus-summary-supersede-article @kindex S (Summary) ! Go to the original article and press @kbd{S s} (@code{gnus-summary-supersede-article}). You will be put in a buffer where you can edit the article all you want before sending it off the usual way. *************** *** 2571,2583 **** --- 2795,2811 ---- @findex gnus-summary-mark-as-read-forward Mark the current article as read (@code{gnus-summary-mark-as-read-forward}). + @item M k @item k @kindex k (Summary) + @kindex M k (Summary) @findex gnus-summary-kill-same-subject-and-select Mark all articles that have the same subject as the current one as read, and then select the next unread article (@code{gnus-summary-kill-same-subject-and-select}). + @item M K @item C-k + @kindex M K (Summary) @kindex C-k (Summary) @findex gnus-summary-kill-same-subject Mark all articles that have the same subject as the current one as read *************** *** 2677,2699 **** @cindex setting process marks @table @kbd @item # - @item M p @kindex # (Summary) @kindex M p p (Summary) @findex gnus-summary-mark-as-processable Mark the current article with the process mark (@code{gnus-summary-mark-as-processable}). @findex gnus-summary-unmark-as-processable - @item M-# @item M p u ! @kindex M-# (Summary) @kindex M p u (Summary) Remove the process mark from the current article (@code{gnus-summary-unmark-as-processable}). - @item C-c M-# @item M p U - @kindex C-c M-# (Summary) @kindex M p U (Summary) @findex gnus-summary-unmark-all-processable Remove the process mark from all articles --- 2905,2925 ---- @cindex setting process marks @table @kbd + @item M p p @item # @kindex # (Summary) @kindex M p p (Summary) @findex gnus-summary-mark-as-processable Mark the current article with the process mark (@code{gnus-summary-mark-as-processable}). @findex gnus-summary-unmark-as-processable @item M p u ! @item M-# @kindex M p u (Summary) + @kindex M-# (Summary) Remove the process mark from the current article (@code{gnus-summary-unmark-as-processable}). @item M p U @kindex M p U (Summary) @findex gnus-summary-unmark-all-processable Remove the process mark from all articles *************** *** 2726,2737 **** Mark all articles in series order (@code{gnus-uu-mark-series}). @end table - @findex gnus-summary-universal-argument - @kindex V u (Summary) - Finally, we have @kbd{V u} (@code{gnus-summary-universal-argument}) that - will perform any operation on all articles that have been marked with - the process mark. - @node Threading @section Threading @cindex threading --- 2952,2957 ---- *************** *** 2760,2801 **** @item gnus-fetch-old-headers @vindex gnus-fetch-old-headers If non-@code{nil}, Gnus will attempt to build old threads by fetching ! more old headers - headers to articles that are marked as read. If it ! has the value `some', only enough headers to connect otherwise loose ! threads will be displayed. Fetching old headers only works if the ! select method you are using supports XOVER. Also remember that if the ! root of the thread has been expired by the server, there's not much Gnus ! can do about that. @item gnus-gather-loose-threads @vindex gnus-gather-loose-threads If non-@code{nil}, Gnus will gather all loose subtrees into one big tree and create a dummy root at the top. (Wait a minute. Root at the top? Yup.) Loose subtrees occur when the real root has expired, or you've ! read it or marked it as read in a previous session. @item gnus-summary-gather-subject-limit ! If this variable is @code{nil}, the entire subject line will be used to ! gather loose threads. If you would limit this to the 20 first ! characters of the subjects, set this variable to 20. @item gnus-summary-make-false-root @vindex gnus-summary-make-false-root When there is no real root of a thread, Gnus will have to fudge ! something. This variable says what method Gnus should use while ! fudging. There are four possible value: @table @code @item adopt Gnus will make the first of the orphaned articles the parent. This parent will adopt all the other articles. The adopted articles will be ! marked as such by pointy brackeds instead of square brackets. This is ! the default value. @item dummy ! Gnus will create a dummy that will stand in as the parent. This dummy ! will be displayed on a line of its own, but it does not correspond to ! any real article. @item empty Gnus won't actually make any article the parent, but simply leave the ! subject field of all orphans except the first empty. (It will use ! @code{gnus-summary-same-subject} as the subject.) @item nil Don't make any article parent at all. Just gather the threads and display them after one another. --- 2980,3031 ---- @item gnus-fetch-old-headers @vindex gnus-fetch-old-headers If non-@code{nil}, Gnus will attempt to build old threads by fetching ! more old headers - headers to articles that are marked as read. If you ! would like to display as few summary lines as possible, but still ! connect as many loose threads as possible, you should set this variable ! to @code{some}. In either case, fetching old headers only works if the ! select method you are using supports @sc{XOVER}. Also remember that if ! the root of the thread has been expired by the server, there's not much ! Gnus can do about that. @item gnus-gather-loose-threads @vindex gnus-gather-loose-threads If non-@code{nil}, Gnus will gather all loose subtrees into one big tree and create a dummy root at the top. (Wait a minute. Root at the top? Yup.) Loose subtrees occur when the real root has expired, or you've ! read or killed the root in a previous session. @item gnus-summary-gather-subject-limit ! Loose threads are gathered by comparing subjects of articles. If this ! variable is @code{nil}, Gnus requires an exact match between the ! subjects of the loose threads before gathering them into one big ! super-thread. This might be too strict a requirement, what with the ! presence of stupid newsreaders that chop off long subjects lines. If ! you think so, set this variable to, say, 20 to require that only the ! first 20 characters of the subjects have to match. If you set this ! variable to a real low number, you'll find that Gnus will gather ! everything in sight into one thread, which isn't very helpful. ! @item gnus-summary-make-false-root @vindex gnus-summary-make-false-root When there is no real root of a thread, Gnus will have to fudge ! something. This variable says what fudging method Gnus should use. ! There are four possible values: @table @code @item adopt Gnus will make the first of the orphaned articles the parent. This parent will adopt all the other articles. The adopted articles will be ! marked as such by pointy brackets instead of the standard square ! brackets. This is the default method. @item dummy ! Gnus will create a dummy summary line that will pretend to be the ! parent. This dummy line does not correspond to any real article, so ! selecting it will just select the first real article after the dummy ! article. @item empty Gnus won't actually make any article the parent, but simply leave the ! subject field of all orphans except the first empty. (Actually, it will ! use @code{gnus-summary-same-subject} as the subject (@pxref{Summary ! Buffer Format}).) @item nil Don't make any article parent at all. Just gather the threads and display them after one another. *************** *** 2803,2810 **** @item gnus-thread-hide-subtree @vindex gnus-thread-hide-subtree ! If non-@code{nil}, all subtrees will be hidden when the summary buffer ! is generated. @item gnus-thread-hide-killed @vindex gnus-thread-hide-killed if you kill a thread and this variable is non-@code{nil}, the subtree --- 3033,3040 ---- @item gnus-thread-hide-subtree @vindex gnus-thread-hide-subtree ! If non-@code{nil}, all threads will be hidden when the summary buffer is ! generated. @item gnus-thread-hide-killed @vindex gnus-thread-hide-killed if you kill a thread and this variable is non-@code{nil}, the subtree *************** *** 2817,2824 **** result in a new thread. @item gnus-thread-indent-level @vindex gnus-thread-indent-level ! This is a number that how much each subthread should be indented. The ! default is @samp{4}. @end table @node Thread Commands --- 3047,3054 ---- result in a new thread. @item gnus-thread-indent-level @vindex gnus-thread-indent-level ! This is a number that says how much each subthread should be indented. ! The default is @samp{4}. @end table @node Thread Commands *************** *** 2831,2839 **** @kindex T k (Summary) @kindex M-C-k (Summary) @findex gnus-summary-kill-thread ! Mark all articles under the current one as read (@code{gnus-summary-kill-thread}). If the prefix argument is positive, ! remove all marks. If the prefix argument is negative, tick articles. @item T l @item M-C-l @kindex T l (Summary) --- 3061,3070 ---- @kindex T k (Summary) @kindex M-C-k (Summary) @findex gnus-summary-kill-thread ! Mark all articles in the current subtread as read (@code{gnus-summary-kill-thread}). If the prefix argument is positive, ! remove all marks instead. If the prefix argument is negative, tick ! articles instead. @item T l @item M-C-l @kindex T l (Summary) *************** *** 2854,2865 **** @item T T @kindex T T (Summary) @findex gnus-summary-toggle-threads ! Toggle showing threads (@code{gnus-summary-toggle-threads}). @item T s @kindex T s (Summary) @findex gnus-summary-show-thread ! Show the thread hidden under the current article, if any ! (@code{gnus-summary-show-thread}). @item T h @kindex T h (Summary) @findex gnus-summary-hide-thread --- 3085,3096 ---- @item T T @kindex T T (Summary) @findex gnus-summary-toggle-threads ! Toggle threading (@code{gnus-summary-toggle-threads}). @item T s @kindex T s (Summary) @findex gnus-summary-show-thread ! Expose the thread hidden under the current article, if any ! (@code{gnus-summary-show-thread}). @item T h @kindex T h (Summary) @findex gnus-summary-hide-thread *************** *** 2867,2880 **** @item T S @kindex T S (Summary) @findex gnus-summary-show-all-threads ! Show all hidden threads (@code{gnus-summary-show-all-threads}). @item T H @kindex T H (Summary) @findex gnus-summary-hide-all-threads Hide all threads (@code{gnus-summary-hide-all-threads}). @end table ! The following commands are all thread movement commands. They all understand the numeric prefix. @table @kbd --- 3098,3111 ---- @item T S @kindex T S (Summary) @findex gnus-summary-show-all-threads ! Expose all hidden threads (@code{gnus-summary-show-all-threads}). @item T H @kindex T H (Summary) @findex gnus-summary-hide-all-threads Hide all threads (@code{gnus-summary-hide-all-threads}). @end table ! The following commands are thread movement commands. They all understand the numeric prefix. @table @kbd *************** *** 2904,2924 **** group and return you to the group buffer. @table @kbd @item q @kindex q (Summary) @findex gnus-summary-exit ! Exit the current group and update all the information ! (@code{gnus-summary-exit}). @item Q @kindex Q (Summary) ! @findex gnus-summary-quit ! Exit the current group without updating any information ! (@code{gnus-summary-quit}). @item c @kindex c (Summary) @findex gnus-summary-catchup-and-exit ! Mark all articles in the group as read and exit ! (@code{gnus-summary-catchup-and-exit}). @end table @vindex gnus-exit-group-hook --- 3135,3165 ---- group and return you to the group buffer. @table @kbd + @item Z Z @item q @kindex q (Summary) @findex gnus-summary-exit ! Exit the current group and update all information on the group ! (@code{gnus-summary-exit}). ! @item Z E @item Q + @kindex Z E (Summary) @kindex Q (Summary) ! @findex gnus-summary-exit-no-update ! Exit the current group without updating any information on the group ! (@code{gnus-summary-exit-no-update}). ! @item Z c @item c + @kindex Z c (Summary) @kindex c (Summary) @findex gnus-summary-catchup-and-exit ! Mark all unticked articles in the group as read and then exit ! (@code{gnus-summary-catchup-and-exit}). ! @item Z C ! @kindex Z C (Summary) ! @findex gnus-summary-catchup-all-and-exit ! Mark all articles, even the ticked ones, as read and then exit ! (@code{gnus-summary-catchup-all-and-exit}). @end table @vindex gnus-exit-group-hook *************** *** 2928,2939 **** @vindex gnus-use-cross-reference When you exit the summary buffer, the data on the current group will be updated (which articles you have read, which articles you have replied ! to, etc.) If the @code{gnus-use-cross-reference} variable is @code{t}, articles ! that are cross-referenced to this group, and are marked as read, will ! also be marked as read in the other subscribed groups they were ! cross-posted to. If this variable is neither @code{nil} nor @code{t}, the ! article will be marked as read in both subscribed and unsubscribed ! groups. Marking cross-posted articles as read ensures that you'll never have to read the same article more than once. Unless, of course, somebody has --- 3169,3180 ---- @vindex gnus-use-cross-reference When you exit the summary buffer, the data on the current group will be updated (which articles you have read, which articles you have replied ! to, etc.) If the @code{gnus-use-cross-reference} variable is @code{t}, ! articles that are cross-referenced to this group, and are marked as ! read, will also be marked as read in the other subscribed groups they ! were cross-posted to. If this variable is neither @code{nil} nor ! @code{t}, the article will be marked as read in both subscribed and ! unsubscribed groups. Marking cross-posted articles as read ensures that you'll never have to read the same article more than once. Unless, of course, somebody has *************** *** 2946,2963 **** separately to several groups is not. One thing that may cause Gnus to not do the cross-posting thing ! correctly is if you use an NNTP server that supports xover (which is ! very nice, because it speeds things up considerably) which does not ! include the Xref header in its NOV lines. This is Evil, but it's ! common. Gnus tries to Do The Right Thing even with xover by registering ! the Xref lines of all articles you actually read, but if you kill the ! articles, or just mark them as read without reading them, Gnus will not ! get a chance to snoop the Xref lines out of these articles, and will be ! unable to use the cross reference mechanism. @vindex gnus-nov-is-evil If you want Gnus to get the Xrefs right all the time, you have to set ! @code{gnus-nov-is-evil} to @code{t}, which slows things down considerably. C'est la vie. --- 3187,3205 ---- separately to several groups is not. One thing that may cause Gnus to not do the cross-posting thing ! correctly is if you use an NNTP server that supports @sc{xover} (which ! is very nice, because it speeds things up considerably) which does not ! include the Xref header in its @sc{NOV} lines. This is Evil, but it's ! common. Gnus tries to Do The Right Thing even with @sc{xover} by ! registering the Xref lines of all articles you actually read, but if you ! kill the articles, or just mark them as read without reading them, Gnus ! will not get a chance to snoop the Xref lines out of these articles, and ! will be unable to use the cross reference mechanism. @vindex gnus-nov-is-evil If you want Gnus to get the Xrefs right all the time, you have to set ! @code{gnus-nov-is-evil} to @code{t}, which slows things down ! considerably. C'est la vie. *************** *** 2996,3021 **** Gnus can save articles in a number of ways. Below is the documentation for saving articles in a fairly straight-forward fashion (ie. little processing of the article is done before it is saved). For a different ! approach (uudecoding, unsharing) see gnus-uu. @xref{Decoding Articles}. @vindex gnus-save-all-headers If @code{gnus-save-all-headers} is non-@code{nil}, Gnus will not delete unwanted headers before saving the article. @table @kbd @item o @kindex o (Summary) @findex gnus-summary-save-article ! Save the current article (@code{gnus-summary-save-article}). ! @item C-o ! @kindex C-o (Summary) @findex gnus-summary-save-article-mail Save the current article in mail format (@code{gnus-summary-save-article-mail}). @end table ! Both these command use the process/prefix convention ! (@pxref{Process/Prefix}). @vindex gnus-default-article-saver You can customize the @code{gnus-default-article-saver} variable to make --- 3238,3287 ---- Gnus can save articles in a number of ways. Below is the documentation for saving articles in a fairly straight-forward fashion (ie. little processing of the article is done before it is saved). For a different ! approach (uudecoding, unsharing) you should use @code{gnus-uu} ! (@pxref{Decoding Articles}). @vindex gnus-save-all-headers If @code{gnus-save-all-headers} is non-@code{nil}, Gnus will not delete unwanted headers before saving the article. @table @kbd + @item V o o @item o + @kindex V o o (Summary) @kindex o (Summary) @findex gnus-summary-save-article ! Save the current article using the default article saver ! (@code{gnus-summary-save-article}). ! @item V o m ! @kindex V o m (Summary) @findex gnus-summary-save-article-mail Save the current article in mail format (@code{gnus-summary-save-article-mail}). + @item V o r + @kindex V o r (Summary) + @findex gnus-summary-save-article-mail + Save the current article in rmail format + (@code{gnus-summary-save-article-rmail}). + @item V o f + @kindex V o f (Summary) + @findex gnus-summary-save-article-file + Save the current article in plain file format + (@code{gnus-summary-save-article-file}). + @item V o h + @kindex V o h (Summary) + @findex gnus-summary-save-article-folder + Save the current article in mh folder format + (@code{gnus-summary-save-article-file}). + @item V o p + @kindex V o p (Summary) + @findex gnus-summary-pipe-output + Save the current article in a pipe. Uhm, like, what I mean is - Pipe + the current article to a process (@code{gnus-summary-pipe-output}). @end table ! All these commands use the process/prefix convention ! (@pxref{Process/Prefix}). @vindex gnus-default-article-saver You can customize the @code{gnus-default-article-saver} variable to make *************** *** 3141,3156 **** entire newsgroup, you'd typically do @kbd{M p a} (@code{gnus-uu-mark-all}) and then @kbd{X U} (@code{gnus-uu-decode-uu}). ! All this is very much different from how gnus-uu worked with @sc{GNUS ! 4.1}, where you had explicit keystrokes for everything under the sun. ! This version of gnus-uu generally assumes that you either mark articles ! in some way (@pxref{Setting Process Marks}) and then press @kbd{X u}. Note: When trying to decode articles that have names matching ! @samp{[Cc][Ii][Nn][Dd][Yy][0-9]+.\\(gif\\|jpg\\)} ! (@code{gnus-uu-notify-files}), gnus-uu will automatically post an ! article on @samp{comp.unix.wizards} saying that you have just viewed the ! file in question. This feature can't be turned off. @node Shared Articles @subsection Shared Articles --- 3407,3424 ---- entire newsgroup, you'd typically do @kbd{M p a} (@code{gnus-uu-mark-all}) and then @kbd{X U} (@code{gnus-uu-decode-uu}). ! All this is very much different from how @code{gnus-uu} worked with ! @sc{GNUS 4.1}, where you had explicit keystrokes for everything under ! the sun. This version of @code{gnus-uu} generally assumes that you ! either mark articles in some way (@pxref{Setting Process Marks}) and ! then press @kbd{X u}. Note: When trying to decode articles that have names matching ! @code{gnus-uu-notify-files}, which hard-coded to ! @samp{[Cc][Ii][Nn][Dd][Yy][0-9]+.\\(gif\\|jpg\\)}, @code{gnus-uu} will ! automatically post an article on @samp{comp.unix.wizards} saying that ! you have just viewed the file in question. This feature can't be turned ! off. @node Shared Articles @subsection Shared Articles *************** *** 3191,3197 **** @subsubsection Rule Variables @cindex rule variables ! Gnus uses @dfn{rule} variables to decide how to view a file. All these variables are on the form @lisp --- 3459,3465 ---- @subsubsection Rule Variables @cindex rule variables ! Gnus uses @dfn{rule variables} to decide how to view a file. All these variables are on the form @lisp *************** *** 3231,3247 **** @item gnus-uu-ignore-files-by-type @vindex gnus-uu-ignore-files-by-type Files with a MIME type matching this variable won't be viewed. Note ! that Gnus tries to guess what type the file is based on the ! name. gnus-uu is not a MIME package, so this is slightly kludgy. @item gnus-uu-tmp-dir @vindex gnus-uu-tmp-dir ! Where gnus-uu does its work. @item gnus-uu-do-not-unpack-archives @vindex gnus-uu-do-not-unpack-archives ! Non-@code{nil} means that gnus-uu won't peek inside archives looking for ! files to dispay. @item gnus-uu-view-and-save @vindex gnus-uu-view-and-save --- 3499,3515 ---- @item gnus-uu-ignore-files-by-type @vindex gnus-uu-ignore-files-by-type Files with a MIME type matching this variable won't be viewed. Note ! that Gnus tries to guess what type the file is based on the name. ! @code{gnus-uu} is not a MIME package, so this is slightly kludgy. @item gnus-uu-tmp-dir @vindex gnus-uu-tmp-dir ! Where @code{gnus-uu} does its work. @item gnus-uu-do-not-unpack-archives @vindex gnus-uu-do-not-unpack-archives ! Non-@code{nil} means that @code{gnus-uu} won't peek inside archives ! looking for files to dispay. @item gnus-uu-view-and-save @vindex gnus-uu-view-and-save *************** *** 3250,3297 **** @item gnus-uu-ignore-default-view-rules @vindex gnus-uu-ignore-default-view-rules ! Non-@code{nil} means that gnus-uu will ignore the default viewing rules. @item gnus-uu-ignore-default-archive-rules @vindex gnus-uu-ignore-default-archive-rules ! Non-@code{nil} means that gnus-uu will ignore the default archive unpacking commands. @item gnus-uu-kill-carriage-return @vindex gnus-uu-kill-carriage-return ! Non-@code{nil} means that gnus-uu will strip all carriage returns from ! articles. @item gnus-uu-unmark-articles-not-decoded @vindex gnus-uu-unmark-articles-not-decoded ! Non-@code{nil} means that gnus-uu will mark articles that were unsuccessfully decoded as unread. @item gnus-uu-correct-stripped-uucode @vindex gnus-uu-correct-stripped-uucode ! Non-@code{nil} means that gnus-uu will *try* to fix uuencoded files that ! have had traling spaces deleted. @item gnus-uu-view-with-metamail @vindex gnus-uu-view-with-metamail ! Non-@code{nil} means that gnus-uu will ignore the viewing commands ! defined by the rule variables and just fudge a MIME content type based ! on the file name. The result will be fed to metamail for viewing. @item gnus-uu-save-in-digest @vindex gnus-uu-save-in-digest ! Non-@code{nil} means that gnus-uu, when asked to save without decoding, ! will save in digests. If this variable is @code{nil}, gnus-uu will just ! save everything in a file without any embellishments. The digesting ! almost conforms to RFC1153 - no easy way to specify any meaningful ! volume and issue numbers were found, so I simply dropped them. @item gnus-uu-post-include-before-composing @vindex gnus-uu-post-include-before-composing ! Non-@code{nil} means that gnus-uu will ask for a file to encode before ! you compose the article. If this variable is @code{t}, you can either ! include an encoded file with @key{C-c C-i} or have one included for you ! when you post the article. @item gnus-uu-post-length @vindex gnus-uu-post-length --- 3518,3568 ---- @item gnus-uu-ignore-default-view-rules @vindex gnus-uu-ignore-default-view-rules ! Non-@code{nil} means that @code{gnus-uu} will ignore the default viewing ! rules. @item gnus-uu-ignore-default-archive-rules @vindex gnus-uu-ignore-default-archive-rules ! Non-@code{nil} means that @code{gnus-uu} will ignore the default archive unpacking commands. @item gnus-uu-kill-carriage-return @vindex gnus-uu-kill-carriage-return ! Non-@code{nil} means that @code{gnus-uu} will strip all carriage returns ! from articles. @item gnus-uu-unmark-articles-not-decoded @vindex gnus-uu-unmark-articles-not-decoded ! Non-@code{nil} means that @code{gnus-uu} will mark articles that were unsuccessfully decoded as unread. @item gnus-uu-correct-stripped-uucode @vindex gnus-uu-correct-stripped-uucode ! Non-@code{nil} means that @code{gnus-uu} will @emph{try} to fix ! uuencoded files that have had traling spaces deleted. @item gnus-uu-view-with-metamail @vindex gnus-uu-view-with-metamail ! Non-@code{nil} means that @code{gnus-uu} will ignore the viewing ! commands defined by the rule variables and just fudge a MIME content ! type based on the file name. The result will be fed to metamail for ! viewing. @item gnus-uu-save-in-digest @vindex gnus-uu-save-in-digest ! Non-@code{nil} means that @code{gnus-uu}, when asked to save without ! decoding, will save in digests. If this variable is @code{nil}, ! @code{gnus-uu} will just save everything in a file without any ! embellishments. The digesting almost conforms to RFC1153 - no easy way ! to specify any meaningful volume and issue numbers were found, so I ! simply dropped them. @item gnus-uu-post-include-before-composing @vindex gnus-uu-post-include-before-composing ! Non-@code{nil} means that @code{gnus-uu} will ask for a file to encode ! before you compose the article. If this variable is @code{t}, you can ! either include an encoded file with @key{C-c C-i} or have one included ! for you when you post the article. @item gnus-uu-post-length @vindex gnus-uu-post-length *************** *** 3300,3310 **** @item gnus-uu-post-threaded @vindex gnus-uu-post-threaded ! Non-@code{nil} means that gnus-uu will post the encoded file in a thread. This may not be smart, as no other decoder I have seen are able to follow threads when collecting uuencoded articles. (Well, I have ! seen one package that does that - gnus-uu, but somehow, I don't think ! that counts...) Default is @code{nil}. @item gnus-uu-post-separate-description @vindex gnus-uu-post-separate-description --- 3571,3581 ---- @item gnus-uu-post-threaded @vindex gnus-uu-post-threaded ! Non-@code{nil} means that @code{gnus-uu} will post the encoded file in a thread. This may not be smart, as no other decoder I have seen are able to follow threads when collecting uuencoded articles. (Well, I have ! seen one package that does that - @code{gnus-uu}, but somehow, I don't ! think that counts...) Default is @code{nil}. @item gnus-uu-post-separate-description @vindex gnus-uu-post-separate-description *************** *** 3378,3388 **** @findex gnus-summary-toggle-mime Toggle whether to run the article through MIME before displaying (@code{gnus-summary-toggle-mime}). - @item V | - @kindex V | (Summary) - @findex gnus-summary-pipe-output - Pipe the current article to a process - (@code{gnus-summary-pipe-output}). @end table There's a battery of commands for washing the article buffer: --- 3649,3654 ---- *************** *** 3445,3450 **** --- 3711,3723 ---- Sort by date (@code{gnus-summary-sort-by-date}). @end table + These functions will work both when you use threading and when you don't + use threading. In the former case, all summary lines will be sorted, + line by line. In the latter case, sorting will be done on a + root-by-root basis, which might not be what you were looking for. To + toggle whether to use threading, type @kbd{T T} (@pxref{Thread + Commands}). + @node Finding the Parent @section Finding the Parent @cindex parent articles *************** *** 3456,3472 **** displayed in the article buffer, you might still be able to. That is, if the current group is fetched by NNTP, the parent hasn't expired and the References in the current article are not mangled, you can just ! press @kbd{^} (@code{gnus-summary-refer-parent-article}). If everything ! goes well, you'll get the parent. If the parent is already displayed in ! the summary buffer, point will just move to this article. @findex gnus-summary-refer-article @kindex M-^ (Summary) You can also ask the NNTP server for an arbitrary article, no matter ! what group it belongs to. @kbd{M-^} (@code{gnus-summary-refer-article}) will ask you for a message-id, which is one of those long thingies that look something like @samp{<38o6up$6f2@@hymir.ifi.uio.no>}. You have to ! get it all exactly right. @vindex gnus-refer-article-method If the group you are reading is located on a backend that does not --- 3729,3746 ---- displayed in the article buffer, you might still be able to. That is, if the current group is fetched by NNTP, the parent hasn't expired and the References in the current article are not mangled, you can just ! press @kbd{^} or @kbd{A r} (@code{gnus-summary-refer-parent-article}). ! If everything goes well, you'll get the parent. If the parent is ! already displayed in the summary buffer, point will just move to this ! article. @findex gnus-summary-refer-article @kindex M-^ (Summary) You can also ask the NNTP server for an arbitrary article, no matter ! what group it belongs to. @kbd{V r} (@code{gnus-summary-refer-article}) will ask you for a message-id, which is one of those long thingies that look something like @samp{<38o6up$6f2@@hymir.ifi.uio.no>}. You have to ! get it all exactly right. No fuzzy searches, I'm afraid. @vindex gnus-refer-article-method If the group you are reading is located on a backend that does not *************** *** 3517,3529 **** @subsection Summary Score Commands @cindex score commands ! General score commands don't actually change score files: @table @kbd @item V S s @kindex V S s (Summary) @findex gnus-summary-set-score Set the score of the current article (@code{gnus-summary-set-score}). @item I C-i @kindex I C-i (Summary) @findex gnus-summary-raise-score --- 3791,3830 ---- @subsection Summary Score Commands @cindex score commands ! All score commands that alter score entries do not actually work towards ! a real score file. That would be to inefficient. Gnus maintains a ! cache of previously loaded score files, one of which is considered the ! @dfn{current score file alist}. The score commands simply insert ! entries into this list, and upon group exit, this list is saved. ! ! The current score file is always the group's local score file, even if ! no such score file actually exists. To insert score commands into some ! other score file (eg. @file{all.SCORE}), you must first make this score ! file the current one. ! ! General score commands that don't actually change the score file: @table @kbd @item V S s @kindex V S s (Summary) @findex gnus-summary-set-score Set the score of the current article (@code{gnus-summary-set-score}). + @item V S c + @kindex V S c (Summary) + @findex gnus-score-change-score-file + Make a different score file the current + (@code{gnus-score-change-score-file}). + @item V S e + @kindex V S e (Summary) + @findex gnus-score-edit-alist + Edit the current score file (@code{gnus-score-edit-alist}). You will be + popped into a @code{gnus-score-mode} buffer (@pxref{Score File + Editing}). + @item V S f + @kindex V S f (Summary) + @findex gnus-score-edit-file + Edit a score file and make this score file the current one + (@code{gnus-score-edit-file}). @item I C-i @kindex I C-i (Summary) @findex gnus-summary-raise-score *************** *** 3534,3550 **** @findex gnus-summary-lower-score Lower the score of the current article (@code{gnus-summary-lower-score}). - @item V S c - @kindex V S c (Summary) - @findex gnus-score-change-score-file - Make a different score file the current - (@code{gnus-score-change-score-file}). - @item V S e - @kindex V S e (Summary) - @findex gnus-score-edit-file - Edit the current score file (@code{gnus-score-edit-file}). You will be - popped into a @code{gnus-score-mode} buffer (@pxref{Score File - Editing}). @end table The rest of these commands modify the local score file. --- 3835,3840 ---- *************** *** 3562,3568 **** numeric prefix) (@code{gnus-score-set-expunge-below}). @end table ! Commands for increasing score: @table @kbd @item I s t --- 3852,3858 ---- numeric prefix) (@code{gnus-score-set-expunge-below}). @end table ! Commands for increasing the score: @table @kbd @item I s t *************** *** 3627,3633 **** (@code{gnus-summary-raise-followups-to-author}). @end table ! Commands for lowering score: @table @kbd @item L s t --- 3917,3923 ---- (@code{gnus-summary-raise-followups-to-author}). @end table ! Commands for lowering the score: @table @kbd @item L s t *************** *** 3848,3855 **** might feel the urge to edit them by hand as well, so we've supplied you with a mode for that. ! It's simply a slightly customized emacs-lisp mode, with these additional ! commands: @table @kbd @item C-c C-c --- 4138,4145 ---- might feel the urge to edit them by hand as well, so we've supplied you with a mode for that. ! It's simply a slightly customized @code{emacs-lisp} mode, with these ! additional commands: @table @kbd @item C-c C-c *************** *** 3869,3875 **** @subsection Scoring Tips @cindex scoring tips ! @table . @item Crossposts If you want to lower the score of crossposts, the line to match on is the Xref header. --- 4159,4165 ---- @subsection Scoring Tips @cindex scoring tips ! @itemize @bullet @item Crossposts If you want to lower the score of crossposts, the line to match on is the Xref header. *************** *** 3882,3888 **** @lisp ("xref" (" +[^ ]+:[0-9]+ +[^ ]+:[0-9]+ +[^ ]+:[0-9]+" -1000 nil r)) @end lisp ! @end table @node Global Score Files @subsection Global Score Files --- 4172,4178 ---- @lisp ("xref" (" +[^ ]+:[0-9]+ +[^ ]+:[0-9]+ +[^ ]+:[0-9]+" -1000 nil r)) @end lisp ! @end itemize @node Global Score Files @subsection Global Score Files *************** *** 3951,3957 **** @end itemize ... I wonder whether other newsreaders will support global score files ! in the future. *Snicker*. Yup, any day now, newsreaders like Blue Wave, xrn and 1stReader are bound to implement scoring. Should we start holding our breath yet? --- 4241,4247 ---- @end itemize ... I wonder whether other newsreaders will support global score files ! in the future. @emph{Snicker}. Yup, any day now, newsreaders like Blue Wave, xrn and 1stReader are bound to implement scoring. Should we start holding our breath yet? *************** *** 4005,4017 **** @node Various Summary Stuff @section Various Summary Stuff @table @kbd - @item V D - @kindex V D (Summary) - @findex gnus-summary-enter-digest-group - If the current article is a digest, you might use this command to enter - you into a group based onthe current digest to ease reading - (@code{gnus-summary-enter-digest-group}). @xref{nndigest}. @item V f @kindex V f (Summary) @findex gnus-summary-fetch-faq --- 4295,4316 ---- @node Various Summary Stuff @section Various Summary Stuff + @menu + * Group Information:: Information oriented commands. + * Searching for Articles:: Multiple article commands. + * Really Various Summary Commands:: Those pesky non-conformant commands. + @end menu + + @vindex gnus-summary-prepare-hook + @code{gnus-summary-prepare-hook} is called after the summary buffer has + been generated. You might use it to, for instance, hilight lines or + modify the look of the buffer in some other ungodly manner. I don't + care. + + @node Group Information + @subsection Group Information + @table @kbd @item V f @kindex V f (Summary) @findex gnus-summary-fetch-faq *************** *** 4020,4031 **** current group (@code{gnus-summary-fetch-faq}). Gnus will try to get the FAQ from @code{gnus-group-faq-directory}, which is usually a directory on a remote machine. ange-ftp will be used for fetching the file. ! @item & ! @kindex & (Summary) ! @findex gnus-summary-expand-window ! This command will prompt you for a header field, a regular expression to ! be matched this field, and a command to be executed if the match is ! made. @item V C-s @kindex V C-s (Summary) @findex gnus-summary-search-article-forward --- 4319,4345 ---- current group (@code{gnus-summary-fetch-faq}). Gnus will try to get the FAQ from @code{gnus-group-faq-directory}, which is usually a directory on a remote machine. ange-ftp will be used for fetching the file. ! @item V d ! @kindex V d (Summary) ! @findex gnus-summary-describe-group ! Give a brief description of the current group ! (@code{gnus-summary-describe-group}). If given a prefix, force reading ! new description from the server. ! @item V ? ! @kindex V ? (Summary) ! @findex gnus-summary-describe-briefly ! Give a very brief description of the most important summary keystrokes ! (@code{gnus-summary-describe-briefly}). ! @item V i ! @kindex V i (Summary) ! @findex gnus-info-find-node ! Go to the Gnus info node (@code{gnus-info-find-node}). ! @end table ! ! @node Searching for Articles ! @subsection Searching for Articles ! ! @table @kbd @item V C-s @kindex V C-s (Summary) @findex gnus-summary-search-article-forward *************** *** 4036,4041 **** --- 4350,4378 ---- @findex gnus-summary-search-article-backward Search through all previous articles for a regexp (@code{gnus-summary-search-article-backward}). + @item V & + @kindex V & (Summary) + @findex gnus-summary-execute-command + This command will prompt you for a header field, a regular expression to + be matched this field, and a command to be executed if the match is + made (@code{gnus-summary-execute-command}). + @item V u + @kindex V u (Summary) + @findex gnus-summary-universal-argument + Perform any operation on all articles that have been marked with + the process mark (@code{gnus-summary-universal-argument}). + @end table + + @node Really Various Summary Commands + @subsection Really Various Summary Commands + + @table @kbd + @item V D + @kindex V D (Summary) + @findex gnus-summary-enter-digest-group + If the current article is a digest, you might use this command to enter + you into a group based onthe current digest to ease reading + (@code{gnus-summary-enter-digest-group}). @xref{nndigest}. @item V T @kindex V T (Summary) @findex gnus-summary-toggle-truncation *************** *** 4049,4060 **** @findex gnus-summary-reselect-current-group Exit this group, and then enter it again (@code{gnus-summary-reselect-current-group}). - @item V d - @kindex V d (Summary) - @findex gnus-summary-describe-group - Give a brief description of the current group - (@code{gnus-summary-describe-group}). If given a prefix, force reading - new description from the server. @item V g @item M-g @kindex V g (Summary) --- 4386,4391 ---- *************** *** 4062,4087 **** @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 ! @kindex V (Summary) ! @findex gnus-version ! Display the Gnus version numbers (@code{gnus-version}). ! @item V ? ! @kindex V ? (Summary) ! @findex gnus-summary-describe-briefly ! Give a very brief description of the most important summary keystrokes ! (@code{gnus-summary-describe-briefly}). ! @item V i ! @kindex V i (Summary) ! @findex gnus-info-find-node ! Go to the Gnus info node (@code{gnus-info-find-node}). @end table - @vindex gnus-summary-prepare-hook - @code{gnus-summary-prepare-hook} is called after the summary buffer has - been generated. You might use it to, for instance, hilight lines, modify - the look, or anything else you feel like. I don't care. - @node The Article Buffer @chapter The Article Buffer @cindex article buffer --- 4393,4408 ---- @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 @chapter The Article Buffer @cindex article buffer *************** *** 4184,4199 **** @vindex gnus-show-mime-method Gnus handles MIME by shoving the articles through @code{gnus-show-mime-method}, which is @code{metamail-buffer} by ! default. Set @code{gnus-show-mime} to @code{t} if you want to use MIME all the ! time; it might be best just use the toggling functions from the summary ! buffer to avoid getting nasty surprises (for instance, you enter the ! group @samp{alt.sing-a-long} and, before you know it, MIME has decoded ! the sounds file in the article and some horrible sing-a-long song comes ! streaming out out your speakers, and you can't find the volume button, ! because there isn't one, and people are starting to look at you, and you ! try to stop the program, but you can't, and you can't find the program ! to control the volume, and everybody else in the room suddenly decides ! to look at you disdainfully, and you'll feel rather stupid.) Any similarity to real events and people is purely coincidental. Ahem. --- 4505,4521 ---- @vindex gnus-show-mime-method Gnus handles MIME by shoving the articles through @code{gnus-show-mime-method}, which is @code{metamail-buffer} by ! default. Set @code{gnus-show-mime} to @code{t} if you want to use MIME ! all the time; it might be best just use the toggling functions from the ! summary buffer to avoid getting nasty surprises (for instance, you enter ! the group @samp{alt.sing-a-long} and, before you know it, MIME has ! decoded the sounds file in the article and some horrible sing-a-long ! song comes streaming out out your speakers, and you can't find the ! volume button, because there isn't one, and people are starting to look ! at you, and you try to stop the program, but you can't, and you can't ! find the program to control the volume, and everybody else in the room ! suddenly decides to look at you disdainfully, and you'll feel rather ! stupid.) Any similarity to real events and people is purely coincidental. Ahem. *************** *** 4392,4401 **** @item gnus-updated-mode-lines @vindex gnus-updated-mode-lines This is a list of buffers that should keep their mode lines updated. ! The list may contain the symbols `group', `article' and `summary'. If ! the corresponding symbol is present, Gnus will keep that mode line ! updated with information that may be pertinent. If this variable is ! @code{nil}, screen refresh may be quicker. @item gnus-mode-non-string-length @vindex gnus-mode-non-string-length --- 4714,4723 ---- @item gnus-updated-mode-lines @vindex gnus-updated-mode-lines This is a list of buffers that should keep their mode lines updated. ! The list may contain the symbols @code{group}, @code{article} and ! @code{summary}. If the corresponding symbol is present, Gnus will keep ! that mode line updated with information that may be pertinent. If this ! variable is @code{nil}, screen refresh may be quicker. @item gnus-mode-non-string-length @vindex gnus-mode-non-string-length *************** *** 4458,4464 **** @item gnus-nov-is-evil This one has to be @code{nil}. If not, grabbing article headers from the NNTP server will not be very fast. Not all NNTP servers support ! XOVER; Gnus will detect this by itself. @end table @node Slow Terminal Connection --- 4780,4786 ---- @item gnus-nov-is-evil This one has to be @code{nil}. If not, grabbing article headers from the NNTP server will not be very fast. Not all NNTP servers support ! @sc{XOVER}; Gnus will detect this by itself. @end table @node Slow Terminal Connection *************** *** 4565,4572 **** backtrace. I will fix bugs, but I can only fix them if you send me a precise description as to how to reproduce the bug. ! If you just need help, you are better off asking on ! @samp{gnu.emacs.gnus}. @node Index @chapter Index --- 4887,4894 ---- backtrace. I will fix bugs, but I can only fix them if you send me a precise description as to how to reproduce the bug. ! @c If you just need help, you are better off asking on ! @c @samp{gnu.emacs.gnus}. @node Index @chapter Index