X-Git-Url: http://cgit.sxemacs.org/?p=gnus;a=blobdiff_plain;f=lisp%2Fgnus-util.el;h=7bacaba286df1d542e96a54f1980432c42f0bf3a;hp=f5e1077f8c462b755e1411b1d4c208f2f83bc7ec;hb=dd2bbb95234eb1d65e1a3a504f40339a4be85418;hpb=dee0c694f05b79f8ee3a20ec30064c829288ef44 diff --git a/lisp/gnus-util.el b/lisp/gnus-util.el index f5e1077f8..7bacaba28 100644 --- a/lisp/gnus-util.el +++ b/lisp/gnus-util.el @@ -1,6 +1,6 @@ ;;; gnus-util.el --- utility functions for Gnus -;; Copyright (C) 1996-2012 Free Software Foundation, Inc. +;; Copyright (C) 1996-2015 Free Software Foundation, Inc. ;; Author: Lars Magne Ingebrigtsen ;; Keywords: news @@ -32,9 +32,6 @@ ;;; Code: -;; For Emacs <22.2 and XEmacs. -(eval-and-compile - (unless (fboundp 'declare-function) (defmacro declare-function (&rest r)))) (eval-when-compile (require 'cl)) @@ -68,7 +65,7 @@ "Value of `completion-styles' to use when completing." :version "24.1" :group 'gnus-meta - :type 'list) + :type '(repeat symbol)) ;; Fixme: this should be a gnus variable, not nnmail-. (defvar nnmail-pathname-coding-system) @@ -225,7 +222,7 @@ is slower." (defun gnus-goto-colon () - (beginning-of-line) + (move-beginning-of-line 1) (let ((eol (point-at-eol))) (goto-char (or (text-property-any (point) eol 'gnus-position t) (search-forward ":" eol t) @@ -316,14 +313,10 @@ Symbols are also allowed; their print names are used instead." ;; Every version of Emacs Gnus supports has built-in float-time. ;; The featurep test silences an irritating compiler warning. -(eval-and-compile +(defalias 'gnus-float-time (if (or (featurep 'emacs) (fboundp '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." - (time-to-seconds (or time (current-time)))))) + 'float-time 'time-to-seconds)) ;;; Keymap macros. @@ -333,6 +326,13 @@ TIME defaults to the current time." (defmacro gnus-define-keys (keymap &rest plist) "Define all keys in PLIST in KEYMAP." + ;; Convert the key [?\S-\ ] to [(shift space)] for XEmacs. + (when (featurep 'xemacs) + (let ((bindings plist)) + (while bindings + (when (equal (car bindings) [?\S-\ ]) + (setcar bindings [(shift space)])) + (setq bindings (cddr bindings))))) `(gnus-define-keys-1 (quote ,keymap) (quote ,plist))) (defmacro gnus-define-keys-safe (keymap &rest plist) @@ -385,19 +385,20 @@ TIME defaults to the current time." (defun gnus-seconds-today () "Return the number of seconds passed today." - (let ((now (decode-time (current-time)))) + (let ((now (decode-time))) (+ (car now) (* (car (cdr now)) 60) (* (car (nthcdr 2 now)) 3600)))) (defun gnus-seconds-month () "Return the number of seconds passed this month." - (let ((now (decode-time (current-time)))) + (let ((now (decode-time))) (+ (car now) (* (car (cdr now)) 60) (* (car (nthcdr 2 now)) 3600) (* (- (car (nthcdr 3 now)) 1) 3600 24)))) (defun gnus-seconds-year () "Return the number of seconds passed this year." - (let ((now (decode-time (current-time))) - (days (format-time-string "%j" (current-time)))) + (let* ((current (current-time)) + (now (decode-time current)) + (days (format-time-string "%j" current))) (+ (car now) (* (car (cdr now)) 60) (* (car (nthcdr 2 now)) 3600) (* (- (string-to-number days) 1) 3600 24)))) @@ -507,11 +508,14 @@ but also to the ones displayed in the echo area." (> message-log-max 0) (/= (length str) 0)) (setq time (current-time)) - (with-current-buffer (get-buffer-create "*Messages*") + (with-current-buffer (if (fboundp 'messages-buffer) + (messages-buffer) + (get-buffer-create "*Messages*")) (goto-char (point-max)) - (insert ,timestamp str "\n") - (forward-line (- message-log-max)) - (delete-region (point-min) (point)) + (let ((inhibit-read-only t)) + (insert ,timestamp str "\n") + (forward-line (- message-log-max)) + (delete-region (point-min) (point))) (goto-char (point-max)))) str) (gnus-add-timestamp-to-message @@ -866,18 +870,29 @@ If there's no subdirectory, delete DIRECTORY as well." (setq beg (point))) (gnus-overlay-put (gnus-make-overlay beg (point)) prop val))))) -(defun gnus-put-text-property-excluding-characters-with-faces (beg end - prop val) - "The same as `put-text-property', but don't put props on characters with the `gnus-face' property." - (let ((b beg)) - (while (/= b end) - (when (get-text-property b 'gnus-face) - (setq b (next-single-property-change b 'gnus-face nil end))) - (when (/= b end) +(defun gnus-put-text-property-excluding-characters-with-faces (beg end prop val) + "The same as `put-text-property', except where `gnus-face' is set. +If so, and PROP is `face', set the second element of its value to VAL. +Otherwise, do nothing." + (while (< beg end) + ;; Property values are compared with `eq'. + (let ((stop (next-single-property-change beg 'face nil end))) + (if (get-text-property beg 'gnus-face) + (when (eq prop 'face) + (setcar (cdr (get-text-property beg 'face)) (or val 'default))) (inline - (gnus-put-text-property - b (setq b (next-single-property-change b 'gnus-face nil end)) - prop val)))))) + (gnus-put-text-property beg stop prop val))) + (setq beg stop)))) + +(defun gnus-get-text-property-excluding-characters-with-faces (pos prop) + "The same as `get-text-property', except where `gnus-face' is set. +If so, and PROP is `face', return the second element of its value. +Otherwise, return the value." + (let ((val (get-text-property pos prop))) + (if (and (get-text-property pos 'gnus-face) + (eq prop 'face)) + (cadr val) + (get-text-property pos prop)))) (defmacro gnus-faces-at (position) "Return a list of faces at POSITION." @@ -916,7 +931,7 @@ If there's no subdirectory, delete DIRECTORY as well." 'previous-extent-change 'previous-char-property-change)) ;;; Protected and atomic operations. dmoore@ucsd.edu 21.11.1996 -;; The primary idea here is to try to protect internal datastructures +;; The primary idea here is to try to protect internal data structures ;; 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. @@ -1007,6 +1022,15 @@ with potentially long computations." (declare-function mm-append-to-file "mm-util" (start end filename &optional codesys inhibit)) +(declare-function rmail-swap-buffers-maybe "rmail" ()) +(declare-function rmail-maybe-set-message-counters "rmail" ()) +(declare-function rmail-count-new-messages "rmail" (&optional nomsg)) +(declare-function rmail-summary-exists "rmail" ()) +(declare-function rmail-show-message "rmail" (&optional n no-summary)) +;; Macroexpansion of rmail-select-summary: +(declare-function rmail-summary-displayed "rmail" ()) +(declare-function rmail-pop-to-buffer "rmail" (&rest args)) +(declare-function rmail-maybe-display-summary "rmail" ()) (defun gnus-output-to-rmail (filename &optional ask) "Append the current article to an Rmail file named FILENAME. @@ -1531,9 +1555,15 @@ SPEC is a predicate specifier that contains stuff like `or', `and', "Call standard `completing-read-function'." (let ((completion-styles gnus-completion-styles)) (completing-read prompt - ;; Old XEmacs (at least 21.4) expect an alist for - ;; collection. - (mapcar 'list collection) + (if (featurep 'xemacs) + ;; Old XEmacs (at least 21.4) expect an alist, + ;; in which the car of each element is a string, + ;; for collection. + (mapcar + (lambda (elem) + (list (format "%s" (or (car-safe elem) elem)))) + collection) + collection) nil require-match initial-input history def))) (autoload 'ido-completing-read "ido") @@ -1855,6 +1885,8 @@ empty directories from OLD-PATH." (get-char-table ,character ,display-table))) `(aref ,display-table ,character))) +(declare-function image-size "image.c" (spec &optional pixels frame)) + (defun gnus-rescale-image (image size) "Rescale IMAGE to SIZE if possible. SIZE is in format (WIDTH . HEIGHT). Return a new image. @@ -1875,17 +1907,25 @@ Sizes are in pixels." image))) image))) +(eval-when-compile (require 'gmm-utils)) (defun gnus-recursive-directory-files (dir) - "Return all regular files below DIR." - (let (files) - (dolist (file (directory-files dir t)) - (when (and (not (member (file-name-nondirectory file) '("." ".."))) - (file-readable-p file)) - (cond - ((file-regular-p file) - (push file files)) - ((file-directory-p file) - (setq files (append (gnus-recursive-directory-files file) files)))))) + "Return all regular files below DIR. +The first found will be returned if a file has hard or symbolic links." + (let (files attr attrs) + (gmm-labels + ((fn (directory) + (dolist (file (directory-files directory t)) + (setq attr (file-attributes (file-truename file))) + (when (and (not (member attr attrs)) + (not (member (file-name-nondirectory file) + '("." ".."))) + (file-readable-p file)) + (push attr attrs) + (cond ((file-regular-p file) + (push file files)) + ((file-directory-p file) + (fn file))))))) + (fn dir)) files)) (defun gnus-list-memq-of-list (elements list) @@ -1938,27 +1978,6 @@ to case differences." (string-equal (downcase str1) (downcase prefix)) (string-equal str1 prefix)))))) -(eval-and-compile - (if (fboundp 'macroexpand-all) - (defalias 'gnus-macroexpand-all 'macroexpand-all) - (defun gnus-macroexpand-all (form &optional environment) - "Return result of expanding macros at all levels in FORM. -If no macros are expanded, FORM is returned unchanged. -The second optional arg ENVIRONMENT specifies an environment of macro -definitions to shadow the loaded ones for use in file byte-compilation." - (if (consp form) - (let ((idx 1) - (len (length (setq form (copy-sequence form)))) - expanded) - (while (< idx len) - (setcar (nthcdr idx form) (gnus-macroexpand-all (nth idx form) - environment)) - (setq idx (1+ idx))) - (if (eq (setq expanded (macroexpand form environment)) form) - form - (gnus-macroexpand-all expanded environment))) - form)))) - ;; Simple check: can be a macro but this way, although slow, it's really clear. ;; We don't use `bound-and-true-p' because it's not in XEmacs. (defun gnus-bound-and-true-p (sym)