Mercurial > hg > xemacs-beta
comparison lisp/vm/vm-summary.el @ 70:131b0175ea99 r20-0b30
Import from CVS: tag r20-0b30
author | cvs |
---|---|
date | Mon, 13 Aug 2007 09:02:59 +0200 |
parents | 05472e90ae02 |
children | 0d2f883870bc |
comparison
equal
deleted
inserted
replaced
69:804d1389bcd6 | 70:131b0175ea99 |
---|---|
1 ;;; Summary gathering and formatting routines for VM | 1 ;;; Summary gathering and formatting routines for VM |
2 ;;; Copyright (C) 1989-1995 Kyle E. Jones | 2 ;;; Copyright (C) 1989, 1990, 1993, 1994, 1995 Kyle E. Jones |
3 ;;; | 3 ;;; |
4 ;;; This program is free software; you can redistribute it and/or modify | 4 ;;; This program is free software; you can redistribute it and/or modify |
5 ;;; it under the terms of the GNU General Public License as published by | 5 ;;; it under the terms of the GNU General Public License as published by |
6 ;;; the Free Software Foundation; either version 1, or (at your option) | 6 ;;; the Free Software Foundation; either version 1, or (at your option) |
7 ;;; any later version. | 7 ;;; any later version. |
20 (defun vm-summary-mode-internal () | 20 (defun vm-summary-mode-internal () |
21 (setq mode-name "VM Summary" | 21 (setq mode-name "VM Summary" |
22 major-mode 'vm-summary-mode | 22 major-mode 'vm-summary-mode |
23 mode-line-format vm-mode-line-format | 23 mode-line-format vm-mode-line-format |
24 ;; must come after the setting of major-mode | 24 ;; must come after the setting of major-mode |
25 mode-popup-menu (and vm-use-menus vm-popup-menu-on-mouse-3 | 25 mode-popup-menu (and vm-use-menus |
26 (vm-menu-support-possible-p) | 26 (vm-menu-support-possible-p) |
27 (vm-menu-mode-menu)) | 27 (vm-menu-mode-menu)) |
28 buffer-read-only t | 28 buffer-read-only t |
29 vm-summary-pointer nil | 29 vm-summary-pointer nil |
30 vm-summary-=> (if (stringp vm-summary-arrow) vm-summary-arrow "") | 30 vm-summary-=> (if (stringp vm-summary-arrow) vm-summary-arrow "") |
31 vm-summary-no-=> (make-string (length vm-summary-=>) ? ) | 31 vm-summary-no-=> (make-string (length vm-summary-=>) ? ) |
32 truncate-lines t) | 32 truncate-lines t) |
33 ;; horizontal scrollbar off by default | 33 ;; horizontal scrollbar off by default |
34 ;; user can turn it on in summary hook if desired. | 34 ;; user can turn it on in summary hook if desired. |
35 (and vm-xemacs-p (featurep 'scrollbar) | 35 (and (fboundp 'set-specifier) |
36 scrollbar-height | |
36 (set-specifier scrollbar-height (cons (current-buffer) 0))) | 37 (set-specifier scrollbar-height (cons (current-buffer) 0))) |
37 (use-local-map vm-summary-mode-map) | 38 (use-local-map vm-summary-mode-map) |
38 (and (vm-menu-support-possible-p) | 39 (and (vm-menu-support-possible-p) |
39 (vm-menu-install-menus)) | 40 (vm-menu-install-menus)) |
40 (and vm-mouse-track-summary | 41 (and (vm-mouse-support-possible-p) |
41 (vm-mouse-support-possible-p) | |
42 (vm-mouse-xemacs-mouse-p) | 42 (vm-mouse-xemacs-mouse-p) |
43 (add-hook 'mode-motion-hook 'mode-motion-highlight-line)) | 43 (add-hook 'mode-motion-hook 'mode-motion-highlight-line)) |
44 (if (and vm-mutable-frames (or vm-frame-per-folder vm-frame-per-summary)) | 44 (if (or vm-frame-per-folder vm-frame-per-summary) |
45 (vm-set-hooks-for-frame-deletion)) | 45 (vm-set-hooks-for-frame-deletion)) |
46 (run-hooks 'vm-summary-mode-hook) | 46 (run-hooks 'vm-summary-mode-hook) |
47 ;; Lucid Emacs apparently used this name | 47 ;; Lucid Emacs apparently used this name |
48 (run-hooks 'vm-summary-mode-hooks)) | 48 (run-hooks 'vm-summary-mode-hooks)) |
49 | 49 |
50 (fset 'vm-summary-mode 'vm-mode) | 50 (fset 'vm-summary-mode 'vm-mode) |
51 (put 'vm-summary-mode 'mode-class 'special) | 51 (put 'vm-summary-mode 'mode-class 'special) |
52 | 52 |
53 (defun vm-summarize (&optional display raise) | 53 (defun vm-summarize (&optional display) |
54 "Summarize the contents of the folder in a summary buffer. | 54 "Summarize the contents of the folder in a summary buffer. |
55 The format is as described by the variable vm-summary-format. Generally | 55 The format is as described by the variable vm-summary-format. Generally |
56 one line per message is most pleasing to the eye but this is not | 56 one line per message is most pleasing to the eye but this is not |
57 mandatory." | 57 mandatory." |
58 (interactive "p\np") | 58 (interactive "p") |
59 (vm-select-folder-buffer) | 59 (vm-select-folder-buffer) |
60 (vm-check-for-killed-summary) | 60 (vm-check-for-killed-summary) |
61 (if (null vm-summary-buffer) | 61 (if (null vm-summary-buffer) |
62 (let ((b (current-buffer)) | 62 (let ((b (current-buffer)) |
63 (read-only vm-folder-read-only)) | 63 (read-only vm-folder-read-only)) |
77 vm-folder-read-only read-only) | 77 vm-folder-read-only read-only) |
78 (vm-summary-mode-internal)) | 78 (vm-summary-mode-internal)) |
79 (vm-set-summary-redo-start-point t))) | 79 (vm-set-summary-redo-start-point t))) |
80 (if display | 80 (if display |
81 (save-excursion | 81 (save-excursion |
82 (vm-goto-new-summary-frame-maybe) | 82 (if vm-frame-per-summary |
83 (let ((w (vm-get-buffer-window vm-summary-buffer))) | |
84 (if (null w) | |
85 (progn | |
86 (vm-goto-new-frame 'summary) | |
87 (vm-set-hooks-for-frame-deletion)) | |
88 (save-excursion | |
89 (select-window w) | |
90 (and vm-warp-mouse-to-new-frame | |
91 (vm-warp-mouse-to-frame-maybe (vm-window-frame w))))))) | |
83 (vm-display vm-summary-buffer t | 92 (vm-display vm-summary-buffer t |
84 '(vm-summarize | 93 '(vm-summarize |
85 vm-summarize-other-frame) | 94 vm-summarize-other-frame) |
86 (list this-command) (not raise)) | 95 (list this-command)) |
87 ;; need to do this after any frame creation because the | 96 ;; need to do this after any frame creation because the |
88 ;; toolbar sets frame-specific height and width specifiers. | 97 ;; toolbar sets frame-specific height and width specifiers. |
89 (set-buffer vm-summary-buffer) | 98 (set-buffer vm-summary-buffer) |
90 (and (vm-toolbar-support-possible-p) vm-use-toolbar | 99 (and (vm-toolbar-support-possible-p) vm-use-toolbar |
91 (vm-toolbar-install-toolbar))) | 100 (vm-toolbar-install-toolbar))) |
107 mp | 116 mp |
108 (n 0) | 117 (n 0) |
109 ;; Just for laughs, make the update interval vary. | 118 ;; Just for laughs, make the update interval vary. |
110 (modulus (+ (% (vm-abs (random)) 11) 10)) | 119 (modulus (+ (% (vm-abs (random)) 11) 10)) |
111 (mouse-track-func | 120 (mouse-track-func |
112 (and vm-mouse-track-summary | 121 (and (vm-mouse-support-possible-p) |
113 (vm-mouse-support-possible-p) | |
114 (vm-mouse-fsfemacs-mouse-p) | 122 (vm-mouse-fsfemacs-mouse-p) |
115 (function vm-mouse-set-mouse-track-highlight))) | 123 (function vm-mouse-set-mouse-track-highlight))) |
116 summary) | 124 summary) |
117 (setq mp m-list) | 125 (setq mp m-list) |
118 (save-excursion | 126 (save-excursion |
139 (insert vm-summary-no-=>) | 147 (insert vm-summary-no-=>) |
140 (vm-tokenized-summary-insert (car mp) (vm-su-summary (car mp))) | 148 (vm-tokenized-summary-insert (car mp) (vm-su-summary (car mp))) |
141 (vm-set-su-end-of (car mp) (point)) | 149 (vm-set-su-end-of (car mp) (point)) |
142 (setq mp (cdr mp) n (1+ n)) | 150 (setq mp (cdr mp) n (1+ n)) |
143 (if (zerop (% n modulus)) | 151 (if (zerop (% n modulus)) |
144 (message "Generating summary... %d" n))) | 152 (vm-unsaved-message "Generating summary... %d" n))) |
145 ;; now convert the ints to markers. | 153 ;; now convert the ints to markers. |
146 (if (>= n modulus) | 154 (if (>= n modulus) |
147 (message "Generating summary markers... ")) | 155 (vm-unsaved-message "Generating summary markers... ")) |
148 (setq mp m-list) | 156 (setq mp m-list) |
149 (while mp | 157 (while mp |
150 (and mouse-track-func (funcall mouse-track-func | 158 (and mouse-track-func (funcall mouse-track-func |
151 (vm-su-start-of (car mp)) | 159 (vm-su-start-of (car mp)) |
152 (vm-su-end-of (car mp)))) | 160 (vm-su-end-of (car mp)))) |
154 (vm-set-su-end-of (car mp) (vm-marker (vm-su-end-of (car mp)))) | 162 (vm-set-su-end-of (car mp) (vm-marker (vm-su-end-of (car mp)))) |
155 (setq mp (cdr mp)))) | 163 (setq mp (cdr mp)))) |
156 (set-buffer-modified-p modified)) | 164 (set-buffer-modified-p modified)) |
157 (run-hooks 'vm-summary-redo-hook))) | 165 (run-hooks 'vm-summary-redo-hook))) |
158 (if (>= n modulus) | 166 (if (>= n modulus) |
159 (message "Generating summary... done")))) | 167 (vm-unsaved-message "Generating summary... done")))) |
160 | 168 |
161 (defun vm-do-needed-summary-rebuild () | 169 (defun vm-do-needed-summary-rebuild () |
162 (if (and vm-summary-redo-start-point vm-summary-buffer) | 170 (if (and vm-summary-redo-start-point vm-summary-buffer) |
163 (progn | 171 (progn |
164 (vm-copy-local-variables vm-summary-buffer 'vm-summary-show-threads) | 172 (vm-copy-local-variables vm-summary-buffer 'vm-summary-show-threads) |
178 (defun vm-update-message-summary (m) | 186 (defun vm-update-message-summary (m) |
179 (if (and (vm-su-start-of m) | 187 (if (and (vm-su-start-of m) |
180 (marker-buffer (vm-su-start-of m))) | 188 (marker-buffer (vm-su-start-of m))) |
181 (let ((modified (buffer-modified-p)) | 189 (let ((modified (buffer-modified-p)) |
182 (mouse-track-func | 190 (mouse-track-func |
183 (and vm-mouse-track-summary | 191 (and (vm-mouse-support-possible-p) |
184 (vm-mouse-support-possible-p) | |
185 (vm-mouse-fsfemacs-mouse-p) | 192 (vm-mouse-fsfemacs-mouse-p) |
186 (function vm-mouse-set-mouse-track-highlight))) | 193 (function vm-mouse-set-mouse-track-highlight))) |
187 summary) | 194 summary) |
188 (save-excursion | 195 (save-excursion |
189 (setq summary (vm-su-summary m)) | 196 (setq summary (vm-su-summary m)) |
194 (unwind-protect | 201 (unwind-protect |
195 (save-excursion | 202 (save-excursion |
196 (goto-char (vm-su-start-of m)) | 203 (goto-char (vm-su-start-of m)) |
197 (setq selected (not (looking-at vm-summary-no-=>))) | 204 (setq selected (not (looking-at vm-summary-no-=>))) |
198 ;; We do a little dance to update the text in | 205 ;; We do a little dance to update the text in |
199 ;; order to make the markers in the text do | 206 ;; order to make the markets in the text do |
200 ;; what we want. | 207 ;; what we want. |
201 ;; | 208 ;; |
202 ;; 1. We need to avoid having the su-start-of | 209 ;; 1. We need to avoid having the su-start-of |
203 ;; and su-end-of markers clumping together at | 210 ;; and su-end-of market clumping together at |
204 ;; the start position. | 211 ;; the start position. |
205 ;; | 212 ;; |
206 ;; 2. We want the window point marker (w->pointm | 213 ;; 2. We want the window point market (w->pointm |
207 ;; in the Emacs display code) to move to the | 214 ;; in the Emacs display code) to move to the |
208 ;; start of the summary entry if it is | 215 ;; start of the summary entry if it is |
209 ;; anywhere within the su-start-of to | 216 ;; anywhere within the su-start-of to |
210 ;; su-end-of region. | 217 ;; su-end-of region. |
211 ;; | 218 ;; |
235 | 242 |
236 (defun vm-set-summary-pointer (m) | 243 (defun vm-set-summary-pointer (m) |
237 (if vm-summary-buffer | 244 (if vm-summary-buffer |
238 (let ((w (vm-get-visible-buffer-window vm-summary-buffer)) | 245 (let ((w (vm-get-visible-buffer-window vm-summary-buffer)) |
239 (mouse-track-func | 246 (mouse-track-func |
240 (and vm-mouse-track-summary | 247 (and (vm-mouse-support-possible-p) |
241 (vm-mouse-support-possible-p) | |
242 (vm-mouse-fsfemacs-mouse-p) | 248 (vm-mouse-fsfemacs-mouse-p) |
243 (function vm-mouse-set-mouse-track-highlight))) | 249 (function vm-mouse-set-mouse-track-highlight))) |
244 (old-window nil)) | 250 (old-window nil)) |
245 (vm-save-buffer-excursion | 251 (vm-save-buffer-excursion |
246 (unwind-protect | 252 (unwind-protect |
281 (and w vm-auto-center-summary (vm-auto-center-summary)) | 287 (and w vm-auto-center-summary (vm-auto-center-summary)) |
282 (run-hooks 'vm-summary-pointer-update-hook))) | 288 (run-hooks 'vm-summary-pointer-update-hook))) |
283 (and old-window (select-window old-window))))))) | 289 (and old-window (select-window old-window))))))) |
284 | 290 |
285 (defun vm-summary-highlight-region (start end face) | 291 (defun vm-summary-highlight-region (start end face) |
286 (cond (vm-fsfemacs-19-p | 292 (cond ((fboundp 'make-overlay) |
287 (if (and vm-summary-overlay (overlay-buffer vm-summary-overlay)) | 293 (if (and vm-summary-overlay (overlay-buffer vm-summary-overlay)) |
288 (move-overlay vm-summary-overlay start end) | 294 (move-overlay vm-summary-overlay start end) |
289 (setq vm-summary-overlay (make-overlay start end)) | 295 (setq vm-summary-overlay (make-overlay start end)) |
290 (overlay-put vm-summary-overlay 'evaporate nil) | 296 (overlay-put vm-summary-overlay 'evaporate nil) |
291 (overlay-put vm-summary-overlay 'face face))) | 297 (overlay-put vm-summary-overlay 'face face))) |
292 (vm-xemacs-p | 298 ((fboundp 'make-extent) |
293 (if (and vm-summary-overlay (extent-end-position vm-summary-overlay)) | 299 (if (and vm-summary-overlay (extent-end-position vm-summary-overlay)) |
294 (set-extent-endpoints vm-summary-overlay start end) | 300 (set-extent-endpoints vm-summary-overlay start end) |
295 (setq vm-summary-overlay (make-extent start end)) | 301 (setq vm-summary-overlay (make-extent start end)) |
296 ;; the reason this isn't needed under FSF Emacs is | |
297 ;; that insert-before-markers also inserts before | |
298 ;; overlays! so a summary update of an entry just | |
299 ;; before this overlay in the summary buffer won't | |
300 ;; leak into the overlay, but it _will_ leak into an | |
301 ;; XEmacs extent. | |
302 (set-extent-property vm-summary-overlay 'start-open t) | |
303 (set-extent-property vm-summary-overlay 'detachable nil) | 302 (set-extent-property vm-summary-overlay 'detachable nil) |
304 (set-extent-property vm-summary-overlay 'face face))))) | 303 (set-extent-property vm-summary-overlay 'face face))))) |
305 | 304 |
306 (defun vm-auto-center-summary () | 305 (defun vm-auto-center-summary () |
307 (if vm-auto-center-summary | 306 (if vm-auto-center-summary |
324 (insert tokens) | 323 (insert tokens) |
325 (let (token) | 324 (let (token) |
326 (while tokens | 325 (while tokens |
327 (setq token (car tokens)) | 326 (setq token (car tokens)) |
328 (cond ((stringp token) | 327 (cond ((stringp token) |
329 (if vm-display-using-mime | 328 (insert token)) |
330 (insert (vm-decode-mime-encoded-words-in-string token)) | |
331 (insert token))) | |
332 ((eq token 'number) | 329 ((eq token 'number) |
333 (insert (vm-padded-number-of message))) | 330 (insert (vm-padded-number-of message))) |
334 ((eq token 'mark) | 331 ((eq token 'mark) |
335 (insert (vm-su-mark message))) | 332 (insert (vm-su-mark message))) |
336 ((eq token 'thread-indent) | 333 ((eq token 'thread-indent) |
443 ((= conv-spec ?*) | 440 ((= conv-spec ?*) |
444 (if tokenize | 441 (if tokenize |
445 (setq token ''mark) | 442 (setq token ''mark) |
446 (setq sexp (cons (list 'vm-su-mark | 443 (setq sexp (cons (list 'vm-su-mark |
447 'vm-su-message) sexp))))) | 444 'vm-su-message) sexp))))) |
448 (cond ((and (not token) vm-display-using-mime) | |
449 (setcar sexp | |
450 (list 'vm-decode-mime-encoded-words-in-string | |
451 (car sexp))))) | |
452 (cond ((and (not token) (match-beginning 1)) | 445 (cond ((and (not token) (match-beginning 1)) |
453 (setcar sexp | 446 (setcar sexp |
454 (list 'vm-left-justify-string (car sexp) | 447 (list 'vm-left-justify-string (car sexp) |
455 (string-to-int | 448 (string-to-int |
456 (substring format | 449 (substring format |
468 (list 'vm-truncate-string (car sexp) | 461 (list 'vm-truncate-string (car sexp) |
469 (string-to-int | 462 (string-to-int |
470 (substring format | 463 (substring format |
471 (match-beginning 4) | 464 (match-beginning 4) |
472 (match-end 4))))))) | 465 (match-end 4))))))) |
473 (cond ((and (not token) vm-display-using-mime) | |
474 (setcar sexp | |
475 (list 'vm-reencode-mime-encoded-words-in-string | |
476 (car sexp))))) | |
477 (setq sexp-fmt | 466 (setq sexp-fmt |
478 (cons (if token "" "%s") | 467 (cons (if token "" "%s") |
479 (cons (substring format | 468 (cons (substring format |
480 last-match-end | 469 last-match-end |
481 (match-beginning 0)) | 470 (match-beginning 0)) |
502 sexp nil | 491 sexp nil |
503 sexp-fmt nil))) | 492 sexp-fmt nil))) |
504 (put format-variable 'vm-compiled-format format) | 493 (put format-variable 'vm-compiled-format format) |
505 (put format-variable 'vm-format-sexp (if list (cons 'list list) sexp)))) | 494 (put format-variable 'vm-format-sexp (if list (cons 'list list) sexp)))) |
506 | 495 |
507 (defun vm-get-header-contents (message header-name-regexp &optional clump-sep) | 496 (defun vm-get-header-contents (message header-name-regexp) |
508 (let ((contents nil) | 497 (let ((contents nil) |
509 regexp) | 498 regexp) |
510 (setq regexp (concat "^\\(" header-name-regexp "\\)") | 499 (setq regexp (concat "^\\(" header-name-regexp "\\)") |
511 message (vm-real-message-of message)) | 500 message (vm-real-message-of message)) |
512 (save-excursion | 501 (save-excursion |
513 (set-buffer (vm-buffer-of (vm-real-message-of message))) | 502 (set-buffer (vm-buffer-of (vm-real-message-of message))) |
514 (save-restriction | 503 (save-restriction |
515 (widen) | 504 (widen) |
516 (goto-char (vm-headers-of message)) | 505 (goto-char (vm-headers-of message)) |
517 (let ((case-fold-search t)) | 506 (let ((case-fold-search t)) |
518 (while (and (or (null contents) clump-sep) | 507 (while (and (re-search-forward regexp (vm-text-of message) t) |
519 (re-search-forward regexp (vm-text-of message) t) | |
520 (save-excursion (goto-char (match-beginning 0)) | 508 (save-excursion (goto-char (match-beginning 0)) |
521 (vm-match-header))) | 509 (vm-match-header))) |
522 (if contents | 510 (if contents |
523 (setq contents | 511 (setq contents |
524 (concat contents clump-sep (vm-matched-header-contents))) | 512 (concat contents ", " (vm-matched-header-contents))) |
525 (setq contents (vm-matched-header-contents)))))) | 513 (setq contents (vm-matched-header-contents)))))) |
526 contents ))) | 514 contents ))) |
527 | 515 |
528 (defun vm-left-justify-string (string width) | 516 (defun vm-left-justify-string (string width) |
529 (if (>= (length string) width) | 517 (if (>= (length string) width) |
534 (if (>= (length string) width) | 522 (if (>= (length string) width) |
535 string | 523 string |
536 (concat (make-string (- width (length string)) ?\ ) string))) | 524 (concat (make-string (- width (length string)) ?\ ) string))) |
537 | 525 |
538 (defun vm-truncate-string (string width) | 526 (defun vm-truncate-string (string width) |
539 (cond | 527 (cond ((<= (length string) width) |
540 ;; doesn't work because the width of wide chars such as the Kanji | |
541 ;; glyphs as not even multiples of the default face's font width. | |
542 ;; ((fboundp 'char-width) | |
543 ;; (let ((i 0) | |
544 ;; (lim (length string)) | |
545 ;; (total 0)) | |
546 ;; (while (and (< i lim) (<= total width)) | |
547 ;; (setq total (+ total (char-width (aref string i))) | |
548 ;; i (1+ i))) | |
549 ;; (if (<= total width) | |
550 ;; string | |
551 ;; (substring string 0 (1- i))))) | |
552 ((<= (length string) width) | |
553 string) | 528 string) |
554 ((< width 0) | 529 ((< width 0) |
555 (substring string width)) | 530 (substring string width)) |
556 (t | 531 (t |
557 (substring string 0 width)))) | 532 (substring string 0 width)))) |
635 (if (not (memq (vm-message-type-of message) | 610 (if (not (memq (vm-message-type-of message) |
636 '(From_ From_-with-Content-Length))) | 611 '(From_ From_-with-Content-Length))) |
637 nil | 612 nil |
638 (save-excursion | 613 (save-excursion |
639 (set-buffer (vm-buffer-of (vm-real-message-of message))) | 614 (set-buffer (vm-buffer-of (vm-real-message-of message))) |
640 (save-excursion | 615 (save-restriction |
641 (save-restriction | 616 (widen) |
642 (widen) | 617 (goto-char (vm-start-of message)) |
643 (goto-char (vm-start-of message)) | 618 (let ((case-fold-search nil)) |
644 (let ((case-fold-search nil)) | 619 (if (or (looking-at |
645 (if (or (looking-at | 620 ;; special case this so that the "remote from blah" |
646 ;; special case this so that the "remote from blah" | 621 ;; isn't included. |
647 ;; isn't included. | 622 "From [^ \t\n]*[ \t]+\\([^ \t\n].*\\) remote from .*") |
648 "From [^ \t\n]*[ \t]+\\([^ \t\n].*\\) remote from .*") | 623 (looking-at "From [^ \t\n]*[ \t]+\\([^ \t\n].*\\)")) |
649 (looking-at "From [^ \t\n]*[ \t]+\\([^ \t\n].*\\)")) | 624 (vm-buffer-substring-no-properties |
650 (vm-buffer-substring-no-properties | 625 (match-beginning 1) |
651 (match-beginning 1) | 626 (match-end 1)))))))) |
652 (match-end 1))))))))) | |
653 | 627 |
654 (defun vm-parse-date (date) | 628 (defun vm-parse-date (date) |
655 (let ((weekday "") | 629 (let ((weekday "") |
656 (monthday "") | 630 (monthday "") |
657 (month "") | 631 (month "") |
732 (vm-set-monthday-of m (substring date (match-beginning 3) (match-end 3))) | 706 (vm-set-monthday-of m (substring date (match-beginning 3) (match-end 3))) |
733 (vm-set-hour-of m (substring date (match-beginning 4) (match-end 4))) | 707 (vm-set-hour-of m (substring date (match-beginning 4) (match-end 4))) |
734 (vm-set-year-of m (substring date (match-beginning 5) (match-end 5))) | 708 (vm-set-year-of m (substring date (match-beginning 5) (match-end 5))) |
735 (if (match-beginning 6) | 709 (if (match-beginning 6) |
736 (vm-set-zone-of m (substring date (match-beginning 6) | 710 (vm-set-zone-of m (substring date (match-beginning 6) |
737 (match-end 6))) | 711 (match-end 6))))) |
738 (vm-set-zone-of m ""))) | |
739 (t | 712 (t |
740 (setq vector (vm-parse-date date)) | 713 (setq vector (vm-parse-date date)) |
741 (vm-set-weekday-of m (elt vector 0)) | 714 (vm-set-weekday-of m (elt vector 0)) |
742 (vm-set-monthday-of m (elt vector 1)) | 715 (vm-set-monthday-of m (elt vector 1)) |
743 (vm-su-do-month m (elt vector 2)) | 716 (vm-su-do-month m (elt vector 2)) |
804 (if (not (memq (vm-message-type-of message) | 777 (if (not (memq (vm-message-type-of message) |
805 '(From_ From_-with-Content-Length))) | 778 '(From_ From_-with-Content-Length))) |
806 nil | 779 nil |
807 (save-excursion | 780 (save-excursion |
808 (set-buffer (vm-buffer-of message)) | 781 (set-buffer (vm-buffer-of message)) |
809 (save-excursion | 782 (save-restriction |
810 (save-restriction | 783 (widen) |
811 (widen) | 784 (goto-char (vm-start-of message)) |
812 (goto-char (vm-start-of message)) | 785 (let ((case-fold-search nil)) |
813 (let ((case-fold-search nil)) | 786 (if (looking-at "From \\([^ \t\n]+\\)") |
814 (if (looking-at "From \\([^ \t\n]+\\)") | 787 (vm-buffer-substring-no-properties |
815 (vm-buffer-substring-no-properties | 788 (match-beginning 1) |
816 (match-beginning 1) | 789 (match-end 1)))))))) |
817 (match-end 1))))))))) | |
818 | 790 |
819 (defun vm-su-do-author (m) | 791 (defun vm-su-do-author (m) |
820 (let ((full-name (vm-get-header-contents m "Full-Name:")) | 792 (let ((full-name (vm-get-header-contents m "Full-Name:")) |
821 (from (or (vm-get-header-contents m "From:" ", ") | 793 (from (or (vm-get-header-contents m "From:") |
822 (vm-grok-From_-author m))) | 794 (vm-grok-From_-author m))) |
823 pair i) | 795 pair) |
824 (if (and full-name (string-match "^[ \t]*$" full-name)) | 796 (if (and full-name (string-match "^[ \t]*$" full-name)) |
825 (setq full-name nil)) | 797 (setq full-name nil)) |
826 (if (null from) | 798 (if (null from) |
827 (progn | 799 (progn |
828 (setq from "???") | 800 (setq from "???") |
832 from (or (nth 1 pair) from) | 804 from (or (nth 1 pair) from) |
833 full-name (or full-name (nth 0 pair) from))) | 805 full-name (or full-name (nth 0 pair) from))) |
834 (if (string-match "\\`\"\\([^\"]+\\)\"\\'" full-name) | 806 (if (string-match "\\`\"\\([^\"]+\\)\"\\'" full-name) |
835 (setq full-name | 807 (setq full-name |
836 (substring full-name (match-beginning 1) (match-end 1)))) | 808 (substring full-name (match-beginning 1) (match-end 1)))) |
837 (while (setq i (string-match "\n" full-name i)) | |
838 (aset full-name i ?\ )) | |
839 (vm-set-full-name-of m full-name) | 809 (vm-set-full-name-of m full-name) |
840 (vm-set-from-of m from))) | 810 (vm-set-from-of m from))) |
841 | 811 |
842 (defun vm-default-chop-full-name (address) | 812 (defun vm-default-chop-full-name (address) |
843 (let ((from address) | 813 (let ((from address) |
890 ;; it passed the tests | 860 ;; it passed the tests |
891 (setq vm-chop-full-name-function 'mail-extract-address-components)) | 861 (setq vm-chop-full-name-function 'mail-extract-address-components)) |
892 (funcall vm-chop-full-name-function address))) | 862 (funcall vm-chop-full-name-function address))) |
893 | 863 |
894 (defun vm-su-do-recipients (m) | 864 (defun vm-su-do-recipients (m) |
895 (let ((mail-use-rfc822 t) i names addresses to cc all list full-name) | 865 (let ((mail-use-rfc822 t) names addresses to cc all list) |
896 (setq to (or (vm-get-header-contents m "To:" ", ") | 866 (setq to (or (vm-get-header-contents m "To:") |
897 (vm-get-header-contents m "Apparently-To:" ", ") | 867 (vm-get-header-contents m "Apparently-To:") |
898 ;; desperation.... | 868 ;; desperation.... |
899 (user-login-name)) | 869 (user-login-name)) |
900 cc (vm-get-header-contents m "Cc:" ", ") | 870 cc (vm-get-header-contents m "Cc:") |
901 all to | 871 all to |
902 all (if all (concat all ", " cc) cc) | 872 all (if all (concat all ", " cc) cc) |
903 addresses (rfc822-addresses all)) | 873 addresses (rfc822-addresses all)) |
904 (setq list (vm-parse-addresses all)) | 874 (setq list (vm-parse-addresses all)) |
905 (while list | 875 (while list |
906 ;; Just like vm-su-do-author: | 876 (cond ((string= (car list) "")) |
907 (setq full-name (or (nth 0 (funcall vm-chop-full-name-function | 877 ((string-match "^\\(\"?\\([^<]+[^ \t\n\"]\\)\"?[ \t\n]+\\)?<\\([^>]+\\)>" |
908 (car list))) | 878 (car list)) |
909 (car list))) | 879 (if (match-beginning 2) |
910 ;; If double quoted are around the full name, fish the name out. | 880 (setq names |
911 (if (string-match "\\`\"\\([^\"]+\\)\"\\'" full-name) | 881 (cons |
912 (setq full-name | 882 (substring (car list) (match-beginning 2) |
913 (substring full-name (match-beginning 1) (match-end 1)))) | 883 (match-end 2)) |
914 (while (setq i (string-match "\n" full-name i)) | 884 names)) |
915 (aset full-name i ?\ )) | 885 (setq names |
916 (setq names (cons full-name names)) | 886 (cons |
887 (substring (car list) (match-beginning 3) | |
888 (match-end 3)) | |
889 names)))) | |
890 ((string-match "[\000-\177]*(\\([^)]+\\))[\000-\177]*" (car list)) | |
891 (setq names | |
892 (cons (substring (car list) (match-beginning 1) | |
893 (match-end 1)) | |
894 names))) | |
895 (t (setq names (cons (car list) names)))) | |
917 (setq list (cdr list))) | 896 (setq list (cdr list))) |
918 (setq names (nreverse names)) ; added by jwz for fixed vm-parse-addresses | 897 (setq names (nreverse names)) ; added by jwz for fixed vm-parse-addresses |
919 (vm-set-to-of m (mapconcat 'identity addresses ", ")) | 898 (vm-set-to-of m (mapconcat 'identity addresses ", ")) |
920 (vm-set-to-names-of m (mapconcat 'identity names ", ")))) | 899 (vm-set-to-names-of m (mapconcat 'identity names ", ")))) |
921 | 900 |
927 | 906 |
928 (defun vm-su-message-id (m) | 907 (defun vm-su-message-id (m) |
929 (or (vm-message-id-of m) | 908 (or (vm-message-id-of m) |
930 (vm-set-message-id-of | 909 (vm-set-message-id-of |
931 m | 910 m |
932 (or (let ((id (vm-get-header-contents m "Message-Id:"))) | 911 (or (vm-get-header-contents m "Message-Id:") |
933 (and id (car (vm-parse id "[^<]*\\(<[^>]+>\\)")))) | |
934 ;; try running md5 on the message body to produce an ID | 912 ;; try running md5 on the message body to produce an ID |
935 ;; better than nothing. | 913 ;; better than nothing. |
936 (save-excursion | 914 (save-excursion |
937 (set-buffer (vm-buffer-of (vm-real-message-of m))) | 915 (set-buffer (vm-buffer-of (vm-real-message-of m))) |
938 (save-restriction | 916 (save-restriction |
961 | 939 |
962 (defun vm-su-subject (m) | 940 (defun vm-su-subject (m) |
963 (or (vm-subject-of m) | 941 (or (vm-subject-of m) |
964 (vm-set-subject-of | 942 (vm-set-subject-of |
965 m | 943 m |
966 (let ((subject (or (vm-get-header-contents m "Subject:" " ") "")) | 944 (let ((subject (or (vm-get-header-contents m "Subject:") "")) |
967 (i nil)) | 945 (i nil)) |
968 (while (setq i (string-match "\n" subject i)) | 946 (if vm-summary-subject-no-newlines |
969 (aset subject i ?\ )) | 947 (while (setq i (string-match "\n" subject i)) |
948 (aset subject i ?\ ))) | |
970 subject )))) | 949 subject )))) |
971 | 950 |
972 (defun vm-su-summary (m) | 951 (defun vm-su-summary (m) |
973 (if (and (vm-virtual-message-p m) (not (vm-virtual-messages-of m))) | 952 (if (and (vm-virtual-message-p m) (not (vm-virtual-messages-of m))) |
974 (or (vm-virtual-summary-of m) | 953 (or (vm-virtual-summary-of m) |
985 (defun vm-fix-my-summary!!! () | 964 (defun vm-fix-my-summary!!! () |
986 (interactive) | 965 (interactive) |
987 (vm-select-folder-buffer) | 966 (vm-select-folder-buffer) |
988 (vm-check-for-killed-summary) | 967 (vm-check-for-killed-summary) |
989 (vm-error-if-folder-empty) | 968 (vm-error-if-folder-empty) |
990 (message "Fixing your summary...") | 969 (vm-unsaved-message "Fixing your summary...") |
991 (let ((mp vm-message-list)) | 970 (let ((mp vm-message-list)) |
992 (while mp | 971 (while mp |
993 (vm-set-summary-of (car mp) nil) | 972 (vm-set-summary-of (car mp) nil) |
994 (vm-mark-for-summary-update (car mp)) | 973 (vm-mark-for-summary-update (car mp)) |
974 (vm-stuff-attributes (car mp)) | |
995 (setq mp (cdr mp))) | 975 (setq mp (cdr mp))) |
996 (vm-stuff-folder-attributes nil) | |
997 (set-buffer-modified-p t) | 976 (set-buffer-modified-p t) |
998 (vm-update-summary-and-mode-line)) | 977 (vm-update-summary-and-mode-line)) |
999 (message "Fixing your summary... done")) | 978 (vm-unsaved-message "Fixing your summary... done")) |
1000 | 979 |
1001 (defun vm-su-thread-indent (m) | 980 (defun vm-su-thread-indent (m) |
1002 (if (natnump vm-summary-thread-indent-level) | 981 (if (natnump vm-summary-thread-indent-level) |
1003 (make-string (* (vm-th-thread-indentation m) | 982 (make-string (* (vm-th-thread-indentation m) |
1004 vm-summary-thread-indent-level) | 983 vm-summary-thread-indent-level) |