DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - metrics - download
Index: T n

⟦790c8efd9⟧ TextFile

    Length: 15920 (0x3e30)
    Types: TextFile
    Names: »news.el«

Derivation

└─⟦a05ed705a⟧ Bits:30007078 DKUUG GNU 2/12/89
    └─⟦32c6b6024⟧ »./gnews-2.0-tar.Z« 
        └─⟦5d06bd818⟧ 
            └─⟦this⟧ »gnews-2.0/news.el« 

TextFile

;;; news.el: news-mode commands for Gnews
;;; Copyright (C) 1987, 1988 by Matthew P Wiener; all rights reserved.

;;; Send bugs, complaints, suggestions etc to weemba@garnet.berkeley.edu

;; Gnews is distributed in the hope that it will be useful, but WITHOUT
;; ANY WARRANTY.  No author or distributor accepts responsibility to
;; anyone for the consequences of using it or for whether it serves any
;; particular purpose or works at all, unless he says so in writing.
;; Refer to the Gnews General License for full details.

;; Everyone is granted permission to copy, modify and redistribute Gnews,
;; but only under the conditions described in the Gnews General License.
;; A copy of this license is supposed to have been given to you along with
;; Gnews so you can know your rights and responsibilities.  It should be
;; accessible with the key sequence "ESC l l" while in News mode.  Among 
;; other things, the copyright notice and this notice must be preserved on
;; all copies.
\f


(defun news-default ()
  "Run the default news command, as given by the value of
the variable news-default-command"
  (interactive)
  (call-interactively news-default-command))

(defun news-yes ()
  "Select the current newsgroup"
  (interactive)
  (if group-current
      (news-goto group-current)
    (news-end t))
  (gnews-flush))

(defun news-next ()
  "Proffer to read news from the next subscribed group for which news
has arrived in, whether or not new news has arrived."
  (interactive)
  (if group-current
      (news-next-intern
	t (cdr (memq (assoc group-current group-roster) group-roster)))
    (news-end t))
  (gnews-flush))

(defun news-next-unread ()
  "Proffer to read news from the next subscribed group for which news
has arrived in."
  (interactive)
  (if group-current
      (news-next-intern
	nil (cdr (memq (assoc group-current group-roster) group-roster)))
    (news-first-unread))
  (gnews-flush))

(defun news-previous ()
  "Proffer to read news from the next subscribed group back, whether or
not new news has arrived."
  (interactive)
  (if group-current
      (news-next-intern
	t (cdr (memq (assoc group-current group-roster)
		     (reverse group-roster))))
    (news-next-intern t (reverse group-roster)))
  (gnews-flush))

(defun news-previous-unread ()
  "Proffer to read news from the next subscribed group back for which
news has arrived in."
  (interactive)
  (if group-current
      (news-next-intern
	nil (cdr (memq (assoc group-current group-roster)
		       (reverse group-roster))))
    (news-next-intern nil (reverse group-roster)))
  (gnews-flush))

(defun news-first ()
  "Select the first newsgroup."
  (interactive)
  (setq news-seen)
  (news-next-intern t group-roster)
  (gnews-flush))

(defun news-first-unread ()
  "Select the first newsgroup with unread news"
  (interactive)
  (setq news-seen)
  (news-next-intern nil group-roster)
  (gnews-flush))

(defun news-last-seen ()
  "Return to the previous newsgroup mentioned"
  (interactive)
  (group-warn-delete-window t)
  (if group-previous
      (let ((g (assoc group-previous group-roster)))
	(setq group-previous group-current
	      group-set-current ""		; force a reset
	      news-default-command 'news-yes
	      news-next-message "")
	(group-new-news g)
	(group-proffer t g (group-get-info g)))
    (message "no previous newsgroup" (ding)))
  (gnews-flush))

