comparison lisp/vm/vm-page.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 ;;; Commands to move around within a VM message 1 ;;; Commands to move around within a VM message
2 ;;; Copyright (C) 1989, 1990, 1991, 1993, 1994 Kyle E. Jones 2 ;;; Copyright (C) 1989-1997 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.
26 (interactive "P") 26 (interactive "P")
27 (let ((mp-changed (vm-follow-summary-cursor)) 27 (let ((mp-changed (vm-follow-summary-cursor))
28 (was-invisible nil)) 28 (was-invisible nil))
29 (vm-select-folder-buffer) 29 (vm-select-folder-buffer)
30 (vm-check-for-killed-summary) 30 (vm-check-for-killed-summary)
31 (vm-check-for-killed-presentation)
31 (vm-error-if-folder-empty) 32 (vm-error-if-folder-empty)
32 (if (null (vm-get-visible-buffer-window (current-buffer))) 33 (and vm-presentation-buffer
33 (let ((point (point))) 34 (set-buffer vm-presentation-buffer))
34 (vm-display (current-buffer) t 35 (let ((point (point))
35 '(vm-scroll-forward vm-scroll-backward) 36 (w (vm-get-visible-buffer-window (current-buffer))))
36 (list this-command 'reading-message)) 37 (if (or (null w)
37 ;; window start sticks to end of clip region when clip 38 (not (vm-frame-totally-visible-p (vm-window-frame w))))
38 ;; region moves back past it in the buffer. fix it. 39 (progn
39 (let ((w (vm-get-visible-buffer-window (current-buffer)))) 40 (vm-display (current-buffer) t
41 '(vm-scroll-forward vm-scroll-backward)
42 (list this-command 'reading-message))
43 ;; window start sticks to end of clip region when clip
44 ;; region moves back past it in the buffer. fix it.
45 (setq w (vm-get-visible-buffer-window (current-buffer)))
40 (if (= (window-start w) (point-max)) 46 (if (= (window-start w) (point-max))
41 (set-window-start w (point-min)))) 47 (set-window-start w (point-min)))
42 (setq was-invisible t))) 48 (setq was-invisible t))))
43 (if (or mp-changed was-invisible 49 (if (or mp-changed was-invisible
44 (and (eq vm-system-state 'previewing) 50 (and (eq vm-system-state 'previewing)
45 (pos-visible-in-window-p 51 (pos-visible-in-window-p
46 (point-max) 52 (point-max)
47 (vm-get-visible-buffer-window (current-buffer))))) 53 (vm-get-visible-buffer-window (current-buffer)))))
101 (let ((vm-message-pointer vmp)) 107 (let ((vm-message-pointer vmp))
102 (vm-emit-eom-blurb))) 108 (vm-emit-eom-blurb)))
103 (t 109 (t
104 (and (> (prefix-numeric-value arg) 0) 110 (and (> (prefix-numeric-value arg) 0)
105 (vm-howl-if-eom))))))) 111 (vm-howl-if-eom)))))))
106 (if (not (or vm-startup-message-displayed vm-inhibit-startup-message)) 112 (if (not vm-startup-message-displayed)
107 (vm-display-startup-message))) 113 (vm-display-startup-message)))
108 114
109 (defun vm-scroll-forward-internal (arg) 115 (defun vm-scroll-forward-internal (arg)
110 (let ((direction (prefix-numeric-value arg)) 116 (let ((direction (prefix-numeric-value arg))
111 (w (selected-window))) 117 (w (selected-window)))
112 (condition-case error-data 118 (condition-case error-data
113 (progn (scroll-up arg) nil) 119 (progn
120 (if (and (> direction 0)
121 (pos-visible-in-window-p
122 (vm-text-end-of (car vm-message-pointer))))
123 (signal 'end-of-buffer nil)
124 (scroll-up arg))
125 nil )
114 (error 126 (error
115 (if (or (and (< direction 0) 127 (if (or (and (< direction 0)
116 (> (point-min) (vm-text-of (car vm-message-pointer)))) 128 (> (point-min) (vm-text-of (car vm-message-pointer))))
117 (and (>= direction 0) 129 (and (>= direction 0)
118 (/= (point-max) 130 (/= (point-max)
235 (defun vm-energize-urls () 247 (defun vm-energize-urls ()
236 ;; Don't search too long in large regions. If the region is 248 ;; Don't search too long in large regions. If the region is
237 ;; large, search just the head and the tail of the region since 249 ;; large, search just the head and the tail of the region since
238 ;; they tend to contain the interesting text. 250 ;; they tend to contain the interesting text.
239 (let ((search-limit vm-url-search-limit) 251 (let ((search-limit vm-url-search-limit)
240 (search-pairs)) 252 search-pairs n)
241 (if (and search-limit (> (- (point-max) (point-min)) search-limit)) 253 (if (and search-limit (> (- (point-max) (point-min)) search-limit))
242 (setq search-pairs (list (cons (point-min) 254 (setq search-pairs (list (cons (point-min)
243 (+ (point-min) (/ search-limit 2))) 255 (+ (point-min) (/ search-limit 2)))
244 (cons (- (point-max) (/ search-limit 2)) 256 (cons (- (point-max) (/ search-limit 2))
245 (point-max)))) 257 (point-max))))
254 nil)) 266 nil))
255 (current-buffer) (point-min) (point-max)) 267 (current-buffer) (point-min) (point-max))
256 (while search-pairs 268 (while search-pairs
257 (goto-char (car (car search-pairs))) 269 (goto-char (car (car search-pairs)))
258 (while (re-search-forward vm-url-regexp (cdr (car search-pairs)) t) 270 (while (re-search-forward vm-url-regexp (cdr (car search-pairs)) t)
259 (setq e (make-extent (match-beginning 0) (match-end 0))) 271 (setq n 1)
272 (while (null (match-beginning n))
273 (vm-increment n))
274 (setq e (make-extent (match-beginning n) (match-end n)))
260 (set-extent-property e 'vm-url t) 275 (set-extent-property e 'vm-url t)
261 (if vm-highlight-url-face 276 (if vm-highlight-url-face
262 (set-extent-property e 'face vm-highlight-url-face)) 277 (set-extent-property e 'face vm-highlight-url-face))
263 (if vm-url-browser 278 (if vm-url-browser
264 (let ((keymap (make-sparse-keymap))) 279 (let ((keymap (make-sparse-keymap)))
265 (define-key keymap 'button2 'vm-mouse-send-url-at-event) 280 (define-key keymap 'button2 'vm-mouse-send-url-at-event)
266 (define-key keymap 'button3 'vm-menu-popup-url-browser-menu) 281 (if vm-popup-menu-on-mouse-3
282 (define-key keymap 'button3 'vm-menu-popup-url-browser-menu))
267 (define-key keymap "\r" 283 (define-key keymap "\r"
268 (function (lambda () (interactive) 284 (function (lambda () (interactive)
269 (vm-mouse-send-url-at-position (point))))) 285 (vm-mouse-send-url-at-position (point)))))
270 (set-extent-property e 'keymap keymap) 286 (set-extent-property e 'keymap keymap)
271 (set-extent-property e 'balloon-help 'vm-url-help) 287 (set-extent-property e 'balloon-help 'vm-url-help)
286 (delete-overlay (car p))) 302 (delete-overlay (car p)))
287 (setq p (cdr p))) 303 (setq p (cdr p)))
288 (while search-pairs 304 (while search-pairs
289 (goto-char (car (car search-pairs))) 305 (goto-char (car (car search-pairs)))
290 (while (re-search-forward vm-url-regexp (cdr (car search-pairs)) t) 306 (while (re-search-forward vm-url-regexp (cdr (car search-pairs)) t)
291 (setq o (make-overlay (match-beginning 0) (match-end 0))) 307 (setq n 1)
308 (while (null (match-beginning n))
309 (vm-increment n))
310 (setq o (make-overlay (match-beginning n) (match-end n)))
292 (overlay-put o 'vm-url t) 311 (overlay-put o 'vm-url t)
293 (if vm-highlight-url-face 312 (if vm-highlight-url-face
294 (overlay-put o 'face vm-highlight-url-face)) 313 (overlay-put o 'face vm-highlight-url-face))
295 (if vm-url-browser 314 (if vm-url-browser
296 (overlay-put o 'mouse-face 'highlight))) 315 (let ((keymap (make-sparse-keymap)))
316 (overlay-put o 'mouse-face 'highlight)
317 (setq keymap (nconc keymap (current-local-map)))
318 (define-key keymap "\r"
319 (function (lambda () (interactive)
320 (vm-mouse-send-url-at-position (point)))))
321 (overlay-put o 'local-map keymap))))
297 (setq search-pairs (cdr search-pairs)))))))) 322 (setq search-pairs (cdr search-pairs))))))))
298 323
299 (defun vm-energize-headers () 324 (defun vm-energize-headers ()
300 (cond 325 (cond
301 ((vm-xemacs-p) 326 ((vm-xemacs-p)
322 ;; this case, since there is no default 'select' 347 ;; this case, since there is no default 'select'
323 ;; action. 348 ;; action.
324 (define-key keymap 'button2 349 (define-key keymap 'button2
325 (list 'lambda () '(interactive) 350 (list 'lambda () '(interactive)
326 (list 'popup-menu (list 'quote menu)))) 351 (list 'popup-menu (list 'quote menu))))
327 (define-key keymap 'button3 352 (if vm-popup-menu-on-mouse-3
328 (list 'lambda () '(interactive) 353 (define-key keymap 'button3
329 (list 'popup-menu (list 'quote menu)))) 354 (list 'lambda () '(interactive)
355 (list 'popup-menu (list 'quote menu)))))
330 (set-extent-property e 'keymap keymap) 356 (set-extent-property e 'keymap keymap)
331 (set-extent-property e 'balloon-help 'vm-mouse-3-help) 357 (set-extent-property e 'balloon-help 'vm-mouse-3-help)
332 (set-extent-property e 'highlight t)) 358 (set-extent-property e 'highlight t))
333 (setq search-tuples (cdr search-tuples))))) 359 (setq search-tuples (cdr search-tuples)))))
334 ((and (vm-fsfemacs-19-p) 360 ((and (vm-fsfemacs-19-p)
408 "Mosaic") 434 "Mosaic")
409 ((eq vm-url-browser 'vm-mouse-send-url-to-netscape) 435 ((eq vm-url-browser 'vm-mouse-send-url-to-netscape)
410 "Netscape") 436 "Netscape")
411 (t (symbol-name vm-url-browser))))) 437 (t (symbol-name vm-url-browser)))))
412 438
413 (defun vm-preview-current-message () 439 (defun vm-energize-urls-in-message-region (&optional start end)
414 (setq vm-system-state 'previewing) 440 (save-excursion
415 (if vm-real-buffers 441 (or start (setq start (vm-headers-of (car vm-message-pointer))))
416 (vm-make-virtual-copy (car vm-message-pointer))) 442 (or end (setq end (vm-text-end-of (car vm-message-pointer))))
443 ;; energize the URLs
444 (if (or vm-highlight-url-face vm-url-browser)
445 (save-restriction
446 (widen)
447 (narrow-to-region start
448 end)
449 (vm-energize-urls)))))
450
451 (defun vm-highlight-headers-maybe ()
452 ;; highlight the headers
453 (if (or vm-highlighted-header-regexp
454 (and (vm-xemacs-p) vm-use-lucid-highlighting))
455 (save-restriction
456 (widen)
457 (narrow-to-region (vm-headers-of (car vm-message-pointer))
458 (vm-text-end-of (car vm-message-pointer)))
459 (vm-highlight-headers))))
460
461 (defun vm-energize-headers-and-xfaces ()
462 ;; energize certain headers
463 (if (and vm-use-menus (vm-menu-support-possible-p))
464 (save-restriction
465 (widen)
466 (narrow-to-region (vm-headers-of (car vm-message-pointer))
467 (vm-text-of (car vm-message-pointer)))
468 (vm-energize-headers)))
469 ;; display xfaces, if we can
470 (if (and vm-display-xfaces
471 (vm-xemacs-p)
472 (vm-multiple-frames-possible-p)
473 (featurep 'xface))
474 (save-restriction
475 (widen)
476 (narrow-to-region (vm-headers-of (car vm-message-pointer))
477 (vm-text-of (car vm-message-pointer)))
478 (vm-display-xface))))
479
480 (defun vm-narrow-for-preview ()
417 (widen) 481 (widen)
418 ;; hide as much of the message body as vm-preview-lines specifies 482 ;; hide as much of the message body as vm-preview-lines specifies
419 (narrow-to-region 483 (narrow-to-region
420 (vm-vheaders-of (car vm-message-pointer)) 484 (vm-vheaders-of (car vm-message-pointer))
421 (cond ((not (eq vm-preview-lines t)) 485 (cond ((not (eq vm-preview-lines t))
423 (vm-text-end-of (car vm-message-pointer)) 487 (vm-text-end-of (car vm-message-pointer))
424 (save-excursion 488 (save-excursion
425 (goto-char (vm-text-of (car vm-message-pointer))) 489 (goto-char (vm-text-of (car vm-message-pointer)))
426 (forward-line (if (natnump vm-preview-lines) vm-preview-lines 0)) 490 (forward-line (if (natnump vm-preview-lines) vm-preview-lines 0))
427 (point)))) 491 (point))))
428 (t (vm-text-end-of (car vm-message-pointer))))) 492 (t (vm-text-end-of (car vm-message-pointer))))))
429 ;; highlight the headers 493
430 (if (or vm-highlighted-header-regexp 494 (defun vm-preview-current-message ()
431 (and (vm-xemacs-p) vm-use-lucid-highlighting)) 495 (vm-save-buffer-excursion
432 (save-restriction 496 (setq vm-system-state 'previewing)
433 (widen) 497 (if vm-real-buffers
434 (narrow-to-region (vm-headers-of (car vm-message-pointer)) 498 (vm-make-virtual-copy (car vm-message-pointer)))
435 (vm-text-end-of (car vm-message-pointer))) 499
436 (vm-highlight-headers))) 500 ;; run the message select hooks.
437 ;; energize the URLs 501 (save-excursion
438 (if (or vm-highlight-url-face vm-url-browser) 502 (vm-select-folder-buffer)
439 (save-restriction 503 (vm-run-message-hook (car vm-message-pointer) 'vm-select-message-hook)
440 (widen) 504 (and vm-select-new-message-hook (vm-new-flag (car vm-message-pointer))
441 (narrow-to-region (vm-headers-of (car vm-message-pointer)) 505 (vm-run-message-hook (car vm-message-pointer)
442 (vm-text-end-of (car vm-message-pointer))) 506 'vm-select-new-message-hook))
443 (vm-energize-urls))) 507 (and vm-select-unread-message-hook
444 ;; energize certain headers 508 (vm-unread-flag (car vm-message-pointer))
445 (if (and vm-use-menus (vm-menu-support-possible-p)) 509 (vm-run-message-hook (car vm-message-pointer)
446 (save-restriction 510 'vm-select-unread-message-hook)))
447 (widen) 511
448 (narrow-to-region (vm-headers-of (car vm-message-pointer)) 512 (vm-narrow-for-preview)
449 (vm-text-of (car vm-message-pointer))) 513 (if (or vm-mime-display-function
450 (vm-energize-headers))) 514 (and vm-display-using-mime
451 515 (not (vm-mime-plain-message-p (car vm-message-pointer)))))
452 ;; display xfaces, if we can 516 (let ((layout (vm-mm-layout (car vm-message-pointer))))
453 (if (and vm-display-xfaces 517 (vm-make-presentation-copy (car vm-message-pointer))
454 (vm-xemacs-p) 518 (vm-save-buffer-excursion
455 (vm-multiple-frames-possible-p) 519 (vm-replace-buffer-in-windows (current-buffer)
456 (featurep 'xface)) 520 vm-presentation-buffer))
457 (save-restriction 521 (set-buffer vm-presentation-buffer)
458 (widen) 522 (setq vm-system-state 'previewing)
459 (narrow-to-region (vm-headers-of (car vm-message-pointer)) 523 (vm-narrow-for-preview))
460 (vm-text-of (car vm-message-pointer))) 524 (setq vm-presentation-buffer nil)
461 (vm-display-xface))) 525 (and vm-presentation-buffer-handle
462 526 (vm-replace-buffer-in-windows vm-presentation-buffer-handle
463 (vm-run-message-hook (car vm-message-pointer) 'vm-select-message-hook) 527 (current-buffer))))
464 (and vm-select-new-message-hook (vm-new-flag (car vm-message-pointer)) 528
465 (vm-run-message-hook (car vm-message-pointer) 529 ;; at this point the current buffer is the presentation buffer
466 'vm-select-new-message-hook)) 530 ;; if we're using one for this message.
467 (and vm-select-unread-message-hook (vm-unread-flag (car vm-message-pointer)) 531
468 (vm-run-message-hook (car vm-message-pointer) 532 (vm-energize-urls-in-message-region)
469 'vm-select-unread-message-hook)) 533 (vm-highlight-headers-maybe)
470 534 (vm-energize-headers-and-xfaces)
471 (if vm-honor-page-delimiters 535
472 (vm-narrow-to-page)) 536 (if vm-honor-page-delimiters
473 (goto-char (vm-text-of (car vm-message-pointer))) 537 (vm-narrow-to-page))
474 ;; If we have a window, set window start appropriately. 538 (goto-char (vm-text-of (car vm-message-pointer)))
475 (let ((w (vm-get-visible-buffer-window (current-buffer)))) 539 ;; If we have a window, set window start appropriately.
476 (if w 540 (let ((w (vm-get-visible-buffer-window (current-buffer))))
477 (progn (set-window-start w (point-min)) 541 (if w
478 (set-window-point w (vm-text-of (car vm-message-pointer)))))) 542 (progn (set-window-start w (point-min))
479 (if (or (null vm-preview-lines) 543 (set-window-point w (vm-text-of (car vm-message-pointer))))))
480 (and (not vm-preview-read-messages) 544 (if (or (null vm-preview-lines)
481 (not (vm-new-flag (car vm-message-pointer))) 545 (and (not vm-preview-read-messages)
482 (not (vm-unread-flag (car vm-message-pointer))))) 546 (not (vm-new-flag (car vm-message-pointer)))
483 (vm-show-current-message) 547 (not (vm-unread-flag (car vm-message-pointer)))))
484 (vm-update-summary-and-mode-line))) 548 (vm-show-current-message)
549 (vm-update-summary-and-mode-line))))
485 550
486 (defun vm-show-current-message () 551 (defun vm-show-current-message ()
487 (save-excursion 552 (and vm-display-using-mime
488 (save-excursion 553 vm-auto-decode-mime-messages
489 (goto-char (point-min)) 554 (not vm-mime-decoded)
490 (widen) 555 (not (vm-mime-plain-message-p (car vm-message-pointer)))
491 (narrow-to-region (point) (vm-text-end-of (car vm-message-pointer)))) 556 (vm-decode-mime-message))
492 (if vm-honor-page-delimiters 557 (vm-save-buffer-excursion
493 (progn 558 (save-excursion
494 (if (looking-at page-delimiter) 559 (save-excursion
495 (forward-page 1)) 560 (goto-char (point-min))
496 (vm-narrow-to-page)))) 561 (widen)
497 ;; don't mark the message as read if the user can't see it! 562 (narrow-to-region (point) (vm-text-end-of (car vm-message-pointer))))
498 (if (vm-get-visible-buffer-window (current-buffer)) 563 (if vm-honor-page-delimiters
499 (progn 564 (progn
500 (setq vm-system-state 'showing) 565 (if (looking-at page-delimiter)
501 (cond ((vm-new-flag (car vm-message-pointer)) 566 (forward-page 1))
502 (vm-set-new-flag (car vm-message-pointer) nil))) 567 (vm-narrow-to-page))))
503 (cond ((vm-unread-flag (car vm-message-pointer)) 568 ;; don't mark the message as read if the user can't see it!
504 (vm-set-unread-flag (car vm-message-pointer) nil))) 569 (if (vm-get-visible-buffer-window (current-buffer))
505 (vm-update-summary-and-mode-line) 570 (progn
506 (vm-howl-if-eom)) 571 (save-excursion
507 (vm-update-summary-and-mode-line))) 572 (setq vm-system-state 'showing)
573 (if vm-mail-buffer
574 (vm-set-buffer-variable vm-mail-buffer 'vm-system-state
575 'showing))
576 ;; We could be in the presentation buffer here. Since
577 ;; the presentation buffer's message pointer and sole
578 ;; message are a mockup, they will cause trouble if
579 ;; passed into the undo/update system. So we switch
580 ;; into the real message buffer to do attribute
581 ;; updates.
582 (vm-select-folder-buffer)
583 (cond ((vm-new-flag (car vm-message-pointer))
584 (vm-set-new-flag (car vm-message-pointer) nil)))
585 (cond ((vm-unread-flag (car vm-message-pointer))
586 (vm-set-unread-flag (car vm-message-pointer) nil))))
587 (vm-update-summary-and-mode-line)
588 (vm-howl-if-eom))
589 (vm-update-summary-and-mode-line))))
508 590
509 (defun vm-expose-hidden-headers () 591 (defun vm-expose-hidden-headers ()
510 "Toggle exposing and hiding message headers that are normally not visible." 592 "Toggle exposing and hiding message headers that are normally not visible."
511 (interactive) 593 (interactive)
512 (vm-follow-summary-cursor) 594 (vm-follow-summary-cursor)
513 (vm-select-folder-buffer) 595 (vm-select-folder-buffer)
514 (vm-check-for-killed-summary) 596 (vm-check-for-killed-summary)
597 (vm-check-for-killed-presentation)
515 (vm-error-if-folder-empty) 598 (vm-error-if-folder-empty)
599 (and vm-presentation-buffer
600 (set-buffer vm-presentation-buffer))
516 (vm-display (current-buffer) t '(vm-expose-hidden-headers) 601 (vm-display (current-buffer) t '(vm-expose-hidden-headers)
517 '(vm-expose-hidden-headers reading-message)) 602 '(vm-expose-hidden-headers reading-message))
518 (let* ((exposed (= (point-min) (vm-start-of (car vm-message-pointer))))) 603 (let* ((exposed (= (point-min) (vm-start-of (car vm-message-pointer)))))
519 (vm-widen-page) 604 (vm-widen-page)
520 (goto-char (point-max)) 605 (goto-char (point-max))
559 "Moves to the beginning of the current message." 644 "Moves to the beginning of the current message."
560 (interactive) 645 (interactive)
561 (vm-follow-summary-cursor) 646 (vm-follow-summary-cursor)
562 (vm-select-folder-buffer) 647 (vm-select-folder-buffer)
563 (vm-check-for-killed-summary) 648 (vm-check-for-killed-summary)
649 (vm-check-for-killed-presentation)
564 (vm-error-if-folder-empty) 650 (vm-error-if-folder-empty)
651 (and vm-presentation-buffer
652 (set-buffer vm-presentation-buffer))
565 (vm-widen-page) 653 (vm-widen-page)
566 (push-mark) 654 (push-mark)
567 (vm-display (current-buffer) t '(vm-beginning-of-message) 655 (vm-display (current-buffer) t '(vm-beginning-of-message)
568 '(vm-beginning-of-message reading-message)) 656 '(vm-beginning-of-message reading-message))
569 (let ((osw (selected-window))) 657 (let ((osw (selected-window)))
581 as necessary." 669 as necessary."
582 (interactive) 670 (interactive)
583 (vm-follow-summary-cursor) 671 (vm-follow-summary-cursor)
584 (vm-select-folder-buffer) 672 (vm-select-folder-buffer)
585 (vm-check-for-killed-summary) 673 (vm-check-for-killed-summary)
674 (vm-check-for-killed-presentation)
586 (vm-error-if-folder-empty) 675 (vm-error-if-folder-empty)
676 (and vm-presentation-buffer
677 (set-buffer vm-presentation-buffer))
587 (if (eq vm-system-state 'previewing) 678 (if (eq vm-system-state 'previewing)
588 (vm-show-current-message)) 679 (vm-show-current-message))
589 (setq vm-system-state 'reading) 680 (setq vm-system-state 'reading)
590 (vm-widen-page) 681 (vm-widen-page)
591 (push-mark) 682 (push-mark)