Mercurial > hg > xemacs-beta
comparison lisp/vm/vm-summary.el @ 20:859a2309aef8 r19-15b93
Import from CVS: tag r19-15b93
author | cvs |
---|---|
date | Mon, 13 Aug 2007 08:50:05 +0200 |
parents | 376386a54a3c |
children | 4103f0995bd7 |
comparison
equal
deleted
inserted
replaced
19:ac1f612d5250 | 20:859a2309aef8 |
---|---|
1 ;;; Summary gathering and formatting routines for VM | 1 ;;; Summary gathering and formatting routines for VM |
2 ;;; Copyright (C) 1989, 1990, 1993, 1994, 1995 Kyle E. Jones | 2 ;;; Copyright (C) 1989-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 | 25 mode-popup-menu (and vm-use-menus vm-popup-menu-on-mouse-3 |
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 "") |
36 scrollbar-height | 36 scrollbar-height |
37 (set-specifier scrollbar-height (cons (current-buffer) 0))) | 37 (set-specifier scrollbar-height (cons (current-buffer) 0))) |
38 (use-local-map vm-summary-mode-map) | 38 (use-local-map vm-summary-mode-map) |
39 (and (vm-menu-support-possible-p) | 39 (and (vm-menu-support-possible-p) |
40 (vm-menu-install-menus)) | 40 (vm-menu-install-menus)) |
41 (and (vm-mouse-support-possible-p) | 41 (and vm-mouse-track-summary |
42 (vm-mouse-support-possible-p) | |
42 (vm-mouse-xemacs-mouse-p) | 43 (vm-mouse-xemacs-mouse-p) |
43 (add-hook 'mode-motion-hook 'mode-motion-highlight-line)) | 44 (add-hook 'mode-motion-hook 'mode-motion-highlight-line)) |
44 (if (or vm-frame-per-folder vm-frame-per-summary) | 45 (if (or vm-frame-per-folder vm-frame-per-summary) |
45 (vm-set-hooks-for-frame-deletion)) | 46 (vm-set-hooks-for-frame-deletion)) |
46 (run-hooks 'vm-summary-mode-hook) | 47 (run-hooks 'vm-summary-mode-hook) |
48 (run-hooks 'vm-summary-mode-hooks)) | 49 (run-hooks 'vm-summary-mode-hooks)) |
49 | 50 |
50 (fset 'vm-summary-mode 'vm-mode) | 51 (fset 'vm-summary-mode 'vm-mode) |
51 (put 'vm-summary-mode 'mode-class 'special) | 52 (put 'vm-summary-mode 'mode-class 'special) |
52 | 53 |
53 (defun vm-summarize (&optional display) | 54 (defun vm-summarize (&optional display raise) |
54 "Summarize the contents of the folder in a summary buffer. | 55 "Summarize the contents of the folder in a summary buffer. |
55 The format is as described by the variable vm-summary-format. Generally | 56 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 | 57 one line per message is most pleasing to the eye but this is not |
57 mandatory." | 58 mandatory." |
58 (interactive "p") | 59 (interactive "p\np") |
59 (vm-select-folder-buffer) | 60 (vm-select-folder-buffer) |
60 (vm-check-for-killed-summary) | 61 (vm-check-for-killed-summary) |
61 (if (null vm-summary-buffer) | 62 (if (null vm-summary-buffer) |
62 (let ((b (current-buffer)) | 63 (let ((b (current-buffer)) |
63 (read-only vm-folder-read-only)) | 64 (read-only vm-folder-read-only)) |
77 vm-folder-read-only read-only) | 78 vm-folder-read-only read-only) |
78 (vm-summary-mode-internal)) | 79 (vm-summary-mode-internal)) |
79 (vm-set-summary-redo-start-point t))) | 80 (vm-set-summary-redo-start-point t))) |
80 (if display | 81 (if display |
81 (save-excursion | 82 (save-excursion |
82 (if vm-frame-per-summary | 83 (vm-goto-new-summary-frame-maybe) |
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))))))) | |
92 (vm-display vm-summary-buffer t | 84 (vm-display vm-summary-buffer t |
93 '(vm-summarize | 85 '(vm-summarize |
94 vm-summarize-other-frame) | 86 vm-summarize-other-frame) |
95 (list this-command)) | 87 (list this-command) (not raise)) |
96 ;; need to do this after any frame creation because the | 88 ;; need to do this after any frame creation because the |
97 ;; toolbar sets frame-specific height and width specifiers. | 89 ;; toolbar sets frame-specific height and width specifiers. |
98 (set-buffer vm-summary-buffer) | 90 (set-buffer vm-summary-buffer) |
99 (and (vm-toolbar-support-possible-p) vm-use-toolbar | 91 (and (vm-toolbar-support-possible-p) vm-use-toolbar |
100 (vm-toolbar-install-toolbar))) | 92 (vm-toolbar-install-toolbar))) |
116 mp | 108 mp |
117 (n 0) | 109 (n 0) |
118 ;; Just for laughs, make the update interval vary. | 110 ;; Just for laughs, make the update interval vary. |
119 (modulus (+ (% (vm-abs (random)) 11) 10)) | 111 (modulus (+ (% (vm-abs (random)) 11) 10)) |
120 (mouse-track-func | 112 (mouse-track-func |
121 (and (vm-mouse-support-possible-p) | 113 (and vm-mouse-track-summary |
114 (vm-mouse-support-possible-p) | |
122 (vm-mouse-fsfemacs-mouse-p) | 115 (vm-mouse-fsfemacs-mouse-p) |
123 (function vm-mouse-set-mouse-track-highlight))) | 116 (function vm-mouse-set-mouse-track-highlight))) |
124 summary) | 117 summary) |
125 (setq mp m-list) | 118 (setq mp m-list) |
126 (save-excursion | 119 (save-excursion |
186 (defun vm-update-message-summary (m) | 179 (defun vm-update-message-summary (m) |
187 (if (and (vm-su-start-of m) | 180 (if (and (vm-su-start-of m) |
188 (marker-buffer (vm-su-start-of m))) | 181 (marker-buffer (vm-su-start-of m))) |
189 (let ((modified (buffer-modified-p)) | 182 (let ((modified (buffer-modified-p)) |
190 (mouse-track-func | 183 (mouse-track-func |
191 (and (vm-mouse-support-possible-p) | 184 (and vm-mouse-track-summary |
185 (vm-mouse-support-possible-p) | |
192 (vm-mouse-fsfemacs-mouse-p) | 186 (vm-mouse-fsfemacs-mouse-p) |
193 (function vm-mouse-set-mouse-track-highlight))) | 187 (function vm-mouse-set-mouse-track-highlight))) |
194 summary) | 188 summary) |
195 (save-excursion | 189 (save-excursion |
196 (setq summary (vm-su-summary m)) | 190 (setq summary (vm-su-summary m)) |
201 (unwind-protect | 195 (unwind-protect |
202 (save-excursion | 196 (save-excursion |
203 (goto-char (vm-su-start-of m)) | 197 (goto-char (vm-su-start-of m)) |
204 (setq selected (not (looking-at vm-summary-no-=>))) | 198 (setq selected (not (looking-at vm-summary-no-=>))) |
205 ;; We do a little dance to update the text in | 199 ;; We do a little dance to update the text in |
206 ;; order to make the markets in the text do | 200 ;; order to make the markers in the text do |
207 ;; what we want. | 201 ;; what we want. |
208 ;; | 202 ;; |
209 ;; 1. We need to avoid having the su-start-of | 203 ;; 1. We need to avoid having the su-start-of |
210 ;; and su-end-of market clumping together at | 204 ;; and su-end-of market clumping together at |
211 ;; the start position. | 205 ;; the start position. |
242 | 236 |
243 (defun vm-set-summary-pointer (m) | 237 (defun vm-set-summary-pointer (m) |
244 (if vm-summary-buffer | 238 (if vm-summary-buffer |
245 (let ((w (vm-get-visible-buffer-window vm-summary-buffer)) | 239 (let ((w (vm-get-visible-buffer-window vm-summary-buffer)) |
246 (mouse-track-func | 240 (mouse-track-func |
247 (and (vm-mouse-support-possible-p) | 241 (and vm-mouse-track-summary |
242 (vm-mouse-support-possible-p) | |
248 (vm-mouse-fsfemacs-mouse-p) | 243 (vm-mouse-fsfemacs-mouse-p) |
249 (function vm-mouse-set-mouse-track-highlight))) | 244 (function vm-mouse-set-mouse-track-highlight))) |
250 (old-window nil)) | 245 (old-window nil)) |
251 (vm-save-buffer-excursion | 246 (vm-save-buffer-excursion |
252 (unwind-protect | 247 (unwind-protect |
297 (overlay-put vm-summary-overlay 'face face))) | 292 (overlay-put vm-summary-overlay 'face face))) |
298 ((fboundp 'make-extent) | 293 ((fboundp 'make-extent) |
299 (if (and vm-summary-overlay (extent-end-position vm-summary-overlay)) | 294 (if (and vm-summary-overlay (extent-end-position vm-summary-overlay)) |
300 (set-extent-endpoints vm-summary-overlay start end) | 295 (set-extent-endpoints vm-summary-overlay start end) |
301 (setq vm-summary-overlay (make-extent start end)) | 296 (setq vm-summary-overlay (make-extent start end)) |
297 ;; the reason this isn't needed under FSF Emacs is | |
298 ;; that insert-before-marker also inserts before | |
299 ;; overlays! so a summary update of an entry just | |
300 ;; before this overlay in the summary buffer won't | |
301 ;; leak into the overlay, but it _will_ leak into an | |
302 ;; XEmacs extent. | |
303 (set-extent-property vm-summary-overlay 'start-open t) | |
302 (set-extent-property vm-summary-overlay 'detachable nil) | 304 (set-extent-property vm-summary-overlay 'detachable nil) |
303 (set-extent-property vm-summary-overlay 'face face))))) | 305 (set-extent-property vm-summary-overlay 'face face))))) |
304 | 306 |
305 (defun vm-auto-center-summary () | 307 (defun vm-auto-center-summary () |
306 (if vm-auto-center-summary | 308 (if vm-auto-center-summary |
491 sexp nil | 493 sexp nil |
492 sexp-fmt nil))) | 494 sexp-fmt nil))) |
493 (put format-variable 'vm-compiled-format format) | 495 (put format-variable 'vm-compiled-format format) |
494 (put format-variable 'vm-format-sexp (if list (cons 'list list) sexp)))) | 496 (put format-variable 'vm-format-sexp (if list (cons 'list list) sexp)))) |
495 | 497 |
496 (defun vm-get-header-contents (message header-name-regexp) | 498 (defun vm-get-header-contents (message header-name-regexp &optional clump-sep) |
497 (let ((contents nil) | 499 (let ((contents nil) |
498 regexp) | 500 regexp) |
499 (setq regexp (concat "^\\(" header-name-regexp "\\)") | 501 (setq regexp (concat "^\\(" header-name-regexp "\\)") |
500 message (vm-real-message-of message)) | 502 message (vm-real-message-of message)) |
501 (save-excursion | 503 (save-excursion |
502 (set-buffer (vm-buffer-of (vm-real-message-of message))) | 504 (set-buffer (vm-buffer-of (vm-real-message-of message))) |
503 (save-restriction | 505 (save-restriction |
504 (widen) | 506 (widen) |
505 (goto-char (vm-headers-of message)) | 507 (goto-char (vm-headers-of message)) |
506 (let ((case-fold-search t)) | 508 (let ((case-fold-search t)) |
507 (while (and (re-search-forward regexp (vm-text-of message) t) | 509 (while (and (or (null contents) clump-sep) |
510 (re-search-forward regexp (vm-text-of message) t) | |
508 (save-excursion (goto-char (match-beginning 0)) | 511 (save-excursion (goto-char (match-beginning 0)) |
509 (vm-match-header))) | 512 (vm-match-header))) |
510 (if contents | 513 (if contents |
511 (setq contents | 514 (setq contents |
512 (concat contents ", " (vm-matched-header-contents))) | 515 (concat contents clump-sep (vm-matched-header-contents))) |
513 (setq contents (vm-matched-header-contents)))))) | 516 (setq contents (vm-matched-header-contents)))))) |
514 contents ))) | 517 contents ))) |
515 | 518 |
516 (defun vm-left-justify-string (string width) | 519 (defun vm-left-justify-string (string width) |
517 (if (>= (length string) width) | 520 (if (>= (length string) width) |
610 (if (not (memq (vm-message-type-of message) | 613 (if (not (memq (vm-message-type-of message) |
611 '(From_ From_-with-Content-Length))) | 614 '(From_ From_-with-Content-Length))) |
612 nil | 615 nil |
613 (save-excursion | 616 (save-excursion |
614 (set-buffer (vm-buffer-of (vm-real-message-of message))) | 617 (set-buffer (vm-buffer-of (vm-real-message-of message))) |
615 (save-restriction | 618 (save-excursion |
616 (widen) | 619 (save-restriction |
617 (goto-char (vm-start-of message)) | 620 (widen) |
618 (let ((case-fold-search nil)) | 621 (goto-char (vm-start-of message)) |
619 (if (or (looking-at | 622 (let ((case-fold-search nil)) |
620 ;; special case this so that the "remote from blah" | 623 (if (or (looking-at |
621 ;; isn't included. | 624 ;; special case this so that the "remote from blah" |
622 "From [^ \t\n]*[ \t]+\\([^ \t\n].*\\) remote from .*") | 625 ;; isn't included. |
623 (looking-at "From [^ \t\n]*[ \t]+\\([^ \t\n].*\\)")) | 626 "From [^ \t\n]*[ \t]+\\([^ \t\n].*\\) remote from .*") |
624 (vm-buffer-substring-no-properties | 627 (looking-at "From [^ \t\n]*[ \t]+\\([^ \t\n].*\\)")) |
625 (match-beginning 1) | 628 (vm-buffer-substring-no-properties |
626 (match-end 1)))))))) | 629 (match-beginning 1) |
630 (match-end 1))))))))) | |
627 | 631 |
628 (defun vm-parse-date (date) | 632 (defun vm-parse-date (date) |
629 (let ((weekday "") | 633 (let ((weekday "") |
630 (monthday "") | 634 (monthday "") |
631 (month "") | 635 (month "") |
777 (if (not (memq (vm-message-type-of message) | 781 (if (not (memq (vm-message-type-of message) |
778 '(From_ From_-with-Content-Length))) | 782 '(From_ From_-with-Content-Length))) |
779 nil | 783 nil |
780 (save-excursion | 784 (save-excursion |
781 (set-buffer (vm-buffer-of message)) | 785 (set-buffer (vm-buffer-of message)) |
782 (save-restriction | 786 (save-excursion |
783 (widen) | 787 (save-restriction |
784 (goto-char (vm-start-of message)) | 788 (widen) |
785 (let ((case-fold-search nil)) | 789 (goto-char (vm-start-of message)) |
786 (if (looking-at "From \\([^ \t\n]+\\)") | 790 (let ((case-fold-search nil)) |
787 (vm-buffer-substring-no-properties | 791 (if (looking-at "From \\([^ \t\n]+\\)") |
788 (match-beginning 1) | 792 (vm-buffer-substring-no-properties |
789 (match-end 1)))))))) | 793 (match-beginning 1) |
794 (match-end 1))))))))) | |
790 | 795 |
791 (defun vm-su-do-author (m) | 796 (defun vm-su-do-author (m) |
792 (let ((full-name (vm-get-header-contents m "Full-Name:")) | 797 (let ((full-name (vm-get-header-contents m "Full-Name:")) |
793 (from (or (vm-get-header-contents m "From:") | 798 (from (or (vm-get-header-contents m "From:" ", ") |
794 (vm-grok-From_-author m))) | 799 (vm-grok-From_-author m))) |
795 pair) | 800 pair i) |
796 (if (and full-name (string-match "^[ \t]*$" full-name)) | 801 (if (and full-name (string-match "^[ \t]*$" full-name)) |
797 (setq full-name nil)) | 802 (setq full-name nil)) |
798 (if (null from) | 803 (if (null from) |
799 (progn | 804 (progn |
800 (setq from "???") | 805 (setq from "???") |
804 from (or (nth 1 pair) from) | 809 from (or (nth 1 pair) from) |
805 full-name (or full-name (nth 0 pair) from))) | 810 full-name (or full-name (nth 0 pair) from))) |
806 (if (string-match "\\`\"\\([^\"]+\\)\"\\'" full-name) | 811 (if (string-match "\\`\"\\([^\"]+\\)\"\\'" full-name) |
807 (setq full-name | 812 (setq full-name |
808 (substring full-name (match-beginning 1) (match-end 1)))) | 813 (substring full-name (match-beginning 1) (match-end 1)))) |
814 (setq full-name (vm-decode-mime-encoded-words-maybe full-name)) | |
815 (while (setq i (string-match "\n" full-name i)) | |
816 (aset full-name i ?\ )) | |
809 (vm-set-full-name-of m full-name) | 817 (vm-set-full-name-of m full-name) |
810 (vm-set-from-of m from))) | 818 (vm-set-from-of m from))) |
811 | 819 |
812 (defun vm-default-chop-full-name (address) | 820 (defun vm-default-chop-full-name (address) |
813 (let ((from address) | 821 (let ((from address) |
860 ;; it passed the tests | 868 ;; it passed the tests |
861 (setq vm-chop-full-name-function 'mail-extract-address-components)) | 869 (setq vm-chop-full-name-function 'mail-extract-address-components)) |
862 (funcall vm-chop-full-name-function address))) | 870 (funcall vm-chop-full-name-function address))) |
863 | 871 |
864 (defun vm-su-do-recipients (m) | 872 (defun vm-su-do-recipients (m) |
865 (let ((mail-use-rfc822 t) names addresses to cc all list) | 873 (let ((mail-use-rfc822 t) i names addresses to cc all list full-name) |
866 (setq to (or (vm-get-header-contents m "To:") | 874 (setq to (or (vm-get-header-contents m "To:" ", ") |
867 (vm-get-header-contents m "Apparently-To:") | 875 (vm-get-header-contents m "Apparently-To:" ", ") |
868 ;; desperation.... | 876 ;; desperation.... |
869 (user-login-name)) | 877 (user-login-name)) |
870 cc (vm-get-header-contents m "Cc:") | 878 cc (vm-get-header-contents m "Cc:" ", ") |
871 all to | 879 all to |
872 all (if all (concat all ", " cc) cc) | 880 all (if all (concat all ", " cc) cc) |
873 addresses (rfc822-addresses all)) | 881 addresses (rfc822-addresses all)) |
874 (setq list (vm-parse-addresses all)) | 882 (setq list (vm-parse-addresses all)) |
875 (while list | 883 (while list |
876 (cond ((string= (car list) "")) | 884 ;; Just like vm-su-do-author: |
877 ((string-match "^\\(\"?\\([^<]+[^ \t\n\"]\\)\"?[ \t\n]+\\)?<\\([^>]+\\)>" | 885 (setq full-name (or (nth 0 (funcall vm-chop-full-name-function |
878 (car list)) | 886 (car list))) |
879 (if (match-beginning 2) | 887 (car list))) |
880 (setq names | 888 ;; If double quoted are around the full name, fish the name out. |
881 (cons | 889 (if (string-match "\\`\"\\([^\"]+\\)\"\\'" full-name) |
882 (substring (car list) (match-beginning 2) | 890 (setq full-name |
883 (match-end 2)) | 891 (substring full-name (match-beginning 1) (match-end 1)))) |
884 names)) | 892 (setq full-name (vm-decode-mime-encoded-words-maybe full-name)) |
885 (setq names | 893 (while (setq i (string-match "\n" full-name i)) |
886 (cons | 894 (aset full-name i ?\ )) |
887 (substring (car list) (match-beginning 3) | 895 (setq names (cons full-name names)) |
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)))) | |
896 (setq list (cdr list))) | 896 (setq list (cdr list))) |
897 (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 |
898 (vm-set-to-of m (mapconcat 'identity addresses ", ")) | 898 (vm-set-to-of m (mapconcat 'identity addresses ", ")) |
899 (vm-set-to-names-of m (mapconcat 'identity names ", ")))) | 899 (vm-set-to-names-of m (mapconcat 'identity names ", ")))) |
900 | 900 |
939 | 939 |
940 (defun vm-su-subject (m) | 940 (defun vm-su-subject (m) |
941 (or (vm-subject-of m) | 941 (or (vm-subject-of m) |
942 (vm-set-subject-of | 942 (vm-set-subject-of |
943 m | 943 m |
944 (let ((subject (or (vm-get-header-contents m "Subject:") "")) | 944 (let ((subject (or (vm-get-header-contents m "Subject:" " ") "")) |
945 (i nil)) | 945 (i nil)) |
946 (if vm-summary-subject-no-newlines | 946 (setq subject (vm-decode-mime-encoded-words-maybe subject)) |
947 (while (setq i (string-match "\n" subject i)) | 947 (while (setq i (string-match "\n" subject i)) |
948 (aset subject i ?\ ))) | 948 (aset subject i ?\ )) |
949 subject )))) | 949 subject )))) |
950 | 950 |
951 (defun vm-su-summary (m) | 951 (defun vm-su-summary (m) |
952 (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))) |
953 (or (vm-virtual-summary-of m) | 953 (or (vm-virtual-summary-of m) |
969 (vm-unsaved-message "Fixing your summary...") | 969 (vm-unsaved-message "Fixing your summary...") |
970 (let ((mp vm-message-list)) | 970 (let ((mp vm-message-list)) |
971 (while mp | 971 (while mp |
972 (vm-set-summary-of (car mp) nil) | 972 (vm-set-summary-of (car mp) nil) |
973 (vm-mark-for-summary-update (car mp)) | 973 (vm-mark-for-summary-update (car mp)) |
974 (vm-stuff-attributes (car mp)) | |
975 (setq mp (cdr mp))) | 974 (setq mp (cdr mp))) |
975 (vm-stuff-folder-attributes nil) | |
976 (set-buffer-modified-p t) | 976 (set-buffer-modified-p t) |
977 (vm-update-summary-and-mode-line)) | 977 (vm-update-summary-and-mode-line)) |
978 (vm-unsaved-message "Fixing your summary... done")) | 978 (vm-unsaved-message "Fixing your summary... done")) |
979 | 979 |
980 (defun vm-su-thread-indent (m) | 980 (defun vm-su-thread-indent (m) |