(defun news-end (&optional err)
  "Select the pseudo-newsgroup at the end of the group list.\n
Optional argument ERR means ding the user."
  (interactive)
  (setq group-previous group-current
	group-current nil)
  (cond (news-seen
	 (setq news-default-command 'news-first-unread
	       news-next-message "")
	 (gnews-message "more %s ? " news-prompt-first))
	(t
	 (setq news-default-command 'news-quit)
	 (gnews-message "more %s ? " news-prompt-quit)))
  (if err (ding))
  (gnews-flush))

(defun news-goto (group &optional nosub dot)
  "Select newsgroup GROUP from .gnewsrc--resubscribes automatically.
In Lisp code, non-nil optional argument NOSUB blocks resubscription,
and non-nil DOT suspends typeahead flushing.\n
Interactively, name completion and abbreviations are available.  Name
completion is the standard Emacs feature.  Abbreviations are special
to Gnews, and are controlled by the following keys:
\\{gnews-abbrev-keymap}
Abbreviations can be added, deleted, and listed with\\<news-mode-map> \
\\[gnews-abbrev-add], \\[gnews-abbrev-delete], and \\[gnews-abbrev-list]\n
If the first character typed is \"\\[news-index]\", the group will be entered
in index-mode.  If the first character typed is an \"\\[news-at]\", the named
group will be set to but not entered."
  (interactive
   (list
    (group-name-read "goto newsgroup: " group-roster 'news-restrictions) nil))
  (group-warn-delete-window t)
  (if (interactive-p)
      (let ((n (aref news-mode-map group-read-mood)))
	(cond ((eq n 'news-index)		; =
	       (group-set group)
	       (news-index nil))
	      ((eq n 'news-at)			; @
	       (setq group-current group)
	       (news-at))
	      (t
	       (group-get group nosub dot))))
    (group-get group nosub dot))
  (if (interactive-p) (gnews-flush)))		; caller decides for itself

(defun news-visit (group)
  "Visit newsgroup GROUP from .gnewsrc without resubscribing."
  (interactive
   (list
    (group-name-read "visit newsgroup: " group-roster 'news-restrictions)))
  (if (interactive-p)
      (let ((n (aref news-mode-map group-read-mood)))
	(cond ((eq n 'news-index)		; =
	       (group-set group)
	       (news-index nil))
	      ((eq n 'news-at)			; @
	       (setq group-current group)
	       (news-at))
	      (t
	       (group-get group t))))
    (group-get group t))
  (gnews-flush))

(defun news-general-goto (group)
  "Select newsgroup GROUP, not necessarily in .gnewsrc."
  ;; unlike the analogous news-{goto,visit}, this is only interactive
  (interactive
   (list (group-name-read
	  "Goto Newsgroup: " (roster-all) 'news-restrictions)))
  (let ((gi (assoc group group-roster))
	(n (aref news-mode-map group-read-mood)))
    (if (nntp-exec t t "group" group)
	(if (or gi (group-proffer-new group))
	    (cond ((eq n 'news-index)		; =
		   (group-set group)
		   (news-index nil))		; doesn't work ??
		  ((eq n 'news-at)		; @
		   (setq group-current group)
		   (news-at))
		  (t				; have to think
		   (group-get group))))		; about this one
      (message "Newsgroup %s does not exist!" group)))
  (gnews-flush))

(defun news-new ()
  "Add recently arrived newsgroups to your .gnewsrc.  Upon being
prompted, use file-name completion to identify them.\n
Use \\[keyboard-quit] to quit."
  (interactive)
  (message "getting list of new newsgroups...")
  (if roster-new nil
    (setq roster-new
	  (delq nil (mapcar
		      (function
			(lambda (g)
			  (if (or (assoc (car g) group-roster)
				  (string-match
				    (concat "^" (regexp-quote (car g)))
				    roster-old))
			      nil g)))
		      (roster-all)))))
  (message "getting list of new newsgroups...done")
  (news-add roster-new "No more new newsgroups" 'news-all)
  (gnews-flush))

(defun news-add (new msg pred)
  "Add newsgroups from the list NEW; when done, show in the
minibuffer the message MSG.  PRED is a newsgroup name restriction
filter: only names that PRED returns non-nil on are offered."
  (condition-case nil
      (progn
	(while new
	  (let* ((add (group-name-read "Add newsgroup: " new pred))
		 (aft (group-name-read (format "place %s after: " add)
				       group-roster 'news-all))
		 (tail (memq (assoc aft group-roster) group-roster)))
	    (setcdr tail (cons (list add t) (cdr tail)))
	    (setq gnews-rc-dangle t new (delq (assoc add new) new))))
	(message msg)
	(sit-for 1))
    (quit))
  (news-first-unread))

(defun news-delete (group)
  "Remove newsgroup GROUP from .gnewsrc file."
  (interactive
   (list
    (group-name-read "delete newsgroup: " group-roster 'news-restrictions)))
  (delq (assoc group group-roster) group-roster)
  (setq gnews-rc-dangle t)
  (gnews-flush))

(defun news-pattern-forward (patt)
  "Proffer to read news from the next subscribed-to newsgroup whose name
matches the regexp PATTern."
  ;; suppress when at $-end
  (interactive (list (read-string "Regexp forward: " news-pattern)))
  (setq news-pattern patt)
  (let ((ng (car (delq nil
		       (mapcar '(lambda (g)
				  (if (string-match patt (car g)) g))
			       (cdr (memq (assoc group-current group-roster)
					  group-roster)))))))
    (if ng
	(group-proffer-must (car ng) ng)
      (message "%s: pattern not found" patt (ding))))
  (gnews-flush))

(defun news-pattern-backward (patt)
  "Proffer to read news from the next subscribed-to newsgroup back whose
name matches the regexp PATTern."
  ;; fix when at $-end
  (interactive (list (read-string "Regexp backward: " news-pattern)))
  (setq news-pattern patt)
  (let* ((gr (reverse group-roster))
	 (ng (car (delq nil
			(mapcar '(lambda (g)
				   (if (string-match patt (car g)) g))
				(cdr (memq (assoc group-current gr) gr)))))))
    (if ng
	(group-proffer-must (car ng) ng)
      (message "%s: pattern not found" patt (ding))))
  (gnews-flush))

(defun news-unsubscribe ()
  "Unsubscribe from the current newsgroup."
  (interactive)
  (if (not group-current)
      (news-end t)
    (group-warn-delete-window t)
    (roster-unsubscribe group-current)
    (setq group-entry-command last-command)
    (news-next-unread-maybe)))

(defun news-at ()
  "Identify the current newsgroup."
  (interactive)
  (if (not group-current)
      (news-end t)
    (group-proffer-must group-current)
    (gnews-flush)))

(defun news-list ()
  "Switch to a roster of the entire newsgroup list."
  (interactive)
  (message "unimplemented")
  (gnews-flush))

(defun news-list-rc (pfx)
  "Switch to newsgroup roster, based on your .gnewsrc.  Prefix argument
PFX means include the unsubscribed groups.\n
>>Currently too primitive for actual usage.<<"
  (interactive "P")
  (roster-display pfx group-roster)
  (gnews-flush))

(defun news-move (group after)
  "Move newsgroup GROUP inside the group-roster to after newsgroup AFTER.
Interactively, move the current newsgroup's location to after the
prompted-for newsgroup."
  (interactive
   (list group-current (if group-current
			   (group-name-read
			     (concat "place " group-current " after: ")
			     group-roster
			     'news-all))))
  (if (not group-current)
      (news-end t)
    (setq gnews-rc-dangle t)
    (let* ((g (assoc group group-roster))
	   (f (assoc after group-roster))
	   (gr (delq g group-roster))
	   (hd (reverse (memq f (reverse gr))))
	   (tl (cdr (memq f gr))))
      (setq group-roster (nconc hd (list g) tl)))))

(defun news-catchup (pfx arg)
  "Catch up in the proffered newsgroup.\n
The two arguments, PFX and ARG--passed interactively as the literal and
numeric prefix argument respectively--control how many newsgroups to
leave unread at the end of the newsgroup:
 * If PFX is null, catch up all the articles.
 * If PFX is numeric, catch up all but the last ARG articles.
 * If PFX is a list, catch up all but the last 10*log_4(ARG) articles.
Note that log_4(ARG) is interactively a count of \\[universal-argument] 's.\n
Cross-posted articles will not be marked read in their other newsgroups."
  (interactive "P\np")
  (group-warn-delete-window t)
  (if (not group-current)
      (news-end t)
    (group-set group-current)
    (if (< (roster-catchup group-current t pfx arg) article-final)
	(news-goto group-current)
      (if (boundp 'index-pop)
	  (progn (bury-buffer index-buffer)
		 (makunbound 'index-pop)))
      (if (not (eq major-mode 'news-mode)) (news-mode))
      (setq group-entry-command last-command)
      (news-next-unread-maybe))
    (gnews-flush)))

(defun news-mark ()
  "Unread news.  All articles in the current newsgroup are marked as unread."
  (interactive)
  (if (not group-current)
      (news-end t)
    (if (y-or-n-p (format "mark %s unread? " group-current))
	(let* ((bg (1- article-first))
	       (gm (if (< 0 bg) (amark-cons 1 bg))))
	  (setcdr (assoc group-current group-roster) (if gm (list t gm) '(t)))
	  (setq amark (if gm (list gm)))
	  (group-roster-write gnews-rc-file-new)))
    (gnews-flush)))

(defun news-only-match (pattern)
  "Restrict future newsgroup profferings to those matching PATTERN."
  (interactive "sRestrict profferings to [regexp]: ")
  (fset 'news-restrictions
	(if (string= "" pattern)
	    'news-all
	  (` (lambda (g)
	       (, (documentation 'news-all))
	       (string-match (, pattern) (car g))))))
  (if (interactive-p)
      (message (news-restrictions-message pattern)))
  (gnews-flush))

(defun news-add-match (pattern)
  "Add newsgroups, not present in your .gnewsrc, matching the regular
expression PATTERN.  Use file-name completion to get their names, and
\\[keyboard-quit] to quit.\n
Upon finishing, future profferings will be restricted to PATTERN."
  (interactive "sAdd newsgroups matching [regexp]: ")
  (news-only-match pattern)
  (news-add (roster-all)
	    (news-restrictions-message pattern)
	    '(lambda (g)
	       (and (news-restrictions g)
		    (not (assoc (car g) group-roster))))))

(defun news-restrictions-message (s)
  (if (string= "" s)
      "Restrictions removed"
    (format "Restrictions %s in effect" s)))

(defun news-immediate ()
  "Enter the current newsgroup at the first unread article, but do not
actually set to the article.\n
Typeahead is never suppressed by this command."
  (interactive)
  (if group-current
      (news-goto group-current nil t)
    (news-end t)))
\f


;;; .gnewsrc functions

(defun news-quit (arg)
  "Quit news, saving the internal news data for next time.\n
In Lisp code, nil ARG means restore the .gnewsrc."
  (interactive (list t))
  (group-warn-delete-window t)
  (if gnews-rc-dangle (group-roster-write gnews-rc-file-new))
  (if gnews-hook-dangle (gnews-hook-write gnews-hook-file))
  (if news-new-noted (setq roster-new (list (car roster-new))))
  (gnews-time-write gnews-time-file)
  (setq mode-line-format default-mode-line-format) 
  (set-buffer-modified-p t)
  (if (nntp-run-p) (nntp-exec t t "quit"))
  (if (nntp-index-run-p) (send-string nntp-index "quit\n"))
  (if (processp nntp) (delete-process nntp))
  (if (processp nntp-index) (delete-process nntp-index))
  (copy-file (if arg gnews-rc-file-new gnews-rc-file-old) gnews-rc-file t)
  (mapcar '(lambda (b)
	     (if (bufferp b)
		 (if gnews-buffer-clean (kill-buffer b) (bury-buffer b))))
	  (gnews-buffer-list))
  (run-hooks 'gnews-quit-hook)
  (gnews-flush)
  (if (boundp 'gnews-configuration-return)
      (set-window-configuration gnews-configuration-return)
    (switch-to-buffer "*scratch*"))
  (sit-for 0))

(defun news-quit-restore ()
  "Quit, but leave .gnewsrc file alone.  What would have been saved
under \\[news-quit] appears in .gnewsrc.new."
  (interactive)
  (news-quit nil))

(defun news-rc-restore ()
  "Convert current group roster status into a .newsrc file.  The command
queries before overwriting an existing .newsrc file."
  (interactive)
  (gnews-to-news-rc (concat gnews-dot-dir ".newsrc"))
  (gnews-flush))

(defun news-restart ()
  "Checkpoint everything, and restart the NNTP internals."
  (interactive)
  (group-warn-delete-window t)
  (if gnews-rc-dangle (group-roster-write gnews-rc-file-new))
  (if gnews-hook-dangle (gnews-hook-write gnews-hook-file))
  (if news-new-noted (setq roster-new (list (car roster-new))))
  (gnews-time-write gnews-time-file)
  (if (nntp-run-p) (nntp-exec t t "quit"))
  (if (nntp-index-run-p) (send-string nntp-index "quit\n"))
  (if (processp nntp) (delete-process nntp))
  (if (processp nntp-index) (delete-process nntp-index))
  (nntp-start "Re")
  (nntp-index-start)
  (message "just a moment...")
  (roster-string-set)
  (cond (group-current
	 (setq group-set-current ""
	       news-default-command (if (string= news-prompt-return
						 news-prompt-yes)
					'news-yes 'news-next))
	 (group-proffer-must group-current))
	(t
	 (setq news-seen t)
	 (news-end))))