* message.el (message-toggle-image-thumbnails): New command.
[gnus] / lisp / gnus-salt.el
index 21c556a..427bfbf 100644 (file)
@@ -1,7 +1,6 @@
 ;;; gnus-salt.el --- alternate summary mode interfaces for Gnus
 
-;; Copyright (C) 1996, 1997, 1998, 1999, 2001, 2002, 2003, 2004, 2005,
-;;   2006, 2007, 2008, 2009, 2010  Free Software Foundation, Inc.
+;; Copyright (C) 1996-1999, 2001-2015 Free Software Foundation, Inc.
 
 ;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org>
 ;; Keywords: news
@@ -101,6 +100,11 @@ It accepts the same format specs that `gnus-summary-line-format' does."
        ["Start reading" gnus-pick-start-reading t]
        ["Switch pick mode off" gnus-pick-mode gnus-pick-mode]))))
 
+(eval-when-compile
+  (when (featurep 'xemacs)
+    (defvar gnus-pick-mode-on-hook)
+    (defvar gnus-pick-mode-off-hook)))
+
 (define-minor-mode gnus-pick-mode
   "Minor mode for providing a pick-and-read interface in Gnus summary buffers.
 
@@ -288,22 +292,25 @@ This must be bound to a button-down mouse event."
                  (mouse-scroll-subr start-window
                                     (1+ (- mouse-row bottom)))))))))))
       (when (consp event)
-       (let ((fun (key-binding (vector (car event)))))
+       (let (;; (fun (key-binding (vector (car event))))
+              )
          ;; Run the binding of the terminating up-event, if possible.
-       ;; In the case of a multiple click, it gives the wrong results,
+          ;; In the case of a multiple click, it gives the wrong results,
          ;; because it would fail to set up a region.
          (when nil
-      ;; (and (= (mod mouse-selection-click-count 3) 0) (fboundp fun))
-       ;; In this case, we can just let the up-event execute normally.
+            ;; (and (= (mod mouse-selection-click-count 3) 0) (fboundp fun))
+            ;; In this case, we can just let the up-event execute normally.
            (let ((end (event-end event)))
              ;; Set the position in the event before we replay it,
              ;; because otherwise it may have a position in the wrong
              ;; buffer.
              (setcar (cdr end) end-of-range)
              ;; Delete the overlay before calling the function,
-            ;; because delete-overlay increases buffer-modified-tick.
+              ;; because delete-overlay increases buffer-modified-tick.
              (push event unread-command-events))))))))
 
+(defvar scroll-in-place)
+
 (defun gnus-pick-next-page ()
   "Go to the next page.  If at the end of the buffer, start reading articles."
   (interactive)
@@ -332,6 +339,11 @@ This must be bound to a button-down mouse event."
       '("Pick"
        ["Switch binary mode off" gnus-binary-mode t]))))
 
+(eval-when-compile
+  (when (featurep 'xemacs)
+    (defvar gnus-binary-mode-on-hook)
+    (defvar gnus-binary-mode-off-hook)))
+
 (define-minor-mode gnus-binary-mode
   "Minor mode for providing a binary group interface in Gnus summary buffers."
   :lighter " Binary" :keymap gnus-binary-mode-map
@@ -347,7 +359,7 @@ This must be bound to a button-down mouse event."
     (when (gnus-visual-p 'binary-menu 'menu)
       (gnus-binary-make-menu-bar)))))
 
-(defun gnus-binary-display-article (article &optional all-header)
+(defun gnus-binary-display-article (article &optional _all-header)
   "Run ARTICLE through the binary decode functions."
   (when (gnus-summary-goto-subject article)
     (let ((gnus-view-pseudos (or gnus-view-pseudos 'automatic)))
@@ -376,7 +388,7 @@ lines."
                 integer)
   :group 'gnus-summary-tree)
 
-(defcustom gnus-selected-tree-face 'modeline
+(defcustom gnus-selected-tree-face 'mode-line
   "*Face used for highlighting selected articles in the thread tree."
   :type 'face
   :group 'gnus-summary-tree)
@@ -414,6 +426,13 @@ Two predefined functions are available:
 
 ;;; Internal variables.
 
+(defvar gnus-tmp-name)
+(defvar gnus-tmp-from)
+(defvar gnus-tmp-number)
+(defvar gnus-tmp-open-bracket)
+(defvar gnus-tmp-close-bracket)
+(defvar gnus-tmp-subject)
+
 (defvar gnus-tree-line-format-alist
   `((?n gnus-tmp-name ?s)
     (?f gnus-tmp-from ?s)
@@ -433,23 +452,23 @@ Two predefined functions are available:
 (defvar gnus-tree-displayed-thread nil)
 (defvar gnus-tree-inhibit nil)
 
-(defvar gnus-tree-mode-map nil)
-(put 'gnus-tree-mode 'mode-class 'special)
+(defvar gnus-tree-mode-map
+  (let ((map (make-keymap)))
+    (suppress-keymap map)
+    (gnus-define-keys
+        map
+      "\r" gnus-tree-select-article
+      gnus-mouse-2 gnus-tree-pick-article
+      "\C-?" gnus-tree-read-summary-keys
+      "h" gnus-tree-show-summary
 
-(unless gnus-tree-mode-map
-  (setq gnus-tree-mode-map (make-keymap))
-  (suppress-keymap gnus-tree-mode-map)
-  (gnus-define-keys
-      gnus-tree-mode-map
-    "\r" gnus-tree-select-article
-    gnus-mouse-2 gnus-tree-pick-article
-    "\C-?" gnus-tree-read-summary-keys
-    "h" gnus-tree-show-summary
+      "\C-c\C-i" gnus-info-find-node)
 
-    "\C-c\C-i" gnus-info-find-node)
+    (substitute-key-definition
+     'undefined 'gnus-tree-read-summary-keys map)
+    map))
 
-  (substitute-key-definition
-   'undefined 'gnus-tree-read-summary-keys gnus-tree-mode-map))
+(put 'gnus-tree-mode 'mode-class 'special)
 
 (defun gnus-tree-make-menu-bar ()
   (unless (boundp 'gnus-tree-menu)
@@ -458,26 +477,20 @@ Two predefined functions are available:
       '("Tree"
        ["Select article" gnus-tree-select-article t]))))
 
-(defun gnus-tree-mode ()
+(define-derived-mode gnus-tree-mode fundamental-mode "Tree"
   "Major mode for displaying thread trees."
-  (interactive)
   (gnus-set-format 'tree-mode)
   (gnus-set-format 'tree t)
   (when (gnus-visual-p 'tree-menu 'menu)
     (gnus-tree-make-menu-bar))
-  (kill-all-local-variables)
   (gnus-simplify-mode-line)
-  (setq mode-name "Tree")
-  (setq major-mode 'gnus-tree-mode)
-  (use-local-map gnus-tree-mode-map)
   (buffer-disable-undo)
   (setq buffer-read-only t)
   (setq truncate-lines t)
-  (save-excursion
+  (save-current-buffer
     (gnus-set-work-buffer)
     (gnus-tree-node-insert (make-mail-header "") nil)
-    (setq gnus-tree-node-length (1- (point))))
-  (gnus-run-mode-hooks 'gnus-tree-mode-hook))
+    (setq gnus-tree-node-length (1- (point)))))
 
 (defun gnus-tree-read-summary-keys (&optional arg)
   "Read a summary buffer key sequence and execute it."
@@ -527,12 +540,6 @@ Two predefined functions are available:
     (when pos
       (cons pos (next-single-property-change pos 'gnus-number)))))
 
-(defun gnus-tree-goto-article (article)
-  (let ((pos (text-property-any
-             (point-min) (point-max) 'gnus-number article)))
-    (when pos
-      (goto-char pos))))
-
 (defun gnus-tree-recenter ()
   "Center point in the tree window."
   (let ((selected (selected-window))
@@ -559,7 +566,7 @@ Two predefined functions are available:
 (defun gnus-get-tree-buffer ()
   "Return the tree buffer properly initialized."
   (with-current-buffer (gnus-get-buffer-create gnus-tree-buffer)
-    (unless (eq major-mode 'gnus-tree-mode)
+    (unless (derived-mode-p 'gnus-tree-mode)
       (gnus-tree-mode))
     (current-buffer)))
 
@@ -568,7 +575,7 @@ Two predefined functions are available:
             (not (one-window-p)))
     (let ((windows 0)
          tot-win-height)
-      (walk-windows (lambda (window) (incf windows)))
+      (walk-windows (lambda (_window) (incf windows)))
       (setq tot-win-height
            (- (frame-height)
               (* window-min-height (1- windows))
@@ -639,24 +646,42 @@ Two predefined functions are available:
     (when (or t (gnus-visual-p 'tree-highlight 'highlight))
       (gnus-tree-highlight-node gnus-tmp-number beg end))))
 
+(defmacro gnus--let-eval (bindings evalsym &rest body)
+  "Build an environment in which to evaluate expressions.
+BINDINGS is a `let'-style list of bindings to use for the environment.
+EVALSYM is then bound in BODY to a function that takes a sexp and evaluates
+it in the environment specified by BINDINGS."
+  (declare (indent 2) (debug ((&rest (sym form)) sym body)))
+  (if (eval '(ignore-errors (let ((x 3)) (eq (eval '(- x 1) '((x . 4))) x))))
+      ;; Use lexical vars if possible.
+      `(let* ((env (list ,@(mapcar (lambda (binding)
+                                     `(cons ',(car binding) ,(cadr binding)))
+                                   bindings)))
+             (,evalsym (lambda (exp) (eval exp env))))
+         ,@body)
+    `(let (,@bindings (,evalsym #'eval)) ,@body)))
+
 (defun gnus-tree-highlight-node (article beg end)
   "Highlight current line according to `gnus-summary-highlight'."
   (let ((list gnus-summary-highlight)
        face)
     (with-current-buffer gnus-summary-buffer
-      (let* ((score (or (cdr (assq article gnus-newsgroup-scored))
+      (let ((uncached (memq article gnus-newsgroup-undownloaded)))
+        (gnus--let-eval
+            ((score (or (cdr (assq article gnus-newsgroup-scored))
                        gnus-summary-default-score 0))
             (default gnus-summary-default-score)
             (default-high gnus-summary-default-high-score)
             (default-low gnus-summary-default-low-score)
-             (uncached (memq article gnus-newsgroup-undownloaded))
+             (uncached uncached)
              (downloaded (not uncached))
             (mark (or (gnus-summary-article-mark article) gnus-unread-mark)))
-       ;; Eval the cars of the lists until we find a match.
-       (while (and list
-                   (not (eval (caar list))))
-         (setq list (cdr list)))))
-    (unless (eq (setq face (cdar list)) (get-text-property beg 'face))
+            evalfun
+          ;; Eval the cars of the lists until we find a match.
+          (while (and list
+                      (not (funcall evalfun (caar list))))
+            (setq list (cdr list))))))
+    (unless (eq (setq face (cdar list)) (gnus-get-text-property-excluding-characters-with-faces beg 'face))
       (gnus-put-text-property-excluding-characters-with-faces
        beg end 'face
        (if (boundp face) (symbol-value face) face)))))
@@ -811,10 +836,10 @@ Two predefined functions are available:
          (gnus-generate-tree top)
          (setq gnus-tree-displayed-thread top))))))
 
-(defun gnus-tree-open (group)
+(defun gnus-tree-open ()
   (gnus-get-tree-buffer))
 
-(defun gnus-tree-close (group)
+(defun gnus-tree-close ()
   (gnus-kill-buffer gnus-tree-buffer))
 
 (defun gnus-tree-perhaps-minimize ()
@@ -825,215 +850,48 @@ Two predefined functions are available:
 
 (defun gnus-highlight-selected-tree (article)
   "Highlight the selected article in the tree."
-  (let ((buf (current-buffer))
-       region)
-    (set-buffer gnus-tree-buffer)
-    (when (setq region (gnus-tree-article-region article))
-      (when (or (not gnus-selected-tree-overlay)
-               (gnus-extent-detached-p gnus-selected-tree-overlay))
-       ;; Create a new overlay.
-       (gnus-overlay-put
-        (setq gnus-selected-tree-overlay
-              (gnus-make-overlay (point-min) (1+ (point-min))))
-        'face gnus-selected-tree-face))
-      ;; Move the overlay to the article.
-      (gnus-move-overlay
-       gnus-selected-tree-overlay (goto-char (car region)) (cdr region))
-      (gnus-tree-minimize)
-      (gnus-tree-recenter)
-      (let ((selected (selected-window)))
-       (when (gnus-get-buffer-window (set-buffer gnus-tree-buffer) t)
-         (select-window (gnus-get-buffer-window (set-buffer gnus-tree-buffer) t))
-         (gnus-horizontal-recenter)
-         (select-window selected))))
-;; If we remove this save-excursion, it updates the wrong mode lines?!?
-    (with-current-buffer gnus-tree-buffer
-      (gnus-set-mode-line 'tree))
-    (set-buffer buf)))
-
-(defun gnus-tree-highlight-article (article face)
-  (with-current-buffer (gnus-get-tree-buffer)
-    (let (region)
+  (when (buffer-live-p gnus-tree-buffer)
+    (let ((buf (current-buffer))
+         region)
+      (set-buffer gnus-tree-buffer)
       (when (setq region (gnus-tree-article-region article))
-       (gnus-put-text-property (car region) (cdr region) 'face face)
-       (set-window-point
-        (gnus-get-buffer-window (current-buffer) t) (cdr region))))))
+       (when (or (not gnus-selected-tree-overlay)
+                 (gnus-extent-detached-p gnus-selected-tree-overlay))
+         ;; Create a new overlay.
+         (gnus-overlay-put
+          (setq gnus-selected-tree-overlay
+                (gnus-make-overlay (point-min) (1+ (point-min))))
+          'face gnus-selected-tree-face))
+       ;; Move the overlay to the article.
+       (gnus-move-overlay
+        gnus-selected-tree-overlay (goto-char (car region)) (cdr region))
+       (gnus-tree-minimize)
+       (gnus-tree-recenter)
+       (let ((selected (selected-window)))
+         (when (gnus-get-buffer-window (set-buffer gnus-tree-buffer) t)
+           (select-window
+            (gnus-get-buffer-window (set-buffer gnus-tree-buffer) t))
+           (gnus-horizontal-recenter)
+           (select-window selected))))
+      ;; If we remove this save-excursion, it updates the wrong mode lines?!?
+      (with-current-buffer gnus-tree-buffer
+       (gnus-set-mode-line 'tree))
+      (set-buffer buf))))
 
-;;;
-;;; gnus-carpal
-;;;
-
-(defvar gnus-carpal-group-buffer-buttons
-  '(("next" . gnus-group-next-unread-group)
-    ("prev" . gnus-group-prev-unread-group)
-    ("read" . gnus-group-read-group)
-    ("select" . gnus-group-select-group)
-    ("catch-up" . gnus-group-catchup-current)
-    ("new-news" . gnus-group-get-new-news-this-group)
-    ("toggle-sub" . gnus-group-unsubscribe-current-group)
-    ("subscribe" . gnus-group-unsubscribe-group)
-    ("kill" . gnus-group-kill-group)
-    ("yank" . gnus-group-yank-group)
-    ("describe" . gnus-group-describe-group)
-    "list"
-    ("subscribed" . gnus-group-list-groups)
-    ("all" . gnus-group-list-all-groups)
-    ("killed" . gnus-group-list-killed)
-    ("zombies" . gnus-group-list-zombies)
-    ("matching" . gnus-group-list-matching)
-    ("post" . gnus-group-post-news)
-    ("mail" . gnus-group-mail)
-    ("local" . (lambda () (interactive) (gnus-group-news 0)))
-    ("rescan" . gnus-group-get-new-news)
-    ("browse-foreign" . gnus-group-browse-foreign)
-    ("exit" . gnus-group-exit)))
-
-(defvar gnus-carpal-summary-buffer-buttons
-  '("mark"
-    ("read" . gnus-summary-mark-as-read-forward)
-    ("tick" . gnus-summary-tick-article-forward)
-    ("clear" . gnus-summary-clear-mark-forward)
-    ("expirable" . gnus-summary-mark-as-expirable)
-    "move"
-    ("scroll" . gnus-summary-next-page)
-    ("next-unread" . gnus-summary-next-unread-article)
-    ("prev-unread" . gnus-summary-prev-unread-article)
-    ("first" . gnus-summary-first-unread-article)
-    ("best" . gnus-summary-best-unread-article)
-    "article"
-    ("headers" . gnus-summary-toggle-header)
-    ("uudecode" . gnus-uu-decode-uu)
-    ("enter-digest" . gnus-summary-enter-digest-group)
-    ("fetch-parent" . gnus-summary-refer-parent-article)
-    "mail"
-    ("move" . gnus-summary-move-article)
-    ("copy" . gnus-summary-copy-article)
-    ("respool" . gnus-summary-respool-article)
-    "threads"
-    ("lower" . gnus-summary-lower-thread)
-    ("kill" . gnus-summary-kill-thread)
-    "post"
-    ("post" . gnus-summary-post-news)
-    ("local" . gnus-summary-news-other-window)
-    ("mail" . gnus-summary-mail-other-window)
-    ("followup" . gnus-summary-followup-with-original)
-    ("reply" . gnus-summary-reply-with-original)
-    ("cancel" . gnus-summary-cancel-article)
-    "misc"
-    ("exit" . gnus-summary-exit)
-    ("fed-up" . gnus-summary-catchup-and-goto-next-group)))
-
-(defvar gnus-carpal-server-buffer-buttons
-  '(("add" . gnus-server-add-server)
-    ("browse" . gnus-server-browse-server)
-    ("list" . gnus-server-list-servers)
-    ("kill" . gnus-server-kill-server)
-    ("yank" . gnus-server-yank-server)
-    ("copy" . gnus-server-copy-server)
-    ("exit" . gnus-server-exit)))
-
-(defvar gnus-carpal-browse-buffer-buttons
-  '(("subscribe" . gnus-browse-unsubscribe-current-group)
-    ("exit" . gnus-browse-exit)))
-
-(defvar gnus-carpal-group-buffer "*Carpal Group*")
-(defvar gnus-carpal-summary-buffer "*Carpal Summary*")
-(defvar gnus-carpal-server-buffer "*Carpal Server*")
-(defvar gnus-carpal-browse-buffer "*Carpal Browse*")
-
-(defvar gnus-carpal-attached-buffer nil)
-
-(defvar gnus-carpal-mode-hook nil
-  "*Hook run in carpal mode buffers.")
-
-(defvar gnus-carpal-button-face 'bold
-  "*Face used on carpal buttons.")
-
-(defvar gnus-carpal-header-face 'bold-italic
-  "*Face used on carpal buffer headers.")
-
-(defvar gnus-carpal-mode-map nil)
-(put 'gnus-carpal-mode 'mode-class 'special)
-
-(if gnus-carpal-mode-map
-    nil
-  (setq gnus-carpal-mode-map (make-keymap))
-  (suppress-keymap gnus-carpal-mode-map)
-  (define-key gnus-carpal-mode-map " " 'gnus-carpal-select)
-  (define-key gnus-carpal-mode-map "\r" 'gnus-carpal-select)
-  (define-key gnus-carpal-mode-map gnus-mouse-2 'gnus-carpal-mouse-select))
-
-(defun gnus-carpal-mode ()
-  "Major mode for clicking buttons.
-
-All normal editing commands are switched off.
-\\<gnus-carpal-mode-map>
-The following commands are available:
-
-\\{gnus-carpal-mode-map}"
-  (interactive)
-  (kill-all-local-variables)
-  (setq mode-line-modified (cdr gnus-mode-line-modified))
-  (setq major-mode 'gnus-carpal-mode)
-  (setq mode-name "Gnus Carpal")
-  (setq mode-line-process nil)
-  (use-local-map gnus-carpal-mode-map)
-  (buffer-disable-undo)
-  (setq buffer-read-only t)
-  (make-local-variable 'gnus-carpal-attached-buffer)
-  (gnus-run-mode-hooks 'gnus-carpal-mode-hook))
-
-(defun gnus-carpal-setup-buffer (type)
-  (let ((buffer (symbol-value (intern (format "gnus-carpal-%s-buffer" type)))))
-    (if (get-buffer buffer)
-       ()
-      (with-current-buffer (gnus-get-buffer-create buffer)
-       (gnus-carpal-mode)
-       (setq gnus-carpal-attached-buffer
-             (intern (format "gnus-%s-buffer" type)))
-       (let ((buttons (symbol-value
-                       (intern (format "gnus-carpal-%s-buffer-buttons"
-                                       type))))
-             (buffer-read-only nil)
-             button)
-         (while buttons
-           (setq button (car buttons)
-                 buttons (cdr buttons))
-           (if (stringp button)
-               (set-text-properties
-                (point)
-                (prog2 (insert button) (point) (insert " "))
-                (list 'face gnus-carpal-header-face))
-             (set-text-properties
-              (point)
-              (prog2 (insert (car button)) (point) (insert " "))
-              (list 'gnus-callback (cdr button)
-                    'face gnus-carpal-button-face
-                    gnus-mouse-face-prop 'highlight))))
-         (let ((fill-column (- (window-width) 2)))
-           (fill-region (point-min) (point-max)))
-         (set-window-point (get-buffer-window (current-buffer))
-                           (point-min)))))))
-
-(defun gnus-carpal-select ()
-  "Select the button under point."
-  (interactive)
-  (let ((func (get-text-property (point) 'gnus-callback)))
-    (if (null func)
-       ()
-      (pop-to-buffer (symbol-value gnus-carpal-attached-buffer))
-      (call-interactively func))))
-
-(defun gnus-carpal-mouse-select (event)
-  "Select the button under the mouse pointer."
-  (interactive "e")
-  (mouse-set-point event)
-  (gnus-carpal-select))
+(defun gnus-tree-highlight-article (article face)
+  ;; The save-excursion here is apparently necessary because
+  ;; `set-window-point' somehow manages to alter the buffer position.
+  (save-excursion
+    (with-current-buffer (gnus-get-tree-buffer)
+      (let (region)
+       (when (setq region (gnus-tree-article-region article))
+         (gnus-put-text-property (car region) (cdr region) 'face face)
+         (set-window-point
+          (gnus-get-buffer-window (current-buffer) t) (cdr region)))))))
 
 ;;; Allow redefinition of functions.
 (gnus-ems-redefine)
 
 (provide 'gnus-salt)
 
-;; arch-tag: 35449164-77b3-4398-bcbd-a2e3e998f810
 ;;; gnus-salt.el ends here