From lars Thu Feb 23 23:20:38 1995
-From: larsi@ifi.uio.no (ding)
+From: larsi@gnus.org (ding)
Date: Fri Feb 24 13:40:45 1995
Subject: So you want to use the new Gnus
Message-ID: <lars-doc1@eyesore.no>
;; Boston, MA 02111-1307, USA.
From lars Thu Feb 23 23:20:38 1995
-From: larsi@ifi.uio.no (ding)
+From: larsi@gnus.org (ding)
Date: Fri Feb 24 13:40:45 1995
Subject: Starting up
Message-ID: <lars-doc2@eyesore.no>
From lars Thu Feb 23 23:20:38 1995
-From: larsi@ifi.uio.no (ding)
+From: larsi@gnus.org (ding)
Date: Fri Feb 24 13:40:45 1995
Subject: Where are all the groups, then?
Message-ID: <lars-doc3@eyesore.no>
From lars Thu Feb 23 23:20:38 1995
-From: larsi@ifi.uio.no (ding)
+From: larsi@gnus.org (ding)
Date: Fri Feb 24 13:40:45 1995
Subject: I want to read my mail!
Message-ID: <lars-doc4@eyesore.no>
From lars Thu Feb 23 23:20:38 1995
-From: larsi@ifi.uio.no (ding)
+From: larsi@gnus.org (ding)
Date: Fri Feb 24 13:40:45 1995
Subject: Foreign newsgroups
Message-ID: <lars-doc5@eyesore.no>
From lars Thu Feb 23 23:20:38 1995
-From: larsi@ifi.uio.no (ding)
+From: larsi@gnus.org (ding)
Date: Fri Feb 24 13:40:45 1995
Subject: Low level changes in GNUS, or, Wrong type argument: stringp, nil
Message-ID: <lars-doc6@eyesore.no>
From lars Thu Feb 23 23:20:38 1995
-From: larsi@ifi.uio.no (ding)
+From: larsi@gnus.org (ding)
Date: Fri Feb 24 13:40:45 1995
Subject: How do I re-scan my mail groups?
Message-ID: <lars-doc8@eyesore.no>
From lars Thu Feb 23 23:20:38 1995
-From: larsi@ifi.uio.no (ding)
+From: larsi@gnus.org (ding)
Date: Fri Feb 24 13:40:45 1995
Subject: How do I set up virtual newsgroups?
Message-ID: <lars-doc9@eyesore.no>
From lars Thu Feb 23 23:20:38 1995
-From: larsi@ifi.uio.no (ding)
+From: larsi@gnus.org (ding)
Date: Fri Feb 24 13:40:45 1995
Subject: Bugs & stuff
Message-ID: <lars-doc7@eyesore.no>
I would, of course, prefer that you locate the bug, fix it, and mail
me the patches, but one can't have everything.
-If you have any questions on usage, the "ding@ifi.uio.no" mailing list
+If you have any questions on usage, the "ding@gnus.org" mailing list
is where to post the questions.
+Sat Apr 19 06:11:31 1997 Lars Magne Ingebrigtsen <larsi@menja.ifi.uio.no>
+
+ * gnus.el: Gnus v5.4.46 is released.
+
+Sat Apr 19 05:40:40 1997 Lars Magne Ingebrigtsen <larsi@ifi.uio.no>
+
+ * gnus-art.el (gnus-read-save-file-name): Expand file name i save
+ dir.
+
+Fri Apr 18 14:25:21 1997 Hrvoje Niksic <hniksic@srce.hr>
+
+ * gnus-art.el (gnus-signature-face): New face; use it.
+
+Sat Apr 19 05:32:43 1997 Kim-Minh Kaplan <kimminh.kaplan@utopia.eunet.fr>
+
+ * gnus-picon.el (gnus-picons-insert-face-if-exists): Add picons to
+ list.
+
+Tue Apr 15 14:08:32 1997 Hrvoje Niksic <hniksic@srce.hr>
+
+ * message.el (message-font-lock-keywords): Be a little bit more
+ case-insensitive.
+
+Wed Apr 16 02:41:31 1997 Hrvoje Niksic <hniksic@srce.hr>
+
+ * message.el (message-insert-to): New argument FORCE.
+
+Sat Apr 19 05:18:10 1997 Lars Magne Ingebrigtsen <larsi@ifi.uio.no>
+
+ * message.el (message-setup): Nix out undo list.
+
+Sat Apr 19 05:00:06 1997 Katsumi Yamaoka <yamaoka@ga.sony.co.jp>
+
+ * gnus-sum.el: Redefine.
+
+Sat Apr 19 04:53:29 1997 Lars Magne Ingebrigtsen <larsi@ifi.uio.no>
+
+ * gnus-art.el (article-display-x-face): Display all XFace
+ headers.
+
+ * gnus-ems.el: appt, not appt.el.
+
+Sat Apr 19 04:04:42 1997 Hrvoje Niksic <hniksic@srce.hr>
+
+ * gnus-xmas.el (gnus-xmas-summary-set-display-table): Don't nix
+ out in Latin1.
+
+Sat Apr 19 02:55:45 1997 Lars Magne Ingebrigtsen <larsi@ifi.uio.no>
+
+ * message.el (message-cancel-news): Only say we cancel if we
+ cancel.
+
+ * gnus-msg.el (gnus-summary-mail-crosspost-complaint): Deactivate
+ mark.
+
+Thu Apr 17 21:37:22 1997 Lars Magne Ingebrigtsen <larsi@ifi.uio.no>
+
+ * message.el (message-mail-alias-type): New variable.
+ (message-mode): Use it.
+
+Wed Apr 16 00:03:37 1997 Lars Magne Ingebrigtsen <larsi@ifi.uio.no>
+
+ * gnus-demon.el (gnus-demon): Ignore errors.
+
+Tue Apr 15 23:50:02 1997 Brad Howes <bhowes@cssun3.corp.mot.com>
+
+ * gnus-demon.el (gnus-demon-time-to-step): New version.
+
+Tue Apr 15 23:32:58 1997 Lars Magne Ingebrigtsen <larsi@ifi.uio.no>
+
+ * message.el (message-send-method-alist): New variable.
+ (message-send): Use it.
+ (message-send-via-news): New function.
+ (message-send-via-mail): New function.
+
+Sun Apr 13 18:22:02 1997 Jens Lautenbacher <jens@metrix.de>
+
+ * gnus.el (gnus-article-display-hook): Fix.
+
+Sun Apr 13 02:07:33 1997 Lars Magne Ingebrigtsen <larsi@ifi.uio.no>
+
+ * gnus-sum.el (gnus-get-newsgroup-headers): Protect against bogus
+ Lines headers.
+
+ * gnus-cache.el (gnus-cache-possibly-enter-article): Check number
+ not nil.
+
Sat Apr 12 23:28:30 1997 Lars Magne Ingebrigtsen <larsi@menja.ifi.uio.no>
* gnus.el: Gnus v5.4.45 is released.
:type 'face
:group 'gnus-article-buttons)
-(defcustom gnus-signature-face 'italic
- "Face used for highlighting a signature in the article buffer."
+(defcustom gnus-signature-face 'gnus-signature-face
+ "Face used for highlighting a signature in the article buffer.
+Obsolete; use the face `gnus-signature-face' for customizations instead."
:type 'face
:group 'gnus-article-highlight
:group 'gnus-article-signature)
+(defface gnus-signature-face
+ '((((type x))
+ (:italic t)))
+ "Face used for highlighting a signature in the article buffer."
+ :group 'gnus-article-highlight
+ :group 'gnus-article-signature)
+
(defface gnus-header-from-face
'((((class color)
(background dark))
(nnheader-narrow-to-headers)
(setq from (message-fetch-field "from"))
(goto-char (point-min))
- (when (and gnus-article-x-face-command
- (or force
- ;; Check whether this face is censored.
- (not gnus-article-x-face-too-ugly)
- (and gnus-article-x-face-too-ugly from
- (not (string-match gnus-article-x-face-too-ugly
- from))))
- ;; Has to be present.
- (re-search-forward "^X-Face: " nil t))
+ (while (and gnus-article-x-face-command
+ (or force
+ ;; Check whether this face is censored.
+ (not gnus-article-x-face-too-ugly)
+ (and gnus-article-x-face-too-ugly from
+ (not (string-match gnus-article-x-face-too-ugly
+ from))))
+ ;; Has to be present.
+ (re-search-forward "^X-Face: " nil t))
;; We now have the area of the buffer where the X-Face is stored.
(let ((beg (point))
(end (1- (re-search-forward "^\\($\\|[^ \t]\\)" nil t))))
- ;; We display the face.
- (if (symbolp gnus-article-x-face-command)
- ;; The command is a lisp function, so we call it.
- (if (gnus-functionp gnus-article-x-face-command)
- (funcall gnus-article-x-face-command beg end)
- (error "%s is not a function" gnus-article-x-face-command))
- ;; The command is a string, so we interpret the command
- ;; as a, well, command, and fork it off.
- (let ((process-connection-type nil))
- (process-kill-without-query
- (start-process
- "article-x-face" nil shell-file-name shell-command-switch
- gnus-article-x-face-command))
- (process-send-region "article-x-face" beg end)
- (process-send-eof "article-x-face")))))))))
+ (save-excursion
+ ;; We display the face.
+ (if (symbolp gnus-article-x-face-command)
+ ;; The command is a lisp function, so we call it.
+ (if (gnus-functionp gnus-article-x-face-command)
+ (funcall gnus-article-x-face-command beg end)
+ (error "%s is not a function" gnus-article-x-face-command))
+ ;; The command is a string, so we interpret the command
+ ;; as a, well, command, and fork it off.
+ (let ((process-connection-type nil))
+ (process-kill-without-query
+ (start-process
+ "article-x-face" nil shell-file-name shell-command-switch
+ gnus-article-x-face-command))
+ (process-send-region "article-x-face" beg end)
+ (process-send-eof "article-x-face"))))))))))
(defalias 'gnus-decode-rfc1522 'article-decode-rfc1522)
(defalias 'gnus-article-decode-rfc1522 'article-decode-rfc1522)
default-name))
;; A single split name was found
((= 1 (length split-name))
- (let* ((name (car split-name))
+ (let* ((name (expand-file-name
+ (car split-name) gnus-article-save-directory))
(dir (cond ((file-directory-p name)
(file-name-as-directory name))
((file-exists-p name) name)
(mail-header-set-number headers (cdr result))))
(let ((number (mail-header-number headers))
file dir)
- (when (and (> number 0) ; Reffed article.
+ (when (and number
+ (> number 0) ; Reffed article.
(or force
(and (or (not gnus-uncacheable-groups)
(not (string-match
"Find out how many seconds to TIME, which is on the form \"17:43\"."
(if (not (stringp time))
time
- (let* ((date (current-time-string))
- (dv (timezone-parse-date date))
- (tdate (timezone-make-arpa-date
- (string-to-number (aref dv 0))
- (string-to-number (aref dv 1))
- (string-to-number (aref dv 2)) time
- (or (aref dv 4) "UT")))
- (nseconds (gnus-time-minus
- (gnus-encode-date tdate) (gnus-encode-date date))))
- (round
- (/ (+ (if (< (car nseconds) 0)
- 86400 0)
- (* 65536 (car nseconds))
- (nth 1 nseconds))
- gnus-demon-timestep)))))
+ (let* ((now (current-time))
+ ;; obtain NOW as discrete components -- make a vector for speed
+ (nowParts (apply 'vector (decode-time now)))
+ ;; obtain THEN as discrete components
+ (thenParts (timezone-parse-time time))
+ (thenHour (string-to-int (elt thenParts 0)))
+ (thenMin (string-to-int (elt thenParts 1)))
+ ;; convert time as elements into number of seconds since EPOCH.
+ (then (encode-time 0
+ thenMin
+ thenHour
+ ;; If THEN is earlier than NOW, make it
+ ;; same time tomorrow. Doc for encode-time
+ ;; says that this is OK.
+ (+ (elt nowParts 3)
+ (if (or (< thenHour (elt nowParts 2))
+ (and (= thenHour (elt nowParts 2))
+ (<= thenMin (elt nowParts 1))))
+ 1 0))
+ (elt nowParts 4)
+ (elt nowParts 5)
+ (elt nowParts 6)
+ (elt nowParts 7)
+ (elt nowParts 8)))
+ ;; calculate number of seconds between NOW and THEN
+ (diff (+ (* 65536 (- (car then) (car now)))
+ (- (cadr then) (cadr now)))))
+ ;; return number of timesteps in the number of seconds
+ (round (/ diff gnus-demon-timestep)))))
(defun gnus-demon ()
"The Gnus daemon that takes care of running all Gnus handlers."
(t (< 0 gnus-demon-idle-time)))) ; Or just need to be idle.
;; So we call the handler.
(progn
- (funcall (car handler))
+ (ignore-errors (funcall (car handler)))
;; And reset the timer.
(setcar (nthcdr 1 handler)
(gnus-demon-time-to-step
((not (numberp idle))
;; We want to call this handler each and every time that
;; Emacs is idle.
- (funcall (car handler)))
+ (ignore-errors (funcall (car handler))))
(t
;; We want to call this handler only if Emacs has been idle
;; for a specified number of timesteps.
(and (not (memq (car handler) gnus-demon-idle-has-been-called))
(< idle gnus-demon-idle-time)
(progn
- (funcall (car handler))
+ (ignore-errors (funcall (car handler)))
;; Make sure the handler won't be called once more in
;; this idle-cycle.
(push (car handler) gnus-demon-idle-has-been-called)))))))))
(eval-and-compile
(autoload 'gnus-xmas-define "gnus-xmas")
(autoload 'gnus-xmas-redefine "gnus-xmas")
- (autoload 'appt-select-lowest-window "appt.el"))
+ (autoload 'appt-select-lowest-window "appt"))
(or (fboundp 'mail-file-babyl-p)
(fset 'mail-file-babyl-p 'rmail-file-p))
(gnus-group-group-name)]
["Info" gnus-group-edit-group (gnus-group-group-name)]
["Local kill file" gnus-group-edit-local-kill (gnus-group-group-name)]
- ["Global kill file" gnus-group-edit-global-kill t])
- ))
+ ["Global kill file" gnus-group-edit-global-kill t])))
(easy-menu-define
gnus-group-group-menu gnus-group-mode-map ""
["Find new newsgroups" gnus-find-new-newsgroups t]
["Transpose" gnus-group-transpose-groups
(gnus-group-group-name)]
- ["Read a directory as a group..." gnus-group-enter-directory t]
- ))
+ ["Read a directory as a group..." gnus-group-enter-directory t]))
(easy-menu-define
gnus-group-misc-menu gnus-group-mode-map ""
["Flush score cache" gnus-score-flush-cache t]
["Toggle topics" gnus-topic-mode t]
["Exit from Gnus" gnus-group-exit t]
- ["Exit without saving" gnus-group-quit t]
- ))
+ ["Exit without saving" gnus-group-quit t]))
(run-hooks 'gnus-group-menu-hook)))
(message-goto-subject)
(re-search-forward " *$")
(replace-match " (crosspost notification)" t t)
+ (deactivate-mark)
(when (gnus-y-or-n-p "Send this complaint? ")
(message-send-and-exit)))))))
picons)))
(when domainp
(setq picons
- (nconc (list (make-annotation
- (if first (concat (if (not rightp) ".") cur
- (if rightp ".")) cur)
- (point) 'text nil nil nil rightp))
- picons))))
+ (nconc
+ (list (make-annotation
+ (if first (concat (if (not rightp) ".") cur
+ (if rightp ".")) cur)
+ (point) 'text nil nil nil rightp))
+ picons))))
(when (and bar (or domainp found))
(setq bar-ann (gnus-picons-try-to-find-face
(concat gnus-xmas-glyph-directory "bar.xbm")
(setq first t))
(when (and addrs domainp)
(let ((it (mapconcat 'downcase (nreverse addrs) ".")))
- (make-annotation
- (if first (concat (if (not rightp) ".") it (if rightp ".")) it)
- (point) 'text nil nil nil rightp)))
+ (setq picons
+ (nconc picons (list (make-annotation
+ (if first
+ (concat (if (not rightp) ".")
+ it (if rightp "."))
+ it)
+ (point) 'text
+ nil nil nil rightp))))))
picons))
(defvar gnus-picons-glyph-alist nil)
(progn
(goto-char p)
(if (search-forward "\nlines: " nil t)
- (if (numberp (setq lines (read cur)))
+ (if (numberp (setq lines (ignore-errors (read cur))))
lines 0)
0))
;; Xref.
(lambda (buf) (switch-to-buffer buf) (gnus-summary-exit))
buffers)))))
+(gnus-ems-redefine)
+
(provide 'gnus-sum)
(run-hooks 'gnus-sum-load-hook)
;; Setup the display table -- like `gnus-summary-setup-display-table',
;; but done in an XEmacsish way.
(let ((table (make-display-table))
- (default-table (specifier-instance current-display-table))
(i 32))
;; Nix out all the control chars...
(while (>= (setq i (1- i)) 0)
;; selective display).
(aset table ?\n nil)
(aset table ?\r nil)
- ;; We nix out any glyphs over 126 that are not set already.
- (when default-table
- (let ((i 256))
- (while (>= (setq i (1- i)) 127)
- ;; Only modify if the default entry is nil.
- (unless (aref default-table i)
- (aset table i [??])))))
+ ;; We nix out any glyphs over 126 below ctl-arrow.
+ (let ((i (if (integerp ctl-arrow) ctl-arrow 160)))
+ (while (>= (setq i (1- i)) 127)
+ (aset table i [??])))
;; Can't use `set-specifier' because of a bug in 19.14 and earlier
(add-spec-to-specifier current-display-table table (current-buffer) nil)))
(defun gnus-xmas-article-display-xface (beg end)
"Display any XFace headers in the current article."
(save-excursion
- (let (xface-glyph)
- (if (featurep 'xface)
- (setq xface-glyph
- (make-glyph (vector 'xface :data
- (concat "X-Face: "
- (buffer-substring beg end)))))
- (let ((cur (current-buffer)))
- (save-excursion
- (gnus-set-work-buffer)
- (insert (format "%s" (buffer-substring beg end cur)))
- (gnus-xmas-call-region "uncompface")
- (goto-char (point-min))
- (insert "/* Width=48, Height=48 */\n")
- (gnus-xmas-call-region "icontopbm")
- (gnus-xmas-call-region "ppmtoxpm")
- (setq xface-glyph
- (make-glyph
- (vector 'xpm :data (buffer-string )))))))
+ (let ((xface-glyph
+ (if (featurep 'xface)
+ (make-glyph (vector 'xface :data
+ (concat "X-Face: "
+ (buffer-substring beg end))))
+ (let ((cur (current-buffer)))
+ (save-excursion
+ (gnus-set-work-buffer)
+ (insert (format "%s" (buffer-substring beg end cur)))
+ (gnus-xmas-call-region "uncompface")
+ (goto-char (point-min))
+ (insert "/* Width=48, Height=48 */\n")
+ (gnus-xmas-call-region "icontopbm")
+ (gnus-xmas-call-region "ppmtoxpm")
+ (make-glyph
+ (vector 'xpm :data (buffer-string))))))))
(set-glyph-face xface-glyph 'gnus-x-face)
(goto-char (point-min))
(re-search-forward "^From:" nil t)
:link '(custom-manual "(gnus)Exiting Gnus")
:group 'gnus)
-(defconst gnus-version-number "5.4.45"
+(defconst gnus-version-number "5.4.46"
"Version number for this version of Gnus.")
(defconst gnus-version (format "Gnus v%s" gnus-version-number)
gnus-article-fill-cited-article
gnus-article-remove-cr
gnus-article-de-quoted-unreadable
- gnus-article-display-x-face
gnus-summary-stop-page-breaking
;; gnus-summary-caesar-message
;; gnus-summary-verbose-headers
gnus-article-strip-leading-blank-lines
gnus-article-strip-multiple-blank-lines
gnus-article-strip-blank-lines
- gnus-article-treat-overstrike))
+ gnus-article-treat-overstrike
+ gnus-article-display-x-face
+ gnus-smiley-display))
(defcustom gnus-article-save-directory gnus-directory
"*Name of the directory articles will be saved in (default \"~/News\")."
(defvar message-mh-deletable-headers '(Message-ID Date Lines Sender)
"If non-nil, delete the deletable headers before feeding to mh.")
+(defvar message-send-method-alist
+ '((news message-news-p message-send-via-news)
+ (mail message-mail-p message-send-via-mail))
+ "Alist of ways to send outgoing messages.
+Each element has the form
+
+ \(TYPE PREDICATE FUNCTION)
+
+where TYPE is a symbol that names the method; PREDICATE is a function
+called without any parameters to determine whether the message is
+a message of type TYPE; and FUNCTION is a function to be called if
+PREDICATE returns non-nil. FUNCTION is called with one parameter --
+the prefix.")
+
+(defvar message-mail-alias-type 'abbrev
+ "*What alias expansion type to use in Message buffers.
+The default is `abbrev', which uses mailabbrev. nil switches
+mail aliases off.")
+
;;; Internal variables.
;;; Well, not really internal.
(let* ((cite-prefix "A-Za-z")
(cite-suffix (concat cite-prefix "0-9_.@-"))
(content "[ \t]*\\(.+\\(\n[ \t].*\\)*\\)"))
- `((,(concat "^\\(To:\\)" content)
+ `((,(concat "^\\([Tt]o:\\)" content)
(1 'message-header-name-face)
(2 'message-header-to-face nil t))
- (,(concat "^\\(^[GBF]?[Cc][Cc]:\\|^Reply-To:\\)" content)
+ (,(concat "^\\(^[GBF]?[Cc][Cc]:\\|^[Rr]eply-[Tt]o:\\)" content)
(1 'message-header-name-face)
(2 'message-header-cc-face nil t))
- (,(concat "^\\(Subject:\\)" content)
+ (,(concat "^\\([Ss]ubject:\\)" content)
(1 'message-header-name-face)
(2 'message-header-subject-face nil t))
- (,(concat "^\\(Newsgroups:\\|Followup-to:\\)" content)
+ (,(concat "^\\([Nn]ewsgroups:\\|Followup-[Tt]o:\\)" content)
(1 'message-header-name-face)
(2 'message-header-newsgroups-face nil t))
(,(concat "^\\([^: \n\t]+:\\)" content)
(easy-menu-add message-mode-menu message-mode-map)
(easy-menu-add message-mode-field-menu message-mode-map)
;; Allow mail alias things.
- (if (fboundp 'mail-abbrevs-setup)
- (mail-abbrevs-setup)
- (funcall (intern "mail-aliases-setup")))
+ (when (eq message-mail-alias-type 'abbrev)
+ (if (fboundp 'mail-abbrevs-setup)
+ (mail-abbrevs-setup)
+ (funcall (intern "mail-aliases-setup"))))
(run-hooks 'text-mode-hook 'message-mode-hook))
\f
\f
-(defun message-insert-to ()
- "Insert a To header that points to the author of the article being replied to."
- (interactive)
+(defun message-insert-to (&optional force)
+ "Insert a To header that points to the author of the article being replied to.
+If the original author requested not to be sent mail, the function signals
+an error.
+With the prefix argument FORCE, insert the header anyway."
+ (interactive "P")
(let ((co (message-fetch-reply-field "mail-copies-to")))
- (when (and co
+ (when (and (null force)
+ co
(equal (downcase co) "never"))
(error "The user has requested not to have copies sent via mail")))
(when (and (message-position-on-field "To")
(message-fix-before-sending)
(run-hooks 'message-send-hook)
(message "Sending...")
- (when (and (or (not (message-news-p))
- (and (or (not (memq 'news message-sent-message-via))
- (y-or-n-p
- "Already sent message via news; resend? "))
- (funcall message-send-news-function arg)))
- (or (not (message-mail-p))
- (and (or (not (memq 'mail message-sent-message-via))
- (y-or-n-p
- "Already sent message via mail; resend? "))
- (message-send-mail arg))))
- (message-do-fcc)
- ;;(when (fboundp 'mail-hist-put-headers-into-history)
- ;; (mail-hist-put-headers-into-history))
- (run-hooks 'message-sent-hook)
- (message "Sending...done")
- ;; If buffer has no file, mark it as unmodified and delete autosave.
- (unless buffer-file-name
- (set-buffer-modified-p nil)
- (delete-auto-save-file-if-necessary t))
- ;; Delete other mail buffers and stuff.
- (message-do-send-housekeeping)
- (message-do-actions message-send-actions)
- ;; Return success.
- t)))
+ (let ((alist message-send-method-alist)
+ elem sent)
+ (while (setq elem (pop alist))
+ (when (and (or (not (funcall (cadr elem)))
+ (and (or (not (memq (car elem)
+ message-sent-message-via))
+ (y-or-n-p
+ (format
+ "Already sent message via %s; resend? "
+ (car elem))))
+ (funcall (caddr elem) arg))))
+ (setq sent t)))
+ (when sent
+ (message-do-fcc)
+ ;;(when (fboundp 'mail-hist-put-headers-into-history)
+ ;; (mail-hist-put-headers-into-history))
+ (run-hooks 'message-sent-hook)
+ (message "Sending...done")
+ ;; If buffer has no file, mark it as unmodified and delete autosave.
+ (unless buffer-file-name
+ (set-buffer-modified-p nil)
+ (delete-auto-save-file-if-necessary t))
+ ;; Delete other mail buffers and stuff.
+ (message-do-send-housekeeping)
+ (message-do-actions message-send-actions)
+ ;; Return success.
+ t))))
+
+(defun message-send-via-mail (arg)
+ "Send the current message via mail."
+ (message-send-mail arg))
+
+(defun message-send-via-news (arg)
+ "Send the current message via news."
+ (funcall message-send-news-function arg))
(defun message-fix-before-sending ()
"Do various things to make the message nice before sending it."
(message-narrow-to-headers)
(run-hooks 'message-header-setup-hook))
(set-buffer-modified-p nil)
+ (setq buffer-undo-list nil)
(run-hooks 'message-setup-hook)
(message-position-point)
(undo-boundary))
mail-header-separator "\n"
message-cancel-message)
(message "Canceling your article...")
- (let ((message-syntax-checks 'dont-check-for-anything-just-trust-me))
- (funcall message-send-news-function))
- (message "Canceling your article...done")
+ (if (let ((message-syntax-checks
+ 'dont-check-for-anything-just-trust-me))
+ (funcall message-send-news-function))
+ (message "Canceling your article...done"))
(kill-buffer buf)))))
;;;###autoload
;;; nndb.el --- nndb access for Gnus
-;; Copyright (C) 1996,97 Free Software Foundation, Inc.
+;; Copyright (C) 1997 Free Software Foundation, Inc.
-;; Author: Kai Grossjohann <grossjohann@ls6.informatik.uni-dortmund.de>
+;; Author: Masanobu UMEDA <umerin@flab.flab.fujitsu.junet>
+;; Kai Grossjohann <grossjohann@ls6.informatik.uni-dortmund.de>
+;; Joe Hildebrand <joe.hildebrand@ilg.com>
+;; David Blacka <davidb@rwhois.net>
;; Keywords: news
-;; This file is part of GNU Emacs.
+;; This file is NOT part of GNU Emacs.
;; GNU Emacs is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;;; Commentary:
-;; I have shamelessly snarfed the code of nntp.el from sgnus.
-;; Kai
-
+;;; This was based upon Kai Grossjohan's shamessly snarfed code and
+;;; further modified by Joe Hildebrand. It has been updated for Red
+;;; Gnus.
+
+;; TODO:
+;;
+;; * Fix bug where server connection can be lost and impossible to regain
+;; This hasn't happened to me in a while; think it was fixed in Rgnus
+;;
+;; * make it handle different nndb servers seemlessly
+;;
+;; * Optimize expire if FORCE
+;;
+;; * Optimize move (only expire once)
+;;
+;; * Deal with add/deletion of groups
+;;
+;; * make the backend TOUCH an article when marked as expireable (will
+;; make article expire 'expiry' days after that moment).
;;-
;; Register nndb with known select methods.
-(require 'gnus)
-(require 'nnmail)
-
-(setq gnus-valid-select-methods
- (cons '("nndb" mail address respool prompt-address)
- gnus-valid-select-methods))
-
+(gnus-declare-backend "nndb" 'mail 'respool 'address 'prompt-address)
;;; Code:
+(require 'nnmail)
(require 'nnheader)
(require 'nntp)
(eval-when-compile (require 'cl))
(defvoo nndb-deliver-program "nndel"
"*The program used to put a message in an NNDB group.")
+(defvoo nndb-server-side-expiry nil
+ "If t, expiry calculation will occur on the server side")
+
+(defvoo nndb-set-expire-date-on-mark nil
+ "If t, the expiry date for a given article will be set to the time
+it was marked as expireable; otherwise the date will be the time the
+article was posted to nndb")
+
;; Variables copied from nntp
(defvoo nndb-server-opened-hook '(nntp-send-authinfo-from-file)
"Like nntp-server-opened-hook."
nntp-server-opened-hook)
-;(defvoo nndb-rlogin-parameters '("telnet" "${NNDBSERVER:=localhost}" "9000")
-; "*Parameters to nndb-open-login. Like nntp-rlogin-parameters."
-; nntp-rlogin-parameters)
-
-;(defvoo nndb-rlogin-user-name nil
-; "*User name for rlogin connect method."
-; nntp-rlogin-user-name)
-
(defvoo nndb-address "localhost"
"*The name of the NNDB server."
nntp-address)
"*Port number to connect to."
nntp-port-number)
-;(defvoo nndb-current-group ""
-; "Like nntp-current-group."
-; nntp-current-group)
+;; change to 'news if you are actually using nndb for news
+(defvoo nndb-article-type 'mail)
(defvoo nndb-status-string nil "" nntp-status-string)
\f
-(defconst nndb-version "nndb 0.3"
+(defconst nndb-version "nndb 0.7"
"Version numbers of this version of NNDB.")
\f
(nnoo-define-basics nndb)
-;; Import other stuff from nntp as is.
-
-(nnoo-import nndb
- (nntp))
-
-;;- maybe this should be mail??
-;;-(defun nndb-request-type (group &optional article)
-;;- 'news)
-
;;------------------------------------------------------------------
-;;- only new stuff below
-
-; nndb-request-update-info does not exist and is not needed
-; nndb-request-update-mark does not exist and is not needed
-
-; nndb-request-scan does not exist
-; get new mail from somewhere -- maybe this is not needed?
-; --> todo
-
-(deffoo nndb-request-create-group (group &optional server args)
- "Creates a group if it doesn't exist yet."
- (nntp-send-command "^[23].*\n" "MKGROUP" group))
-
-; todo -- use some other time than the creation time of the article
-; best is time since article has been marked as expirable
-(deffoo nndb-request-expire-articles
+;; this function turns the lisp list into a string list. There is
+;; probably a more efficient way to do this.
+(defun nndb-build-article-string (articles)
+ (let (art-string art)
+ (while articles
+ (setq art (pop articles))
+ (setq art-string (concat art-string art " ")))
+ art-string))
+
+(defun nndb-build-expire-rest-list (total expire)
+ (let (art rest)
+ (while total
+ (setq art (pop total))
+ (if (memq art expire)
+ ()
+ (push art rest)))
+ rest))
+
+
+;;
+(deffoo nndb-request-type (group &optional article)
+ nndb-article-type)
+
+;; nndb-request-update-info does not exist and is not needed
+
+;; nndb-request-update-mark does not exist; it should be used to TOUCH
+;; articles as they are marked exipirable
+(defun nndb-touch-article (group article)
+ (nntp-send-command nil "X-TOUCH" article))
+
+(deffoo nndb-request-update-mark
+ (group article mark)
+ "Sets the expiry date for ARTICLE in GROUP to now, if the mark is 'E'"
+ (if (and nndb-set-expire-date-on-mark (string-equal mark "E"))
+ (nndb-touch-article group article))
+ mark)
+
+;; nndb-request-create-group -- currently this isn't necessary; nndb
+;; creates groups on demand.
+
+;; todo -- use some other time than the creation time of the article
+;; best is time since article has been marked as expirable
+
+(defun nndb-request-expire-articles-local
(articles &optional group server force)
- "Expires ARTICLES from GROUP on SERVER.
-If FORCE, delete regardless of expiration date, otherwise use normal
-expiry mechanism."
- (let (msg art)
- (nntp-possibly-change-group group server) ;;-
+ "Let gnus do the date check and issue the delete commands."
+ (let (msg art delete-list (num-delete 0) rest)
+ (nntp-possibly-change-group group server)
(while articles
(setq art (pop articles))
- (nntp-send-command "^\\([23]\\|^423\\).*\n" "DATE" art)
+ (nntp-send-command "^\\([23]\\|^423\\).*\n" "X-DATE" art)
(setq msg (nndb-status-message))
- ;; CCC we shouldn't be using the variable nndb-status-string?
- (if (string-match "^423" (nnheader-get-report 'nndb))
+ (if (string-match "^423" msg)
()
- (unless (string-match "\\([0-9]+\\) \\([0-9]+\\)$" msg)
- (error "Not a valid response for DATE command: %s"
- msg))
- (if (nnmail-expired-article-p
- group
- (list (string-to-int
- (substring msg (match-beginning 1) (match-end 1)))
- (string-to-int
- (substring msg (match-beginning 2) (match-end 2))))
- force)
- (nnheader-message 5 "Deleting article %s in %s..."
- art group)
- (nntp-send-command "^[23].*\n" "DELETE" art))))))
+ (or (string-match "'\\(.+\\)'" msg)
+ (error "Not a valid response for X-DATE command: %s"
+ msg))
+ (if (nnmail-expired-article-p
+ group
+ (gnus-encode-date
+ (substring msg (match-beginning 1) (match-end 1)))
+ force)
+ (progn
+ (setq delete-list (concat delete-list " " (int-to-string art)))
+ (setq num-delete (1+ num-delete)))
+ (push art rest))))
+ (if (> (length delete-list) 0)
+ (progn
+ (nnheader-message 5 "Deleting %s article(s) from %s"
+ (int-to-string num-delete) group)
+ (nntp-send-command "^[23].*\n" "X-DELETE" delete-list))
+ )
+
+ (message "")
+ (nconc rest articles)))
+
+(defun nndb-get-remote-expire-response ()
+ (let (list)
+ (set-buffer nntp-server-buffer)
+ (goto-char (point-min))
+ (if (looking-at "^[34]")
+ ;; x-expire returned error--presume no articles were expirable)
+ (setq list nil)
+ ;; otherwise, pull all of the following numbers into the list
+ (re-search-forward "follows\r?\n?" nil t)
+ (while (re-search-forward "^[0-9]+$" nil t)
+ (push (string-to-int (match-string 0)) list)))
+ list))
+
+(defun nndb-request-expire-articles-remote
+ (articles &optional group server force)
+ "Let the nndb backend expire articles"
+ (let (days art-string delete-list (num-delete 0))
+ (nntp-possibly-change-group group server)
+
+ ;; first calculate the wait period in days
+ (setq days (or (and nnmail-expiry-wait-function
+ (funcall nnmail-expiry-wait-function group))
+ nnmail-expiry-wait))
+ ;; now handle the special cases
+ (cond (force
+ (setq days 0))
+ ((eq days 'never)
+ ;; This isn't an expirable group.
+ (setq days -1))
+ ((eq days 'immediate)
+ (setq days 0)))
+
+
+ ;; build article string
+ (setq art-string (concat days " " (nndb-build-article-string articles)))
+ (nntp-send-command "^\.\r?\n\\|^[345].*\n" "X-EXPIRE" art-string)
+
+ (setq delete-list (nndb-get-remote-expire-response))
+ (setq num-delete (length delete-list))
+ (if (> num-delete 0)
+ (nnheader-message 5 "Deleting %s article(s) from %s"
+ (int-to-string num-delete) group))
+
+ (nndb-build-expire-rest-list articles delete-list)))
+
+(deffoo nndb-request-expire-articles
+ (articles &optional group server force)
+ "Expires ARTICLES from GROUP on SERVER.
+If FORCE, delete regardless of exiration date, otherwise use normal
+expiry mechanism."
+ (if nndb-server-side-expiry
+ (nndb-request-expire-articles-remote articles group server force)
+ (nndb-request-expire-articles-local articles group server force)))
(deffoo nndb-request-move-article
- (article group server accept-form &optional last)
+ (article group server accept-form &optional last)
"Move ARTICLE (a number) from GROUP on SERVER.
Evals ACCEPT-FORM in current buffer, where the article is.
Optional LAST is ignored."
- (let ((artbuf (get-buffer-create " *nndb move*"))
+ ;; we guess that the second arg in accept-form is the new group,
+ ;; which it will be for nndb, which is all that matters anyway
+ (let ((new-group (nth 1 accept-form)) result)
+ (nntp-possibly-change-group group server)
+
+ ;; use the move command for nndb-to-nndb moves
+ (if (string-match "^nndb" new-group)
+ (let ((new-group-name (gnus-group-real-name new-group)))
+ (nntp-send-command "^[23].*\n" "X-MOVE" article new-group-name)
+ (cons new-group article))
+ ;; else move normally
+ (let ((artbuf (get-buffer-create " *nndb move*")))
+ (and
+ (nndb-request-article article group server artbuf)
+ (save-excursion
+ (set-buffer artbuf)
+ (insert-buffer-substring nntp-server-buffer)
+ (setq result (eval accept-form))
+ (kill-buffer (current-buffer))
+ result)
+ (nndb-request-expire-articles (list article)
+ group
+ server
+ t))
result)
- (and
- (nndb-request-article article group server artbuf)
- (save-excursion
- (set-buffer artbuf)
- (setq result (eval accept-form))
- (kill-buffer (current-buffer))
- result)
- (nndb-request-expire-articles (list article)
- group
- server
- t))
- result))
-
+ )))
+
(deffoo nndb-request-accept-article (group server &optional last)
"The article in the current buffer is put into GROUP."
- (nntp-possibly-change-group group server) ;;-
- (let (art statmsg)
+ (nntp-possibly-change-group group server)
+ (let (art msg)
(when (nntp-send-command "^[23].*\r?\n" "ACCEPT" group)
(nnheader-insert "")
- (nntp-encode-text)
- (nntp-send-buffer "^[23].*\n")
- (setq statmsg (nntp-status-message))
- (unless (string-match "^\\([0-9]+\\)" statmsg)
- (error "nndb: %s" statmsg))
- (setq art (substring statmsg
- (match-beginning 1)
- (match-end 1)))
- (message "nndb: accepted %s" art)
- (list art))))
+ (nntp-send-buffer "^[23].*\n"))
+
+ (set-buffer nntp-server-buffer)
+ (setq msg (buffer-string (point-min) (point-max)))
+ (or (string-match "^\\([0-9]+\\)" msg)
+ (error "nndb: %s" msg))
+ (setq art (substring msg (match-beginning 1) (match-end 1)))
+ (message "nndb: accepted %s" art)
+ (list art)))
(deffoo nndb-request-replace-article (article group buffer)
- "ARTICLE is the number of the article in GROUP to be replaced
+ "ARTICLE is the number of the article in GROUP to be replaced
with the contents of the BUFFER."
(set-buffer buffer)
- (let (art statmsg)
- (when (nntp-send-command "^[23].*\r?\n" "REPLACE" (int-to-string article))
- (nnheader-insert "")
- (nntp-encode-text)
- (nntp-send-buffer "^[23].*\n")
-; (setq statmsg (nntp-status-message))
-; (or (string-match "^\\([0-9]+\\)" statmsg)
-; (error "nndb: %s" statmsg))
-; (setq art (substring statmsg
-; (match-beginning 1)
-; (match-end 1)))
-; (message "nndb: replaced %s" art)
- (list (int-to-string article)))))
+ (when (nntp-send-command "^[23].*\r?\n" "X-REPLACE" (int-to-string article))
+ (nnheader-insert "")
+ (nntp-send-buffer "^[23.*\n")
+ (list (int-to-string article))))
; nndb-request-delete-group does not exist
; todo -- maybe later
; nndb-request-rename-group does not exist
; todo -- maybe later
+;; -- standard compatability functions
+
+(deffoo nndb-status-message (&optional server)
+ "Return server status as a string."
+ (set-buffer nntp-server-buffer)
+ (buffer-string (point-min) (point-max)))
+
+;; Import stuff from nntp
+
+(nnoo-import nndb
+ (nntp))
+
(provide 'nndb)
+
'((any . "from\\|to\\|cc\\|sender\\|apparently-to\\|resent-from\\|resent-to\\|resent-cc")
(mail . "mailer-daemon\\|postmaster\\|uucp")
(to . "to\\|cc\\|apparently-to\\|resent-to\\|resent-cc")
- (from . "from\\|sender\\|resent-from"))
+ (from . "from\\|sender\\|resent-from")
+ (nato . "to\\|cc\\|resent-to\\|resent-cc")
+ (naany . "from\\|to\\|cc\\|sender\\|resent-from\\|resent-to\\|resent-cc"))
"Alist of abbreviations allowed in `nnmail-split-fancy'."
:group 'nnmail-split
:type '(repeat (cons :format "%v" symbol regexp)))
(defvar gnus-article-buffer)
;;;###autoload
(defun gnus-smiley-display ()
+ "Display \"smileys\" as small graphical icons."
(interactive)
(save-excursion
(set-buffer gnus-article-buffer)
+Sat Apr 12 16:51:32 1997 Robert Bihlmeyer <robbe@orcus.priv.at>
+
+ * gnus.texi (Thwarting Email Spam): Addition.
+
+Tue Apr 15 16:11:38 1997 Lars Magne Ingebrigtsen <larsi@ifi.uio.no>
+
+ * message.texi (Various Message Variables): Addition.
+
+ * gnus.texi (Thwarting Email Spam): Addition.
+
Sat Apr 12 00:26:47 1997 Francois Felix Ingrand <felix@laas.fr>
* gnus.texi (NoCeM): Addition.
\input texinfo @c -*-texinfo-*-
@setfilename gnus
-@settitle Gnus 5.4.45 Manual
+@settitle Gnus 5.4.46 Manual
@synindex fn cp
@synindex vr cp
@synindex pg cp
@tex
@titlepage
-@title Gnus 5.4.45 Manual
+@title Gnus 5.4.46 Manual
@author by Lars Magne Ingebrigtsen
@page
spool or your mbox file. All at the same time, if you want to push your
luck.
-This manual corresponds to Gnus 5.4.45.
+This manual corresponds to Gnus 5.4.46.
@end ifinfo
@item S O p
@kindex S O p (Summary)
@findex gnus-uu-digest-post-forward
+@cindex digests
+@cindex making digests
Digest the current series and forward the result to a newsgroup
-(@code{gnus-uu-digest-mail-forward}).
+(@code{gnus-uu-digest-mail-forward}). This command uses the
+process/prefix convention.
@item S u
@kindex S u (Summary)
@subsection Pick and Read
@cindex pick and read
-Some newsreaders (like @code{nn} and, uhm, @code{nn}) use a two-phased
-reading interface. The user first marks the articles she wants to read
-from a summary buffer. Then she starts reading the articles with just
-an article buffer displayed.
+Some newsreaders (like @code{nn} and, uhm, @code{Netnews} on VM/CMS) use
+a two-phased reading interface. The user first marks the articles she
+wants to read from a summary buffer. Then she starts reading the
+articles with just an article buffer displayed.
@findex gnus-pick-mode
@kindex M-x gnus-pick-mode
First, pick one (1) legal mail address that you can be reached at, and
put it in your @code{From} header of all your news articles. (I've
-chosen @samp{larsi@@trym.ifi.uio.no}.)
+chosen @samp{larsi@@trym.ifi.uio.no}, but for many addresses on the form
+@samp{larsi+usenet@@ifi.uio.no} will be a better choice. Ask your
+sysadm whether your sendmail installation accepts keywords in the local
+part of the mail address.)
@lisp
(setq message-default-news-headers
citizen, you can even send off complaints to the proper authorities on
each unsolicited commercial email---at your leisure.
+If you are also a lazy net citizen, you will probably prefer complaining
+automatically with the @file{gnus-junk.el} package, availiable FOR FREE
+at @file{<URL:http://stud2.tuwien.ac.at/~e9426626/gnus-junk.html>}.
+Since most e-mail spam is sent automatically, this may reconcile the
+cosmic balance somewhat.
+
This works for me. It allows people an easy way to contact me (they can
just press @kbd{r} in the usual way), and I'm not bothered at all with
spam. It's a win-win situation. Forging @code{From} headers to point
files = "files" *[ space <string> ]
exclude-files = "exclude-files" *[ space <string> ]
read-only = "read-only" [ space "nil" / space "t" ]
-adapt = "adapt" [ space "nil" / space "t" / space adapt-rule ]
+adapt = "adapt" [ space "ignore" / space "t" / space adapt-rule ]
adapt-rule = "(" *[ <string> *[ "(" <string> <integer> ")" ] ")"
local = "local" *[ space "(" <string> space <form> ")" ]
eval = "eval" space <form>
\input texinfo @c -*-texinfo-*-
@setfilename message
-@settitle Message 5.4.45 Manual
+@settitle Message 5.4.46 Manual
@synindex fn cp
@synindex vr cp
@synindex pg cp
@tex
@titlepage
-@title Message 5.4.45 Manual
+@title Message 5.4.46 Manual
@author by Lars Magne Ingebrigtsen
@page
* Key Index:: List of Message mode keys.
@end menu
-This manual corresponds to Message 5.4.45. Message is distributed with
+This manual corresponds to Message 5.4.46. Message is distributed with
the Gnus distribution bearing the same version number as this manual
has.
@cindex mail aliases
@cindex aliases
-Message uses @code{mailabbrev} to handle mail aliases.
+@vindex message-mail-alias-type
+The @code{message-mail-alias-type} variable controls what type of mail
+alias expansion to use. Currently only one form is supported---Message
+uses @code{mailabbrev} to handle mail aliases. If this variable is
+@code{nil}, no mail alias expansion will be performed.
+
@code{mailabbrev} works by parsing the @file{/etc/mailrc} and
@file{~/.mailrc} files. These files look like:
@vindex message-mode-syntax-table
Syntax table used in message mode buffers.
+@item message-send-method-alist
+@vindex message-send-method-alist
+
+Alist of ways to send outgoing messages. Each element has the form
+
+@lisp
+(TYPE PREDICATE FUNCTION)
+@end lisp
+
+@table @var
+@item type
+A symbol that names the method.
+
+@item predicate
+A function called without any parameters to determine whether the
+message is a message of type @var{type}.
+
+@item function
+A function to be called if @var{predicate} returns non-@code{nil}.
+@var{function} is called with one parameter -- the prefix.
+@end table
+
+@lisp
+((news message-news-p message-send-via-news)
+ (mail message-mail-p message-send-via-mail))
+@end lisp
+
+
+
@end table
* new Date header scoring type -- older, newer
* use the summary toolbar in the article buffer.
+
+* a command to fetch all articles that are less than X days old.
+
+* in pick mode, `q' should save the list of selected articles in the
+group info. The next time the group is selected, these articles
+will automatically get the process mark.
+
+* Isn't it possible to (also?) allow M-^ to automatically try the
+default server if it fails on the current server? (controlled by a
+user variable, {nil, t, 'ask}).
+
+* make it possible to cancel articles using the select method for the
+current group.
+
+* `gnus-summary-select-article-on-entry' or something. It'll default
+to t and will select whatever article decided by `gnus-auto-select-first'.
+
+* a new variable to control which selection commands should be unselecting.
+`first', `best', `next', `prev', `next-unread', `prev-unread' are
+candidates.
+
+* be able to select groups that have no articles in them
+to be able to post in them (using the current select method).
+