;;; gnus-util.el --- utility functions for Gnus
-;; Copyright (C) 1996, 1997, 1998, 1999, 2000
+;; Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001
;; Free Software Foundation, Inc.
;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org>
;;; Code:
(require 'custom)
-(eval-when-compile (require 'cl))
+(eval-when-compile
+ (require 'cl)
+ ;; Fixme: this should be a gnus variable, not nnmail-.
+ (defvar nnmail-pathname-coding-system))
(require 'nnheader)
-(require 'message)
(require 'time-date)
(eval-and-compile
+ (autoload 'message-fetch-field "message")
(autoload 'rmail-insert-rmail-file-header "rmail")
(autoload 'rmail-count-new-messages "rmail")
(autoload 'rmail-show-message "rmail"))
(when (gnus-buffer-exists-p buf)
(kill-buffer buf))))
-(fset 'gnus-point-at-bol
- (if (fboundp 'point-at-bol)
- 'point-at-bol
- 'line-beginning-position))
+(defalias 'gnus-point-at-bol
+ (if (fboundp 'point-at-bol)
+ 'point-at-bol
+ 'line-beginning-position))
-(fset 'gnus-point-at-eol
- (if (fboundp 'point-at-eol)
- 'point-at-eol
- 'line-end-position))
+(defalias 'gnus-point-at-eol
+ (if (fboundp 'point-at-eol)
+ 'point-at-eol
+ 'line-end-position))
(defun gnus-delete-first (elt list)
"Delete by side effect the first occurrence of ELT as a member of LIST."
(delete-char 1))
(goto-char (next-single-property-change (point) prop nil (point-max))))))
+(require 'nnheader)
(defun gnus-newsgroup-directory-form (newsgroup)
"Make hierarchical directory name from NEWSGROUP name."
- (let ((newsgroup (gnus-newsgroup-savable-name newsgroup))
- (len (length newsgroup))
- idx)
- ;; If this is a foreign group, we don't want to translate the
- ;; entire name.
- (if (setq idx (string-match ":" newsgroup))
- (aset newsgroup idx ?/)
- (setq idx 0))
- ;; Replace all occurrences of `.' with `/'.
- (while (< idx len)
- (when (= (aref newsgroup idx) ?.)
- (aset newsgroup idx ?/))
- (setq idx (1+ idx)))
- newsgroup))
+ (let* ((newsgroup (gnus-newsgroup-savable-name newsgroup))
+ (idx (string-match ":" newsgroup)))
+ (concat
+ (if idx (substring newsgroup 0 idx))
+ (if idx "/")
+ (nnheader-replace-chars-in-string
+ (if idx (substring newsgroup (1+ idx)) newsgroup)
+ ?. ?/))))
(defun gnus-newsgroup-savable-name (group)
;; Replace any slashes in a group name (eg. an ange-ftp nndoc group)
time)))))
(defsubst gnus-time-iso8601 (time)
- "Return a string of TIME in YYMMDDTHHMMSS format."
+ "Return a string of TIME in YYYYMMDDTHHMMSS format."
(format-time-string "%Y%m%dT%H%M%S" time))
(defun gnus-date-iso8601 (date)
- "Convert the DATE to YYMMDDTHHMMSS."
+ "Convert the DATE to YYYYMMDDTHHMMSS."
(condition-case ()
(gnus-time-iso8601 (gnus-date-get-time date))
(error "")))
"Return a list of Message-IDs in REFERENCES."
(let ((beg 0)
ids)
- (while (string-match "<[^>]+>" references beg)
+ (while (string-match "<[^> \t]+>" references beg)
(push (substring references (match-beginning 0) (setq beg (match-end 0)))
ids))
(nreverse ids)))
(file-name-nondirectory file))))
(copy-file file to))
-(defun gnus-kill-all-overlays ()
- "Delete all overlays in the current buffer."
- (let* ((overlayss (overlay-lists))
- (buffer-read-only nil)
- (overlays (delq nil (nconc (car overlayss) (cdr overlayss)))))
- (while overlays
- (delete-overlay (pop overlays)))))
-
(defvar gnus-work-buffer " *gnus work*")
(defun gnus-set-work-buffer ()
(defun gnus-make-directory (directory)
"Make DIRECTORY (and all its parents) if it doesn't exist."
+ (require 'nnmail)
(let ((file-name-coding-system nnmail-pathname-coding-system))
(when (and directory
(not (file-exists-p directory)))
"Write the current buffer's contents to FILE."
;; Make sure the directory exists.
(gnus-make-directory (file-name-directory file))
- ;; Write the buffer.
- (write-region (point-min) (point-max) file nil 'quietly))
+ (let ((file-name-coding-system nnmail-pathname-coding-system))
+ ;; Write the buffer.
+ (write-region (point-min) (point-max) file nil 'quietly)))
(defun gnus-delete-file (file)
"Delete FILE if it exists."
(save-excursion
(save-restriction
(goto-char beg)
- (while (re-search-forward "[ \t]+\\|[ \t]*\n" end 'move)
+ (while (re-search-forward gnus-emphasize-whitespace-regexp end 'move)
(gnus-put-text-property beg (match-beginning 0) prop val)
(setq beg (point)))
(gnus-put-text-property beg (point) prop val)))))
(save-excursion
(set-buffer file-buffer)
(rmail-insert-rmail-file-header)
- (let ((require-final-newline nil))
+ (let ((require-final-newline nil)
+ (coding-system-for-write mm-text-coding-system))
(gnus-write-buffer filename)))
(kill-buffer file-buffer))
(error "Output file does not exist")))
(let ((file-buffer (create-file-buffer filename)))
(save-excursion
(set-buffer file-buffer)
- (let ((require-final-newline nil))
+ (let ((require-final-newline nil)
+ (coding-system-for-write mm-text-coding-system))
(gnus-write-buffer filename)))
(kill-buffer file-buffer))
(error "Output file does not exist")))
(forward-line 1))
(nreverse result)))))
-(defun gnus-netrc-machine (list machine &optional port)
- "Return the netrc values from LIST for MACHINE or for the default entry."
+(defun gnus-netrc-machine (list machine &optional port defaultport)
+ "Return the netrc values from LIST for MACHINE or for the default entry.
+If PORT specified, only return entries with matching port tokens.
+Entries without port tokens default to DEFAULTPORT."
(let ((rest list)
result)
(while list
(when result
(setq result (nreverse result))
(while (and result
- (not (equal (or port "nntp")
+ (not (equal (or port defaultport "nntp")
(or (gnus-netrc-get (car result) "port")
- "nntp"))))
+ defaultport "nntp"))))
(pop result))
(car result))))
(pop list))
(nreverse out)))
-(defun gnus-delete-alist (key alist)
- "Delete all entries in ALIST that have a key eq to KEY."
- (let (entry)
- (while (setq entry (assq key alist))
- (setq alist (delq entry alist)))
- alist))
+(if (fboundp 'assq-delete-all)
+ (defalias 'gnus-delete-alist 'assq-delete-all)
+ (defun gnus-delete-alist (key alist)
+ "Delete from ALIST all elements whose car is KEY.
+Return the modified alist."
+ (let (entry)
+ (while (setq entry (assq key alist))
+ (setq alist (delq entry alist)))
+ alist)))
(defmacro gnus-pull (key alist &optional assoc-p)
"Modify ALIST to be without KEY."
t))
(defun gnus-write-active-file (file hashtb &optional full-names)
- (with-temp-file file
- (mapatoms
- (lambda (sym)
- (when (and sym
- (boundp sym)
- (symbol-value sym))
- (insert (format "%S %d %d y\n"
- (if full-names
- sym
- (intern (gnus-group-real-name (symbol-name sym))))
- (or (cdr (symbol-value sym))
- (car (symbol-value sym)))
- (car (symbol-value sym))))))
- hashtb)
- (goto-char (point-max))
- (while (search-backward "\\." nil t)
- (delete-char 1))))
+ (let ((coding-system-for-write nnmail-active-file-coding-system))
+ (with-temp-file file
+ (mapatoms
+ (lambda (sym)
+ (when (and sym
+ (boundp sym)
+ (symbol-value sym))
+ (insert (format "%S %d %d y\n"
+ (if full-names
+ sym
+ (intern (gnus-group-real-name (symbol-name sym))))
+ (or (cdr (symbol-value sym))
+ (car (symbol-value sym)))
+ (car (symbol-value sym))))))
+ hashtb)
+ (goto-char (point-max))
+ (while (search-backward "\\." nil t)
+ (delete-char 1)))))
+
+(if (fboundp 'union)
+ (defalias 'gnus-union 'union)
+ (defun gnus-union (l1 l2)
+ "Set union of lists L1 and L2."
+ (cond ((null l1) l2)
+ ((null l2) l1)
+ ((equal l1 l2) l1)
+ (t
+ (or (>= (length l1) (length l2))
+ (setq l1 (prog1 l2 (setq l2 l1))))
+ (while l2
+ (or (member (car l2) l1)
+ (push (car l2) l1))
+ (pop l2))
+ l1))))
+
+(defun gnus-add-text-properties-when
+ (property value start end properties &optional object)
+ "Like `gnus-add-text-properties', only applied on where PROPERTY is VALUE."
+ (let (point)
+ (while (and start
+ (< start end) ;; XEmacs will loop for every when start=end.
+ (setq point (text-property-not-all start end property value)))
+ (gnus-add-text-properties start point properties object)
+ (setq start (text-property-any point end property value)))
+ (if start
+ (gnus-add-text-properties start end properties object))))
+
+(defun gnus-remove-text-properties-when
+ (property value start end properties &optional object)
+ "Like `remove-text-properties', only applied on where PROPERTY is VALUE."
+ (let (point)
+ (while (and start
+ (< start end)
+ (setq point (text-property-not-all start end property value)))
+ (remove-text-properties start point properties object)
+ (setq start (text-property-any point end property value)))
+ (if start
+ (remove-text-properties start end properties object))
+ t))
+
+(defun gnus-string-equal (x y)
+ "Like `string-equal', except it compares case-insensitively."
+ (and (= (length x) (length y))
+ (or (string-equal x y)
+ (string-equal (downcase x) (downcase y)))))
(provide 'gnus-util)