;;; gnus-util.el --- utility functions for Gnus
-;; Copyright (C) 1996 Free Software Foundation, Inc.
+;; Copyright (C) 1996,97 Free Software Foundation, Inc.
;; Author: Lars Magne Ingebrigtsen <larsi@ifi.uio.no>
;; Keywords: news
(require 'timezone)
(require 'message)
+(eval-and-compile
+ (autoload 'nnmail-date-to-time "nnmail"))
+
(defun gnus-boundp (variable)
"Return non-nil if VARIABLE is bound and non-nil."
(and (boundp variable)
(defmacro gnus-eval-in-buffer-window (buffer &rest forms)
"Pop to BUFFER, evaluate FORMS, and then return to the original window."
(let ((tempvar (make-symbol "GnusStartBufferWindow"))
- (w (make-symbol "w"))
- (buf (make-symbol "buf")))
+ (w (make-symbol "w"))
+ (buf (make-symbol "buf")))
`(let* ((,tempvar (selected-window))
- (,buf ,buffer)
- (,w (get-buffer-window ,buf 'visible)))
+ (,buf ,buffer)
+ (,w (get-buffer-window ,buf 'visible)))
(unwind-protect
- (progn
- (if ,w
- (select-window ,w)
- (pop-to-buffer ,buf))
- ,@forms)
- (select-window ,tempvar)))))
+ (progn
+ (if ,w
+ (progn
+ (select-window ,w)
+ (set-buffer (window-buffer ,w)))
+ (pop-to-buffer ,buf))
+ ,@forms)
+ (select-window ,tempvar)))))
(put 'gnus-eval-in-buffer-window 'lisp-indent-function 1)
(put 'gnus-eval-in-buffer-window 'edebug-form-spec '(form body))
(when (gnus-buffer-exists-p buf)
(kill-buffer buf))))
-(defsubst gnus-point-at-bol ()
- "Return point at the beginning of the line."
- (let ((p (point)))
- (beginning-of-line)
- (prog1
- (point)
- (goto-char p))))
-
-(defsubst gnus-point-at-eol ()
- "Return point at the end of the line."
- (let ((p (point)))
- (end-of-line)
- (prog1
- (point)
- (goto-char p))))
+(if (fboundp 'point-at-bol)
+ (fset 'gnus-point-at-bol 'point-at-bol)
+ (defun gnus-point-at-bol ()
+ "Return point at the beginning of the line."
+ (let ((p (point)))
+ (beginning-of-line)
+ (prog1
+ (point)
+ (goto-char p)))))
+
+(if (fboundp 'point-at-eol)
+ (fset 'gnus-point-at-eol 'point-at-eol)
+ (defun gnus-point-at-eol ()
+ "Return point at the end of the line."
+ (let ((p (point)))
+ (end-of-line)
+ (prog1
+ (point)
+ (goto-char p)))))
(defun gnus-delete-first (elt list)
"Delete by side effect the first occurrence of ELT as a member of LIST."
(defun gnus-completing-read (default prompt &rest args)
;; Like `completing-read', except that DEFAULT is the default argument.
- (let* ((prompt (if default
+ (let* ((prompt (if default
(concat prompt " (default " default ") ")
(concat prompt " ")))
(answer (apply 'completing-read prompt args)))
(defsubst gnus-time-iso8601 (time)
"Return a string of TIME in YYMMDDTHHMMSS format."
(format-time-string "%Y%m%dT%H%M%S" time))
-
+
(defun gnus-date-iso8601 (header)
"Convert the date field in HEADER to YYMMDDTHHMMSS"
(condition-case ()
(sit-for duration))))
nil)
-(defun gnus-parent-id (references &optional n)
- "Return the last Message-ID in REFERENCES.
-If N, return the Nth ancestor instead."
- (when references
- (let ((ids (gnus-split-references references)))
- (car (last ids (or n 1))))))
-
(defun gnus-split-references (references)
"Return a list of Message-IDs in REFERENCES."
(let ((beg 0)
ids))
(nreverse ids)))
+(defun gnus-parent-id (references &optional n)
+ "Return the last Message-ID in REFERENCES.
+If N, return the Nth ancestor instead."
+ (when references
+ (let ((ids (inline (gnus-split-references references))))
+ (car (last ids (or n 1))))))
+
(defun gnus-buffer-live-p (buffer)
"Say whether BUFFER is alive or not."
(and buffer
(goto-char orig)
;; Scroll horizontally to center (sort of) the point.
(if (> max (window-width))
- (set-window-hscroll
+ (set-window-hscroll
(get-buffer-window (current-buffer) t)
(min (- (current-column) (/ (window-width) 3))
(+ 2 (- max (window-width)))))
Timezone package is used."
(condition-case ()
(progn
- (setq date (inline (timezone-fix-time
- date nil
+ (setq date (inline (timezone-fix-time
+ date nil
(aref (inline (timezone-parse-date date)) 4))))
(inline
(timezone-make-sortable-date
(timezone-make-time-string
(aref date 3) (aref date 4) (aref date 5))))))
(error "")))
-
+
(defun gnus-copy-file (file &optional to)
"Copy FILE to TO."
(interactive
(defun gnus-make-sort-function (funs)
"Return a composite sort condition based on the functions in FUNC."
- (cond
+ (cond
((not (listp funs)) funs)
((null funs) funs)
((cdr funs)
`(,(car funs) t1 t2)))
(defun gnus-turn-off-edit-menu (type)
- "Turn off edit meny in `gnus-TYPE-mode-map'."
+ "Turn off edit menu in `gnus-TYPE-mode-map'."
(define-key (symbol-value (intern (format "gnus-%s-mode-map" type)))
[menu-bar edit] 'undefined))
(defun gnus-prin1 (form)
"Use `prin1' on FORM in the current buffer.
Bind `print-quoted' to t while printing."
- (let ((print-quoted t))
+ (let ((print-quoted t)
+ print-level print-length)
(prin1 form (current-buffer))))
(defun gnus-prin1-to-string (form)
;(put 'gnus-atomic-setq 'edebug-form-spec '(body))
+;;; Functions for saving to babyl/mail files.
+
+(defvar rmail-default-rmail-file)
+(defun gnus-output-to-rmail (filename &optional ask)
+ "Append the current article to an Rmail file named FILENAME."
+ (require 'rmail)
+ ;; Most of these codes are borrowed from rmailout.el.
+ (setq filename (expand-file-name filename))
+ (setq rmail-default-rmail-file filename)
+ (let ((artbuf (current-buffer))
+ (tmpbuf (get-buffer-create " *Gnus-output*")))
+ (save-excursion
+ (or (get-file-buffer filename)
+ (file-exists-p filename)
+ (if (or (not ask)
+ (gnus-yes-or-no-p
+ (concat "\"" filename "\" does not exist, create it? ")))
+ (let ((file-buffer (create-file-buffer filename)))
+ (save-excursion
+ (set-buffer file-buffer)
+ (rmail-insert-rmail-file-header)
+ (let ((require-final-newline nil))
+ (gnus-write-buffer filename)))
+ (kill-buffer file-buffer))
+ (error "Output file does not exist")))
+ (set-buffer tmpbuf)
+ (erase-buffer)
+ (insert-buffer-substring artbuf)
+ (gnus-convert-article-to-rmail)
+ ;; Decide whether to append to a file or to an Emacs buffer.
+ (let ((outbuf (get-file-buffer filename)))
+ (if (not outbuf)
+ (append-to-file (point-min) (point-max) filename)
+ ;; File has been visited, in buffer OUTBUF.
+ (set-buffer outbuf)
+ (let ((buffer-read-only nil)
+ (msg (and (boundp 'rmail-current-message)
+ (symbol-value 'rmail-current-message))))
+ ;; If MSG is non-nil, buffer is in RMAIL mode.
+ (when msg
+ (widen)
+ (narrow-to-region (point-max) (point-max)))
+ (insert-buffer-substring tmpbuf)
+ (when msg
+ (goto-char (point-min))
+ (widen)
+ (search-backward "\^_")
+ (narrow-to-region (point) (point-max))
+ (goto-char (1+ (point-min)))
+ (rmail-count-new-messages t)
+ (rmail-show-message msg))))))
+ (kill-buffer tmpbuf)))
+
+(defun gnus-output-to-mail (filename &optional ask)
+ "Append the current article to a mail file named FILENAME."
+ (setq filename (expand-file-name filename))
+ (let ((artbuf (current-buffer))
+ (tmpbuf (get-buffer-create " *Gnus-output*")))
+ (save-excursion
+ ;; Create the file, if it doesn't exist.
+ (when (and (not (get-file-buffer filename))
+ (not (file-exists-p filename)))
+ (if (or (not ask)
+ (gnus-y-or-n-p
+ (concat "\"" filename "\" does not exist, create it? ")))
+ (let ((file-buffer (create-file-buffer filename)))
+ (save-excursion
+ (set-buffer file-buffer)
+ (let ((require-final-newline nil))
+ (gnus-write-buffer filename)))
+ (kill-buffer file-buffer))
+ (error "Output file does not exist")))
+ (set-buffer tmpbuf)
+ (erase-buffer)
+ (insert-buffer-substring artbuf)
+ (goto-char (point-min))
+ (if (looking-at "From ")
+ (forward-line 1)
+ (insert "From nobody " (current-time-string) "\n"))
+ (let (case-fold-search)
+ (while (re-search-forward "^From " nil t)
+ (beginning-of-line)
+ (insert ">")))
+ ;; Decide whether to append to a file or to an Emacs buffer.
+ (let ((outbuf (get-file-buffer filename)))
+ (if (not outbuf)
+ (let ((buffer-read-only nil))
+ (save-excursion
+ (goto-char (point-max))
+ (forward-char -2)
+ (unless (looking-at "\n\n")
+ (goto-char (point-max))
+ (unless (bolp)
+ (insert "\n"))
+ (insert "\n"))
+ (goto-char (point-max))
+ (append-to-file (point-min) (point-max) filename)))
+ ;; File has been visited, in buffer OUTBUF.
+ (set-buffer outbuf)
+ (let ((buffer-read-only nil))
+ (goto-char (point-max))
+ (unless (eobp)
+ (insert "\n"))
+ (insert "\n")
+ (insert-buffer-substring tmpbuf)))))
+ (kill-buffer tmpbuf)))
+
+(defun gnus-convert-article-to-rmail ()
+ "Convert article in current buffer to Rmail message format."
+ (let ((buffer-read-only nil))
+ ;; Convert article directly into Babyl format.
+ (goto-char (point-min))
+ (insert "\^L\n0, unseen,,\n*** EOOH ***\n")
+ (while (search-forward "\n\^_" nil t) ;single char
+ (replace-match "\n^_" t t)) ;2 chars: "^" and "_"
+ (goto-char (point-max))
+ (insert "\^_")))
+
(provide 'gnus-util)
;;; gnus-util.el ends here