comparison lisp/gnus/gnus-salt.el @ 16:0293115a14e9 r19-15b91

Import from CVS: tag r19-15b91
author cvs
date Mon, 13 Aug 2007 08:49:20 +0200
parents 376386a54a3c
children d95e72db5c07
comparison
equal deleted inserted replaced
15:ad457d5f7d04 16:0293115a14e9
1 ;;; gnus-salt.el --- alternate summary mode interfaces for Gnus 1 ;;; gnus-salt.el --- alternate summary mode interfaces for Gnus
2 ;; Copyright (C) 1996 Free Software Foundation, Inc. 2 ;; Copyright (C) 1996,97 Free Software Foundation, Inc.
3 3
4 ;; Author: Lars Magne Ingebrigtsen <larsi@ifi.uio.no> 4 ;; Author: Lars Magne Ingebrigtsen <larsi@ifi.uio.no>
5 5
6 ;; This file is part of GNU Emacs. 6 ;; This file is part of GNU Emacs.
7 7
23 ;;; Commentary: 23 ;;; Commentary:
24 24
25 ;;; Code: 25 ;;; Code:
26 26
27 (require 'gnus) 27 (require 'gnus)
28 (eval-when-compile (require 'cl)) 28 (require 'gnus-sum)
29 29
30 ;;; 30 ;;;
31 ;;; gnus-pick-mode 31 ;;; gnus-pick-mode
32 ;;; 32 ;;;
33 33
37 (defvar gnus-pick-display-summary nil 37 (defvar gnus-pick-display-summary nil
38 "*Display summary while reading.") 38 "*Display summary while reading.")
39 39
40 (defvar gnus-pick-mode-hook nil 40 (defvar gnus-pick-mode-hook nil
41 "Hook run in summary pick mode buffers.") 41 "Hook run in summary pick mode buffers.")
42
43 (defvar gnus-mark-unpicked-articles-as-read nil
44 "*If non-nil, mark all unpicked articles as read.")
45
46 (defvar gnus-pick-elegant-flow t
47 "If non-nil, gnus-pick-start-reading will run gnus-summary-next-group when no articles have been picked.")
48
49 (defvar gnus-summary-pick-line-format
50 "%-5P %U\%R\%z\%I\%(%[%4L: %-20,20n%]%) %s\n"
51 "*The format specification of the lines in pick buffers.
52 It accepts the same format specs that `gnus-summary-line-format' does.")
42 53
43 ;;; Internal variables. 54 ;;; Internal variables.
44 55
45 (defvar gnus-pick-mode-map nil) 56 (defvar gnus-pick-mode-map nil)
46 57
49 60
50 (gnus-define-keys 61 (gnus-define-keys
51 gnus-pick-mode-map 62 gnus-pick-mode-map
52 "t" gnus-uu-mark-thread 63 "t" gnus-uu-mark-thread
53 "T" gnus-uu-unmark-thread 64 "T" gnus-uu-unmark-thread
54 " " gnus-summary-mark-as-processable 65 " " gnus-pick-next-page
55 "u" gnus-summary-unmark-as-processable 66 "u" gnus-summary-unmark-as-processable
56 "U" gnus-summary-unmark-all-processable 67 "U" gnus-summary-unmark-all-processable
57 "v" gnus-uu-mark-over 68 "v" gnus-uu-mark-over
58 "r" gnus-uu-mark-region 69 "r" gnus-uu-mark-region
59 "R" gnus-uu-unmark-region 70 "R" gnus-uu-unmark-region
60 "e" gnus-uu-mark-by-regexp 71 "e" gnus-uu-mark-by-regexp
61 "E" gnus-uu-mark-by-regexp 72 "E" gnus-uu-mark-by-regexp
62 "b" gnus-uu-mark-buffer 73 "b" gnus-uu-mark-buffer
63 "B" gnus-uu-unmark-buffer 74 "B" gnus-uu-unmark-buffer
75 "." gnus-pick-article
76 gnus-down-mouse-2 gnus-pick-mouse-pick-region
77 ;;gnus-mouse-2 gnus-pick-mouse-pick
78 "X" gnus-pick-start-reading
64 "\r" gnus-pick-start-reading)) 79 "\r" gnus-pick-start-reading))
65 80
66 (defun gnus-pick-make-menu-bar () 81 (defun gnus-pick-make-menu-bar ()
67 (unless (boundp 'gnus-pick-menu) 82 (unless (boundp 'gnus-pick-menu)
68 (easy-menu-define 83 (easy-menu-define
87 "Minor mode for providing a pick-and-read interface in Gnus summary buffers. 102 "Minor mode for providing a pick-and-read interface in Gnus summary buffers.
88 103
89 \\{gnus-pick-mode-map}" 104 \\{gnus-pick-mode-map}"
90 (interactive "P") 105 (interactive "P")
91 (when (eq major-mode 'gnus-summary-mode) 106 (when (eq major-mode 'gnus-summary-mode)
92 (make-local-variable 'gnus-pick-mode) 107 (if (not (set (make-local-variable 'gnus-pick-mode)
93 (setq gnus-pick-mode 108 (if (null arg) (not gnus-pick-mode)
94 (if (null arg) (not gnus-pick-mode) 109 (> (prefix-numeric-value arg) 0))))
95 (> (prefix-numeric-value arg) 0))) 110 (remove-hook 'gnus-message-setup-hook 'gnus-pick-setup-message)
96 (when gnus-pick-mode
97 ;; Make sure that we don't select any articles upon group entry. 111 ;; Make sure that we don't select any articles upon group entry.
98 (make-local-variable 'gnus-auto-select-first) 112 (set (make-local-variable 'gnus-auto-select-first) nil)
99 (setq gnus-auto-select-first nil) 113 ;; Change line format.
114 (setq gnus-summary-line-format gnus-summary-pick-line-format)
115 (setq gnus-summary-line-format-spec nil)
116 (gnus-update-format-specifications nil 'summary)
117 (gnus-update-summary-mark-positions)
118 (add-hook 'gnus-message-setup-hook 'gnus-pick-setup-message)
119 (set (make-local-variable 'gnus-summary-goto-unread) 'never)
100 ;; Set up the menu. 120 ;; Set up the menu.
101 (when (and menu-bar-mode 121 (when (gnus-visual-p 'pick-menu 'menu)
102 (gnus-visual-p 'pick-menu 'menu))
103 (gnus-pick-make-menu-bar)) 122 (gnus-pick-make-menu-bar))
104 (unless (assq 'gnus-pick-mode minor-mode-alist) 123 (unless (assq 'gnus-pick-mode minor-mode-alist)
105 (push '(gnus-pick-mode " Pick") minor-mode-alist)) 124 (push '(gnus-pick-mode " Pick") minor-mode-alist))
106 (unless (assq 'gnus-pick-mode minor-mode-map-alist) 125 (unless (assq 'gnus-pick-mode minor-mode-map-alist)
107 (push (cons 'gnus-pick-mode gnus-pick-mode-map) 126 (push (cons 'gnus-pick-mode gnus-pick-mode-map)
108 minor-mode-map-alist)) 127 minor-mode-map-alist))
109 (run-hooks 'gnus-pick-mode-hook)))) 128 (run-hooks 'gnus-pick-mode-hook))))
110 129
130 (defun gnus-pick-setup-message ()
131 "Make Message do the right thing on exit."
132 (when (and (gnus-buffer-live-p gnus-summary-buffer)
133 (save-excursion
134 (set-buffer gnus-summary-buffer)
135 gnus-pick-mode))
136 (message-add-action
137 '(gnus-configure-windows 'pick t) 'send 'exit 'postpone 'kill)))
138
139 (defvar gnus-pick-line-number 1)
140 (defun gnus-pick-line-number ()
141 "Return the current line number."
142 (if (bobp)
143 (setq gnus-pick-line-number 1)
144 (incf gnus-pick-line-number)))
145
111 (defun gnus-pick-start-reading (&optional catch-up) 146 (defun gnus-pick-start-reading (&optional catch-up)
112 "Start reading the picked articles. 147 "Start reading the picked articles.
113 If given a prefix, mark all unpicked articles as read." 148 If given a prefix, mark all unpicked articles as read."
114 (interactive "P") 149 (interactive "P")
115 (unless gnus-newsgroup-processable 150 (if gnus-newsgroup-processable
116 (error "No articles have been picked")) 151 (progn
117 (gnus-summary-limit-to-articles nil) 152 (gnus-summary-limit-to-articles nil)
118 (when catch-up 153 (when (or catch-up gnus-mark-unpicked-articles-as-read)
119 (gnus-summary-limit-mark-excluded-as-read)) 154 (gnus-summary-limit-mark-excluded-as-read))
120 (gnus-summary-first-unread-article) 155 (gnus-summary-first-article)
121 (gnus-configure-windows (if gnus-pick-display-summary 'article 'pick) t)) 156 (gnus-configure-windows
122 157 (if gnus-pick-display-summary 'article 'pick) t))
158 (if gnus-pick-elegant-flow
159 (progn
160 (when (or catch-up gnus-mark-unpicked-articles-as-read)
161 (gnus-summary-limit-mark-excluded-as-read))
162 (if (gnus-group-quit-config gnus-newsgroup-name)
163 (gnus-summary-exit)
164 (gnus-summary-next-group)))
165 (error "No articles have been picked"))))
166
167 (defun gnus-pick-article (&optional arg)
168 "Pick the article on the current line.
169 If ARG, pick the article on that line instead."
170 (interactive "P")
171 (when arg
172 (let (pos)
173 (save-excursion
174 (goto-char (point-min))
175 (when (zerop (forward-line (1- (prefix-numeric-value arg))))
176 (setq pos (point))))
177 (if (not pos)
178 (gnus-error 2 "No such line: %s" arg)
179 (goto-char pos))))
180 (gnus-summary-mark-as-processable 1))
181
182 (defun gnus-pick-mouse-pick (e)
183 (interactive "e")
184 (mouse-set-point e)
185 (save-excursion
186 (gnus-summary-mark-as-processable 1)))
187
188 (defun gnus-pick-mouse-pick-region (start-event)
189 "Pick articles that the mouse is dragged over.
190 This must be bound to a button-down mouse event."
191 (interactive "e")
192 (mouse-minibuffer-check start-event)
193 (let* ((echo-keystrokes 0)
194 (start-posn (event-start start-event))
195 (start-point (posn-point start-posn))
196 (start-line (1+ (count-lines 1 start-point)))
197 (start-window (posn-window start-posn))
198 (start-frame (window-frame start-window))
199 (bounds (window-edges start-window))
200 (top (nth 1 bounds))
201 (bottom (if (window-minibuffer-p start-window)
202 (nth 3 bounds)
203 ;; Don't count the mode line.
204 (1- (nth 3 bounds))))
205 (click-count (1- (event-click-count start-event))))
206 (setq mouse-selection-click-count click-count)
207 (setq mouse-selection-click-count-buffer (current-buffer))
208 (mouse-set-point start-event)
209 ;; In case the down click is in the middle of some intangible text,
210 ;; use the end of that text, and put it in START-POINT.
211 (when (< (point) start-point)
212 (goto-char start-point))
213 (gnus-pick-article)
214 (setq start-point (point))
215 ;; end-of-range is used only in the single-click case.
216 ;; It is the place where the drag has reached so far
217 ;; (but not outside the window where the drag started).
218 (let (event end end-point last-end-point (end-of-range (point)))
219 (track-mouse
220 (while (progn
221 (setq event (read-event))
222 (or (mouse-movement-p event)
223 (eq (car-safe event) 'switch-frame)))
224 (if (eq (car-safe event) 'switch-frame)
225 nil
226 (setq end (event-end event)
227 end-point (posn-point end))
228 (when end-point
229 (setq last-end-point end-point))
230
231 (cond
232 ;; Are we moving within the original window?
233 ((and (eq (posn-window end) start-window)
234 (integer-or-marker-p end-point))
235 ;; Go to START-POINT first, so that when we move to END-POINT,
236 ;; if it's in the middle of intangible text,
237 ;; point jumps in the direction away from START-POINT.
238 (goto-char start-point)
239 (goto-char end-point)
240 (gnus-pick-article)
241 ;; In case the user moved his mouse really fast, pick
242 ;; articles on the line between this one and the last one.
243 (let* ((this-line (1+ (count-lines 1 end-point)))
244 (min-line (min this-line start-line))
245 (max-line (max this-line start-line)))
246 (while (< min-line max-line)
247 (goto-line min-line)
248 (gnus-pick-article)
249 (setq min-line (1+ min-line)))
250 (setq start-line this-line))
251 (when (zerop (% click-count 3))
252 (setq end-of-range (point))))
253 (t
254 (let ((mouse-row (cdr (cdr (mouse-position)))))
255 (cond
256 ((null mouse-row))
257 ((< mouse-row top)
258 (mouse-scroll-subr start-window (- mouse-row top)))
259 ((>= mouse-row bottom)
260 (mouse-scroll-subr start-window
261 (1+ (- mouse-row bottom)))))))))))
262 (when (consp event)
263 (let ((fun (key-binding (vector (car event)))))
264 ;; Run the binding of the terminating up-event, if possible.
265 ;; In the case of a multiple click, it gives the wrong results,
266 ;; because it would fail to set up a region.
267 (when nil
268 ;; (and (= (mod mouse-selection-click-count 3) 0) (fboundp fun))
269 ;; In this case, we can just let the up-event execute normally.
270 (let ((end (event-end event)))
271 ;; Set the position in the event before we replay it,
272 ;; because otherwise it may have a position in the wrong
273 ;; buffer.
274 (setcar (cdr end) end-of-range)
275 ;; Delete the overlay before calling the function,
276 ;; because delete-overlay increases buffer-modified-tick.
277 (push event unread-command-events))))))))
278
279 (defun gnus-pick-next-page ()
280 "Go to the next page. If at the end of the buffer, start reading articles."
281 (interactive)
282 (let ((scroll-in-place nil))
283 (condition-case nil
284 (scroll-up)
285 (end-of-buffer (gnus-pick-start-reading)))))
123 286
124 ;;; 287 ;;;
125 ;;; gnus-binary-mode 288 ;;; gnus-binary-mode
126 ;;; 289 ;;;
127 290
128 (defvar gnus-binary-mode nil 291 (defvar gnus-binary-mode nil
129 "Minor mode for provind a binary group interface in Gnus summary buffers.") 292 "Minor mode for providing a binary group interface in Gnus summary buffers.")
130 293
131 (defvar gnus-binary-mode-hook nil 294 (defvar gnus-binary-mode-hook nil
132 "Hook run in summary binary mode buffers.") 295 "Hook run in summary binary mode buffers.")
133 296
134 (defvar gnus-binary-mode-map nil) 297 (defvar gnus-binary-mode-map nil)
160 (make-local-variable 'gnus-auto-select-first) 323 (make-local-variable 'gnus-auto-select-first)
161 (setq gnus-auto-select-first nil) 324 (setq gnus-auto-select-first nil)
162 (make-local-variable 'gnus-summary-display-article-function) 325 (make-local-variable 'gnus-summary-display-article-function)
163 (setq gnus-summary-display-article-function 'gnus-binary-display-article) 326 (setq gnus-summary-display-article-function 'gnus-binary-display-article)
164 ;; Set up the menu. 327 ;; Set up the menu.
165 (when (and menu-bar-mode 328 (when (gnus-visual-p 'binary-menu 'menu)
166 (gnus-visual-p 'binary-menu 'menu))
167 (gnus-binary-make-menu-bar)) 329 (gnus-binary-make-menu-bar))
168 (unless (assq 'gnus-binary-mode minor-mode-alist) 330 (unless (assq 'gnus-binary-mode minor-mode-alist)
169 (push '(gnus-binary-mode " Binary") minor-mode-alist)) 331 (push '(gnus-binary-mode " Binary") minor-mode-alist))
170 (unless (assq 'gnus-binary-mode minor-mode-map-alist) 332 (unless (assq 'gnus-binary-mode minor-mode-map-alist)
171 (push (cons 'gnus-binary-mode gnus-binary-mode-map) 333 (push (cons 'gnus-binary-mode gnus-binary-mode-map)
202 (defvar gnus-tree-brackets '((?\[ . ?\]) (?\( . ?\)) 364 (defvar gnus-tree-brackets '((?\[ . ?\]) (?\( . ?\))
203 (?\{ . ?\}) (?< . ?>)) 365 (?\{ . ?\}) (?< . ?>))
204 "Brackets used in tree nodes.") 366 "Brackets used in tree nodes.")
205 367
206 (defvar gnus-tree-parent-child-edges '(?- ?\\ ?|) 368 (defvar gnus-tree-parent-child-edges '(?- ?\\ ?|)
207 "Charaters used to connect parents with children.") 369 "Characters used to connect parents with children.")
208 370
209 (defvar gnus-tree-mode-line-format "Gnus: %%b %S %Z" 371 (defvar gnus-tree-mode-line-format "Gnus: %%b %S %Z"
210 "*The format specification for the tree mode line.") 372 "*The format specification for the tree mode line.")
211 373
212 (defvar gnus-generate-tree-function 'gnus-generate-vertical-tree 374 (defvar gnus-generate-tree-function 'gnus-generate-vertical-tree
268 (gnus-parse-format gnus-tree-mode-line-format 430 (gnus-parse-format gnus-tree-mode-line-format
269 gnus-summary-mode-line-format-alist)) 431 gnus-summary-mode-line-format-alist))
270 (setq gnus-tree-line-format-spec 432 (setq gnus-tree-line-format-spec
271 (gnus-parse-format gnus-tree-line-format 433 (gnus-parse-format gnus-tree-line-format
272 gnus-tree-line-format-alist t)) 434 gnus-tree-line-format-alist t))
273 (when (and menu-bar-mode 435 (when (gnus-visual-p 'tree-menu 'menu)
274 (gnus-visual-p 'tree-menu 'menu))
275 (gnus-tree-make-menu-bar)) 436 (gnus-tree-make-menu-bar))
276 (kill-all-local-variables) 437 (kill-all-local-variables)
277 (gnus-simplify-mode-line) 438 (gnus-simplify-mode-line)
278 (setq mode-name "Tree") 439 (setq mode-name "Tree")
279 (setq major-mode 'gnus-tree-mode) 440 (setq major-mode 'gnus-tree-mode)
337 (select-window tree-window) 498 (select-window tree-window)
338 (when gnus-selected-tree-overlay 499 (when gnus-selected-tree-overlay
339 (goto-char (or (gnus-overlay-end gnus-selected-tree-overlay) 1))) 500 (goto-char (or (gnus-overlay-end gnus-selected-tree-overlay) 1)))
340 (let* ((top (cond ((< (window-height) 4) 0) 501 (let* ((top (cond ((< (window-height) 4) 0)
341 ((< (window-height) 7) 1) 502 ((< (window-height) 7) 1)
342 (t 2))) 503 (t 2)))
343 (height (1- (window-height))) 504 (height (1- (window-height)))
344 (bottom (save-excursion (goto-char (point-max)) 505 (bottom (save-excursion (goto-char (point-max))
345 (forward-line (- height)) 506 (forward-line (- height))
346 (point)))) 507 (point))))
347 ;; Set the window start to either `bottom', which is the biggest 508 ;; Set the window start to either `bottom', which is the biggest
366 (not (one-window-p))) 527 (not (one-window-p)))
367 (let ((windows 0) 528 (let ((windows 0)
368 tot-win-height) 529 tot-win-height)
369 (walk-windows (lambda (window) (incf windows))) 530 (walk-windows (lambda (window) (incf windows)))
370 (setq tot-win-height 531 (setq tot-win-height
371 (- (frame-height) 532 (- (frame-height)
372 (* window-min-height (1- windows)) 533 (* window-min-height (1- windows))
373 2)) 534 2))
374 (let* ((window-min-height 2) 535 (let* ((window-min-height 2)
375 (height (count-lines (point-min) (point-max))) 536 (height (count-lines (point-min) (point-max)))
376 (min (max (1- window-min-height) height)) 537 (min (max (1- window-min-height) height))
381 (wh (and win (1- (window-height win))))) 542 (wh (and win (1- (window-height win)))))
382 (setq tot (min tot tot-win-height)) 543 (setq tot (min tot tot-win-height))
383 (when (and win 544 (when (and win
384 (not (eq tot wh))) 545 (not (eq tot wh)))
385 (let ((selected (selected-window))) 546 (let ((selected (selected-window)))
386 (select-window win) 547 (when (ignore-errors (select-window win))
387 (enlarge-window (- tot wh)) 548 (enlarge-window (- tot wh))
388 (select-window selected))))))) 549 (select-window selected))))))))
389 550
390 ;;; Generating the tree. 551 ;;; Generating the tree.
391 552
392 (defun gnus-tree-node-insert (header sparse &optional adopted) 553 (defun gnus-tree-node-insert (header sparse &optional adopted)
393 (let* ((dummy (stringp header)) 554 (let* ((dummy (stringp header))
414 (substring gnus-tmp-from 0 beg)))) 575 (substring gnus-tmp-from 0 beg))))
415 ((memq gnus-tmp-number sparse) 576 ((memq gnus-tmp-number sparse)
416 "***") 577 "***")
417 (t gnus-tmp-from))) 578 (t gnus-tmp-from)))
418 (gnus-tmp-open-bracket 579 (gnus-tmp-open-bracket
419 (cond ((memq gnus-tmp-number sparse) 580 (cond ((memq gnus-tmp-number sparse)
420 (caadr gnus-tree-brackets)) 581 (caadr gnus-tree-brackets))
421 (dummy (caaddr gnus-tree-brackets)) 582 (dummy (caaddr gnus-tree-brackets))
422 (adopted (car (nth 3 gnus-tree-brackets))) 583 (adopted (car (nth 3 gnus-tree-brackets)))
423 (t (caar gnus-tree-brackets)))) 584 (t (caar gnus-tree-brackets))))
424 (gnus-tmp-close-bracket 585 (gnus-tmp-close-bracket
495 (insert (car gnus-tree-parent-child-edges)) 656 (insert (car gnus-tree-parent-child-edges))
496 ;; If the level isn't zero, then we insert some indentation. 657 ;; If the level isn't zero, then we insert some indentation.
497 (unless (zerop level) 658 (unless (zerop level)
498 (gnus-tree-indent level) 659 (gnus-tree-indent level)
499 (insert (cadr gnus-tree-parent-child-edges)) 660 (insert (cadr gnus-tree-parent-child-edges))
500 (setq col (- (setq beg (point)) (gnus-point-at-bol) 1)) 661 (setq col (- (setq beg (point)) (point-at-bol) 1))
501 ;; Draw "|" lines upwards. 662 ;; Draw "|" lines upwards.
502 (while (progn 663 (while (progn
503 (forward-line -1) 664 (forward-line -1)
504 (forward-char col) 665 (forward-char col)
505 (= (following-char) ? )) 666 (= (following-char) ? ))
514 (unless (bolp) 675 (unless (bolp)
515 (insert "\n")) 676 (insert "\n"))
516 ;; Recurse downwards in all children of this article. 677 ;; Recurse downwards in all children of this article.
517 (while thread 678 (while thread
518 (gnus-generate-horizontal-tree 679 (gnus-generate-horizontal-tree
519 (pop thread) (if do (1+ level) level) 680 (pop thread) (if do (1+ level) level)
520 (or dummyp dummy) dummy))))) 681 (or dummyp dummy) dummy)))))
521 682
522 (defsubst gnus-tree-indent-vertical () 683 (defsubst gnus-tree-indent-vertical ()
523 (let ((len (- (* (1+ gnus-tree-node-length) gnus-tmp-indent) 684 (let ((len (- (* (1+ gnus-tree-node-length) gnus-tmp-indent)
524 (- (point) (gnus-point-at-bol))))) 685 (- (point) (point-at-bol)))))
525 (when (> len 0) 686 (when (> len 0)
526 (insert (make-string len ? ))))) 687 (insert (make-string len ? )))))
527 688
528 (defsubst gnus-tree-forward-line (n) 689 (defsubst gnus-tree-forward-line (n)
529 (while (>= (decf n) 0) 690 (while (>= (decf n) 0)
534 695
535 (defun gnus-generate-vertical-tree (thread level &optional dummyp adopted) 696 (defun gnus-generate-vertical-tree (thread level &optional dummyp adopted)
536 "Generate a vertical tree." 697 "Generate a vertical tree."
537 (let* ((dummy (stringp (car thread))) 698 (let* ((dummy (stringp (car thread)))
538 (do (or dummy 699 (do (or dummy
539 (memq (mail-header-number (car thread)) gnus-tmp-limit))) 700 (and (car thread)
701 (memq (mail-header-number (car thread))
702 gnus-tmp-limit))))
540 beg) 703 beg)
541 (if (not do) 704 (if (not do)
542 ;; We don't want this article. 705 ;; We don't want this article.
543 (setq thread (cdr thread)) 706 (setq thread (cdr thread))
544 (if (not (save-excursion (beginning-of-line) (bobp))) 707 (if (not (save-excursion (beginning-of-line) (bobp)))
555 (delete-char -1) 718 (delete-char -1)
556 (insert (cadr gnus-tree-parent-child-edges)) 719 (insert (cadr gnus-tree-parent-child-edges))
557 (setq beg (point)) 720 (setq beg (point))
558 ;; Draw "-" lines leftwards. 721 ;; Draw "-" lines leftwards.
559 (while (progn 722 (while (progn
560 (forward-char -2) 723 (unless (bolp)
724 (forward-char -2))
561 (= (following-char) ? )) 725 (= (following-char) ? ))
562 (delete-char 1) 726 (delete-char 1)
563 (insert (car gnus-tree-parent-child-edges))) 727 (insert (car gnus-tree-parent-child-edges)))
564 (goto-char beg) 728 (goto-char beg)
565 (gnus-tree-forward-line 1))) 729 (gnus-tree-forward-line 1)))
575 (end-of-line) 739 (end-of-line)
576 (incf gnus-tmp-indent)) 740 (incf gnus-tmp-indent))
577 ;; Recurse downwards in all children of this article. 741 ;; Recurse downwards in all children of this article.
578 (while thread 742 (while thread
579 (gnus-generate-vertical-tree 743 (gnus-generate-vertical-tree
580 (pop thread) (if do (1+ level) level) 744 (pop thread) (if do (1+ level) level)
581 (or dummyp dummy) dummy))))) 745 (or dummyp dummy) dummy)))))
582 746
583 ;;; Interface functions. 747 ;;; Interface functions.
584 748
585 (defun gnus-possibly-generate-tree (article &optional force) 749 (defun gnus-possibly-generate-tree (article &optional force)
586 "Generate the thread tree for ARTICLE if it isn't displayed already." 750 "Generate the thread tree for ARTICLE if it isn't displayed already."
587 (when (save-excursion 751 (when (save-excursion
588 (set-buffer gnus-summary-buffer) 752 (set-buffer gnus-summary-buffer)
589 (and gnus-use-trees 753 (and gnus-use-trees
754 gnus-show-threads
590 (vectorp (gnus-summary-article-header article)))) 755 (vectorp (gnus-summary-article-header article))))
591 (save-excursion 756 (save-excursion
592 (let ((top (save-excursion 757 (let ((top (save-excursion
593 (set-buffer gnus-summary-buffer) 758 (set-buffer gnus-summary-buffer)
594 (gnus-cut-thread 759 (gnus-cut-thread
595 (gnus-remove-thread 760 (gnus-remove-thread
596 (mail-header-id 761 (mail-header-id
597 (gnus-summary-article-header article)) t)))) 762 (gnus-summary-article-header article))
763 t))))
598 (gnus-tmp-limit gnus-newsgroup-limit) 764 (gnus-tmp-limit gnus-newsgroup-limit)
599 (gnus-tmp-sparse gnus-newsgroup-sparse)) 765 (gnus-tmp-sparse gnus-newsgroup-sparse))
600 (when (or force 766 (when (or force
601 (not (eq top gnus-tree-displayed-thread))) 767 (not (eq top gnus-tree-displayed-thread)))
602 (gnus-generate-tree top) 768 (gnus-generate-tree top)
604 770
605 (defun gnus-tree-open (group) 771 (defun gnus-tree-open (group)
606 (gnus-get-tree-buffer)) 772 (gnus-get-tree-buffer))
607 773
608 (defun gnus-tree-close (group) 774 (defun gnus-tree-close (group)
609 ;(gnus-kill-buffer gnus-tree-buffer) 775 ;(gnus-kill-buffer gnus-tree-buffer)
610 ) 776 )
611 777
612 (defun gnus-highlight-selected-tree (article) 778 (defun gnus-highlight-selected-tree (article)
613 "Highlight the selected article in the tree." 779 "Highlight the selected article in the tree."
614 (let ((buf (current-buffer)) 780 (let ((buf (current-buffer))
644 (when (setq region (gnus-tree-article-region article)) 810 (when (setq region (gnus-tree-article-region article))
645 (gnus-put-text-property (car region) (cdr region) 'face face) 811 (gnus-put-text-property (car region) (cdr region) 'face face)
646 (set-window-point 812 (set-window-point
647 (get-buffer-window (current-buffer) t) (cdr region)))))) 813 (get-buffer-window (current-buffer) t) (cdr region))))))
648 814
815 ;;;
816 ;;; gnus-carpal
817 ;;;
818
819 (defvar gnus-carpal-group-buffer-buttons
820 '(("next" . gnus-group-next-unread-group)
821 ("prev" . gnus-group-prev-unread-group)
822 ("read" . gnus-group-read-group)
823 ("select" . gnus-group-select-group)
824 ("catch-up" . gnus-group-catchup-current)
825 ("new-news" . gnus-group-get-new-news-this-group)
826 ("toggle-sub" . gnus-group-unsubscribe-current-group)
827 ("subscribe" . gnus-group-unsubscribe-group)
828 ("kill" . gnus-group-kill-group)
829 ("yank" . gnus-group-yank-group)
830 ("describe" . gnus-group-describe-group)
831 "list"
832 ("subscribed" . gnus-group-list-groups)
833 ("all" . gnus-group-list-all-groups)
834 ("killed" . gnus-group-list-killed)
835 ("zombies" . gnus-group-list-zombies)
836 ("matching" . gnus-group-list-matching)
837 ("post" . gnus-group-post-news)
838 ("mail" . gnus-group-mail)
839 ("rescan" . gnus-group-get-new-news)
840 ("browse-foreign" . gnus-group-browse-foreign)
841 ("exit" . gnus-group-exit)))
842
843 (defvar gnus-carpal-summary-buffer-buttons
844 '("mark"
845 ("read" . gnus-summary-mark-as-read-forward)
846 ("tick" . gnus-summary-tick-article-forward)
847 ("clear" . gnus-summary-clear-mark-forward)
848 ("expirable" . gnus-summary-mark-as-expirable)
849 "move"
850 ("scroll" . gnus-summary-next-page)
851 ("next-unread" . gnus-summary-next-unread-article)
852 ("prev-unread" . gnus-summary-prev-unread-article)
853 ("first" . gnus-summary-first-unread-article)
854 ("best" . gnus-summary-best-unread-article)
855 "article"
856 ("headers" . gnus-summary-toggle-header)
857 ("uudecode" . gnus-uu-decode-uu)
858 ("enter-digest" . gnus-summary-enter-digest-group)
859 ("fetch-parent" . gnus-summary-refer-parent-article)
860 "mail"
861 ("move" . gnus-summary-move-article)
862 ("copy" . gnus-summary-copy-article)
863 ("respool" . gnus-summary-respool-article)
864 "threads"
865 ("lower" . gnus-summary-lower-thread)
866 ("kill" . gnus-summary-kill-thread)
867 "post"
868 ("post" . gnus-summary-post-news)
869 ("mail" . gnus-summary-mail)
870 ("followup" . gnus-summary-followup-with-original)
871 ("reply" . gnus-summary-reply-with-original)
872 ("cancel" . gnus-summary-cancel-article)
873 "misc"
874 ("exit" . gnus-summary-exit)
875 ("fed-up" . gnus-summary-catchup-and-goto-next-group)))
876
877 (defvar gnus-carpal-server-buffer-buttons
878 '(("add" . gnus-server-add-server)
879 ("browse" . gnus-server-browse-server)
880 ("list" . gnus-server-list-servers)
881 ("kill" . gnus-server-kill-server)
882 ("yank" . gnus-server-yank-server)
883 ("copy" . gnus-server-copy-server)
884 ("exit" . gnus-server-exit)))
885
886 (defvar gnus-carpal-browse-buffer-buttons
887 '(("subscribe" . gnus-browse-unsubscribe-current-group)
888 ("exit" . gnus-browse-exit)))
889
890 (defvar gnus-carpal-group-buffer "*Carpal Group*")
891 (defvar gnus-carpal-summary-buffer "*Carpal Summary*")
892 (defvar gnus-carpal-server-buffer "*Carpal Server*")
893 (defvar gnus-carpal-browse-buffer "*Carpal Browse*")
894
895 (defvar gnus-carpal-attached-buffer nil)
896
897 (defvar gnus-carpal-mode-hook nil
898 "*Hook run in carpal mode buffers.")
899
900 (defvar gnus-carpal-button-face 'bold
901 "*Face used on carpal buttons.")
902
903 (defvar gnus-carpal-header-face 'bold-italic
904 "*Face used on carpal buffer headers.")
905
906 (defvar gnus-carpal-mode-map nil)
907 (put 'gnus-carpal-mode 'mode-class 'special)
908
909 (if gnus-carpal-mode-map
910 nil
911 (setq gnus-carpal-mode-map (make-keymap))
912 (suppress-keymap gnus-carpal-mode-map)
913 (define-key gnus-carpal-mode-map " " 'gnus-carpal-select)
914 (define-key gnus-carpal-mode-map "\r" 'gnus-carpal-select)
915 (define-key gnus-carpal-mode-map gnus-mouse-2 'gnus-carpal-mouse-select))
916
917 (defun gnus-carpal-mode ()
918 "Major mode for clicking buttons.
919
920 All normal editing commands are switched off.
921 \\<gnus-carpal-mode-map>
922 The following commands are available:
923
924 \\{gnus-carpal-mode-map}"
925 (interactive)
926 (kill-all-local-variables)
927 (setq mode-line-modified "-- ")
928 (setq major-mode 'gnus-carpal-mode)
929 (setq mode-name "Gnus Carpal")
930 (setq mode-line-process nil)
931 (use-local-map gnus-carpal-mode-map)
932 (buffer-disable-undo (current-buffer))
933 (setq buffer-read-only t)
934 (make-local-variable 'gnus-carpal-attached-buffer)
935 (run-hooks 'gnus-carpal-mode-hook))
936
937 (defun gnus-carpal-setup-buffer (type)
938 (let ((buffer (symbol-value (intern (format "gnus-carpal-%s-buffer" type)))))
939 (if (get-buffer buffer)
940 ()
941 (save-excursion
942 (set-buffer (get-buffer-create buffer))
943 (gnus-carpal-mode)
944 (setq gnus-carpal-attached-buffer
945 (intern (format "gnus-%s-buffer" type)))
946 (gnus-add-current-to-buffer-list)
947 (let ((buttons (symbol-value
948 (intern (format "gnus-carpal-%s-buffer-buttons"
949 type))))
950 (buffer-read-only nil)
951 button)
952 (while buttons
953 (setq button (car buttons)
954 buttons (cdr buttons))
955 (if (stringp button)
956 (gnus-set-text-properties
957 (point)
958 (prog2 (insert button) (point) (insert " "))
959 (list 'face gnus-carpal-header-face))
960 (gnus-set-text-properties
961 (point)
962 (prog2 (insert (car button)) (point) (insert " "))
963 (list 'gnus-callback (cdr button)
964 'face gnus-carpal-button-face
965 gnus-mouse-face-prop 'highlight))))
966 (let ((fill-column (- (window-width) 2)))
967 (fill-region (point-min) (point-max)))
968 (set-window-point (get-buffer-window (current-buffer))
969 (point-min)))))))
970
971 (defun gnus-carpal-select ()
972 "Select the button under point."
973 (interactive)
974 (let ((func (get-text-property (point) 'gnus-callback)))
975 (if (null func)
976 ()
977 (pop-to-buffer (symbol-value gnus-carpal-attached-buffer))
978 (call-interactively func))))
979
980 (defun gnus-carpal-mouse-select (event)
981 "Select the button under the mouse pointer."
982 (interactive "e")
983 (mouse-set-point event)
984 (gnus-carpal-select))
985
649 ;;; Allow redefinition of functions. 986 ;;; Allow redefinition of functions.
650 (gnus-ems-redefine) 987 (gnus-ems-redefine)
651 988
652 (provide 'gnus-salt) 989 (provide 'gnus-salt)
653 990