X-Git-Url: https://cgit.sxemacs.org/?a=blobdiff_plain;f=lisp%2Fgnus-util.el;h=28a8c5dbed4303a60b63da2a483695cb45efd92b;hb=34d3c95696a2b7a1110ea12015c9582b0a9e4003;hp=a3275224e7f6c8bcb3a750807a0c3566f8946fb0;hpb=8b5af94e55ef83ee46b42d32d92fa1ce95dcacf5;p=gnus diff --git a/lisp/gnus-util.el b/lisp/gnus-util.el index a3275224e..28a8c5dbe 100644 --- a/lisp/gnus-util.el +++ b/lisp/gnus-util.el @@ -1,7 +1,7 @@ ;;; gnus-util.el --- utility functions for Gnus ;; Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, -;; 2005, 2006, 2007, 2008 Free Software Foundation, Inc. +;; 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. ;; Author: Lars Magne Ingebrigtsen ;; Keywords: news @@ -38,6 +38,12 @@ (unless (fboundp 'declare-function) (defmacro declare-function (&rest r)))) (eval-when-compile (require 'cl)) + +(eval-when-compile + (unless (fboundp 'with-no-warnings) + (defmacro with-no-warnings (&rest body) + `(progn ,@body)))) + ;; Fixme: this should be a gnus variable, not nnmail-. (defvar nnmail-pathname-coding-system) (defvar nnmail-active-file-coding-system) @@ -50,19 +56,16 @@ (require 'time-date) (require 'netrc) -(eval-and-compile - (autoload 'message-fetch-field "message") - (autoload 'gnus-get-buffer-window "gnus-win") - (autoload 'rmail-insert-rmail-file-header "rmail") - (autoload 'rmail-count-new-messages "rmail") - (autoload 'rmail-show-message "rmail") - (autoload 'nnheader-narrow-to-headers "nnheader") - (autoload 'nnheader-replace-chars-in-string "nnheader")) +(autoload 'message-fetch-field "message") +(autoload 'gnus-get-buffer-window "gnus-win") +(autoload 'nnheader-narrow-to-headers "nnheader") +(autoload 'nnheader-replace-chars-in-string "nnheader") +(autoload 'mail-header-remove-comments "mail-parse") (eval-and-compile (cond ;; Prefer `replace-regexp-in-string' (present in Emacs, XEmacs 21.5, - ;; SXEmacs 22.1.4) over `replace-in-string'. The later leads to inf-loops + ;; SXEmacs 22.1.4) over `replace-in-string'. The latter leads to inf-loops ;; on empty matches: ;; (replace-in-string "foo" "/*$" "/") ;; (replace-in-string "xe" "\\(x\\)?" "") @@ -288,6 +291,15 @@ Symbols are also allowed; their print names are used instead." (and (= (car fdate) (car date)) (> (nth 1 fdate) (nth 1 date)))))) +(eval-and-compile + (if (and (fboundp 'float-time) + (subrp (symbol-function 'float-time))) + (defalias 'gnus-float-time 'float-time) + (defun gnus-float-time (&optional time) + "Convert time value TIME to a floating point number. +TIME defaults to the current time." + (with-no-warnings (time-to-seconds (or time (current-time))))))) + ;;; Keymap macros. (defmacro gnus-local-set-keys (&rest plist) @@ -446,8 +458,8 @@ respectively.") Returns \" ? \" if there's bad input or if an other error occurs. Input should look like this: \"Sun, 14 Oct 2001 13:34:39 +0200\"." (condition-case () - (let* ((messy-date (time-to-seconds (safe-date-to-time messy-date))) - (now (time-to-seconds (current-time))) + (let* ((messy-date (gnus-float-time (safe-date-to-time messy-date))) + (now (gnus-float-time)) ;;If we don't find something suitable we'll use this one (my-format "%b %d '%y")) (let* ((difference (- now messy-date)) @@ -626,7 +638,7 @@ ARGS are passed to `message'." (defun gnus-split-references (references) "Return a list of Message-IDs in REFERENCES." (let ((beg 0) - (references (or references "")) + (references (mail-header-remove-comments (or references ""))) ids) (while (string-match "<[^<]+[^< \t]" references beg) (push (substring references (match-beginning 0) (setq beg (match-end 0))) @@ -653,8 +665,9 @@ If N, return the Nth ancestor instead." (while (nthcdr n ids) (setq ids (cdr ids))) (car ids)) - (when (string-match "\\(<[^<]+>\\)[ \t]*\\'" references) - (match-string 1 references))))) + (let ((references (mail-header-remove-comments references))) + (when (string-match "\\(<[^<]+>\\)[ \t]*\\'" references) + (match-string 1 references)))))) (defun gnus-buffer-live-p (buffer) "Say whether BUFFER is alive or not." @@ -957,10 +970,10 @@ If there's no subdirectory, delete DIRECTORY as well." (overlays-at pos))))))) ;;; Protected and atomic operations. dmoore@ucsd.edu 21.11.1996 -;;; The primary idea here is to try to protect internal datastructures -;;; from becoming corrupted when the user hits C-g, or if a hook or -;;; similar blows up. Often in Gnus multiple tables/lists need to be -;;; updated at the same time, or information can be lost. +;; The primary idea here is to try to protect internal datastructures +;; from becoming corrupted when the user hits C-g, or if a hook or +;; similar blows up. Often in Gnus multiple tables/lists need to be +;; updated at the same time, or information can be lost. (defvar gnus-atomic-be-safe t "If t, certain operations will be protected from interruption by C-g.") @@ -979,7 +992,7 @@ variables and then do only the assignment atomically." (put 'gnus-atomic-progn 'lisp-indent-function 0) (defmacro gnus-atomic-progn-assign (protect &rest forms) - "Evaluate FORMS, but insure that the variables listed in PROTECT + "Evaluate FORMS, but ensure that the variables listed in PROTECT are not changed if anything in FORMS signals an error or otherwise non-locally exits. The variables listed in PROTECT are updated atomically. It is safe to use gnus-atomic-progn-assign with long computations. @@ -1052,31 +1065,45 @@ with potentially long computations." (autoload 'rmail-summary-displayed "rmail") (autoload 'rmail-maybe-display-summary "rmail")))) -(defvar rmail-default-rmail-file) (defvar mm-text-coding-system) (declare-function mm-append-to-file "mm-util" (start end filename &optional codesys inhibit)) (defun gnus-output-to-rmail (filename &optional ask) - "Append the current article to an Rmail file named FILENAME." + "Append the current article to an Rmail file named FILENAME. +In Emacs 22 this writes Babyl format; in Emacs 23 it writes mbox unless +FILENAME exists and is Babyl format." (require 'rmail) (require 'mm-util) - ;; Most of these codes are borrowed from rmailout.el. + ;; Some of this codes is borrowed from rmailout.el. (setq filename (expand-file-name filename)) - (setq rmail-default-rmail-file filename) + ;; FIXME should we really be messing with this defcustom? + ;; It is not needed for the operation of this function. + (if (boundp 'rmail-default-rmail-file) + (setq rmail-default-rmail-file filename) ; 22 + (setq rmail-default-file filename)) ; 23 (let ((artbuf (current-buffer)) - (tmpbuf (get-buffer-create " *Gnus-output*"))) + (tmpbuf (get-buffer-create " *Gnus-output*")) + ;; Babyl rmail.el defines this, mbox does not. + (babyl (fboundp 'rmail-insert-rmail-file-header))) (save-excursion - (or (get-file-buffer filename) - (file-exists-p filename) + ;; Note that we ignore the possibility of visiting a Babyl + ;; format buffer in Emacs 23, since Rmail no longer supports that. + (or (get-file-buffer filename) + (progn + ;; In case someone wants to write to a Babyl file from Emacs 23. + (when (file-exists-p filename) + (setq babyl (mail-file-babyl-p filename)) + t)) (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) + (if (fboundp 'rmail-insert-rmail-file-header) + (rmail-insert-rmail-file-header)) (let ((require-final-newline nil) (coding-system-for-write mm-text-coding-system)) (gnus-write-buffer filename))) @@ -1085,32 +1112,56 @@ with potentially long computations." (set-buffer tmpbuf) (erase-buffer) (insert-buffer-substring artbuf) - (gnus-convert-article-to-rmail) + (if babyl + (gnus-convert-article-to-rmail) + ;; Non-Babyl case copied from gnus-output-to-mail. + (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 ((file-name-coding-system nnmail-pathname-coding-system)) - (mm-append-to-file (point-min) (point-max) filename)) + (progn + (unless babyl ; from gnus-output-to-mail + (let ((buffer-read-only nil)) + (goto-char (point-max)) + (forward-char -2) + (unless (looking-at "\n\n") + (goto-char (point-max)) + (unless (bolp) + (insert "\n")) + (insert "\n")))) + (let ((file-name-coding-system nnmail-pathname-coding-system)) + (mm-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. + ;; Compare this with rmail-output-to-rmail-buffer in Emacs 23. (when msg - (widen) - (narrow-to-region (point-max) (point-max))) + (unless babyl + (rmail-swap-buffers-maybe) + (rmail-maybe-set-message-counters)) + (widen) + (narrow-to-region (point-max) (point-max))) (insert-buffer-substring tmpbuf) (when msg - (goto-char (point-min)) - (widen) - (search-backward "\n\^_") - (narrow-to-region (point) (point-max)) + (when babyl + (goto-char (point-min)) + (widen) + (search-backward "\n\^_") + (narrow-to-region (point) (point-max))) (rmail-count-new-messages t) (when (rmail-summary-exists) (rmail-select-summary (rmail-update-summary))) - (rmail-count-new-messages t) (rmail-show-message msg)) (save-buffer))))) (kill-buffer tmpbuf))) @@ -1592,6 +1643,7 @@ CHOICE is a list of the choice char and help message at IDX." (kill-buffer buf)) tchar)) +(declare-function x-focus-frame "xfns.c" (frame)) (declare-function w32-focus-frame "../term/w32-win" (frame)) (defun gnus-select-frame-set-input-focus (frame) @@ -1609,7 +1661,7 @@ CHOICE is a list of the choice char and help message at IDX." (t (raise-frame frame) (select-frame frame) - (cond ((memq window-system '(x mac)) + (cond ((memq window-system '(x ns mac)) (x-focus-frame frame)) ((eq window-system 'w32) (w32-focus-frame frame))) @@ -1798,6 +1850,30 @@ is allowed once again. (Immediately, if `inhibit-quit' is nil.)" ;; that intends to handle the quit signal next time. (eval '(ignore nil)))))) +(defalias 'gnus-read-shell-command + (if (fboundp 'read-shell-command) 'read-shell-command 'read-string)) + +(defmacro gnus-put-display-table (range value display-table) + "Set the value for char RANGE to VALUE in DISPLAY-TABLE. " + (if (featurep 'xemacs) + (progn + `(if (fboundp 'put-display-table) + (put-display-table ,range ,value ,display-table) + (if (sequencep ,display-table) + (aset ,display-table ,range ,value) + (put-char-table ,range ,value ,display-table)))) + `(aset ,display-table ,range ,value))) + +(defmacro gnus-get-display-table (character display-table) + "Find value for CHARACTER in DISPLAY-TABLE. " + (if (featurep 'xemacs) + `(if (fboundp 'get-display-table) + (get-display-table ,character ,display-table) + (if (sequencep ,display-table) + (aref ,display-table ,character) + (get-char-table ,character ,display-table))) + `(aref ,display-table ,character))) + (provide 'gnus-util) ;; arch-tag: f94991af-d32b-4c97-8c26-ca12a934de49