*** pub/rgnus/lisp/article.el Fri Oct 11 12:07:35 1996 --- rgnus/lisp/article.el Tue Oct 29 17:19:57 1996 *************** *** 252,258 **** ;; Then treat the rest of the header lines. (narrow-to-region (point) ! (progn (search-forward "\n\n" nil t) (forward-line -1) (point))) ;; Then we use the two regular expressions ;; `gnus-ignored-headers' and `gnus-visible-headers' to ;; select which header lines is to remain visible in the --- 252,260 ---- ;; Then treat the rest of the header lines. (narrow-to-region (point) ! (if (search-forward "\n\n" nil t) ; if there's a body ! (progn (forward-line -1) (point)) ! (point-max))) ;; Then we use the two regular expressions ;; `gnus-ignored-headers' and `gnus-visible-headers' to ;; select which header lines is to remain visible in the *************** *** 632,638 **** (defvar mime::preview/content-list) (defvar mime::preview-content-info/point-min) (defun article-narrow-to-signature () ! "Narrow to the signature." (widen) (when (and (boundp 'mime::preview/content-list) mime::preview/content-list) --- 634,640 ---- (defvar mime::preview/content-list) (defvar mime::preview-content-info/point-min) (defun article-narrow-to-signature () ! "Narrow to the signature; return t if a signature is found, else nil." (widen) (when (and (boundp 'mime::preview/content-list) mime::preview/content-list) *** pub/rgnus/lisp/custom-edit.el Thu Oct 10 13:44:36 1996 --- rgnus/lisp/custom-edit.el Tue Oct 29 17:41:48 1996 *************** *** 4,10 **** ;; ;; Author: Per Abrahamsen ;; Keywords: help, faces ! ;; Version: 0.993 ;; X-URL: http://www.dina.kvl.dk/~abraham/custom/ ;;; Commentary: --- 4,10 ---- ;; ;; Author: Per Abrahamsen ;; Keywords: help, faces ! ;; Version: 0.995 ;; X-URL: http://www.dina.kvl.dk/~abraham/custom/ ;;; Commentary: *************** *** 15,20 **** --- 15,21 ---- (require 'custom) (require 'widget-edit) + (require 'easymenu) (define-widget-keywords :custom-show :custom-magic :custom-state :custom-level :custom-form *************** *** 285,294 **** (form (widget-get widget :custom-form)) (state (widget-get widget :custom-state)) (symbol (widget-get widget :value)) (child-type (or (get symbol 'custom-type) 'sexp)) ! (type (if (listp child-type) ! child-type ! (list child-type))) (conv (widget-convert type)) (value (if (boundp symbol) (symbol-value symbol) --- 286,299 ---- (form (widget-get widget :custom-form)) (state (widget-get widget :custom-state)) (symbol (widget-get widget :value)) + (options (get symbol 'custom-options)) (child-type (or (get symbol 'custom-type) 'sexp)) ! (type (let ((tmp (if (listp child-type) ! child-type ! (list child-type)))) ! (when options ! (widget-put tmp :options options)) ! tmp)) (conv (widget-convert type)) (value (if (boundp symbol) (symbol-value symbol) *************** *** 668,673 **** --- 673,699 ---- (widget-value-set widget (intern answer)) (widget-apply widget :notify widget event) (widget-setup)))) + + ;;; The `hook' Widget. + + (define-widget 'hook 'list + "A emacs lisp hook" + :convert-widget 'custom-hook-convert-widget + :tag "Hook") + + (defun custom-hook-convert-widget (widget) + ;; Handle `:custom-options'. + (let* ((options (widget-get widget :options)) + (other `(editable-list :inline t (function :format "%v"))) + (args (if options + (list `(checklist :inline t + ,@(mapcar (lambda (entry) + `(function-item ,entry)) + options)) + other) + (list other)))) + (widget-put widget :args args) + widget)) ;;; The `custom-group' Widget. *** pub/rgnus/lisp/custom.el Thu Oct 10 13:44:33 1996 --- rgnus/lisp/custom.el Tue Oct 29 17:41:46 1996 *************** *** 4,10 **** ;; ;; Author: Per Abrahamsen ;; Keywords: help, faces ! ;; Version: 0.993 ;; X-URL: http://www.dina.kvl.dk/~abraham/custom/ ;;; Commentary: --- 4,10 ---- ;; ;; Author: Per Abrahamsen ;; Keywords: help, faces ! ;; Version: 0.995 ;; X-URL: http://www.dina.kvl.dk/~abraham/custom/ ;;; Commentary: *************** *** 19,25 **** (require 'widget) ! (define-widget-keywords :type :group) ;; These autoloads should be deleted when the file is added to Emacs (autoload 'customize "custom-edit" nil t) --- 19,25 ---- (require 'widget) ! (define-widget-keywords :options :type :group) ;; These autoloads should be deleted when the file is added to Emacs (autoload 'customize "custom-edit" nil t) *************** *** 48,60 **** (color-instance-name (specifier-instance (face-background 'default)))) ! (error nil)))) ! (cond (bg-resource (intern (downcase bg-resource))) ! ((and color ! (< (apply '+ (custom-x-color-values color)) ! (/ (apply '+ (custom-x-color-values "white")) 3))) ! 'dark) ! (t 'light)))) ;;; The `defcustom' Macro. --- 48,68 ---- (color-instance-name (specifier-instance (face-background 'default)))) ! (error nil))) ! (mode (cond (bg-resource (intern (downcase bg-resource))) ! ((and color ! (< (apply '+ (custom-x-color-values color)) ! (/ (apply '+ (custom-x-color-values "white")) ! 3))) ! 'dark) ! (t 'light)))) ! (if (fboundp 'set-frame-property) ! ;; `modify-frame-properties' is borken on XEmacs 19.14. ! (set-frame-property (selected-frame) 'background-mode mode) ! ;; `set-frame-property' is unimplemented in Emacs 19.34. ! (modify-frame-parameters (selected-frame) ! (cons (cons 'background-mode mode) params))) ! mode)) ;;; The `defcustom' Macro. *************** *** 80,85 **** --- 88,96 ---- (setq args (cdr args)) (cond ((eq keyword :type) (put symbol 'custom-type value)) + ((eq keyword :options) + (put symbol 'custom-options + (append value (get symbol 'custom-options)))) ((eq keyword :group) (custom-add-to-group value symbol 'custom-variable)) (t *************** *** 98,104 **** The following KEYWORD's are defined: ! :type VALUE should be a sexp widget. :group VALUE should be a customization group. Add SYMBOL to that group. --- 109,116 ---- The following KEYWORD's are defined: ! :type VALUE should be a widget type. ! :options VALUE should be a list of valid members of the widget type. :group VALUE should be a customization group. Add SYMBOL to that group. *************** *** 113,122 **** (defun custom-declare-face (face spec doc &rest args) "Like `defface', but FACE is evaluated as a normal argument." (put face 'factory-face spec) ! (unless (facep face) ! ;; If the user has already created the face, respect that. ! (let ((value (or (get face 'saved-face) spec))) ! (custom-face-display-set face value))) (when doc (put face 'face-documentation doc)) (while args --- 125,135 ---- (defun custom-declare-face (face spec doc &rest args) "Like `defface', but FACE is evaluated as a normal argument." (put face 'factory-face spec) ! (when (fboundp 'facep) ! (unless (facep face) ! ;; If the user has already created the face, respect that. ! (let ((value (or (get face 'saved-face) spec))) ! (custom-face-display-set face value)))) (when doc (put face 'face-documentation doc)) (while args *************** *** 274,280 **** (defun custom-display-match-frame (display frame) "Non-nil iff DISPLAY matches FRAME. If FRAME is nil, the current FRAME is used." ! ;; This is a kludge to get started, we realle should use specifiers! (unless frame (setq frame (selected-frame))) (if (eq display t) --- 287,293 ---- (defun custom-display-match-frame (display frame) "Non-nil iff DISPLAY matches FRAME. If FRAME is nil, the current FRAME is used." ! ;; This is a kludge to get started, we really should use specifiers! (unless frame (setq frame (selected-frame))) (if (eq display t) *************** *** 287,295 **** (options (cdr entry))) (setq display (cdr display)) (cond ((eq req 'type) ! (setq match (if (fboundp 'device-type) (device-type frame) ! (memq window-system options)))) ((eq req 'class) (let ((class (if (fboundp 'device-class) (device-class frame) --- 300,309 ---- (options (cdr entry))) (setq display (cdr display)) (cond ((eq req 'type) ! (let ((type (if (fboundp 'device-type) (device-type frame) ! window-system))) ! (setq match (memq type options)))) ((eq req 'class) (let ((class (if (fboundp 'device-class) (device-class frame) *** pub/rgnus/lisp/gnus-art.el Tue Oct 8 12:47:05 1996 --- rgnus/lisp/gnus-art.el Tue Oct 29 17:21:58 1996 *************** *** 73,86 **** * gnus-summary-save-in-rmail (Rmail format) * gnus-summary-save-in-mail (Unix mail format) * gnus-summary-save-in-folder (MH folder) ! * gnus-summary-save-in-file (article format). ! * gnus-summary-save-in-vm (use VM's folder format)." :group 'article :type '(radio (function-item gnus-summary-save-in-rmail) (function-item gnus-summary-save-in-mail) (function-item gnus-summary-save-in-folder) (function-item gnus-summary-save-in-file) ! (function-item gnus-summary-save-in-vm))) (defcustom gnus-rmail-save-name 'gnus-plain-save-name "A function generating a file name to save articles in Rmail format. --- 73,88 ---- * gnus-summary-save-in-rmail (Rmail format) * gnus-summary-save-in-mail (Unix mail format) * gnus-summary-save-in-folder (MH folder) ! * gnus-summary-save-in-file (article format) ! * gnus-summary-save-in-vm (use VM's folder format) ! * gnus-summary-write-to-file (article format -- overwrite)." :group 'article :type '(radio (function-item gnus-summary-save-in-rmail) (function-item gnus-summary-save-in-mail) (function-item gnus-summary-save-in-folder) (function-item gnus-summary-save-in-file) ! (function-item gnus-summary-save-in-vm) ! (function-item gnus-summary-write-to-file))) (defcustom gnus-rmail-save-name 'gnus-plain-save-name "A function generating a file name to save articles in Rmail format. *************** *** 473,479 **** ;; Remember the directory name to save articles. (setq gnus-newsgroup-last-mail filename))) ! (defun gnus-summary-save-in-file (&optional filename) "Append this article to file. Optional argument FILENAME specifies file name. Directory to save to is default to `gnus-article-save-directory'." --- 475,481 ---- ;; Remember the directory name to save articles. (setq gnus-newsgroup-last-mail filename))) ! (defun gnus-summary-save-in-file (&optional filename overwrite) "Append this article to file. Optional argument FILENAME specifies file name. Directory to save to is default to `gnus-article-save-directory'." *************** *** 489,520 **** (save-excursion (save-restriction (widen) (gnus-output-to-file filename)))) ;; Remember the directory name to save articles. (setq gnus-newsgroup-last-file filename))) ! (defun gnus-summary-save-body-in-file (&optional filename) "Append this article body to a file. Optional argument FILENAME specifies file name. The directory to save in defaults to `gnus-article-save-directory'." (interactive) ! (gnus-set-global-variables) ! (let ((default-name ! (funcall gnus-file-save-name gnus-newsgroup-name ! gnus-current-headers gnus-newsgroup-last-file))) ! (setq filename (gnus-read-save-file-name ! "Save %s body in file:" default-name filename)) ! (gnus-make-directory (file-name-directory filename)) ! (gnus-eval-in-buffer-window gnus-original-article-buffer ! (save-excursion ! (save-restriction ! (widen) ! (goto-char (point-min)) ! (when (search-forward "\n\n" nil t) ! (narrow-to-region (point) (point-max))) ! (gnus-output-to-file filename)))) ! ;; Remember the directory name to save articles. ! (setq gnus-newsgroup-last-file filename))) (defun gnus-summary-save-in-pipe (&optional command) "Pipe this article to subprocess." --- 491,509 ---- (save-excursion (save-restriction (widen) + (when (and overwrite + (file-exists-p filename)) + (delete-file filename)) (gnus-output-to-file filename)))) ;; Remember the directory name to save articles. (setq gnus-newsgroup-last-file filename))) ! (defun gnus-summary-write-to-file (&optional filename) "Append this article body to a file. Optional argument FILENAME specifies file name. The directory to save in defaults to `gnus-article-save-directory'." (interactive) ! (gnus-summary-save-in-file nil t)) (defun gnus-summary-save-in-pipe (&optional command) "Pipe this article to subprocess." *************** *** 1472,1478 **** gnus-button-fetch-group 3) ("\\(\n\t ]*\\)>?\\)" 1 t gnus-button-message-id 3) ! ("\\( \n\t]+\\)>?" 0 t gnus-button-reply 2) ;; This is how URLs _should_ be embedded in text... ("]*\\)>" 0 t gnus-button-url 1) ;; Next regexp stolen from highlight-headers.el. --- 1461,1467 ---- gnus-button-fetch-group 3) ("\\(\n\t ]*\\)>?\\)" 1 t gnus-button-message-id 3) ! ("\\( \n\t]+\\)>?" 0 t gnus-url-mailto 2) ;; This is how URLs _should_ be embedded in text... ("]*\\)>" 0 t gnus-button-url 1) ;; Next regexp stolen from highlight-headers.el. *************** *** 1831,1836 **** --- 1820,1908 ---- (nntp-port-number ,(if (match-end 3) (match-string 3 address) "nntp")))))) + + (defun gnus-split-string (string pattern) + "Return a list of substrings of STRING which are separated by PATTERN." + (let (parts (start 0)) + (while (string-match pattern string start) + (setq parts (cons (substring string start (match-beginning 0)) parts) + start (match-end 0))) + (nreverse (cons (substring string start) parts)))) + + (defun gnus-url-parse-query-string (query &optional downcase) + (let (retval pairs cur key val) + (setq pairs (gnus-split-string query "&")) + (while pairs + (setq cur (car pairs) + pairs (cdr pairs)) + (if (not (string-match "=" cur)) + nil ; Grace + (setq key (gnus-url-unhex-string (substring cur 0 (match-beginning 0))) + val (gnus-url-unhex-string (substring cur (match-end 0) nil))) + (if downcase + (setq key (downcase key))) + (setq cur (assoc key retval)) + (if cur + (setcdr cur (cons val (cdr cur))) + (setq retval (cons (list key val) retval))))) + retval)) + + (defun gnus-url-unhex (x) + (if (> x ?9) + (if (>= x ?a) + (+ 10 (- x ?a)) + (+ 10 (- x ?A))) + (- x ?0))) + + (defun gnus-url-unhex-string (str &optional allow-newlines) + "Remove %XXX embedded spaces, etc in a url. + If optional second argument ALLOW-NEWLINES is non-nil, then allow the + decoding of carriage returns and line feeds in the string, which is normally + forbidden in URL encoding." + (setq str (or str "")) + (let ((tmp "") + (case-fold-search t)) + (while (string-match "%[0-9a-f][0-9a-f]" str) + (let* ((start (match-beginning 0)) + (ch1 (gnus-url-unhex (elt str (+ start 1)))) + (code (+ (* 16 ch1) + (gnus-url-unhex (elt str (+ start 2)))))) + (setq tmp (concat + tmp (substring str 0 start) + (cond + (allow-newlines + (char-to-string code)) + ((or (= code ?\n) (= code ?\r)) + " ") + (t (char-to-string code)))) + str (substring str (match-end 0))))) + (setq tmp (concat tmp str)) + tmp)) + + (defun gnus-url-mailto (url) + ;; Send mail to someone + (if (not (string-match "mailto:/*\\(.*\\)" url)) + (error "Malformed mailto link: %s" url)) + (setq url (substring url (match-beginning 1) nil)) + (let (to args source-url subject func) + (if (string-match (regexp-quote "?") url) + (setq to (gnus-url-unhex-string (substring url 0 (match-beginning 0))) + args (gnus-url-parse-query-string + (substring url (match-end 0) nil) t)) + (setq to (gnus-url-unhex-string url))) + (setq args (cons (list "to" to) args) + subject (cdr-safe (assoc "subject" args))) + (message-mail) + (while args + (setq func (intern-soft (concat "message-goto-" (downcase (caar args))))) + (if (fboundp func) + (funcall func) + (message-position-on-field (caar args))) + (insert (mapconcat 'identity (cdar args) ", ")) + (setq args (cdr args))) + (if subject + (message-goto-body) + (message-goto-subject)))) (defun gnus-button-mailto (address) ;; Mail to ADDRESS. *** pub/rgnus/lisp/gnus-async.el Tue Oct 8 12:47:05 1996 --- rgnus/lisp/gnus-async.el Tue Oct 29 17:19:57 1996 *************** *** 104,110 **** (gnus-async-release-semaphore 'gnus-async-article-semaphore))) (put 'gnus-asynch-with-semaphore 'lisp-indent-function 0) - (put 'gnus-asynch-with-semaphore 'lisp-indent-hook 0) (put 'gnus-asynch-with-semaphore 'edebug-form-spec '(body)) ;;; --- 104,109 ---- *************** *** 199,211 **** "Return a callback function." `(lambda (arg) (save-excursion ! (gnus-async-set-buffer) ! (gnus-async-with-semaphore ! (push (list ',(intern (format "%s-%d" group article)) ! ,mark (set-marker (make-marker) ! (point-max)) ! ,group ,article) ! gnus-async-article-alist)) (if (not (gnus-buffer-live-p ,summary)) (gnus-async-with-semaphore (setq gnus-async-fetch-list nil)) --- 198,210 ---- "Return a callback function." `(lambda (arg) (save-excursion ! (when arg ! (gnus-async-set-buffer) ! (gnus-async-with-semaphore ! (push (list ',(intern (format "%s-%d" group article)) ! ,mark (set-marker (make-marker) (point-max)) ! ,group ,article) ! gnus-async-article-alist))) (if (not (gnus-buffer-live-p ,summary)) (gnus-async-with-semaphore (setq gnus-async-fetch-list nil)) *** pub/rgnus/lisp/gnus-cache.el Tue Oct 8 12:47:04 1996 --- rgnus/lisp/gnus-cache.el Tue Oct 29 17:19:58 1996 *************** *** 397,409 **** (defun gnus-cache-file-name (group article) (concat (file-name-as-directory gnus-cache-directory) (file-name-as-directory ! (if (gnus-use-long-file-name 'not-cache) ! group ! (let ((group (nnheader-replace-chars-in-string group ?/ ?_))) ! ;; Translate the first colon into a slash. ! (when (string-match ":" group) ! (aset group (match-beginning 0) ?/)) ! (nnheader-replace-chars-in-string group ?. ?/)))) (if (stringp article) article (int-to-string article)))) (defun gnus-cache-update-article (group article) --- 397,410 ---- (defun gnus-cache-file-name (group article) (concat (file-name-as-directory gnus-cache-directory) (file-name-as-directory ! (nnheader-translate-file-chars ! (if (gnus-use-long-file-name 'not-cache) ! group ! (let ((group (nnheader-replace-chars-in-string group ?/ ?_))) ! ;; Translate the first colon into a slash. ! (when (string-match ":" group) ! (aset group (match-beginning 0) ?/)) ! (nnheader-replace-chars-in-string group ?. ?/))))) (if (stringp article) article (int-to-string article)))) (defun gnus-cache-update-article (group article) *** pub/rgnus/lisp/gnus-demon.el Tue Oct 8 12:47:03 1996 --- rgnus/lisp/gnus-demon.el Tue Oct 29 17:19:58 1996 *************** *** 220,256 **** (defun gnus-demon-scan-nocem () "Scan NoCeM groups for NoCeM messages." ! (gnus-nocem-scan-groups)) (defun gnus-demon-add-disconnection () "Add daemonic server disconnection to Gnus." (gnus-demon-add-handler 'gnus-demon-close-connections nil 30)) (defun gnus-demon-close-connections () ! (gnus-close-backends)) (defun gnus-demon-add-scanmail () "Add daemonic scanning of mail from the mail backends." (gnus-demon-add-handler 'gnus-demon-scan-mail 120 60)) (defun gnus-demon-scan-mail () ! (let ((servers gnus-opened-servers) ! server) ! (while (setq server (car (pop servers))) ! (and (gnus-check-backend-function 'request-scan (car server)) ! (or (gnus-server-opened server) ! (gnus-open-server server)) ! (gnus-request-scan nil server))))) (defun gnus-demon-add-rescan () "Add daemonic scanning of new articles from all backends." (gnus-demon-add-handler 'gnus-demon-scan-news 120 60)) (defun gnus-demon-scan-news () ! (when (gnus-alive-p) ! (save-excursion ! (set-buffer gnus-group-buffer) ! (gnus-group-get-new-news)))) (provide 'gnus-demon) --- 220,260 ---- (defun gnus-demon-scan-nocem () "Scan NoCeM groups for NoCeM messages." ! (save-window-excursion ! (gnus-nocem-scan-groups))) (defun gnus-demon-add-disconnection () "Add daemonic server disconnection to Gnus." (gnus-demon-add-handler 'gnus-demon-close-connections nil 30)) (defun gnus-demon-close-connections () ! (save-window-excursion ! (gnus-close-backends))) (defun gnus-demon-add-scanmail () "Add daemonic scanning of mail from the mail backends." (gnus-demon-add-handler 'gnus-demon-scan-mail 120 60)) (defun gnus-demon-scan-mail () ! (save-window-excursion ! (let ((servers gnus-opened-servers) ! server) ! (while (setq server (car (pop servers))) ! (and (gnus-check-backend-function 'request-scan (car server)) ! (or (gnus-server-opened server) ! (gnus-open-server server)) ! (gnus-request-scan nil server)))))) (defun gnus-demon-add-rescan () "Add daemonic scanning of new articles from all backends." (gnus-demon-add-handler 'gnus-demon-scan-news 120 60)) (defun gnus-demon-scan-news () ! (save-window-excursion ! (when (gnus-alive-p) ! (save-excursion ! (set-buffer gnus-group-buffer) ! (gnus-group-get-new-news))))) (provide 'gnus-demon) *** pub/rgnus/lisp/gnus-ems.el Fri Oct 11 12:07:35 1996 --- rgnus/lisp/gnus-ems.el Tue Oct 29 19:39:18 1996 *************** *** 27,32 **** --- 27,34 ---- (eval-when-compile (require 'cl)) + ;;; Function aliases later to be redefined for XEmacs usage. + (defvar gnus-xemacs (string-match "XEmacs\\|Lucid" emacs-version) "Non-nil if running under XEmacs.") *************** *** 79,86 **** "{ echo '/* Width=48, Height=48 */'; uncompface; } | icontopbm | xv -quit -" "String or function to be executed to display an X-Face header. If it is a string, the command will be executed in a sub-shell ! asynchronously. The compressed face will be piped to this command.") ! ) (cond ((string-match "XEmacs\\|Lucid" emacs-version) --- 81,87 ---- "{ echo '/* Width=48, Height=48 */'; uncompface; } | icontopbm | xv -quit -" "String or function to be executed to display an X-Face header. If it is a string, the command will be executed in a sub-shell ! asynchronously. The compressed face will be piped to this command.")) (cond ((string-match "XEmacs\\|Lucid" emacs-version) *** pub/rgnus/lisp/gnus-group.el Thu Oct 17 01:47:04 1996 --- rgnus/lisp/gnus-group.el Tue Oct 29 17:19:59 1996 *************** *** 872,877 **** --- 872,878 ---- gnus-group-misc-menu gnus-group-mode-map "" '("Misc" ["Send a bug report" gnus-bug t] + ["Customize" gnus-group-customize t] ["Send a mail" gnus-group-mail t] ["Post an article..." gnus-group-post-news t] ["Check for new news" gnus-group-get-new-news t] *************** *** 1004,1009 **** --- 1005,1012 ---- (gnus-group-default-level nil t) gnus-group-default-list-level gnus-level-subscribed)))) + ;; Just do this here, for no particular good reason. + (gnus-clear-inboxes-moved) (unless level (setq level (car gnus-group-list-mode) unread (cdr gnus-group-list-mode))) *** pub/rgnus/lisp/gnus-kill.el Wed Oct 16 01:34:47 1996 --- rgnus/lisp/gnus-kill.el Tue Oct 29 17:19:59 1996 *************** *** 628,638 **** (eval form)))))) did-kill))) ! (defun gnus-execute (field regexp form &optional backward ignore-marked) "If FIELD of article header matches REGEXP, execute lisp FORM (or a string). If FIELD is an empty string (or nil), entire article body is searched for. If optional 1st argument BACKWARD is non-nil, do backward instead. ! If optional 2nd argument IGNORE-MARKED is non-nil, articles which are marked as read or ticked are ignored." (save-excursion (let ((killed-no 0) --- 628,638 ---- (eval form)))))) did-kill))) ! (defun gnus-execute (field regexp form &optional backward unread) "If FIELD of article header matches REGEXP, execute lisp FORM (or a string). If FIELD is an empty string (or nil), entire article body is searched for. If optional 1st argument BACKWARD is non-nil, do backward instead. ! If optional 2nd argument UNREAD is non-nil, articles which are marked as read or ticked are ignored." (save-excursion (let ((killed-no 0) *************** *** 658,665 **** (setq article (gnus-summary-article-number))) ;; Find later articles. (setq article ! (gnus-summary-search-forward ! ignore-marked nil backward))) (and (or (null gnus-newsgroup-kill-headers) (memq article gnus-newsgroup-kill-headers)) (vectorp (setq header (gnus-summary-article-header article))) --- 658,664 ---- (setq article (gnus-summary-article-number))) ;; Find later articles. (setq article ! (gnus-summary-search-forward unread nil backward))) (and (or (null gnus-newsgroup-kill-headers) (memq article gnus-newsgroup-kill-headers)) (vectorp (setq header (gnus-summary-article-header article))) *** pub/rgnus/lisp/gnus-msg.el Tue Oct 8 12:46:59 1996 --- rgnus/lisp/gnus-msg.el Tue Oct 29 17:20:00 1996 *************** *** 183,189 **** 'send)) (put 'gnus-setup-message 'lisp-indent-function 1) - (put 'gnus-setup-message 'lisp-indent-hook 1) (put 'gnus-setup-message 'edebug-form-spec '(form body)) ;;; Post news commands of Gnus group mode and summary mode --- 183,188 ---- *************** *** 563,576 **** (interactive "P") (gnus-summary-reply (gnus-summary-work-articles n))) ! (defun gnus-summary-mail-forward (&optional post) ! "Forward the current message to another user." (interactive "P") (gnus-set-global-variables) (gnus-setup-message 'forward (gnus-summary-select-article) (set-buffer gnus-original-article-buffer) ! (message-forward post))) (defun gnus-summary-resend-message (address) "Resend the current article to ADDRESS." --- 562,578 ---- (interactive "P") (gnus-summary-reply (gnus-summary-work-articles n))) ! (defun gnus-summary-mail-forward (&optional full-headers post) ! "Forward the current message to another user. ! If FULL-HEADERS (the prefix), include full headers when forwarding." (interactive "P") (gnus-set-global-variables) (gnus-setup-message 'forward (gnus-summary-select-article) (set-buffer gnus-original-article-buffer) ! (let ((message-included-forward-headers ! (if full-headers "" message-included-forward-headers))) ! (message-forward post)))) (defun gnus-summary-resend-message (address) "Resend the current article to ADDRESS." *************** *** 580,589 **** (set-buffer gnus-original-article-buffer) (message-resend address))) ! (defun gnus-summary-post-forward () ! "Forward the current article to a newsgroup." ! (interactive) ! (gnus-summary-mail-forward t)) (defvar gnus-nastygram-message "The following article was inappropriately posted to %s.\n\n" --- 582,592 ---- (set-buffer gnus-original-article-buffer) (message-resend address))) ! (defun gnus-summary-post-forward (&optional full-headers) ! "Forward the current article to a newsgroup. ! If FULL-HEADERS (the prefix), include full headers when forwarding." ! (interactive "P") ! (gnus-summary-mail-forward full-headers t)) (defvar gnus-nastygram-message "The following article was inappropriately posted to %s.\n\n" *** pub/rgnus/lisp/gnus-nocem.el Fri Oct 11 12:07:37 1996 --- rgnus/lisp/gnus-nocem.el Tue Oct 29 17:20:00 1996 *************** *** 185,207 **** (let ((b (search-forward "\n@@BEGIN NCM BODY\n" nil t)) (e (search-forward "\n@@END NCM BODY\n" nil t)) (buf (current-buffer)) ! ncm id) (when (and b e) (narrow-to-region b (1+ (match-beginning 0))) (goto-char (point-min)) (while (search-forward "\t" nil t) ! (when (condition-case nil ! (boundp (let ((obarray gnus-active-hashtb)) (read buf))) ! (error nil)) ! (beginning-of-line) ! (while (= (following-char) ?\t) ! (forward-line -1)) ! (setq id (buffer-substring (point) (1- (search-forward "\t")))) ! (push id ncm) ! (gnus-sethash id t gnus-nocem-hashtb) ! (forward-line 1) ! (while (= (following-char) ?\t) ! (forward-line 1)))) (when ncm (setq gnus-nocem-touched-alist t) (push (cons (let ((time (current-time))) (setcdr (cdr time) nil) time) --- 185,212 ---- (let ((b (search-forward "\n@@BEGIN NCM BODY\n" nil t)) (e (search-forward "\n@@END NCM BODY\n" nil t)) (buf (current-buffer)) ! ncm id group) (when (and b e) (narrow-to-region b (1+ (match-beginning 0))) (goto-char (point-min)) (while (search-forward "\t" nil t) ! (condition-case nil ! (setq group (let ((obarray gnus-active-hashtb)) (read buf))) ! (error nil)) ! (if (not (boundp group)) ! ;; Make sure all entries in the hashtb are bound. ! (set group nil) ! (when (gnus-gethash (symbol-name group) gnus-newsrc-hashtb) ! ;; Valid group. ! (beginning-of-line) ! (while (= (following-char) ?\t) ! (forward-line -1)) ! (setq id (buffer-substring (point) (1- (search-forward "\t")))) ! (push id ncm) ! (gnus-sethash id t gnus-nocem-hashtb) ! (forward-line 1) ! (while (= (following-char) ?\t) ! (forward-line 1))))) (when ncm (setq gnus-nocem-touched-alist t) (push (cons (let ((time (current-time))) (setcdr (cdr time) nil) time) *** pub/rgnus/lisp/gnus-score.el Fri Oct 11 12:07:38 1996 --- rgnus/lisp/gnus-score.el Tue Oct 29 19:20:17 1996 *************** *** 323,331 **** ("followup" 2 gnus-score-followup) ("thread" 5 gnus-score-thread))) - (eval-and-compile - (autoload 'gnus-uu-ctl-map "gnus-uu" nil nil 'keymap)) - ;;; Summary mode score maps. (gnus-define-keys (gnus-summary-score-map "V" gnus-summary-mode-map) --- 323,328 ---- *************** *** 469,475 **** (if (eq (nth 4 entry) (nth 3 s)) s nil)) ! char-to-type )) 2))) (gnus-score-kill-help-buffer) --- 466,472 ---- (if (eq (nth 4 entry) (nth 3 s)) s nil)) ! char-to-type)) 2))) (gnus-score-kill-help-buffer) *************** *** 499,504 **** --- 496,507 ---- (if mimic (message "%c %c %c" prefix hchar tchar pchar) (message "")) (unless (setq temporary (cadr (assq pchar char-to-perm))) + ;; Deal with der(r)ided superannuated paradigms. + (when (and (eq (1+ prefix) 77) + (eq (+ hchar 12) 109) + (eq tchar 114) + (eq (- pchar 4) 111)) + (error "You rang?")) (if mimic (error "%c %c %c %c" prefix hchar tchar pchar) (error "")))) *************** *** 524,531 **** (nth 1 entry) ; Header match ; Match type ; Type ! (if (eq 's score) nil score) ; Score ! (if (eq 'perm temporary) ; Temp nil temporary) (not (nth 3 entry))) ; Prompt --- 527,534 ---- (nth 1 entry) ; Header match ; Match type ; Type ! (if (eq score 's) nil score) ; Score ! (if (eq temporary 'perm) ; Temp nil temporary) (not (nth 3 entry))) ; Prompt *************** *** 1962,1971 **** (or gnus-newsgroup-adaptive-score-file (gnus-score-file-name gnus-newsgroup-name gnus-adaptive-file-suffix)))) ! (cond ! ;; Perform ordinary line scoring. ! ((or (not (listp gnus-use-adaptive-scoring)) ! (memq 'line gnus-use-adaptive-scoring)) (save-excursion (let* ((malist (gnus-copy-sequence gnus-adaptive-score-alist)) (alist malist) --- 1965,1973 ---- (or gnus-newsgroup-adaptive-score-file (gnus-score-file-name gnus-newsgroup-name gnus-adaptive-file-suffix)))) ! ;; Perform ordinary line scoring. ! (when (or (not (listp gnus-use-adaptive-scoring)) ! (memq 'line gnus-use-adaptive-scoring)) (save-excursion (let* ((malist (gnus-copy-sequence gnus-adaptive-score-alist)) (alist malist) *************** *** 2023,2030 **** (setq elem (cdr elem))))) (setq data (cdr data)))))) ! ;; Perform adaptive word scoring. ! ((memq 'word gnus-use-adaptive-scoring) (nnheader-temp-write nil (let* ((hashtb (gnus-make-hashtable 1000)) (date (gnus-day-number (current-time-string))) --- 2025,2033 ---- (setq elem (cdr elem))))) (setq data (cdr data)))))) ! ;; Perform adaptive word scoring. ! (when (and (listp gnus-use-adaptive-scoring) ! (memq 'word gnus-use-adaptive-scoring)) (nnheader-temp-write nil (let* ((hashtb (gnus-make-hashtable 1000)) (date (gnus-day-number (current-time-string))) *************** *** 2033,2039 **** word d score val) (unwind-protect (progn ! (set-syntax-table syntab) ;; Go through all articles. (while (setq d (pop data)) (when (and --- 2036,2042 ---- word d score val) (unwind-protect (progn ! (set-syntax-table gnus-adaptive-word-syntax-table) ;; Go through all articles. (while (setq d (pop data)) (when (and *************** *** 2069,2075 **** (gnus-summary-score-entry "subject" (symbol-name word) 'w (symbol-value word) date nil t))) ! hashtb))))))) (defun gnus-score-edit-done () (let ((bufnam (buffer-file-name (current-buffer))) --- 2072,2078 ---- (gnus-summary-score-entry "subject" (symbol-name word) 'w (symbol-value word) date nil t))) ! hashtb)))))) (defun gnus-score-edit-done () (let ((bufnam (buffer-file-name (current-buffer))) *** pub/rgnus/lisp/gnus-setup.el Thu Oct 3 02:25:10 1996 --- rgnus/lisp/gnus-setup.el Tue Oct 29 19:20:17 1996 *************** *** 158,169 **** (setq message-cite-function 'sc-cite-original) (autoload 'sc-cite-original "supercite")) ! ;;;### (autoloads (gnus-batch-score gnus-fetch-group gnus gnus-slave gnus-no-server gnus-update-format) "gnus" "lisp/gnus.el" (12473 2137)) ;;; Generated autoloads from lisp/gnus.el - (autoload 'gnus-update-format "gnus" "\ - Update the format specification near point." t nil) - (autoload 'gnus-slave-no-server "gnus" "\ Read network news as a slave without connecting to local server." t nil) --- 158,166 ---- (setq message-cite-function 'sc-cite-original) (autoload 'sc-cite-original "supercite")) ! ;;;### (autoloads (gnus gnus-slave gnus-no-server) "gnus" "lisp/gnus.el" (12473 2137)) ;;; Generated autoloads from lisp/gnus.el (autoload 'gnus-slave-no-server "gnus" "\ Read network news as a slave without connecting to local server." t nil) *************** *** 184,203 **** startup level. If ARG is non-nil and not a positive number, Gnus will prompt the user for the name of an NNTP server to use." t nil) ! (autoload 'gnus-fetch-group "gnus" "\ Start Gnus if necessary and enter GROUP. Returns whether the fetching was successful or not." t nil) (defalias 'gnus-batch-kill 'gnus-batch-score) ! (autoload 'gnus-batch-score "gnus" "\ Run batched scoring. Usage: emacs -batch -l gnus -f gnus-batch-score ... Newsgroups is a list of strings in Bnews format. If you want to score the comp hierarchy, you'd say \"comp.all\". If you would not like to score the alt hierarchy, you'd say \"!alt.all\"." t nil) - - ;;;*** (provide 'gnus-setup) --- 181,205 ---- startup level. If ARG is non-nil and not a positive number, Gnus will prompt the user for the name of an NNTP server to use." t nil) ! ;;;*** ! ! ;;; These have moved out of gnus.el into other files. ! ;;; FIX FIX FIX: should other things be in gnus-setup? or these not in it? ! (autoload 'gnus-update-format "gnus-spec" "\ ! Update the format specification near point." t nil) ! ! (autoload 'gnus-fetch-group "gnus-group" "\ Start Gnus if necessary and enter GROUP. Returns whether the fetching was successful or not." t nil) (defalias 'gnus-batch-kill 'gnus-batch-score) ! (autoload 'gnus-batch-score "gnus-kill" "\ Run batched scoring. Usage: emacs -batch -l gnus -f gnus-batch-score ... Newsgroups is a list of strings in Bnews format. If you want to score the comp hierarchy, you'd say \"comp.all\". If you would not like to score the alt hierarchy, you'd say \"!alt.all\"." t nil) (provide 'gnus-setup) *** pub/rgnus/lisp/gnus-soup.el Tue Oct 8 12:46:57 1996 --- rgnus/lisp/gnus-soup.el Tue Oct 29 17:20:01 1996 *************** *** 165,170 **** --- 165,174 ---- "Make a SOUP packet from the SOUP areas." (interactive) (gnus-soup-read-areas) + (unless (file-exists-p gnus-soup-directory) + (message "No such directory: %s" gnus-soup-directory)) + (when (null (directory-files gnus-soup-directory nil "\\.MSG$")) + (message "No files to pack.")) (gnus-soup-pack gnus-soup-directory gnus-soup-packer)) (defun gnus-group-brew-soup (n) *** pub/rgnus/lisp/gnus-sum.el Thu Oct 17 01:47:09 1996 --- rgnus/lisp/gnus-sum.el Tue Oct 29 17:20:02 1996 *************** *** 278,284 **** In particular, if `vertical' do only vertical recentering. If non-nil and non-`vertical', do both horizontal and vertical recentering." :group 'gnus-summary ! :type '(choice (const "none" nil) (const vertical) (sexp :menu-tag "both" t))) --- 278,284 ---- In particular, if `vertical' do only vertical recentering. If non-nil and non-`vertical', do both horizontal and vertical recentering." :group 'gnus-summary ! :type '(choice (const :tag "none" nil) (const vertical) (sexp :menu-tag "both" t))) *************** *** 1494,1499 **** --- 1494,1500 ---- (gnus-define-keys (gnus-summary-save-map "O" gnus-summary-mode-map) "o" gnus-summary-save-article "m" gnus-summary-save-article-mail + "F" gnus-summary-write-article-file "r" gnus-summary-save-article-rmail "f" gnus-summary-save-article-file "b" gnus-summary-save-article-body-file *************** *** 1685,1690 **** --- 1686,1692 ---- ["Save in default format" gnus-summary-save-article t] ["Save in file" gnus-summary-save-article-file t] ["Save in Unix mail format" gnus-summary-save-article-mail t] + ["Write to file" gnus-summary-write-article-mail t] ["Save in MH folder" gnus-summary-save-article-folder t] ["Save in VM folder" gnus-summary-save-article-vm t] ["Save in RMAIL mbox" gnus-summary-save-article-rmail t] *************** *** 2293,2299 **** ;; Saving hidden threads. (put 'gnus-save-hidden-threads 'lisp-indent-function 0) - (put 'gnus-save-hidden-threads 'lisp-indent-hook 0) (put 'gnus-save-hidden-threads 'edebug-form-spec '(body)) (defmacro gnus-save-hidden-threads (&rest forms) --- 2295,2300 ---- *************** *** 3269,3277 **** (defsubst gnus-article-sort-by-date (h1 h2) "Sort articles by root article date." ! (string-lessp ! (inline (gnus-sortable-date (mail-header-date h1))) ! (inline (gnus-sortable-date (mail-header-date h2))))) (defun gnus-thread-sort-by-date (h1 h2) "Sort threads by root article date." --- 3270,3278 ---- (defsubst gnus-article-sort-by-date (h1 h2) "Sort articles by root article date." ! (gnus-time-less ! (gnus-date-get-time (mail-header-date h1)) ! (gnus-date-get-time (mail-header-date h2)))) (defun gnus-thread-sort-by-date (h1 h2) "Sort threads by root article date." *************** *** 4713,4719 **** (save-excursion (while articles (gnus-summary-goto-subject (setq article (pop articles))) ! (command-execute func) (gnus-summary-remove-process-mark article))))) (gnus-summary-position-point)) --- 4714,4721 ---- (save-excursion (while articles (gnus-summary-goto-subject (setq article (pop articles))) ! (let (gnus-newsgroup-processable) ! (command-execute func)) (gnus-summary-remove-process-mark article))))) (gnus-summary-position-point)) *************** *** 7981,7986 **** --- 7983,7999 ---- (interactive "P") (gnus-set-global-variables) (let ((gnus-default-article-saver 'gnus-summary-save-in-file)) + (gnus-summary-save-article arg))) + + (defun gnus-summary-write-article-file (&optional arg) + "Write the current article to a file, deleting the previous file. + If N is a positive number, save the N next articles. + If N is a negative number, save the N previous articles. + If N is nil and any articles have been marked with the process mark, + save those articles instead." + (interactive "P") + (gnus-set-global-variables) + (let ((gnus-default-article-saver 'gnus-summary-write-to-file)) (gnus-summary-save-article arg))) (defun gnus-summary-save-article-body-file (&optional arg) *** pub/rgnus/lisp/gnus-topic.el Tue Oct 8 12:46:54 1996 --- rgnus/lisp/gnus-topic.el Tue Oct 29 21:07:23 1996 *************** *** 437,444 **** (while (and (zerop (forward-line 1)) (> (or (gnus-group-topic-level) (1+ level)) level))) (delete-region beg (point)) ! (setcar (cdadr (gnus-topic-find-topology topic)) ! (if insert 'visible 'invisible)) (when hide (setcdr (cdadr (gnus-topic-find-topology topic)) (list hide))) --- 437,444 ---- (while (and (zerop (forward-line 1)) (> (or (gnus-group-topic-level) (1+ level)) level))) (delete-region beg (point)) ! (setcdr (cadr (gnus-topic-find-topology topic)) ! (if insert (list 'visible) (list 'invisible))) (when hide (setcdr (cdadr (gnus-topic-find-topology topic)) (list hide))) *************** *** 1033,1039 **** (let ((topic (gnus-group-topic-name))) (gnus-topic-remove-topic nil t) (push (gnus-topic-find-topology topic nil nil gnus-topic-topology) ! gnus-topic-killed-topics)) (gnus-group-kill-group n discard) (gnus-topic-update-topic))) --- 1033,1040 ---- (let ((topic (gnus-group-topic-name))) (gnus-topic-remove-topic nil t) (push (gnus-topic-find-topology topic nil nil gnus-topic-topology) ! gnus-topic-killed-topics) ! (gnus-topic-enter-dribble)) (gnus-group-kill-group n discard) (gnus-topic-update-topic))) *************** *** 1048,1053 **** --- 1049,1055 ---- (gnus-topic-create-topic (caar item) (gnus-topic-parent-topic previous) previous item) + (gnus-topic-enter-dribble) (gnus-topic-goto-topic (caar item))) (let* ((prev (gnus-group-group-name)) (gnus-topic-inhibit-change-level t) *** pub/rgnus/lisp/gnus-undo.el Sun Sep 1 05:26:06 1996 --- rgnus/lisp/gnus-undo.el Tue Oct 29 17:20:03 1996 *************** *** 128,134 **** ,@form)))) (put 'gnus-undo-register 'lisp-indent-function 0) - (put 'gnus-undo-register 'lisp-indent-hook 0) (put 'gnus-undo-register 'edebug-form-spec '(body)) (defun gnus-undo-register-1 (function) --- 128,133 ---- *** pub/rgnus/lisp/gnus-util.el Wed Oct 16 01:34:48 1996 --- rgnus/lisp/gnus-util.el Tue Oct 29 17:20:03 1996 *************** *** 52,58 **** (select-window ,tempvar))))) (put 'gnus-eval-in-buffer-window 'lisp-indent-function 1) - (put 'gnus-eval-in-buffer-window 'lisp-indent-hook 1) (put 'gnus-eval-in-buffer-window 'edebug-form-spec '(form body)) (defmacro gnus-intern-safe (string hashtable) --- 52,57 ---- *************** *** 275,292 **** `(gnus-define-keys-1 (quote ,keymap) (quote ,plist) t)) (put 'gnus-define-keys 'lisp-indent-function 1) - (put 'gnus-define-keys 'lisp-indent-hook 1) (put 'gnus-define-keys-safe 'lisp-indent-function 1) - (put 'gnus-define-keys-safe 'lisp-indent-hook 1) (put 'gnus-local-set-keys 'lisp-indent-function 1) - (put 'gnus-local-set-keys 'lisp-indent-hook 1) (defmacro gnus-define-keymap (keymap &rest plist) "Define all keys in PLIST in KEYMAP." `(gnus-define-keys-1 ,keymap (quote ,plist))) (put 'gnus-define-keymap 'lisp-indent-function 1) - (put 'gnus-define-keymap 'lisp-indent-hook 1) (defun gnus-define-keys-1 (keymap plist &optional safe) (when (null keymap) --- 274,287 ---- *************** *** 349,366 **** timezone-months-assoc)) "???")))))) ! (defun 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 () ! (gnus-time-iso8601 (nnmail-date-to-time (mail-header-date header))) (error ""))) (defun gnus-mode-string-quote (string) ! "Quote all \"%\" in STRING." (save-excursion (gnus-set-work-buffer) (insert string) --- 344,373 ---- timezone-months-assoc)) "???")))))) ! (defmacro gnus-date-get-time (date) ! "Convert DATE string to Emacs time. ! Cache the result as a text property stored in DATE." ! ;; Either return the cached value... ! `(let ((d ,date)) ! (or (get-text-property 0 'gnus-time d) ! ;; or compute the value... ! (let ((time (nnmail-date-to-time d))) ! ;; and store it back in the string. ! (put-text-property 0 1 'gnus-time time d) ! time)))) ! ! (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 () ! (gnus-time-iso8601 (gnus-date-get-time (mail-header-date header))) (error ""))) (defun gnus-mode-string-quote (string) ! "Quote all \"%\"'s in STRING." (save-excursion (gnus-set-work-buffer) (insert string) *** pub/rgnus/lisp/gnus-xmas.el Fri Oct 11 12:07:39 1996 --- rgnus/lisp/gnus-xmas.el Tue Oct 29 19:37:25 1996 *************** *** 260,266 **** (defmacro gnus-xmas-menu-add (type &rest menus) `(gnus-xmas-menu-add-1 ',type ',menus)) (put 'gnus-xmas-menu-add 'lisp-indent-function 1) - (put 'gnus-xmas-menu-add 'lisp-indent-hook 1) (defun gnus-xmas-menu-add-1 (type menus) (when (and menu-bar-mode --- 260,265 ---- *************** *** 270,314 **** (defun gnus-xmas-group-menu-add () (gnus-xmas-menu-add group ! gnus-group-reading-menu gnus-group-group-menu gnus-group-misc-menu)) (defun gnus-xmas-summary-menu-add () (gnus-xmas-menu-add summary ! gnus-summary-misc-menu gnus-summary-kill-menu ! gnus-summary-article-menu gnus-summary-thread-menu ! gnus-summary-post-menu )) (defun gnus-xmas-article-menu-add () (gnus-xmas-menu-add article ! gnus-article-article-menu gnus-article-treatment-menu)) (defun gnus-xmas-score-menu-add () (gnus-xmas-menu-add score ! gnus-score-menu)) (defun gnus-xmas-pick-menu-add () (gnus-xmas-menu-add pick ! gnus-pick-menu)) (defun gnus-xmas-binary-menu-add () (gnus-xmas-menu-add binary ! gnus-binary-menu)) (defun gnus-xmas-tree-menu-add () (gnus-xmas-menu-add tree ! gnus-tree-menu)) (defun gnus-xmas-server-menu-add () (gnus-xmas-menu-add menu ! gnus-server-server-menu gnus-server-connections-menu)) (defun gnus-xmas-browse-menu-add () (gnus-xmas-menu-add browse ! gnus-browse-menu)) (defun gnus-xmas-grouplens-menu-add () (gnus-xmas-menu-add grouplens ! gnus-grouplens-menu)) (defun gnus-xmas-read-event-char () "Get the next event." --- 269,317 ---- (defun gnus-xmas-group-menu-add () (gnus-xmas-menu-add group ! gnus-group-reading-menu gnus-group-group-menu gnus-group-misc-menu)) (defun gnus-xmas-summary-menu-add () (gnus-xmas-menu-add summary ! gnus-summary-misc-menu gnus-summary-kill-menu ! gnus-summary-article-menu gnus-summary-thread-menu ! gnus-summary-post-menu )) (defun gnus-xmas-article-menu-add () (gnus-xmas-menu-add article ! gnus-article-article-menu gnus-article-treatment-menu)) (defun gnus-xmas-score-menu-add () (gnus-xmas-menu-add score ! gnus-score-menu)) (defun gnus-xmas-pick-menu-add () (gnus-xmas-menu-add pick ! gnus-pick-menu)) ! ! (defun gnus-xmas-topic-menu-add () ! (gnus-xmas-menu-add topic ! gnus-topic-menu)) (defun gnus-xmas-binary-menu-add () (gnus-xmas-menu-add binary ! gnus-binary-menu)) (defun gnus-xmas-tree-menu-add () (gnus-xmas-menu-add tree ! gnus-tree-menu)) (defun gnus-xmas-server-menu-add () (gnus-xmas-menu-add menu ! gnus-server-server-menu gnus-server-connections-menu)) (defun gnus-xmas-browse-menu-add () (gnus-xmas-menu-add browse ! gnus-browse-menu)) (defun gnus-xmas-grouplens-menu-add () (gnus-xmas-menu-add grouplens ! gnus-grouplens-menu)) (defun gnus-xmas-read-event-char () "Get the next event." *************** *** 440,445 **** --- 443,449 ---- (add-hook 'gnus-score-mode-hook 'gnus-xmas-score-menu-add) (add-hook 'gnus-pick-mode-hook 'gnus-xmas-pick-menu-add) + (add-hook 'gnus-topic-mode-hook 'gnus-xmas-topic-menu-add) (add-hook 'gnus-tree-mode-hook 'gnus-xmas-tree-menu-add) (add-hook 'gnus-binary-mode-hook 'gnus-xmas-binary-menu-add) (add-hook 'gnus-grouplens-mode-hook 'gnus-xmas-grouplens-menu-add) *** pub/rgnus/lisp/gnus.el Thu Oct 17 01:47:10 1996 --- rgnus/lisp/gnus.el Tue Oct 29 19:39:18 1996 *************** *** 42,55 **** "Score and kill file handling." :group 'gnus ) ! (defconst gnus-version-number "0.52" "Version number for this version of Gnus.") (defconst gnus-version (format "Red Gnus v%s" gnus-version-number) "Version string for this version of Gnus.") (defcustom gnus-inhibit-startup-message nil ! "*If non-nil, the startup message will not be displayed." :group 'gnus-start :type 'boolean) --- 42,57 ---- "Score and kill file handling." :group 'gnus ) ! (defconst gnus-version-number "0.53" "Version number for this version of Gnus.") (defconst gnus-version (format "Red Gnus v%s" gnus-version-number) "Version string for this version of Gnus.") (defcustom gnus-inhibit-startup-message nil ! "*If non-nil, the startup message will not be displayed. ! This variable is used before `.gnus.el' is loaded, so it should ! be set in `.emacs' instead." :group 'gnus-start :type 'boolean) *************** *** 69,74 **** --- 71,94 ---- (t 'ignore))) + (defalias 'gnus-make-overlay 'make-overlay) + (defalias 'gnus-overlay-put 'overlay-put) + (defalias 'gnus-move-overlay 'move-overlay) + (defalias 'gnus-overlay-end 'overlay-end) + (defalias 'gnus-extent-detached-p 'ignore) + (defalias 'gnus-extent-start-open 'ignore) + (defalias 'gnus-set-text-properties 'set-text-properties) + (defalias 'gnus-group-remove-excess-properties 'ignore) + (defalias 'gnus-topic-remove-excess-properties 'ignore) + (defalias 'gnus-appt-select-lowest-window 'appt-select-lowest-window) + (defalias 'gnus-mail-strip-quoted-names 'mail-strip-quoted-names) + (defalias 'gnus-make-local-hook 'make-local-hook) + (defalias 'gnus-add-hook 'add-hook) + (defalias 'gnus-character-to-event 'identity) + (defalias 'gnus-add-text-properties 'add-text-properties) + (defalias 'gnus-put-text-property 'put-text-property) + (defalias 'gnus-mode-line-buffer-identification 'identity) + ;; The XEmacs people think this is evil, so it must go. (defun custom-face-lookup (&optional fg bg stipple bold italic underline) "Lookup or create a face with specified attributes." *************** *** 810,815 **** --- 830,837 ---- ("hexl" hexl-hex-string-to-integer) ("pp" pp pp-to-string pp-eval-expression) ("mail-extr" mail-extract-address-components) + ("message" :interactive t + message-send-and-exit message-yank-original) ("nnmail" nnmail-split-fancy nnmail-article-group nnmail-date-to-time) ("nnvirtual" nnvirtual-catchup-group nnvirtual-convert-headers) ("timezone" timezone-make-date-arpa-standard timezone-fix-time *************** *** 823,829 **** gnus-soup-send-replies gnus-soup-save-areas gnus-soup-pack-packet) ("nnsoup" nnsoup-pack-replies) ("score-mode" :interactive t gnus-score-mode) ! ("gnus-mh" gnus-mh-mail-setup gnus-summary-save-article-folder gnus-Folder-save-name gnus-folder-save-name) ("gnus-mh" :interactive t gnus-summary-save-in-folder) ("gnus-demon" gnus-demon-add-nocem gnus-demon-add-scanmail --- 845,851 ---- gnus-soup-send-replies gnus-soup-save-areas gnus-soup-pack-packet) ("nnsoup" nnsoup-pack-replies) ("score-mode" :interactive t gnus-score-mode) ! ("gnus-mh" gnus-summary-save-article-folder gnus-Folder-save-name gnus-folder-save-name) ("gnus-mh" :interactive t gnus-summary-save-in-folder) ("gnus-demon" gnus-demon-add-nocem gnus-demon-add-scanmail *************** *** 849,868 **** gnus-cache-retrieve-headers gnus-cache-possibly-alter-active gnus-cache-enter-remove-article gnus-cached-article-p gnus-cache-open gnus-cache-close gnus-cache-update-article) ! ("gnus-cache" :interactive t gnus-jog-cache gnus-cache-enter-article ! gnus-cache-remove-article gnus-summary-insert-cached-articles) ! ("gnus-score" :interactive t ! gnus-summary-increase-score gnus-summary-lower-score ! gnus-score-flush-cache gnus-score-close ! gnus-score-raise-same-subject-and-select ! gnus-score-raise-same-subject gnus-score-default ! gnus-score-raise-thread gnus-score-lower-same-subject-and-select ! gnus-score-lower-same-subject gnus-score-lower-thread ! gnus-possibly-score-headers gnus-summary-raise-score ! gnus-summary-set-score gnus-summary-current-score ! gnus-score-followup-article) ! ("gnus-score" ! (gnus-summary-score-map keymap) gnus-score-save gnus-score-headers gnus-current-score-file-nondirectory gnus-score-adaptive gnus-score-find-trace gnus-score-file-name) ("gnus-cus" :interactive t gnus-group-customize gnus-score-customize) --- 871,890 ---- gnus-cache-retrieve-headers gnus-cache-possibly-alter-active gnus-cache-enter-remove-article gnus-cached-article-p gnus-cache-open gnus-cache-close gnus-cache-update-article) ! ("gnus-cache" :interactive t gnus-jog-cache gnus-cache-enter-article ! gnus-cache-remove-article gnus-summary-insert-cached-articles) ! ("gnus-score" :interactive t ! gnus-summary-increase-score gnus-summary-set-score ! gnus-summary-raise-thread gnus-summary-raise-same-subject ! gnus-summary-raise-score gnus-summary-raise-same-subject-and-select ! gnus-summary-lower-thread gnus-summary-lower-same-subject ! gnus-summary-lower-score gnus-summary-lower-same-subject-and-select ! gnus-summary-current-score gnus-score-default ! gnus-score-flush-cache gnus-score-close ! gnus-possibly-score-headers gnus-score-followup-article ! gnus-score-followup-thread) ! ("gnus-score" ! (gnus-summary-score-map keymap) gnus-score-save gnus-score-headers gnus-current-score-file-nondirectory gnus-score-adaptive gnus-score-find-trace gnus-score-file-name) ("gnus-cus" :interactive t gnus-group-customize gnus-score-customize) *************** *** 882,898 **** gnus-uu-decode-unshar-and-save-view gnus-uu-decode-save-view gnus-uu-decode-binhex-view) ("gnus-msg" (gnus-summary-send-map keymap) ! gnus-mail-yank-original gnus-mail-send-and-exit ! gnus-article-mail gnus-new-mail gnus-mail-reply ! gnus-copy-article-buffer gnus-extended-version) ("gnus-msg" :interactive t gnus-group-post-news gnus-group-mail gnus-summary-post-news gnus-summary-followup gnus-summary-followup-with-original gnus-summary-cancel-article gnus-summary-supersede-article ! gnus-post-news gnus-inews-news ! gnus-summary-reply gnus-summary-reply-with-original gnus-summary-mail-forward gnus-summary-mail-other-window ! gnus-summary-resend-message gnus-summary-bounced-mail gnus-bug) ("gnus-picon" :interactive t gnus-article-display-picons gnus-group-display-picons gnus-picons-article-display-x-face --- 904,917 ---- gnus-uu-decode-unshar-and-save-view gnus-uu-decode-save-view gnus-uu-decode-binhex-view) ("gnus-msg" (gnus-summary-send-map keymap) ! gnus-article-mail gnus-copy-article-buffer gnus-extended-version) ("gnus-msg" :interactive t gnus-group-post-news gnus-group-mail gnus-summary-post-news gnus-summary-followup gnus-summary-followup-with-original gnus-summary-cancel-article gnus-summary-supersede-article ! gnus-post-news gnus-summary-reply gnus-summary-reply-with-original gnus-summary-mail-forward gnus-summary-mail-other-window ! gnus-summary-resend-message gnus-summary-resend-bounced-mail gnus-bug) ("gnus-picon" :interactive t gnus-article-display-picons gnus-group-display-picons gnus-picons-article-display-x-face *************** *** 900,906 **** ("gnus-gl" bbb-login bbb-logout bbb-grouplens-group-p gnus-grouplens-mode) ("smiley" :interactive t gnus-smiley-display) - ("gnus" gnus-add-current-to-buffer-list gnus-add-shutdown) ("gnus-win" gnus-configure-windows) ("gnus-sum" gnus-summary-insert-line gnus-summary-read-group gnus-list-of-unread-articles gnus-list-of-read-articles --- 919,924 ---- *************** *** 915,923 **** gnus-backlog-remove-article) ("gnus-art" gnus-article-read-summary-keys gnus-article-save gnus-article-prepare gnus-article-set-window-start ! gnus-article-show-all-headers gnus-article-next-page ! gnus-article-prev-page gnus-request-article-this-buffer ! gnus-article-mode gnus-article-setup-buffer gnus-narrow-to-page) ("gnus-art" :interactive t gnus-article-hide-headers gnus-article-hide-boring-headers gnus-article-treat-overstrike gnus-article-word-wrap --- 933,941 ---- gnus-backlog-remove-article) ("gnus-art" gnus-article-read-summary-keys gnus-article-save gnus-article-prepare gnus-article-set-window-start ! gnus-article-next-page gnus-article-prev-page ! gnus-request-article-this-buffer gnus-article-mode ! gnus-article-setup-buffer gnus-narrow-to-page) ("gnus-art" :interactive t gnus-article-hide-headers gnus-article-hide-boring-headers gnus-article-treat-overstrike gnus-article-word-wrap *************** *** 933,947 **** ("gnus-int" gnus-request-type) ("gnus-start" gnus-newsrc-parse-options gnus-1 gnus-no-server-1 gnus-dribble-enter) ! ("gnus-dup" gnus-dup-suppress-articles gnus-dup-enter-articles) ("gnus-range" gnus-copy-sequence) - ("gnus-vm" gnus-vm-mail-setup) ("gnus-eform" gnus-edit-form) ("gnus-move" :interactive t gnus-group-move-group-to-server gnus-change-server) ("gnus-logic" gnus-score-advanced) ! ("gnus-undo" gnus-undo-mode gnus-undo-register ! gnus-dup-unsuppress-article) ("gnus-async" gnus-async-request-fetched-article gnus-async-prefetch-next gnus-async-prefetch-article gnus-async-prefetch-remove-group) ("article" article-decode-rfc1522) --- 951,964 ---- ("gnus-int" gnus-request-type) ("gnus-start" gnus-newsrc-parse-options gnus-1 gnus-no-server-1 gnus-dribble-enter) ! ("gnus-dup" gnus-dup-suppress-articles gnus-dup-unsuppress-article ! gnus-dup-enter-articles) ("gnus-range" gnus-copy-sequence) ("gnus-eform" gnus-edit-form) ("gnus-move" :interactive t gnus-group-move-group-to-server gnus-change-server) ("gnus-logic" gnus-score-advanced) ! ("gnus-undo" gnus-undo-mode gnus-undo-register) ("gnus-async" gnus-async-request-fetched-article gnus-async-prefetch-next gnus-async-prefetch-article gnus-async-prefetch-remove-group) ("article" article-decode-rfc1522) *************** *** 1026,1051 **** (defvar gnus-group-mode-map (make-keymap)) (gnus-suppress-keymap gnus-group-mode-map) - ;;; Function aliases later to be redefined for XEmacs usage. - - (defalias 'gnus-make-overlay 'make-overlay) - (defalias 'gnus-overlay-put 'overlay-put) - (defalias 'gnus-move-overlay 'move-overlay) - (defalias 'gnus-overlay-end 'overlay-end) - (defalias 'gnus-extent-detached-p 'ignore) - (defalias 'gnus-extent-start-open 'ignore) - (defalias 'gnus-set-text-properties 'set-text-properties) - (defalias 'gnus-group-remove-excess-properties 'ignore) - (defalias 'gnus-topic-remove-excess-properties 'ignore) - (defalias 'gnus-appt-select-lowest-window 'appt-select-lowest-window) - (defalias 'gnus-mail-strip-quoted-names 'mail-strip-quoted-names) - (defalias 'gnus-make-local-hook 'make-local-hook) - (defalias 'gnus-add-hook 'add-hook) - (defalias 'gnus-character-to-event 'identity) - (defalias 'gnus-add-text-properties 'add-text-properties) - (defalias 'gnus-put-text-property 'put-text-property) - (defalias 'gnus-mode-line-buffer-identification 'identity) - ;; Fix by Hallvard B Furuseth . --- 1043,1048 ---- *************** *** 1066,1072 **** (defmacro gnus-sethash (string value hashtable) "Set hash value. Arguments are STRING, VALUE, and HASHTABLE." `(set (intern ,string ,hashtable) ,value)) ! (put 'nnheader-temp-write 'edebug-form-spec '(form form form)) (defmacro gnus-group-unread (group) "Get the currently computed number of unread articles in GROUP." --- 1063,1069 ---- (defmacro gnus-sethash (string value hashtable) "Set hash value. Arguments are STRING, VALUE, and HASHTABLE." `(set (intern ,string ,hashtable) ,value)) ! (put 'gnus-sethash 'edebug-form-spec '(form form form)) (defmacro gnus-group-unread (group) "Get the currently computed number of unread articles in GROUP." *************** *** 1583,1590 **** ((< colon dot) colon) ((< dot colon) dot))) ":") ! group (substring group (+ 1 colon)) ! ))) (t (let* ((colon (string-match ":" group))) (setq foreign (concat (substring group 0 (+ 1 colon))) --- 1580,1586 ---- ((< colon dot) colon) ((< dot colon) dot))) ":") ! group (substring group (+ 1 colon))))) (t (let* ((colon (string-match ":" group))) (setq foreign (concat (substring group 0 (+ 1 colon))) *************** *** 1599,1605 **** (setq name (concat foreign name group) group nil))) name)) - ;;; --- 1595,1600 ---- *** pub/rgnus/lisp/message.el Thu Oct 17 01:47:13 1996 --- rgnus/lisp/message.el Tue Oct 29 19:50:11 1996 *************** *** 301,307 **** Used by `message-yank-original' via `message-yank-cite'.") ;;;###autoload ! (defvar message-cite-function 'message-cite-original "*Function for citing an original message.") ;;;###autoload --- 301,311 ---- Used by `message-yank-original' via `message-yank-cite'.") ;;;###autoload ! (defvar message-cite-function ! (if (and (boundp 'mail-citation-hook) ! mail-citation-hook) ! mail-citation-hook ! 'message-cite-original) "*Function for citing an original message.") ;;;###autoload *************** *** 429,434 **** --- 433,444 ---- (defvar message-send-hook nil "Hook run before sending messages.") + (defvar message-send-mail-hook nil + "Hook run before sending mail messages.") + + (defvar message-send-news-hook nil + "Hook run before sending news messages.") + (defvar message-sent-hook nil "Hook run after sending messages.") *************** *** 545,578 **** (defun message-tokenize-header (header &optional separator) "Split HEADER into a list of header elements. \",\" is used as the separator." ! (let ((regexp (format "[%s]+" (or separator ","))) ! (beg 1) ! (first t) ! quoted elems paren) ! (save-excursion ! (message-set-work-buffer) ! (insert header) ! (goto-char (point-min)) ! (while (not (eobp)) ! (if first ! (setq first nil) ! (forward-char 1)) ! (cond ((and (> (point) beg) ! (or (eobp) ! (and (looking-at regexp) ! (not quoted) ! (not paren)))) ! (push (buffer-substring beg (point)) elems) ! (setq beg (match-end 0))) ! ((= (following-char) ?\") ! (setq quoted (not quoted))) ! ((and (= (following-char) ?\() ! (not quoted)) ! (setq paren t)) ! ((and (= (following-char) ?\)) ! (not quoted)) ! (setq paren nil)))) ! (nreverse elems)))) (defun message-fetch-field (header) "The same as `mail-fetch-field', only remove all newlines." --- 555,590 ---- (defun message-tokenize-header (header &optional separator) "Split HEADER into a list of header elements. \",\" is used as the separator." ! (if (not header) ! nil ! (let ((regexp (format "[%s]+" (or separator ","))) ! (beg 1) ! (first t) ! quoted elems paren) ! (save-excursion ! (message-set-work-buffer) ! (insert header) ! (goto-char (point-min)) ! (while (not (eobp)) ! (if first ! (setq first nil) ! (forward-char 1)) ! (cond ((and (> (point) beg) ! (or (eobp) ! (and (looking-at regexp) ! (not quoted) ! (not paren)))) ! (push (buffer-substring beg (point)) elems) ! (setq beg (match-end 0))) ! ((= (following-char) ?\") ! (setq quoted (not quoted))) ! ((and (= (following-char) ?\() ! (not quoted)) ! (setq paren t)) ! ((and (= (following-char) ?\)) ! (not quoted)) ! (setq paren nil)))) ! (nreverse elems))))) (defun message-fetch-field (header) "The same as `mail-fetch-field', only remove all newlines." *************** *** 981,1000 **** "Insert a signature. See documentation for the `message-signature' variable." (interactive (list 0)) (let* ((signature ! (cond ((and (null message-signature) ! (eq force 0)) ! (save-excursion ! (goto-char (point-max)) ! (not (re-search-backward ! message-signature-separator nil t)))) ! ((and (null message-signature) ! force) ! t) ! ((message-functionp message-signature) ! (funcall message-signature)) ! ((listp message-signature) ! (eval message-signature)) ! (t message-signature))) (signature (cond ((stringp signature) signature) --- 993,1013 ---- "Insert a signature. See documentation for the `message-signature' variable." (interactive (list 0)) (let* ((signature ! (cond ! ((and (null message-signature) ! (eq force 0)) ! (save-excursion ! (goto-char (point-max)) ! (not (re-search-backward ! message-signature-separator nil t)))) ! ((and (null message-signature) ! force) ! t) ! ((message-functionp message-signature) ! (funcall message-signature)) ! ((listp message-signature) ! (eval message-signature)) ! (t message-signature))) (signature (cond ((stringp signature) signature) *************** *** 1356,1362 **** (defun message-send-mail (&optional arg) (require 'mail-utils) ! (let ((tembuf (generate-new-buffer " message temp")) (case-fold-search nil) (news (message-news-p)) (mailbuf (current-buffer))) --- 1369,1375 ---- (defun message-send-mail (&optional arg) (require 'mail-utils) ! (let ((tembuf (message-generate-new-buffer-clone-locals " message temp")) (case-fold-search nil) (news (message-news-p)) (mailbuf (current-buffer))) *************** *** 1412,1417 **** --- 1425,1431 ---- (replace-match "\n") (backward-char 1) (setq delimline (point-marker)) + (run-hooks 'message-send-mail-hook) ;; Insert an extra newline if we need it to work around ;; Sun's bug that swallows newlines. (goto-char (1+ delimline)) *************** *** 1463,1468 **** --- 1477,1483 ---- (re-search-forward (concat "^" (regexp-quote mail-header-separator) "\n")) (replace-match "\n") + (run-hooks 'message-send-mail-hook) ;; send the message (case (apply *************** *** 1494,1500 **** ;; should never happen (t (error "qmail-inject reported unknown failure.")))) - (defun message-send-mail-with-mh () "Send the prepared message buffer with mh." (let ((mh-previous-window-config nil) --- 1509,1514 ---- *************** *** 1511,1521 **** (concat "^" (symbol-name (car headers)) ": *") nil t) (message-delete-line)) (pop headers))) ;; Pass it on to mh. (mh-send-letter))) (defun message-send-news (&optional arg) ! (let ((tembuf (generate-new-buffer " *message temp*")) (case-fold-search nil) (method (if (message-functionp message-post-method) (funcall message-post-method arg) --- 1525,1536 ---- (concat "^" (symbol-name (car headers)) ": *") nil t) (message-delete-line)) (pop headers))) + (run-hooks 'message-send-mail-hook) ;; Pass it on to mh. (mh-send-letter))) (defun message-send-news (&optional arg) ! (let ((tembuf (message-generate-new-buffer-clone-locals " *message temp*")) (case-fold-search nil) (method (if (message-functionp message-post-method) (funcall message-post-method arg) *************** *** 1536,1542 **** (message-cleanup-headers) (if (not (message-check-news-syntax)) (progn ! (message "Posting nor performed") nil) (unwind-protect (save-excursion --- 1551,1557 ---- (message-cleanup-headers) (if (not (message-check-news-syntax)) (progn ! ;;(message "Posting not performed") nil) (unwind-protect (save-excursion *************** *** 1564,1569 **** --- 1579,1585 ---- (concat "^" (regexp-quote mail-header-separator) "\n")) (replace-match "\n") (backward-char 1)) + (run-hooks 'message-send-news-hook) (require (car method)) (funcall (intern (format "%s-open-server" (car method))) (cadr method) (cddr method)) *************** *** 1581,1837 **** ;;; Header generation & syntax checking. ;;; (defun message-check-news-syntax () "Check the syntax of the message." (and ! ;; We narrow to the headers and check them first. ! (save-excursion ! (save-restriction ! (message-narrow-to-headers) ! (and ! ;; Check for commands in Subject. ! (or ! (message-check-element 'subject-cmsg) ! (save-excursion ! (if (string-match "^cmsg " (message-fetch-field "subject")) ! (y-or-n-p ! "The control code \"cmsg \" is in the subject. Really post? ") ! t))) ! ;; Check for multiple identical headers. ! (or (message-check-element 'multiple-headers) ! (save-excursion ! (let (found) ! (while (and (not found) ! (re-search-forward "^[^ \t:]+: " nil t)) ! (save-excursion ! (or (re-search-forward ! (concat "^" (setq found ! (buffer-substring ! (match-beginning 0) ! (- (match-end 0) 2)))) ! nil t) ! (setq found nil)))) ! (if found ! (y-or-n-p ! (format "Multiple %s headers. Really post? " found)) ! t)))) ! ;; Check for Version and Sendsys. ! (or (message-check-element 'sendsys) ! (save-excursion ! (if (re-search-forward "^Sendsys:\\|^Version:" nil t) ! (y-or-n-p ! (format "The article contains a %s command. Really post? " ! (buffer-substring (match-beginning 0) ! (1- (match-end 0))))) ! t))) ! ;; See whether we can shorten Followup-To. ! (or (message-check-element 'shorten-followup-to) ! (let ((newsgroups (message-fetch-field "newsgroups")) ! (followup-to (message-fetch-field "followup-to")) ! to) ! (when (and newsgroups (string-match "," newsgroups) ! (not followup-to) ! (not ! (zerop ! (length ! (setq to (completing-read ! "Followups to: (default all groups) " ! (mapcar (lambda (g) (list g)) ! (cons "poster" ! (message-tokenize-header ! newsgroups))))))))) ! (goto-char (point-min)) ! (insert "Followup-To: " to "\n")) ! t)) ! ;; Check "Shoot me". ! (or (message-check-element 'shoot) ! (save-excursion ! (if (re-search-forward ! "Message-ID.*.i-have-a-misconfigured-system-so-shoot-me" ! nil t) ! (y-or-n-p ! "You appear to have a misconfigured system. Really post? ") ! t))) ! ;; Check for Approved. ! (or (message-check-element 'approved) ! (save-excursion ! (if (re-search-forward "^Approved:" nil t) ! (y-or-n-p ! "The article contains an Approved header. Really post? ") ! t))) ! ;; Check the Message-ID header. ! (or (message-check-element 'message-id) ! (save-excursion ! (let* ((case-fold-search t) ! (message-id (message-fetch-field "message-id"))) ! (or (not message-id) ! (and (string-match "@" message-id) ! (string-match "@[^\\.]*\\." message-id)) ! (y-or-n-p ! (format ! "The Message-ID looks strange: \"%s\". Really post? " ! message-id)))))) ! ;; Check the Subject header. ! (or ! (message-check-element 'subject) ! (save-excursion ! (let* ((case-fold-search t) ! (subject (message-fetch-field "subject"))) ! (or ! (and subject ! (not (string-match "\\`[ \t]*\\'" subject))) ! (progn ! (message ! "The subject field is empty or missing. Posting is denied.") ! nil))))) ! ;; Check the Newsgroups & Followup-To headers. ! (or ! (message-check-element 'existing-newsgroups) ! (let* ((case-fold-search t) ! (newsgroups (message-fetch-field "newsgroups")) ! (followup-to (message-fetch-field "followup-to")) ! (groups (message-tokenize-header ! (if followup-to ! (concat newsgroups "," followup-to) ! newsgroups))) ! (hashtb (and (boundp 'gnus-active-hashtb) ! gnus-active-hashtb)) ! errors) ! (if (not hashtb) ! t ! (while groups ! (when (and (not (boundp (intern (car groups) hashtb))) ! (not (equal (car groups) "poster"))) ! (push (car groups) errors)) ! (pop groups)) ! (if (not errors) ! t ! (y-or-n-p ! (format ! "Really post to %s unknown group%s: %s " ! (if (= (length errors) 1) "this" "these") ! (if (= (length errors) 1) "" "s") ! (mapconcat 'identity errors ", "))))))) ! ;; Check the Newsgroups & Followup-To headers for syntax errors. ! (or ! (message-check-element 'valid-newsgroups) ! (let ((case-fold-search t) ! (headers '("Newsgroups" "Followup-To")) ! header error) ! (while (and headers (not error)) ! (when (setq header (mail-fetch-field (car headers))) ! (if (or ! (not ! (string-match ! "\\`\\([-+_&.a-zA-Z0-9]+\\)?\\(,[-+_&.a-zA-Z0-9]+\\)*\\'" ! header)) ! (memq ! nil (mapcar ! (lambda (g) ! (not (string-match "\\.\\'\\|\\.\\." g))) ! (message-tokenize-header header ",")))) ! (setq error t))) ! (unless error ! (pop headers))) ! (if (not error) ! t ! (y-or-n-p ! (format "The %s header looks odd: \"%s\". Really post? " ! (car headers) header))))) ! ;; Check the From header. ! (or (save-excursion ! (let* ((case-fold-search t) ! (from (message-fetch-field "from"))) ! (cond ! ((not from) ! (message "There is no From line. Posting is denied.") ! nil) ! ((not (string-match "@[^\\.]*\\." from)) ! (message ! "Denied posting -- the From looks strange: \"%s\"." from) ! nil) ! ((string-match "@[^@]*@" from) ! (message ! "Denied posting -- two \"@\"'s in the From header: %s." from) ! nil) ! ((string-match "(.*).*(.*)" from) ! (message ! "Denied posting -- the From header looks strange: \"%s\"." ! from) ! nil) ! (t t)))))))) ! ;; Check for long lines. ! (or (message-check-element 'long-lines) ! (save-excursion (goto-char (point-min)) ! (re-search-forward ! (concat "^" (regexp-quote mail-header-separator) "$")) ! (while (and ! (progn ! (end-of-line) ! (< (current-column) 80)) ! (zerop (forward-line 1)))) ! (or (bolp) ! (eobp) ! (y-or-n-p ! "You have lines longer than 79 characters. Really post? ")))) ;; Check whether the article is empty. ! (or (message-check-element 'empty) ! (save-excursion ! (goto-char (point-min)) ! (re-search-forward ! (concat "^" (regexp-quote mail-header-separator) "$")) ! (forward-line 1) ! (let ((b (point))) ! (goto-char (point-max)) ! (re-search-backward message-signature-separator nil t) ! (beginning-of-line) ! (or (re-search-backward "[^ \n\t]" b t) ! (y-or-n-p "Empty article. Really post? "))))) ;; Check for control characters. ! (or (message-check-element 'control-chars) ! (save-excursion ! (if (re-search-forward "[\000-\007\013\015-\037\200-\237]" nil t) ! (y-or-n-p ! "The article contains control characters. Really post? ") ! t))) ;; Check excessive size. ! (or (message-check-element 'size) ! (if (> (buffer-size) 60000) ! (y-or-n-p ! (format "The article is %d octets long. Really post? " ! (buffer-size))) ! t)) ;; Check whether any new text has been added. ! (or (message-check-element 'new-text) ! (not message-checksum) ! (not (and (eq (message-checksum) (car message-checksum)) ! (eq (buffer-size) (cdr message-checksum)))) ! (y-or-n-p ! "It looks like no new text has been added. Really post? ")) ;; Check the length of the signature. ! (or ! (message-check-element 'signature) ! (progn ! (goto-char (point-max)) ! (if (or (not (re-search-backward message-signature-separator nil t)) ! (search-forward message-forward-end-separator nil t)) ! t ! (if (> (count-lines (point) (point-max)) 5) ! (y-or-n-p ! (format ! "Your .sig is %d lines; it should be max 4. Really post? " ! (1- (count-lines (point) (point-max))))) ! t)))))) ! ! (defun message-check-element (type) ! "Returns non-nil if this type is not to be checked." ! (if (eq message-syntax-checks 'dont-check-for-anything-just-trust-me) ! t ! (let ((able (assq type message-syntax-checks))) ! (and (consp able) ! (eq (cdr able) 'disabled))))) (defun message-checksum () "Return a \"checksum\" for the current buffer." --- 1597,1848 ---- ;;; Header generation & syntax checking. ;;; + (defmacro message-check (type &rest forms) + "Eval FORMS if TYPE is to be checked." + `(or (message-check-element ,type) + (save-excursion + ,@forms))) + + (put 'message-check 'lisp-indent-function 1) + (put 'message-check 'edebug-form-spec '(form body)) + + (defun message-check-element (type) + "Returns non-nil if this type is not to be checked." + (if (eq message-syntax-checks 'dont-check-for-anything-just-trust-me) + t + (let ((able (assq type message-syntax-checks))) + (and (consp able) + (eq (cdr able) 'disabled))))) + (defun message-check-news-syntax () "Check the syntax of the message." + (save-excursion + (save-restriction + (widen) + (and + ;; We narrow to the headers and check them first. + (save-excursion + (save-restriction + (message-narrow-to-headers) + (message-check-news-header-syntax))) + ;; Check the body. + (message-check-news-body-syntax))))) + + (defun message-check-news-header-syntax () (and ! ;; Check for commands in Subject. ! (message-check 'subject-cmsg ! (if (string-match "^cmsg " (message-fetch-field "subject")) ! (y-or-n-p ! "The control code \"cmsg\" is in the subject. Really post? ") ! t)) ! ;; Check for multiple identical headers. ! (message-check 'multiple-headers ! (let (found) ! (while (and (not found) ! (re-search-forward "^[^ \t:]+: " nil t)) (save-excursion ! (or (re-search-forward ! (concat "^" (setq found ! (buffer-substring ! (match-beginning 0) (- (match-end 0) 2)))) ! nil t) ! (setq found nil)))) ! (if found ! (y-or-n-p (format "Multiple %s headers. Really post? " found)) ! t))) ! ;; Check for Version and Sendsys. ! (message-check 'sendsys ! (if (re-search-forward "^Sendsys:\\|^Version:" nil t) ! (y-or-n-p ! (format "The article contains a %s command. Really post? " ! (buffer-substring (match-beginning 0) ! (1- (match-end 0))))) ! t)) ! ;; See whether we can shorten Followup-To. ! (message-check 'shorten-followup-to ! (let ((newsgroups (message-fetch-field "newsgroups")) ! (followup-to (message-fetch-field "followup-to")) ! to) ! (when (and newsgroups ! (string-match "," newsgroups) ! (not followup-to) ! (not ! (zerop ! (length ! (setq to (completing-read ! "Followups to: (default all groups) " ! (mapcar (lambda (g) (list g)) ! (cons "poster" ! (message-tokenize-header ! newsgroups))))))))) (goto-char (point-min)) ! (insert "Followup-To: " to "\n")) ! t)) ! ;; Check "Shoot me". ! (message-check 'shoot ! (if (re-search-forward ! "Message-ID.*.i-have-a-misconfigured-system-so-shoot-me" nil t) ! (y-or-n-p "You appear to have a misconfigured system. Really post? ") ! t)) ! ;; Check for Approved. ! (message-check 'approved ! (if (re-search-forward "^Approved:" nil t) ! (y-or-n-p "The article contains an Approved header. Really post? ") ! t)) ! ;; Check the Message-ID header. ! (message-check 'message-id ! (let* ((case-fold-search t) ! (message-id (message-fetch-field "message-id"))) ! (or (not message-id) ! (and (string-match "@" message-id) ! (string-match "@[^\\.]*\\." message-id)) ! (y-or-n-p ! (format "The Message-ID looks strange: \"%s\". Really post? " ! message-id))))) ! ;; Check the Subject header. ! (message-check 'subject ! (let* ((case-fold-search t) ! (subject (message-fetch-field "subject"))) ! (or ! (and subject ! (not (string-match "\\`[ \t]*\\'" subject))) ! (ignore ! (message ! "The subject field is empty or missing. Posting is denied."))))) ! ;; Check the Newsgroups & Followup-To headers. ! (message-check 'existing-newsgroups ! (let* ((case-fold-search t) ! (newsgroups (message-fetch-field "newsgroups")) ! (followup-to (message-fetch-field "followup-to")) ! (groups (message-tokenize-header ! (if followup-to ! (concat newsgroups "," followup-to) ! newsgroups))) ! (hashtb (and (boundp 'gnus-active-hashtb) ! gnus-active-hashtb)) ! errors) ! (if (not hashtb) ! t ! (while groups ! (when (and (not (boundp (intern (car groups) hashtb))) ! (not (equal (car groups) "poster"))) ! (push (car groups) errors)) ! (pop groups)) ! (if (not errors) ! t ! (y-or-n-p ! (format ! "Really post to %s unknown group%s: %s " ! (if (= (length errors) 1) "this" "these") ! (if (= (length errors) 1) "" "s") ! (mapconcat 'identity errors ", "))))))) ! ;; Check the Newsgroups & Followup-To headers for syntax errors. ! (message-check 'valid-newsgroups ! (let ((case-fold-search t) ! (headers '("Newsgroups" "Followup-To")) ! header error) ! (while (and headers (not error)) ! (when (setq header (mail-fetch-field (car headers))) ! (if (or ! (not ! (string-match ! "\\`\\([-+_&.a-zA-Z0-9]+\\)?\\(,[-+_&.a-zA-Z0-9]+\\)*\\'" ! header)) ! (memq ! nil (mapcar ! (lambda (g) ! (not (string-match "\\.\\'\\|\\.\\." g))) ! (message-tokenize-header header ",")))) ! (setq error t))) ! (unless error ! (pop headers))) ! (if (not error) ! t ! (y-or-n-p ! (format "The %s header looks odd: \"%s\". Really post? " ! (car headers) header))))) ! ;; Check the From header. ! (message-check 'from ! (let* ((case-fold-search t) ! (from (message-fetch-field "from")) ! (ad (nth 1 (mail-extract-address-components from)))) ! (cond ! ((not from) ! (message "There is no From line. Posting is denied.") ! nil) ! ((or (not (string-match "@[^\\.]*\\." ad)) ;larsi@ifi ! (string-match "\\.\\." ad) ;larsi@ifi..uio ! (string-match "@\\." ad) ;larsi@.ifi.uio ! (string-match "\\.$" ad) ;larsi@ifi.uio. ! (not (string-match "^[^@]+@[^@]+$" ad)) ;larsi.ifi.uio ! (string-match "(.*).*(.*)" from)) ;(lars) (lars) ! (message ! "Denied posting -- the From looks strange: \"%s\"." from) ! nil) ! (t t)))))) ! ! (defun message-check-news-body-syntax () ! (and ! ;; Check for long lines. ! (message-check 'long-lines ! (goto-char (point-min)) ! (re-search-forward ! (concat "^" (regexp-quote mail-header-separator) "$")) ! (while (and ! (progn ! (end-of-line) ! (< (current-column) 80)) ! (zerop (forward-line 1)))) ! (or (bolp) ! (eobp) ! (y-or-n-p ! "You have lines longer than 79 characters. Really post? "))) ;; Check whether the article is empty. ! (message-check 'empty ! (goto-char (point-min)) ! (re-search-forward ! (concat "^" (regexp-quote mail-header-separator) "$")) ! (forward-line 1) ! (let ((b (point))) ! (goto-char (point-max)) ! (re-search-backward message-signature-separator nil t) ! (beginning-of-line) ! (or (re-search-backward "[^ \n\t]" b t) ! (y-or-n-p "Empty article. Really post? ")))) ;; Check for control characters. ! (message-check 'control-chars ! (if (re-search-forward "[\000-\007\013\015-\037\200-\237]" nil t) ! (y-or-n-p ! "The article contains control characters. Really post? ") ! t)) ;; Check excessive size. ! (message-check 'size ! (if (> (buffer-size) 60000) ! (y-or-n-p ! (format "The article is %d octets long. Really post? " ! (buffer-size))) ! t)) ;; Check whether any new text has been added. ! (message-check 'new-text ! (or ! (not message-checksum) ! (not (and (eq (message-checksum) (car message-checksum)) ! (eq (buffer-size) (cdr message-checksum)))) ! (y-or-n-p ! "It looks like no new text has been added. Really post? "))) ;; Check the length of the signature. ! (message-check 'signature ! (goto-char (point-max)) ! (if (or (not (re-search-backward message-signature-separator nil t)) ! (search-forward message-forward-end-separator nil t)) ! t ! (if (> (count-lines (point) (point-max)) 5) ! (y-or-n-p ! (format ! "Your .sig is %d lines; it should be max 4. Really post? " ! (1- (count-lines (point) (point-max))))) ! t))))) (defun message-checksum () "Return a \"checksum\" for the current buffer." *************** *** 2272,2278 **** (downcase secure-sender))))) (goto-char (point-min)) ;; Rename any old Sender headers to Original-Sender. ! (when (re-search-forward "^Sender:" nil t) (beginning-of-line) (insert "Original-") (beginning-of-line)) --- 2283,2289 ---- (downcase secure-sender))))) (goto-char (point-min)) ;; Rename any old Sender headers to Original-Sender. ! (when (re-search-forward "^\\(Original-\\)*Sender:" nil t) (beginning-of-line) (insert "Original-") (beginning-of-line)) *************** *** 3117,3122 **** --- 3128,3152 ---- (apply 'append (mapcar 'message-flatten-list-1 list))) (list (list list)))) + + (defun message-generate-new-buffer-clone-locals (name &optional varstr) + "Create and return a buffer with a name based on NAME using generate-new-buffer. + Then clone the local variables and values from the old buffer to the + new one, cloning only the locals having a substring matching the + regexp varstr." + (let ((oldlocals (buffer-local-variables))) + (save-excursion + (set-buffer (generate-new-buffer name)) + (mapcar (lambda (dude) + (when (and (car dude) + (or (not varstr) + (string-match varstr (symbol-name (car dude))))) + (condition-case () + (set (make-local-variable (car dude)) + (cdr dude)) + (error)))) + oldlocals) + (current-buffer)))) (run-hooks 'message-load-hook) *** pub/rgnus/lisp/messcompat.el Tue Jul 2 08:42:10 1996 --- rgnus/lisp/messcompat.el Tue Oct 29 17:20:06 1996 *************** *** 63,71 **** "*Number of spaces to insert at the beginning of each cited line. Used by `message-yank-original' via `message-yank-cite'.") - (defvar message-cite-function (car mail-citation-hook) - "*Function for citing an original message.") - (defvar message-signature mail-signature "*String to be inserted at the end of the message buffer. If t, the `message-signature-file' file will be inserted instead. --- 63,68 ---- *** pub/rgnus/lisp/nnbabyl.el Mon Sep 30 23:42:39 1996 --- rgnus/lisp/nnbabyl.el Tue Oct 29 17:20:06 1996 *************** *** 117,122 **** --- 117,123 ---- (deffoo nnbabyl-open-server (server &optional defs) (nnoo-change-server 'nnbabyl server defs) + (nnbabyl-create-mbox) (cond ((not (file-exists-p nnbabyl-mbox-file)) (nnbabyl-close-server) *************** *** 242,248 **** (deffoo nnbabyl-request-list (&optional server) (save-excursion (nnmail-find-file nnbabyl-active-file) ! (setq nnbabyl-group-alist (nnmail-get-active)))) (deffoo nnbabyl-request-newgroups (date &optional server) (nnbabyl-request-list server)) --- 243,250 ---- (deffoo nnbabyl-request-list (&optional server) (save-excursion (nnmail-find-file nnbabyl-active-file) ! (setq nnbabyl-group-alist (nnmail-get-active)) ! t)) (deffoo nnbabyl-request-newgroups (date &optional server) (nnbabyl-request-list server)) *************** *** 523,530 **** nnbabyl-group-alist)) (cdr active))) ! (defun nnbabyl-read-mbox () ! (nnmail-activate 'nnbabyl) (unless (file-exists-p nnbabyl-mbox-file) ;; Create a new, empty RMAIL mbox file. (save-excursion --- 525,531 ---- nnbabyl-group-alist)) (cdr active))) ! (defun nnbabyl-create-mbox () (unless (file-exists-p nnbabyl-mbox-file) ;; Create a new, empty RMAIL mbox file. (save-excursion *************** *** 533,539 **** (setq buffer-file-name nnbabyl-mbox-file) (insert "BABYL OPTIONS:\n\n\^_") (nnmail-write-region ! (point-min) (point-max) nnbabyl-mbox-file t 'nomesg))) (if (and nnbabyl-mbox-buffer (buffer-name nnbabyl-mbox-buffer) --- 534,544 ---- (setq buffer-file-name nnbabyl-mbox-file) (insert "BABYL OPTIONS:\n\n\^_") (nnmail-write-region ! (point-min) (point-max) nnbabyl-mbox-file t 'nomesg)))) ! ! (defun nnbabyl-read-mbox () ! (nnmail-activate 'nnbabyl) ! (nnbabyl-create-mbox) (if (and nnbabyl-mbox-buffer (buffer-name nnbabyl-mbox-buffer) *** pub/rgnus/lisp/nnfolder.el Mon Sep 30 23:42:41 1996 --- rgnus/lisp/nnfolder.el Tue Oct 29 17:20:07 1996 *************** *** 287,293 **** (nnfolder-possibly-change-group nil server) (save-excursion (nnmail-find-file nnfolder-active-file) ! (setq nnfolder-group-alist (nnmail-get-active)))) (deffoo nnfolder-request-newgroups (date &optional server) (nnfolder-possibly-change-group nil server) --- 287,294 ---- (nnfolder-possibly-change-group nil server) (save-excursion (nnmail-find-file nnfolder-active-file) ! (setq nnfolder-group-alist (nnmail-get-active)) ! t)) (deffoo nnfolder-request-newgroups (date &optional server) (nnfolder-possibly-change-group nil server) *** pub/rgnus/lisp/nnheader.el Mon Sep 30 23:42:41 1996 --- rgnus/lisp/nnheader.el Tue Oct 29 17:20:07 1996 *************** *** 518,524 **** (kill-buffer ,temp-buffer))))))) (put 'nnheader-temp-write 'lisp-indent-function 1) - (put 'nnheader-temp-write 'lisp-indent-hook 1) (put 'nnheader-temp-write 'edebug-form-spec '(form body)) (defvar jka-compr-compression-info-list) --- 518,523 ---- *** pub/rgnus/lisp/nnmail.el Fri Oct 11 12:07:40 1996 --- rgnus/lisp/nnmail.el Tue Oct 29 17:20:07 1996 *************** *** 395,401 **** ;; If getting from mail spool directory, ;; use movemail to move rather than just renaming, ;; so as to interlock with the mailer. ! (unless (setq popmail (string-match "^po:" (file-name-nondirectory inbox))) (setq movemail t)) (when popmail (setq inbox (file-name-nondirectory inbox))) --- 395,402 ---- ;; If getting from mail spool directory, ;; use movemail to move rather than just renaming, ;; so as to interlock with the mailer. ! (unless (setq popmail (string-match ! "^po:" (file-name-nondirectory inbox))) (setq movemail t)) (when popmail (setq inbox (file-name-nondirectory inbox))) *************** *** 409,415 **** (if popmail (progn (setq nnmail-internal-password nnmail-pop-password) ! (when (and nnmail-pop-password-required (not nnmail-pop-password)) (setq nnmail-internal-password (nnmail-read-passwd (format "Password for %s: " --- 410,417 ---- (if popmail (progn (setq nnmail-internal-password nnmail-pop-password) ! (when (and nnmail-pop-password-required ! (not nnmail-pop-password)) (setq nnmail-internal-password (nnmail-read-passwd (format "Password for %s: " *************** *** 458,464 **** 'call-process (append (list ! (expand-file-name nnmail-movemail-program exec-directory) nil errors nil inbox tofile) (when nnmail-internal-password (list nnmail-internal-password)))))) --- 460,467 ---- 'call-process (append (list ! (expand-file-name nnmail-movemail-program ! exec-directory) nil errors nil inbox tofile) (when nnmail-internal-password (list nnmail-internal-password)))))) *************** *** 1051,1082 **** ;; already activated. (defun nnmail-activate (backend &optional force) (let (file timestamp file-time) ! (when (or (not (symbol-value (intern (format "%s-group-alist" backend)))) ! force ! (and (setq file (condition-case () ! (symbol-value (intern (format "%s-active-file" ! backend))) ! (error nil))) ! (setq file-time (nth 5 (file-attributes file))) ! (or (not ! (setq timestamp ! (condition-case () ! (symbol-value (intern ! (format "%s-active-timestamp" ! backend))) ! (error 'none)))) ! (not (consp timestamp)) ! (equal timestamp '(0 0)) ! (> (nth 0 file-time) (nth 0 timestamp)) ! (and (= (nth 0 file-time) (nth 0 timestamp)) ! (> (nth 1 file-time) (nth 1 timestamp)))))) ! (save-excursion ! (or (eq timestamp 'none) ! (set (intern (format "%s-active-timestamp" backend)) ! (current-time))) ! (funcall (intern (format "%s-request-list" backend))) ! (set (intern (format "%s-group-alist" backend)) ! (nnmail-get-active)))) t)) (defun nnmail-message-id () --- 1054,1094 ---- ;; already activated. (defun nnmail-activate (backend &optional force) (let (file timestamp file-time) ! (if (or (not (symbol-value (intern (format "%s-group-alist" backend)))) ! force ! (and (setq file (condition-case () ! (symbol-value (intern (format "%s-active-file" ! backend))) ! (error nil))) ! (setq file-time (nth 5 (file-attributes file))) ! (or (not ! (setq timestamp ! (condition-case () ! (symbol-value (intern ! (format "%s-active-timestamp" ! backend))) ! (error 'none)))) ! (not (consp timestamp)) ! (equal timestamp '(0 0)) ! (> (nth 0 file-time) (nth 0 timestamp)) ! (and (= (nth 0 file-time) (nth 0 timestamp)) ! (> (nth 1 file-time) (nth 1 timestamp)))))) ! (save-excursion ! (or (eq timestamp 'none) ! (set (intern (format "%s-active-timestamp" backend)) ! ;;; dmoore@ucsd.edu 25.10.96 ! ;;; it's not always the case that current-time ! ;;; does correspond to changes in the file's time. So just compare ! ;;; the file's new time against its own previous time. ! ;;; (current-time) ! file-time ! )) ! (funcall (intern (format "%s-request-list" backend))) ! ;;; dmoore@ucsd.edu 25.10.96 ! ;;; BACKEND-request-list already does this itself! ! ;;; (set (intern (format "%s-group-alist" backend)) ! ;;; (nnmail-get-active)) ! )) t)) (defun nnmail-message-id () *** pub/rgnus/lisp/nnmbox.el Mon Sep 30 23:42:43 1996 --- rgnus/lisp/nnmbox.el Tue Oct 29 17:20:08 1996 *************** *** 115,120 **** --- 115,121 ---- (deffoo nnmbox-open-server (server &optional defs) (nnoo-change-server 'nnmbox server defs) + (nnmbox-create-mbox) (cond ((not (file-exists-p nnmbox-mbox-file)) (nnmbox-close-server) *************** *** 208,214 **** (deffoo nnmbox-request-list (&optional server) (save-excursion (nnmail-find-file nnmbox-active-file) ! (setq nnmbox-group-alist (nnmail-get-active)))) (deffoo nnmbox-request-newgroups (date &optional server) (nnmbox-request-list server)) --- 209,216 ---- (deffoo nnmbox-request-list (&optional server) (save-excursion (nnmail-find-file nnmbox-active-file) ! (setq nnmbox-group-alist (nnmail-get-active)) ! t)) (deffoo nnmbox-request-newgroups (date &optional server) (nnmbox-request-list server)) *************** *** 481,490 **** nnmbox-group-alist)) (cdr active))) (defun nnmbox-read-mbox () (nnmail-activate 'nnmbox) ! (when (not (file-exists-p nnmbox-mbox-file)) ! (nnmail-write-region 1 1 nnmbox-mbox-file t 'nomesg)) (if (and nnmbox-mbox-buffer (buffer-name nnmbox-mbox-buffer) (save-excursion --- 483,495 ---- nnmbox-group-alist)) (cdr active))) + (defun nnmbox-create-mbox () + (when (not (file-exists-p nnmbox-mbox-file)) + (nnmail-write-region 1 1 nnmbox-mbox-file t 'nomesg))) + (defun nnmbox-read-mbox () (nnmail-activate 'nnmbox) ! (nnmbox-create-mbox) (if (and nnmbox-mbox-buffer (buffer-name nnmbox-mbox-buffer) (save-excursion *** pub/rgnus/lisp/nnmh.el Fri Oct 11 12:07:40 1996 --- rgnus/lisp/nnmh.el Tue Oct 29 17:20:08 1996 *************** *** 452,459 **** (string-to-int f)) (directory-files (nnmail-group-pathname group nnmh-directory) ! nil "^[0-9]+$") ! '>)))) (when files (setcdr active (car files))))) (setcdr active (1+ (cdr active))) --- 452,459 ---- (string-to-int f)) (directory-files (nnmail-group-pathname group nnmh-directory) ! nil "^[0-9]+$")) ! '>))) (when files (setcdr active (car files))))) (setcdr active (1+ (cdr active))) *** pub/rgnus/lisp/nnml.el Thu Oct 17 01:47:13 1996 --- rgnus/lisp/nnml.el Tue Oct 29 17:20:08 1996 *************** *** 144,150 **** (when (not (file-exists-p nnml-directory)) (condition-case () (make-directory nnml-directory t) ! (error t))) (cond ((not (file-exists-p nnml-directory)) (nnml-close-server) --- 144,150 ---- (when (not (file-exists-p nnml-directory)) (condition-case () (make-directory nnml-directory t) ! (error))) (cond ((not (file-exists-p nnml-directory)) (nnml-close-server) *************** *** 235,241 **** (deffoo nnml-request-list (&optional server) (save-excursion (nnmail-find-file nnml-active-file) ! (setq nnml-group-alist (nnmail-get-active)))) (deffoo nnml-request-newgroups (date &optional server) (nnml-request-list server)) --- 235,242 ---- (deffoo nnml-request-list (&optional server) (save-excursion (nnmail-find-file nnml-active-file) ! (setq nnml-group-alist (nnmail-get-active)) ! t)) (deffoo nnml-request-newgroups (date &optional server) (nnml-request-list server)) *** pub/rgnus/lisp/nnoo.el Fri Oct 11 12:07:40 1996 --- rgnus/lisp/nnoo.el Tue Oct 29 17:20:09 1996 *************** *** 39,45 **** `(defvar ,var ,init)) (nnoo-define ',var ',map))) (put 'defvoo 'lisp-indent-function 2) - (put 'defvoo 'lisp-indent-hook 2) (put 'defvoo 'edebug-form-spec '(var init &optional doc &rest map)) (defmacro deffoo (func args &rest forms) --- 39,44 ---- *************** *** 48,54 **** (defun ,func ,args ,@forms) (nnoo-register-function ',func))) (put 'deffoo 'lisp-indent-function 2) - (put 'deffoo 'lisp-indent-hook 2) (put 'deffoo 'edebug-form-spec '(&define name lambda-list def-body)) (defun nnoo-register-function (func) --- 47,52 ---- *************** *** 65,71 **** nil nil) nnoo-definition-alist))) (put 'nnoo-declare 'lisp-indent-function 1) - (put 'nnoo-declare 'lisp-indent-hook 1) (defun nnoo-parents (backend) (nth 1 (assoc backend nnoo-definition-alist))) --- 63,68 ---- *************** *** 79,85 **** (defmacro nnoo-import (backend &rest imports) `(nnoo-import-1 ',backend ',imports)) (put 'nnoo-import 'lisp-indent-function 1) - (put 'nnoo-import 'lisp-indent-hook 1) (defun nnoo-import-1 (backend imports) (let ((call-function --- 76,81 ---- *************** *** 113,119 **** (defmacro nnoo-map-functions (backend &rest maps) `(nnoo-map-functions-1 ',backend ',maps)) (put 'nnoo-map-functions 'lisp-indent-function 1) - (put 'nnoo-map-functions 'lisp-indent-hook 1) (defun nnoo-map-functions-1 (backend maps) (let (m margs i) --- 109,114 ---- *** pub/rgnus/lisp/nnsoup.el Tue Oct 1 05:02:10 1996 --- rgnus/lisp/nnsoup.el Tue Oct 29 17:20:09 1996 *************** *** 386,427 **** prefix)) (defun nnsoup-read-areas () ! (save-excursion ! (set-buffer nntp-server-buffer) ! (let ((areas (gnus-soup-parse-areas (concat nnsoup-tmp-directory "AREAS"))) ! entry number area lnum cur-prefix file) ! ;; Go through all areas in the new AREAS file. ! (while (setq area (pop areas)) ! ;; Change the name to the permanent name and move the files. ! (setq cur-prefix (nnsoup-next-prefix)) ! (message "Incorporating file %s..." cur-prefix) ! (when (file-exists-p ! (setq file (concat nnsoup-tmp-directory ! (gnus-soup-area-prefix area) ".IDX"))) ! (rename-file file (nnsoup-file cur-prefix))) ! (when (file-exists-p ! (setq file (concat nnsoup-tmp-directory ! (gnus-soup-area-prefix area) ".MSG"))) ! (rename-file file (nnsoup-file cur-prefix t)) ! (gnus-soup-set-area-prefix area cur-prefix) ! ;; Find the number of new articles in this area. ! (setq number (nnsoup-number-of-articles area)) ! (if (not (setq entry (assoc (gnus-soup-area-name area) ! nnsoup-group-alist))) ! ;; If this is a new area (group), we just add this info to ! ;; the group alist. ! (push (list (gnus-soup-area-name area) ! (cons 1 number) ! (list (cons 1 number) area)) ! nnsoup-group-alist) ! ;; There are already articles in this group, so we add this ! ;; info to the end of the entry. ! (nconc entry (list (list (cons (1+ (setq lnum (cdadr entry))) ! (+ lnum number)) ! area))) ! (setcdr (cadr entry) (+ lnum number)))))) ! (nnsoup-write-active-file t) ! (delete-file (concat nnsoup-tmp-directory "AREAS")))) (defun nnsoup-number-of-articles (area) (save-excursion --- 386,428 ---- prefix)) (defun nnsoup-read-areas () ! (when (file-exists-p (concat nnsoup-tmp-directory "AREAS")) ! (save-excursion ! (set-buffer nntp-server-buffer) ! (let ((areas (gnus-soup-parse-areas (concat nnsoup-tmp-directory "AREAS"))) ! entry number area lnum cur-prefix file) ! ;; Go through all areas in the new AREAS file. ! (while (setq area (pop areas)) ! ;; Change the name to the permanent name and move the files. ! (setq cur-prefix (nnsoup-next-prefix)) ! (message "Incorporating file %s..." cur-prefix) ! (when (file-exists-p ! (setq file (concat nnsoup-tmp-directory ! (gnus-soup-area-prefix area) ".IDX"))) ! (rename-file file (nnsoup-file cur-prefix))) ! (when (file-exists-p ! (setq file (concat nnsoup-tmp-directory ! (gnus-soup-area-prefix area) ".MSG"))) ! (rename-file file (nnsoup-file cur-prefix t)) ! (gnus-soup-set-area-prefix area cur-prefix) ! ;; Find the number of new articles in this area. ! (setq number (nnsoup-number-of-articles area)) ! (if (not (setq entry (assoc (gnus-soup-area-name area) ! nnsoup-group-alist))) ! ;; If this is a new area (group), we just add this info to ! ;; the group alist. ! (push (list (gnus-soup-area-name area) ! (cons 1 number) ! (list (cons 1 number) area)) ! nnsoup-group-alist) ! ;; There are already articles in this group, so we add this ! ;; info to the end of the entry. ! (nconc entry (list (list (cons (1+ (setq lnum (cdadr entry))) ! (+ lnum number)) ! area))) ! (setcdr (cadr entry) (+ lnum number)))))) ! (nnsoup-write-active-file t) ! (delete-file (concat nnsoup-tmp-directory "AREAS"))))) (defun nnsoup-number-of-articles (area) (save-excursion *************** *** 552,563 **** --- 553,569 ---- (defun nnsoup-pack-replies () "Make an outbound package of SOUP replies." (interactive) + (unless (file-exists-p nnsoup-replies-directory) + (message "No such directory: %s" nnsoup-replies-directory)) ;; Write all data buffers. (gnus-soup-save-areas) ;; Write the active file. (nnsoup-write-active-file) ;; Write the REPLIES file. (nnsoup-write-replies) + ;; Check whether there is anything here. + (when (null (directory-files nnsoup-replies-directory nil "\\.MSG$")) + (error "No files to pack.")) ;; Pack all these files into a SOUP packet. (gnus-soup-pack nnsoup-replies-directory nnsoup-packer)) *** pub/rgnus/lisp/nntp.el Wed Oct 16 03:45:15 1996 --- rgnus/lisp/nntp.el Tue Oct 29 17:20:09 1996 *************** *** 596,601 **** --- 596,602 ---- ;; Wait for the status string to arrive. (setq nntp-server-type (buffer-string)) (let ((alist nntp-server-action-alist) + (case-fold-search t) entry) ;; Run server-specific commands. (while alist *************** *** 638,644 **** (nntp-inside-change-function t)) (setq nntp-process-callback nil) (save-excursion ! (funcall callback t)))))))) (defun nntp-retrieve-data (command address port buffer &optional wait-for callback decode) --- 639,646 ---- (nntp-inside-change-function t)) (setq nntp-process-callback nil) (save-excursion ! (funcall callback (buffer-name ! (get-buffer nntp-process-to-buffer)))))))))) (defun nntp-retrieve-data (command address port buffer &optional wait-for callback decode) *************** *** 741,756 **** (defun nntp-decode-text (&optional cr-only) "Decode the text in the current buffer." (goto-char (point-min)) ! (current-buffer) (while (search-forward "\r" nil t) (delete-char -1)) (unless cr-only (goto-char (point-max)) (forward-line -1) (when (looking-at ".\n") (delete-char 2)) (goto-char (point-min)) (delete-region (point) (progn (forward-line 1) (point))) (while (search-forward "\n.." nil t) (delete-char -1)))) --- 743,761 ---- (defun nntp-decode-text (&optional cr-only) "Decode the text in the current buffer." (goto-char (point-min)) ! ;; Remove \R's. (while (search-forward "\r" nil t) (delete-char -1)) (unless cr-only + ;; Remove trailing ".\n" end-of-transfer marker. (goto-char (point-max)) (forward-line -1) (when (looking-at ".\n") (delete-char 2)) + ;; Delete status line. (goto-char (point-min)) (delete-region (point) (progn (forward-line 1) (point))) + ;; Remove "." -> ".." encoding. (while (search-forward "\n.." nil t) (delete-char -1)))) *** pub/rgnus/lisp/nnweb.el Fri Oct 11 12:07:41 1996 --- rgnus/lisp/nnweb.el Tue Oct 29 17:20:10 1996 *************** *** 33,38 **** --- 33,41 ---- (require 'gnus-util) (require 'w3) (require 'url) + (condition-case () + (require 'w3-forms) + (error)) (nnoo-declare nnweb) *** pub/rgnus/lisp/widget-edit.el Thu Oct 10 13:44:42 1996 --- rgnus/lisp/widget-edit.el Tue Oct 29 17:41:53 1996 *************** *** 4,10 **** ;; ;; Author: Per Abrahamsen ;; Keywords: extensions ! ;; Version: 0.993 ;; X-URL: http://www.dina.kvl.dk/~abraham/custom/ ;;; Commentary: --- 4,10 ---- ;; ;; Author: Per Abrahamsen ;; Keywords: extensions ! ;; Version: 0.995 ;; X-URL: http://www.dina.kvl.dk/~abraham/custom/ ;;; Commentary: *************** *** 23,40 **** (require 'custom) (error nil)) ! (eval-and-compile ! (unless (and (featurep 'custom) (fboundp 'custom-declare-variable)) ! ;; We have the old custom-library, hack around it! ! (defmacro defgroup (&rest args) nil) ! (defmacro defcustom (&rest args) nil) ! (defmacro defface (&rest args) nil) ! (when (fboundp 'copy-face) ! (copy-face 'default 'widget-documentation-face) ! (copy-face 'bold 'widget-button-face) ! (copy-face 'italic 'widget-field-face)) ! (defvar widget-mouse-face 'highlight) ! (defvar widget-menu-max-size 40))) ;;; Compatibility. --- 23,39 ---- (require 'custom) (error nil)) ! (unless (and (featurep 'custom) (fboundp 'custom-declare-variable)) ! ;; We have the old custom-library, hack around it! ! (defmacro defgroup (&rest args) nil) ! (defmacro defcustom (&rest args) nil) ! (defmacro defface (&rest args) nil) ! (when (fboundp 'copy-face) ! (copy-face 'default 'widget-documentation-face) ! (copy-face 'bold 'widget-button-face) ! (copy-face 'italic 'widget-field-face)) ! (defvar widget-mouse-face 'highlight) ! (defvar widget-menu-max-size 40)) ;;; Compatibility. *************** *** 214,219 **** --- 213,220 ---- (let ((face (widget-apply widget :button-face-get))) (add-text-properties from to (list 'button widget 'mouse-face widget-mouse-face + 'start-open t + 'end-open t 'face face)))) (defun widget-specify-doc (widget from to) *************** *** 1774,1780 **** (intern value) value))) ! (define-widget 'function 'symbol ;; Should complete on functions. "A lisp function." :tag "Function") --- 1775,1781 ---- (intern value) value))) ! (define-widget 'function 'sexp ;; Should complete on functions. "A lisp function." :tag "Function") *************** *** 1863,1872 **** (prin1-to-string value) value)) :match (lambda (widget value) (numberp value))) - - (define-widget 'hook 'sexp - "A emacs lisp hook" - :tag "Hook") (define-widget 'list 'group "A lisp list." --- 1864,1869 ---- *** pub/rgnus/lisp/widget.el Thu Oct 10 13:44:39 1996 --- rgnus/lisp/widget.el Tue Oct 29 17:41:50 1996 *************** *** 4,10 **** ;; ;; Author: Per Abrahamsen ;; Keywords: help, extensions, faces, hypermedia ! ;; Version: 0.993 ;; X-URL: http://www.dina.kvl.dk/~abraham/custom/ ;;; Commentary: --- 4,10 ---- ;; ;; Author: Per Abrahamsen ;; Keywords: help, extensions, faces, hypermedia ! ;; Version: 0.995 ;; X-URL: http://www.dina.kvl.dk/~abraham/custom/ ;;; Commentary: *** pub/rgnus/lisp/ChangeLog Thu Oct 17 01:47:15 1996 --- rgnus/lisp/ChangeLog Tue Oct 29 21:07:22 1996 *************** *** 1,3 **** --- 1,183 ---- + Tue Oct 29 20:42:07 1996 Lars Magne Ingebrigtsen + + * gnus-topic.el (gnus-topic-remove-topic): Fold properly. + + Tue Oct 29 19:45:25 1996 Lars Magne Ingebrigtsen + + * message.el (message-generate-new-buffer-clone-locals): Bugged + out under XEmacs. + + Tue Oct 29 19:21:47 1996 David Moore + + * gnus.el: Fixed autoloads. + + Tue Oct 29 17:21:42 1996 Lars Magne Ingebrigtsen + + * gnus-art.el (gnus-url-mailto): `message-goto-subject' takes no + args. + + Mon Oct 28 15:42:21 1996 Lars Magne Ingebrigtsen + + * gnus.el: Autoload gnus-score-followup-thread. + (gnus-inhibit-startup-message): Doc fix. + + Sat Oct 26 15:48:28 1996 Lars Magne Ingebrigtsen + + * gnus-xmas.el (gnus-xmas-topic-menu-add): Add menu. + + * gnus-topic.el (gnus-topic-kill-group): Enter into dribble. + + * gnus-sum.el (gnus-summary-universal-argument): Bind + `gnus-newsgroup-process-marked' to nil before calling functions. + + Sat Oct 26 15:31:18 1996 David Moore + + * nnmail.el (nnmail-activate): Faster version. + + Fri Oct 25 09:02:08 1996 Lars Magne Ingebrigtsen + + * nnsoup.el (nnsoup-pack-replies): Error empty dirs. + + * gnus-msg.el (gnus-summary-mail-forward): Allow prefix to forward + full headers. + + Thu Oct 24 07:20:30 1996 Lars Magne Ingebrigtsen + + * gnus-nocem.el (gnus-nocem-enter-article): Would enter unbound + symbols into hashtb. + + Thu Oct 24 07:12:23 1996 Michael R. Cook + + * nnmh.el (nnmh-active-number): Misplaced paren. + + Thu Oct 24 07:02:54 1996 Lars Magne Ingebrigtsen + + * gnus-group.el (gnus-group-list-groups): Clear inboxes. + + * gnus-async.el (gnus-make-async-article-function): Use the + success param. + + * nntp.el (nntp-after-change-function-callback): Pass along the + right success param. + + Wed Oct 23 18:33:15 1996 Lars Magne Ingebrigtsen + + * gnus-score.el (gnus-summary-increase-score): Spud. + + Wed Oct 23 07:55:42 1996 William Perry + + * gnus-art.el (gnus-url-mailto): New function. + + Wed Oct 23 06:57:10 1996 Lars Magne Ingebrigtsen + + * nnbabyl.el (nnbabyl-create-mbox): New function. + (nnbabyl-open-server): Create mbox. + + * nnmbox.el (nnmbox-create-mbox): New function. + + Tue Oct 22 07:30:12 1996 Lars Magne Ingebrigtsen + + * nnml.el (nnml-request-list): Always return t. + + Tue Oct 22 03:16:27 1996 Felix Lee + + * gnus-score.el (gnus-score-adaptive): Use the right syntax + table. + + Tue Oct 22 03:08:30 1996 Lars Magne Ingebrigtsen + + * message.el (message-generate-headers): Rename Original-Sender as + well. + (message-send-news): Typo. + (message-send-news): Don't message. + + Tue Oct 22 03:06:49 1996 Felix Lee + + * gnus-score.el (gnus-score-adaptive): gnus-score-adaptive will do + line scoring or word scoring, but not both. + + Tue Oct 22 02:48:08 1996 Lars Magne Ingebrigtsen + + * message.el (message-send-news): Use it. + (message-send-mail): Ditto. + + Tue Oct 22 02:40:14 1996 Joev Dubach + + * message.el (message-generate-new-buffer-clone-locals): New + function. + + Tue Oct 22 01:19:47 1996 Lars Magne Ingebrigtsen + + * message.el: Removed `lisp-indent-hook' throughout all files. + + * gnus.el (gnus-sethash): Fix edebug form spec. + + * gnus-cache.el (gnus-cache-file-name): Translate file chars. + + Sun Oct 20 03:41:47 1996 Lars Magne Ingebrigtsen + + * nntp.el (nntp-read-server-type): Fold case. + + Sat Oct 19 08:03:17 1996 Michael Ernst + + * article.el (article-hide-headers): Do the right thing on + articles with no bodies. + (article-narrow-to-signature): Doc fix. + + Sat Oct 19 07:53:49 1996 Lars Magne Ingebrigtsen + + * nnsoup.el (nnsoup-pack-replies): Refuse to pack when there is + nothing to pack. + (nnsoup-read-areas): Don't bug out on empty packets. + + * gnus-soup.el (gnus-soup-pack-packet): Refuse to pack empty + packets. + + Sat Oct 19 07:43:33 1996 Kees de Bruin + + * gnus-sum.el (gnus-auto-center-summary): Fix. + + Sat Oct 19 07:32:27 1996 Marc Horowitz + + * gnus-topic.el (gnus-topic-remove-topic): Would clobber + duplicates. + + Sat Oct 19 07:01:14 1996 Lars Magne Ingebrigtsen + + * message.el (message-send-mail-hook): New hook. + (message-send-news-hook): Ditto. + + * gnus-art.el (gnus-summary-write-to-file): New function. + + Sat Oct 19 06:56:34 1996 Kees de Bruin + + * gnus-sum.el (gnus-summary-save-article-mail-overwrite): New + command and keystroke. + + Thu Oct 17 06:25:55 1996 Lars Magne Ingebrigtsen + + * gnus-sum.el (gnus-article-sort-by-date): Use faster + implementation. + + * gnus-util.el (gnus-string-get-time): New macro. + + * message.el (message-check-news-syntax): Check more thorougly the + From header. + (message-check): New macro. + + Thu Oct 17 06:03:56 1996 Carsten Leonhardt + + * gnus-ems.el (gnus-xemacs): Avoid clobbering functions. + + Thu Oct 17 05:34:15 1996 Lars Magne Ingebrigtsen + + * message.el (message-cite-function): Initialize from + mail-citation-hook. + + Thu Oct 17 02:45:47 1996 Lars Magne Ingebrigtsen + + * gnus.el: Red Gnus v0.52 is released. + Wed Oct 16 21:01:41 1996 Lars Magne Ingebrigtsen * gnus-sum.el (gnus-summary-catchup): Return t. *** pub/rgnus/texi/custom.texi Tue Sep 17 03:16:56 1996 --- rgnus/texi/custom.texi Tue Oct 29 17:42:00 1996 *************** *** 1,7 **** \input texinfo.tex @c %**start of header ! @setfilename custom.info @settitle The Customization Library @iftex @afourpaper --- 1,7 ---- \input texinfo.tex @c %**start of header ! @setfilename custom @settitle The Customization Library @iftex @afourpaper *************** *** 9,19 **** @end iftex @c %**end of header @node Top, Introduction, (dir), (dir) @comment node-name, next, previous, up @top The Customization Library ! Version: 0.9 @menu * Introduction:: --- 9,30 ---- @end iftex @c %**end of header + @menu + * Introduction:: + * User Commands:: + * The Customization Buffer:: + * Declaring Groups:: + * Declaring Variables:: + * Declaring Faces:: + * The Init File:: + * Wishlist:: + @end menu + @node Top, Introduction, (dir), (dir) @comment node-name, next, previous, up @top The Customization Library ! Version: 0.995 @menu * Introduction:: *************** *** 72,148 **** Create a customization buffer containing a single variable. @item customize-face ! Create a customization buffer contaning a single face. @item customize-apropos Create a customization buffer containing all variables, faces, and groups that match a user specified regular expression. @end table ! @node The Customization Buffer, Declaring Groups, User Commands, Top @comment node-name, next, previous, up @section The Customization Buffer. ! Here should be a description of how to use a customization buffer. ! For now, try to press @kbd{C-h m} in the buffer, or read @ref{User ! Interface,,widget,The Widget Library}. ! The interface will change, as it currently stinks. Here is some hints ! about how to use it though: ! @itemize @bullet ! @item ! Groups and user option start on a new line, and look like this ! @t{@b{name}:}. If you move point above to the @t{@b{name}} and press ! @kbd{@key{RET}}, or move the mouse pointer above it and press ! @kbd{mouse-2}, you will be presented with a menu. I call this the ! @dfn{tag menu} below. ! @item ! For groups and faces, you need to activate @samp{Toggle Hide} from the ! tag menu to be able to see the content. ! @item ! After editing a variable or face, you must activate @samp{Apply} for the ! setting to take effect, and @samp{Set Default} for marking the widget ! value as the new default value. ! @item ! After setting new default values with @samp{Set Default}, you must ! activate the @samp{Save} button in the bottom of the screen to save the ! new defaults. Otherwise the new defaults will be silently forgotten. ! @item ! Pushing @samp{Save} is a no-op unless you have activated @samp{Set Default} ! for some user option. ! @item ! The @code{face} widget never attempts to display the current value of a ! face. Instead it allows you to specify how the face should be ! initialized. This is done with a list of @dfn{display} and ! @dfn{attributes} pairs, where the first display that matches a frame ! specify the attributes to use for that frame. ! ! A display can either match all frames, or only frames with a given ! @dfn{type}, @dfn{class}, and @dfn{background}. The checkbox before each ! of these display parameters determine whether the parameter will be ! checked. If the checkbox before @samp{Type} is unchecked, the display ! will match all types of frames. If it is checked, it will match the ! type of frames specified on the rest of the line. ! ! The attributes are specified next. Each attribute line begins with a ! checkbox, if that checkbox is unchecked the face will not affect that ! particular attribute on the screen, otherwise the face will force the ! the text to have the value for attribute specified after the attrbute ! name. This means that an attribute like @samp{bold} in effect have ! three states: If the first checkmark is unchecked, the face will not ! affect the boldness of the text. If the first checkmark is checked, but ! the second is unchecked, the text will be forced to be unbold. If both ! checkmarks are checked, the text will be forced to be bold. ! ! Think about this, and mail me a suggestion for how to make the face ! widget more intuitive. ! @end itemize @node Declaring Groups, Declaring Variables, The Customization Buffer, Top @comment node-name, next, previous, up --- 83,414 ---- Create a customization buffer containing a single variable. @item customize-face ! Create a customization buffer containing a single face. @item customize-apropos Create a customization buffer containing all variables, faces, and groups that match a user specified regular expression. @end table ! @node The Customization Buffer, Declaring Groups, User Commands, Top @comment node-name, next, previous, up @section The Customization Buffer. ! The customization buffer allows the user to make temporary or permanent ! changes to how specific aspects of emacs works, by setting and editing ! user options. ! The customization buffer contains three types of text: ! @table @dfn ! @item informative text ! where the normal editing commands are disabled. ! @item editable fields ! where you can edit with the usual emacs commands. Editable fields are ! usually displayed with a grey background if your terminal supports ! colors, or an italic font otherwise. ! ! @item buttons ! which can be activated by either pressing the @kbd{@key{ret}} while ! point is located on the text, or pushing @kbd{mouse-2} while the mouse ! pointer is above the tex. Buttons are usually displayed in a bold ! font. ! @end table ! You can move to the next the next editable field or button by pressing ! @kbd{@key{tab}} or the previous with @kbd{M-@key{tab}}. Some buttons ! have a small helpful message about their purpose, which will be ! displayed when you move to it with the @key{tab} key. ! ! The buffer is divided into three part, an introductory text, a list of ! customization options, and a line of customization buttons. Each part ! will be described in the following. ! @menu ! * The Introductory Text:: ! * The Customization Options:: ! * The Variable Options:: ! * The Face Options:: ! * The Group Options:: ! * The State Button:: ! * The Customization Buttons:: ! @end menu ! @node The Introductory Text, The Customization Options, The Customization Buffer, The Customization Buffer ! @comment node-name, next, previous, up ! @subsection The Introductory Text ! The start of the buffer contains a short explanation of what it is, and ! how to get help. It will typically look like this: ! ! @example ! This is a customization buffer. ! Push RET or click mouse-2 on the word _help_ for more information. ! @end example ! ! Rather boring. It is mostly just informative text, but the word ! @samp{help} is a button that will bring up this document when ! activated. ! ! @node The Customization Options, The Variable Options, The Introductory Text, The Customization Buffer ! @comment node-name, next, previous, up ! @subsection The Customization Options ! ! Each customization option looks similar to the following text: ! ! @example ! *** custom-background-mode: default ! [ ] [?] The brightness of the background. ! @end example ! ! The option contains the parts described below. ! ! @table @samp ! @item *** ! The Level Button. The customization options in the buffer are organized ! in a hierarchy, which is indicated by the number of stars in the level ! button. The top level options will be shown as @samp{*}. When they are ! expanded, the suboptions will be shown as @samp{**}. The example option ! is thus a subsuboption. ! ! Activating the level buttons will toggle between hiding and exposing the ! content of that option. The content can either be the value of the ! option, as in this example, or a list of suboptions. ! ! @item custom-background-mode ! This is the tag of the the option. The tag is a name of a variable, a ! face, or customization group. Activating the tag has an effect that ! depends on the exact type of the option. In this particular case, ! activating the tag will bring up a menu that will allow you to choose ! from the three possible values of the `custom-background-mode' ! variable. ! ! @item default ! After the tag, the options value is shown. Depending on its type, you ! may be able to edit the value directly. If an option should contain a ! file name, it is displayed in an editable field, i.e. you can edit it ! using the standard emacs editing commands. ! ! @item [ ] ! The state button. This look of this button will indicate the state of ! the option, e.g. whether it is currently hidden, or whether it has been ! modified or not. Activating the button will allow you to change the ! state, e.g. apply or reset the changes you have made. This is explained ! in detail in the following sections. ! ! @item [?] ! The documentation button. If the documentation is more than one line, ! this button will be present. Activating the button will toggle whether ! the complete documentation is shown, or only the first line. ! ! @item The brightness of the background. ! This is a documentation string explaining the purpose of this particular ! customization option. ! ! @end table ! ! @node The Variable Options, The Face Options, The Customization Options, The Customization Buffer ! @comment node-name, next, previous, up ! @subsection The Variable Options ! ! The most common customization options are emacs lisp variables. The ! actual editing of these variables depend on what type values the ! variable is expected to contain. For example, a lisp variable whose ! value should be a string will typically be represented with an editable ! text field in the buffer, where you can change the string directly. If ! the value is a list, each item in the list will be presented in the ! buffer buffer on a separate line, with buttons to insert new items in ! the list, or delete existing items from the list. You may want to see ! @ref{User Interface,,, widget, The Widget Library}, where some examples ! of editing are discussed. ! ! You can either choose to edit the value directly, or edit the default ! value for that variable. The default value is a lisp expression that ! will be evaluated when you start emacs. The result of the evaluation ! will be used as the initial value for that variable. Editing the ! default value is for experts only, but if the current value of the ! variable is of a wrong type (i.e. a symbol where a string is expected), ! the `edit default' mode will always be selected. ! ! You can see what mode is currently selected by looking at the state ! button. If it uses parenthesises (like @samp{( )}) it is in `Edit ! default' mode, with square brackets (like @samp{[ ]}) it is normal edit ! mode. You can switch mode by activating the state button, and select ! either @samp{Edit} or @samp{Edit default} from the menu. ! ! You can change the state of the variable with the other menu items: ! ! @table @samp ! @item Apply ! When you have made your modifications in the buffer, you need to ! activate this item to make the modifications take effect. The ! modifications will be forgotten next time you run emacs. ! ! @item Set Default ! Unless you activate this item instead! This will mark the modification ! as permanent, i.e. the changes will be remembered in the next emacs ! session. ! ! @item Reset ! If you have made some modifications and not yet applied them, you can ! undo the modification by activating this item. ! ! @item Reset to Default ! Activating this item will reset the value of the variable to the last ! value you marked as permanent with `Set Default'. ! ! @item Reset to Factory Settings ! Activating this item will undo all modifications you have made, and ! reset the value to the initial value specified by the program itself. ! @end table ! ! By default, the value of large or complicated variables are hidden. You ! can show the value by clicking on the level button. ! ! @node The Face Options, The Group Options, The Variable Options, The Customization Buffer ! @comment node-name, next, previous, up ! @subsection The Face Options ! ! A face is an object that controls the appearance of some buffer text. ! The face has a number of possible attributes, such as boldness, ! foreground color, and more. For each attribute you can specify whether ! this attribute is controlled by the face, and if so, what the value is. ! For example, if the attribute bold is not controlled by a face, using ! that face on some buffer text will not affect its boldness. If the bold ! attribute is controlled by the face, it can be turned either on or of. ! ! It is possible to specify that a face should have different attributes ! on different device types. For example, a face may make text red on a ! color device, and bold on a monochrome device. ! ! The way this is presented in the customization buffer is to have a list ! of display specifications, and for each display specification a list of ! face attributes. For each face attribute, there is a checkbox ! specifying whether this attribute has effect and what the value is. ! Here is an example: ! ! @example ! *** custom-invalid-face: (sample) ! [ ] Face used when the customize item is invalid. ! [INS] [DEL] Display: [ ] Type: [ ] X [ ] TTY ! [X] Class: [X] Color [ ] Grayscale [ ] Monochrome ! [ ] Background: [ ] Light [ ] Dark ! Attributes: [ ] Bold: off ! [ ] Italic: off ! [ ] Underline: off ! [X] Foreground: yellow (sample) ! [X] Background: red (sample) ! [ ] Stipple: ! [INS] [DEL] Display: all ! Attributes: [X] Bold: on ! [X] Italic: on ! [X] Underline: on ! [ ] Foreground: default (sample) ! [ ] Background: default (sample) ! [ ] Stipple: ! [INS] ! @end example ! ! This has two display specifications. The first will match all color ! displays, independently on whether the device is X11 or a tty, and ! whether background color is dark or light. For devices matching this ! specification, @samp{custom-invalid-face} will force text to be ! displayed in yellow on red, but leave all other attributes alone. ! ! The second display will simply match everything. Since the list is ! prioritised, this means that it will match all non-color displays. For ! these, the face will not affect the foreground or background color, but ! force the font to be both bold, italic, and underline. ! ! You can add or delete display specifications by activating the ! @samp{[INS]} and @samp{[DEL]} buttons, and modify them by clicking on ! the check boxes. The first checkbox in each line in the display ! specification is special. It specify whether this particular property ! will even be relevant. By not checking the box in the first display, we ! match all device types, also device types other than X11 and tty, for ! example ms-windows, nextstep, and mac os. ! ! After modifying the face, you can activate the state button to make the ! changes take effect. The menu items in the state button menu is similar ! to the state menu items for variables described in the previous section. ! ! @node The Group Options, The State Button, The Face Options, The Customization Buffer ! @comment node-name, next, previous, up ! @subsection The Group Options ! ! Since Emacs has approximately a zillion configuration options, they have ! been organized in groups. Each group can contain other groups, thus ! creating a customization hierarchy. The nesting of the customization ! within the visible part of this hierarchy is indicated by the number of ! stars in the level button. ! ! Since there is really no customization needed for the group itself, the ! menu items in the groups state button will affect all modified group ! members recursively. Thus, if you activate the @samp{Apply} menu item, ! all variables and faces that have been modified and belong to that group ! will be applied. For those members that themselves are groups, it will ! work as if you had activated the @samp{Apply} menu item on them as well. ! ! @node The State Button, The Customization Buttons, The Group Options, The Customization Buffer ! @comment node-name, next, previous, up ! @subsection The State Button ! ! The state button has two purposes. The first is to hold the state menu, ! as described in the previous sections. The second is to indicate the ! state of each customization item. This is done by the character inside ! the brackets. The following states have been defined, the first that ! applies to the current item will be used: ! ! @table @samp ! @item - ! The option is currently hidden. For group options that means the ! members are not shown, for variables and faces that the value is not ! shown. You cannot perform any of the state change operations on a ! hidden customization option. ! ! @item * ! The value if this option has been modified in the buffer, but not yet ! applied. ! ! @item + ! The current value of this option is different from the default value. ! ! @item ! ! The default value of this option is different from the factory setting. ! ! @item @@ ! The factory setting of this option is not known. This occurs when you ! try to customize variables or faces that have not been explicitly ! declared as customizable. ! ! @item SPC ! The factory setting is still in effect. ! ! @end table ! ! For non-hidden group options, the state shown is the most severe state ! of its members, where more severe means that it appears earlier in the ! list above (except hidden members, which are ignored). ! ! @node The Customization Buttons, , The State Button, The Customization Buffer ! @comment node-name, next, previous, up ! @subsection The Customization Buttons ! ! The last part of the customization buffer looks like this: ! ! @example ! [Apply] [Set Default] [Reset] [Save] ! @end example ! ! Activating the @samp{[Apply]}, @samp{[Set Default]}, or @samp{[Reset]} ! button will affect all modified customization items that are visible in ! the buffer. ! ! Activating the @samp{[Save]} button will ensure that all customization ! options who are marked as persistent with @samp{Set default} (either ! with the button at the end of the buffer, or with any of the state ! button menus), will actually be saved in your initialization file. @node Declaring Groups, Declaring Variables, The Customization Buffer, Top @comment node-name, next, previous, up *************** *** 150,167 **** Use @code{defgroup} to declare new customization groups. ! @defun defgroup symbol members [keyword value]... doc Declare @var{symbol} as a customization group containing @var{members}. @var{symbol} does not need to be quoted. @var{members} should be an alist of the form ((@var{name} @var{widget})...) where @var{name} is a symbol and @var{widget} is a widget for editing that symbol. Useful widgets are @code{custom-variable} for editing variables, @code{custom-face} for editing faces, and @code{custom-group} for editing groups.@refill - @var{doc} is the group documentation. - The following @var{keyword}'s are defined: @table @code --- 416,433 ---- Use @code{defgroup} to declare new customization groups. ! @defun defgroup symbol members doc [keyword value]... Declare @var{symbol} as a customization group containing @var{members}. @var{symbol} does not need to be quoted. + @var{doc} is the group documentation. + @var{members} should be an alist of the form ((@var{name} @var{widget})...) where @var{name} is a symbol and @var{widget} is a widget for editing that symbol. Useful widgets are @code{custom-variable} for editing variables, @code{custom-face} for editing faces, and @code{custom-group} for editing groups.@refill The following @var{keyword}'s are defined: @table @code *************** *** 181,187 **** Use @code{defcustom} to declare user editable variables. ! @defun defcustom symbol [keyword value]... doc Declare @var{symbol} as a customizable variable that defaults to @var{value}. Neither @var{symbol} nor @var{value} needs to be quoted. If @var{symbol} is not already bound, initialize it to @var{value}. --- 447,453 ---- Use @code{defcustom} to declare user editable variables. ! @defun defcustom symbol value doc [keyword value]... Declare @var{symbol} as a customizable variable that defaults to @var{value}. Neither @var{symbol} nor @var{value} needs to be quoted. If @var{symbol} is not already bound, initialize it to @var{value}. *************** *** 192,204 **** @table @code @item :type ! @var{value} should be a sexp widget. @item :group @var{value} should be a customization group. Add @var{symbol} to that group. @end table ! @xref{Sexp Types,,widget,The Widget Library}, for information about widgets to use together with the @code{:type} keyword. @end defun --- 458,473 ---- @table @code @item :type ! @var{value} should be a widget type. ! @item :options ! @var{value} should be a list of possible members of the specified type. ! For hooks, this is a list of function names. @item :group @var{value} should be a customization group. Add @var{symbol} to that group. @end table ! @xref{Sexp Types,,,widget,The Widget Library}, for information about widgets to use together with the @code{:type} keyword. @end defun *************** *** 215,221 **** Faces are declared with @code{defface}. ! @defun defface FACE SPEC [KEYWORD VALUE]... DOC Declare @var{face} as a customizable face that defaults to @var{spec}. @var{face} does not need to be quoted. --- 484,490 ---- Faces are declared with @code{defface}. ! @defun defface face spec doc [keyword value]... Declare @var{face} as a customizable face that defaults to @var{spec}. @var{face} does not need to be quoted. *************** *** 287,298 **** @itemize @bullet @item ! The names of the menu items for the @code{custom-variable}, ! @code{custom-face}, and @code{custom-group} tags should be rethought. ! Some of the actions may be better placed as buttons in the buffer. ! ! @item ! The menu items above should be grayed out when the information is missing. I.e. if a variable doesn't have a factory setting, the user should not be allowed to select the @samp{Factory} menu item. --- 556,562 ---- @itemize @bullet @item ! The menu items should be grayed out when the information is missing. I.e. if a variable doesn't have a factory setting, the user should not be allowed to select the @samp{Factory} menu item. *************** *** 301,317 **** customize buffer. @item - There should be buttons that will apply, set, reset, etc. all the relevant - widgets in a customize buffer. - - @item - There should be a menu in the customize buffer. - - @item - The group widget should allow you to apply, set, reset, etc. all the - relevant members of the group. - - @item There should be a function to create a customize menu from a group. @item --- 565,570 ---- *************** *** 326,353 **** Support real specifiers under XEmacs. @item ! @code{customize-apropos} should only match user options that has either ! been declared with this library, or variables whose documentation start ! with @samp{*}. With an prefix argument, also match all variables that ! has a documentation string. ! ! @item ! If there is only one line of documentation, the @samp{Documentation} ! tag-menu items should go from `first line only' to `none' without going ! over `full'. I.e. it should have two states instead of three. ! ! @item ! @code{custom-face} should display the @code{face-documentation} ! property. @item ! @code{custom-face}, @code{custom-variable}, and @code{custom-group} ! should be derived from a common @code{custom} widget. @item ! Integrate with @file{w3} so you can customization buffers with much ! better formatting. I'm thinking about adding a name ! tag. @end itemize --- 579,593 ---- Support real specifiers under XEmacs. @item ! Integrate with @file{w3} so you can customization buffers with much ! better formatting. I'm thinking about adding a name ! tag. @item ! Try to keep track of whether it is necessary to save or not. @item ! Offer to save if you exit emacs with unsaved customizations. @end itemize *** pub/rgnus/texi/gnus.texi Thu Oct 17 02:42:52 1996 --- rgnus/texi/gnus.texi Wed Oct 30 00:05:37 1996 *************** *** 1,7 **** \input texinfo @c -*-texinfo-*- @setfilename gnus ! @settitle Red Gnus 0.52 Manual @synindex fn cp @synindex vr cp @synindex pg cp --- 1,7 ---- \input texinfo @c -*-texinfo-*- @setfilename gnus ! @settitle Red Gnus 0.53 Manual @synindex fn cp @synindex vr cp @synindex pg cp *************** *** 287,293 **** @tex @titlepage ! @title Red Gnus 0.52 Manual @author by Lars Magne Ingebrigtsen @page --- 287,293 ---- @tex @titlepage ! @title Red Gnus 0.53 Manual @author by Lars Magne Ingebrigtsen @page *************** *** 961,972 **** @item gnus-inhibit-startup-message @vindex gnus-inhibit-startup-message If non-@code{nil}, the startup message won't be displayed. That way, ! your boss might not notice as easily that you are reading news instead of doing ! your job. @item gnus-no-groups-message @vindex gnus-no-groups-message Message displayed by Gnus when no groups are available. @end table --- 961,983 ---- @item gnus-inhibit-startup-message @vindex gnus-inhibit-startup-message If non-@code{nil}, the startup message won't be displayed. That way, ! your boss might not notice as easily that you are reading news instead ! of doing your job. Note that this variable is used before ! @file{.gnus.el} is loaded, so it should be set in @code{.emacs} instead. @item gnus-no-groups-message @vindex gnus-no-groups-message Message displayed by Gnus when no groups are available. + + @item gnus-play-startup-jingle + @vindex gnus-play-startup-jingle + If non-@code{nil}, play the Gnus jingle at startup. + + @item gnus-startup-jingle + @vindex gnus-startup-jingle + Jingle to be played if the above variable is non-@code{nil}. The + default is @samp{Tuxedomoon.Jingle4.au}. + @end table *************** *** 3521,3527 **** @kindex S o m (Summary) @findex gnus-summary-mail-forward Forward the current article to some other person ! (@code{gnus-summary-mail-forward}). @item S m @itemx m --- 3532,3539 ---- @kindex S o m (Summary) @findex gnus-summary-mail-forward Forward the current article to some other person ! (@code{gnus-summary-mail-forward}). If given a prefix, include the full ! headers of the forwarded article. @item S m @itemx m *************** *** 3623,3629 **** @kindex S o p (Summary) @findex gnus-summary-post-forward Forward the current article to a newsgroup ! (@code{gnus-summary-post-forward}). @item S O p @kindex S O p (Summary) --- 3635,3642 ---- @kindex S o p (Summary) @findex gnus-summary-post-forward Forward the current article to a newsgroup ! (@code{gnus-summary-post-forward}). If given a prefix, include the full ! headers of the forwarded article. @item S O p @kindex S O p (Summary) *************** *** 4938,4943 **** --- 4951,4962 ---- Save the current article in plain file format (@code{gnus-summary-save-article-file}). + @item O F + @kindex O F (Summary) + @findex gnus-summary-write-article-file + Write the current article in plain file format, overwriting any previous + file contents (@code{gnus-summary-write-article-file}). + @item O b @kindex O b (Summary) @findex gnus-summary-save-article-body-file *************** *** 8577,8583 **** ;; People... (any "larsi@@ifi\\.uio\\.no" "people.Lars Magne Ingebrigtsen")) ;; Unmatched mail goes to the catch all group. ! "misc.misc"))") @end lisp This variable has the format of a @dfn{split}. A split is a (possibly) --- 8596,8602 ---- ;; People... (any "larsi@@ifi\\.uio\\.no" "people.Lars Magne Ingebrigtsen")) ;; Unmatched mail goes to the catch all group. ! "misc.misc") @end lisp This variable has the format of a @dfn{split}. A split is a (possibly) *************** *** 10154,10159 **** --- 10173,10179 ---- * Reverse Scoring:: That problem child of old is not problem. * Global Score Files:: Earth-spanning, ear-splitting score files. * Kill Files:: They are still here, but they can be ignored. + * Converting Kill Files:: Translating kill files to score files. * GroupLens:: Getting predictions on what you like to read. * Advanced Scoring:: Using logical expressions to build score rules. * Score Decays:: It can be useful to let scores wither away. *************** *** 11356,11361 **** --- 11376,11401 ---- @end table + @node Converting Kill Files + @section Converting Kill Files + @cindex kill files + @cindex converting kill files + + If you have loads of old kill files, you may want to convert them into + score files. If they are ``regular'', you can use + the @file{gnus-kill-to-score.el} package; if not, you'll have to do it + by hand. + + The kill to score conversion package isn't included in Gnus by default. + You can fetch it from + @file{http://www.ifi.uio.no/~larsi/ding-other/gnus-kill-to-score}. + + If your old kill files are very complex---if they contain more + non-@code{gnus-kill} forms than not, you'll have to convert them by + hand. Or just let them be as they are. Gnus will still use them as + before. + + @node GroupLens @section GroupLens @cindex GroupLens *************** *** 13166,13171 **** --- 13206,13218 ---- On July 28th 1996 work on Red Gnus was begun. + If you happen upon a version of Gnus that has a name that is prefixed -- + ``(ding) Gnus'', ``September Gnus'', ``Red Gnus'', ``Mamey Sapote Gnus'' + -- don't panic. Don't let it know that you're frightened. Back away. + Slowly. Whatever you do, don't run. Walk away, calmly, until you're + out of its reach. Find a proper released version of Gnus and snuggle up + to that instead. + @menu * Why?:: What's the point of Gnus? * Compatibility:: Just how compatible is Gnus with @sc{gnus}? *************** *** 13406,13411 **** --- 13453,13461 ---- @item Luis Fernandes---design and graphics. + @item + Erik Naggum---help, ideas, support, code and stuff. + @item Wes Hardaker---@file{gnus-picon.el} and the manual section on @dfn{picons} (@pxref{Picons}). *************** *** 13476,13491 **** Marc Auslander, Mark Borges, Lance A. Brown, Martin Buchholz, Alastair Burt, Joao Cachopo, Massimo Campostrini, ! Michael Cook, Glenn Coombs, Frank D. Cringle, Geoffrey T. Dairiki, Ulrik Dickow, Dave Disser, Paul Eggert, Michael Ernst, Luc Van Eycken, --- 13526,13544 ---- Marc Auslander, Mark Borges, Lance A. Brown, + Kees de Bruin, Martin Buchholz, + Kevin Buhr, Alastair Burt, Joao Cachopo, Massimo Campostrini, ! Michael R. Cook, Glenn Coombs, Frank D. Cringle, Geoffrey T. Dairiki, Ulrik Dickow, Dave Disser, + Joev Dubach, Paul Eggert, Michael Ernst, Luc Van Eycken, *************** *** 13499,13518 **** --- 13552,13579 ---- Ishikawa Ichiro, @c Ishikawa Francois Felix Ingrand, Lee Iverson, + Randell Jesup, Fred Johansen, Thor Kristoffersen, Jens Lautenbacher, + Carsten Leonhardt, Christian Limpach, + Tonny Madsen, + Shlomo Mahlab, Nat Makarevitch, Timo Metzemakers, Richard Mlynarik, + David Moore, Lantz Moore, Morioka Tomohiko, @c Morioka Hrvoje Niksic, Andy Norman, + Alexandre Oliva, Ken Olstad, Masaharu Onishi, @c Onishi Hideki Ono, @c Ono + William Perry, + Stephen Peters, Ulrich Pfeifer, Colin Rafferty, Bart Robinson, *************** *** 13549,13555 **** @menu * ding Gnus:: New things in Gnus 5.0/5.1, the first new Gnus. * September Gnus:: The Thing Formally Known As Gnus 5.3/5.3. ! * Red Gnus:: The future. @end menu These lists are, of course, just @emph{short} overviews of the --- 13610,13616 ---- @menu * ding Gnus:: New things in Gnus 5.0/5.1, the first new Gnus. * September Gnus:: The Thing Formally Known As Gnus 5.3/5.3. ! * Red Gnus:: The future---Gnus 5.4/5.5. @end menu These lists are, of course, just @emph{short} overviews of the *** pub/rgnus/texi/message.texi Mon Sep 30 23:42:48 1996 --- rgnus/texi/message.texi Tue Oct 29 17:20:15 1996 *************** *** 886,891 **** --- 886,899 ---- @vindex message-send-hook Hook run before sending messages. + @item message-send-mail-hook + @vindex message-send-mail-hook + Hook run before sending mail messages. + + @item message-send-news-hook + @vindex message-send-news-hook + Hook run before sending news messages. + @item message-sent-hook @vindex message-sent-hook Hook run after sending messages. *** pub/rgnus/texi/widget.texi Tue Sep 17 03:16:52 1996 --- rgnus/texi/widget.texi Tue Oct 29 17:41:57 1996 *************** *** 1,9 **** \input texinfo.tex ! @c $Id: widget.texi,v 1.9 1996/09/16 22:57:14 abraham Exp $ @c %**start of header ! @setfilename widget.info @settitle The Emacs Widget Library @iftex @afourpaper --- 1,9 ---- \input texinfo.tex ! @c $Id: widget.texi,v 1.23 1996/10/29 12:36:26 abraham Exp $ @c %**start of header ! @setfilename widget @settitle The Emacs Widget Library @iftex @afourpaper *************** *** 15,21 **** @comment node-name, next, previous, up @top The Emacs Widget Library ! Version: 0.9 @menu * Introduction:: --- 15,21 ---- @comment node-name, next, previous, up @top The Emacs Widget Library ! Version: 0.995 @menu * Introduction:: *************** *** 47,67 **** @item link Areas of text with an associated action. Intended for hypertext links embedded in text. ! @item push Like link, but intended for stand-alone buttons. ! @item field An editable text field. It can be either variable or fixed length. ! @item choice Allows the user to choose one of multiple options from a menu, each option is itself a widget. Only the selected option will be visible in the buffer. ! @item radio Allows the user to choose one of multiple options by pushing radio buttons. The options are implemented as widgets. All options will be visible in the buffer. @item item ! A simple constant widget intended to be used in the @code{choice} and ! @code{radio} widgets. @item choice-item An button item only intended for use in choices. When pushed, the user will be asked to select another option from the choice widget. --- 47,67 ---- @item link Areas of text with an associated action. Intended for hypertext links embedded in text. ! @item push-button Like link, but intended for stand-alone buttons. ! @item editable-field An editable text field. It can be either variable or fixed length. ! @item menu-choice Allows the user to choose one of multiple options from a menu, each option is itself a widget. Only the selected option will be visible in the buffer. ! @item radio-button-choice Allows the user to choose one of multiple options by pushing radio buttons. The options are implemented as widgets. All options will be visible in the buffer. @item item ! A simple constant widget intended to be used in the @code{menu-choice} and ! @code{radio-button-choice} widgets. @item choice-item An button item only intended for use in choices. When pushed, the user will be asked to select another option from the choice widget. *************** *** 69,75 **** A simple @samp{on}/@samp{off} switch. @item checkbox A checkbox (@samp{[ ]}/@samp{[X]}). ! @item repeat Create an editable list. The user can insert or delete items in the list. Each list item is itself a widget. @end table --- 69,75 ---- A simple @samp{on}/@samp{off} switch. @item checkbox A checkbox (@samp{[ ]}/@samp{[X]}). ! @item editable-list Create an editable list. The user can insert or delete items in the list. Each list item is itself a widget. @end table *************** *** 178,184 **** For example, capitalizing all text from the middle of one field to the middle of another field is prohibited. ! Editing text fields are created by the @code{field} widget. The editing text fields are highlighted with the @code{widget-field-face} face, making them easy to find. --- 178,184 ---- For example, capitalizing all text from the middle of one field to the middle of another field is prohibited. ! Editing text fields are created by the @code{editable-field} widget. The editing text fields are highlighted with the @code{widget-field-face} face, making them easy to find. *************** *** 217,227 **** @item The Option Field Tags. When you activate one of these buttons, you will be asked to choose between a number of different options. This is how you edit an option ! field. Option fields are created by the @code{choice} widget. In the example, @samp{@b{Choose}} is an option field tag. @item The @samp{@b{[INS]}} and @samp{@b{[DEL]}} buttons. Activating these will insert or delete elements from a editable list. ! The list is created by the @code{repeat} widget. @item Embedded Buttons. The @samp{@b{_other work_}} is an example of an embedded button. Embedded buttons are not associated with a fields, but can serve --- 217,227 ---- @item The Option Field Tags. When you activate one of these buttons, you will be asked to choose between a number of different options. This is how you edit an option ! field. Option fields are created by the @code{menu-choice} widget. In the example, @samp{@b{Choose}} is an option field tag. @item The @samp{@b{[INS]}} and @samp{@b{[DEL]}} buttons. Activating these will insert or delete elements from a editable list. ! The list is created by the @code{editable-list} widget. @item Embedded Buttons. The @samp{@b{_other work_}} is an example of an embedded button. Embedded buttons are not associated with a fields, but can serve *************** *** 231,241 **** Activating one of these will convert it to the other. This is useful for implementing multiple-choice fields. You can create it wit @item The @samp{@b{( )}} and @samp{@b{(*)}} buttons. ! Only one radio button in a @code{radio} widget can be selected at any time. When you push one of the unselected radio buttons, it will be selected and the previous selected radio button will become unselected. @item The @samp{@b{[Apply Form]}} @samp{@b{[Reset Form]}} buttons. ! These are explicit buttons made with the @code{push} widget. The main difference from the @code{link} widget is that the buttons are intended to be displayed more like buttons in a GUI, once Emacs grows powerful enough. --- 231,241 ---- Activating one of these will convert it to the other. This is useful for implementing multiple-choice fields. You can create it wit @item The @samp{@b{( )}} and @samp{@b{(*)}} buttons. ! Only one radio button in a @code{radio-button-choice} widget can be selected at any time. When you push one of the unselected radio buttons, it will be selected and the previous selected radio button will become unselected. @item The @samp{@b{[Apply Form]}} @samp{@b{[Reset Form]}} buttons. ! These are explicit buttons made with the @code{push-button} widget. The main difference from the @code{link} widget is that the buttons are intended to be displayed more like buttons in a GUI, once Emacs grows powerful enough. *************** *** 277,282 **** --- 277,285 ---- @lisp (require 'widget) + (eval-when-compile + (require 'widget-edit)) + (defvar widget-example-repeat) (defun widget-example () *************** *** 288,297 **** (let ((inhibit-read-only t)) (erase-buffer)) (widget-insert "Here is some documentation.\n\nName: ") ! (widget-create 'field :size 13 "My Name") ! (widget-create 'choice :tag "Choose" :value "This" :help-echo "Choose me, please!" --- 291,300 ---- (let ((inhibit-read-only t)) (erase-buffer)) (widget-insert "Here is some documentation.\n\nName: ") ! (widget-create 'editable-field :size 13 "My Name") ! (widget-create 'menu-choice :tag "Choose" :value "This" :help-echo "Choose me, please!" *************** *** 300,308 **** (widget-value widget))) '(item :tag "This option" :value "This") '(choice-item "That option") ! '(field :menu-tag "No option" "Thus option")) (widget-insert "Address: ") ! (widget-create 'field "Some Place\nIn some City\nSome country.") (widget-insert "\nSee also ") (widget-create 'link --- 303,311 ---- (widget-value widget))) '(item :tag "This option" :value "This") '(choice-item "That option") ! '(editable-field :menu-tag "No option" "Thus option")) (widget-insert "Address: ") ! (widget-create 'editable-field "Some Place\nIn some City\nSome country.") (widget-insert "\nSee also ") (widget-create 'link *************** *** 313,319 **** "other work") (widget-insert " for more information.\n\nNumbers: count to three below\n") (setq widget-example-repeat ! (widget-create 'repeat :entry-format "%i %d %v" :notify (lambda (widget &rest ignore) (let ((old (widget-get widget --- 316,322 ---- "other work") (widget-insert " for more information.\n\nNumbers: count to three below\n") (setq widget-example-repeat ! (widget-create 'editable-list :entry-format "%i %d %v" :notify (lambda (widget &rest ignore) (let ((old (widget-get widget *************** *** 323,329 **** (widget-put widget ':example-length new) (message "You can count to %d." new)))) :value '("One" "Eh, two?" "Five!") ! '(field :value "three"))) (widget-insert "\n\nSelect multiple:\n\n") (widget-create 'checkbox t) (widget-insert " This\n") --- 326,332 ---- (widget-put widget ':example-length new) (message "You can count to %d." new)))) :value '("One" "Eh, two?" "Five!") ! '(editable-field :value "three"))) (widget-insert "\n\nSelect multiple:\n\n") (widget-create 'checkbox t) (widget-insert " This\n") *************** *** 333,345 **** :notify (lambda (&rest ignore) (message "Tickle")) t) (widget-insert " Thus\n\nSelect one:\n\n") ! (widget-create 'radio :value "One" :notify (lambda (widget &rest ignore) ! (message "You selected %s" (widget-value widget))) '(item "One") '(item "Anthor One.") '(item "A Final One.")) (widget-insert "\n") ! (widget-create 'push :notify (lambda (&rest ignore) (if (= (length (widget-value widget-example-repeat)) 3) --- 336,349 ---- :notify (lambda (&rest ignore) (message "Tickle")) t) (widget-insert " Thus\n\nSelect one:\n\n") ! (widget-create 'radio-button-choice :value "One" :notify (lambda (widget &rest ignore) ! (message "You selected %s" ! (widget-value widget))) '(item "One") '(item "Anthor One.") '(item "A Final One.")) (widget-insert "\n") ! (widget-create 'push-button :notify (lambda (&rest ignore) (if (= (length (widget-value widget-example-repeat)) 3) *************** *** 347,353 **** (error "Three was the count!"))) "Apply Form") (widget-insert " ") ! (widget-create 'push :notify (lambda (&rest ignore) (widget-example)) "Reset Form") --- 351,357 ---- (error "Three was the count!"))) "Apply Form") (widget-insert " ") ! (widget-create 'push-button :notify (lambda (&rest ignore) (widget-example)) "Reset Form") *************** *** 446,451 **** --- 450,464 ---- @item %d Insert the string specified by @code{:doc} here. + @item %h + Like @samp{%d}, with the following modifications: If the documentation + string is more than one line, it will add a button which will toggle + between showing only the first line, and showing the full text. + Furthermore, if there is no @code{:doc} property in the widget, it will + instead examine the @code{:documentation-property} property. If it is a + lambda expression, it will be called with the widget's value as an + argument, and the result will be used as the documentation text. + @item %t Insert the string specified by @code{:tag} here, or the @code{princ} representation of the value if there is no tag. *************** *** 469,474 **** --- 482,499 ---- Message displayed whenever you move to the widget with either @code{widget-forward} or @code{widget-backward}. + @item :indent + An integer indicating the absolute number of spaces to indent children + of this widget. + + @item :offset + An integer indicating how many extra spaces to add to the widget's + grandchildren compared to this widget. + + @item :extra-offset + An integer indicating how many extra spaces to add to the widget's + children compared to this widget. + @item :notify A function called each time the widget or a nested widget is changed. The function is called with two or three arguments. The first argument *************** *** 478,488 **** @item :menu-tag Tag used in the menu when the widget is used as an option in a ! @code{choice} widget. @item :menu-tag-get Function used for finding the tag when the widget is used as an option ! in a @code{choice} widget. By default, the tag used will be either the @code{:menu-tag} or @code{:tag} property if present, or the @code{princ} representation of the @code{:value} property if not. --- 503,513 ---- @item :menu-tag Tag used in the menu when the widget is used as an option in a ! @code{menu-choice} widget. @item :menu-tag-get Function used for finding the tag when the widget is used as an option ! in a @code{menu-choice} widget. By default, the tag used will be either the @code{:menu-tag} or @code{:tag} property if present, or the @code{princ} representation of the @code{:value} property if not. *************** *** 497,522 **** @code{:error} property to a string explaining the error. @item :parent ! The parent of a nested widget (e.g. a @code{choice} item or an element of a ! @code{repeat} widget). @end table @menu * link:: ! * push:: ! * field:: * text:: ! * choice:: ! * radio:: * item:: * choice-item:: * toggle:: * checkbox:: * checklist:: ! * repeat:: @end menu ! @node link, push, Basic Types, Basic Types @comment node-name, next, previous, up @subsection The @code{link} Widget --- 522,547 ---- @code{:error} property to a string explaining the error. @item :parent ! The parent of a nested widget (e.g. a @code{menu-choice} item or an element of a ! @code{editable-list} widget). @end table @menu * link:: ! * push-button:: ! * editable-field:: * text:: ! * menu-choice:: ! * radio-button-choice:: * item:: * choice-item:: * toggle:: * checkbox:: * checklist:: ! * editable-list:: @end menu ! @node link, push-button, Basic Types, Basic Types @comment node-name, next, previous, up @subsection The @code{link} Widget *************** *** 530,557 **** property. The value should be a string, which will be inserted in the buffer. ! @node push, field, link, Basic Types @comment node-name, next, previous, up ! @subsection The @code{push} Widget Syntax: @example ! TYPE ::= (push [KEYWORD ARGUMENT]... [ VALUE ]) @end example The @var{value}, if present, is used to initialize the @code{:value} property. The value should be a string, which will be inserted in the buffer. ! @node field, text, push, Basic Types @comment node-name, next, previous, up ! @subsection The @code{field} Widget Syntax: @example ! TYPE ::= (field [KEYWORD ARGUMENT]... [ VALUE ]) @end example The @var{value}, if present, is used to initialize the @code{:value} --- 555,582 ---- property. The value should be a string, which will be inserted in the buffer. ! @node push-button, editable-field, link, Basic Types @comment node-name, next, previous, up ! @subsection The @code{push-button} Widget Syntax: @example ! TYPE ::= (push-button [KEYWORD ARGUMENT]... [ VALUE ]) @end example The @var{value}, if present, is used to initialize the @code{:value} property. The value should be a string, which will be inserted in the buffer. ! @node editable-field, text, push-button, Basic Types @comment node-name, next, previous, up ! @subsection The @code{editable-field} Widget Syntax: @example ! TYPE ::= (editable-field [KEYWORD ARGUMENT]... [ VALUE ]) @end example The @var{value}, if present, is used to initialize the @code{:value} *************** *** 571,596 **** @item :keymap Keymap used in the editable field. @code{widget-keymap} will allow you ! to use normal editing commands, even if these has been supressed in the current buffer. @end table ! @node text, choice, field, Basic Types @comment node-name, next, previous, up @subsection The @code{text} Widget ! This is just like @code{field}, but intended for multiline text fields. ! @node choice, radio, text, Basic Types @comment node-name, next, previous, up ! @subsection The @code{choice} Widget Syntax: @example ! TYPE ::= (choice [KEYWORD ARGUMENT]... TYPE ... ) @end example The @var{type} arguments represents each possible choice. The widgets --- 596,642 ---- @item :keymap Keymap used in the editable field. @code{widget-keymap} will allow you ! to use normal editing commands, even if these has been suppressed in the current buffer. + @item :hide-front-space + @itemx :hide-rear-space + In order to keep track of the editable field, emacs places an invisible + space character in front of the field, and for fixed sized fields also + in the rear end of the field. For fields that extent to the end of the + line, the terminating linefeed serves that purpose instead. + + Emacs will try to make the spaces intangible when it is safe to do so. + Intangible means that the cursor motion commands will skip over the + character as if it didn't exist. This is safe to do when the text + preceding or following the widget cannot possible change during the + lifetime of the @code{editable-field} widget. The preferred way to tell + Emacs this, is to add text to the @code{:format} property around the + value. For example @code{:format "Tag: %v "}. + + You can overwrite the internal safety check by setting the + @code{:hide-front-space} or @code{:hide-rear-space} properties to + non-nil. This is not recommended. For example, @emph{all} text that + belongs to a widget (i.e. is created from its @code{:format} string) will + change whenever the widget changes its value. + @end table ! @node text, menu-choice, editable-field, Basic Types @comment node-name, next, previous, up @subsection The @code{text} Widget ! This is just like @code{editable-field}, but intended for multiline text fields. ! @node menu-choice, radio-button-choice, text, Basic Types @comment node-name, next, previous, up ! @subsection The @code{menu-choice} Widget Syntax: @example ! TYPE ::= (menu-choice [KEYWORD ARGUMENT]... TYPE ... ) @end example The @var{type} arguments represents each possible choice. The widgets *************** *** 603,608 **** --- 649,658 ---- Widget type used as a fallback when the value does not match any of the specified @var{type} arguments. + @item :case-fold + Set this to nil if you don't want to ignore case when prompting for a + choice through the minibuffer. + @item :children A list whose car is the widget representing the currently chosen type in the buffer. *************** *** 614,627 **** The list of types. @end table ! @node radio, item, choice, Basic Types @comment node-name, next, previous, up ! @subsection The @code{radio} Widget Syntax: @example ! TYPE ::= (radio [KEYWORD ARGUMENT]... TYPE ... ) @end example The @var{type} arguments represents each possible choice. The widgets --- 664,677 ---- The list of types. @end table ! @node radio-button-choice, item, menu-choice, Basic Types @comment node-name, next, previous, up ! @subsection The @code{radio-button-choice} Widget Syntax: @example ! TYPE ::= (radio-button-choice [KEYWORD ARGUMENT]... TYPE ... ) @end example The @var{type} arguments represents each possible choice. The widgets *************** *** 657,674 **** The list of types. @end table ! You can add extra radio button items to a radio widget after it has been ! created with the function `widget-radio-add-item'. @defun widget-radio-add-item widget type ! Add to radio widget @var{widget} a new radio button item of type @var{type}. @end defun ! Please note that such items added after the radio widget has been ! created will @strong{not} be properly destructed when you call ! @code{widget-delete}. ! @node item, choice-item, radio, Basic Types @comment node-name, next, previous, up @subsection The @code{item} Widget --- 707,726 ---- The list of types. @end table ! You can add extra radio button items to a @code{radio-button-choice} ! widget after it has been created with the function ! @code{widget-radio-add-item}. @defun widget-radio-add-item widget type ! Add to @code{radio-button-choice} widget @var{widget} a new radio button item of type ! @var{type}. @end defun ! Please note that such items added after the @code{radio-button-choice} ! widget has been created will @strong{not} be properly destructed when ! you call @code{widget-delete}. ! @node item, choice-item, radio-button-choice, Basic Types @comment node-name, next, previous, up @subsection The @code{item} Widget *************** *** 739,745 **** TYPE ::= (checkbox [KEYWORD ARGUMENT]...) @end example ! @node checklist, repeat, checkbox, Basic Types @comment node-name, next, previous, up @subsection The @code{checklist} Widget --- 791,797 ---- TYPE ::= (checkbox [KEYWORD ARGUMENT]...) @end example ! @node checklist, editable-list, checkbox, Basic Types @comment node-name, next, previous, up @subsection The @code{checklist} Widget *************** *** 779,792 **** The list of types. @end table ! @node repeat, , checklist, Basic Types @comment node-name, next, previous, up ! @subsection The @code{repeat} Widget Syntax: @example ! TYPE ::= ([KEYWORD ARGUMENT]... TYPE) @end example The value is a list, where each member represent one widget of type --- 831,844 ---- The list of types. @end table ! @node editable-list, , checklist, Basic Types @comment node-name, next, previous, up ! @subsection The @code{editable-list} Widget Syntax: @example ! TYPE ::= (editable-list [KEYWORD ARGUMENT]... TYPE) @end example The value is a list, where each member represent one widget of type *************** *** 795,804 **** The following extra properties are recognized. @table @code - @item :indent - Number of spaces inserted before each member of the list, except for the - first. - @item :entry-format This string will be inserted for each entry in the list. The following @samp{%} escapes are available: --- 847,852 ---- *************** *** 867,873 **** field. The @code{sexp} widget takes the same keyword arguments as the ! @code{field} widget. @end deffn @node atoms, composite, generic, Sexp Types --- 915,921 ---- field. The @code{sexp} widget takes the same keyword arguments as the ! @code{editable-field} widget. @end deffn @node atoms, composite, generic, Sexp Types *************** *** 888,894 **** property and must be an expression of the same type as the widget. I.e. the string widget can only be initialized with a string. ! All the atom widgets take the same keyword arguments as the @code{field} widget. @deffn Widget string --- 936,942 ---- property and must be an expression of the same type as the widget. I.e. the string widget can only be initialized with a string. ! All the atom widgets take the same keyword arguments as the @code{editable-field} widget. @deffn Widget string *************** *** 925,930 **** --- 973,984 ---- Allows you to edit a number in an editable field. @end deffn + @deffn Widget boolean + Allows you to edit a boolean. In lisp this means a variable which is + either nil meaning false, or non-nil meaning true. + @end deffn + + @node composite, , atoms, Sexp Types @comment node-name, next, previous, up @subsection Composite Sexp Widgets. *************** *** 941,968 **** @deffn Widget cons The value of a @code{cons} widget is a cons-cell where the car is the value of the first component and the cdr is the value of the second ! coponent. There must be exactly two components. @end deffn @deffn Widget lisp ! The value of a @code{cons} widget is a list containing the value of each of its component. @end deffn @deffn Widget vector ! The value of a @code{cons} widget is a vector containing the value of each of its component. @end deffn The above suffice for specifying fixed size lists and vectors. To get variable length lists and vectors, you can use a @code{choice}, ! @code{radio}, @code{checklist} or @code{repeat} widget together with the ! @code{:inline} keyword. If any component of a composite widget has the ! @code{:inline} keyword set, its value must be a list which will then be ! spliced into the composite. For example, to specify a list whose first ! element must be a file name, and whose remaining arguments should either ! by the symbol @code{t} or two files, you can use the following widget ! specification: @example (list file --- 995,1022 ---- @deffn Widget cons The value of a @code{cons} widget is a cons-cell where the car is the value of the first component and the cdr is the value of the second ! component. There must be exactly two components. @end deffn @deffn Widget lisp ! The value of a @code{lisp} widget is a list containing the value of each of its component. @end deffn @deffn Widget vector ! The value of a @code{vector} widget is a vector containing the value of each of its component. @end deffn The above suffice for specifying fixed size lists and vectors. To get variable length lists and vectors, you can use a @code{choice}, ! @code{set} or @code{repeat} widgets together with the @code{:inline} ! keywords. If any component of a composite widget has the @code{:inline} ! keyword set, its value must be a list which will then be spliced into ! the composite. For example, to specify a list whose first element must ! be a file name, and whose remaining arguments should either by the ! symbol @code{t} or two files, you can use the following widget ! specification: @example (list file *************** *** 979,984 **** --- 1033,1057 ---- hard to implement so instead of confuse you more by trying to explain it here, I'll just suggest you meditate over it for a while. + @deffn Widget choice + Allows you to edit a sexp which may have one of fixed set of types. It + is currently implemented with the @code{choice-menu} basic widget, and + has a similar syntax. + @end deffn + + @deffn Widget set + Allows you to specify a type which must be a list whose elements all + belong to given set. The elements of the list is not significant. This + is implemented on top of the @code{checklist} basic widget, and has a + similar syntax. + @end deffn + + @deffn Widget repeat + Allows you to specify a variable length list whose members are all of + the same type. Implemented on top of the `editable-list' basic widget, + and has a similar syntax. + @end deffn + @node Widget Properties, Defining New Widgets, Sexp Types, Top @comment node-name, next, previous, up @section Properties *************** *** 1111,1116 **** --- 1184,1193 ---- Function to handle unknown @samp{%} escapes in the format string. It will be called with the widget and the escape character as arguments. You can set this to allow your widget to handle non-standard escapes. + + You should end up calling @code{widget-default-format-handler} to handle + unknown escape sequences, which will handle the @samp{%h} and any future + escape sequences, as well as give an error for unknown escapes. @end table If you want to define a new widget from scratch, use the @code{default} *************** *** 1119,1125 **** @deffn Widget default [ keyword argument ] Widget used as a base for other widgets. ! It provides most of the functionality that is refered to as ``by default'' in this text. @end deffn --- 1196,1202 ---- @deffn Widget default [ keyword argument ] Widget used as a base for other widgets. ! It provides most of the functionality that is referred to as ``by default'' in this text. @end deffn *************** *** 1158,1180 **** equivalents. @item - There should be a way to probe a widget to see if the user has modified - it. - - @item - The support for indentation of component widgets should be finished. - - @item There should be support for browsing the widget documentation. @item There should be a way to specify that @key{RET} in a field will call the @code{:activate} function. This should be used by widgets such as ! @code{file} and @code{symbol} prompt with completion. This way, we ! could also get rid of the default tag for the @code{file} widget. @item ! The @code{choice} tag should be prettier, something like the abbreviated menus in Open Look. @item --- 1235,1249 ---- equivalents. @item There should be support for browsing the widget documentation. @item There should be a way to specify that @key{RET} in a field will call the @code{:activate} function. This should be used by widgets such as ! @code{file} and @code{symbol} prompt with completion. @item ! The @code{menu-choice} tag should be prettier, something like the abbreviated menus in Open Look. @item *************** *** 1183,1193 **** specific to the first widget where I used them. @item ! Unchecked items in a @code{radio} or @code{checklist} should be grayed ! out, and the subwidgets should somehow become inactive. This could ! perhaps be implemented by binding @code{widget-inactive} to t when inserting ! the grayed out subwidget, and let the widget-specify functions check ! that variable. @end itemize --- 1252,1262 ---- specific to the first widget where I used them. @item ! Unchecked items in a @code{radio-button-choice} or @code{checklist} ! should be grayed out, and the subwidgets should somehow become inactive. ! This could perhaps be implemented by binding @code{widget-inactive} to t ! when inserting the grayed out subwidget, and let the widget-specify ! functions check that variable. @end itemize *** pub/rgnus/texi/ChangeLog Fri Oct 11 12:52:48 1996 --- rgnus/texi/ChangeLog Tue Oct 29 17:20:15 1996 *************** *** 1,3 **** --- 1,29 ---- + Mon Oct 28 15:50:08 1996 Lars Magne Ingebrigtsen + + * gnus.texi (Startup Variables): Addition. + + Fri Oct 25 09:04:59 1996 Lars Magne Ingebrigtsen + + * gnus.texi (Summary Mail Commands): Addition. + + Wed Oct 23 08:28:29 1996 Hrvoje Niksic + + * gnus.texi (Fancy Mail Splitting): Removed trailing garbage. + + Tue Oct 22 07:36:02 1996 Lars Magne Ingebrigtsen + + * gnus.texi (Converting Kill Files): New. + + Sat Oct 19 07:17:28 1996 Lars Magne Ingebrigtsen + + * gnus.texi (Saving Articles): Addition. + + * message.texi (Various Message Variables): Addition. + + Thu Oct 17 06:53:04 1996 Lars Magne Ingebrigtsen + + * gnus.texi (Contributors): Added names. + Fri Oct 11 12:38:59 1996 Lars Magne Ingebrigtsen * gnus.texi (Adaptive Scoring): Addition.