comparison lisp/follow.el @ 18133:7900f6f3c36e

(follow-windows-aligned-p): Doc fix. (follow-post-command-hook, follow-recenter): Doc fix. (follow-end-of-buffer, follow-windows-aligned-p): Doc fix. (follow-post-command-hook, follow-maximize-region): Doc fix. (set-process-filter, process-filter, move-overlay): Advice doc fix.
author Karl Heuer <kwzh@gnu.org>
date Tue, 03 Jun 1997 07:09:13 +0000
parents 89f6e1e17d2d
children f8860990bdf7
comparison
equal deleted inserted replaced
18132:95f6ac42b352 18133:7900f6f3c36e
1 ;;; follow.el --- Minor mode, Synchronize windows showing the same buffer. 1 ;;; follow.el --- Minor mode, Synchronize windows showing the same buffer.
2 2
3 ;; Copyright (C) 1995, 1996 Free Software Foundation, Inc. 3 ;; Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
4 4
5 ;; Author: Anders Lindgren <andersl@csd.uu.se> 5 ;; Author: Anders Lindgren <andersl@csd.uu.se>
6 ;; Maintainer: Anders Lindgren <andersl@csd.uu.se> 6 ;; Maintainer: Anders Lindgren <andersl@csd.uu.se>
7 ;; Created: 25 May 1995 7 ;; Created: 25 May 1995
8 ;; Version: 1.7 8 ;; Version: 1.7
34 ;; combines windows into one tall virtual window. 34 ;; combines windows into one tall virtual window.
35 ;; 35 ;;
36 ;; The feeling of a "virtual window" has been accomplished by the use 36 ;; The feeling of a "virtual window" has been accomplished by the use
37 ;; of two major techniques: 37 ;; of two major techniques:
38 ;; 38 ;;
39 ;; * The windows always displays adjacent sections of the buffer. 39 ;; * The windows always displays adjacent sections of the buffer.
40 ;; This means that whenever one window is moved, all the 40 ;; This means that whenever one window is moved, all the
41 ;; others will follow. (Hence the name Follow Mode.) 41 ;; others will follow. (Hence the name Follow Mode.)
42 ;; 42 ;;
43 ;; * Should the point (cursor) end up outside a window, another 43 ;; * Should the point (cursor) end up outside a window, another
44 ;; window displaying that point is selected, if possible. This 44 ;; window displaying that point is selected, if possible. This
45 ;; makes it possible to walk between windows using normal cursor 45 ;; makes it possible to walk between windows using normal cursor
46 ;; movement commands. 46 ;; movement commands.
47 ;; 47 ;;
48 ;; Follow mode comes to its prime when used on a large screen and two 48 ;; Follow mode comes to its prime when used on a large screen and two
49 ;; side-by-side window are used. The user can, with the help of Follow 49 ;; side-by-side window are used. The user can, with the help of Follow
50 ;; mode, use two full-height windows as though they would have been 50 ;; mode, use two full-height windows as though they would have been
79 ;; 79 ;;
80 ;; +----------+----------+ 80 ;; +----------+----------+
81 ;; |1 |73 | 81 ;; |1 |73 |
82 ;; |2 |74 | 82 ;; |2 |74 |
83 ;; |3 |75 | 83 ;; |3 |75 |
84 ;; ... ... 84 ;; ... ...
85 ;; |71 |143 | 85 ;; |71 |143 |
86 ;; |72 |144 | 86 ;; |72 |144 |
87 ;; +----------+----------+ 87 ;; +----------+----------+
88 ;; 88 ;;
89 ;; As you can see, the right-hand window starts at line 73, the line 89 ;; As you can see, the right-hand window starts at line 73, the line
95 ;; line of the left-hand window. Enter new lines into the 95 ;; line of the left-hand window. Enter new lines into the
96 ;; text. Enter long lines spanning several lines, or several 96 ;; text. Enter long lines spanning several lines, or several
97 ;; windows. 97 ;; windows.
98 ;; 98 ;;
99 ;; * Should you find `Follow' mode annoying, just type 99 ;; * Should you find `Follow' mode annoying, just type
100 ;; M-x follow-mode <RETURN> 100 ;; M-x follow-mode <RETURN>
101 ;; to turn it off. 101 ;; to turn it off.
102 102
103 103
104 ;; Installation: 104 ;; Installation:
105 ;; 105 ;;
226 ;; 226 ;;
227 ;; Example from my ~/.emacs: 227 ;; Example from my ~/.emacs:
228 ;; (global-set-key [f8] 'follow-mode) 228 ;; (global-set-key [f8] 'follow-mode)
229 229
230 230
231 ;; Implementation: 231 ;; Implementation:
232 ;; 232 ;;
233 ;; In an ideal world, follow mode would have been implemented in the 233 ;; In an ideal world, follow mode would have been implemented in the
234 ;; kernal of the display routines, making sure that the windows (in 234 ;; kernal of the display routines, making sure that the windows (in
235 ;; follow mode) ALWAYS are aligned. On planet earth, however, we must 235 ;; follow mode) ALWAYS are aligned. On planet earth, however, we must
236 ;; accept a solution where we ALMOST ALWAYS can make sure that the 236 ;; accept a solution where we ALMOST ALWAYS can make sure that the
276 ;; 02-Jul-95 andersl * compute-motion imitated with a ugly workaround, 276 ;; 02-Jul-95 andersl * compute-motion imitated with a ugly workaround,
277 ;; Works with XEmacs again! 277 ;; Works with XEmacs again!
278 ;; 15-Jul-95 andersl * find-file hook. 278 ;; 15-Jul-95 andersl * find-file hook.
279 ;; * submit-feedback. 279 ;; * submit-feedback.
280 ;; * Survives major mode changes. 280 ;; * Survives major mode changes.
281 ;; * Region spanning multiple windows looks 281 ;; * Region spanning multiple windows looks
282 ;; resonabely good. 282 ;; reasonably good.
283 ;; 19-Jul-95 andersl * New process-filter handling. 283 ;; 19-Jul-95 andersl * New process-filter handling.
284 ;; 1-Aug-95 andersl * XEmacs scrollbar support. 284 ;; 1-Aug-95 andersl * XEmacs scrollbar support.
285 ;; * Emacs 19 `window-size-change' support. 285 ;; * Emacs 19 `window-size-change' support.
286 ;; * `save-window-excursion' removed, it triggered 286 ;; * `save-window-excursion' removed, it triggered
287 ;; a redraw! 287 ;; a redraw!
288 ;; 5-Aug-95 andersl * `follow-switch-to-current-buffer-all' added. 288 ;; 5-Aug-95 andersl * `follow-switch-to-current-buffer-all' added.
289 ;; 16-Nov-95 andersl * V1.0 released! 289 ;; 16-Nov-95 andersl * V1.0 released!
290 ;; 17-Nov-95 andersl * Byte compiler silencer for XEmacs broken. 290 ;; 17-Nov-95 andersl * Byte compiler silencer for XEmacs broken.
291 ;; * fkey-end-of-buffer treated the same way 291 ;; * fkey-end-of-buffer treated the same way
292 ;; end-of-buffer is. 292 ;; end-of-buffer is.
293 ;; * follow-mode-off-hook added. 293 ;; * follow-mode-off-hook added.
294 ;; (Suggested by David Hughes, thanks!) 294 ;; (Suggested by David Hughes, thanks!)
295 ;; 20-Nov-95 andersl * Bug in menu code corrected. 295 ;; 20-Nov-95 andersl * Bug in menu code corrected.
296 ;; (Reported by Robert E. Brown, thanks!) 296 ;; (Reported by Robert E. Brown, thanks!)
297 ;; 5-Dec-95 andersl * `follow-avoid-tail-recenter' added to the 297 ;; 5-Dec-95 andersl * `follow-avoid-tail-recenter' added to the
298 ;; post-command-idle-hook to avoid recentering 298 ;; post-command-idle-hook to avoid recentering
304 ;; * `move-overlay' advices, drag-region works. 304 ;; * `move-overlay' advices, drag-region works.
305 ;; 2-Jan-96 andersl * XEmacs: isearch fixed. 305 ;; 2-Jan-96 andersl * XEmacs: isearch fixed.
306 ;; * `follow-calc-win-end' created. 306 ;; * `follow-calc-win-end' created.
307 ;; 8-Jan-96 andersl * XEmacs: `window-end' with `guarantee' 307 ;; 8-Jan-96 andersl * XEmacs: `window-end' with `guarantee'
308 ;; argument used in `follow-calc-win-end'. 308 ;; argument used in `follow-calc-win-end'.
309 ;; 9-Jan-96 andersl * `follow-end-of-buffer' added. 309 ;; 9-Jan-96 andersl * `follow-end-of-buffer' added.
310 ;; Code in post hook removed. 310 ;; Code in post hook removed.
311 ;; * XEmacs: Post hook is always executed 311 ;; * XEmacs: Post hook is always executed
312 ;; after a mouse button event. 312 ;; after a mouse button event.
313 ;; 22-Jan-96 andersl * 1.5 released. 313 ;; 22-Jan-96 andersl * 1.5 released.
314 ;; 314 ;;
383 383
384 (defvar follow-mode-map nil 384 (defvar follow-mode-map nil
385 "*Minor mode keymap for Follow mode.") 385 "*Minor mode keymap for Follow mode.")
386 386
387 (defvar follow-mode-line-text " Follow" 387 (defvar follow-mode-line-text " Follow"
388 "*Text shown in the mode line when Follow mode is active. 388 "*Text shown in the mode line when Follow mode is active.
389 Defaults to \" Follow\". Examples of other values 389 Defaults to \" Follow\". Examples of other values
390 are \" Fw\", or simply \"\".") 390 are \" Fw\", or simply \"\".")
391 391
392 (defvar follow-auto nil 392 (defvar follow-auto nil
393 "*Non-nil activates Follow mode whenever a file is loaded.") 393 "*Non-nil activates Follow mode whenever a file is loaded.")
398 After that, changing the prefix key requires manipulating keymaps.") 398 After that, changing the prefix key requires manipulating keymaps.")
399 399
400 (defvar follow-intercept-processes t 400 (defvar follow-intercept-processes t
401 "*When non-nil, Follow Mode will monitor process output.") 401 "*When non-nil, Follow Mode will monitor process output.")
402 402
403 (defvar follow-emacs-version-xemacs-p 403 (defvar follow-emacs-version-xemacs-p
404 (string-match "XEmacs" emacs-version) 404 (string-match "XEmacs" emacs-version)
405 "Non-nil when running under XEmacs.") 405 "Non-nil when running under XEmacs.")
406 406
407 (defvar follow-avoid-tail-recenter-p 407 (defvar follow-avoid-tail-recenter-p
408 (not follow-emacs-version-xemacs-p) 408 (not follow-emacs-version-xemacs-p)
409 "*When non-nil, patch emacs so that tail windows won't be recentered. 409 "*When non-nil, patch emacs so that tail windows won't be recentered.
410 410
411 A \"tail window\" is a window which displays only the end of 411 A \"tail window\" is a window which displays only the end of
412 the buffer. Normally it is practical for the user that empty 412 the buffer. Normally it is practical for the user that empty
413 windows are recentered automatically. However, when using 413 windows are recentered automatically. However, when using
414 Follow Mode it breaks the display when the end is displayed 414 Follow Mode it breaks the display when the end is displayed
415 in a window \"above\" the last window. This is for 415 in a window \"above\" the last window. This is for
416 example the case when displaying a short page in info. 416 example the case when displaying a short page in info.
417 417
418 Must be set before Follow Mode is loaded. 418 Must be set before Follow Mode is loaded.
419 419
420 Please note that it is not possible to fully prevent Emacs from 420 Please note that it is not possible to fully prevent Emacs from
453 453
454 (defvar follow-deactive-menu nil 454 (defvar follow-deactive-menu nil
455 "The menu visible when Follow mode is deactivated.") 455 "The menu visible when Follow mode is deactivated.")
456 456
457 (defvar follow-inside-post-command-hook nil 457 (defvar follow-inside-post-command-hook nil
458 "Non-nil when inside Follow modes `post-command-hook'. 458 "Non-nil when inside Follow modes `post-command-hook'.
459 Used by `follow-window-size-change'.") 459 Used by `follow-window-size-change'.")
460 460
461 (defvar follow-windows-start-end-cache nil 461 (defvar follow-windows-start-end-cache nil
462 "Cache used by `follow-window-start-end'.") 462 "Cache used by `follow-window-start-end'.")
463 463
472 (require 'reporter) 472 (require 'reporter)
473 (and (y-or-n-p "Do you really want to submit a report on Follow mode? ") 473 (and (y-or-n-p "Do you really want to submit a report on Follow mode? ")
474 (reporter-submit-bug-report 474 (reporter-submit-bug-report
475 "Anders Lindgren <andersl@csd.uu.se>" 475 "Anders Lindgren <andersl@csd.uu.se>"
476 follow-mode-version 476 follow-mode-version
477 '(post-command-hook 477 '(post-command-hook
478 post-command-idle-hook 478 post-command-idle-hook
479 pre-command-hook 479 pre-command-hook
480 window-size-change-functions 480 window-size-change-functions
481 window-scroll-functions 481 window-scroll-functions
482 follow-mode-hook 482 follow-mode-hook
483 follow-mode-off-hook 483 follow-mode-off-hook
484 follow-auto 484 follow-auto
485 follow-intercept-processes 485 follow-intercept-processes
486 follow-avoid-tail-recenter-p 486 follow-avoid-tail-recenter-p
487 follow-process-filter-alist) 487 follow-process-filter-alist)
488 nil 488 nil
489 nil 489 nil
490 (concat 490 (concat
491 "Hi Anders!\n\n" 491 "Hi Anders!\n\n"
492 "(I have read the section on how to report bugs in the " 492 "(I have read the section on how to report bugs in the "
493 "Emacs manual.)\n\n" 493 "Emacs manual.)\n\n"
494 "Even though I know you are busy, I thought you might " 494 "Even though I know you are busy, I thought you might "
495 "want to know...\n\n")))) 495 "want to know...\n\n"))))
497 ;;}}} 497 ;;}}}
498 ;;{{{ Debug messages 498 ;;{{{ Debug messages
499 499
500 ;; This inline function must be as small as possible! 500 ;; This inline function must be as small as possible!
501 ;; Maybe we should define a macro which expands to nil if 501 ;; Maybe we should define a macro which expands to nil if
502 ;; the varible is not set. 502 ;; the variable is not set.
503 503
504 (defsubst follow-debug-message (&rest args) 504 (defsubst follow-debug-message (&rest args)
505 "Like message, but only active when `follow-debug' is non-nil." 505 "Like message, but only active when `follow-debug' is non-nil."
506 (if (and (boundp 'follow-debug) follow-debug) 506 (if (and (boundp 'follow-debug) follow-debug)
507 (apply 'message args))) 507 (apply 'message args)))
551 ;; the look and feel of Follow mode.) 551 ;; the look and feel of Follow mode.)
552 ;; 552 ;;
553 ;; (The function `substitute-key-definition' does not work 553 ;; (The function `substitute-key-definition' does not work
554 ;; in all versions of Emacs.) 554 ;; in all versions of Emacs.)
555 (mapcar 555 (mapcar
556 (function 556 (function
557 (lambda (pair) 557 (lambda (pair)
558 (let ((old (car pair)) 558 (let ((old (car pair))
559 (new (cdr pair))) 559 (new (cdr pair)))
560 (mapcar (function (lambda (key) 560 (mapcar (function (lambda (key)
561 (define-key follow-mode-map key new))) 561 (define-key follow-mode-map key new)))
562 (where-is-internal old global-map))))) 562 (where-is-internal old global-map)))))
563 '((end-of-buffer . follow-end-of-buffer) 563 '((end-of-buffer . follow-end-of-buffer)
564 (fkey-end-of-buffer . follow-end-of-buffer))) 564 (fkey-end-of-buffer . follow-end-of-buffer)))
565 565
570 (if (not follow-emacs-version-xemacs-p) 570 (if (not follow-emacs-version-xemacs-p)
571 571
572 ;; 572 ;;
573 ;; Emacs 19 573 ;; Emacs 19
574 ;; 574 ;;
575 (let ((menumap (funcall (symbol-function 'make-sparse-keymap) 575 (let ((menumap (funcall (symbol-function 'make-sparse-keymap)
576 "Follow")) 576 "Follow"))
577 (count 0) 577 (count 0)
578 id) 578 id)
579 (mapcar 579 (mapcar
580 (function 580 (function
581 (lambda (item) 581 (lambda (item)
582 (setq id 582 (setq id
583 (or (cdr item) 583 (or (cdr item)
584 (progn 584 (progn
585 (setq count (+ count 1)) 585 (setq count (+ count 1))
586 (intern (format "separator-%d" count))))) 586 (intern (format "separator-%d" count)))))
587 (define-key menumap (vector id) item) 587 (define-key menumap (vector id) item)
604 ("Delete Other Windows and Split" 604 ("Delete Other Windows and Split"
605 . follow-delete-other-windows-and-split) 605 . follow-delete-other-windows-and-split)
606 ("--") 606 ("--")
607 ("Scroll Down" . follow-scroll-down) 607 ("Scroll Down" . follow-scroll-down)
608 ("Scroll Up" . follow-scroll-up))) 608 ("Scroll Up" . follow-scroll-up)))
609 609
610 ;; If there is a `tools' meny, we use it. However, we can't add a 610 ;; If there is a `tools' meny, we use it. However, we can't add a
611 ;; minor-mode specific item to it (it's broken), so we make the 611 ;; minor-mode specific item to it (it's broken), so we make the
612 ;; contents ghosted when not in use, and add ourselves to the 612 ;; contents ghosted when not in use, and add ourselves to the
613 ;; global map. If no `tools' menu is present, just make a 613 ;; global map. If no `tools' menu is present, just make a
614 ;; top-level menu visible when the mode is activated. 614 ;; top-level menu visible when the mode is activated.
615 615
616 (let ((tools-map (lookup-key (current-global-map) [menu-bar tools])) 616 (let ((tools-map (lookup-key (current-global-map) [menu-bar tools]))
617 (last nil)) 617 (last nil))
618 (if (sequencep tools-map) 618 (if (sequencep tools-map)
619 (progn 619 (progn
620 ;; Find the last entry in the menu and store it in `last'. 620 ;; Find the last entry in the menu and store it in `last'.
621 (mapcar (function 621 (mapcar (function
622 (lambda (x) 622 (lambda (x)
623 (setq last (or (cdr-safe 623 (setq last (or (cdr-safe
624 (cdr-safe 624 (cdr-safe
625 (cdr-safe x))) 625 (cdr-safe x)))
626 last)))) 626 last))))
627 tools-map) 627 tools-map)
628 (if last 628 (if last
629 (progn 629 (progn
630 (funcall (symbol-function 'define-key-after) 630 (funcall (symbol-function 'define-key-after)
650 ["Scroll Up" follow-scroll-up t] 650 ["Scroll Up" follow-scroll-up t]
651 ["Scroll Down" follow-scroll-down t] 651 ["Scroll Down" follow-scroll-down t]
652 ["Delete Other Windows and Split" 652 ["Delete Other Windows and Split"
653 follow-delete-other-windows-and-split t] 653 follow-delete-other-windows-and-split t]
654 ["Switch To Buffer" follow-switch-to-buffer t] 654 ["Switch To Buffer" follow-switch-to-buffer t]
655 ["Switch To Buffer (all windows)" 655 ["Switch To Buffer (all windows)"
656 follow-switch-to-buffer-all t] 656 follow-switch-to-buffer-all t]
657 ["First Window" follow-first-window t] 657 ["First Window" follow-first-window t]
658 ["Last Window" follow-last-window t] 658 ["Last Window" follow-last-window t]
659 ["Next Windows" follow-next-window t] 659 ["Next Windows" follow-next-window t]
660 ["Previous Window" follow-previous-window t] 660 ["Previous Window" follow-previous-window t]
708 (interactive) 708 (interactive)
709 (follow-mode -1)) 709 (follow-mode -1))
710 710
711 711
712 ;;;###autoload 712 ;;;###autoload
713 (defun follow-mode (arg) 713 (defun follow-mode (arg)
714 "Minor mode which combines windows into one tall virtual window. 714 "Minor mode which combines windows into one tall virtual window.
715 715
716 The feeling of a \"virtual window\" has been accomplished by the use 716 The feeling of a \"virtual window\" has been accomplished by the use
717 of two major techniques: 717 of two major techniques:
718 718
719 * The windows always displays adjacent sections of the buffer. 719 * The windows always displays adjacent sections of the buffer.
720 This means that whenever one window is moved, all the 720 This means that whenever one window is moved, all the
721 others will follow. (Hence the name Follow Mode.) 721 others will follow. (Hence the name Follow Mode.)
722 722
723 * Should the point (cursor) end up outside a window, another 723 * Should the point (cursor) end up outside a window, another
724 window displaying that point is selected, if possible. This 724 window displaying that point is selected, if possible. This
725 makes it possible to walk between windows using normal cursor 725 makes it possible to walk between windows using normal cursor
726 movement commands. 726 movement commands.
727 727
728 Follow mode comes to its prime when used on a large screen and two 728 Follow mode comes to its prime when used on a large screen and two
729 side-by-side window are used. The user can, with the help of Follow 729 side-by-side window are used. The user can, with the help of Follow
730 mode, use two full-height windows as though they would have been 730 mode, use two full-height windows as though they would have been
763 (if (boundp 'scroll-on-clipped-lines) 763 (if (boundp 'scroll-on-clipped-lines)
764 (set 'scroll-on-clipped-lines nil)) 764 (set 'scroll-on-clipped-lines nil))
765 (force-mode-line-update) 765 (force-mode-line-update)
766 (add-hook 'post-command-hook 'follow-post-command-hook t) 766 (add-hook 'post-command-hook 'follow-post-command-hook t)
767 (if (boundp 'post-command-idle-hook) 767 (if (boundp 'post-command-idle-hook)
768 (add-hook 'post-command-idle-hook 768 (add-hook 'post-command-idle-hook
769 'follow-avoid-tail-recenter t)) 769 'follow-avoid-tail-recenter t))
770 (run-hooks 'follow-mode-hook)) 770 (run-hooks 'follow-mode-hook))
771 771
772 ((and (not follow-mode) follow-mode-orig) ; Off 772 ((and (not follow-mode) follow-mode-orig) ; Off
773 (force-mode-line-update) 773 (force-mode-line-update)
869 (start (window-start (car windows)))) 869 (start (window-start (car windows))))
870 (if (eq start (point-min)) 870 (if (eq start (point-min))
871 (signal 'beginning-of-buffer nil) 871 (signal 'beginning-of-buffer nil)
872 (select-window win) 872 (select-window win)
873 (goto-char start) 873 (goto-char start)
874 (vertical-motion (- (- (window-height win) 874 (vertical-motion (- (- (window-height win)
875 1 875 1
876 next-screen-context-lines))) 876 next-screen-context-lines)))
877 (set-window-start win (point)) 877 (set-window-start win (point))
878 (goto-char start) 878 (goto-char start)
879 (vertical-motion (- next-screen-context-lines 1)) 879 (vertical-motion (- next-screen-context-lines 1))
880 (setq follow-internal-force-redisplay t)))))) 880 (setq follow-internal-force-redisplay t))))))
885 ;;;###autoload 885 ;;;###autoload
886 (defun follow-delete-other-windows-and-split (&optional arg) 886 (defun follow-delete-other-windows-and-split (&optional arg)
887 "Create two side by side windows and enter Follow Mode. 887 "Create two side by side windows and enter Follow Mode.
888 888
889 Execute this command to display as much as possible of the text 889 Execute this command to display as much as possible of the text
890 in the selected window. All other windows, in the current 890 in the selected window. All other windows, in the current
891 frame, are deleted and the selected window is split in two 891 frame, are deleted and the selected window is split in two
892 side-by-side windows. Follow Mode is activated, hence the 892 side-by-side windows. Follow Mode is activated, hence the
893 two windows always will display two successive pages. 893 two windows always will display two successive pages.
894 \(If one window is moved, the other one will follow.) 894 \(If one window is moved, the other one will follow.)
895 895
896 If ARG is positive, the leftmost window is selected. If it negative, 896 If ARG is positive, the leftmost window is selected. If it negative,
897 the rightmost is selected. If ARG is nil, the leftmost window is 897 the rightmost is selected. If ARG is nil, the leftmost window is
899 899
900 To bind this command to a hotkey, place the following line 900 To bind this command to a hotkey, place the following line
901 in your `~/.emacs' file, replacing [f7] by your favourite key: 901 in your `~/.emacs' file, replacing [f7] by your favourite key:
902 (global-set-key [f7] 'follow-delete-other-windows-and-split)" 902 (global-set-key [f7] 'follow-delete-other-windows-and-split)"
903 (interactive "P") 903 (interactive "P")
904 (let ((other (or (and (null arg) 904 (let ((other (or (and (null arg)
905 (not (eq (selected-window) 905 (not (eq (selected-window)
906 (frame-first-window (selected-frame))))) 906 (frame-first-window (selected-frame)))))
907 (and arg 907 (and arg
908 (< (prefix-numeric-value arg) 0)))) 908 (< (prefix-numeric-value arg) 0))))
909 (start (window-start))) 909 (start (window-start)))
910 (delete-other-windows) 910 (delete-other-windows)
911 (split-window-horizontally) 911 (split-window-horizontally)
912 (if other 912 (if other
913 (progn 913 (progn
914 (other-window 1) 914 (other-window 1)
915 (set-window-start (selected-window) start) 915 (set-window-start (selected-window) start)
916 (setq follow-internal-force-redisplay t))) 916 (setq follow-internal-force-redisplay t)))
917 (follow-mode 1))) 917 (follow-mode 1)))
929 929
930 930
931 (defun follow-switch-to-buffer-all (&optional buffer) 931 (defun follow-switch-to-buffer-all (&optional buffer)
932 "Show BUFFER in all windows on this frame. 932 "Show BUFFER in all windows on this frame.
933 Defaults to current buffer." 933 Defaults to current buffer."
934 (interactive (list (read-buffer "Switch to Buffer: " 934 (interactive (list (read-buffer "Switch to Buffer: "
935 (current-buffer)))) 935 (current-buffer))))
936 (or buffer (setq buffer (current-buffer))) 936 (or buffer (setq buffer (current-buffer)))
937 (let ((orig-window (selected-window))) 937 (let ((orig-window (selected-window)))
938 (walk-windows 938 (walk-windows
939 (function 939 (function
940 (lambda (win) 940 (lambda (win)
941 (select-window win) 941 (select-window win)
942 (switch-to-buffer buffer)))) 942 (switch-to-buffer buffer))))
943 (select-window orig-window) 943 (select-window orig-window)
944 (follow-redisplay))) 944 (follow-redisplay)))
945 945
946 946
947 (defun follow-switch-to-current-buffer-all () 947 (defun follow-switch-to-current-buffer-all ()
948 "Show current buffer in all windows on this frame, and enter Follow Mode. 948 "Show current buffer in all windows on this frame, and enter Follow Mode.
949 949
950 To bind this command to a hotkey place the following line 950 To bind this command to a hotkey place the following line
951 in your `~/.emacs' file: 951 in your `~/.emacs' file:
952 (global-set-key [f7] 'follow-switch-to-current-buffer-all)" 952 (global-set-key [f7] 'follow-switch-to-current-buffer-all)"
953 (interactive) 953 (interactive)
954 (or (and (boundp 'follow-mode) follow-mode) 954 (or (and (boundp 'follow-mode) follow-mode)
955 (follow-mode 1)) 955 (follow-mode 1))
992 992
993 ;;}}} 993 ;;}}}
994 ;;{{{ Redraw 994 ;;{{{ Redraw
995 995
996 (defun follow-recenter (&optional arg) 996 (defun follow-recenter (&optional arg)
997 "Recenter the middle window around the point, 997 "Recenter the middle window around point.
998 and rearrange all other windows around the middle window. 998 Rearrange all other windows around the middle window.
999 999
1000 With a positive argument, place the current line ARG lines 1000 With a positive argument, place the current line ARG lines
1001 from the top. With a negative, place it -ARG lines from the 1001 from the top. With a negative, place it -ARG lines from the
1002 bottom." 1002 bottom."
1003 (interactive "P") 1003 (interactive "P")
1040 1040
1041 ;;}}} 1041 ;;}}}
1042 ;;{{{ End of buffer 1042 ;;{{{ End of buffer
1043 1043
1044 (defun follow-end-of-buffer (&optional arg) 1044 (defun follow-end-of-buffer (&optional arg)
1045 "Move point to the end of the buffer. Follow Mode style. 1045 "Move point to the end of the buffer, Follow Mode style.
1046 1046
1047 If the end is not visible, it will be displayed in the last possible 1047 If the end is not visible, it will be displayed in the last possible
1048 window in the Follow Mode window chain. 1048 window in the Follow Mode window chain.
1049 1049
1050 The mark is left at the previous position. With arg N, put point N/10 1050 The mark is left at the previous position. With arg N, put point N/10
1051 of the way from the true end." 1051 of the way from the true end."
1052 (interactive "P") 1052 (interactive "P")
1053 (let ((followers (follow-all-followers)) 1053 (let ((followers (follow-all-followers))
1054 (pos (point))) 1054 (pos (point)))
1055 (cond (arg 1055 (cond (arg
1056 (select-window (car (reverse followers)))) 1056 (select-window (car (reverse followers))))
1057 ((follow-select-if-end-visible 1057 ((follow-select-if-end-visible
1058 (follow-windows-start-end followers))) 1058 (follow-windows-start-end followers)))
1059 (t 1059 (t
1060 (select-window (car (reverse followers))))) 1060 (select-window (car (reverse followers)))))
1061 (goto-char pos) 1061 (goto-char pos)
1062 (end-of-buffer arg))) 1062 (end-of-buffer arg)))
1091 (nreverse windows))) 1091 (nreverse windows)))
1092 1092
1093 1093
1094 (defun follow-split-followers (windows &optional win) 1094 (defun follow-split-followers (windows &optional win)
1095 "Split the WINDOWS into the sets: predecessors and successors. 1095 "Split the WINDOWS into the sets: predecessors and successors.
1096 Return `(PRED . SUCC)' where `PRED' and `SUCC' are ordered starting 1096 Return `(PRED . SUCC)' where `PRED' and `SUCC' are ordered starting
1097 from the selected window." 1097 from the selected window."
1098 (or win 1098 (or win
1099 (setq win (selected-window))) 1099 (setq win (selected-window)))
1100 (let ((pred '())) 1100 (let ((pred '()))
1101 (while (not (eq (car windows) win)) 1101 (while (not (eq (car windows) win))
1102 (setq pred (cons (car windows) pred)) 1102 (setq pred (cons (car windows) pred))
1103 (setq windows (cdr windows))) 1103 (setq windows (cdr windows)))
1120 ;; the 'guarantee options. GOOD! 1120 ;; the 'guarantee options. GOOD!
1121 (let ((end (window-end win t))) 1121 (let ((end (window-end win t)))
1122 (if (= end (funcall (symbol-function 'point-max) 1122 (if (= end (funcall (symbol-function 'point-max)
1123 (window-buffer win))) 1123 (window-buffer win)))
1124 (list end t) 1124 (list end t)
1125 (list (+ end 1) nil))) 1125 (list (+ end 1) nil)))
1126 ;; Emacs 19: We have to calculate the end by ourselves. 1126 ;; Emacs 19: We have to calculate the end by ourselves.
1127 ;; This code works on both XEmacs and Emacs 19, but now 1127 ;; This code works on both XEmacs and Emacs 19, but now
1128 ;; that XEmacs has got custom-written code, this could 1128 ;; that XEmacs has got custom-written code, this could
1129 ;; be optimized for Emacs 19. 1129 ;; be optimized for Emacs 19.
1130 (let ((orig-win (and win (selected-window))) 1130 (let ((orig-win (and win (selected-window)))
1202 follow-windows-start-end-cache 1202 follow-windows-start-end-cache
1203 (let ((win-start-end '()) 1203 (let ((win-start-end '())
1204 (orig-win (selected-window))) 1204 (orig-win (selected-window)))
1205 (while windows 1205 (while windows
1206 (select-window (car windows)) 1206 (select-window (car windows))
1207 (setq win-start-end 1207 (setq win-start-end
1208 (cons (cons (car windows) 1208 (cons (cons (car windows)
1209 (cons (window-start) 1209 (cons (window-start)
1210 (follow-calc-win-end))) 1210 (follow-calc-win-end)))
1211 win-start-end)) 1211 win-start-end))
1212 (setq windows (cdr windows))) 1212 (setq windows (cdr windows)))
1213 (select-window orig-win) 1213 (select-window orig-win)
1226 ;; By `aligned' we mean that for all adjecent windows, the end of the 1226 ;; By `aligned' we mean that for all adjecent windows, the end of the
1227 ;; first is equal with the start of the successor. The first window 1227 ;; first is equal with the start of the successor. The first window
1228 ;; should start at a full screen line. 1228 ;; should start at a full screen line.
1229 1229
1230 (defsubst follow-windows-aligned-p (win-start-end) 1230 (defsubst follow-windows-aligned-p (win-start-end)
1231 "Non-nil if the follower WINDOWS are alinged." 1231 "Non-nil if the follower WINDOWS are aligned."
1232 (let ((res t)) 1232 (let ((res t))
1233 (save-excursion 1233 (save-excursion
1234 (goto-char (window-start (car (car win-start-end)))) 1234 (goto-char (window-start (car (car win-start-end))))
1235 (if (bolp) 1235 (if (bolp)
1236 nil 1236 nil
1237 (vertical-motion 0 (car (car win-start-end))) 1237 (vertical-motion 0 (car (car win-start-end)))
1308 ;; it wasn't just moved here. (i.e. M-> shall not unconditionally place 1308 ;; it wasn't just moved here. (i.e. M-> shall not unconditionally place
1309 ;; the point in the selected window.) 1309 ;; the point in the selected window.)
1310 ;; 1310 ;;
1311 ;; (Compability cludge: in Emacs 19 `window-end' is equal to `point-max'; 1311 ;; (Compability cludge: in Emacs 19 `window-end' is equal to `point-max';
1312 ;; in XEmacs, it is equal to `point-max + 1'. Should I really bother 1312 ;; in XEmacs, it is equal to `point-max + 1'. Should I really bother
1313 ;; checking `window-end' now when I check `end-of-buffer' explicitylt?) 1313 ;; checking `window-end' now when I check `end-of-buffer' explicitly?)
1314 1314
1315 (defun follow-select-if-end-visible (win-start-end) 1315 (defun follow-select-if-end-visible (win-start-end)
1316 "Select and return a window, if end is visible in it." 1316 "Select and return a window, if end is visible in it."
1317 (let ((win nil)) 1317 (let ((win nil))
1318 (while (and (not win) win-start-end) 1318 (while (and (not win) win-start-end)
1341 end-pos-end-p) 1341 end-pos-end-p)
1342 (save-excursion 1342 (save-excursion
1343 (goto-char (window-start (car windows))) 1343 (goto-char (window-start (car windows)))
1344 ;; Make sure the line start in the beginning of a real screen 1344 ;; Make sure the line start in the beginning of a real screen
1345 ;; line. 1345 ;; line.
1346 (vertical-motion 0 (car windows)) 1346 (vertical-motion 0 (car windows))
1347 (if (< dest (point)) 1347 (if (< dest (point))
1348 ;; Above the start, not visible. 1348 ;; Above the start, not visible.
1349 nil 1349 nil
1350 ;; At or below the start. Check the windows. 1350 ;; At or below the start. Check the windows.
1351 (save-window-excursion 1351 (save-window-excursion
1357 ;; the window. 1357 ;; the window.
1358 (if (or (car (cdr end-pos-end-p)) 1358 (if (or (car (cdr end-pos-end-p))
1359 (< dest (point))) 1359 (< dest (point)))
1360 (setq win (car windows)) 1360 (setq win (car windows))
1361 (setq windows (cdr windows))))))) 1361 (setq windows (cdr windows)))))))
1362 (if win 1362 (if win
1363 (select-window win)) 1363 (select-window win))
1364 win)) 1364 win))
1365 1365
1366 1366
1367 ;;}}} 1367 ;;}}}
1368 ;;{{{ Redisplay 1368 ;;{{{ Redisplay
1369 1369
1370 ;; Redraw all the windows on the screen, starting with the top window. 1370 ;; Redraw all the windows on the screen, starting with the top window.
1371 ;; The window used as as marker is WIN, or the selcted window if WIN 1371 ;; The window used as as marker is WIN, or the selcted window if WIN
1372 ;; is nil. 1372 ;; is nil.
1373 1373
1374 (defun follow-redisplay (&optional windows win) 1374 (defun follow-redisplay (&optional windows win)
1375 "Reposition the WINDOWS around WIN. 1375 "Reposition the WINDOWS around WIN.
1376 Should the point be too close to the roof we redisplay everything 1376 Should the point be too close to the roof we redisplay everything
1377 from the top. WINDOWS should contain a list of windows to 1377 from the top. WINDOWS should contain a list of windows to
1378 redisplay, it is assumed that WIN is a member of the list. 1378 redisplay, it is assumed that WIN is a member of the list.
1379 Should WINDOWS be nil, the windows displaying the 1379 Should WINDOWS be nil, the windows displaying the
1380 same buffer as WIN, in the current frame, are used. 1380 same buffer as WIN, in the current frame, are used.
1381 Should WIN be nil, the selected window is used." 1381 Should WIN be nil, the selected window is used."
1382 (or win 1382 (or win
1383 (setq win (selected-window))) 1383 (setq win (selected-window)))
1384 (or windows 1384 (or windows
1385 (setq windows (follow-all-followers win))) 1385 (setq windows (follow-all-followers win)))
1386 (follow-downward windows (follow-calculate-first-window-start windows win))) 1386 (follow-downward windows (follow-calculate-first-window-start windows win)))
1387 1387
1388 1388
1389 ;; Redisplay a chain of windows. Start every window directly after the 1389 ;; Redisplay a chain of windows. Start every window directly after the
1424 1424
1425 (defun follow-calculate-first-window-start (windows &optional win start) 1425 (defun follow-calculate-first-window-start (windows &optional win start)
1426 "Calculate the start of the first window. 1426 "Calculate the start of the first window.
1427 1427
1428 WINDOWS is a chain of windows to work with. WIN is the window 1428 WINDOWS is a chain of windows to work with. WIN is the window
1429 to recenter around. It is assumed that WIN starts at position 1429 to recenter around. It is assumed that WIN starts at position
1430 START." 1430 START."
1431 (or win 1431 (or win
1432 (setq win (selected-window))) 1432 (setq win (selected-window)))
1433 (or start 1433 (or start
1434 (setq start (window-start win))) 1434 (setq start (window-start win)))
1435 (let ((guess (follow-estimate-first-window-start windows win start))) 1435 (let ((guess (follow-estimate-first-window-start windows win start)))
1436 (if (car guess) 1436 (if (car guess)
1437 (cdr guess) 1437 (cdr guess)
1438 ;; The guess wasn't exact, try to enhance it. 1438 ;; The guess wasn't exact, try to enhance it.
1439 (let ((win-start (follow-calc-win-start windows (cdr guess) win))) 1439 (let ((win-start (follow-calc-win-start windows (cdr guess) win)))
1440 (cond ((= win-start start) 1440 (cond ((= win-start start)
1441 (follow-debug-message "exact") 1441 (follow-debug-message "exact")
1442 (cdr guess)) 1442 (cdr guess))
1443 ((< win-start start) 1443 ((< win-start start)
1444 (follow-debug-message "above") 1444 (follow-debug-message "above")
1445 (follow-calculate-first-window-start-from-above 1445 (follow-calculate-first-window-start-from-above
1446 windows (cdr guess) win start)) 1446 windows (cdr guess) win start))
1447 (t 1447 (t
1448 (follow-debug-message "below") 1448 (follow-debug-message "below")
1449 (follow-calculate-first-window-start-from-below 1449 (follow-calculate-first-window-start-from-below
1450 windows (cdr guess) win start))))))) 1450 windows (cdr guess) win start)))))))
1451 1451
1452 1452
1453 ;; `exact' is disabled due to XEmacs and fonts of variable 1453 ;; `exact' is disabled due to XEmacs and fonts of variable
1454 ;; height. 1454 ;; height.
1472 1472
1473 1473
1474 ;; Find the starting point, start at GUESS and search downward. 1474 ;; Find the starting point, start at GUESS and search downward.
1475 ;; The returned point is always a point below GUESS. 1475 ;; The returned point is always a point below GUESS.
1476 1476
1477 (defun follow-calculate-first-window-start-from-above 1477 (defun follow-calculate-first-window-start-from-above
1478 (windows guess win start) 1478 (windows guess win start)
1479 (save-excursion 1479 (save-excursion
1480 (let ((done nil) 1480 (let ((done nil)
1481 win-start 1481 win-start
1482 res) 1482 res)
1488 (progn 1488 (progn
1489 (setq done t) 1489 (setq done t)
1490 (setq res (point-max))) 1490 (setq res (point-max)))
1491 (setq win-start (follow-calc-win-start windows (point) win)) 1491 (setq win-start (follow-calc-win-start windows (point) win))
1492 (if (>= win-start start) 1492 (if (>= win-start start)
1493 (progn 1493 (progn
1494 (setq done t) 1494 (setq done t)
1495 (setq res (point)))))) 1495 (setq res (point))))))
1496 res))) 1496 res)))
1497 1497
1498 1498
1555 ;; investigate this further... 1555 ;; investigate this further...
1556 1556
1557 (defun follow-avoid-tail-recenter (&rest rest) 1557 (defun follow-avoid-tail-recenter (&rest rest)
1558 "Make sure windows displaying the end of a buffer aren't recentered. 1558 "Make sure windows displaying the end of a buffer aren't recentered.
1559 1559
1560 This is done by reading and rewriting the start positon of 1560 This is done by reading and rewriting the start positon of
1561 non-first windows in Follow Mode." 1561 non-first windows in Follow Mode."
1562 (if follow-avoid-tail-recenter-p 1562 (if follow-avoid-tail-recenter-p
1563 (let* ((orig-buffer (current-buffer)) 1563 (let* ((orig-buffer (current-buffer))
1564 (top (frame-first-window (selected-frame))) 1564 (top (frame-first-window (selected-frame)))
1565 (win top) 1565 (win top)
1574 (progn 1574 (progn
1575 (setq start (window-start win)) 1575 (setq start (window-start win))
1576 (set-buffer (window-buffer win)) 1576 (set-buffer (window-buffer win))
1577 (setq pair (cons (window-buffer win) (window-frame win))) 1577 (setq pair (cons (window-buffer win) (window-frame win)))
1578 (if (member pair who) 1578 (if (member pair who)
1579 (if (and (boundp 'follow-mode) follow-mode 1579 (if (and (boundp 'follow-mode) follow-mode
1580 (eq (point-max) start)) 1580 (eq (point-max) start))
1581 ;; Write the same window start back, but don't 1581 ;; Write the same window start back, but don't
1582 ;; set the NOFORCE flag. 1582 ;; set the NOFORCE flag.
1583 (set-window-start win start)) 1583 (set-window-start win start))
1584 (setq who (cons pair who))) 1584 (setq who (cons pair who)))
1600 ;; We divide the check into two parts; whether we are at the end or not. 1600 ;; We divide the check into two parts; whether we are at the end or not.
1601 ;; This is due to the fact that the end can actaually be visible 1601 ;; This is due to the fact that the end can actaually be visible
1602 ;; in several window even though they are aligned. 1602 ;; in several window even though they are aligned.
1603 1603
1604 (defun follow-post-command-hook () 1604 (defun follow-post-command-hook ()
1605 "Ensure that the windows in Follow mode are adjecent after each command." 1605 "Ensure that the windows in Follow mode are adjacent after each command."
1606 (setq follow-inside-post-command-hook t) 1606 (setq follow-inside-post-command-hook t)
1607 (if (or (not (input-pending-p)) 1607 (if (or (not (input-pending-p))
1608 ;; Sometimes, in XEmacs, mouse events are not handled 1608 ;; Sometimes, in XEmacs, mouse events are not handled
1609 ;; properly by `input-pending-p'. A typical example is 1609 ;; properly by `input-pending-p'. A typical example is
1610 ;; when clicking on a node in `info'. 1610 ;; when clicking on a node in `info'.
1615 (symbol-value 'current-mouse-event)))) 1615 (symbol-value 'current-mouse-event))))
1616 ;; Work in the selected window, not in the current buffer. 1616 ;; Work in the selected window, not in the current buffer.
1617 (let ((orig-buffer (current-buffer)) 1617 (let ((orig-buffer (current-buffer))
1618 (win (selected-window))) 1618 (win (selected-window)))
1619 (set-buffer (window-buffer win)) 1619 (set-buffer (window-buffer win))
1620 (or (and (symbolp this-command) 1620 (or (and (symbolp this-command)
1621 (get this-command 'follow-mode-use-cache)) 1621 (get this-command 'follow-mode-use-cache))
1622 (follow-invalidate-cache)) 1622 (follow-invalidate-cache))
1623 (if (and (boundp 'follow-mode) follow-mode 1623 (if (and (boundp 'follow-mode) follow-mode
1624 (not (window-minibuffer-p win))) 1624 (not (window-minibuffer-p win)))
1625 ;; The buffer shown in the selected window is in follow 1625 ;; The buffer shown in the selected window is in follow
1654 ;; end of the file, character are removed 1654 ;; end of the file, character are removed
1655 ;; from the window above, which is very 1655 ;; from the window above, which is very
1656 ;; unintuitive. 1656 ;; unintuitive.
1657 ((and visible 1657 ((and visible
1658 aligned 1658 aligned
1659 (not (memq this-command 1659 (not (memq this-command
1660 '(backward-delete-char 1660 '(backward-delete-char
1661 delete-backward-char 1661 delete-backward-char
1662 backward-delete-char-untabify 1662 backward-delete-char-untabify
1663 kill-region)))) 1663 kill-region))))
1664 (follow-debug-message "Max: same")) 1664 (follow-debug-message "Max: same"))
1675 (follow-debug-message "Max: default") 1675 (follow-debug-message "Max: default")
1676 (select-window (car (reverse windows))) 1676 (select-window (car (reverse windows)))
1677 (goto-char dest) 1677 (goto-char dest)
1678 (setq visible nil) 1678 (setq visible nil)
1679 (setq aligned nil))) 1679 (setq aligned nil)))
1680 1680
1681 ;; We're not at the end, here life is much simpler. 1681 ;; We're not at the end, here life is much simpler.
1682 (cond 1682 (cond
1683 ;; This is the normal case! 1683 ;; This is the normal case!
1684 ;; It should be optimized for speed. 1684 ;; It should be optimized for speed.
1685 ((and visible aligned) 1685 ((and visible aligned)
1686 (follow-debug-message "same")) 1686 (follow-debug-message "same"))
1687 ;; Pick a position in any window. If the 1687 ;; Pick a position in any window. If the
1688 ;; display is ok, this will pick the `correct' 1688 ;; display is ok, this will pick the `correct'
1710 ;; If we can position the cursor without moving the first 1710 ;; If we can position the cursor without moving the first
1711 ;; window, do it. This is the case which catches `RET' 1711 ;; window, do it. This is the case which catches `RET'
1712 ;; at the bottom of a window. 1712 ;; at the bottom of a window.
1713 ((follow-select-if-visible-from-first dest windows) 1713 ((follow-select-if-visible-from-first dest windows)
1714 (follow-debug-message "Below first") 1714 (follow-debug-message "Below first")
1715 (setq visible t) 1715 (setq visible t)
1716 (setq aligned t) 1716 (setq aligned t)
1717 (follow-redisplay windows (car windows)) 1717 (follow-redisplay windows (car windows))
1718 (goto-char dest)) 1718 (goto-char dest))
1719 ;; None of the above. For simplicity, we stick to the 1719 ;; None of the above. For simplicity, we stick to the
1720 ;; selected window. 1720 ;; selected window.
1741 (setq aligned nil)) 1741 (setq aligned nil))
1742 ;; Redraw the windows whenever needed. 1742 ;; Redraw the windows whenever needed.
1743 (if (or follow-internal-force-redisplay 1743 (if (or follow-internal-force-redisplay
1744 (not (or aligned 1744 (not (or aligned
1745 (follow-windows-aligned-p win-start-end))) 1745 (follow-windows-aligned-p win-start-end)))
1746 (not (inline (follow-point-visible-all-windows-p 1746 (not (inline (follow-point-visible-all-windows-p
1747 win-start-end)))) 1747 win-start-end))))
1748 (progn 1748 (progn
1749 (setq follow-internal-force-redisplay nil) 1749 (setq follow-internal-force-redisplay nil)
1750 (follow-redisplay windows (selected-window)) 1750 (follow-redisplay windows (selected-window))
1751 (setq win-start-end (follow-windows-start-end windows)) 1751 (setq win-start-end (follow-windows-start-end windows))
1761 ;; window.) 1761 ;; window.)
1762 (if (follow-pos-visible dest win win-start-end) 1762 (if (follow-pos-visible dest win win-start-end)
1763 nil 1763 nil
1764 (follow-select-if-visible dest win-start-end) 1764 (follow-select-if-visible dest win-start-end)
1765 (goto-char dest)))) 1765 (goto-char dest))))
1766 1766
1767 ;; If the region is visible, make it look good when spanning 1767 ;; If the region is visible, make it look good when spanning
1768 ;; multiple windows. 1768 ;; multiple windows.
1769 (if (or (and (boundp 'mark-active) (symbol-value 'mark-active)) 1769 (if (or (and (boundp 'mark-active) (symbol-value 'mark-active))
1770 (and (fboundp 'region-active-p) 1770 (and (fboundp 'region-active-p)
1771 (funcall (symbol-function 'region-active-p)))) 1771 (funcall (symbol-function 'region-active-p))))
1772 (follow-maximize-region 1772 (follow-maximize-region
1773 (selected-window) windows win-start-end)) 1773 (selected-window) windows win-start-end))
1774 1774
1775 (inline (follow-avoid-tail-recenter)) 1775 (inline (follow-avoid-tail-recenter))
1776 ;; DEBUG 1776 ;; DEBUG
1777 ;;(if (not (follow-windows-aligned-p 1777 ;;(if (not (follow-windows-aligned-p
1778 ;; (follow-windows-start-end windows))) 1778 ;; (follow-windows-start-end windows)))
1779 ;; (message "follow-mode: windows still unaligend!")) 1779 ;; (message "follow-mode: windows still unaligend!"))
1780 ;; END OF DEBUG 1780 ;; END OF DEBUG
1781 ) ; Matches (let* 1781 ) ; Matches (let*
1782 ;; Buffer not in follow mode: 1782 ;; Buffer not in follow mode:
1788 1788
1789 ;;}}} 1789 ;;}}}
1790 ;;{{{ The region 1790 ;;{{{ The region
1791 1791
1792 ;; Tries to make the highlighted area representing the region look 1792 ;; Tries to make the highlighted area representing the region look
1793 ;; good when spanning several windows. 1793 ;; good when spanning several windows.
1794 ;; 1794 ;;
1795 ;; Not perfect, as the point can't be placed at window end, only at 1795 ;; Not perfect, as the point can't be placed at window end, only at
1796 ;; end-1. Whis will highlight a little bit in windows above 1796 ;; end-1. This will highlight a little bit in windows above
1797 ;; the current. 1797 ;; the current.
1798 1798
1799 (defun follow-maximize-region (win windows win-start-end) 1799 (defun follow-maximize-region (win windows win-start-end)
1800 "Make a highlighted region stretching multiple windows look good 1800 "Make a highlighted region stretching multiple windows look good."
1801 when in Follow mode."
1802 (let* ((all (follow-split-followers windows win)) 1801 (let* ((all (follow-split-followers windows win))
1803 (pred (car all)) 1802 (pred (car all))
1804 (succ (cdr all)) 1803 (succ (cdr all))
1805 data) 1804 data)
1806 (while pred 1805 (while pred
1846 scroll-bar-scroll-up 1845 scroll-bar-scroll-up
1847 scroll-bar-set-window-start))) 1846 scroll-bar-set-window-start)))
1848 (while cmds 1847 (while cmds
1849 (eval 1848 (eval
1850 (` (defadvice (, (intern (symbol-name (car cmds)))) 1849 (` (defadvice (, (intern (symbol-name (car cmds))))
1851 (after 1850 (after
1852 (, (intern (concat "follow-" (symbol-name (car cmds))))) 1851 (, (intern (concat "follow-" (symbol-name (car cmds)))))
1853 activate) 1852 activate)
1854 "Adviced by Follow Mode." 1853 "Adviced by Follow Mode."
1855 (follow-redraw-after-event (ad-get-arg 0))))) 1854 (follow-redraw-after-event (ad-get-arg 0)))))
1856 (setq cmds (cdr cmds)))) 1855 (setq cmds (cdr cmds))))
1857 1856
1858 1857
1859 (defun follow-redraw-after-event (event) 1858 (defun follow-redraw-after-event (event)
1860 "Adviced by Follow mode." 1859 "Adviced by Follow mode."
1861 (condition-case nil 1860 (condition-case nil
1862 (let* ((orig-win (selected-window)) 1861 (let* ((orig-win (selected-window))
1863 (win (nth 0 (funcall 1862 (win (nth 0 (funcall
1864 (symbol-function 'event-start) event))) 1863 (symbol-function 'event-start) event)))
1865 (fmode (assq 'follow-mode 1864 (fmode (assq 'follow-mode
1866 (buffer-local-variables 1865 (buffer-local-variables
1867 (window-buffer win))))) 1866 (window-buffer win)))))
1868 (if (and fmode (cdr fmode)) 1867 (if (and fmode (cdr fmode))
1869 ;; The selected window is in follow-mode 1868 ;; The selected window is in follow-mode
1870 (progn 1869 (progn
1871 ;; Recenter around the dragged window. 1870 ;; Recenter around the dragged window.
1880 ;;; XEmacs style scrollbars. 1879 ;;; XEmacs style scrollbars.
1881 ;;; 1880 ;;;
1882 1881
1883 ;; Advice all scrollbar functions on the form: 1882 ;; Advice all scrollbar functions on the form:
1884 ;; 1883 ;;
1885 ;; (defadvice scrollbar-line-down 1884 ;; (defadvice scrollbar-line-down
1886 ;; (after follow-scrollbar-line-down activate) 1885 ;; (after follow-scrollbar-line-down activate)
1887 ;; (follow-xemacs-scrollbar-support (ad-get-arg 0))) 1886 ;; (follow-xemacs-scrollbar-support (ad-get-arg 0)))
1888 1887
1889 (let ((cmds '(scrollbar-line-down ; Window 1888 (let ((cmds '(scrollbar-line-down ; Window
1890 scrollbar-line-up 1889 scrollbar-line-up
1892 scrollbar-page-up 1891 scrollbar-page-up
1893 scrollbar-to-bottom ; Window 1892 scrollbar-to-bottom ; Window
1894 scrollbar-to-top 1893 scrollbar-to-top
1895 scrollbar-vertical-drag ; Object 1894 scrollbar-vertical-drag ; Object
1896 ))) 1895 )))
1897 1896
1898 (while cmds 1897 (while cmds
1899 (eval 1898 (eval
1900 (` (defadvice (, (intern (symbol-name (car cmds)))) 1899 (` (defadvice (, (intern (symbol-name (car cmds))))
1901 (after 1900 (after
1902 (, (intern (concat "follow-" (symbol-name (car cmds))))) 1901 (, (intern (concat "follow-" (symbol-name (car cmds)))))
1903 activate) 1902 activate)
1904 "Adviced by `follow-mode'." 1903 "Adviced by `follow-mode'."
1905 (follow-xemacs-scrollbar-support (ad-get-arg 0))))) 1904 (follow-xemacs-scrollbar-support (ad-get-arg 0)))))
1906 (setq cmds (cdr cmds)))) 1905 (setq cmds (cdr cmds))))
1907 1906
1915 WINDOW can be an object or a window." 1914 WINDOW can be an object or a window."
1916 (condition-case nil 1915 (condition-case nil
1917 (progn 1916 (progn
1918 (if (consp window) 1917 (if (consp window)
1919 (setq window (car window))) 1918 (setq window (car window)))
1920 (let ((fmode (assq 'follow-mode 1919 (let ((fmode (assq 'follow-mode
1921 (buffer-local-variables 1920 (buffer-local-variables
1922 (window-buffer window)))) 1921 (window-buffer window))))
1923 (orig-win (selected-window))) 1922 (orig-win (selected-window)))
1924 (if (and fmode (cdr fmode)) 1923 (if (and fmode (cdr fmode))
1925 (progn 1924 (progn
1926 ;; Recenter around the dragged window. 1925 ;; Recenter around the dragged window.
1947 ;;; Our generic filter calls the original filter, or inserts the 1946 ;;; Our generic filter calls the original filter, or inserts the
1948 ;;; output into the buffer, if the buffer originally didn't have an 1947 ;;; output into the buffer, if the buffer originally didn't have an
1949 ;;; output filter. It also makes sure that the windows connected to 1948 ;;; output filter. It also makes sure that the windows connected to
1950 ;;; the buffer are aligned. 1949 ;;; the buffer are aligned.
1951 ;;; 1950 ;;;
1952 ;;; Discussion: How to we find processes which doesn't call 1951 ;;; Discussion: How do we find processes which don't call
1953 ;;; `set-process-filter'? (How often are processes created in a 1952 ;;; `set-process-filter'? (How often are processes created in a
1954 ;;; buffer after Follow mode are activated?) 1953 ;;; buffer after Follow mode are activated?)
1955 ;;; 1954 ;;;
1956 ;;; Discussion: Should we also advice `process-filter' to make our 1955 ;;; Discussion: Should we also advice `process-filter' to make our
1957 ;;; filter invisible to others? 1956 ;;; filter invisible to others?
1960 1959
1961 ;; Do not call this with 'follow-generic-filter as the name of the 1960 ;; Do not call this with 'follow-generic-filter as the name of the
1962 ;; filter... 1961 ;; filter...
1963 1962
1964 (defadvice set-process-filter (before follow-set-process-filter activate) 1963 (defadvice set-process-filter (before follow-set-process-filter activate)
1965 "Follow Mode listens to calls to this function to make 1964 "Ensure process output will be displayed correctly in Follow Mode buffers."
1966 sure process output will be displayed correctly in buffers 1965
1967 in which the mode is activated. 1966 Follow Mode inserts its own process filter to do its
1968
1969 Follow Mode inserts its own process filter to do its
1970 magic stuff before the real process filter is called." 1967 magic stuff before the real process filter is called."
1971 (if follow-intercept-processes 1968 (if follow-intercept-processes
1972 (progn 1969 (progn
1973 (setq follow-process-filter-alist 1970 (setq follow-process-filter-alist
1974 (delq (assq (ad-get-arg 0) follow-process-filter-alist) 1971 (delq (assq (ad-get-arg 0) follow-process-filter-alist)
1976 (follow-tidy-process-filter-alist) 1973 (follow-tidy-process-filter-alist)
1977 (cond ((eq (ad-get-arg 1) t)) 1974 (cond ((eq (ad-get-arg 1) t))
1978 ((eq (ad-get-arg 1) nil) 1975 ((eq (ad-get-arg 1) nil)
1979 (ad-set-arg 1 'follow-generic-filter)) 1976 (ad-set-arg 1 'follow-generic-filter))
1980 (t 1977 (t
1981 (setq follow-process-filter-alist 1978 (setq follow-process-filter-alist
1982 (cons (cons (ad-get-arg 0) (ad-get-arg 1)) 1979 (cons (cons (ad-get-arg 0) (ad-get-arg 1))
1983 follow-process-filter-alist)) 1980 follow-process-filter-alist))
1984 (ad-set-arg 1 'follow-generic-filter)))))) 1981 (ad-set-arg 1 'follow-generic-filter))))))
1985 1982
1986 1983
1987 (defun follow-call-set-process-filter (proc filter) 1984 (defun follow-call-set-process-filter (proc filter)
1988 "Call original `set-process-filter' without the Follow mode advice." 1985 "Call original `set-process-filter' without the Follow mode advice."
1989 (ad-disable-advice 'set-process-filter 'before 1986 (ad-disable-advice 'set-process-filter 'before
1990 'follow-set-process-filter) 1987 'follow-set-process-filter)
1991 (ad-activate 'set-process-filter) 1988 (ad-activate 'set-process-filter)
1992 (prog1 1989 (prog1
1993 (set-process-filter proc filter) 1990 (set-process-filter proc filter)
1994 (ad-enable-advice 'set-process-filter 'before 1991 (ad-enable-advice 'set-process-filter 'before
1995 'follow-set-process-filter) 1992 'follow-set-process-filter)
1996 (ad-activate 'set-process-filter))) 1993 (ad-activate 'set-process-filter)))
1997 1994
1998 1995
1999 (defadvice process-filter (after follow-process-filter activate) 1996 (defadvice process-filter (after follow-process-filter activate)
2000 "Normally when Follow mode is activated all processes has the 1997 "Return the original process filter, not `follow-generic-filter'."
2001 process filter set to `follow-generic-filter'. With this advice,
2002 the original process filter is returned."
2003 (cond ((eq ad-return-value 'follow-generic-filter) 1998 (cond ((eq ad-return-value 'follow-generic-filter)
2004 (setq ad-return-value 1999 (setq ad-return-value
2005 (cdr-safe (assq (ad-get-arg 0) 2000 (cdr-safe (assq (ad-get-arg 0)
2006 follow-process-filter-alist)))))) 2001 follow-process-filter-alist))))))
2007 2002
2008 2003
2009 (defun follow-call-process-filter (proc) 2004 (defun follow-call-process-filter (proc)
2010 "Call original `process-filter' without the Follow mode advice." 2005 "Call original `process-filter' without the Follow mode advice."
2011 (ad-disable-advice 'process-filter 'after 2006 (ad-disable-advice 'process-filter 'after
2012 'follow-process-filter) 2007 'follow-process-filter)
2013 (ad-activate 'process-filter) 2008 (ad-activate 'process-filter)
2014 (prog1 2009 (prog1
2015 (process-filter proc) 2010 (process-filter proc)
2016 (ad-enable-advice 'process-filter 'after 2011 (ad-enable-advice 'process-filter 'after
2017 'follow-process-filter) 2012 'follow-process-filter)
2018 (ad-activate 'process-filter))) 2013 (ad-activate 'process-filter)))
2019 2014
2020 2015
2021 (defun follow-tidy-process-filter-alist () 2016 (defun follow-tidy-process-filter-alist ()
2022 "Remove old processes from `follow-process-filter-alist'." 2017 "Remove old processes from `follow-process-filter-alist'."
2023 (let ((alist follow-process-filter-alist) 2018 (let ((alist follow-process-filter-alist)
2024 (ps (process-list)) 2019 (ps (process-list))
2025 (new ())) 2020 (new ()))
2026 (while alist 2021 (while alist
2027 (if (and (not (memq (process-status (car (car alist))) 2022 (if (and (not (memq (process-status (car (car alist)))
2028 '(exit signal closed nil))) 2023 '(exit signal closed nil)))
2029 (memq (car (car alist)) ps)) 2024 (memq (car (car alist)) ps))
2030 (setq new (cons (car alist) new))) 2025 (setq new (cons (car alist) new)))
2031 (setq alist (cdr alist))) 2026 (setq alist (cdr alist)))
2032 (setq follow-process-filter-alist new))) 2027 (setq follow-process-filter-alist new)))
2058 (defun follow-stop-intercept-process-output () 2053 (defun follow-stop-intercept-process-output ()
2059 "Stop Follow Mode from spying on processes. 2054 "Stop Follow Mode from spying on processes.
2060 2055
2061 All current spypoints are removed and no new will be added. 2056 All current spypoints are removed and no new will be added.
2062 2057
2063 The effect is that Follow mode won't be able to handle buffers 2058 The effect is that Follow mode won't be able to handle buffers
2064 connected to processes. 2059 connected to processes.
2065 2060
2066 The only reason to call this function is if the Follow mode spy filter 2061 The only reason to call this function is if the Follow mode spy filter
2067 would interfere with some other package. If this happens, please 2062 would interfere with some other package. If this happens, please
2068 report this using the `follow-submit-feedback' function." 2063 report this using the `follow-submit-feedback' function."
2069 (interactive) 2064 (interactive)
2070 (follow-tidy-process-filter-alist) 2065 (follow-tidy-process-filter-alist)
2071 (let ((list (process-list))) 2066 (let ((list (process-list)))
2072 (while list 2067 (while list
2073 (if (eq (process-filter (car list)) 'follow-generic-filter) 2068 (if (eq (process-filter (car list)) 'follow-generic-filter)
2074 (progn 2069 (progn
2075 (follow-call-set-process-filter 2070 (follow-call-set-process-filter
2076 (car list) 2071 (car list)
2077 (cdr-safe (assq (car list) follow-process-filter-alist))) 2072 (cdr-safe (assq (car list) follow-process-filter-alist)))
2078 (setq follow-process-filter-alist 2073 (setq follow-process-filter-alist
2079 (delq (assq (car list) follow-process-filter-alist) 2074 (delq (assq (car list) follow-process-filter-alist)
2080 follow-process-filter-alist)))) 2075 follow-process-filter-alist))))
2081 (setq list (cdr list)))) 2076 (setq list (cdr list))))
2082 (setq follow-intercept-processes nil)) 2077 (setq follow-intercept-processes nil))
2083 2078
2108 ;(or (input-pending-p) 2103 ;(or (input-pending-p)
2109 ; (follow-avoid-tail-recenter)) 2104 ; (follow-avoid-tail-recenter))
2110 2105
2111 ;; Output the `output'. 2106 ;; Output the `output'.
2112 (let ((filter (cdr-safe (assq proc follow-process-filter-alist)))) 2107 (let ((filter (cdr-safe (assq proc follow-process-filter-alist))))
2113 (cond 2108 (cond
2114 ;; Call the original filter function 2109 ;; Call the original filter function
2115 (filter 2110 (filter
2116 (funcall filter proc output)) 2111 (funcall filter proc output))
2117 2112
2118 ;; No filter, but we've got a buffer. Just output into it. 2113 ;; No filter, but we've got a buffer. Just output into it.
2145 ;; feel it's more correct.) 2140 ;; feel it's more correct.)
2146 (if (and buf win (window-live-p win)) 2141 (if (and buf win (window-live-p win))
2147 (progn 2142 (progn
2148 (set-buffer buf) 2143 (set-buffer buf)
2149 (if (and (boundp 'follow-mode) follow-mode) 2144 (if (and (boundp 'follow-mode) follow-mode)
2150 (progn 2145 (progn
2151 (select-window win) 2146 (select-window win)
2152 (let* ((windows (follow-all-followers win)) 2147 (let* ((windows (follow-all-followers win))
2153 (win-start-end (follow-windows-start-end windows)) 2148 (win-start-end (follow-windows-start-end windows))
2154 (new-window-start (window-start win)) 2149 (new-window-start (window-start win))
2155 (new-window-point (window-point win))) 2150 (new-window-point (window-point win)))
2163 ((not (eq orig-window-start new-window-start)) 2158 ((not (eq orig-window-start new-window-start))
2164 (follow-debug-message "filter: Moved") 2159 (follow-debug-message "filter: Moved")
2165 (set-window-start win orig-window-start) 2160 (set-window-start win orig-window-start)
2166 (follow-redisplay windows win) 2161 (follow-redisplay windows win)
2167 (setq win-start-end (follow-windows-start-end windows)) 2162 (setq win-start-end (follow-windows-start-end windows))
2168 (follow-select-if-visible new-window-point 2163 (follow-select-if-visible new-window-point
2169 win-start-end) 2164 win-start-end)
2170 (goto-char new-window-point) 2165 (goto-char new-window-point)
2171 (if (eq win (selected-window)) 2166 (if (eq win (selected-window))
2172 (set-window-start win new-window-start)) 2167 (set-window-start win new-window-start))
2173 (setq win-start-end (follow-windows-start-end windows))) 2168 (setq win-start-end (follow-windows-start-end windows)))
2175 ((pos-visible-in-window-p new-window-point) 2170 ((pos-visible-in-window-p new-window-point)
2176 (follow-debug-message "filter: Visible in window")) 2171 (follow-debug-message "filter: Visible in window"))
2177 ;; Avoid redisplaying the first window. If the 2172 ;; Avoid redisplaying the first window. If the
2178 ;; point is visible at a window below, 2173 ;; point is visible at a window below,
2179 ;; redisplay and select it. 2174 ;; redisplay and select it.
2180 ((follow-select-if-visible-from-first 2175 ((follow-select-if-visible-from-first
2181 new-window-point windows) 2176 new-window-point windows)
2182 (follow-debug-message "filter: Seen from first") 2177 (follow-debug-message "filter: Seen from first")
2183 (follow-redisplay windows (car windows)) 2178 (follow-redisplay windows (car windows))
2184 (goto-char new-window-point) 2179 (goto-char new-window-point)
2185 (setq win-start-end 2180 (setq win-start-end
2186 (follow-windows-start-end windows))) 2181 (follow-windows-start-end windows)))
2187 ;; None of the above. We stick to the current window. 2182 ;; None of the above. We stick to the current window.
2188 (t 2183 (t
2189 (follow-debug-message "filter: nothing"))) 2184 (follow-debug-message "filter: nothing")))
2190 2185
2191 ;; Here we have slected a window. Make sure the 2186 ;; Here we have slected a window. Make sure the
2192 ;; windows are aligned and the point is visible 2187 ;; windows are aligned and the point is visible
2193 ;; in the selected window. 2188 ;; in the selected window.
2194 (if (and (not (follow-pos-visible 2189 (if (and (not (follow-pos-visible
2195 (point) (selected-window) win-start-end)) 2190 (point) (selected-window) win-start-end))
2196 (not return-to-orig-win)) 2191 (not return-to-orig-win))
2197 (progn 2192 (progn
2198 (sit-for 0) 2193 (sit-for 0)
2199 (setq win-start-end 2194 (setq win-start-end
2200 (follow-windows-start-end windows)))) 2195 (follow-windows-start-end windows))))
2201 2196
2202 (if (or follow-internal-force-redisplay 2197 (if (or follow-internal-force-redisplay
2203 (not (follow-windows-aligned-p win-start-end))) 2198 (not (follow-windows-aligned-p win-start-end)))
2204 (follow-redisplay windows))))))) 2199 (follow-redisplay windows)))))))
2209 ;; Restore the orignal buffer, unless the filter explicitly 2204 ;; Restore the orignal buffer, unless the filter explicitly
2210 ;; changed buffer or killed the old buffer. 2205 ;; changed buffer or killed the old buffer.
2211 (if (and (eq buf (current-buffer)) 2206 (if (and (eq buf (current-buffer))
2212 (buffer-name old-buffer)) 2207 (buffer-name old-buffer))
2213 (set-buffer old-buffer))) 2208 (set-buffer old-buffer)))
2214 2209
2215 (follow-invalidate-cache) 2210 (follow-invalidate-cache)
2216 2211
2217 ;; Normally, if the display has been changed, it is redrawn. All 2212 ;; Normally, if the display has been changed, it is redrawn. All
2218 ;; windows showing only the end of a buffer is unconditionally 2213 ;; windows showing only the end of a buffer is unconditionally
2219 ;; recentered, we can't prevent it by calling 2214 ;; recentered, we can't prevent it by calling
2261 (orig-frame (selected-frame)) 2256 (orig-frame (selected-frame))
2262 windows 2257 windows
2263 buf) 2258 buf)
2264 (select-frame frame) 2259 (select-frame frame)
2265 (unwind-protect 2260 (unwind-protect
2266 (walk-windows 2261 (walk-windows
2267 (function 2262 (function
2268 (lambda (win) 2263 (lambda (win)
2269 (setq buf (window-buffer win)) 2264 (setq buf (window-buffer win))
2270 (if (memq buf buffers) 2265 (if (memq buf buffers)
2271 nil 2266 nil
2272 (set-buffer buf) 2267 (set-buffer buf)
2312 (boundp 'isearch-window-configuration) 2307 (boundp 'isearch-window-configuration)
2313 isearch-window-configuration 2308 isearch-window-configuration
2314 (boundp 'isearch-slow-terminal-mode) 2309 (boundp 'isearch-slow-terminal-mode)
2315 (not isearch-slow-terminal-mode)) 2310 (not isearch-slow-terminal-mode))
2316 (let ((buf (current-buffer))) 2311 (let ((buf (current-buffer)))
2317 (setq isearch-window-configuration 2312 (setq isearch-window-configuration
2318 (current-window-configuration)) 2313 (current-window-configuration))
2319 (set-buffer buf))))) 2314 (set-buffer buf)))))
2320 2315
2321 ;;}}} 2316 ;;}}}
2322 ;;{{{ Tail window handling 2317 ;;{{{ Tail window handling
2323 2318
2324 ;;; In Emacs (not XEmacs) windows showing nothing are sometimes 2319 ;;; In Emacs (not XEmacs) windows showing nothing are sometimes
2325 ;;; recentered. When in Follow Mode, this is not desireable for 2320 ;;; recentered. When in Follow Mode, this is not desireable for
2326 ;;; non-first windows in the window chain. This section tries to 2321 ;;; non-first windows in the window chain. This section tries to
2327 ;;; make the windows stay where they should be. 2322 ;;; make the windows stay where they should be.
2328 ;;; 2323 ;;;
2329 ;;; If the display is updated, all windows starting at (point-max) are 2324 ;;; If the display is updated, all windows starting at (point-max) are
2367 ;; tail windows. 2362 ;; tail windows.
2368 2363
2369 (if (and follow-avoid-tail-recenter-p 2364 (if (and follow-avoid-tail-recenter-p
2370 (fboundp 'move-overlay)) 2365 (fboundp 'move-overlay))
2371 (defadvice move-overlay (before follow-move-overlay activate) 2366 (defadvice move-overlay (before follow-move-overlay activate)
2372 "Adviced by Follow Mode. Don't recenter windows showing only 2367 "Adviced by Follow Mode.
2373 the end of a buffer. This prevents `mouse-drag-region' from 2368 Don't recenter windows showing only the end of a buffer.
2374 messing things up." 2369 This prevents `mouse-drag-region' from messing things up."
2375 (follow-avoid-tail-recenter))) 2370 (follow-avoid-tail-recenter)))
2376 2371
2377 ;;}}} 2372 ;;}}}
2378 ;;{{{ profile support 2373 ;;{{{ profile support
2379 2374
2382 ;; 2377 ;;
2383 ;; Invalid indentation on purpose! 2378 ;; Invalid indentation on purpose!
2384 2379
2385 (cond (nil 2380 (cond (nil
2386 (setq elp-function-list 2381 (setq elp-function-list
2387 '(window-end 2382 '(window-end
2388 vertical-motion 2383 vertical-motion
2389 ; sit-for ;; elp can't handle advices... 2384 ; sit-for ;; elp can't handle advices...
2390 follow-mode 2385 follow-mode
2391 follow-all-followers 2386 follow-all-followers
2392 follow-split-followers 2387 follow-split-followers
2393 follow-redisplay 2388 follow-redisplay
2394 follow-downward 2389 follow-downward
2395 follow-calculate-first-window-start 2390 follow-calculate-first-window-start
2396 follow-estimate-first-window-start 2391 follow-estimate-first-window-start
2397 follow-calculate-first-window-start-from-above 2392 follow-calculate-first-window-start-from-above