diff options
| author | Alan Mackenzie | 2015-12-20 12:33:30 +0000 |
|---|---|---|
| committer | Alan Mackenzie | 2015-12-20 12:33:30 +0000 |
| commit | df32db2f5f3dcad4b2b16fd52e51e1c7bd846609 (patch) | |
| tree | 74c24ce0fd04942ec496aab04d8f25482944107e | |
| parent | 6a8a41c5104b29846ed6e69da7576e0960f2bf14 (diff) | |
| parent | a72a9fbbbc9cd5f5933719b11489c2578eb0aa59 (diff) | |
| download | emacs-df32db2f5f3dcad4b2b16fd52e51e1c7bd846609.tar.gz emacs-df32db2f5f3dcad4b2b16fd52e51e1c7bd846609.zip | |
Merge branch 'scratch/follow' into emacs-25
This allows Isearch, etc., to work well when Follow Mode is active.
| -rw-r--r-- | doc/lispref/functions.texi | 17 | ||||
| -rw-r--r-- | doc/lispref/positions.texi | 12 | ||||
| -rw-r--r-- | doc/lispref/windows.texi | 88 | ||||
| -rw-r--r-- | lisp/follow.el | 176 | ||||
| -rw-r--r-- | lisp/isearch.el | 125 | ||||
| -rw-r--r-- | lisp/replace.el | 8 | ||||
| -rw-r--r-- | lisp/textmodes/ispell.el | 79 | ||||
| -rw-r--r-- | lisp/window.el | 146 |
8 files changed, 577 insertions, 74 deletions
diff --git a/doc/lispref/functions.texi b/doc/lispref/functions.texi index 8835667b82d..7cc041fa77e 100644 --- a/doc/lispref/functions.texi +++ b/doc/lispref/functions.texi | |||
| @@ -861,15 +861,18 @@ into a list. @code{mapc} always returns @var{sequence}. | |||
| 861 | 861 | ||
| 862 | @defun mapconcat function sequence separator | 862 | @defun mapconcat function sequence separator |
| 863 | @code{mapconcat} applies @var{function} to each element of | 863 | @code{mapconcat} applies @var{function} to each element of |
| 864 | @var{sequence}: the results, which must be strings, are concatenated. | 864 | @var{sequence}; the results, which must be sequences of characters |
| 865 | Between each pair of result strings, @code{mapconcat} inserts the string | 865 | (strings, vectors, or lists), are concatenated into a single string |
| 866 | @var{separator}. Usually @var{separator} contains a space or comma or | 866 | return value. Between each pair of result sequences, @code{mapconcat} |
| 867 | other suitable punctuation. | 867 | inserts the characters from @var{separator}, which also must be a |
| 868 | string, or a vector or list of characters. @xref{Sequences Arrays | ||
| 869 | Vectors}. | ||
| 868 | 870 | ||
| 869 | The argument @var{function} must be a function that can take one | 871 | The argument @var{function} must be a function that can take one |
| 870 | argument and return a string. The argument @var{sequence} can be any | 872 | argument and returns a sequence of characters: a string, a vector, or |
| 871 | kind of sequence except a char-table; that is, a list, a vector, a | 873 | a list. The argument @var{sequence} can be any kind of sequence |
| 872 | bool-vector, or a string. | 874 | except a char-table; that is, a list, a vector, a bool-vector, or a |
| 875 | string. | ||
| 873 | 876 | ||
| 874 | @example | 877 | @example |
| 875 | @group | 878 | @group |
diff --git a/doc/lispref/positions.texi b/doc/lispref/positions.texi index 72b76ce5c8f..9daf5cef059 100644 --- a/doc/lispref/positions.texi +++ b/doc/lispref/positions.texi | |||
| @@ -572,6 +572,18 @@ The value returned is the window line number point has moved to, with | |||
| 572 | the top line in the window numbered 0. | 572 | the top line in the window numbered 0. |
| 573 | @end deffn | 573 | @end deffn |
| 574 | 574 | ||
| 575 | @vindex move-to-window-group-line-function | ||
| 576 | @defun move-to-window-group-line count | ||
| 577 | This function is like @code{move-to-window-line}, except that when the | ||
| 578 | selected window is a part of a group of windows (@pxref{Window | ||
| 579 | Group}), @code{move-to-window-group-line} will move to a position with | ||
| 580 | respect to the entire group, not just the single window. This | ||
| 581 | condition holds when the buffer local variable | ||
| 582 | @code{move-to-window-group-line-function} is set to a function. In | ||
| 583 | this case, @code{move-to-window-group-line} calls the function with | ||
| 584 | the argument @var{count}, then returns its result. | ||
| 585 | @end defun | ||
| 586 | |||
| 575 | @defun compute-motion from frompos to topos width offsets window | 587 | @defun compute-motion from frompos to topos width offsets window |
| 576 | This function scans the current buffer, calculating screen positions. | 588 | This function scans the current buffer, calculating screen positions. |
| 577 | It scans the buffer forward from position @var{from}, assuming that is | 589 | It scans the buffer forward from position @var{from}, assuming that is |
diff --git a/doc/lispref/windows.texi b/doc/lispref/windows.texi index 5c7947eeca6..e45201b0570 100644 --- a/doc/lispref/windows.texi +++ b/doc/lispref/windows.texi | |||
| @@ -133,6 +133,30 @@ This function returns the selected window (which is always a live | |||
| 133 | window). | 133 | window). |
| 134 | @end defun | 134 | @end defun |
| 135 | 135 | ||
| 136 | @anchor{Window Group}Sometimes several windows collectively and | ||
| 137 | cooperatively display a buffer, for example, under the management of | ||
| 138 | Follow Mode (@pxref{Follow Mode,,, emacs}), where the windows together | ||
| 139 | display a bigger portion of the buffer than one window could alone. | ||
| 140 | It is often useful to consider such a @dfn{window group} as a single | ||
| 141 | entity. Several functions such as @code{window-group-start} | ||
| 142 | (@pxref{Window Start and End}) allow you to do this by supplying, as | ||
| 143 | an argument, one of the windows as a stand in for the whole group. | ||
| 144 | |||
| 145 | @defun selected-window-group | ||
| 146 | @vindex selected-window-group-function | ||
| 147 | When the selected window is a member of a group of windows, this | ||
| 148 | function returns a list of the windows in the group, ordered such that | ||
| 149 | the first window in the list is displaying the earliest part of the | ||
| 150 | buffer, and so on. Otherwise the function returns a list containing | ||
| 151 | just the selected window. | ||
| 152 | |||
| 153 | The selected window is considered part of a group when the buffer | ||
| 154 | local variable @code{selected-window-group-function} is set to a | ||
| 155 | function. In this case, @code{selected-window-group} calls it with no | ||
| 156 | arguments and returns its result (which should be the list of windows | ||
| 157 | in the group). | ||
| 158 | @end defun | ||
| 159 | |||
| 136 | @node Windows and Frames | 160 | @node Windows and Frames |
| 137 | @section Windows and Frames | 161 | @section Windows and Frames |
| 138 | 162 | ||
| @@ -3098,6 +3122,17 @@ window-start position; if you move point, do not expect the window-start | |||
| 3098 | position to change in response until after the next redisplay. | 3122 | position to change in response until after the next redisplay. |
| 3099 | @end defun | 3123 | @end defun |
| 3100 | 3124 | ||
| 3125 | @defun window-group-start &optional window | ||
| 3126 | @vindex window-group-start-function | ||
| 3127 | This function is like @code{window-start}, except that when | ||
| 3128 | @var{window} is a part of a group of windows (@pxref{Window Group}), | ||
| 3129 | @code{window-group-start} returns the start position of the entire | ||
| 3130 | group. This condition holds when the buffer local variable | ||
| 3131 | @code{window-group-start-function} is set to a function. In this | ||
| 3132 | case, @code{window-group-start} calls the function with the single | ||
| 3133 | argument @var{window}, then returns its result. | ||
| 3134 | @end defun | ||
| 3135 | |||
| 3101 | @cindex window end position | 3136 | @cindex window end position |
| 3102 | @defun window-end &optional window update | 3137 | @defun window-end &optional window update |
| 3103 | This function returns the position where display of its buffer ends in | 3138 | This function returns the position where display of its buffer ends in |
| @@ -3124,6 +3159,18 @@ way real redisplay would do. It does not alter the | |||
| 3124 | text will end if scrolling is not required. | 3159 | text will end if scrolling is not required. |
| 3125 | @end defun | 3160 | @end defun |
| 3126 | 3161 | ||
| 3162 | @vindex window-group-end-function | ||
| 3163 | @defun window-group-end window update | ||
| 3164 | This function is like @code{window-end}, except that when @var{window} | ||
| 3165 | is a part of a group of windows (@pxref{Window Group}), | ||
| 3166 | @code{window-group-end} returns the end position of the entire group. | ||
| 3167 | This condition holds when the buffer local variable | ||
| 3168 | @code{window-group-end-function} is set to a function. In this case, | ||
| 3169 | @code{window-group-end} calls the function with the two arguments | ||
| 3170 | @var{window} and @var{update}, then returns its result. The argument | ||
| 3171 | @var{update} has the same meaning as in @code{window-end}. | ||
| 3172 | @end defun | ||
| 3173 | |||
| 3127 | @defun set-window-start window position &optional noforce | 3174 | @defun set-window-start window position &optional noforce |
| 3128 | This function sets the display-start position of @var{window} to | 3175 | This function sets the display-start position of @var{window} to |
| 3129 | @var{position} in @var{window}'s buffer. It returns @var{position}. | 3176 | @var{position} in @var{window}'s buffer. It returns @var{position}. |
| @@ -3187,6 +3234,19 @@ off screen at the next redisplay, then redisplay computes a new window-start | |||
| 3187 | position that works well with point, and thus @var{position} is not used. | 3234 | position that works well with point, and thus @var{position} is not used. |
| 3188 | @end defun | 3235 | @end defun |
| 3189 | 3236 | ||
| 3237 | @vindex set-window-group-start-function | ||
| 3238 | @defun set-window-group-start window position &optional noforce | ||
| 3239 | This function is like @code{set-window-start}, except that when | ||
| 3240 | @var{window} is a part of a group of windows (@pxref{Window Group}), | ||
| 3241 | @code{set-window-group-start} sets the start position of the entire | ||
| 3242 | group. This condition holds when the buffer local variable | ||
| 3243 | @code{set-window-group-start-function} is set to a function. In this | ||
| 3244 | case, @code{set-window-group-start} calls the function with the three | ||
| 3245 | arguments @var{window}, @var{position}, and @var{noforce}, then | ||
| 3246 | returns its result. The arguments @var{position} and @var{noforce} in | ||
| 3247 | this function have the same meaning as in @code{set-window-start}. | ||
| 3248 | @end defun | ||
| 3249 | |||
| 3190 | @defun pos-visible-in-window-p &optional position window partially | 3250 | @defun pos-visible-in-window-p &optional position window partially |
| 3191 | This function returns non-@code{nil} if @var{position} is within the | 3251 | This function returns non-@code{nil} if @var{position} is within the |
| 3192 | range of text currently visible on the screen in @var{window}. It | 3252 | range of text currently visible on the screen in @var{window}. It |
| @@ -3228,6 +3288,21 @@ Here is an example: | |||
| 3228 | @end example | 3288 | @end example |
| 3229 | @end defun | 3289 | @end defun |
| 3230 | 3290 | ||
| 3291 | @vindex pos-visible-in-window-group-p-function | ||
| 3292 | @defun pos-visible-in-window-group-p &optional position window partially | ||
| 3293 | This function is like @code{pos-visible-in-window-p}, except that when | ||
| 3294 | @var{window} is a part of a group of windows (@pxref{Window Group}), | ||
| 3295 | @code{pos-visible-in-window-group-p} tests the visibility of @var{pos} | ||
| 3296 | in the entire group, not just in the single @var{window}. This | ||
| 3297 | condition holds when the buffer local variable | ||
| 3298 | @code{pos-visible-in-window-group-p-function} is set to a function. | ||
| 3299 | In this case @code{pos-visible-in-window-group-p} calls the function | ||
| 3300 | with the three arguments @var{position}, @var{window}, and | ||
| 3301 | @var{partially}, then returns its result. The arguments | ||
| 3302 | @var{position} and @var{partially} have the same meaning as in | ||
| 3303 | @code{pos-visible-in-window-p}. | ||
| 3304 | @end defun | ||
| 3305 | |||
| 3231 | @defun window-line-height &optional line window | 3306 | @defun window-line-height &optional line window |
| 3232 | This function returns the height of text line @var{line} in | 3307 | This function returns the height of text line @var{line} in |
| 3233 | @var{window}. If @var{line} is one of @code{header-line} or | 3308 | @var{window}. If @var{line} is one of @code{header-line} or |
| @@ -3471,6 +3546,19 @@ the top of the window. The command @code{recenter-top-bottom} offers | |||
| 3471 | a more convenient way to achieve this. | 3546 | a more convenient way to achieve this. |
| 3472 | @end deffn | 3547 | @end deffn |
| 3473 | 3548 | ||
| 3549 | @vindex recenter-window-group-function | ||
| 3550 | @defun recenter-window-group &optional count | ||
| 3551 | This function is like @code{recenter}, except that when the selected | ||
| 3552 | window is part of a group of windows (@pxref{Window Group}), | ||
| 3553 | @code{recenter-window-group} scrolls the entire group. This condition | ||
| 3554 | holds when the buffer local variable | ||
| 3555 | @code{recenter-window-group-function} is set to a function. In this | ||
| 3556 | case, @code{recenter-window-group} calls the function with the | ||
| 3557 | argument @var{count}, then returns its result. The argument | ||
| 3558 | @var{count} has the same meaning as in @code{recenter}, but with | ||
| 3559 | respect to the entire window group. | ||
| 3560 | @end defun | ||
| 3561 | |||
| 3474 | @defopt recenter-redisplay | 3562 | @defopt recenter-redisplay |
| 3475 | If this variable is non-@code{nil}, calling @code{recenter} with a | 3563 | If this variable is non-@code{nil}, calling @code{recenter} with a |
| 3476 | @code{nil} argument redraws the frame. The default value is | 3564 | @code{nil} argument redraws the frame. The default value is |
diff --git a/lisp/follow.el b/lisp/follow.el index 37de923e6a5..71e8824947d 100644 --- a/lisp/follow.el +++ b/lisp/follow.el | |||
| @@ -421,7 +421,21 @@ Keys specific to Follow mode: | |||
| 421 | (progn | 421 | (progn |
| 422 | (add-hook 'compilation-filter-hook 'follow-align-compilation-windows t t) | 422 | (add-hook 'compilation-filter-hook 'follow-align-compilation-windows t t) |
| 423 | (add-hook 'post-command-hook 'follow-post-command-hook t) | 423 | (add-hook 'post-command-hook 'follow-post-command-hook t) |
| 424 | (add-hook 'window-size-change-functions 'follow-window-size-change t)) | 424 | (add-hook 'window-size-change-functions 'follow-window-size-change t) |
| 425 | (add-hook 'after-change-functions 'follow-after-change nil t) | ||
| 426 | (add-hook 'isearch-update-post-hook 'follow-post-command-hook nil t) | ||
| 427 | (add-hook 'replace-update-post-hook 'follow-post-command-hook nil t) | ||
| 428 | (add-hook 'ispell-update-post-hook 'follow-post-command-hook nil t) | ||
| 429 | |||
| 430 | (setq window-group-start-function 'follow-window-start) | ||
| 431 | (setq window-group-end-function 'follow-window-end) | ||
| 432 | (setq set-window-group-start-function 'follow-set-window-start) | ||
| 433 | (setq recenter-window-group-function 'follow-recenter) | ||
| 434 | (setq pos-visible-in-window-group-p-function | ||
| 435 | 'follow-pos-visible-in-window-p) | ||
| 436 | (setq selected-window-group-function 'follow-all-followers) | ||
| 437 | (setq move-to-window-group-line-function 'follow-move-to-window-line)) | ||
| 438 | |||
| 425 | ;; Remove globally-installed hook functions only if there is no | 439 | ;; Remove globally-installed hook functions only if there is no |
| 426 | ;; other Follow mode buffer. | 440 | ;; other Follow mode buffer. |
| 427 | (let ((buffers (buffer-list)) | 441 | (let ((buffers (buffer-list)) |
| @@ -432,6 +446,19 @@ Keys specific to Follow mode: | |||
| 432 | (unless following | 446 | (unless following |
| 433 | (remove-hook 'post-command-hook 'follow-post-command-hook) | 447 | (remove-hook 'post-command-hook 'follow-post-command-hook) |
| 434 | (remove-hook 'window-size-change-functions 'follow-window-size-change))) | 448 | (remove-hook 'window-size-change-functions 'follow-window-size-change))) |
| 449 | |||
| 450 | (kill-local-variable 'move-to-window-group-line-function) | ||
| 451 | (kill-local-variable 'selected-window-group-function) | ||
| 452 | (kill-local-variable 'pos-visible-in-window-group-p-function) | ||
| 453 | (kill-local-variable 'recenter-window-group-function) | ||
| 454 | (kill-local-variable 'set-window-group-start-function) | ||
| 455 | (kill-local-variable 'window-group-end-function) | ||
| 456 | (kill-local-variable 'window-group-start-function) | ||
| 457 | |||
| 458 | (remove-hook 'ispell-update-post-hook 'follow-post-command-hook t) | ||
| 459 | (remove-hook 'replace-update-post-hook 'follow-post-command-hook t) | ||
| 460 | (remove-hook 'isearch-update-post-hook 'follow-post-command-hook t) | ||
| 461 | (remove-hook 'after-change-functions 'follow-after-change t) | ||
| 435 | (remove-hook 'compilation-filter-hook 'follow-align-compilation-windows t))) | 462 | (remove-hook 'compilation-filter-hook 'follow-align-compilation-windows t))) |
| 436 | 463 | ||
| 437 | (defun follow-find-file-hook () | 464 | (defun follow-find-file-hook () |
| @@ -1015,6 +1042,10 @@ Otherwise, return nil." | |||
| 1015 | ;; is nil. Start every window directly after the end of the previous | 1042 | ;; is nil. Start every window directly after the end of the previous |
| 1016 | ;; window, to make sure long lines are displayed correctly. | 1043 | ;; window, to make sure long lines are displayed correctly. |
| 1017 | 1044 | ||
| 1045 | (defvar follow-start-end-invalid t | ||
| 1046 | "When non-nil, indicates `follow-windows-start-end-cache' is invalid.") | ||
| 1047 | (make-variable-buffer-local 'follow-start-end-invalid) | ||
| 1048 | |||
| 1018 | (defun follow-redisplay (&optional windows win preserve-win) | 1049 | (defun follow-redisplay (&optional windows win preserve-win) |
| 1019 | "Reposition the WINDOWS around WIN. | 1050 | "Reposition the WINDOWS around WIN. |
| 1020 | Should point be too close to the roof we redisplay everything | 1051 | Should point be too close to the roof we redisplay everything |
| @@ -1047,7 +1078,8 @@ repositioning the other windows." | |||
| 1047 | (dolist (w windows) | 1078 | (dolist (w windows) |
| 1048 | (unless (and preserve-win (eq w win)) | 1079 | (unless (and preserve-win (eq w win)) |
| 1049 | (set-window-start w start)) | 1080 | (set-window-start w start)) |
| 1050 | (setq start (car (follow-calc-win-end w)))))) | 1081 | (setq start (car (follow-calc-win-end w)))) |
| 1082 | (setq follow-start-end-invalid nil))) | ||
| 1051 | 1083 | ||
| 1052 | (defun follow-estimate-first-window-start (windows win start) | 1084 | (defun follow-estimate-first-window-start (windows win start) |
| 1053 | "Estimate the position of the first window. | 1085 | "Estimate the position of the first window. |
| @@ -1443,6 +1475,146 @@ non-first windows in Follow mode." | |||
| 1443 | 1475 | ||
| 1444 | (add-hook 'window-scroll-functions 'follow-avoid-tail-recenter t) | 1476 | (add-hook 'window-scroll-functions 'follow-avoid-tail-recenter t) |
| 1445 | 1477 | ||
| 1478 | ;;; Low level window start and end. | ||
| 1479 | |||
| 1480 | ;; These routines are the Follow Mode versions of the low level | ||
| 1481 | ;; functions described on page "Window Start and End" of the elisp | ||
| 1482 | ;; manual, e.g. `window-group-start'. The aim is to be able to handle | ||
| 1483 | ;; Follow Mode windows by replacing `window-start' by | ||
| 1484 | ;; `window-group-start', etc. | ||
| 1485 | |||
| 1486 | (defun follow-after-change (_beg _end _old-len) | ||
| 1487 | "After change function: set `follow-start-end-invalid'." | ||
| 1488 | (setq follow-start-end-invalid t)) | ||
| 1489 | |||
| 1490 | (defun follow-window-start (&optional window) | ||
| 1491 | "Return position at which display currently starts in the | ||
| 1492 | Follow Mode group of windows which includes WINDOW. | ||
| 1493 | |||
| 1494 | WINDOW must be a live window and defaults to the selected one. | ||
| 1495 | This is updated by redisplay or by calling | ||
| 1496 | `follow-set-window-start'." | ||
| 1497 | (let ((windows (follow-all-followers window))) | ||
| 1498 | (window-start (car windows)))) | ||
| 1499 | |||
| 1500 | (defun follow-window-end (&optional window update) | ||
| 1501 | "Return position at which display currently ends in the Follow | ||
| 1502 | Mode group of windows which includes WINDOW. | ||
| 1503 | |||
| 1504 | WINDOW must be a live window and defaults to the selected one. | ||
| 1505 | This is updated by redisplay, when it runs to completion. | ||
| 1506 | Simply changing the buffer text or setting `window-start' does | ||
| 1507 | not update this value. | ||
| 1508 | |||
| 1509 | Return nil if there is no recorded value. (This can happen if | ||
| 1510 | the last redisplay of WINDOW was preempted, and did not | ||
| 1511 | finish.) If UPDATE is non-nil, compute the up-to-date position | ||
| 1512 | if it isn't already recorded." | ||
| 1513 | (let* ((windows (follow-all-followers window)) | ||
| 1514 | (last (car (last windows)))) | ||
| 1515 | (when (and update follow-start-end-invalid) | ||
| 1516 | (follow-redisplay windows (car windows))) | ||
| 1517 | (window-end last update))) | ||
| 1518 | |||
| 1519 | (defun follow-set-window-start (window pos &optional noforce) | ||
| 1520 | "Make display in the Follow Mode group of windows which includes | ||
| 1521 | WINDOW start at position POS in WINDOW's buffer. | ||
| 1522 | |||
| 1523 | WINDOW must be a live window and defaults to the selected one. Return | ||
| 1524 | POS. Optional third arg NOFORCE non-nil inhibits next redisplay from | ||
| 1525 | overriding motion of point in order to display at this exact start." | ||
| 1526 | (let ((windows (follow-all-followers window))) | ||
| 1527 | (setq follow-start-end-invalid t) | ||
| 1528 | (set-window-start (car windows) pos noforce))) | ||
| 1529 | |||
| 1530 | (defun follow-pos-visible-in-window-p (&optional pos window partially) | ||
| 1531 | "Return non-nil if position POS is currently on the frame in one of | ||
| 1532 | the windows in the Follow Mode group which includes WINDOW. | ||
| 1533 | |||
| 1534 | WINDOW must be a live window and defaults to the selected one. | ||
| 1535 | |||
| 1536 | Return nil if that position is scrolled vertically out of view. If a | ||
| 1537 | character is only partially visible, nil is returned, unless the | ||
| 1538 | optional argument PARTIALLY is non-nil. If POS is only out of view | ||
| 1539 | because of horizontal scrolling, return non-nil. If POS is t, it | ||
| 1540 | specifies the position of the last visible glyph in WINDOW. POS | ||
| 1541 | defaults to point in WINDOW; WINDOW defaults to the selected window. | ||
| 1542 | |||
| 1543 | If POS is visible, return t if PARTIALLY is nil; if PARTIALLY is non-nil, | ||
| 1544 | the return value is a list of 2 or 6 elements (X Y [RTOP RBOT ROWH VPOS]), | ||
| 1545 | where X and Y are the pixel coordinates relative to the top left corner | ||
| 1546 | of the actual window containing it. The remaining elements are | ||
| 1547 | omitted if the character after POS is fully visible; otherwise, RTOP | ||
| 1548 | and RBOT are the number of pixels off-window at the top and bottom of | ||
| 1549 | the screen line (\"row\") containing POS, ROWH is the visible height | ||
| 1550 | of that row, and VPOS is the row number \(zero-based)." | ||
| 1551 | (let* ((windows (follow-all-followers window)) | ||
| 1552 | (last (car (last windows)))) | ||
| 1553 | (when follow-start-end-invalid | ||
| 1554 | (follow-redisplay windows (car windows))) | ||
| 1555 | (let* ((cache (follow-windows-start-end windows)) | ||
| 1556 | (last-elt (car (last cache))) | ||
| 1557 | our-pos pertinent-elt) | ||
| 1558 | (setq pertinent-elt | ||
| 1559 | (if (eq pos t) | ||
| 1560 | last-elt | ||
| 1561 | (setq our-pos (or pos (point))) | ||
| 1562 | (catch 'element | ||
| 1563 | (while cache | ||
| 1564 | (when (< our-pos (nth 2 (car cache))) | ||
| 1565 | (throw 'element (car cache))) | ||
| 1566 | (setq cache (cdr cache))) | ||
| 1567 | last-elt))) | ||
| 1568 | (pos-visible-in-window-p our-pos (car pertinent-elt) partially)))) | ||
| 1569 | |||
| 1570 | (defun follow-move-to-window-line (arg) | ||
| 1571 | "Position point relative to the Follow mode group containing the selected window. | ||
| 1572 | ARG nil means position point at center of the window group. | ||
| 1573 | Else, ARG specifies vertical position within the window group; | ||
| 1574 | zero means top of the first window in the group, negative means | ||
| 1575 | relative to bottom of the last window in the group." | ||
| 1576 | (let* ((windows (follow-all-followers)) | ||
| 1577 | (start-end (follow-windows-start-end windows)) | ||
| 1578 | (rev-start-end (reverse start-end)) | ||
| 1579 | (lines 0) | ||
| 1580 | middle-window elt count) | ||
| 1581 | (select-window | ||
| 1582 | (cond | ||
| 1583 | ((null arg) | ||
| 1584 | (setq rev-start-end (nthcdr (/ (length windows) 2) rev-start-end)) | ||
| 1585 | (prog1 (car (car rev-start-end)) | ||
| 1586 | (while (setq rev-start-end (cdr rev-start-end)) | ||
| 1587 | (setq elt (car rev-start-end) | ||
| 1588 | count (count-screen-lines (cadr elt) (nth 2 elt) | ||
| 1589 | nil (car elt)) | ||
| 1590 | lines (+ lines count))))) | ||
| 1591 | ((>= arg 0) | ||
| 1592 | (while (and (cdr start-end) | ||
| 1593 | (progn | ||
| 1594 | (setq elt (car start-end) | ||
| 1595 | count (count-screen-lines (cadr elt) (nth 2 elt) | ||
| 1596 | nil (car elt))) | ||
| 1597 | (>= arg count))) | ||
| 1598 | (setq arg (- arg count) | ||
| 1599 | lines (+ lines count) | ||
| 1600 | start-end (cdr start-end))) | ||
| 1601 | (car (car start-end))) | ||
| 1602 | (t ; (< arg 0) | ||
| 1603 | (while (and (cadr rev-start-end) | ||
| 1604 | (progn | ||
| 1605 | (setq elt (car rev-start-end) | ||
| 1606 | count (count-lines (cadr elt) (nth 2 elt))) | ||
| 1607 | (<= arg (- count)))) | ||
| 1608 | (setq arg (+ arg count) | ||
| 1609 | rev-start-end (cdr rev-start-end))) | ||
| 1610 | (prog1 (car (car rev-start-end)) | ||
| 1611 | (while (setq rev-start-end (cdr rev-start-end)) | ||
| 1612 | (setq elt (car rev-start-end) | ||
| 1613 | count (count-screen-lines (cadr elt) (nth 2 elt) | ||
| 1614 | nil (car elt)) | ||
| 1615 | lines (+ lines count))))))) | ||
| 1616 | (+ lines (move-to-window-line arg)))) | ||
| 1617 | |||
| 1446 | ;;; Profile support | 1618 | ;;; Profile support |
| 1447 | 1619 | ||
| 1448 | ;; The following (non-evaluated) section can be used to | 1620 | ;; The following (non-evaluated) section can be used to |
diff --git a/lisp/isearch.el b/lisp/isearch.el index 8c98d36f4aa..05dc2931d93 100644 --- a/lisp/isearch.el +++ b/lisp/isearch.el | |||
| @@ -961,7 +961,8 @@ used to set the value of `isearch-regexp-function'." | |||
| 961 | 961 | ||
| 962 | (defun isearch-update () | 962 | (defun isearch-update () |
| 963 | "This is called after every isearch command to update the display. | 963 | "This is called after every isearch command to update the display. |
| 964 | The last thing it does is to run `isearch-update-post-hook'." | 964 | The second last thing it does is to run `isearch-update-post-hook'. |
| 965 | The last thing is to trigger a new round of lazy highlighting." | ||
| 965 | (unless (eq (current-buffer) isearch--current-buffer) | 966 | (unless (eq (current-buffer) isearch--current-buffer) |
| 966 | (when (buffer-live-p isearch--current-buffer) | 967 | (when (buffer-live-p isearch--current-buffer) |
| 967 | (with-current-buffer isearch--current-buffer | 968 | (with-current-buffer isearch--current-buffer |
| @@ -978,12 +979,10 @@ The last thing it does is to run `isearch-update-post-hook'." | |||
| 978 | (null executing-kbd-macro)) | 979 | (null executing-kbd-macro)) |
| 979 | (progn | 980 | (progn |
| 980 | (if (not (input-pending-p)) | 981 | (if (not (input-pending-p)) |
| 981 | (if isearch-message-function | 982 | (funcall (or isearch-message-function #'isearch-message))) |
| 982 | (funcall isearch-message-function) | ||
| 983 | (isearch-message))) | ||
| 984 | (if (and isearch-slow-terminal-mode | 983 | (if (and isearch-slow-terminal-mode |
| 985 | (not (or isearch-small-window | 984 | (not (or isearch-small-window |
| 986 | (pos-visible-in-window-p)))) | 985 | (pos-visible-in-window-group-p)))) |
| 987 | (let ((found-point (point))) | 986 | (let ((found-point (point))) |
| 988 | (setq isearch-small-window t) | 987 | (setq isearch-small-window t) |
| 989 | (move-to-window-line 0) | 988 | (move-to-window-line 0) |
| @@ -1004,10 +1003,10 @@ The last thing it does is to run `isearch-update-post-hook'." | |||
| 1004 | (let ((current-scroll (window-hscroll)) | 1003 | (let ((current-scroll (window-hscroll)) |
| 1005 | visible-p) | 1004 | visible-p) |
| 1006 | (set-window-hscroll (selected-window) isearch-start-hscroll) | 1005 | (set-window-hscroll (selected-window) isearch-start-hscroll) |
| 1007 | (setq visible-p (pos-visible-in-window-p nil nil t)) | 1006 | (setq visible-p (pos-visible-in-window-group-p nil nil t)) |
| 1008 | (if (or (not visible-p) | 1007 | (if (or (not visible-p) |
| 1009 | ;; When point is not visible because of hscroll, | 1008 | ;; When point is not visible because of hscroll, |
| 1010 | ;; pos-visible-in-window-p returns non-nil, but | 1009 | ;; pos-visible-in-window-group-p returns non-nil, but |
| 1011 | ;; the X coordinate it returns is 1 pixel beyond | 1010 | ;; the X coordinate it returns is 1 pixel beyond |
| 1012 | ;; the last visible one. | 1011 | ;; the last visible one. |
| 1013 | (>= (car visible-p) (window-body-width nil t))) | 1012 | (>= (car visible-p) (window-body-width nil t))) |
| @@ -1020,12 +1019,12 @@ The last thing it does is to run `isearch-update-post-hook'." | |||
| 1020 | (setq ;; quit-flag nil not for isearch-mode | 1019 | (setq ;; quit-flag nil not for isearch-mode |
| 1021 | isearch-adjusted nil | 1020 | isearch-adjusted nil |
| 1022 | isearch-yank-flag nil) | 1021 | isearch-yank-flag nil) |
| 1023 | (when isearch-lazy-highlight | ||
| 1024 | (isearch-lazy-highlight-new-loop)) | ||
| 1025 | ;; We must prevent the point moving to the end of composition when a | 1022 | ;; We must prevent the point moving to the end of composition when a |
| 1026 | ;; part of the composition has just been searched. | 1023 | ;; part of the composition has just been searched. |
| 1027 | (setq disable-point-adjustment t) | 1024 | (setq disable-point-adjustment t) |
| 1028 | (run-hooks 'isearch-update-post-hook)) | 1025 | (run-hooks 'isearch-update-post-hook) |
| 1026 | (when isearch-lazy-highlight | ||
| 1027 | (isearch-lazy-highlight-new-loop))) | ||
| 1029 | 1028 | ||
| 1030 | (defun isearch-done (&optional nopush edit) | 1029 | (defun isearch-done (&optional nopush edit) |
| 1031 | "Exit Isearch mode. | 1030 | "Exit Isearch mode. |
| @@ -1058,7 +1057,7 @@ NOPUSH is t and EDIT is t." | |||
| 1058 | (setq minibuffer-message-timeout isearch-original-minibuffer-message-timeout) | 1057 | (setq minibuffer-message-timeout isearch-original-minibuffer-message-timeout) |
| 1059 | (isearch-dehighlight) | 1058 | (isearch-dehighlight) |
| 1060 | (lazy-highlight-cleanup lazy-highlight-cleanup) | 1059 | (lazy-highlight-cleanup lazy-highlight-cleanup) |
| 1061 | (let ((found-start (window-start)) | 1060 | (let ((found-start (window-group-start)) |
| 1062 | (found-point (point))) | 1061 | (found-point (point))) |
| 1063 | (when isearch-window-configuration | 1062 | (when isearch-window-configuration |
| 1064 | (set-window-configuration isearch-window-configuration) | 1063 | (set-window-configuration isearch-window-configuration) |
| @@ -1068,7 +1067,7 @@ NOPUSH is t and EDIT is t." | |||
| 1068 | ;; This has an annoying side effect of clearing the last_modiff | 1067 | ;; This has an annoying side effect of clearing the last_modiff |
| 1069 | ;; field of the window, which can cause unwanted scrolling, | 1068 | ;; field of the window, which can cause unwanted scrolling, |
| 1070 | ;; so don't do it unless truly necessary. | 1069 | ;; so don't do it unless truly necessary. |
| 1071 | (set-window-start (selected-window) found-start t)))) | 1070 | (set-window-group-start (selected-window) found-start t)))) |
| 1072 | 1071 | ||
| 1073 | (setq isearch-mode nil) | 1072 | (setq isearch-mode nil) |
| 1074 | (if isearch-input-method-local-p | 1073 | (if isearch-input-method-local-p |
| @@ -1299,13 +1298,6 @@ You can update the global isearch variables by setting new values to | |||
| 1299 | (unwind-protect | 1298 | (unwind-protect |
| 1300 | (progn ,@body) | 1299 | (progn ,@body) |
| 1301 | 1300 | ||
| 1302 | ;; Set point at the start (end) of old match if forward (backward), | ||
| 1303 | ;; so after exiting minibuffer isearch resumes at the start (end) | ||
| 1304 | ;; of this match and can find it again. | ||
| 1305 | (if (and old-other-end (eq old-point (point)) | ||
| 1306 | (eq isearch-forward isearch-new-forward)) | ||
| 1307 | (goto-char old-other-end)) | ||
| 1308 | |||
| 1309 | ;; Always resume isearching by restarting it. | 1301 | ;; Always resume isearching by restarting it. |
| 1310 | (isearch-mode isearch-forward | 1302 | (isearch-mode isearch-forward |
| 1311 | isearch-regexp | 1303 | isearch-regexp |
| @@ -1318,7 +1310,17 @@ You can update the global isearch variables by setting new values to | |||
| 1318 | isearch-message isearch-new-message | 1310 | isearch-message isearch-new-message |
| 1319 | isearch-forward isearch-new-forward | 1311 | isearch-forward isearch-new-forward |
| 1320 | isearch-regexp-function isearch-new-regexp-function | 1312 | isearch-regexp-function isearch-new-regexp-function |
| 1321 | isearch-case-fold-search isearch-new-case-fold)) | 1313 | isearch-case-fold-search isearch-new-case-fold) |
| 1314 | |||
| 1315 | ;; Restore the minibuffer message before moving point. | ||
| 1316 | (funcall (or isearch-message-function #'isearch-message) nil t) | ||
| 1317 | |||
| 1318 | ;; Set point at the start (end) of old match if forward (backward), | ||
| 1319 | ;; so after exiting minibuffer isearch resumes at the start (end) | ||
| 1320 | ;; of this match and can find it again. | ||
| 1321 | (if (and old-other-end (eq old-point (point)) | ||
| 1322 | (eq isearch-forward isearch-new-forward)) | ||
| 1323 | (goto-char old-other-end))) | ||
| 1322 | 1324 | ||
| 1323 | ;; Empty isearch-string means use default. | 1325 | ;; Empty isearch-string means use default. |
| 1324 | (when (= 0 (length isearch-string)) | 1326 | (when (= 0 (length isearch-string)) |
| @@ -1931,6 +1933,8 @@ If search string is empty, just beep." | |||
| 1931 | (length isearch-string)))) | 1933 | (length isearch-string)))) |
| 1932 | isearch-message (mapconcat 'isearch-text-char-description | 1934 | isearch-message (mapconcat 'isearch-text-char-description |
| 1933 | isearch-string ""))) | 1935 | isearch-string ""))) |
| 1936 | ;; Do the following before moving point. | ||
| 1937 | (funcall (or isearch-message-function #'isearch-message) nil t) | ||
| 1934 | ;; Use the isearch-other-end as new starting point to be able | 1938 | ;; Use the isearch-other-end as new starting point to be able |
| 1935 | ;; to find the remaining part of the search string again. | 1939 | ;; to find the remaining part of the search string again. |
| 1936 | ;; This is like what `isearch-search-and-update' does, | 1940 | ;; This is like what `isearch-search-and-update' does, |
| @@ -2107,6 +2111,8 @@ With argument, add COUNT copies of the character." | |||
| 2107 | (setq isearch-case-fold-search | 2111 | (setq isearch-case-fold-search |
| 2108 | (isearch-no-upper-case-p isearch-string isearch-regexp)))) | 2112 | (isearch-no-upper-case-p isearch-string isearch-regexp)))) |
| 2109 | ;; Not regexp, not reverse, or no match at point. | 2113 | ;; Not regexp, not reverse, or no match at point. |
| 2114 | ;; Do the following before moving point. | ||
| 2115 | (funcall (or isearch-message-function #'isearch-message) nil t) | ||
| 2110 | (if (and isearch-other-end (not isearch-adjusted)) | 2116 | (if (and isearch-other-end (not isearch-adjusted)) |
| 2111 | (goto-char (if isearch-forward isearch-other-end | 2117 | (goto-char (if isearch-forward isearch-other-end |
| 2112 | (min isearch-opoint | 2118 | (min isearch-opoint |
| @@ -2273,10 +2279,12 @@ Return nil if it's completely visible, or if point is visible, | |||
| 2273 | together with as much of the search string as will fit; the symbol | 2279 | together with as much of the search string as will fit; the symbol |
| 2274 | `above' if we need to scroll the text downwards; the symbol `below', | 2280 | `above' if we need to scroll the text downwards; the symbol `below', |
| 2275 | if upwards." | 2281 | if upwards." |
| 2276 | (let ((w-start (window-start)) | 2282 | (let ((w-start (window-group-start)) |
| 2277 | (w-end (window-end nil t)) | 2283 | (w-end (window-group-end nil t)) |
| 2278 | (w-L1 (save-excursion (move-to-window-line 1) (point))) | 2284 | (w-L1 (save-excursion |
| 2279 | (w-L-1 (save-excursion (move-to-window-line -1) (point))) | 2285 | (save-selected-window (move-to-window-group-line 1) (point)))) |
| 2286 | (w-L-1 (save-excursion | ||
| 2287 | (save-selected-window (move-to-window-group-line -1) (point)))) | ||
| 2280 | start end) ; start and end of search string in buffer | 2288 | start end) ; start and end of search string in buffer |
| 2281 | (if isearch-forward | 2289 | (if isearch-forward |
| 2282 | (setq end isearch-point start (or isearch-other-end isearch-point)) | 2290 | (setq end isearch-point start (or isearch-other-end isearch-point)) |
| @@ -2303,15 +2311,15 @@ the bottom." | |||
| 2303 | (if above | 2311 | (if above |
| 2304 | (progn | 2312 | (progn |
| 2305 | (goto-char start) | 2313 | (goto-char start) |
| 2306 | (recenter 0) | 2314 | (recenter-window-group 0) |
| 2307 | (when (>= isearch-point (window-end nil t)) | 2315 | (when (>= isearch-point (window-group-end nil t)) |
| 2308 | (goto-char isearch-point) | 2316 | (goto-char isearch-point) |
| 2309 | (recenter -1))) | 2317 | (recenter-window-group -1))) |
| 2310 | (goto-char end) | 2318 | (goto-char end) |
| 2311 | (recenter -1) | 2319 | (recenter-window-group -1) |
| 2312 | (when (< isearch-point (window-start)) | 2320 | (when (< isearch-point (window-group-start)) |
| 2313 | (goto-char isearch-point) | 2321 | (goto-char isearch-point) |
| 2314 | (recenter 0)))) | 2322 | (recenter-window-group 0)))) |
| 2315 | (goto-char isearch-point)) | 2323 | (goto-char isearch-point)) |
| 2316 | 2324 | ||
| 2317 | (defvar isearch-pre-scroll-point nil) | 2325 | (defvar isearch-pre-scroll-point nil) |
| @@ -2458,6 +2466,7 @@ Search is updated accordingly." | |||
| 2458 | (isearch-ring-adjust1 advance) | 2466 | (isearch-ring-adjust1 advance) |
| 2459 | (if search-ring-update | 2467 | (if search-ring-update |
| 2460 | (progn | 2468 | (progn |
| 2469 | (funcall (or isearch-message-function #'isearch-message) nil t) | ||
| 2461 | (isearch-search) | 2470 | (isearch-search) |
| 2462 | (isearch-push-state) | 2471 | (isearch-push-state) |
| 2463 | (isearch-update)) | 2472 | (isearch-update)) |
| @@ -2530,6 +2539,13 @@ If there is no completion possible, say so and continue searching." | |||
| 2530 | 2539 | ||
| 2531 | (defun isearch-message (&optional c-q-hack ellipsis) | 2540 | (defun isearch-message (&optional c-q-hack ellipsis) |
| 2532 | ;; Generate and print the message string. | 2541 | ;; Generate and print the message string. |
| 2542 | |||
| 2543 | ;; N.B.: This function should always be called with point at the | ||
| 2544 | ;; search point, because in certain (rare) circumstances, undesired | ||
| 2545 | ;; scrolling can happen when point is elsewhere. These | ||
| 2546 | ;; circumstances are when follow-mode is active, the search string | ||
| 2547 | ;; spans two (or several) windows, and the message about to be | ||
| 2548 | ;; displayed will cause the echo area to expand. | ||
| 2533 | (let ((cursor-in-echo-area ellipsis) | 2549 | (let ((cursor-in-echo-area ellipsis) |
| 2534 | (m isearch-message) | 2550 | (m isearch-message) |
| 2535 | (fail-pos (isearch-fail-pos t))) | 2551 | (fail-pos (isearch-fail-pos t))) |
| @@ -2723,9 +2739,6 @@ update the match data, and return point." | |||
| 2723 | 2739 | ||
| 2724 | (defun isearch-search () | 2740 | (defun isearch-search () |
| 2725 | ;; Do the search with the current search string. | 2741 | ;; Do the search with the current search string. |
| 2726 | (if isearch-message-function | ||
| 2727 | (funcall isearch-message-function nil t) | ||
| 2728 | (isearch-message nil t)) | ||
| 2729 | (if (and (eq isearch-case-fold-search t) search-upper-case) | 2742 | (if (and (eq isearch-case-fold-search t) search-upper-case) |
| 2730 | (setq isearch-case-fold-search | 2743 | (setq isearch-case-fold-search |
| 2731 | (isearch-no-upper-case-p isearch-string isearch-regexp))) | 2744 | (isearch-no-upper-case-p isearch-string isearch-regexp))) |
| @@ -3023,6 +3036,7 @@ since they have special meaning in a regexp." | |||
| 3023 | (defvar isearch-lazy-highlight-timer nil) | 3036 | (defvar isearch-lazy-highlight-timer nil) |
| 3024 | (defvar isearch-lazy-highlight-last-string nil) | 3037 | (defvar isearch-lazy-highlight-last-string nil) |
| 3025 | (defvar isearch-lazy-highlight-window nil) | 3038 | (defvar isearch-lazy-highlight-window nil) |
| 3039 | (defvar isearch-lazy-highlight-window-group nil) | ||
| 3026 | (defvar isearch-lazy-highlight-window-start nil) | 3040 | (defvar isearch-lazy-highlight-window-start nil) |
| 3027 | (defvar isearch-lazy-highlight-window-end nil) | 3041 | (defvar isearch-lazy-highlight-window-end nil) |
| 3028 | (defvar isearch-lazy-highlight-case-fold-search nil) | 3042 | (defvar isearch-lazy-highlight-case-fold-search nil) |
| @@ -3064,8 +3078,8 @@ by other Emacs features." | |||
| 3064 | (sit-for 0) ;make sure (window-start) is credible | 3078 | (sit-for 0) ;make sure (window-start) is credible |
| 3065 | (or (not (equal isearch-string | 3079 | (or (not (equal isearch-string |
| 3066 | isearch-lazy-highlight-last-string)) | 3080 | isearch-lazy-highlight-last-string)) |
| 3067 | (not (eq (selected-window) | 3081 | (not (memq (selected-window) |
| 3068 | isearch-lazy-highlight-window)) | 3082 | isearch-lazy-highlight-window-group)) |
| 3069 | (not (eq isearch-lazy-highlight-case-fold-search | 3083 | (not (eq isearch-lazy-highlight-case-fold-search |
| 3070 | isearch-case-fold-search)) | 3084 | isearch-case-fold-search)) |
| 3071 | (not (eq isearch-lazy-highlight-regexp | 3085 | (not (eq isearch-lazy-highlight-regexp |
| @@ -3076,9 +3090,9 @@ by other Emacs features." | |||
| 3076 | isearch-lax-whitespace)) | 3090 | isearch-lax-whitespace)) |
| 3077 | (not (eq isearch-lazy-highlight-regexp-lax-whitespace | 3091 | (not (eq isearch-lazy-highlight-regexp-lax-whitespace |
| 3078 | isearch-regexp-lax-whitespace)) | 3092 | isearch-regexp-lax-whitespace)) |
| 3079 | (not (= (window-start) | 3093 | (not (= (window-group-start) |
| 3080 | isearch-lazy-highlight-window-start)) | 3094 | isearch-lazy-highlight-window-start)) |
| 3081 | (not (= (window-end) ; Window may have been split/joined. | 3095 | (not (= (window-group-end) ; Window may have been split/joined. |
| 3082 | isearch-lazy-highlight-window-end)) | 3096 | isearch-lazy-highlight-window-end)) |
| 3083 | (not (eq isearch-forward | 3097 | (not (eq isearch-forward |
| 3084 | isearch-lazy-highlight-forward)) | 3098 | isearch-lazy-highlight-forward)) |
| @@ -3086,7 +3100,7 @@ by other Emacs features." | |||
| 3086 | (not (equal isearch-error | 3100 | (not (equal isearch-error |
| 3087 | isearch-lazy-highlight-error)))) | 3101 | isearch-lazy-highlight-error)))) |
| 3088 | ;; something important did indeed change | 3102 | ;; something important did indeed change |
| 3089 | (lazy-highlight-cleanup t) ;kill old loop & remove overlays | 3103 | (lazy-highlight-cleanup t) ;kill old loop & remove overlays |
| 3090 | (setq isearch-lazy-highlight-error isearch-error) | 3104 | (setq isearch-lazy-highlight-error isearch-error) |
| 3091 | ;; It used to check for `(not isearch-error)' here, but actually | 3105 | ;; It used to check for `(not isearch-error)' here, but actually |
| 3092 | ;; lazy-highlighting might find matches to highlight even when | 3106 | ;; lazy-highlighting might find matches to highlight even when |
| @@ -3094,8 +3108,9 @@ by other Emacs features." | |||
| 3094 | (setq isearch-lazy-highlight-start-limit beg | 3108 | (setq isearch-lazy-highlight-start-limit beg |
| 3095 | isearch-lazy-highlight-end-limit end) | 3109 | isearch-lazy-highlight-end-limit end) |
| 3096 | (setq isearch-lazy-highlight-window (selected-window) | 3110 | (setq isearch-lazy-highlight-window (selected-window) |
| 3097 | isearch-lazy-highlight-window-start (window-start) | 3111 | isearch-lazy-highlight-window-group (selected-window-group) |
| 3098 | isearch-lazy-highlight-window-end (window-end) | 3112 | isearch-lazy-highlight-window-start (window-group-start) |
| 3113 | isearch-lazy-highlight-window-end (window-group-end) | ||
| 3099 | ;; Start lazy-highlighting at the beginning of the found | 3114 | ;; Start lazy-highlighting at the beginning of the found |
| 3100 | ;; match (`isearch-other-end'). If no match, use point. | 3115 | ;; match (`isearch-other-end'). If no match, use point. |
| 3101 | ;; One of the next two variables (depending on search direction) | 3116 | ;; One of the next two variables (depending on search direction) |
| @@ -3113,10 +3128,10 @@ by other Emacs features." | |||
| 3113 | isearch-lazy-highlight-regexp-lax-whitespace isearch-regexp-lax-whitespace | 3128 | isearch-lazy-highlight-regexp-lax-whitespace isearch-regexp-lax-whitespace |
| 3114 | isearch-lazy-highlight-regexp-function isearch-regexp-function | 3129 | isearch-lazy-highlight-regexp-function isearch-regexp-function |
| 3115 | isearch-lazy-highlight-forward isearch-forward) | 3130 | isearch-lazy-highlight-forward isearch-forward) |
| 3116 | (unless (equal isearch-string "") | 3131 | (unless (equal isearch-string "") |
| 3117 | (setq isearch-lazy-highlight-timer | 3132 | (setq isearch-lazy-highlight-timer |
| 3118 | (run-with-idle-timer lazy-highlight-initial-delay nil | 3133 | (run-with-idle-timer lazy-highlight-initial-delay nil |
| 3119 | 'isearch-lazy-highlight-update))))) | 3134 | 'isearch-lazy-highlight-update))))) |
| 3120 | 3135 | ||
| 3121 | (defun isearch-lazy-highlight-search () | 3136 | (defun isearch-lazy-highlight-search () |
| 3122 | "Search ahead for the next or previous match, for lazy highlighting. | 3137 | "Search ahead for the next or previous match, for lazy highlighting. |
| @@ -3139,13 +3154,13 @@ Attempt to do the search exactly the way the pending Isearch would." | |||
| 3139 | (+ isearch-lazy-highlight-start | 3154 | (+ isearch-lazy-highlight-start |
| 3140 | ;; Extend bound to match whole string at point | 3155 | ;; Extend bound to match whole string at point |
| 3141 | (1- (length isearch-lazy-highlight-last-string))) | 3156 | (1- (length isearch-lazy-highlight-last-string))) |
| 3142 | (window-end))) | 3157 | (window-group-end))) |
| 3143 | (max (or isearch-lazy-highlight-start-limit (point-min)) | 3158 | (max (or isearch-lazy-highlight-start-limit (point-min)) |
| 3144 | (if isearch-lazy-highlight-wrapped | 3159 | (if isearch-lazy-highlight-wrapped |
| 3145 | (- isearch-lazy-highlight-end | 3160 | (- isearch-lazy-highlight-end |
| 3146 | ;; Extend bound to match whole string at point | 3161 | ;; Extend bound to match whole string at point |
| 3147 | (1- (length isearch-lazy-highlight-last-string))) | 3162 | (1- (length isearch-lazy-highlight-last-string))) |
| 3148 | (window-start)))))) | 3163 | (window-group-start)))))) |
| 3149 | ;; Use a loop like in `isearch-search'. | 3164 | ;; Use a loop like in `isearch-search'. |
| 3150 | (while retry | 3165 | (while retry |
| 3151 | (setq success (isearch-search-string | 3166 | (setq success (isearch-search-string |
| @@ -3169,7 +3184,7 @@ Attempt to do the search exactly the way the pending Isearch would." | |||
| 3169 | (with-local-quit | 3184 | (with-local-quit |
| 3170 | (save-selected-window | 3185 | (save-selected-window |
| 3171 | (if (and (window-live-p isearch-lazy-highlight-window) | 3186 | (if (and (window-live-p isearch-lazy-highlight-window) |
| 3172 | (not (eq (selected-window) isearch-lazy-highlight-window))) | 3187 | (not (memq (selected-window) isearch-lazy-highlight-window-group))) |
| 3173 | (select-window isearch-lazy-highlight-window)) | 3188 | (select-window isearch-lazy-highlight-window)) |
| 3174 | (save-excursion | 3189 | (save-excursion |
| 3175 | (save-match-data | 3190 | (save-match-data |
| @@ -3189,12 +3204,12 @@ Attempt to do the search exactly the way the pending Isearch would." | |||
| 3189 | (if isearch-lazy-highlight-forward | 3204 | (if isearch-lazy-highlight-forward |
| 3190 | (if (= mb (if isearch-lazy-highlight-wrapped | 3205 | (if (= mb (if isearch-lazy-highlight-wrapped |
| 3191 | isearch-lazy-highlight-start | 3206 | isearch-lazy-highlight-start |
| 3192 | (window-end))) | 3207 | (window-group-end))) |
| 3193 | (setq found nil) | 3208 | (setq found nil) |
| 3194 | (forward-char 1)) | 3209 | (forward-char 1)) |
| 3195 | (if (= mb (if isearch-lazy-highlight-wrapped | 3210 | (if (= mb (if isearch-lazy-highlight-wrapped |
| 3196 | isearch-lazy-highlight-end | 3211 | isearch-lazy-highlight-end |
| 3197 | (window-start))) | 3212 | (window-group-start))) |
| 3198 | (setq found nil) | 3213 | (setq found nil) |
| 3199 | (forward-char -1))) | 3214 | (forward-char -1))) |
| 3200 | 3215 | ||
| @@ -3204,8 +3219,8 @@ Attempt to do the search exactly the way the pending Isearch would." | |||
| 3204 | ;; 1000 is higher than ediff's 100+, | 3219 | ;; 1000 is higher than ediff's 100+, |
| 3205 | ;; but lower than isearch main overlay's 1001 | 3220 | ;; but lower than isearch main overlay's 1001 |
| 3206 | (overlay-put ov 'priority 1000) | 3221 | (overlay-put ov 'priority 1000) |
| 3207 | (overlay-put ov 'face lazy-highlight-face) | 3222 | (overlay-put ov 'face lazy-highlight-face))) |
| 3208 | (overlay-put ov 'window (selected-window)))) | 3223 | ;(overlay-put ov 'window (selected-window)))) |
| 3209 | ;; Remember the current position of point for | 3224 | ;; Remember the current position of point for |
| 3210 | ;; the next call of `isearch-lazy-highlight-update' | 3225 | ;; the next call of `isearch-lazy-highlight-update' |
| 3211 | ;; when `lazy-highlight-max-at-a-time' is too small. | 3226 | ;; when `lazy-highlight-max-at-a-time' is too small. |
| @@ -3221,12 +3236,12 @@ Attempt to do the search exactly the way the pending Isearch would." | |||
| 3221 | (setq isearch-lazy-highlight-wrapped t) | 3236 | (setq isearch-lazy-highlight-wrapped t) |
| 3222 | (if isearch-lazy-highlight-forward | 3237 | (if isearch-lazy-highlight-forward |
| 3223 | (progn | 3238 | (progn |
| 3224 | (setq isearch-lazy-highlight-end (window-start)) | 3239 | (setq isearch-lazy-highlight-end (window-group-start)) |
| 3225 | (goto-char (max (or isearch-lazy-highlight-start-limit (point-min)) | 3240 | (goto-char (max (or isearch-lazy-highlight-start-limit (point-min)) |
| 3226 | (window-start)))) | 3241 | (window-group-start)))) |
| 3227 | (setq isearch-lazy-highlight-start (window-end)) | 3242 | (setq isearch-lazy-highlight-start (window-group-end)) |
| 3228 | (goto-char (min (or isearch-lazy-highlight-end-limit (point-max)) | 3243 | (goto-char (min (or isearch-lazy-highlight-end-limit (point-max)) |
| 3229 | (window-end)))))))) | 3244 | (window-group-end)))))))) |
| 3230 | (unless nomore | 3245 | (unless nomore |
| 3231 | (setq isearch-lazy-highlight-timer | 3246 | (setq isearch-lazy-highlight-timer |
| 3232 | (run-at-time lazy-highlight-interval nil | 3247 | (run-at-time lazy-highlight-interval nil |
diff --git a/lisp/replace.el b/lisp/replace.el index 54b3a71bda2..d48f4f3fdf9 100644 --- a/lisp/replace.el +++ b/lisp/replace.el | |||
| @@ -2011,6 +2011,9 @@ passed in. If LITERAL is set, no checking is done, anyway." | |||
| 2011 | (when backward (goto-char (nth 0 match-data))) | 2011 | (when backward (goto-char (nth 0 match-data))) |
| 2012 | noedit) | 2012 | noedit) |
| 2013 | 2013 | ||
| 2014 | (defvar replace-update-post-hook nil | ||
| 2015 | "Function(s) to call after query-replace has found a match in the buffer.") | ||
| 2016 | |||
| 2014 | (defvar replace-search-function nil | 2017 | (defvar replace-search-function nil |
| 2015 | "Function to use when searching for strings to replace. | 2018 | "Function to use when searching for strings to replace. |
| 2016 | It is used by `query-replace' and `replace-string', and is called | 2019 | It is used by `query-replace' and `replace-string', and is called |
| @@ -2264,7 +2267,7 @@ It must return a string." | |||
| 2264 | (and nonempty-match | 2267 | (and nonempty-match |
| 2265 | (or (not regexp-flag) | 2268 | (or (not regexp-flag) |
| 2266 | (and (if backward | 2269 | (and (if backward |
| 2267 | (looking-back search-string) | 2270 | (looking-back search-string nil) |
| 2268 | (looking-at search-string)) | 2271 | (looking-at search-string)) |
| 2269 | (let ((match (match-data))) | 2272 | (let ((match (match-data))) |
| 2270 | (and (/= (nth 0 match) (nth 1 match)) | 2273 | (and (/= (nth 0 match) (nth 1 match)) |
| @@ -2318,7 +2321,8 @@ It must return a string." | |||
| 2318 | ;; `real-match-data'. | 2321 | ;; `real-match-data'. |
| 2319 | (while (not done) | 2322 | (while (not done) |
| 2320 | (set-match-data real-match-data) | 2323 | (set-match-data real-match-data) |
| 2321 | (replace-highlight | 2324 | (run-hooks 'replace-update-post-hook) ; Before `replace-highlight'. |
| 2325 | (replace-highlight | ||
| 2322 | (match-beginning 0) (match-end 0) | 2326 | (match-beginning 0) (match-end 0) |
| 2323 | start end search-string | 2327 | start end search-string |
| 2324 | regexp-flag delimited-flag case-fold-search backward) | 2328 | regexp-flag delimited-flag case-fold-search backward) |
diff --git a/lisp/textmodes/ispell.el b/lisp/textmodes/ispell.el index aa51446d6b4..05a5da57b66 100644 --- a/lisp/textmodes/ispell.el +++ b/lisp/textmodes/ispell.el | |||
| @@ -1782,6 +1782,51 @@ Extended character mode can be changed for this buffer by placing | |||
| 1782 | a `~' followed by an extended-character mode -- such as `~.tex'. | 1782 | a `~' followed by an extended-character mode -- such as `~.tex'. |
| 1783 | The last occurring definition in the buffer will be used.") | 1783 | The last occurring definition in the buffer will be used.") |
| 1784 | 1784 | ||
| 1785 | (defun ispell--\\w-filter (char) | ||
| 1786 | "Return CHAR in a string when CHAR doesn't have \"word\" syntax, | ||
| 1787 | nil otherwise. CHAR must be a character." | ||
| 1788 | (let ((str (string char))) | ||
| 1789 | (and | ||
| 1790 | (not (string-match "\\w" str)) | ||
| 1791 | str))) | ||
| 1792 | |||
| 1793 | (defun ispell--make-\\w-expression (chars) | ||
| 1794 | "Make a regular expression like \"\\(\\w\\|[-_]\\)\". | ||
| 1795 | This (parenthesized) expression matches either a character of | ||
| 1796 | \"word\" syntax or one in CHARS. | ||
| 1797 | |||
| 1798 | CHARS is a string of characters. A member of CHARS is omitted | ||
| 1799 | from the expression if it already has word syntax. (Be careful | ||
| 1800 | about special characters such as ?\\, ?^, ?], and ?- in CHARS.) | ||
| 1801 | If after this filtering there are no chars left, or only one, a | ||
| 1802 | special form of the expression is generated." | ||
| 1803 | (let ((filtered | ||
| 1804 | (mapconcat #'ispell--\\w-filter chars ""))) | ||
| 1805 | (concat | ||
| 1806 | "\\(\\w" | ||
| 1807 | (cond | ||
| 1808 | ((equal filtered "") | ||
| 1809 | "\\)") | ||
| 1810 | ((eq (length filtered) 1) | ||
| 1811 | (concat "\\|" filtered "\\)")) | ||
| 1812 | (t | ||
| 1813 | (concat "\\|[" filtered "]\\)")))))) | ||
| 1814 | |||
| 1815 | (defun ispell--make-filename-or-URL-re () | ||
| 1816 | "Construct a regexp to match some file names or URLs or email addresses. | ||
| 1817 | The expression is crafted to match as great a variety of these | ||
| 1818 | objects as practicable, without too many false matches happening." | ||
| 1819 | (concat ;"\\(--+\\|_+\\|" | ||
| 1820 | "\\(/\\w\\|\\(" | ||
| 1821 | (ispell--make-\\w-expression "-_") | ||
| 1822 | "+[.:@]\\)\\)" | ||
| 1823 | (ispell--make-\\w-expression "-_") | ||
| 1824 | "*\\([.:/@]+" | ||
| 1825 | (ispell--make-\\w-expression "-_~=?&") | ||
| 1826 | "+\\)+" | ||
| 1827 | ;"\\)" | ||
| 1828 | )) | ||
| 1829 | |||
| 1785 | ;;;###autoload | 1830 | ;;;###autoload |
| 1786 | (defvar ispell-skip-region-alist | 1831 | (defvar ispell-skip-region-alist |
| 1787 | `((ispell-words-keyword forward-line) | 1832 | `((ispell-words-keyword forward-line) |
| @@ -1798,7 +1843,7 @@ The last occurring definition in the buffer will be used.") | |||
| 1798 | ;; Matches e-mail addresses, file names, http addresses, etc. The | 1843 | ;; Matches e-mail addresses, file names, http addresses, etc. The |
| 1799 | ;; `-+' `_+' patterns are necessary for performance reasons when | 1844 | ;; `-+' `_+' patterns are necessary for performance reasons when |
| 1800 | ;; `-' or `_' part of word syntax. | 1845 | ;; `-' or `_' part of word syntax. |
| 1801 | (,(purecopy "\\(--+\\|_+\\|\\(/\\w\\|\\(\\(\\w\\|[-_]\\)+[.:@]\\)\\)\\(\\w\\|[-_]\\)*\\([.:/@]+\\(\\w\\|[-_~=?&]\\)+\\)+\\)")) | 1846 | ; (,(purecopy "\\(--+\\|_+\\|\\(/\\w\\|\\(\\(\\w\\|[-_]\\)+[.:@]\\)\\)\\(\\w\\|[-_]\\)*\\([.:/@]+\\(\\w\\|[-_~=?&]\\)+\\)+\\)")) |
| 1802 | ;; above checks /.\w sequences | 1847 | ;; above checks /.\w sequences |
| 1803 | ;;("\\(--+\\|\\(/\\|\\(\\(\\w\\|[-_]\\)+[.:@]\\)\\)\\(\\w\\|[-_]\\)*\\([.:/@]+\\(\\w\\|[-_~=?&]\\)+\\)+\\)") | 1848 | ;;("\\(--+\\|\\(/\\|\\(\\(\\w\\|[-_]\\)+[.:@]\\)\\)\\(\\w\\|[-_]\\)*\\([.:/@]+\\(\\w\\|[-_~=?&]\\)+\\)+\\)") |
| 1804 | ;; This is a pretty complex regexp. It can be simplified to the following: | 1849 | ;; This is a pretty complex regexp. It can be simplified to the following: |
| @@ -2248,6 +2293,11 @@ If so, ask if it needs to be saved." | |||
| 2248 | (setq ispell-pdict-modified-p nil)) | 2293 | (setq ispell-pdict-modified-p nil)) |
| 2249 | 2294 | ||
| 2250 | 2295 | ||
| 2296 | (defvar ispell-update-post-hook nil | ||
| 2297 | "A normal hook invoked from the ispell command loop. | ||
| 2298 | It is called once per iteration, before displaying a prompt to | ||
| 2299 | the user.") | ||
| 2300 | |||
| 2251 | (defun ispell-command-loop (miss guess word start end) | 2301 | (defun ispell-command-loop (miss guess word start end) |
| 2252 | "Display possible corrections from list MISS. | 2302 | "Display possible corrections from list MISS. |
| 2253 | GUESS lists possibly valid affix construction of WORD. | 2303 | GUESS lists possibly valid affix construction of WORD. |
| @@ -2315,8 +2365,10 @@ Global `ispell-quit' set to start location to continue spell session." | |||
| 2315 | count (ispell-int-char (1+ count)))) | 2365 | count (ispell-int-char (1+ count)))) |
| 2316 | (setq count (ispell-int-char (- count ?0 skipped)))) | 2366 | (setq count (ispell-int-char (- count ?0 skipped)))) |
| 2317 | 2367 | ||
| 2368 | (run-hooks 'ispell-update-post-hook) | ||
| 2369 | |||
| 2318 | ;; ensure word is visible | 2370 | ;; ensure word is visible |
| 2319 | (if (not (pos-visible-in-window-p end)) | 2371 | (if (not (pos-visible-in-window-group-p end)) |
| 2320 | (sit-for 0)) | 2372 | (sit-for 0)) |
| 2321 | 2373 | ||
| 2322 | ;; Display choices for misspelled word. | 2374 | ;; Display choices for misspelled word. |
| @@ -2845,13 +2897,20 @@ Also position fit window to BUFFER and select it." | |||
| 2845 | (prog1 | 2897 | (prog1 |
| 2846 | (condition-case nil | 2898 | (condition-case nil |
| 2847 | (split-window | 2899 | (split-window |
| 2848 | nil (- ispell-choices-win-default-height) 'above) | 2900 | ;; Chose the last of a window group, since |
| 2901 | ;; otherwise, the lowering of another window's | ||
| 2902 | ;; TL corner would cause the logical order of | ||
| 2903 | ;; the windows to be changed. | ||
| 2904 | (car (last (selected-window-group))) | ||
| 2905 | (- ispell-choices-win-default-height) 'above) | ||
| 2849 | (error nil)) | 2906 | (error nil)) |
| 2850 | (modify-frame-parameters frame '((unsplittable . t)))))) | 2907 | (modify-frame-parameters frame '((unsplittable . t)))))) |
| 2851 | (and (not unsplittable) | 2908 | (and (not unsplittable) |
| 2852 | (condition-case nil | 2909 | (condition-case nil |
| 2853 | (split-window | 2910 | (split-window |
| 2854 | nil (- ispell-choices-win-default-height) 'above) | 2911 | ;; See comment above. |
| 2912 | (car (last (selected-window-group))) | ||
| 2913 | (- ispell-choices-win-default-height) 'above) | ||
| 2855 | (error nil))) | 2914 | (error nil))) |
| 2856 | (display-buffer buffer)))) | 2915 | (display-buffer buffer)))) |
| 2857 | (if (not window) | 2916 | (if (not window) |
| @@ -3374,7 +3433,8 @@ Must be called after `ispell-buffer-local-parsing' due to dependence on mode." | |||
| 3374 | (if (string= "" comment-end) "^" (regexp-quote comment-end))) | 3433 | (if (string= "" comment-end) "^" (regexp-quote comment-end))) |
| 3375 | (if (and (null ispell-check-comments) comment-start) | 3434 | (if (and (null ispell-check-comments) comment-start) |
| 3376 | (regexp-quote comment-start)) | 3435 | (regexp-quote comment-start)) |
| 3377 | (ispell-begin-skip-region ispell-skip-region-alist))) | 3436 | (ispell-begin-skip-region ispell-skip-region-alist) |
| 3437 | (ispell--make-filename-or-URL-re))) | ||
| 3378 | "\\|")) | 3438 | "\\|")) |
| 3379 | 3439 | ||
| 3380 | 3440 | ||
| @@ -3413,6 +3473,8 @@ Manual checking must include comments and tib references. | |||
| 3413 | The list is of the form described by variable `ispell-skip-region-alist'. | 3473 | The list is of the form described by variable `ispell-skip-region-alist'. |
| 3414 | Must be called after `ispell-buffer-local-parsing' due to dependence on mode." | 3474 | Must be called after `ispell-buffer-local-parsing' due to dependence on mode." |
| 3415 | (let ((skip-alist ispell-skip-region-alist)) | 3475 | (let ((skip-alist ispell-skip-region-alist)) |
| 3476 | (setq skip-alist (append (list (list (ispell--make-filename-or-URL-re))) | ||
| 3477 | skip-alist)) | ||
| 3416 | ;; only additional explicit region definition is tex. | 3478 | ;; only additional explicit region definition is tex. |
| 3417 | (if (eq ispell-parser 'tex) | 3479 | (if (eq ispell-parser 'tex) |
| 3418 | (setq case-fold-search nil | 3480 | (setq case-fold-search nil |
| @@ -4106,9 +4168,10 @@ You can bind this to the key C-c i in GNUS or mail by adding to | |||
| 4106 | (ispell-non-empty-string vm-included-text-prefix))) | 4168 | (ispell-non-empty-string vm-included-text-prefix))) |
| 4107 | (t default-prefix))) | 4169 | (t default-prefix))) |
| 4108 | (ispell-skip-region-alist | 4170 | (ispell-skip-region-alist |
| 4109 | (cons (list (concat "^\\(" cite-regexp "\\)") | 4171 | (cons (list (ispell--make-filename-or-URL-re)) |
| 4110 | (function forward-line)) | 4172 | (cons (list (concat "^\\(" cite-regexp "\\)") |
| 4111 | ispell-skip-region-alist)) | 4173 | (function forward-line)) |
| 4174 | ispell-skip-region-alist))) | ||
| 4112 | (old-case-fold-search case-fold-search) | 4175 | (old-case-fold-search case-fold-search) |
| 4113 | (dictionary-alist ispell-message-dictionary-alist) | 4176 | (dictionary-alist ispell-message-dictionary-alist) |
| 4114 | (ispell-checking-message t)) | 4177 | (ispell-checking-message t)) |
diff --git a/lisp/window.el b/lisp/window.el index 54ac8115727..c57fef441f5 100644 --- a/lisp/window.el +++ b/lisp/window.el | |||
| @@ -7870,6 +7870,152 @@ Return non-nil if the window was shrunk, nil otherwise." | |||
| 7870 | (remove-hook 'kill-buffer-hook delete-window-hook t)))))) | 7870 | (remove-hook 'kill-buffer-hook delete-window-hook t)))))) |
| 7871 | 7871 | ||
| 7872 | 7872 | ||
| 7873 | ;;; | ||
| 7874 | ;; Groups of windows (Follow Mode). | ||
| 7875 | ;; | ||
| 7876 | ;; This section of functions extends the functionality of some window | ||
| 7877 | ;; manipulating commands to groups of windows co-operatively | ||
| 7878 | ;; displaying a buffer, typically with Follow Mode. | ||
| 7879 | ;; | ||
| 7880 | ;; The xxx-function variables are permanent locals so that their local | ||
| 7881 | ;; status is undone only when explicitly programmed, not when a buffer | ||
| 7882 | ;; is reverted or a mode function is called. | ||
| 7883 | |||
| 7884 | (defvar window-group-start-function nil) | ||
| 7885 | (make-variable-buffer-local 'window-group-start-function) | ||
| 7886 | (put 'window-group-start-function 'permanent-local t) | ||
| 7887 | (defun window-group-start (&optional window) | ||
| 7888 | "Return position at which display currently starts in the group of | ||
| 7889 | windows containing WINDOW. When a grouping mode (such as Follow Mode) | ||
| 7890 | is not active, this function is identical to `window-start'. | ||
| 7891 | |||
| 7892 | WINDOW must be a live window and defaults to the selected one. | ||
| 7893 | This is updated by redisplay or by calling `set-window*-start'." | ||
| 7894 | (if (functionp window-group-start-function) | ||
| 7895 | (funcall window-group-start-function window) | ||
| 7896 | (window-start window))) | ||
| 7897 | |||
| 7898 | (defvar window-group-end-function nil) | ||
| 7899 | (make-variable-buffer-local 'window-group-end-function) | ||
| 7900 | (put 'window-group-end-function 'permanent-local t) | ||
| 7901 | (defun window-group-end (&optional window update) | ||
| 7902 | "Return position at which display currently ends in the group of | ||
| 7903 | windows containing WINDOW. When a grouping mode (such as Follow Mode) | ||
| 7904 | is not active, this function is identical to `window-end'. | ||
| 7905 | |||
| 7906 | WINDOW must be a live window and defaults to the selected one. | ||
| 7907 | This is updated by redisplay, when it runs to completion. | ||
| 7908 | Simply changing the buffer text or setting `window-group-start' | ||
| 7909 | does not update this value. | ||
| 7910 | Return nil if there is no recorded value. (This can happen if the | ||
| 7911 | last redisplay of WINDOW was preempted, and did not finish.) | ||
| 7912 | If UPDATE is non-nil, compute the up-to-date position | ||
| 7913 | if it isn't already recorded." | ||
| 7914 | (if (functionp window-group-end-function) | ||
| 7915 | (funcall window-group-end-function window update) | ||
| 7916 | (window-end window update))) | ||
| 7917 | |||
| 7918 | (defvar set-window-group-start-function nil) | ||
| 7919 | (make-variable-buffer-local 'set-window-group-start-function) | ||
| 7920 | (put 'set-window-group-start-function 'permanent-local t) | ||
| 7921 | (defun set-window-group-start (window pos &optional noforce) | ||
| 7922 | "Make display in the group of windows containing WINDOW start at | ||
| 7923 | position POS in WINDOW's buffer. When a grouping mode (such as Follow | ||
| 7924 | Mode) is not active, this function is identical to `set-window-start'. | ||
| 7925 | |||
| 7926 | WINDOW must be a live window and defaults to the selected one. Return | ||
| 7927 | POS. Optional third arg NOFORCE non-nil inhibits next redisplay from | ||
| 7928 | overriding motion of point in order to display at this exact start." | ||
| 7929 | (if (functionp set-window-group-start-function) | ||
| 7930 | (funcall set-window-group-start-function window pos noforce) | ||
| 7931 | (set-window-start window pos noforce))) | ||
| 7932 | |||
| 7933 | (defvar recenter-window-group-function nil) | ||
| 7934 | (make-variable-buffer-local 'recenter-window-group-function) | ||
| 7935 | (put 'recenter-window-group-function 'permanent-local t) | ||
| 7936 | (defun recenter-window-group (&optional arg) | ||
| 7937 | "Center point in the group of windows containing the selected window | ||
| 7938 | and maybe redisplay frame. When a grouping mode (such as Follow Mode) | ||
| 7939 | is not active, this function is identical to `recenter'. | ||
| 7940 | |||
| 7941 | With a numeric prefix argument ARG, recenter putting point on screen line ARG | ||
| 7942 | relative to the first window in the selected window group. If ARG is | ||
| 7943 | negative, it counts up from the bottom of the last window in the | ||
| 7944 | group. (ARG should be less than the total height of the window group.) | ||
| 7945 | |||
| 7946 | If ARG is omitted or nil, then recenter with point on the middle line of | ||
| 7947 | the selected window group; if the variable `recenter-redisplay' is | ||
| 7948 | non-nil, also erase the entire frame and redraw it (when | ||
| 7949 | `auto-resize-tool-bars' is set to `grow-only', this resets the | ||
| 7950 | tool-bar's height to the minimum height needed); if | ||
| 7951 | `recenter-redisplay' has the special value `tty', then only tty frames | ||
| 7952 | are redrawn. | ||
| 7953 | |||
| 7954 | Just C-u as prefix means put point in the center of the window | ||
| 7955 | and redisplay normally--don't erase and redraw the frame." | ||
| 7956 | (if (functionp recenter-window-group-function) | ||
| 7957 | (funcall recenter-window-group-function arg) | ||
| 7958 | (recenter arg))) | ||
| 7959 | |||
| 7960 | (defvar pos-visible-in-window-group-p-function nil) | ||
| 7961 | (make-variable-buffer-local 'pos-visible-in-window-group-p-function) | ||
| 7962 | (put 'pos-visible-in-window-group-p-function 'permanent-local t) | ||
| 7963 | (defun pos-visible-in-window-group-p (&optional pos window partially) | ||
| 7964 | "Return non-nil if position POS is currently on the frame in the | ||
| 7965 | window group containing WINDOW. When a grouping mode (such as Follow | ||
| 7966 | Mode) is not active, this function is identical to | ||
| 7967 | `pos-visible-in-window-p'. | ||
| 7968 | |||
| 7969 | WINDOW must be a live window and defaults to the selected one. | ||
| 7970 | |||
| 7971 | Return nil if that position is scrolled vertically out of view. If a | ||
| 7972 | character is only partially visible, nil is returned, unless the | ||
| 7973 | optional argument PARTIALLY is non-nil. If POS is only out of view | ||
| 7974 | because of horizontal scrolling, return non-nil. If POS is t, it | ||
| 7975 | specifies the position of the last visible glyph in the window group. | ||
| 7976 | POS defaults to point in WINDOW; WINDOW defaults to the selected | ||
| 7977 | window. | ||
| 7978 | |||
| 7979 | If POS is visible, return t if PARTIALLY is nil; if PARTIALLY is non-nil, | ||
| 7980 | the return value is a list of 2 or 6 elements (X Y [RTOP RBOT ROWH VPOS]), | ||
| 7981 | where X and Y are the pixel coordinates relative to the top left corner | ||
| 7982 | of the window. The remaining elements are omitted if the character after | ||
| 7983 | POS is fully visible; otherwise, RTOP and RBOT are the number of pixels | ||
| 7984 | off-window at the top and bottom of the screen line (\"row\") containing | ||
| 7985 | POS, ROWH is the visible height of that row, and VPOS is the row number | ||
| 7986 | \(zero-based)." | ||
| 7987 | (if (functionp pos-visible-in-window-group-p-function) | ||
| 7988 | (funcall pos-visible-in-window-group-p-function pos window partially) | ||
| 7989 | (pos-visible-in-window-p pos window partially))) | ||
| 7990 | |||
| 7991 | (defvar selected-window-group-function nil) | ||
| 7992 | (make-variable-buffer-local 'selected-window-group-function) | ||
| 7993 | (put 'selected-window-group-function 'permanent-local t) | ||
| 7994 | (defun selected-window-group () | ||
| 7995 | "Return the list of windows in the group containing the selected window. | ||
| 7996 | When a grouping mode (such as Follow Mode) is not active, the | ||
| 7997 | result is a list containing only the selected window." | ||
| 7998 | (if (functionp selected-window-group-function) | ||
| 7999 | (funcall selected-window-group-function) | ||
| 8000 | (list (selected-window)))) | ||
| 8001 | |||
| 8002 | (defvar move-to-window-group-line-function nil) | ||
| 8003 | (make-variable-buffer-local 'move-to-window-group-line-function) | ||
| 8004 | (put 'move-to-window-group-line-function 'permanent-local t) | ||
| 8005 | (defun move-to-window-group-line (arg) | ||
| 8006 | "Position point relative to the the current group of windows. | ||
| 8007 | When a grouping mode (such as Follow Mode) is not active, this | ||
| 8008 | function is identical to `move-to-window-line'. | ||
| 8009 | |||
| 8010 | ARG nil means position point at center of the window group. | ||
| 8011 | Else, ARG specifies the vertical position within the window | ||
| 8012 | group; zero means top of first window in the group, negative | ||
| 8013 | means relative to the bottom of the last window in the group." | ||
| 8014 | (if (functionp move-to-window-group-line-function) | ||
| 8015 | (funcall move-to-window-group-line-function arg) | ||
| 8016 | (move-to-window-line arg))) | ||
| 8017 | |||
| 8018 | |||
| 7873 | (defvar recenter-last-op nil | 8019 | (defvar recenter-last-op nil |
| 7874 | "Indicates the last recenter operation performed. | 8020 | "Indicates the last recenter operation performed. |
| 7875 | Possible values: `top', `middle', `bottom', integer or float numbers. | 8021 | Possible values: `top', `middle', `bottom', integer or float numbers. |