mirror of
https://git.savannah.gnu.org/git/emacs.git
synced 2025-01-05 11:45:45 +00:00
Merge branch 'scratch/follow' into emacs-25
This allows Isearch, etc., to work well when Follow Mode is active.
This commit is contained in:
commit
df32db2f5f
@ -861,15 +861,18 @@ into a list. @code{mapc} always returns @var{sequence}.
|
||||
|
||||
@defun mapconcat function sequence separator
|
||||
@code{mapconcat} applies @var{function} to each element of
|
||||
@var{sequence}: the results, which must be strings, are concatenated.
|
||||
Between each pair of result strings, @code{mapconcat} inserts the string
|
||||
@var{separator}. Usually @var{separator} contains a space or comma or
|
||||
other suitable punctuation.
|
||||
@var{sequence}; the results, which must be sequences of characters
|
||||
(strings, vectors, or lists), are concatenated into a single string
|
||||
return value. Between each pair of result sequences, @code{mapconcat}
|
||||
inserts the characters from @var{separator}, which also must be a
|
||||
string, or a vector or list of characters. @xref{Sequences Arrays
|
||||
Vectors}.
|
||||
|
||||
The argument @var{function} must be a function that can take one
|
||||
argument and return a string. The argument @var{sequence} can be any
|
||||
kind of sequence except a char-table; that is, a list, a vector, a
|
||||
bool-vector, or a string.
|
||||
argument and returns a sequence of characters: a string, a vector, or
|
||||
a list. The argument @var{sequence} can be any kind of sequence
|
||||
except a char-table; that is, a list, a vector, a bool-vector, or a
|
||||
string.
|
||||
|
||||
@example
|
||||
@group
|
||||
|
@ -572,6 +572,18 @@ The value returned is the window line number point has moved to, with
|
||||
the top line in the window numbered 0.
|
||||
@end deffn
|
||||
|
||||
@vindex move-to-window-group-line-function
|
||||
@defun move-to-window-group-line count
|
||||
This function is like @code{move-to-window-line}, except that when the
|
||||
selected window is a part of a group of windows (@pxref{Window
|
||||
Group}), @code{move-to-window-group-line} will move to a position with
|
||||
respect to the entire group, not just the single window. This
|
||||
condition holds when the buffer local variable
|
||||
@code{move-to-window-group-line-function} is set to a function. In
|
||||
this case, @code{move-to-window-group-line} calls the function with
|
||||
the argument @var{count}, then returns its result.
|
||||
@end defun
|
||||
|
||||
@defun compute-motion from frompos to topos width offsets window
|
||||
This function scans the current buffer, calculating screen positions.
|
||||
It scans the buffer forward from position @var{from}, assuming that is
|
||||
|
@ -133,6 +133,30 @@ This function returns the selected window (which is always a live
|
||||
window).
|
||||
@end defun
|
||||
|
||||
@anchor{Window Group}Sometimes several windows collectively and
|
||||
cooperatively display a buffer, for example, under the management of
|
||||
Follow Mode (@pxref{Follow Mode,,, emacs}), where the windows together
|
||||
display a bigger portion of the buffer than one window could alone.
|
||||
It is often useful to consider such a @dfn{window group} as a single
|
||||
entity. Several functions such as @code{window-group-start}
|
||||
(@pxref{Window Start and End}) allow you to do this by supplying, as
|
||||
an argument, one of the windows as a stand in for the whole group.
|
||||
|
||||
@defun selected-window-group
|
||||
@vindex selected-window-group-function
|
||||
When the selected window is a member of a group of windows, this
|
||||
function returns a list of the windows in the group, ordered such that
|
||||
the first window in the list is displaying the earliest part of the
|
||||
buffer, and so on. Otherwise the function returns a list containing
|
||||
just the selected window.
|
||||
|
||||
The selected window is considered part of a group when the buffer
|
||||
local variable @code{selected-window-group-function} is set to a
|
||||
function. In this case, @code{selected-window-group} calls it with no
|
||||
arguments and returns its result (which should be the list of windows
|
||||
in the group).
|
||||
@end defun
|
||||
|
||||
@node Windows and Frames
|
||||
@section Windows and Frames
|
||||
|
||||
@ -3098,6 +3122,17 @@ window-start position; if you move point, do not expect the window-start
|
||||
position to change in response until after the next redisplay.
|
||||
@end defun
|
||||
|
||||
@defun window-group-start &optional window
|
||||
@vindex window-group-start-function
|
||||
This function is like @code{window-start}, except that when
|
||||
@var{window} is a part of a group of windows (@pxref{Window Group}),
|
||||
@code{window-group-start} returns the start position of the entire
|
||||
group. This condition holds when the buffer local variable
|
||||
@code{window-group-start-function} is set to a function. In this
|
||||
case, @code{window-group-start} calls the function with the single
|
||||
argument @var{window}, then returns its result.
|
||||
@end defun
|
||||
|
||||
@cindex window end position
|
||||
@defun window-end &optional window update
|
||||
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
|
||||
text will end if scrolling is not required.
|
||||
@end defun
|
||||
|
||||
@vindex window-group-end-function
|
||||
@defun window-group-end window update
|
||||
This function is like @code{window-end}, except that when @var{window}
|
||||
is a part of a group of windows (@pxref{Window Group}),
|
||||
@code{window-group-end} returns the end position of the entire group.
|
||||
This condition holds when the buffer local variable
|
||||
@code{window-group-end-function} is set to a function. In this case,
|
||||
@code{window-group-end} calls the function with the two arguments
|
||||
@var{window} and @var{update}, then returns its result. The argument
|
||||
@var{update} has the same meaning as in @code{window-end}.
|
||||
@end defun
|
||||
|
||||
@defun set-window-start window position &optional noforce
|
||||
This function sets the display-start position of @var{window} to
|
||||
@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
|
||||
position that works well with point, and thus @var{position} is not used.
|
||||
@end defun
|
||||
|
||||
@vindex set-window-group-start-function
|
||||
@defun set-window-group-start window position &optional noforce
|
||||
This function is like @code{set-window-start}, except that when
|
||||
@var{window} is a part of a group of windows (@pxref{Window Group}),
|
||||
@code{set-window-group-start} sets the start position of the entire
|
||||
group. This condition holds when the buffer local variable
|
||||
@code{set-window-group-start-function} is set to a function. In this
|
||||
case, @code{set-window-group-start} calls the function with the three
|
||||
arguments @var{window}, @var{position}, and @var{noforce}, then
|
||||
returns its result. The arguments @var{position} and @var{noforce} in
|
||||
this function have the same meaning as in @code{set-window-start}.
|
||||
@end defun
|
||||
|
||||
@defun pos-visible-in-window-p &optional position window partially
|
||||
This function returns non-@code{nil} if @var{position} is within the
|
||||
range of text currently visible on the screen in @var{window}. It
|
||||
@ -3228,6 +3288,21 @@ Here is an example:
|
||||
@end example
|
||||
@end defun
|
||||
|
||||
@vindex pos-visible-in-window-group-p-function
|
||||
@defun pos-visible-in-window-group-p &optional position window partially
|
||||
This function is like @code{pos-visible-in-window-p}, except that when
|
||||
@var{window} is a part of a group of windows (@pxref{Window Group}),
|
||||
@code{pos-visible-in-window-group-p} tests the visibility of @var{pos}
|
||||
in the entire group, not just in the single @var{window}. This
|
||||
condition holds when the buffer local variable
|
||||
@code{pos-visible-in-window-group-p-function} is set to a function.
|
||||
In this case @code{pos-visible-in-window-group-p} calls the function
|
||||
with the three arguments @var{position}, @var{window}, and
|
||||
@var{partially}, then returns its result. The arguments
|
||||
@var{position} and @var{partially} have the same meaning as in
|
||||
@code{pos-visible-in-window-p}.
|
||||
@end defun
|
||||
|
||||
@defun window-line-height &optional line window
|
||||
This function returns the height of text line @var{line} in
|
||||
@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
|
||||
a more convenient way to achieve this.
|
||||
@end deffn
|
||||
|
||||
@vindex recenter-window-group-function
|
||||
@defun recenter-window-group &optional count
|
||||
This function is like @code{recenter}, except that when the selected
|
||||
window is part of a group of windows (@pxref{Window Group}),
|
||||
@code{recenter-window-group} scrolls the entire group. This condition
|
||||
holds when the buffer local variable
|
||||
@code{recenter-window-group-function} is set to a function. In this
|
||||
case, @code{recenter-window-group} calls the function with the
|
||||
argument @var{count}, then returns its result. The argument
|
||||
@var{count} has the same meaning as in @code{recenter}, but with
|
||||
respect to the entire window group.
|
||||
@end defun
|
||||
|
||||
@defopt recenter-redisplay
|
||||
If this variable is non-@code{nil}, calling @code{recenter} with a
|
||||
@code{nil} argument redraws the frame. The default value is
|
||||
|
176
lisp/follow.el
176
lisp/follow.el
@ -421,7 +421,21 @@ Keys specific to Follow mode:
|
||||
(progn
|
||||
(add-hook 'compilation-filter-hook 'follow-align-compilation-windows t t)
|
||||
(add-hook 'post-command-hook 'follow-post-command-hook t)
|
||||
(add-hook 'window-size-change-functions 'follow-window-size-change t))
|
||||
(add-hook 'window-size-change-functions 'follow-window-size-change t)
|
||||
(add-hook 'after-change-functions 'follow-after-change nil t)
|
||||
(add-hook 'isearch-update-post-hook 'follow-post-command-hook nil t)
|
||||
(add-hook 'replace-update-post-hook 'follow-post-command-hook nil t)
|
||||
(add-hook 'ispell-update-post-hook 'follow-post-command-hook nil t)
|
||||
|
||||
(setq window-group-start-function 'follow-window-start)
|
||||
(setq window-group-end-function 'follow-window-end)
|
||||
(setq set-window-group-start-function 'follow-set-window-start)
|
||||
(setq recenter-window-group-function 'follow-recenter)
|
||||
(setq pos-visible-in-window-group-p-function
|
||||
'follow-pos-visible-in-window-p)
|
||||
(setq selected-window-group-function 'follow-all-followers)
|
||||
(setq move-to-window-group-line-function 'follow-move-to-window-line))
|
||||
|
||||
;; Remove globally-installed hook functions only if there is no
|
||||
;; other Follow mode buffer.
|
||||
(let ((buffers (buffer-list))
|
||||
@ -432,6 +446,19 @@ Keys specific to Follow mode:
|
||||
(unless following
|
||||
(remove-hook 'post-command-hook 'follow-post-command-hook)
|
||||
(remove-hook 'window-size-change-functions 'follow-window-size-change)))
|
||||
|
||||
(kill-local-variable 'move-to-window-group-line-function)
|
||||
(kill-local-variable 'selected-window-group-function)
|
||||
(kill-local-variable 'pos-visible-in-window-group-p-function)
|
||||
(kill-local-variable 'recenter-window-group-function)
|
||||
(kill-local-variable 'set-window-group-start-function)
|
||||
(kill-local-variable 'window-group-end-function)
|
||||
(kill-local-variable 'window-group-start-function)
|
||||
|
||||
(remove-hook 'ispell-update-post-hook 'follow-post-command-hook t)
|
||||
(remove-hook 'replace-update-post-hook 'follow-post-command-hook t)
|
||||
(remove-hook 'isearch-update-post-hook 'follow-post-command-hook t)
|
||||
(remove-hook 'after-change-functions 'follow-after-change t)
|
||||
(remove-hook 'compilation-filter-hook 'follow-align-compilation-windows t)))
|
||||
|
||||
(defun follow-find-file-hook ()
|
||||
@ -1015,6 +1042,10 @@ Otherwise, return nil."
|
||||
;; is nil. Start every window directly after the end of the previous
|
||||
;; window, to make sure long lines are displayed correctly.
|
||||
|
||||
(defvar follow-start-end-invalid t
|
||||
"When non-nil, indicates `follow-windows-start-end-cache' is invalid.")
|
||||
(make-variable-buffer-local 'follow-start-end-invalid)
|
||||
|
||||
(defun follow-redisplay (&optional windows win preserve-win)
|
||||
"Reposition the WINDOWS around WIN.
|
||||
Should point be too close to the roof we redisplay everything
|
||||
@ -1047,7 +1078,8 @@ repositioning the other windows."
|
||||
(dolist (w windows)
|
||||
(unless (and preserve-win (eq w win))
|
||||
(set-window-start w start))
|
||||
(setq start (car (follow-calc-win-end w))))))
|
||||
(setq start (car (follow-calc-win-end w))))
|
||||
(setq follow-start-end-invalid nil)))
|
||||
|
||||
(defun follow-estimate-first-window-start (windows win start)
|
||||
"Estimate the position of the first window.
|
||||
@ -1443,6 +1475,146 @@ non-first windows in Follow mode."
|
||||
|
||||
(add-hook 'window-scroll-functions 'follow-avoid-tail-recenter t)
|
||||
|
||||
;;; Low level window start and end.
|
||||
|
||||
;; These routines are the Follow Mode versions of the low level
|
||||
;; functions described on page "Window Start and End" of the elisp
|
||||
;; manual, e.g. `window-group-start'. The aim is to be able to handle
|
||||
;; Follow Mode windows by replacing `window-start' by
|
||||
;; `window-group-start', etc.
|
||||
|
||||
(defun follow-after-change (_beg _end _old-len)
|
||||
"After change function: set `follow-start-end-invalid'."
|
||||
(setq follow-start-end-invalid t))
|
||||
|
||||
(defun follow-window-start (&optional window)
|
||||
"Return position at which display currently starts in the
|
||||
Follow Mode group of windows which includes WINDOW.
|
||||
|
||||
WINDOW must be a live window and defaults to the selected one.
|
||||
This is updated by redisplay or by calling
|
||||
`follow-set-window-start'."
|
||||
(let ((windows (follow-all-followers window)))
|
||||
(window-start (car windows))))
|
||||
|
||||
(defun follow-window-end (&optional window update)
|
||||
"Return position at which display currently ends in the Follow
|
||||
Mode group of windows which includes WINDOW.
|
||||
|
||||
WINDOW must be a live window and defaults to the selected one.
|
||||
This is updated by redisplay, when it runs to completion.
|
||||
Simply changing the buffer text or setting `window-start' does
|
||||
not update this value.
|
||||
|
||||
Return nil if there is no recorded value. (This can happen if
|
||||
the last redisplay of WINDOW was preempted, and did not
|
||||
finish.) If UPDATE is non-nil, compute the up-to-date position
|
||||
if it isn't already recorded."
|
||||
(let* ((windows (follow-all-followers window))
|
||||
(last (car (last windows))))
|
||||
(when (and update follow-start-end-invalid)
|
||||
(follow-redisplay windows (car windows)))
|
||||
(window-end last update)))
|
||||
|
||||
(defun follow-set-window-start (window pos &optional noforce)
|
||||
"Make display in the Follow Mode group of windows which includes
|
||||
WINDOW start at position POS in WINDOW's buffer.
|
||||
|
||||
WINDOW must be a live window and defaults to the selected one. Return
|
||||
POS. Optional third arg NOFORCE non-nil inhibits next redisplay from
|
||||
overriding motion of point in order to display at this exact start."
|
||||
(let ((windows (follow-all-followers window)))
|
||||
(setq follow-start-end-invalid t)
|
||||
(set-window-start (car windows) pos noforce)))
|
||||
|
||||
(defun follow-pos-visible-in-window-p (&optional pos window partially)
|
||||
"Return non-nil if position POS is currently on the frame in one of
|
||||
the windows in the Follow Mode group which includes WINDOW.
|
||||
|
||||
WINDOW must be a live window and defaults to the selected one.
|
||||
|
||||
Return nil if that position is scrolled vertically out of view. If a
|
||||
character is only partially visible, nil is returned, unless the
|
||||
optional argument PARTIALLY is non-nil. If POS is only out of view
|
||||
because of horizontal scrolling, return non-nil. If POS is t, it
|
||||
specifies the position of the last visible glyph in WINDOW. POS
|
||||
defaults to point in WINDOW; WINDOW defaults to the selected window.
|
||||
|
||||
If POS is visible, return t if PARTIALLY is nil; if PARTIALLY is non-nil,
|
||||
the return value is a list of 2 or 6 elements (X Y [RTOP RBOT ROWH VPOS]),
|
||||
where X and Y are the pixel coordinates relative to the top left corner
|
||||
of the actual window containing it. The remaining elements are
|
||||
omitted if the character after POS is fully visible; otherwise, RTOP
|
||||
and RBOT are the number of pixels off-window at the top and bottom of
|
||||
the screen line (\"row\") containing POS, ROWH is the visible height
|
||||
of that row, and VPOS is the row number \(zero-based)."
|
||||
(let* ((windows (follow-all-followers window))
|
||||
(last (car (last windows))))
|
||||
(when follow-start-end-invalid
|
||||
(follow-redisplay windows (car windows)))
|
||||
(let* ((cache (follow-windows-start-end windows))
|
||||
(last-elt (car (last cache)))
|
||||
our-pos pertinent-elt)
|
||||
(setq pertinent-elt
|
||||
(if (eq pos t)
|
||||
last-elt
|
||||
(setq our-pos (or pos (point)))
|
||||
(catch 'element
|
||||
(while cache
|
||||
(when (< our-pos (nth 2 (car cache)))
|
||||
(throw 'element (car cache)))
|
||||
(setq cache (cdr cache)))
|
||||
last-elt)))
|
||||
(pos-visible-in-window-p our-pos (car pertinent-elt) partially))))
|
||||
|
||||
(defun follow-move-to-window-line (arg)
|
||||
"Position point relative to the Follow mode group containing the selected window.
|
||||
ARG nil means position point at center of the window group.
|
||||
Else, ARG specifies vertical position within the window group;
|
||||
zero means top of the first window in the group, negative means
|
||||
relative to bottom of the last window in the group."
|
||||
(let* ((windows (follow-all-followers))
|
||||
(start-end (follow-windows-start-end windows))
|
||||
(rev-start-end (reverse start-end))
|
||||
(lines 0)
|
||||
middle-window elt count)
|
||||
(select-window
|
||||
(cond
|
||||
((null arg)
|
||||
(setq rev-start-end (nthcdr (/ (length windows) 2) rev-start-end))
|
||||
(prog1 (car (car rev-start-end))
|
||||
(while (setq rev-start-end (cdr rev-start-end))
|
||||
(setq elt (car rev-start-end)
|
||||
count (count-screen-lines (cadr elt) (nth 2 elt)
|
||||
nil (car elt))
|
||||
lines (+ lines count)))))
|
||||
((>= arg 0)
|
||||
(while (and (cdr start-end)
|
||||
(progn
|
||||
(setq elt (car start-end)
|
||||
count (count-screen-lines (cadr elt) (nth 2 elt)
|
||||
nil (car elt)))
|
||||
(>= arg count)))
|
||||
(setq arg (- arg count)
|
||||
lines (+ lines count)
|
||||
start-end (cdr start-end)))
|
||||
(car (car start-end)))
|
||||
(t ; (< arg 0)
|
||||
(while (and (cadr rev-start-end)
|
||||
(progn
|
||||
(setq elt (car rev-start-end)
|
||||
count (count-lines (cadr elt) (nth 2 elt)))
|
||||
(<= arg (- count))))
|
||||
(setq arg (+ arg count)
|
||||
rev-start-end (cdr rev-start-end)))
|
||||
(prog1 (car (car rev-start-end))
|
||||
(while (setq rev-start-end (cdr rev-start-end))
|
||||
(setq elt (car rev-start-end)
|
||||
count (count-screen-lines (cadr elt) (nth 2 elt)
|
||||
nil (car elt))
|
||||
lines (+ lines count)))))))
|
||||
(+ lines (move-to-window-line arg))))
|
||||
|
||||
;;; Profile support
|
||||
|
||||
;; The following (non-evaluated) section can be used to
|
||||
|
125
lisp/isearch.el
125
lisp/isearch.el
@ -961,7 +961,8 @@ used to set the value of `isearch-regexp-function'."
|
||||
|
||||
(defun isearch-update ()
|
||||
"This is called after every isearch command to update the display.
|
||||
The last thing it does is to run `isearch-update-post-hook'."
|
||||
The second last thing it does is to run `isearch-update-post-hook'.
|
||||
The last thing is to trigger a new round of lazy highlighting."
|
||||
(unless (eq (current-buffer) isearch--current-buffer)
|
||||
(when (buffer-live-p isearch--current-buffer)
|
||||
(with-current-buffer isearch--current-buffer
|
||||
@ -978,12 +979,10 @@ The last thing it does is to run `isearch-update-post-hook'."
|
||||
(null executing-kbd-macro))
|
||||
(progn
|
||||
(if (not (input-pending-p))
|
||||
(if isearch-message-function
|
||||
(funcall isearch-message-function)
|
||||
(isearch-message)))
|
||||
(funcall (or isearch-message-function #'isearch-message)))
|
||||
(if (and isearch-slow-terminal-mode
|
||||
(not (or isearch-small-window
|
||||
(pos-visible-in-window-p))))
|
||||
(pos-visible-in-window-group-p))))
|
||||
(let ((found-point (point)))
|
||||
(setq isearch-small-window t)
|
||||
(move-to-window-line 0)
|
||||
@ -1004,10 +1003,10 @@ The last thing it does is to run `isearch-update-post-hook'."
|
||||
(let ((current-scroll (window-hscroll))
|
||||
visible-p)
|
||||
(set-window-hscroll (selected-window) isearch-start-hscroll)
|
||||
(setq visible-p (pos-visible-in-window-p nil nil t))
|
||||
(setq visible-p (pos-visible-in-window-group-p nil nil t))
|
||||
(if (or (not visible-p)
|
||||
;; When point is not visible because of hscroll,
|
||||
;; pos-visible-in-window-p returns non-nil, but
|
||||
;; pos-visible-in-window-group-p returns non-nil, but
|
||||
;; the X coordinate it returns is 1 pixel beyond
|
||||
;; the last visible one.
|
||||
(>= (car visible-p) (window-body-width nil t)))
|
||||
@ -1020,12 +1019,12 @@ The last thing it does is to run `isearch-update-post-hook'."
|
||||
(setq ;; quit-flag nil not for isearch-mode
|
||||
isearch-adjusted nil
|
||||
isearch-yank-flag nil)
|
||||
(when isearch-lazy-highlight
|
||||
(isearch-lazy-highlight-new-loop))
|
||||
;; We must prevent the point moving to the end of composition when a
|
||||
;; part of the composition has just been searched.
|
||||
(setq disable-point-adjustment t)
|
||||
(run-hooks 'isearch-update-post-hook))
|
||||
(run-hooks 'isearch-update-post-hook)
|
||||
(when isearch-lazy-highlight
|
||||
(isearch-lazy-highlight-new-loop)))
|
||||
|
||||
(defun isearch-done (&optional nopush edit)
|
||||
"Exit Isearch mode.
|
||||
@ -1058,7 +1057,7 @@ NOPUSH is t and EDIT is t."
|
||||
(setq minibuffer-message-timeout isearch-original-minibuffer-message-timeout)
|
||||
(isearch-dehighlight)
|
||||
(lazy-highlight-cleanup lazy-highlight-cleanup)
|
||||
(let ((found-start (window-start))
|
||||
(let ((found-start (window-group-start))
|
||||
(found-point (point)))
|
||||
(when isearch-window-configuration
|
||||
(set-window-configuration isearch-window-configuration)
|
||||
@ -1068,7 +1067,7 @@ NOPUSH is t and EDIT is t."
|
||||
;; This has an annoying side effect of clearing the last_modiff
|
||||
;; field of the window, which can cause unwanted scrolling,
|
||||
;; so don't do it unless truly necessary.
|
||||
(set-window-start (selected-window) found-start t))))
|
||||
(set-window-group-start (selected-window) found-start t))))
|
||||
|
||||
(setq isearch-mode nil)
|
||||
(if isearch-input-method-local-p
|
||||
@ -1299,13 +1298,6 @@ You can update the global isearch variables by setting new values to
|
||||
(unwind-protect
|
||||
(progn ,@body)
|
||||
|
||||
;; Set point at the start (end) of old match if forward (backward),
|
||||
;; so after exiting minibuffer isearch resumes at the start (end)
|
||||
;; of this match and can find it again.
|
||||
(if (and old-other-end (eq old-point (point))
|
||||
(eq isearch-forward isearch-new-forward))
|
||||
(goto-char old-other-end))
|
||||
|
||||
;; Always resume isearching by restarting it.
|
||||
(isearch-mode isearch-forward
|
||||
isearch-regexp
|
||||
@ -1318,7 +1310,17 @@ You can update the global isearch variables by setting new values to
|
||||
isearch-message isearch-new-message
|
||||
isearch-forward isearch-new-forward
|
||||
isearch-regexp-function isearch-new-regexp-function
|
||||
isearch-case-fold-search isearch-new-case-fold))
|
||||
isearch-case-fold-search isearch-new-case-fold)
|
||||
|
||||
;; Restore the minibuffer message before moving point.
|
||||
(funcall (or isearch-message-function #'isearch-message) nil t)
|
||||
|
||||
;; Set point at the start (end) of old match if forward (backward),
|
||||
;; so after exiting minibuffer isearch resumes at the start (end)
|
||||
;; of this match and can find it again.
|
||||
(if (and old-other-end (eq old-point (point))
|
||||
(eq isearch-forward isearch-new-forward))
|
||||
(goto-char old-other-end)))
|
||||
|
||||
;; Empty isearch-string means use default.
|
||||
(when (= 0 (length isearch-string))
|
||||
@ -1931,6 +1933,8 @@ If search string is empty, just beep."
|
||||
(length isearch-string))))
|
||||
isearch-message (mapconcat 'isearch-text-char-description
|
||||
isearch-string "")))
|
||||
;; Do the following before moving point.
|
||||
(funcall (or isearch-message-function #'isearch-message) nil t)
|
||||
;; Use the isearch-other-end as new starting point to be able
|
||||
;; to find the remaining part of the search string again.
|
||||
;; This is like what `isearch-search-and-update' does,
|
||||
@ -2107,6 +2111,8 @@ With argument, add COUNT copies of the character."
|
||||
(setq isearch-case-fold-search
|
||||
(isearch-no-upper-case-p isearch-string isearch-regexp))))
|
||||
;; Not regexp, not reverse, or no match at point.
|
||||
;; Do the following before moving point.
|
||||
(funcall (or isearch-message-function #'isearch-message) nil t)
|
||||
(if (and isearch-other-end (not isearch-adjusted))
|
||||
(goto-char (if isearch-forward isearch-other-end
|
||||
(min isearch-opoint
|
||||
@ -2273,10 +2279,12 @@ Return nil if it's completely visible, or if point is visible,
|
||||
together with as much of the search string as will fit; the symbol
|
||||
`above' if we need to scroll the text downwards; the symbol `below',
|
||||
if upwards."
|
||||
(let ((w-start (window-start))
|
||||
(w-end (window-end nil t))
|
||||
(w-L1 (save-excursion (move-to-window-line 1) (point)))
|
||||
(w-L-1 (save-excursion (move-to-window-line -1) (point)))
|
||||
(let ((w-start (window-group-start))
|
||||
(w-end (window-group-end nil t))
|
||||
(w-L1 (save-excursion
|
||||
(save-selected-window (move-to-window-group-line 1) (point))))
|
||||
(w-L-1 (save-excursion
|
||||
(save-selected-window (move-to-window-group-line -1) (point))))
|
||||
start end) ; start and end of search string in buffer
|
||||
(if isearch-forward
|
||||
(setq end isearch-point start (or isearch-other-end isearch-point))
|
||||
@ -2303,15 +2311,15 @@ the bottom."
|
||||
(if above
|
||||
(progn
|
||||
(goto-char start)
|
||||
(recenter 0)
|
||||
(when (>= isearch-point (window-end nil t))
|
||||
(recenter-window-group 0)
|
||||
(when (>= isearch-point (window-group-end nil t))
|
||||
(goto-char isearch-point)
|
||||
(recenter -1)))
|
||||
(recenter-window-group -1)))
|
||||
(goto-char end)
|
||||
(recenter -1)
|
||||
(when (< isearch-point (window-start))
|
||||
(recenter-window-group -1)
|
||||
(when (< isearch-point (window-group-start))
|
||||
(goto-char isearch-point)
|
||||
(recenter 0))))
|
||||
(recenter-window-group 0))))
|
||||
(goto-char isearch-point))
|
||||
|
||||
(defvar isearch-pre-scroll-point nil)
|
||||
@ -2458,6 +2466,7 @@ Search is updated accordingly."
|
||||
(isearch-ring-adjust1 advance)
|
||||
(if search-ring-update
|
||||
(progn
|
||||
(funcall (or isearch-message-function #'isearch-message) nil t)
|
||||
(isearch-search)
|
||||
(isearch-push-state)
|
||||
(isearch-update))
|
||||
@ -2530,6 +2539,13 @@ If there is no completion possible, say so and continue searching."
|
||||
|
||||
(defun isearch-message (&optional c-q-hack ellipsis)
|
||||
;; Generate and print the message string.
|
||||
|
||||
;; N.B.: This function should always be called with point at the
|
||||
;; search point, because in certain (rare) circumstances, undesired
|
||||
;; scrolling can happen when point is elsewhere. These
|
||||
;; circumstances are when follow-mode is active, the search string
|
||||
;; spans two (or several) windows, and the message about to be
|
||||
;; displayed will cause the echo area to expand.
|
||||
(let ((cursor-in-echo-area ellipsis)
|
||||
(m isearch-message)
|
||||
(fail-pos (isearch-fail-pos t)))
|
||||
@ -2723,9 +2739,6 @@ update the match data, and return point."
|
||||
|
||||
(defun isearch-search ()
|
||||
;; Do the search with the current search string.
|
||||
(if isearch-message-function
|
||||
(funcall isearch-message-function nil t)
|
||||
(isearch-message nil t))
|
||||
(if (and (eq isearch-case-fold-search t) search-upper-case)
|
||||
(setq isearch-case-fold-search
|
||||
(isearch-no-upper-case-p isearch-string isearch-regexp)))
|
||||
@ -3023,6 +3036,7 @@ since they have special meaning in a regexp."
|
||||
(defvar isearch-lazy-highlight-timer nil)
|
||||
(defvar isearch-lazy-highlight-last-string nil)
|
||||
(defvar isearch-lazy-highlight-window nil)
|
||||
(defvar isearch-lazy-highlight-window-group nil)
|
||||
(defvar isearch-lazy-highlight-window-start nil)
|
||||
(defvar isearch-lazy-highlight-window-end nil)
|
||||
(defvar isearch-lazy-highlight-case-fold-search nil)
|
||||
@ -3064,8 +3078,8 @@ by other Emacs features."
|
||||
(sit-for 0) ;make sure (window-start) is credible
|
||||
(or (not (equal isearch-string
|
||||
isearch-lazy-highlight-last-string))
|
||||
(not (eq (selected-window)
|
||||
isearch-lazy-highlight-window))
|
||||
(not (memq (selected-window)
|
||||
isearch-lazy-highlight-window-group))
|
||||
(not (eq isearch-lazy-highlight-case-fold-search
|
||||
isearch-case-fold-search))
|
||||
(not (eq isearch-lazy-highlight-regexp
|
||||
@ -3076,9 +3090,9 @@ by other Emacs features."
|
||||
isearch-lax-whitespace))
|
||||
(not (eq isearch-lazy-highlight-regexp-lax-whitespace
|
||||
isearch-regexp-lax-whitespace))
|
||||
(not (= (window-start)
|
||||
(not (= (window-group-start)
|
||||
isearch-lazy-highlight-window-start))
|
||||
(not (= (window-end) ; Window may have been split/joined.
|
||||
(not (= (window-group-end) ; Window may have been split/joined.
|
||||
isearch-lazy-highlight-window-end))
|
||||
(not (eq isearch-forward
|
||||
isearch-lazy-highlight-forward))
|
||||
@ -3086,7 +3100,7 @@ by other Emacs features."
|
||||
(not (equal isearch-error
|
||||
isearch-lazy-highlight-error))))
|
||||
;; something important did indeed change
|
||||
(lazy-highlight-cleanup t) ;kill old loop & remove overlays
|
||||
(lazy-highlight-cleanup t) ;kill old loop & remove overlays
|
||||
(setq isearch-lazy-highlight-error isearch-error)
|
||||
;; It used to check for `(not isearch-error)' here, but actually
|
||||
;; lazy-highlighting might find matches to highlight even when
|
||||
@ -3094,8 +3108,9 @@ by other Emacs features."
|
||||
(setq isearch-lazy-highlight-start-limit beg
|
||||
isearch-lazy-highlight-end-limit end)
|
||||
(setq isearch-lazy-highlight-window (selected-window)
|
||||
isearch-lazy-highlight-window-start (window-start)
|
||||
isearch-lazy-highlight-window-end (window-end)
|
||||
isearch-lazy-highlight-window-group (selected-window-group)
|
||||
isearch-lazy-highlight-window-start (window-group-start)
|
||||
isearch-lazy-highlight-window-end (window-group-end)
|
||||
;; Start lazy-highlighting at the beginning of the found
|
||||
;; match (`isearch-other-end'). If no match, use point.
|
||||
;; One of the next two variables (depending on search direction)
|
||||
@ -3113,10 +3128,10 @@ by other Emacs features."
|
||||
isearch-lazy-highlight-regexp-lax-whitespace isearch-regexp-lax-whitespace
|
||||
isearch-lazy-highlight-regexp-function isearch-regexp-function
|
||||
isearch-lazy-highlight-forward isearch-forward)
|
||||
(unless (equal isearch-string "")
|
||||
(setq isearch-lazy-highlight-timer
|
||||
(run-with-idle-timer lazy-highlight-initial-delay nil
|
||||
'isearch-lazy-highlight-update)))))
|
||||
(unless (equal isearch-string "")
|
||||
(setq isearch-lazy-highlight-timer
|
||||
(run-with-idle-timer lazy-highlight-initial-delay nil
|
||||
'isearch-lazy-highlight-update)))))
|
||||
|
||||
(defun isearch-lazy-highlight-search ()
|
||||
"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."
|
||||
(+ isearch-lazy-highlight-start
|
||||
;; Extend bound to match whole string at point
|
||||
(1- (length isearch-lazy-highlight-last-string)))
|
||||
(window-end)))
|
||||
(window-group-end)))
|
||||
(max (or isearch-lazy-highlight-start-limit (point-min))
|
||||
(if isearch-lazy-highlight-wrapped
|
||||
(- isearch-lazy-highlight-end
|
||||
;; Extend bound to match whole string at point
|
||||
(1- (length isearch-lazy-highlight-last-string)))
|
||||
(window-start))))))
|
||||
(window-group-start))))))
|
||||
;; Use a loop like in `isearch-search'.
|
||||
(while retry
|
||||
(setq success (isearch-search-string
|
||||
@ -3169,7 +3184,7 @@ Attempt to do the search exactly the way the pending Isearch would."
|
||||
(with-local-quit
|
||||
(save-selected-window
|
||||
(if (and (window-live-p isearch-lazy-highlight-window)
|
||||
(not (eq (selected-window) isearch-lazy-highlight-window)))
|
||||
(not (memq (selected-window) isearch-lazy-highlight-window-group)))
|
||||
(select-window isearch-lazy-highlight-window))
|
||||
(save-excursion
|
||||
(save-match-data
|
||||
@ -3189,12 +3204,12 @@ Attempt to do the search exactly the way the pending Isearch would."
|
||||
(if isearch-lazy-highlight-forward
|
||||
(if (= mb (if isearch-lazy-highlight-wrapped
|
||||
isearch-lazy-highlight-start
|
||||
(window-end)))
|
||||
(window-group-end)))
|
||||
(setq found nil)
|
||||
(forward-char 1))
|
||||
(if (= mb (if isearch-lazy-highlight-wrapped
|
||||
isearch-lazy-highlight-end
|
||||
(window-start)))
|
||||
(window-group-start)))
|
||||
(setq found nil)
|
||||
(forward-char -1)))
|
||||
|
||||
@ -3204,8 +3219,8 @@ Attempt to do the search exactly the way the pending Isearch would."
|
||||
;; 1000 is higher than ediff's 100+,
|
||||
;; but lower than isearch main overlay's 1001
|
||||
(overlay-put ov 'priority 1000)
|
||||
(overlay-put ov 'face lazy-highlight-face)
|
||||
(overlay-put ov 'window (selected-window))))
|
||||
(overlay-put ov 'face lazy-highlight-face)))
|
||||
;(overlay-put ov 'window (selected-window))))
|
||||
;; Remember the current position of point for
|
||||
;; the next call of `isearch-lazy-highlight-update'
|
||||
;; 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."
|
||||
(setq isearch-lazy-highlight-wrapped t)
|
||||
(if isearch-lazy-highlight-forward
|
||||
(progn
|
||||
(setq isearch-lazy-highlight-end (window-start))
|
||||
(setq isearch-lazy-highlight-end (window-group-start))
|
||||
(goto-char (max (or isearch-lazy-highlight-start-limit (point-min))
|
||||
(window-start))))
|
||||
(setq isearch-lazy-highlight-start (window-end))
|
||||
(window-group-start))))
|
||||
(setq isearch-lazy-highlight-start (window-group-end))
|
||||
(goto-char (min (or isearch-lazy-highlight-end-limit (point-max))
|
||||
(window-end))))))))
|
||||
(window-group-end))))))))
|
||||
(unless nomore
|
||||
(setq isearch-lazy-highlight-timer
|
||||
(run-at-time lazy-highlight-interval nil
|
||||
|
@ -2011,6 +2011,9 @@ passed in. If LITERAL is set, no checking is done, anyway."
|
||||
(when backward (goto-char (nth 0 match-data)))
|
||||
noedit)
|
||||
|
||||
(defvar replace-update-post-hook nil
|
||||
"Function(s) to call after query-replace has found a match in the buffer.")
|
||||
|
||||
(defvar replace-search-function nil
|
||||
"Function to use when searching for strings to replace.
|
||||
It is used by `query-replace' and `replace-string', and is called
|
||||
@ -2264,7 +2267,7 @@ It must return a string."
|
||||
(and nonempty-match
|
||||
(or (not regexp-flag)
|
||||
(and (if backward
|
||||
(looking-back search-string)
|
||||
(looking-back search-string nil)
|
||||
(looking-at search-string))
|
||||
(let ((match (match-data)))
|
||||
(and (/= (nth 0 match) (nth 1 match))
|
||||
@ -2318,7 +2321,8 @@ It must return a string."
|
||||
;; `real-match-data'.
|
||||
(while (not done)
|
||||
(set-match-data real-match-data)
|
||||
(replace-highlight
|
||||
(run-hooks 'replace-update-post-hook) ; Before `replace-highlight'.
|
||||
(replace-highlight
|
||||
(match-beginning 0) (match-end 0)
|
||||
start end search-string
|
||||
regexp-flag delimited-flag case-fold-search backward)
|
||||
|
@ -1782,6 +1782,51 @@ Extended character mode can be changed for this buffer by placing
|
||||
a `~' followed by an extended-character mode -- such as `~.tex'.
|
||||
The last occurring definition in the buffer will be used.")
|
||||
|
||||
(defun ispell--\\w-filter (char)
|
||||
"Return CHAR in a string when CHAR doesn't have \"word\" syntax,
|
||||
nil otherwise. CHAR must be a character."
|
||||
(let ((str (string char)))
|
||||
(and
|
||||
(not (string-match "\\w" str))
|
||||
str)))
|
||||
|
||||
(defun ispell--make-\\w-expression (chars)
|
||||
"Make a regular expression like \"\\(\\w\\|[-_]\\)\".
|
||||
This (parenthesized) expression matches either a character of
|
||||
\"word\" syntax or one in CHARS.
|
||||
|
||||
CHARS is a string of characters. A member of CHARS is omitted
|
||||
from the expression if it already has word syntax. (Be careful
|
||||
about special characters such as ?\\, ?^, ?], and ?- in CHARS.)
|
||||
If after this filtering there are no chars left, or only one, a
|
||||
special form of the expression is generated."
|
||||
(let ((filtered
|
||||
(mapconcat #'ispell--\\w-filter chars "")))
|
||||
(concat
|
||||
"\\(\\w"
|
||||
(cond
|
||||
((equal filtered "")
|
||||
"\\)")
|
||||
((eq (length filtered) 1)
|
||||
(concat "\\|" filtered "\\)"))
|
||||
(t
|
||||
(concat "\\|[" filtered "]\\)"))))))
|
||||
|
||||
(defun ispell--make-filename-or-URL-re ()
|
||||
"Construct a regexp to match some file names or URLs or email addresses.
|
||||
The expression is crafted to match as great a variety of these
|
||||
objects as practicable, without too many false matches happening."
|
||||
(concat ;"\\(--+\\|_+\\|"
|
||||
"\\(/\\w\\|\\("
|
||||
(ispell--make-\\w-expression "-_")
|
||||
"+[.:@]\\)\\)"
|
||||
(ispell--make-\\w-expression "-_")
|
||||
"*\\([.:/@]+"
|
||||
(ispell--make-\\w-expression "-_~=?&")
|
||||
"+\\)+"
|
||||
;"\\)"
|
||||
))
|
||||
|
||||
;;;###autoload
|
||||
(defvar ispell-skip-region-alist
|
||||
`((ispell-words-keyword forward-line)
|
||||
@ -1798,7 +1843,7 @@ The last occurring definition in the buffer will be used.")
|
||||
;; Matches e-mail addresses, file names, http addresses, etc. The
|
||||
;; `-+' `_+' patterns are necessary for performance reasons when
|
||||
;; `-' or `_' part of word syntax.
|
||||
(,(purecopy "\\(--+\\|_+\\|\\(/\\w\\|\\(\\(\\w\\|[-_]\\)+[.:@]\\)\\)\\(\\w\\|[-_]\\)*\\([.:/@]+\\(\\w\\|[-_~=?&]\\)+\\)+\\)"))
|
||||
; (,(purecopy "\\(--+\\|_+\\|\\(/\\w\\|\\(\\(\\w\\|[-_]\\)+[.:@]\\)\\)\\(\\w\\|[-_]\\)*\\([.:/@]+\\(\\w\\|[-_~=?&]\\)+\\)+\\)"))
|
||||
;; above checks /.\w sequences
|
||||
;;("\\(--+\\|\\(/\\|\\(\\(\\w\\|[-_]\\)+[.:@]\\)\\)\\(\\w\\|[-_]\\)*\\([.:/@]+\\(\\w\\|[-_~=?&]\\)+\\)+\\)")
|
||||
;; 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."
|
||||
(setq ispell-pdict-modified-p nil))
|
||||
|
||||
|
||||
(defvar ispell-update-post-hook nil
|
||||
"A normal hook invoked from the ispell command loop.
|
||||
It is called once per iteration, before displaying a prompt to
|
||||
the user.")
|
||||
|
||||
(defun ispell-command-loop (miss guess word start end)
|
||||
"Display possible corrections from list MISS.
|
||||
GUESS lists possibly valid affix construction of WORD.
|
||||
@ -2315,8 +2365,10 @@ Global `ispell-quit' set to start location to continue spell session."
|
||||
count (ispell-int-char (1+ count))))
|
||||
(setq count (ispell-int-char (- count ?0 skipped))))
|
||||
|
||||
(run-hooks 'ispell-update-post-hook)
|
||||
|
||||
;; ensure word is visible
|
||||
(if (not (pos-visible-in-window-p end))
|
||||
(if (not (pos-visible-in-window-group-p end))
|
||||
(sit-for 0))
|
||||
|
||||
;; Display choices for misspelled word.
|
||||
@ -2845,13 +2897,20 @@ Also position fit window to BUFFER and select it."
|
||||
(prog1
|
||||
(condition-case nil
|
||||
(split-window
|
||||
nil (- ispell-choices-win-default-height) 'above)
|
||||
;; Chose the last of a window group, since
|
||||
;; otherwise, the lowering of another window's
|
||||
;; TL corner would cause the logical order of
|
||||
;; the windows to be changed.
|
||||
(car (last (selected-window-group)))
|
||||
(- ispell-choices-win-default-height) 'above)
|
||||
(error nil))
|
||||
(modify-frame-parameters frame '((unsplittable . t))))))
|
||||
(and (not unsplittable)
|
||||
(condition-case nil
|
||||
(split-window
|
||||
nil (- ispell-choices-win-default-height) 'above)
|
||||
;; See comment above.
|
||||
(car (last (selected-window-group)))
|
||||
(- ispell-choices-win-default-height) 'above)
|
||||
(error nil)))
|
||||
(display-buffer buffer))))
|
||||
(if (not window)
|
||||
@ -3374,7 +3433,8 @@ Must be called after `ispell-buffer-local-parsing' due to dependence on mode."
|
||||
(if (string= "" comment-end) "^" (regexp-quote comment-end)))
|
||||
(if (and (null ispell-check-comments) comment-start)
|
||||
(regexp-quote comment-start))
|
||||
(ispell-begin-skip-region ispell-skip-region-alist)))
|
||||
(ispell-begin-skip-region ispell-skip-region-alist)
|
||||
(ispell--make-filename-or-URL-re)))
|
||||
"\\|"))
|
||||
|
||||
|
||||
@ -3413,6 +3473,8 @@ Manual checking must include comments and tib references.
|
||||
The list is of the form described by variable `ispell-skip-region-alist'.
|
||||
Must be called after `ispell-buffer-local-parsing' due to dependence on mode."
|
||||
(let ((skip-alist ispell-skip-region-alist))
|
||||
(setq skip-alist (append (list (list (ispell--make-filename-or-URL-re)))
|
||||
skip-alist))
|
||||
;; only additional explicit region definition is tex.
|
||||
(if (eq ispell-parser 'tex)
|
||||
(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
|
||||
(ispell-non-empty-string vm-included-text-prefix)))
|
||||
(t default-prefix)))
|
||||
(ispell-skip-region-alist
|
||||
(cons (list (concat "^\\(" cite-regexp "\\)")
|
||||
(function forward-line))
|
||||
ispell-skip-region-alist))
|
||||
(cons (list (ispell--make-filename-or-URL-re))
|
||||
(cons (list (concat "^\\(" cite-regexp "\\)")
|
||||
(function forward-line))
|
||||
ispell-skip-region-alist)))
|
||||
(old-case-fold-search case-fold-search)
|
||||
(dictionary-alist ispell-message-dictionary-alist)
|
||||
(ispell-checking-message t))
|
||||
|
146
lisp/window.el
146
lisp/window.el
@ -7869,6 +7869,152 @@ Return non-nil if the window was shrunk, nil otherwise."
|
||||
(with-current-buffer buffer-to-kill
|
||||
(remove-hook 'kill-buffer-hook delete-window-hook t))))))
|
||||
|
||||
|
||||
;;;
|
||||
;; Groups of windows (Follow Mode).
|
||||
;;
|
||||
;; This section of functions extends the functionality of some window
|
||||
;; manipulating commands to groups of windows co-operatively
|
||||
;; displaying a buffer, typically with Follow Mode.
|
||||
;;
|
||||
;; The xxx-function variables are permanent locals so that their local
|
||||
;; status is undone only when explicitly programmed, not when a buffer
|
||||
;; is reverted or a mode function is called.
|
||||
|
||||
(defvar window-group-start-function nil)
|
||||
(make-variable-buffer-local 'window-group-start-function)
|
||||
(put 'window-group-start-function 'permanent-local t)
|
||||
(defun window-group-start (&optional window)
|
||||
"Return position at which display currently starts in the group of
|
||||
windows containing WINDOW. When a grouping mode (such as Follow Mode)
|
||||
is not active, this function is identical to `window-start'.
|
||||
|
||||
WINDOW must be a live window and defaults to the selected one.
|
||||
This is updated by redisplay or by calling `set-window*-start'."
|
||||
(if (functionp window-group-start-function)
|
||||
(funcall window-group-start-function window)
|
||||
(window-start window)))
|
||||
|
||||
(defvar window-group-end-function nil)
|
||||
(make-variable-buffer-local 'window-group-end-function)
|
||||
(put 'window-group-end-function 'permanent-local t)
|
||||
(defun window-group-end (&optional window update)
|
||||
"Return position at which display currently ends in the group of
|
||||
windows containing WINDOW. When a grouping mode (such as Follow Mode)
|
||||
is not active, this function is identical to `window-end'.
|
||||
|
||||
WINDOW must be a live window and defaults to the selected one.
|
||||
This is updated by redisplay, when it runs to completion.
|
||||
Simply changing the buffer text or setting `window-group-start'
|
||||
does not update this value.
|
||||
Return nil if there is no recorded value. (This can happen if the
|
||||
last redisplay of WINDOW was preempted, and did not finish.)
|
||||
If UPDATE is non-nil, compute the up-to-date position
|
||||
if it isn't already recorded."
|
||||
(if (functionp window-group-end-function)
|
||||
(funcall window-group-end-function window update)
|
||||
(window-end window update)))
|
||||
|
||||
(defvar set-window-group-start-function nil)
|
||||
(make-variable-buffer-local 'set-window-group-start-function)
|
||||
(put 'set-window-group-start-function 'permanent-local t)
|
||||
(defun set-window-group-start (window pos &optional noforce)
|
||||
"Make display in the group of windows containing WINDOW start at
|
||||
position POS in WINDOW's buffer. When a grouping mode (such as Follow
|
||||
Mode) is not active, this function is identical to `set-window-start'.
|
||||
|
||||
WINDOW must be a live window and defaults to the selected one. Return
|
||||
POS. Optional third arg NOFORCE non-nil inhibits next redisplay from
|
||||
overriding motion of point in order to display at this exact start."
|
||||
(if (functionp set-window-group-start-function)
|
||||
(funcall set-window-group-start-function window pos noforce)
|
||||
(set-window-start window pos noforce)))
|
||||
|
||||
(defvar recenter-window-group-function nil)
|
||||
(make-variable-buffer-local 'recenter-window-group-function)
|
||||
(put 'recenter-window-group-function 'permanent-local t)
|
||||
(defun recenter-window-group (&optional arg)
|
||||
"Center point in the group of windows containing the selected window
|
||||
and maybe redisplay frame. When a grouping mode (such as Follow Mode)
|
||||
is not active, this function is identical to `recenter'.
|
||||
|
||||
With a numeric prefix argument ARG, recenter putting point on screen line ARG
|
||||
relative to the first window in the selected window group. If ARG is
|
||||
negative, it counts up from the bottom of the last window in the
|
||||
group. (ARG should be less than the total height of the window group.)
|
||||
|
||||
If ARG is omitted or nil, then recenter with point on the middle line of
|
||||
the selected window group; if the variable `recenter-redisplay' is
|
||||
non-nil, also erase the entire frame and redraw it (when
|
||||
`auto-resize-tool-bars' is set to `grow-only', this resets the
|
||||
tool-bar's height to the minimum height needed); if
|
||||
`recenter-redisplay' has the special value `tty', then only tty frames
|
||||
are redrawn.
|
||||
|
||||
Just C-u as prefix means put point in the center of the window
|
||||
and redisplay normally--don't erase and redraw the frame."
|
||||
(if (functionp recenter-window-group-function)
|
||||
(funcall recenter-window-group-function arg)
|
||||
(recenter arg)))
|
||||
|
||||
(defvar pos-visible-in-window-group-p-function nil)
|
||||
(make-variable-buffer-local 'pos-visible-in-window-group-p-function)
|
||||
(put 'pos-visible-in-window-group-p-function 'permanent-local t)
|
||||
(defun pos-visible-in-window-group-p (&optional pos window partially)
|
||||
"Return non-nil if position POS is currently on the frame in the
|
||||
window group containing WINDOW. When a grouping mode (such as Follow
|
||||
Mode) is not active, this function is identical to
|
||||
`pos-visible-in-window-p'.
|
||||
|
||||
WINDOW must be a live window and defaults to the selected one.
|
||||
|
||||
Return nil if that position is scrolled vertically out of view. If a
|
||||
character is only partially visible, nil is returned, unless the
|
||||
optional argument PARTIALLY is non-nil. If POS is only out of view
|
||||
because of horizontal scrolling, return non-nil. If POS is t, it
|
||||
specifies the position of the last visible glyph in the window group.
|
||||
POS defaults to point in WINDOW; WINDOW defaults to the selected
|
||||
window.
|
||||
|
||||
If POS is visible, return t if PARTIALLY is nil; if PARTIALLY is non-nil,
|
||||
the return value is a list of 2 or 6 elements (X Y [RTOP RBOT ROWH VPOS]),
|
||||
where X and Y are the pixel coordinates relative to the top left corner
|
||||
of the window. The remaining elements are omitted if the character after
|
||||
POS is fully visible; otherwise, RTOP and RBOT are the number of pixels
|
||||
off-window at the top and bottom of the screen line (\"row\") containing
|
||||
POS, ROWH is the visible height of that row, and VPOS is the row number
|
||||
\(zero-based)."
|
||||
(if (functionp pos-visible-in-window-group-p-function)
|
||||
(funcall pos-visible-in-window-group-p-function pos window partially)
|
||||
(pos-visible-in-window-p pos window partially)))
|
||||
|
||||
(defvar selected-window-group-function nil)
|
||||
(make-variable-buffer-local 'selected-window-group-function)
|
||||
(put 'selected-window-group-function 'permanent-local t)
|
||||
(defun selected-window-group ()
|
||||
"Return the list of windows in the group containing the selected window.
|
||||
When a grouping mode (such as Follow Mode) is not active, the
|
||||
result is a list containing only the selected window."
|
||||
(if (functionp selected-window-group-function)
|
||||
(funcall selected-window-group-function)
|
||||
(list (selected-window))))
|
||||
|
||||
(defvar move-to-window-group-line-function nil)
|
||||
(make-variable-buffer-local 'move-to-window-group-line-function)
|
||||
(put 'move-to-window-group-line-function 'permanent-local t)
|
||||
(defun move-to-window-group-line (arg)
|
||||
"Position point relative to the the current group of windows.
|
||||
When a grouping mode (such as Follow Mode) is not active, this
|
||||
function is identical to `move-to-window-line'.
|
||||
|
||||
ARG nil means position point at center of the window group.
|
||||
Else, ARG specifies the vertical position within the window
|
||||
group; zero means top of first window in the group, negative
|
||||
means relative to the bottom of the last window in the group."
|
||||
(if (functionp move-to-window-group-line-function)
|
||||
(funcall move-to-window-group-line-function arg)
|
||||
(move-to-window-line arg)))
|
||||
|
||||
|
||||
(defvar recenter-last-op nil
|
||||
"Indicates the last recenter operation performed.
|
||||
|
Loading…
Reference in New Issue
Block a user