1 ;;; gnus.el --- a newsreader for GNU Emacs
2 ;; Copyright (C) 1987,88,89,90,93,94,95,96 Free Software Foundation, Inc.
4 ;; Author: Masanobu UMEDA <umerin@flab.flab.fujitsu.junet>
5 ;; Lars Magne Ingebrigtsen <larsi@ifi.uio.no>
8 ;; This file is part of GNU Emacs.
10 ;; GNU Emacs is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, or (at your option)
15 ;; GNU Emacs is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GNU Emacs; see the file COPYING. If not, write to the
22 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
23 ;; Boston, MA 02111-1307, USA.
29 (eval '(run-hooks 'gnus-load-hook))
31 (defconst gnus-version-number "0.5"
32 "Version number for this version of Gnus.")
34 (defconst gnus-version (format "Red Gnus v%s" gnus-version-number)
35 "Version string for this version of Gnus.")
37 (defvar gnus-inhibit-startup-message nil
38 "*If non-nil, the startup message will not be displayed.")
40 ;;; Internal variables
42 (defvar gnus-group-buffer "*Group*")
48 (switch-to-buffer gnus-group-buffer)
49 (let ((buffer-read-only nil))
51 (unless gnus-inhibit-startup-message
52 (gnus-group-startup-message)
55 (defun gnus-indent-rigidly (start end arg)
56 "Indent rigidly using only spaces and no tabs."
59 (narrow-to-region start end)
60 (indent-rigidly start end arg)
61 (goto-char (point-min))
62 (while (search-forward "\t" nil t)
63 (replace-match " " t t)))))
65 (defun gnus-group-startup-message (&optional x y)
66 "Insert startup message in current buffer."
67 ;; Insert the message.
92 (gnus-indent-rigidly (point-min) (point-max)
93 (/ (max (- (window-width) (or x 46)) 0) 2))
94 (goto-char (point-min))
96 (let* ((pheight (count-lines (point-min) (point-max)))
97 (wheight (window-height))
98 (rest (- wheight pheight)))
99 (insert (make-string (max 0 (* 2 (/ rest 3))) ?\n)))
101 (goto-char (point-min))
102 (and (search-forward "Praxis" nil t)
103 (put-text-property (match-beginning 0) (match-end 0) 'face 'bold))
104 (goto-char (point-min))
105 (setq mode-line-buffer-identification gnus-version)
106 (set-buffer-modified-p t))
117 ;; Fix by Hallvard B Furuseth <h.b.furuseth@usit.uio.no>.
118 ;; If you want the cursor to go somewhere else, set these two
119 ;; functions in some startup hook to whatever you want.
120 (defalias 'gnus-summary-position-point 'gnus-goto-colon)
121 (defalias 'gnus-group-position-point 'gnus-goto-colon)
123 ;;; Various macros and substs.
125 (defun gnus-header-from (header)
126 (mail-header-from header))
128 (defmacro gnus-gethash (string hashtable)
129 "Get hash value of STRING in HASHTABLE."
130 `(symbol-value (intern-soft ,string ,hashtable)))
132 (defmacro gnus-sethash (string value hashtable)
133 "Set hash value. Arguments are STRING, VALUE, and HASHTABLE."
134 `(set (intern ,string ,hashtable) ,value))
136 (defmacro gnus-group-unread (group)
137 "Get the currently computed number of unread articles in GROUP."
138 `(car (gnus-gethash ,group gnus-newsrc-hashtb)))
140 (defmacro gnus-group-entry (group)
141 "Get the newsrc entry for GROUP."
142 `(gnus-gethash ,group gnus-newsrc-hashtb))
144 (defmacro gnus-active (group)
145 "Get active info on GROUP."
146 `(gnus-gethash ,group gnus-active-hashtb))
148 (defmacro gnus-set-active (group active)
149 "Set GROUP's active info."
150 `(gnus-sethash ,group ,active gnus-active-hashtb))
152 (defun gnus-alive-p ()
153 "Say whether Gnus is running or not."
154 (and gnus-group-buffer
155 (get-buffer gnus-group-buffer)
157 (set-buffer gnus-group-buffer)
158 (eq major-mode 'gnus-group-mode))))
160 ;; Info access macros.
162 (defmacro gnus-info-group (info)
164 (defmacro gnus-info-rank (info)
166 (defmacro gnus-info-read (info)
168 (defmacro gnus-info-marks (info)
170 (defmacro gnus-info-method (info)
172 (defmacro gnus-info-params (info)
175 (defmacro gnus-info-level (info)
176 `(let ((rank (gnus-info-rank ,info)))
180 (defmacro gnus-info-score (info)
181 `(let ((rank (gnus-info-rank ,info)))
182 (or (and (consp rank) (cdr rank)) 0)))
184 (defmacro gnus-info-set-group (info group)
185 `(setcar ,info ,group))
186 (defmacro gnus-info-set-rank (info rank)
187 `(setcar (nthcdr 1 ,info) ,rank))
188 (defmacro gnus-info-set-read (info read)
189 `(setcar (nthcdr 2 ,info) ,read))
190 (defmacro gnus-info-set-marks (info marks &optional extend)
192 `(gnus-info-set-entry ,info ,marks 3)
193 `(setcar (nthcdr 3 ,info) ,marks)))
194 (defmacro gnus-info-set-method (info method &optional extend)
196 `(gnus-info-set-entry ,info ,method 4)
197 `(setcar (nthcdr 4 ,info) ,method)))
198 (defmacro gnus-info-set-params (info params &optional extend)
200 `(gnus-info-set-entry ,info ,params 5)
201 `(setcar (nthcdr 5 ,info) ,params)))
203 (defun gnus-info-set-entry (info entry number)
204 ;; Extend the info until we have enough elements.
205 (while (< (length info) number)
206 (nconc info (list nil)))
208 (setcar (nthcdr number info) entry))
210 (defmacro gnus-info-set-level (info level)
211 `(let ((rank (cdr ,info)))
212 (if (consp (car rank))
213 (setcar (car rank) ,level)
214 (setcar rank ,level))))
215 (defmacro gnus-info-set-score (info score)
216 `(let ((rank (cdr ,info)))
217 (if (consp (car rank))
218 (setcdr (car rank) ,score)
219 (setcar rank (cons (car rank) ,score)))))
221 (defmacro gnus-get-info (group)
222 `(nth 2 (gnus-gethash ,group gnus-newsrc-hashtb)))
224 ;; Byte-compiler warning.
226 ;; Find out whether the gnus-visual TYPE is wanted.
227 (defun gnus-visual-p (&optional type class)
228 (and gnus-visual ; Has to be non-nil, at least.
229 (if (not type) ; We don't care about type.
231 (if (listp gnus-visual) ; It's a list, so we check it.
232 (or (memq type gnus-visual)
233 (memq class gnus-visual))
236 ;;; Load the compatability functions.
246 (defvar gnus-shutdown-alist nil)
248 (defun gnus-add-shutdown (function &rest symbols)
249 "Run FUNCTION whenever one of SYMBOLS is shut down."
250 (push (cons function symbols) gnus-shutdown-alist))
252 (defun gnus-shutdown (symbol)
253 "Shut down everything that waits for SYMBOL."
254 (let ((alist gnus-shutdown-alist)
256 (while (setq entry (pop alist))
257 (when (memq symbol (cdr entry))
258 (funcall (car entry))))))
262 ;;; Gnus Utility Functions
265 ;; Add the current buffer to the list of buffers to be killed on exit.
266 (defun gnus-add-current-to-buffer-list ()
267 (or (memq (current-buffer) gnus-buffer-list)
268 (setq gnus-buffer-list (cons (current-buffer) gnus-buffer-list))))
270 (defun gnus-version (&optional arg)
271 "Version number of this version of Gnus.
272 If ARG, insert string at point."
274 (let ((methods gnus-valid-select-methods)
277 ;; Go through all the legal select methods and add their version
278 ;; numbers to the total version string. Only the backends that are
279 ;; currently in use will have their message numbers taken into
282 (setq meth (intern (concat (caar methods) "-version")))
284 (stringp (symbol-value meth))
285 (setq mess (concat mess "; " (symbol-value meth))))
286 (setq methods (cdr methods)))
288 (insert (message mess))
291 (defun gnus-continuum-version (version)
292 "Return VERSION as a floating point number."
293 (when (or (string-match "^\\([^ ]+\\)? ?Gnus v?\\([0-9.]+\\)$" version)
294 (string-match "^\\(.?\\)gnus-\\([0-9.]+\\)$" version))
295 (let* ((alpha (and (match-beginning 1) (match-string 1 version)))
296 (number (match-string 2 version))
298 (string-match "\\([0-9]\\)\\.\\([0-9]+\\)\\.?\\([0-9]+\\)?" number)
299 (setq major (string-to-number (match-string 1 number)))
300 (setq minor (string-to-number (match-string 2 number)))
301 (setq least (if (match-beginning 3)
302 (string-to-number (match-string 3 number))
306 (format "%s00%02d%02d"
308 ((member alpha '("(ding)" "d")) "4.99")
309 ((member alpha '("September" "s")) "5.01")
310 ((member alpha '("Red" "r")) "5.03"))
312 (format "%d.%02d%02d" major minor least))))))
314 (defun gnus-info-find-node ()
315 "Find Info documentation of Gnus."
317 ;; Enlarge info window if needed.
318 (let ((mode major-mode)
320 (Info-goto-node (cadr (assq mode gnus-info-nodes)))
321 (setq gnus-info-buffer (current-buffer))
322 (gnus-configure-windows 'info)))
324 ;;; More various functions.
326 (defun gnus-group-read-only-p (&optional group)
327 "Check whether GROUP supports editing or not.
328 If GROUP is nil, `gnus-newsgroup-name' will be checked instead. Note
329 that that variable is buffer-local to the summary buffers."
330 (let ((group (or group gnus-newsgroup-name)))
331 (not (gnus-check-backend-function 'request-replace-article group))))
333 (defun gnus-group-total-expirable-p (group)
334 "Check whether GROUP is total-expirable or not."
335 (let ((params (gnus-info-params (gnus-get-info group))))
336 (or (memq 'total-expire params)
337 (cdr (assq 'total-expire params)) ; (total-expire . t)
338 (and gnus-total-expirable-newsgroups ; Check var.
339 (string-match gnus-total-expirable-newsgroups group)))))
341 (defun gnus-group-auto-expirable-p (group)
342 "Check whether GROUP is total-expirable or not."
343 (let ((params (gnus-info-params (gnus-get-info group))))
344 (or (memq 'auto-expire params)
345 (cdr (assq 'auto-expire params)) ; (auto-expire . t)
346 (and gnus-auto-expirable-newsgroups ; Check var.
347 (string-match gnus-auto-expirable-newsgroups group)))))
349 (defun gnus-virtual-group-p (group)
350 "Say whether GROUP is virtual or not."
351 (memq 'virtual (assoc (symbol-name (car (gnus-find-method-for-group group)))
352 gnus-valid-select-methods)))
354 (defun gnus-news-group-p (group &optional article)
355 "Return non-nil if GROUP (and ARTICLE) come from a news server."
356 (or (gnus-member-of-valid 'post group) ; Ordinary news group.
357 (and (gnus-member-of-valid 'post-mail group) ; Combined group.
358 (eq (gnus-request-type group article) 'news))))
360 ;; Returns a list of writable groups.
361 (defun gnus-writable-groups ()
362 (let ((alist gnus-newsrc-alist)
364 (while (setq group (car (pop alist)))
365 (unless (gnus-group-read-only-p group)
366 (push group groups)))
369 ;; Check whether to use long file names.
370 (defun gnus-use-long-file-name (symbol)
371 ;; The variable has to be set...
372 (and gnus-use-long-file-name
373 ;; If it isn't a list, then we return t.
374 (or (not (listp gnus-use-long-file-name))
375 ;; If it is a list, and the list contains `symbol', we
377 (not (memq symbol gnus-use-long-file-name)))))
379 ;; Generate a unique new group name.
380 (defun gnus-generate-new-group-name (leaf)
383 (while (gnus-gethash name gnus-newsrc-hashtb)
384 (setq name (concat leaf "<" (int-to-string (setq num (1+ num))) ">")))
387 (defun gnus-ephemeral-group-p (group)
388 "Say whether GROUP is ephemeral or not."
389 (gnus-group-get-parameter group 'quit-config))
391 (defun gnus-group-quit-config (group)
392 "Return the quit-config of GROUP."
393 (gnus-group-get-parameter group 'quit-config))
395 (defun gnus-simplify-mode-line ()
396 "Make mode lines a bit simpler."
397 (setq mode-line-modified "-- ")
398 (when (listp mode-line-format)
399 (make-local-variable 'mode-line-format)
400 (setq mode-line-format (copy-sequence mode-line-format))
401 (when (equal (nth 3 mode-line-format) " ")
402 (setcar (nthcdr 3 mode-line-format) " "))))
404 ;;; Servers and groups.
406 (defsubst gnus-server-add-address (method)
407 (let ((method-name (symbol-name (car method))))
408 (if (and (memq 'address (assoc method-name gnus-valid-select-methods))
409 (not (assq (intern (concat method-name "-address")) method)))
410 (append method (list (list (intern (concat method-name "-address"))
414 (defsubst gnus-server-get-method (group method)
415 ;; Input either a server name, and extended server name, or a
416 ;; select method, and return a select method.
417 (cond ((stringp method)
418 (gnus-server-to-method method))
419 ((equal method gnus-select-method)
421 ((and (stringp (car method)) group)
422 (gnus-server-extend-method group method))
423 ((and method (not group)
424 (equal (cadr method) ""))
427 (gnus-server-add-address method))))
429 (defun gnus-server-to-method (server)
430 "Map virtual server names to select methods."
432 ;; Is this a method, perhaps?
433 (and server (listp server) server)
434 ;; Perhaps this is the native server?
435 (and (equal server "native") gnus-select-method)
436 ;; It should be in the server alist.
437 (cdr (assoc server gnus-server-alist))
438 ;; If not, we look through all the opened server
439 ;; to see whether we can find it there.
440 (let ((opened gnus-opened-servers))
442 (not (equal server (format "%s:%s" (caaar opened)
447 (defmacro gnus-method-equal (ss1 ss2)
448 "Say whether two servers are equal."
452 (and (= (length s1) (length s2))
454 (while (and s1 (member (car s1) s2))
458 (defun gnus-server-equal (m1 m2)
459 "Say whether two methods are equal."
460 (let ((m1 (cond ((null m1) gnus-select-method)
461 ((stringp m1) (gnus-server-to-method m1))
463 (m2 (cond ((null m2) gnus-select-method)
464 ((stringp m2) (gnus-server-to-method m2))
466 (gnus-method-equal m1 m2)))
468 (defun gnus-servers-using-backend (backend)
469 "Return a list of known servers using BACKEND."
470 (let ((opened gnus-opened-servers)
473 (when (eq backend (caaar opened))
474 (push (caar opened) out))
478 (defun gnus-archive-server-wanted-p ()
479 "Say whether the user wants to use the archive server."
481 ((or (not gnus-message-archive-method)
482 (not gnus-message-archive-group))
484 ((and gnus-message-archive-method gnus-message-archive-group)
487 (let ((active (cadr (assq 'nnfolder-active-file
488 gnus-message-archive-method))))
490 (file-exists-p active))))))
492 (defun gnus-group-prefixed-name (group method)
493 "Return the whole name from GROUP and METHOD."
494 (and (stringp method) (setq method (gnus-server-to-method method)))
497 (concat (format "%s" (car method))
499 (or (assoc (format "%s" (car method))
500 (gnus-methods-using 'address))
501 (gnus-server-equal method gnus-message-archive-method))
503 (not (string= (nth 1 method) "")))
504 (concat "+" (nth 1 method)))
507 (defun gnus-group-real-prefix (group)
508 "Return the prefix of the current group name."
509 (if (string-match "^[^:]+:" group)
510 (substring group 0 (match-end 0))
513 (defun gnus-group-method (group)
514 "Return the server or method used for selecting GROUP."
515 (let ((prefix (gnus-group-real-prefix group)))
516 (if (equal prefix "")
518 (let ((servers gnus-opened-servers)
520 backend possible found)
521 (if (string-match "^[^\\+]+\\+" prefix)
522 (setq backend (intern (substring prefix 0 (1- (match-end 0))))
523 server (substring prefix (match-end 0) (1- (length prefix))))
524 (setq backend (intern (substring prefix 0 (1- (length prefix))))))
526 (when (eq (caaar servers) backend)
527 (setq possible (caar servers))
528 (when (equal (cadaar servers) server)
529 (setq found (caar servers))))
531 (or (car (rassoc found gnus-server-alist))
533 (car (rassoc possible gnus-server-alist))
535 (list backend server))))))
537 (defsubst gnus-secondary-method-p (method)
538 "Return whether METHOD is a secondary select method."
539 (let ((methods gnus-secondary-select-methods)
540 (gmethod (gnus-server-get-method nil method)))
542 (not (equal (gnus-server-get-method nil (car methods))
544 (setq methods (cdr methods)))
547 (defun gnus-group-foreign-p (group)
548 "Say whether a group is foreign or not."
549 (and (not (gnus-group-native-p group))
550 (not (gnus-group-secondary-p group))))
552 (defun gnus-group-native-p (group)
553 "Say whether the group is native or not."
554 (not (string-match ":" group)))
556 (defun gnus-group-secondary-p (group)
557 "Say whether the group is secondary or not."
558 (gnus-secondary-method-p (gnus-find-method-for-group group)))
560 (defun gnus-group-get-parameter (group &optional symbol)
561 "Returns the group parameters for GROUP.
562 If SYMBOL, return the value of that symbol in the group parameters."
563 (let ((params (gnus-info-params (gnus-get-info group))))
565 (gnus-group-parameter-value params symbol)
568 (defun gnus-group-parameter-value (params symbol)
569 "Return the value of SYMBOL in group PARAMS."
570 (or (car (memq symbol params)) ; It's either a simple symbol
571 (cdr (assq symbol params)))) ; or a cons.
573 (defun gnus-group-add-parameter (group param)
574 "Add parameter PARAM to GROUP."
575 (let ((info (gnus-get-info group)))
577 () ; This is a dead group. We just ignore it.
578 ;; Cons the new param to the old one and update.
579 (gnus-group-set-info (cons param (gnus-info-params info))
582 (defun gnus-group-set-parameter (group name value)
583 "Set parameter NAME to VALUE in GROUP."
584 (let ((info (gnus-get-info group)))
586 () ; This is a dead group. We just ignore it.
587 (let ((old-params (gnus-info-params info))
588 (new-params (list (cons name value))))
590 (if (or (not (listp (car old-params)))
591 (not (eq (caar old-params) name)))
592 (setq new-params (append new-params (list (car old-params)))))
593 (setq old-params (cdr old-params)))
594 (gnus-group-set-info new-params group 'params)))))
596 (defun gnus-group-add-score (group &optional score)
597 "Add SCORE to the GROUP score.
598 If SCORE is nil, add 1 to the score of GROUP."
599 (let ((info (gnus-get-info group)))
601 (gnus-info-set-score info (+ (gnus-info-score info) (or score 1))))))
603 ;; Function written by Stainless Steel Rat <ratinox@ccs.neu.edu>.
604 (defun gnus-short-group-name (group &optional levels)
605 "Collapse GROUP name LEVELS."
612 (while (string-match "\\." group skip)
613 (setq skip (match-end 0)
616 (if (string-match ":" group)
617 (setq foreign (substring group 0 (match-end 0))
618 group (substring group (match-end 0))))
620 (if (and (string-match "\\." group)
621 (> levels (- gnus-group-uncollapsed-levels 1)))
622 (setq name (concat name (substring group 0 1))
623 group (substring group (match-end 0))
625 name (concat name "."))
626 (setq name (concat foreign name group)
632 ;;; Kill file handling.
635 (defun gnus-apply-kill-file ()
636 "Apply a kill file to the current newsgroup.
637 Returns the number of articles marked as read."
638 (if (or (file-exists-p (gnus-newsgroup-kill-file nil))
639 (file-exists-p (gnus-newsgroup-kill-file gnus-newsgroup-name)))
640 (gnus-apply-kill-file-internal)
643 (defun gnus-kill-save-kill-buffer ()
644 (let ((file (gnus-newsgroup-kill-file gnus-newsgroup-name)))
645 (when (get-file-buffer file)
647 (set-buffer (get-file-buffer file))
648 (and (buffer-modified-p) (save-buffer))
649 (kill-buffer (current-buffer))))))
651 (defvar gnus-kill-file-name "KILL"
652 "Suffix of the kill files.")
654 (defun gnus-newsgroup-kill-file (newsgroup)
655 "Return the name of a kill file name for NEWSGROUP.
656 If NEWSGROUP is nil, return the global kill file name instead."
658 ;; The global KILL file is placed at top of the directory.
659 ((or (null newsgroup)
660 (string-equal newsgroup ""))
661 (expand-file-name gnus-kill-file-name
662 gnus-kill-files-directory))
663 ;; Append ".KILL" to newsgroup name.
664 ((gnus-use-long-file-name 'not-kill)
665 (expand-file-name (concat (gnus-newsgroup-savable-name newsgroup)
666 "." gnus-kill-file-name)
667 gnus-kill-files-directory))
668 ;; Place "KILL" under the hierarchical directory.
670 (expand-file-name (concat (gnus-newsgroup-directory-form newsgroup)
671 "/" gnus-kill-file-name)
672 gnus-kill-files-directory))))
676 (defun gnus-member-of-valid (symbol group)
677 "Find out if GROUP has SYMBOL as part of its \"valid\" spec."
679 (symbol-name (car (gnus-find-method-for-group group)))
680 gnus-valid-select-methods)))
682 (defun gnus-method-option-p (method option)
683 "Return non-nil if select METHOD has OPTION as a parameter."
684 (when (stringp method)
685 (setq method (gnus-server-to-method method)))
686 (memq option (assoc (format "%s" (car method))
687 gnus-valid-select-methods)))
689 (defun gnus-server-extend-method (group method)
690 ;; This function "extends" a virtual server. If the server is
691 ;; "hello", and the select method is ("hello" (my-var "something"))
692 ;; in the group "alt.alt", this will result in a new virtual server
693 ;; called "hello+alt.alt".
696 (if (equal (car method) "native") gnus-select-method
697 (cdr (assoc (car method) gnus-server-alist))))))
698 (setcar (cdr entry) (concat (nth 1 entry) "+" group))
699 (nconc entry (cdr method))))
701 (defun gnus-server-status (method)
702 "Return the status of METHOD."
703 (nth 1 (assoc method gnus-opened-servers)))
705 (defun gnus-group-name-to-method (group)
706 "Return a select method suitable for GROUP."
707 (if (string-match ":" group)
708 (let ((server (substring group 0 (match-beginning 0))))
709 (if (string-match "\\+" server)
710 (list (intern (substring server 0 (match-beginning 0)))
711 (substring server (match-end 0)))
712 (list (intern server) "")))
715 (defun gnus-find-method-for-group (group &optional info)
716 "Find the select method that GROUP uses."
717 (or gnus-override-method
720 (let ((info (or info (gnus-get-info group)))
723 (not (setq method (gnus-info-method info)))
724 (equal method "native"))
727 (cond ((stringp method)
728 (gnus-server-to-method method))
729 ((stringp (car method))
730 (gnus-server-extend-method group method))
733 (cond ((equal (cadr method) "")
735 ((null (cadr method))
736 (list (car method) ""))
738 (gnus-server-add-address method)))))))
740 (defun gnus-check-backend-function (func group)
741 "Check whether GROUP supports function FUNC."
742 (let ((method (if (stringp group) (car (gnus-find-method-for-group group))
744 (fboundp (intern (format "%s-%s" method func)))))
746 (defun gnus-methods-using (feature)
747 "Find all methods that have FEATURE."
748 (let ((valids gnus-valid-select-methods)
751 (if (memq feature (car valids))
752 (setq outs (cons (car valids) outs)))
753 (setq valids (cdr valids)))
756 (defun gnus-read-method (prompt)
757 "Prompt the user for a method.
758 Allow completion over sensible values."
761 prompt (append gnus-valid-select-methods gnus-server-alist)
762 nil t nil 'gnus-method-history)))
765 (setq method gnus-select-method))
766 ((assoc method gnus-valid-select-methods)
768 (if (memq 'prompt-address
769 (assoc method gnus-valid-select-methods))
770 (read-string "Address: ")
772 ((assoc method gnus-server-alist)
777 ;;; User-level commands.
780 (defun gnus-slave-no-server (&optional arg)
781 "Read network news as a slave, without connecting to local server"
783 (gnus-no-server arg t))
786 (defun gnus-no-server (&optional arg slave)
788 If ARG is a positive number, Gnus will use that as the
789 startup level. If ARG is nil, Gnus will be started at level 2.
790 If ARG is non-nil and not a positive number, Gnus will
791 prompt the user for the name of an NNTP server to use.
792 As opposed to `gnus', this command will not connect to the local server."
794 (gnus-no-server-1 arg slave))
797 (defun gnus-slave (&optional arg)
798 "Read news as a slave."
800 (gnus arg nil 'slave))
803 (defun gnus-other-frame (&optional arg)
804 "Pop up a frame to read news."
806 (if (get-buffer gnus-group-buffer)
807 (let ((pop-up-frames t))
809 (select-frame (make-frame))
812 (defun gnus (&optional arg dont-connect slave)
814 If ARG is non-nil and a positive number, Gnus will use that as the
815 startup level. If ARG is non-nil and not a positive number, Gnus will
816 prompt the user for the name of an NNTP server to use."
818 (gnus-1 arg dont-connect slave))
820 ;; Allow redefinition of Gnus functions.
826 ;;; gnus.el ends here