unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* Re: Request for enhancement:  Scrolling (etc.) in incremental search.
       [not found] <it1e3b.75.ln@acm.acm>
@ 2003-02-25 16:57 ` Richard Stallman
  2003-02-25 22:37 ` Kim F. Storm
  1 sibling, 0 replies; 12+ messages in thread
From: Richard Stallman @ 2003-02-25 16:57 UTC (permalink / raw)
  Cc: emacs-devel

It looks like your change would mean that all these commands ALWAYS
remain in the search.  That is a big incompatible change, and I have
doubts that I would like it.

Now, having some POSSIBLE way to give these commands
and remain in the search might be ok.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Request for enhancement:  Scrolling (etc.) in incremental search.
       [not found] <it1e3b.75.ln@acm.acm>
  2003-02-25 16:57 ` Richard Stallman
@ 2003-02-25 22:37 ` Kim F. Storm
  2003-02-26 10:57   ` Alan Mackenzie
  1 sibling, 1 reply; 12+ messages in thread
From: Kim F. Storm @ 2003-02-25 22:37 UTC (permalink / raw)


Alan Mackenzie <none@example.invalid> writes:

> PROBLEM:  While searching through a file with incremental search (C-s), I
> often find myself wanting to do things like this:
> 

[...]

> 
> UNFORTUNATELY, as soon as I do any of the above, the search is
> terminated, and I find it more irritating than most people might believe

Except for the prefix arg handling (creeping featurism IMO :-),
you can achieve the same effect by suitable bindings in
isearch-mode-map, e.g.

(define-key isearch-mode-map "\C-l" 'recenter)
(define-key isearch-mode-map [prior] 'scroll-down)
(define-key isearch-mode-map [next] 'scroll-up)

(defvar isearch-control-X-map (make-sparse-keymap))
(define-key isearch-control-X-map "2" 'split-window-vertically)
(define-key isearch-control-X-map "\C-b" 'list-buffers)
(define-key isearch-control-X-map [t] 'isearch-other-control-char)
(define-key isearch-mode-map "\C-x" isearch-control-X-map)


-- 
Kim F. Storm <storm@cua.dk> http://www.cua.dk

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Request for enhancement:  Scrolling (etc.) in incremental search.
  2003-02-25 22:37 ` Kim F. Storm
@ 2003-02-26 10:57   ` Alan Mackenzie
  0 siblings, 0 replies; 12+ messages in thread
From: Alan Mackenzie @ 2003-02-26 10:57 UTC (permalink / raw)
  Cc: emacs-devel



On Tue, 25 Feb 2003, Kim F. Storm wrote:

>Alan Mackenzie <none@example.invalid> writes:

>> UNFORTUNATELY, as soon as I do any of the above, the search is
>> terminated, and I find it more irritating than most people might
>> believe

>Except for the prefix arg handling (creeping featurism IMO :-), you can
>achieve the same effect by suitable bindings in isearch-mode-map, e.g.

>(define-key isearch-mode-map "\C-l" 'recenter)
>(define-key isearch-mode-map [prior] 'scroll-down)
>(define-key isearch-mode-map [next] 'scroll-up)

This way, you don't get the lazy-highlighting after C-l on the parts of
the window that weren't previously visible.  Also scroll-\(up\|down\)
can scroll the current search string at point out of the window.  This
wrenches point away from the current search string, yet still leaves
isearch-mode active.

I think that the prefix arg stuff is a good idea.  Somebody (else) is
going to want to do M-2 <next> to scroll the text up 2 lines.

>Kim F. Storm <storm@cua.dk> http://www.cua.dk

-- 
Alan Mackenzie (Munich, Germany)
acm@muc.de

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Request for enhancement: Scrolling (etc.) in incremental search.
       [not found] <E18kfaI-0007iR-00@fencepost.gnu.org>
@ 2003-02-26 13:36 ` Alan Mackenzie
  2003-03-01  2:26   ` Richard Stallman
  0 siblings, 1 reply; 12+ messages in thread
From: Alan Mackenzie @ 2003-02-26 13:36 UTC (permalink / raw)


On Tue, 25 Feb 2003, Richard Stallman wrote:

> It looks like your change would mean that all these commands ALWAYS
> remain in the search.  That is a big incompatible change, and I have
> doubts that I would like it.

The entire new feature is enabled by a customization switch
(isearch-allow-scroll).  I set it enabled in my patch, but it could
(should?) be disabled by default.

> Now, having some POSSIBLE way to give these commands and remain in the
> search might be ok.

Were you thinking of something like
(define-key isearch-mode-map "\M-s" 'isearch-toggle-scrolling), analogous
to isearch-toggle-case-fold?

Having used this hack for several weeks, I would now find it infuriating
to have to type M-s for each new search started.  I'd want to be able to
customize it such that scrolling would be allowed by default.  In that
case, it might be better for the customization switch to specify the
default setting for "isearch-scrolling-allowed" rather than an absolute
enablement.

-- 
Alan Mackenzie (Munich, Germany)
acm@muc.de

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Request for enhancement: Scrolling (etc.) in incremental search.
  2003-02-26 13:36 ` Alan Mackenzie
@ 2003-03-01  2:26   ` Richard Stallman
  0 siblings, 0 replies; 12+ messages in thread
From: Richard Stallman @ 2003-03-01  2:26 UTC (permalink / raw)
  Cc: emacs-devel

    The entire new feature is enabled by a customization switch
    (isearch-allow-scroll).  I set it enabled in my patch, but it could
    (should?) be disabled by default.

I have no objections to it if it is disabled by default.

    Were you thinking of something like
    (define-key isearch-mode-map "\M-s" 'isearch-toggle-scrolling), analogous
    to isearch-toggle-case-fold?

I don't like the idea of stealing yet another command.
I would just make a user option to turn this on and off.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Request for enhancement: Scrolling (etc.) in incremental search.
@ 2003-10-21 22:03 Alan Mackenzie
  2003-10-22  8:09 ` Alan Mackenzie
  2003-10-23  9:23 ` Richard Stallman
  0 siblings, 2 replies; 12+ messages in thread
From: Alan Mackenzie @ 2003-10-21 22:03 UTC (permalink / raw)


[-- Attachment #1: Type: TEXT/PLAIN, Size: 2776 bytes --]

In February, I submitted a patch to enable scrolling commands to be used
from within isearch mode without aborting the current search.  RMS
responded as follows:

On Sat, 1 Mar 2003, Richard Stallman wrote:

>    The entire new feature is enabled by a customization switch
>    (isearch-allow-scroll).  I set it enabled in my patch, but it could
>    (should?) be disabled by default.
>
>I have no objections to it if it is disabled by default.
>

Here is an (almost) complete version.  To enable this facility, set the
customizable variable isearch-allow-scroll to a non-nil value.  (It is
set to nil by default.)  The enclosed patch to search.texi explains how
it works.

I'm not entirely happy with my documentation patch to search.texi.
Possibly parts of the "Configuring scrolling" page really belong in the
elisp rather than the emacs info pages.  I'm not brilliantly happy at
using the @table command to get a list without separating blank lines.

The only thing which is missing from this set of patch is the setting of
the isearch-scroll property for the pertinent functions.  I think this
would best be done (at least for those which are written in lisp) inside
the files.el where the functions are defined.  I don't know how best to
set the property for the pertinent primitive functions.  Here is a list
of the functions to ease experimentation:

(if (fboundp 'scroll-bar-toolkit-scroll)
    (put 'scroll-bar-toolkit-scroll 'isearch-scroll t))
(if (fboundp 'mac-handle-scroll-bar-event)
    (put 'mac-handle-scroll-bar-event 'isearch-scroll t))
(if (fboundp 'w32-handle-scroll-bar-event)
    (put 'w32-handle-scroll-bar-event 'isearch-scroll t))

(put 'recenter 'isearch-scroll t)       ; Built-in
(put 'reposition-window 'isearch-scroll t) ; reposition.el, autoloaded
(put 'scroll-down 'isearch-scroll t)    ; Built-in
(put 'scroll-up 'isearch-scroll t)      ; Built-in

(put 'beginning-of-buffer-other-window 'isearch-scroll t) ; simple.el
(put 'delete-other-windows 'isearch-scroll t) ; Built-in
(put 'split-window-vertically 'isearch-scroll t) ; window.el
(put 'end-of-buffer-other-window 'isearch-scroll t) ; simple.el
(put 'scroll-other-window 'isearch-scroll t) ; Built-in
(put 'scroll-other-window-down 'isearch-scroll t) ; simple.el
(put 'list-buffers 'isearch-scroll t)   ; buff-menu.el
(put 'enlarge-window 'isearch-scroll t) ; Built-in
(put 'balance-windows 'isearch-scroll t) ; window.el

(put 'universal-argument 'isearch-scroll t) ; simple.el
(put 'negative-argument 'isearch-scroll t) ; simple.el
(put 'digit-argument 'isearch-scroll t) ; simple.el 

I'd appreciate this amendment being considered for installation in Emacs.

I'd appreciate cc's of any followup correspondence.

Thanks in advance.

-- 
Alan Mackenzie (Munich, Germany)
acm@muc.de


[-- Attachment #2: isearch.1.222.acm.el.diff --]
[-- Type: TEXT/PLAIN, Size: 9063 bytes --]

1226a1227,1328
> (defun isearch-unread-key-sequence (keylist)
>   "Unread the given key-sequence KEYLIST, being careful with scroll-bar or
> mode-line events."
>   (cancel-kbd-macro-events)
>   (apply 'isearch-unread keylist)
>   ;; If the event was a scroll-bar or mode-line click, the event will have
>   ;; been prefixed by a symbol such as vertical-scroll-bar.  We must remove
>   ;; it here, because this symbol will be attached to the event again next
>   ;; time it gets read by read-key-sequence.
>   ;;
>   ;; (Old comment from isearch-other-meta-char: "Note that we don't have to
>   ;; modify the event anymore in 21 because read_key_sequence no longer
>   ;; modifies events to produce fake prefix keys.")
>   (if (and (> (length keylist) 1)
>            (symbolp (car keylist))
>            (listp (cadr keylist))
>            (not (numberp (posn-point
>                           (event-start (cadr keylist)  )))))
>       (pop unread-command-events)))
> 
> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
> ;; scrolling within isearch-mode.  Alan Mackenzie (acm@muc.de), 2003/2/24
> ;;
> ;; The idea here is that certain vertical scrolling commands (like C-l
> ;; (recenter)) should be usable WITHIN isearch mode.  For a command to be
> ;; suitable, it must NOT alter the buffer, swap to another buffer or frame,
> ;; tamper with isearch's state, or move point.  It is unacceptable for the
> ;; search string to be scrolled out of the current window.  If a command
> ;; attempts this, we scroll the text back again.
> ;;
> ;; Horizontal scrolling commands are currently not catered for.
> ;;
> ;; We implement this feature with a property called isearch-scroll.  If a
> ;; command's symbol has the value t for this property it is a scrolling
> ;; command.
> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
> 
> (defcustom isearch-allow-scroll nil
>   "If non-nil, certain scrolling commands are allowed during incremental search."
>   :type 'boolean 
>   :group 'isearch)
> 
> (defun isearch-string-out-of-window (isearch-point)
>   "Is the search string currently outside of the window?  Return nil if it's
> completely visible, or if point is visible, together with as much of the
> search string as will fit; 'above if we need to scroll the text downwards;
> '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)))
>         start end)                  ; start and end of search string in buffer
>     (if isearch-forward
>         (setq end isearch-point  start (or isearch-other-end isearch-point))
>       (setq start isearch-point  end (or isearch-other-end isearch-point)))
>     (cond ((or (and (>= start w-start) (<= end w-end))
>                (if isearch-forward
>                    (and (>= isearch-point w-L-1) (< isearch-point w-end)) ; point on Line -1
>                  (and (>= isearch-point w-start) (< isearch-point w-L1)))) ; point on Line 0
>            nil)
>           ((and (< start w-start)
>                 (< isearch-point w-L-1))
>            'above)
>           (t 'below))))
> 
> (defun isearch-back-into-window (above isearch-point)
>   "Scroll the window to bring the search string back into view, restoring
> point to ISEARCH-POINT in the process.  ABOVE is t when the search string is
> above the top of the window, nil when it is beneath the bottom."
>   (let (start end)
>     (if isearch-forward
>         (setq end isearch-point  start (or isearch-other-end isearch-point))
>       (setq start isearch-point  end (or isearch-other-end isearch-point)))
>     (if above
>         (progn
>           (goto-char start)
>           (recenter 0)
>           (when (>= isearch-point (window-end nil t))
>             (goto-char isearch-point)
>             (recenter -1)))
>       (goto-char end)
>       (recenter -1)
>       (when (< isearch-point (window-start))
>         (goto-char isearch-point)
>         (recenter 0))))
>   (goto-char isearch-point))
> 
> (defun isearch-reread-key-sequence-naturally (keylist)
>   "Reread the current key sequence KEYLIST with isearch-mode's own keymap
> deactivated.  Return the key sequence as a string/vector."
>   (isearch-unread-key-sequence keylist)
>   (let (overriding-terminal-local-map)
>     (read-key-sequence nil)))  ; This will go through function-key-map, if nec.
> 
> (defun isearch-lookup-scroll-key (key)
>   "If the supplied key sequence, KEY, is bound to a scrolling command, return
> this command (always a symbol), otherwise nil."
>   (let* ((overriding-terminal-local-map nil)
>          (binding (key-binding key)))
>     (and binding (symbolp binding) (commandp binding)
>          (eq (get binding 'isearch-scroll) t)
>          binding)))
1230,1236c1332,1349
< (defun isearch-other-meta-char ()
<   "Exit the search normally and reread this key sequence.
< But only if `search-exit-option' is non-nil, the default.
< If it is the symbol `edit', the search string is edited in the minibuffer
< and the meta character is unread so that it applies to editing the string."
<   (interactive)
<   (let* ((key (this-command-keys))
---
> (defun isearch-other-meta-char (&optional arg)
>   "See if the current key-sequence can be converted to something usable in
> isearch-mode, either by converting it with the function-key-map, downcasing a
> key with C-<upper case>, or finding a \"scrolling command\" bound to it.  \(In
> the last case, we may have to read more events.\)  If so, either unread the
> converted sequence or execute the command.
> 
> Otherwise, if `search-exit-option' is non-nil (the default) unread the
> key-sequence and exit the search normally.  If it is the symbol `edit', the
> search string is edited in the minibuffer and the meta character is unread so
> that it applies to editing the string.
> 
> ARG is the prefix argument.  It will be transmitted through to the scrolling
> command or to the command which exits isearch-mode."
>   (interactive "P")
>   (let* ((key (if current-prefix-arg    ; not nec the same as ARG
>                   (substring (this-command-keys) universal-argument-num-events)
>                 (this-command-keys)))
1238c1351,1352
< 	 (keylist (listify-key-sequence key)))
---
> 	 (keylist (listify-key-sequence key))
>          scroll-command isearch-point)
1289a1404,1420
>           ;; Handle a scrolling function.
>           ((and isearch-allow-scroll
>                 (progn (setq key (isearch-reread-key-sequence-naturally keylist))
>                        (setq keylist (listify-key-sequence key))
>                        (setq main-event (aref key 0))
>                        (setq scroll-command (isearch-lookup-scroll-key key))))
>            ;; From this point onwards, KEY, KEYLIST and MAIN-EVENT hold a
>            ;; complete key sequence, possibly as modified by function-key-map,
>            ;; not merely the one or two event fragment which invoked
>            ;; isearch-other-meta-char in the first place.
>            (setq isearch-point (point))
>            (setq prefix-arg arg)
>            (command-execute scroll-command)
>            (let ((ab-bel (isearch-string-out-of-window isearch-point)))
>              (if ab-bel
>                  (isearch-back-into-window (eq ab-bel 'above) isearch-point)))
>            (isearch-update))
1292,1306c1423,1424
< 	     (cancel-kbd-macro-events)
< 	     (apply 'isearch-unread keylist)
< 
< 	     ;; Properly handle scroll-bar and mode-line clicks for
< 	     ;; which a dummy prefix event was generated as (aref key
< 	     ;; 0).  Note that we don't have to modify the event
< 	     ;; anymore in 21 because read_key_sequence no longer modifies
< 	     ;; events to produce fake prefix keys.
< 	     (when (and (> (length key) 1)
< 			(symbolp (aref key 0))
< 			(listp (aref key 1))
< 			(not (numberp (posn-point
< 				       (event-start (aref key 1))))))
< 	       (pop unread-command-events)
< 	       (setq main-event (car unread-command-events)))
---
>              (isearch-unread-key-sequence keylist)
>              (setq main-event (car unread-command-events))
1336,1337c1454,1456
< 	       (isearch-clean-overlays))))
< 	  (t;; otherwise nil
---
> 	       (isearch-clean-overlays)
>                (setq prefix-arg arg))))
>           (t;; otherwise nil
1999a2119
> (defvar isearch-lazy-highlight-window-end nil)
2034c2154,2156
<                          isearch-lazy-highlight-window-start))))
---
>                          isearch-lazy-highlight-window-start))
>                  (not (= (window-end)   ; Window may have been split/joined.
>                          isearch-lazy-highlight-window-end))))
2039a2162
>             isearch-lazy-highlight-window-end   (window-end)

[-- Attachment #3: simple.1.621.acm.el.diff --]
[-- Type: TEXT/PLAIN, Size: 4310 bytes --]

*** simple.1.621.el	Sat Oct 11 12:26:50 2003
--- simple.1.621.acm.el	Tue Oct 21 20:23:29 2003
***************
*** 1657,1662 ****
--- 1657,1683 ----
  `universal-argument-other-key' uses this to discard those events
  from (this-command-keys), and reread only the final command.")
  
+ (defvar overriding-map-is-bound nil
+   "Is t when overriding-terminal-local-map is setq'd to
+ universal-argument-map, nil otherwise.")
+ 
+ (defvar saved-overriding-map nil
+   "Holds \(for later restoration\) the previous value of
+ overriding-terminal-local-map whilst \"universal argument mode\" is active.")
+ 
+ (defun ensure-overriding-map-is-bound ()
+   "\"Bind\" overriding-terminal-local-map to universal-argument map, if it
+ isn't already so bound."
+   (unless overriding-map-is-bound
+     (setq saved-overriding-map overriding-terminal-local-map)
+     (setq overriding-terminal-local-map universal-argument-map)
+     (setq overriding-map-is-bound t)))
+ 
+ (defun restore-overriding-map ()
+   "Restore overriding-terminal-local-map to its previous value."
+   (setq overriding-terminal-local-map saved-overriding-map)
+   (setq overriding-map-is-bound nil))
+ 
  (defun universal-argument ()
    "Begin a numeric argument for the following command.
  Digits or minus sign following \\[universal-argument] make up the numeric argument.
***************
*** 1670,1676 ****
    (interactive)
    (setq prefix-arg (list 4))
    (setq universal-argument-num-events (length (this-command-keys)))
!   (setq overriding-terminal-local-map universal-argument-map))
  
  ;; A subsequent C-u means to multiply the factor by 4 if we've typed
  ;; nothing but C-u's; otherwise it means to terminate the prefix arg.
--- 1691,1697 ----
    (interactive)
    (setq prefix-arg (list 4))
    (setq universal-argument-num-events (length (this-command-keys)))
!   (ensure-overriding-map-is-bound))
  
  ;; A subsequent C-u means to multiply the factor by 4 if we've typed
  ;; nothing but C-u's; otherwise it means to terminate the prefix arg.
***************
*** 1681,1687 ****
      (if (eq arg '-)
  	(setq prefix-arg (list -4))
        (setq prefix-arg arg)
!       (setq overriding-terminal-local-map nil)))
    (setq universal-argument-num-events (length (this-command-keys))))
  
  (defun negative-argument (arg)
--- 1702,1708 ----
      (if (eq arg '-)
  	(setq prefix-arg (list -4))
        (setq prefix-arg arg)
!       (restore-overriding-map)))
    (setq universal-argument-num-events (length (this-command-keys))))
  
  (defun negative-argument (arg)
***************
*** 1695,1701 ****
  	(t
  	 (setq prefix-arg '-)))
    (setq universal-argument-num-events (length (this-command-keys)))
!   (setq overriding-terminal-local-map universal-argument-map))
  
  (defun digit-argument (arg)
    "Part of the numeric argument for the next command.
--- 1716,1722 ----
  	(t
  	 (setq prefix-arg '-)))
    (setq universal-argument-num-events (length (this-command-keys)))
!   (ensure-overriding-map-is-bound))
  
  (defun digit-argument (arg)
    "Part of the numeric argument for the next command.
***************
*** 1714,1720 ****
  	  (t
  	   (setq prefix-arg digit))))
    (setq universal-argument-num-events (length (this-command-keys)))
!   (setq overriding-terminal-local-map universal-argument-map))
  
  ;; For backward compatibility, minus with no modifiers is an ordinary
  ;; command if digits have already been entered.
--- 1735,1741 ----
  	  (t
  	   (setq prefix-arg digit))))
    (setq universal-argument-num-events (length (this-command-keys)))
!   (ensure-overriding-map-is-bound))
  
  ;; For backward compatibility, minus with no modifiers is an ordinary
  ;; command if digits have already been entered.
***************
*** 1735,1741 ****
  	  (append (nthcdr universal-argument-num-events keylist)
  		  unread-command-events)))
    (reset-this-command-lengths)
!   (setq overriding-terminal-local-map nil))
  \f
  ;;;; Window system cut and paste hooks.
  
--- 1756,1762 ----
  	  (append (nthcdr universal-argument-num-events keylist)
  		  unread-command-events)))
    (reset-this-command-lengths)
!   (restore-overriding-map))
  \f
  ;;;; Window system cut and paste hooks.
  

[-- Attachment #4: lisp.ChangeLog --]
[-- Type: TEXT/PLAIN, Size: 638 bytes --]

2003-10-21  Alan Mackenzie  <acm@muc.de>

	Add changes to allow scrolling whilst in isearch mode.

	* isearch.el:
	(isearch-unread-key-sequence): New function.
	(isearch-other-meta-char): Doc string and funtionality enhanced.
	(isearch-lazy-highlight-window-end): New variable.
	(isearch-lazy-highlight-new-loop): Minor enhancements.
	
	* simple.el:
	(overriding-map-is-bound, saved-overriding-map): New variables.
	(ensure-overriding-map-is-bound, restore-overriding-map): New
	functions.
	(universal-argument, universal-argument-more, negative-argument,
	digit-argument, universal-argument-other-key): Minor changes.
	

[-- Attachment #5: search.1.40.acm.texi.diff --]
[-- Type: TEXT/PLAIN, Size: 8234 bytes --]

*** search.1.40.texi	Tue Sep 23 21:00:35 2003
--- search.1.40.acm.texi	Tue Oct 21 21:05:11 2003
***************
*** 19,32 ****
  asks interactively which occurrences to replace.
  
  @menu
! * Incremental Search::	   Search happens as you type the string.
! * Nonincremental Search::  Specify entire string and then search.
! * Word Search::		   Search for sequence of words.
! * Regexp Search::	   Search for match for a regexp.
! * Regexps::		   Syntax of regular expressions.
! * Search Case::		   To ignore case while searching, or not.
! * Replace::		   Search, and replace some or all matches.
! * Other Repeating Search:: Operating on all matches for some regexp.
  @end menu
  
  @node Incremental Search, Nonincremental Search, Search, Search
--- 19,33 ----
  asks interactively which occurrences to replace.
  
  @menu
! * Incremental Search::		Search happens as you type the string.
! * Nonincremental Search::	Specify entire string and then search.
! * Word Search::			Search for sequence of words.
! * Regexp Search::		Search for match for a regexp.
! * Regexps::			Syntax of regular expressions.
! * Search Case::			To ignore case while searching, or not.
! * Configuring Scrolling::	Scrolling within incremental search.
! * Replace::			Search, and replace some or all matches.
! * Other Repeating Search::	Operating on all matches for some regexp.
  @end menu
  
  @node Incremental Search, Nonincremental Search, Search, Search
***************
*** 226,231 ****
--- 227,260 ----
  of bindings, look at the documentation of @code{isearch-mode} with
  @kbd{C-h f isearch-mode @key{RET}}.
  
+ @subsection Scrolling During Incremental Search
+ 
+   Vertical scrolling during incremental search can be enabled by
+ setting the customizable variable @code{isearch-allow-scroll} to a
+ non-nil value.
+ 
+   You can then use the vertical scroll-bar or certain keyboard
+ commands such as @kbd{@key{PRIOR}} (@code{scroll-down}),
+ @kbd{@key{NEXT}} (@code{scroll-up}) and @kbd{C-l} (@code{recenter})
+ within the search, thus letting you see more of the text near the
+ current match.  You must run these commands via their key sequences to
+ stay in the search - typing M-x @var{comand-name} will always
+ terminate a search.
+ 
+   You can give prefix arguments to these commands in the usual way.
+ The current match cannot be scrolled out of the window - this is
+ intentional.
+ 
+   Several other commands, such as @kbd{C-x 2}
+ (@code{split-window-vertically}) and @kbd{C-x ^}
+ (@code{enlarge-window}) which don't scroll the window, are
+ nevertheless made available under this rubric, since they are likewise
+ handy during a search.
+ 
+   For a list of commands which are configured as scrolling commands by
+ default and instructions on how thus to configure other commands, see
+ @ref{Configuring Scrolling}.
+ 
  @subsection Slow Terminal Incremental Search
  
    Incremental search on a slow terminal uses a modified style of display
***************
*** 762,768 ****
  for matching parens.)
  @end ignore
  
! @node Search Case, Replace, Regexps, Search
  @section Searching and Case
  
    Incremental searches in Emacs normally ignore the case of the text
--- 791,797 ----
  for matching parens.)
  @end ignore
  
! @node Search Case, Configuring Scrolling, Regexps, Search
  @section Searching and Case
  
    Incremental searches in Emacs normally ignore the case of the text
***************
*** 792,798 ****
  performed by the replace commands (@pxref{Replace}) and the minibuffer
  history matching commands (@pxref{Minibuffer History}).
  
! @node Replace, Other Repeating Search, Search Case, Search
  @section Replacement Commands
  @cindex replacement
  @cindex search-and-replace commands
--- 821,902 ----
  performed by the replace commands (@pxref{Replace}) and the minibuffer
  history matching commands (@pxref{Minibuffer History}).
  
! @node Configuring Scrolling, Replace, Search Case, Search
! @section Configuring Scrolling
! @cindex scrolling in incremental search
! @vindex isearch-allow-scroll
! 
! Scrolling, etc., during incremental search is enabled by setting the
! customizable variable @code{isearch-allow-scroll} to a non-nil value.
! 
! @c See Subject: Info file:  How do I get an itemized list without blank lines?
! @c Date: Sat, 12 Apr 2003 09:45:31 +0000  in gnu.emacs.help
! @subsection Standard scrolling commands
! Here is the list of commands which are configured by default to be
! ``scrolling'' commands in an incremental search, together with their
! usual bindings:
! @subsubsection Commands which scroll the window:
! @table @asis
! @item @code{scroll-bar-toolkit-scroll} (@kbd{@key{vertical-scroll-bar}@key{mouse-1}} in X-Windows)
! @itemx @code{mac-handle-scroll-bar-event} (@kbd{@key{vertical-scroll-bar}@key{mouse-1}} on a Mac)
! @itemx @code{w32-handle-scroll-bar-event} (@kbd{@key{vertical-scroll-bar}@key{mouse-1}} in MS-Windows)
! @item @code{recenter} (@kbd{C-l}) @xref{Scrolling}.
! @itemx @code{reposition-window} (@kbd{C-M-l}) @xref{Scrolling}.
! @itemx @code{scroll-up} (@kbd{@key{NEXT}}) @xref{Scrolling}.
! @itemx @code{scroll-down} (@kbd{@key{PRIOR}}) @xref{Scrolling}.
! @end table
! 
! @subsubsection Commands which act on the other window:
! @table @asis
! @item @code{list-buffers} (@kbd{C-x C-b}) @xref{List Buffers}.
! @itemx @code{scroll-other-window} (@kbd{C-M-v}) @xref{Other Window}.
! @itemx @code{scroll-other-window-down} (@kbd{C-M-S-v}) @xref{Other Window}.
! @itemx @code{beginning-of-buffer-other-window} (@kbd{M-@key{home}})
! @itemx @code{end-of-buffer-other-window} (@kbd{M-@key{end}})
! @end table
! 
! @subsubsection Commands which change the window layout:
! @table @asis
! @item @code{delete-other-windows} (@kbd{C-x 1}) @xref{Change Window}.
! @itemx @code{balance-windows} (@kbd{C-x +}) @xref{Change Window}.
! @itemx @code{split-window-vertically} (@kbd{C-x 2}) @xref{Split Window}.
! @itemx @code{enlarge-window} (@kbd{C-x ^}) @xref{Change Window}.
! @end table
! 
! @subsection Configuring other commands as scrolling commands
! To do this, set a command's isearch-scroll property to the value t.
! For example:
! 
! @example
! @code{(put 'my-command 'isearch-scroll t)}
! @end example
! 
! You should only thus configure commands which are ``safe'': i.e., they
! won't leave emacs in an inconsistent state when executed within a
! search - that is to say, the following things may be changed by a
! command only temporarily, and must be restored before the command
! finishes:
! 
! @enumerate
! @item
! Point.
! @item
! The buffer contents.
! @item
! The selected window and selected frame.
! @item
! The current match-data @xref{Match Data,,,elisp}.
! @end enumerate
! 
! Additionally, the command must not delete the current window and must
! not itself attempt an incremental search.  It may, however, change the
! window's size, or create or delete other windows and frames.
! 
! Note that an attempt by a command to scroll the text
! @emph{horizontally} won't work, although it will do no harm - any such
! scrolling will be overriden and nullified by the display code.
! 
! @node Replace, Other Repeating Search, Configuring Scrolling, Search
  @section Replacement Commands
  @cindex replacement
  @cindex search-and-replace commands
***************
*** 814,823 ****
  (@pxref{Expanding Abbrevs}).
  
  @menu
! * Unconditional Replace::  Replacing all matches for a string.
! * Regexp Replace::         Replacing all matches for a regexp.
! * Replacement and Case::   How replacements preserve case of letters.
! * Query Replace::          How to use querying.
  @end menu
  
  @node Unconditional Replace, Regexp Replace, Replace, Replace
--- 918,927 ----
  (@pxref{Expanding Abbrevs}).
  
  @menu
! * Unconditional Replace::	Replacing all matches for a string.
! * Regexp Replace::		Replacing all matches for a regexp.
! * Replacement and Case::	How replacements preserve case of letters.
! * Query Replace::		How to use querying.
  @end menu
  
  @node Unconditional Replace, Regexp Replace, Replace, Replace

[-- Attachment #6: man.Changelog --]
[-- Type: TEXT/PLAIN, Size: 114 bytes --]

2003-10-21  Alan Mackenzie  <acm@muc.de>

	* search.texi: Document a new scrolling facility in isearch mode.


[-- Attachment #7: Type: text/plain, Size: 141 bytes --]

_______________________________________________
Emacs-devel mailing list
Emacs-devel@gnu.org
http://mail.gnu.org/mailman/listinfo/emacs-devel

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Request for enhancement: Scrolling (etc.) in incremental search.
  2003-10-21 22:03 Request for enhancement: Scrolling (etc.) in incremental search Alan Mackenzie
@ 2003-10-22  8:09 ` Alan Mackenzie
  2003-10-23  9:23 ` Richard Stallman
  1 sibling, 0 replies; 12+ messages in thread
From: Alan Mackenzie @ 2003-10-22  8:09 UTC (permalink / raw)


[-- Attachment #1: Type: TEXT/PLAIN, Size: 588 bytes --]



On Tue, 21 Oct 2003, Alan Mackenzie wrote:

>In February, I submitted a patch to enable scrolling commands to be used
>from within isearch mode without aborting the current search. 
....

>Here is an (almost) complete version.  To enable this facility, set the
>customizable variable isearch-allow-scroll to a non-nil value.  (It is
>set to nil by default.)  The enclosed patch to search.texi explains how
>it works.

Sorry:  One of my patch files, isearch.1.222.acm.el.diff, wasn't in
context format.  It is now.  Here it is again.

>-- 
>Alan Mackenzie (Munich, Germany)
>acm@muc.de


[-- Attachment #2: isearch.1.222.acm.el.diff --]
[-- Type: TEXT/PLAIN, Size: 12317 bytes --]

*** isearch.1.222.el	Tue Sep 23 21:04:28 2003
--- isearch.1.222.acm.el	Tue Oct 21 20:53:36 2003
***************
*** 1224,1241 ****
  	(goto-char isearch-barrier)))
    (isearch-process-search-char last-command-char))
  
  
  (defalias 'isearch-other-control-char 'isearch-other-meta-char)
  
! (defun isearch-other-meta-char ()
!   "Exit the search normally and reread this key sequence.
! But only if `search-exit-option' is non-nil, the default.
! If it is the symbol `edit', the search string is edited in the minibuffer
! and the meta character is unread so that it applies to editing the string."
!   (interactive)
!   (let* ((key (this-command-keys))
  	 (main-event (aref key 0))
! 	 (keylist (listify-key-sequence key)))
      (cond ((and (= (length key) 1)
  		(let ((lookup (lookup-key function-key-map key)))
  		  (not (or (null lookup) (integerp lookup)
--- 1224,1355 ----
  	(goto-char isearch-barrier)))
    (isearch-process-search-char last-command-char))
  
+ (defun isearch-unread-key-sequence (keylist)
+   "Unread the given key-sequence KEYLIST, being careful with scroll-bar or
+ mode-line events."
+   (cancel-kbd-macro-events)
+   (apply 'isearch-unread keylist)
+   ;; If the event was a scroll-bar or mode-line click, the event will have
+   ;; been prefixed by a symbol such as vertical-scroll-bar.  We must remove
+   ;; it here, because this symbol will be attached to the event again next
+   ;; time it gets read by read-key-sequence.
+   ;;
+   ;; (Old comment from isearch-other-meta-char: "Note that we don't have to
+   ;; modify the event anymore in 21 because read_key_sequence no longer
+   ;; modifies events to produce fake prefix keys.")
+   (if (and (> (length keylist) 1)
+            (symbolp (car keylist))
+            (listp (cadr keylist))
+            (not (numberp (posn-point
+                           (event-start (cadr keylist)  )))))
+       (pop unread-command-events)))
+ 
+ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+ ;; scrolling within isearch-mode.  Alan Mackenzie (acm@muc.de), 2003/2/24
+ ;;
+ ;; The idea here is that certain vertical scrolling commands (like C-l
+ ;; (recenter)) should be usable WITHIN isearch mode.  For a command to be
+ ;; suitable, it must NOT alter the buffer, swap to another buffer or frame,
+ ;; tamper with isearch's state, or move point.  It is unacceptable for the
+ ;; search string to be scrolled out of the current window.  If a command
+ ;; attempts this, we scroll the text back again.
+ ;;
+ ;; Horizontal scrolling commands are currently not catered for.
+ ;;
+ ;; We implement this feature with a property called isearch-scroll.  If a
+ ;; command's symbol has the value t for this property it is a scrolling
+ ;; command.
+ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+ 
+ (defcustom isearch-allow-scroll nil
+   "If non-nil, certain scrolling commands are allowed during incremental search."
+   :type 'boolean 
+   :group 'isearch)
+ 
+ (defun isearch-string-out-of-window (isearch-point)
+   "Is the search string currently outside of the window?  Return nil if it's
+ completely visible, or if point is visible, together with as much of the
+ search string as will fit; 'above if we need to scroll the text downwards;
+ '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)))
+         start end)                  ; start and end of search string in buffer
+     (if isearch-forward
+         (setq end isearch-point  start (or isearch-other-end isearch-point))
+       (setq start isearch-point  end (or isearch-other-end isearch-point)))
+     (cond ((or (and (>= start w-start) (<= end w-end))
+                (if isearch-forward
+                    (and (>= isearch-point w-L-1) (< isearch-point w-end)) ; point on Line -1
+                  (and (>= isearch-point w-start) (< isearch-point w-L1)))) ; point on Line 0
+            nil)
+           ((and (< start w-start)
+                 (< isearch-point w-L-1))
+            'above)
+           (t 'below))))
+ 
+ (defun isearch-back-into-window (above isearch-point)
+   "Scroll the window to bring the search string back into view, restoring
+ point to ISEARCH-POINT in the process.  ABOVE is t when the search string is
+ above the top of the window, nil when it is beneath the bottom."
+   (let (start end)
+     (if isearch-forward
+         (setq end isearch-point  start (or isearch-other-end isearch-point))
+       (setq start isearch-point  end (or isearch-other-end isearch-point)))
+     (if above
+         (progn
+           (goto-char start)
+           (recenter 0)
+           (when (>= isearch-point (window-end nil t))
+             (goto-char isearch-point)
+             (recenter -1)))
+       (goto-char end)
+       (recenter -1)
+       (when (< isearch-point (window-start))
+         (goto-char isearch-point)
+         (recenter 0))))
+   (goto-char isearch-point))
+ 
+ (defun isearch-reread-key-sequence-naturally (keylist)
+   "Reread the current key sequence KEYLIST with isearch-mode's own keymap
+ deactivated.  Return the key sequence as a string/vector."
+   (isearch-unread-key-sequence keylist)
+   (let (overriding-terminal-local-map)
+     (read-key-sequence nil)))  ; This will go through function-key-map, if nec.
+ 
+ (defun isearch-lookup-scroll-key (key)
+   "If the supplied key sequence, KEY, is bound to a scrolling command, return
+ this command (always a symbol), otherwise nil."
+   (let* ((overriding-terminal-local-map nil)
+          (binding (key-binding key)))
+     (and binding (symbolp binding) (commandp binding)
+          (eq (get binding 'isearch-scroll) t)
+          binding)))
  
  (defalias 'isearch-other-control-char 'isearch-other-meta-char)
  
! (defun isearch-other-meta-char (&optional arg)
!   "See if the current key-sequence can be converted to something usable in
! isearch-mode, either by converting it with the function-key-map, downcasing a
! key with C-<upper case>, or finding a \"scrolling command\" bound to it.  \(In
! the last case, we may have to read more events.\)  If so, either unread the
! converted sequence or execute the command.
! 
! Otherwise, if `search-exit-option' is non-nil (the default) unread the
! key-sequence and exit the search normally.  If it is the symbol `edit', the
! search string is edited in the minibuffer and the meta character is unread so
! that it applies to editing the string.
! 
! ARG is the prefix argument.  It will be transmitted through to the scrolling
! command or to the command which exits isearch-mode."
!   (interactive "P")
!   (let* ((key (if current-prefix-arg    ; not nec the same as ARG
!                   (substring (this-command-keys) universal-argument-num-events)
!                 (this-command-keys)))
  	 (main-event (aref key 0))
! 	 (keylist (listify-key-sequence key))
!          scroll-command isearch-point)
      (cond ((and (= (length key) 1)
  		(let ((lookup (lookup-key function-key-map key)))
  		  (not (or (null lookup) (integerp lookup)
***************
*** 1287,1309 ****
  	  ((eq search-exit-option 'edit)
  	   (apply 'isearch-unread keylist)
  	   (isearch-edit-string))
  	  (search-exit-option
  	   (let (window)
! 	     (cancel-kbd-macro-events)
! 	     (apply 'isearch-unread keylist)
! 
! 	     ;; Properly handle scroll-bar and mode-line clicks for
! 	     ;; which a dummy prefix event was generated as (aref key
! 	     ;; 0).  Note that we don't have to modify the event
! 	     ;; anymore in 21 because read_key_sequence no longer modifies
! 	     ;; events to produce fake prefix keys.
! 	     (when (and (> (length key) 1)
! 			(symbolp (aref key 0))
! 			(listp (aref key 1))
! 			(not (numberp (posn-point
! 				       (event-start (aref key 1))))))
! 	       (pop unread-command-events)
! 	       (setq main-event (car unread-command-events)))
  
  	     ;; If we got a mouse click event, that event contains the
  	     ;; window clicked on. maybe it was read with the buffer
--- 1401,1427 ----
  	  ((eq search-exit-option 'edit)
  	   (apply 'isearch-unread keylist)
  	   (isearch-edit-string))
+           ;; Handle a scrolling function.
+           ((and isearch-allow-scroll
+                 (progn (setq key (isearch-reread-key-sequence-naturally keylist))
+                        (setq keylist (listify-key-sequence key))
+                        (setq main-event (aref key 0))
+                        (setq scroll-command (isearch-lookup-scroll-key key))))
+            ;; From this point onwards, KEY, KEYLIST and MAIN-EVENT hold a
+            ;; complete key sequence, possibly as modified by function-key-map,
+            ;; not merely the one or two event fragment which invoked
+            ;; isearch-other-meta-char in the first place.
+            (setq isearch-point (point))
+            (setq prefix-arg arg)
+            (command-execute scroll-command)
+            (let ((ab-bel (isearch-string-out-of-window isearch-point)))
+              (if ab-bel
+                  (isearch-back-into-window (eq ab-bel 'above) isearch-point)))
+            (isearch-update))
  	  (search-exit-option
  	   (let (window)
!              (isearch-unread-key-sequence keylist)
!              (setq main-event (car unread-command-events))
  
  	     ;; If we got a mouse click event, that event contains the
  	     ;; window clicked on. maybe it was read with the buffer
***************
*** 1333,1340 ****
  		   (isearch-done)
  		   (isearch-clean-overlays))
  	       (isearch-done)
! 	       (isearch-clean-overlays))))
! 	  (t;; otherwise nil
  	   (isearch-process-search-string key key)))))
  
  (defun isearch-quote-char ()
--- 1451,1459 ----
  		   (isearch-done)
  		   (isearch-clean-overlays))
  	       (isearch-done)
! 	       (isearch-clean-overlays)
!                (setq prefix-arg arg))))
!           (t;; otherwise nil
  	   (isearch-process-search-string key key)))))
  
  (defun isearch-quote-char ()
***************
*** 1997,2002 ****
--- 2116,2122 ----
  (defvar isearch-lazy-highlight-last-string nil)
  (defvar isearch-lazy-highlight-window nil)
  (defvar isearch-lazy-highlight-window-start nil)
+ (defvar isearch-lazy-highlight-window-end nil)
  (defvar isearch-lazy-highlight-case-fold-search nil)
  (defvar isearch-lazy-highlight-regexp nil)
  
***************
*** 2031,2042 ****
  		 (not (eq isearch-lazy-highlight-regexp
  			  isearch-regexp))
                   (not (= (window-start)
!                          isearch-lazy-highlight-window-start))))
      ;; something important did indeed change
      (isearch-lazy-highlight-cleanup t) ;kill old loop & remove overlays
      (when (not isearch-invalid-regexp)
        (setq isearch-lazy-highlight-window       (selected-window)
              isearch-lazy-highlight-window-start (window-start)
              isearch-lazy-highlight-start        (point)
              isearch-lazy-highlight-end          (point)
              isearch-lazy-highlight-last-string  isearch-string
--- 2151,2165 ----
  		 (not (eq isearch-lazy-highlight-regexp
  			  isearch-regexp))
                   (not (= (window-start)
!                          isearch-lazy-highlight-window-start))
!                  (not (= (window-end)   ; Window may have been split/joined.
!                          isearch-lazy-highlight-window-end))))
      ;; something important did indeed change
      (isearch-lazy-highlight-cleanup t) ;kill old loop & remove overlays
      (when (not isearch-invalid-regexp)
        (setq isearch-lazy-highlight-window       (selected-window)
              isearch-lazy-highlight-window-start (window-start)
+             isearch-lazy-highlight-window-end   (window-end)
              isearch-lazy-highlight-start        (point)
              isearch-lazy-highlight-end          (point)
              isearch-lazy-highlight-last-string  isearch-string

[-- Attachment #3: Type: text/plain, Size: 141 bytes --]

_______________________________________________
Emacs-devel mailing list
Emacs-devel@gnu.org
http://mail.gnu.org/mailman/listinfo/emacs-devel

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Request for enhancement: Scrolling (etc.) in incremental search.
  2003-10-21 22:03 Request for enhancement: Scrolling (etc.) in incremental search Alan Mackenzie
  2003-10-22  8:09 ` Alan Mackenzie
@ 2003-10-23  9:23 ` Richard Stallman
  2003-10-23 21:48   ` Alan Mackenzie
  1 sibling, 1 reply; 12+ messages in thread
From: Richard Stallman @ 2003-10-23  9:23 UTC (permalink / raw)
  Cc: emacs-devel

as long as it is disabled by default, i don't object.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Request for enhancement: Scrolling (etc.) in incremental search.
  2003-10-23  9:23 ` Richard Stallman
@ 2003-10-23 21:48   ` Alan Mackenzie
  2003-10-24 23:24     ` Richard Stallman
  2003-11-10  6:49     ` Juri Linkov
  0 siblings, 2 replies; 12+ messages in thread
From: Alan Mackenzie @ 2003-10-23 21:48 UTC (permalink / raw)


[-- Attachment #1: Type: TEXT/PLAIN, Size: 2239 bytes --]



On Thu, 23 Oct 2003, Richard Stallman wrote:

>as long as it is disabled by default, i don't object.
>

Here is my patch amended so that the doc-strings conform to Emacs
standards.

Is this complete repetition the least painful way to submit such a "patch
to a patch" or would it be prefered to submit literally a "patch to a
patch", saving bandwidth at the cost of convenience?

[A quick reminder of what this is for:  it lets you scroll the window
during incremental search, so that you can see more of what's around
point without leaving the search.  I've been using it for months, and
wouldn't want to be without it now.  :-]

I've put the `put' forms for the universal argument functions directly
into their sources in simple.el.  So here is an amended list to go into
a .emacs file for experimentation:

*************************************************************************
(setq isearch-allow-scroll t)

(if (fboundp 'scroll-bar-toolkit-scroll)
    (put 'scroll-bar-toolkit-scroll 'isearch-scroll t))
(if (fboundp 'mac-handle-scroll-bar-event)
    (put 'mac-handle-scroll-bar-event 'isearch-scroll t))
(if (fboundp 'w32-handle-scroll-bar-event)
    (put 'w32-handle-scroll-bar-event 'isearch-scroll t))

(put 'recenter 'isearch-scroll t)       ; Built-in
(put 'reposition-window 'isearch-scroll t) ; reposition.el, autoloaded
(put 'scroll-down 'isearch-scroll t)    ; Built-in
(put 'scroll-up 'isearch-scroll t)      ; Built-in

(put 'beginning-of-buffer-other-window 'isearch-scroll t) ; simple.el
(put 'delete-other-windows 'isearch-scroll t) ; Built-in
(put 'split-window-vertically 'isearch-scroll t) ; window.el
(put 'end-of-buffer-other-window 'isearch-scroll t) ; simple.el
(put 'scroll-other-window 'isearch-scroll t) ; Built-in
(put 'scroll-other-window-down 'isearch-scroll t) ; simple.el
(put 'list-buffers 'isearch-scroll t)   ; buff-menu.el
(put 'enlarge-window 'isearch-scroll t) ; Built-in
(put 'balance-windows 'isearch-scroll t) ; window.el
*************************************************************************

If this patch is to find its way into Emacs, I'll also need to patch
window.el etc. with these forms.

cc's of followups would be appreciated.

-- 
Alan Mackenzie (Munich, Germany)
acm@muc.de


[-- Attachment #2: isearch.1.222.acm.el.diff --]
[-- Type: TEXT/PLAIN, Size: 13600 bytes --]

*** isearch.1.222.el	Tue Sep 23 21:04:28 2003
--- isearch.1.222.acm.el	Thu Oct 23 20:58:21 2003
***************
*** 242,248 ****
        (while l
  	(set-char-table-default table (car l) 'isearch-printing-char)
  	(setq l (cdr l))))
!     ;; Make function keys, etc, exit the search.
      (define-key map [t] 'isearch-other-control-char)
      ;; Control chars, by default, end isearch mode transparently.
      ;; We need these explicit definitions because, in a dense keymap,
--- 242,249 ----
        (while l
  	(set-char-table-default table (car l) 'isearch-printing-char)
  	(setq l (cdr l))))
!     ;; Make function keys, etc, which aren't bound to a scrolling-function
!     ;; exit the search.
      (define-key map [t] 'isearch-other-control-char)
      ;; Control chars, by default, end isearch mode transparently.
      ;; We need these explicit definitions because, in a dense keymap,
***************
*** 1224,1241 ****
  	(goto-char isearch-barrier)))
    (isearch-process-search-char last-command-char))
  
  
  (defalias 'isearch-other-control-char 'isearch-other-meta-char)
  
! (defun isearch-other-meta-char ()
!   "Exit the search normally and reread this key sequence.
! But only if `search-exit-option' is non-nil, the default.
! If it is the symbol `edit', the search string is edited in the minibuffer
! and the meta character is unread so that it applies to editing the string."
!   (interactive)
!   (let* ((key (this-command-keys))
  	 (main-event (aref key 0))
! 	 (keylist (listify-key-sequence key)))
      (cond ((and (= (length key) 1)
  		(let ((lookup (lookup-key function-key-map key)))
  		  (not (or (null lookup) (integerp lookup)
--- 1225,1367 ----
  	(goto-char isearch-barrier)))
    (isearch-process-search-char last-command-char))
  
+ (defun isearch-unread-key-sequence (keylist)
+   "Unread the given key-sequence KEYLIST.
+ Scroll-bar or mode-line events are processed appropriately."
+   (cancel-kbd-macro-events)
+   (apply 'isearch-unread keylist)
+   ;; If the event was a scroll-bar or mode-line click, the event will have
+   ;; been prefixed by a symbol such as vertical-scroll-bar.  We must remove
+   ;; it here, because this symbol will be attached to the event again next
+   ;; time it gets read by read-key-sequence.
+   ;;
+   ;; (Old comment from isearch-other-meta-char: "Note that we don't have to
+   ;; modify the event anymore in 21 because read_key_sequence no longer
+   ;; modifies events to produce fake prefix keys.")
+   (if (and (> (length keylist) 1)
+            (symbolp (car keylist))
+            (listp (cadr keylist))
+            (not (numberp (posn-point
+                           (event-start (cadr keylist)  )))))
+       (pop unread-command-events)))
+ 
+ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+ ;; scrolling within Isearch mode.  Alan Mackenzie (acm@muc.de), 2003/2/24
+ ;;
+ ;; The idea here is that certain vertical scrolling commands (like C-l
+ ;; `recenter') should be usable WITHIN Isearch mode.  For a command to be
+ ;; suitable, it must NOT alter the buffer, swap to another buffer or frame,
+ ;; tamper with isearch's state, or move point.  It is unacceptable for the
+ ;; search string to be scrolled out of the current window.  If a command
+ ;; attempts this, we scroll the text back again.
+ ;;
+ ;; We implement this feature with a property called `isearch-scroll'.
+ ;; If a command's symbol has the value t for this property it is a
+ ;; scrolling command.  The feature needs to be enabled by setting the
+ ;; customizable variable `isearch-allow-scroll' to a non-nil value.
+ ;;
+ ;; The universal argument commands (e.g. C-u) in simple.el are marked
+ ;; as scrolling commands, and isearch.el has been amended to allow
+ ;; prefix arguments to be passed through to scrolling commands.  Thus
+ ;; M-0 C-l will scroll point to the top of the window.
+ ;;
+ ;; Horizontal scrolling commands are currently not catered for.
+ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+ 
+ (defcustom isearch-allow-scroll nil
+   "If non-nil, scrolling commands are allowed during incremental search."
+   :type 'boolean
+   :group 'isearch)
+ 
+ (defun isearch-string-out-of-window (isearch-point)
+   "Test whether the search string is currently outside of the window.
+ 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)))
+         start end)                  ; start and end of search string in buffer
+     (if isearch-forward
+         (setq end isearch-point  start (or isearch-other-end isearch-point))
+       (setq start isearch-point  end (or isearch-other-end isearch-point)))
+     (cond ((or (and (>= start w-start) (<= end w-end))
+                (if isearch-forward
+                    (and (>= isearch-point w-L-1) (< isearch-point w-end)) ; point on Line -1
+                  (and (>= isearch-point w-start) (< isearch-point w-L1)))) ; point on Line 0
+            nil)
+           ((and (< start w-start)
+                 (< isearch-point w-L-1))
+            'above)
+           (t 'below))))
+ 
+ (defun isearch-back-into-window (above isearch-point)
+   "Scroll the window to bring the search string back into view.
+ Restore point to ISEARCH-POINT in the process.  ABOVE is t when the
+ search string is above the top of the window, nil when it is beneath
+ the bottom."
+   (let (start end)
+     (if isearch-forward
+         (setq end isearch-point  start (or isearch-other-end isearch-point))
+       (setq start isearch-point  end (or isearch-other-end isearch-point)))
+     (if above
+         (progn
+           (goto-char start)
+           (recenter 0)
+           (when (>= isearch-point (window-end nil t))
+             (goto-char isearch-point)
+             (recenter -1)))
+       (goto-char end)
+       (recenter -1)
+       (when (< isearch-point (window-start))
+         (goto-char isearch-point)
+         (recenter 0))))
+   (goto-char isearch-point))
+ 
+ (defun isearch-reread-key-sequence-naturally (keylist)
+   "Reread key sequence KEYLIST with Isearch mode's keymap deactivated.
+ Return the key sequence as a string/vector."
+   (isearch-unread-key-sequence keylist)
+   (let (overriding-terminal-local-map)
+     (read-key-sequence nil)))  ; This will go through function-key-map, if nec.
+ 
+ (defun isearch-lookup-scroll-key (key-seq)
+   "If KEY-SEQ is bound to a scrolling command, return it as a symbol.
+ Otherwise return nil."
+   (let* ((overriding-terminal-local-map nil)
+          (binding (key-binding key-seq)))
+     (and binding (symbolp binding) (commandp binding)
+          (eq (get binding 'isearch-scroll) t)
+          binding)))
  
  (defalias 'isearch-other-control-char 'isearch-other-meta-char)
  
! (defun isearch-other-meta-char (&optional arg)
!   "Process a miscellaneous key sequence in Isearch mode.
! 
! Try to convert the current key-sequence to something usable in Isearch
! mode, either by converting it with `function-key-map', downcasing a
! key with C-<upper case>, or finding a \"scrolling command\" bound to
! it.  \(In the last case, we may have to read more events.)  If so,
! either unread the converted sequence or execute the command.
! 
! Otherwise, if `search-exit-option' is non-nil (the default) unread the
! key-sequence and exit the search normally.  If it is the symbol
! `edit', the search string is edited in the minibuffer and the meta
! character is unread so that it applies to editing the string.
! 
! ARG is the prefix argument.  It will be transmitted through to the
! scrolling command or to the command whose key-sequence exits
! Isearch mode."
!   (interactive "P")
!   (let* ((key (if current-prefix-arg    ; not nec the same as ARG
!                   (substring (this-command-keys) universal-argument-num-events)
!                 (this-command-keys)))
  	 (main-event (aref key 0))
! 	 (keylist (listify-key-sequence key))
!          scroll-command isearch-point)
      (cond ((and (= (length key) 1)
  		(let ((lookup (lookup-key function-key-map key)))
  		  (not (or (null lookup) (integerp lookup)
***************
*** 1287,1309 ****
  	  ((eq search-exit-option 'edit)
  	   (apply 'isearch-unread keylist)
  	   (isearch-edit-string))
  	  (search-exit-option
  	   (let (window)
! 	     (cancel-kbd-macro-events)
! 	     (apply 'isearch-unread keylist)
! 
! 	     ;; Properly handle scroll-bar and mode-line clicks for
! 	     ;; which a dummy prefix event was generated as (aref key
! 	     ;; 0).  Note that we don't have to modify the event
! 	     ;; anymore in 21 because read_key_sequence no longer modifies
! 	     ;; events to produce fake prefix keys.
! 	     (when (and (> (length key) 1)
! 			(symbolp (aref key 0))
! 			(listp (aref key 1))
! 			(not (numberp (posn-point
! 				       (event-start (aref key 1))))))
! 	       (pop unread-command-events)
! 	       (setq main-event (car unread-command-events)))
  
  	     ;; If we got a mouse click event, that event contains the
  	     ;; window clicked on. maybe it was read with the buffer
--- 1413,1439 ----
  	  ((eq search-exit-option 'edit)
  	   (apply 'isearch-unread keylist)
  	   (isearch-edit-string))
+           ;; Handle a scrolling function.
+           ((and isearch-allow-scroll
+                 (progn (setq key (isearch-reread-key-sequence-naturally keylist))
+                        (setq keylist (listify-key-sequence key))
+                        (setq main-event (aref key 0))
+                        (setq scroll-command (isearch-lookup-scroll-key key))))
+            ;; From this point onwards, KEY, KEYLIST and MAIN-EVENT hold a
+            ;; complete key sequence, possibly as modified by function-key-map,
+            ;; not merely the one or two event fragment which invoked
+            ;; isearch-other-meta-char in the first place.
+            (setq isearch-point (point))
+            (setq prefix-arg arg)
+            (command-execute scroll-command)
+            (let ((ab-bel (isearch-string-out-of-window isearch-point)))
+              (if ab-bel
+                  (isearch-back-into-window (eq ab-bel 'above) isearch-point)))
+            (isearch-update))
  	  (search-exit-option
  	   (let (window)
!              (isearch-unread-key-sequence keylist)
!              (setq main-event (car unread-command-events))
  
  	     ;; If we got a mouse click event, that event contains the
  	     ;; window clicked on. maybe it was read with the buffer
***************
*** 1333,1340 ****
  		   (isearch-done)
  		   (isearch-clean-overlays))
  	       (isearch-done)
! 	       (isearch-clean-overlays))))
! 	  (t;; otherwise nil
  	   (isearch-process-search-string key key)))))
  
  (defun isearch-quote-char ()
--- 1463,1471 ----
  		   (isearch-done)
  		   (isearch-clean-overlays))
  	       (isearch-done)
! 	       (isearch-clean-overlays)
!                (setq prefix-arg arg))))
!           (t;; otherwise nil
  	   (isearch-process-search-string key key)))))
  
  (defun isearch-quote-char ()
***************
*** 1997,2002 ****
--- 2128,2134 ----
  (defvar isearch-lazy-highlight-last-string nil)
  (defvar isearch-lazy-highlight-window nil)
  (defvar isearch-lazy-highlight-window-start nil)
+ (defvar isearch-lazy-highlight-window-end nil)
  (defvar isearch-lazy-highlight-case-fold-search nil)
  (defvar isearch-lazy-highlight-regexp nil)
  
***************
*** 2031,2042 ****
  		 (not (eq isearch-lazy-highlight-regexp
  			  isearch-regexp))
                   (not (= (window-start)
!                          isearch-lazy-highlight-window-start))))
      ;; something important did indeed change
      (isearch-lazy-highlight-cleanup t) ;kill old loop & remove overlays
      (when (not isearch-invalid-regexp)
        (setq isearch-lazy-highlight-window       (selected-window)
              isearch-lazy-highlight-window-start (window-start)
              isearch-lazy-highlight-start        (point)
              isearch-lazy-highlight-end          (point)
              isearch-lazy-highlight-last-string  isearch-string
--- 2163,2177 ----
  		 (not (eq isearch-lazy-highlight-regexp
  			  isearch-regexp))
                   (not (= (window-start)
!                          isearch-lazy-highlight-window-start))
!                  (not (= (window-end)   ; Window may have been split/joined.
!                          isearch-lazy-highlight-window-end))))
      ;; something important did indeed change
      (isearch-lazy-highlight-cleanup t) ;kill old loop & remove overlays
      (when (not isearch-invalid-regexp)
        (setq isearch-lazy-highlight-window       (selected-window)
              isearch-lazy-highlight-window-start (window-start)
+             isearch-lazy-highlight-window-end   (window-end)
              isearch-lazy-highlight-start        (point)
              isearch-lazy-highlight-end          (point)
              isearch-lazy-highlight-last-string  isearch-string

[-- Attachment #3: simple.1.621.acm.el.diff --]
[-- Type: TEXT/PLAIN, Size: 5074 bytes --]

*** simple.1.621.el	Sat Oct 11 12:26:50 2003
--- simple.1.621.acm.el	Thu Oct 23 20:26:20 2003
***************
*** 1657,1662 ****
--- 1657,1682 ----
  `universal-argument-other-key' uses this to discard those events
  from (this-command-keys), and reread only the final command.")
  
+ (defvar overriding-map-is-bound nil
+   "Non-nil when `overriding-terminal-local-map' is `universal-argument-map'.")
+ 
+ (defvar saved-overriding-map nil
+   "The saved value of `overriding-terminal-local-map'.
+ That variable gets restored to this value on exiting \"universal
+ argument mode\".")
+ 
+ (defun ensure-overriding-map-is-bound ()
+   "Check `overriding-terminal-local-map' is `universal-argument-map'."
+   (unless overriding-map-is-bound
+     (setq saved-overriding-map overriding-terminal-local-map)
+     (setq overriding-terminal-local-map universal-argument-map)
+     (setq overriding-map-is-bound t)))
+ 
+ (defun restore-overriding-map ()
+   "Restore `overriding-terminal-local-map' to its saved value."
+   (setq overriding-terminal-local-map saved-overriding-map)
+   (setq overriding-map-is-bound nil))
+ 
  (defun universal-argument ()
    "Begin a numeric argument for the following command.
  Digits or minus sign following \\[universal-argument] make up the numeric argument.
***************
*** 1670,1676 ****
    (interactive)
    (setq prefix-arg (list 4))
    (setq universal-argument-num-events (length (this-command-keys)))
!   (setq overriding-terminal-local-map universal-argument-map))
  
  ;; A subsequent C-u means to multiply the factor by 4 if we've typed
  ;; nothing but C-u's; otherwise it means to terminate the prefix arg.
--- 1690,1697 ----
    (interactive)
    (setq prefix-arg (list 4))
    (setq universal-argument-num-events (length (this-command-keys)))
!   (ensure-overriding-map-is-bound))
! (put 'universal-argument 'isearch-scroll t)
  
  ;; A subsequent C-u means to multiply the factor by 4 if we've typed
  ;; nothing but C-u's; otherwise it means to terminate the prefix arg.
***************
*** 1681,1687 ****
      (if (eq arg '-)
  	(setq prefix-arg (list -4))
        (setq prefix-arg arg)
!       (setq overriding-terminal-local-map nil)))
    (setq universal-argument-num-events (length (this-command-keys))))
  
  (defun negative-argument (arg)
--- 1702,1708 ----
      (if (eq arg '-)
  	(setq prefix-arg (list -4))
        (setq prefix-arg arg)
!       (restore-overriding-map)))
    (setq universal-argument-num-events (length (this-command-keys))))
  
  (defun negative-argument (arg)
***************
*** 1695,1701 ****
  	(t
  	 (setq prefix-arg '-)))
    (setq universal-argument-num-events (length (this-command-keys)))
!   (setq overriding-terminal-local-map universal-argument-map))
  
  (defun digit-argument (arg)
    "Part of the numeric argument for the next command.
--- 1716,1723 ----
  	(t
  	 (setq prefix-arg '-)))
    (setq universal-argument-num-events (length (this-command-keys)))
!   (ensure-overriding-map-is-bound))
! (put 'negative-argument 'isearch-scroll t)
  
  (defun digit-argument (arg)
    "Part of the numeric argument for the next command.
***************
*** 1714,1720 ****
  	  (t
  	   (setq prefix-arg digit))))
    (setq universal-argument-num-events (length (this-command-keys)))
!   (setq overriding-terminal-local-map universal-argument-map))
  
  ;; For backward compatibility, minus with no modifiers is an ordinary
  ;; command if digits have already been entered.
--- 1736,1743 ----
  	  (t
  	   (setq prefix-arg digit))))
    (setq universal-argument-num-events (length (this-command-keys)))
!   (ensure-overriding-map-is-bound))
! (put 'digit-argument 'isearch-scroll t)
  
  ;; For backward compatibility, minus with no modifiers is an ordinary
  ;; command if digits have already been entered.
***************
*** 1735,1741 ****
  	  (append (nthcdr universal-argument-num-events keylist)
  		  unread-command-events)))
    (reset-this-command-lengths)
!   (setq overriding-terminal-local-map nil))
  \f
  ;;;; Window system cut and paste hooks.
  
--- 1758,1764 ----
  	  (append (nthcdr universal-argument-num-events keylist)
  		  unread-command-events)))
    (reset-this-command-lengths)
!   (restore-overriding-map))
  \f
  ;;;; Window system cut and paste hooks.
  
***************
*** 3348,3354 ****
        (setq arg (current-column)))
    (if (not (integerp arg))
        ;; Disallow missing argument; it's probably a typo for C-x C-f.
!       (error "set-fill-column requires an explicit argument")
      (message "Fill column set to %d (was %d)" arg fill-column)
      (setq fill-column arg)))
  \f
--- 3371,3377 ----
        (setq arg (current-column)))
    (if (not (integerp arg))
        ;; Disallow missing argument; it's probably a typo for C-x C-f.
!       (error "Set-fill-column requires an explicit argument")
      (message "Fill column set to %d (was %d)" arg fill-column)
      (setq fill-column arg)))
  \f

[-- Attachment #4: Lisp.ChangeLog --]
[-- Type: TEXT/PLAIN, Size: 681 bytes --]

2003-10-23  Alan Mackenzie  <acm@muc.de>

	Add changes to allow scrolling whilst in isearch mode.

	* isearch.el:
	(isearch-unread-key-sequence): New function, extracted from
	isearch-other-meta-char.
	(isearch-other-meta-char): Doc string and functionality enhanced.
	(isearch-lazy-highlight-window-end): New variable.
	(isearch-lazy-highlight-new-loop): Minor enhancements.
	
	* simple.el:
	(overriding-map-is-bound, saved-overriding-map): New variables.
	(ensure-overriding-map-is-bound, restore-overriding-map): New
	functions.
	(universal-argument, universal-argument-more, negative-argument,
	digit-argument, universal-argument-other-key): Minor changes.
	

[-- Attachment #5: search.1.40.acm.texi.diff --]
[-- Type: TEXT/PLAIN, Size: 8234 bytes --]

*** search.1.40.texi	Tue Sep 23 21:00:35 2003
--- search.1.40.acm.texi	Tue Oct 21 21:05:11 2003
***************
*** 19,32 ****
  asks interactively which occurrences to replace.
  
  @menu
! * Incremental Search::	   Search happens as you type the string.
! * Nonincremental Search::  Specify entire string and then search.
! * Word Search::		   Search for sequence of words.
! * Regexp Search::	   Search for match for a regexp.
! * Regexps::		   Syntax of regular expressions.
! * Search Case::		   To ignore case while searching, or not.
! * Replace::		   Search, and replace some or all matches.
! * Other Repeating Search:: Operating on all matches for some regexp.
  @end menu
  
  @node Incremental Search, Nonincremental Search, Search, Search
--- 19,33 ----
  asks interactively which occurrences to replace.
  
  @menu
! * Incremental Search::		Search happens as you type the string.
! * Nonincremental Search::	Specify entire string and then search.
! * Word Search::			Search for sequence of words.
! * Regexp Search::		Search for match for a regexp.
! * Regexps::			Syntax of regular expressions.
! * Search Case::			To ignore case while searching, or not.
! * Configuring Scrolling::	Scrolling within incremental search.
! * Replace::			Search, and replace some or all matches.
! * Other Repeating Search::	Operating on all matches for some regexp.
  @end menu
  
  @node Incremental Search, Nonincremental Search, Search, Search
***************
*** 226,231 ****
--- 227,260 ----
  of bindings, look at the documentation of @code{isearch-mode} with
  @kbd{C-h f isearch-mode @key{RET}}.
  
+ @subsection Scrolling During Incremental Search
+ 
+   Vertical scrolling during incremental search can be enabled by
+ setting the customizable variable @code{isearch-allow-scroll} to a
+ non-nil value.
+ 
+   You can then use the vertical scroll-bar or certain keyboard
+ commands such as @kbd{@key{PRIOR}} (@code{scroll-down}),
+ @kbd{@key{NEXT}} (@code{scroll-up}) and @kbd{C-l} (@code{recenter})
+ within the search, thus letting you see more of the text near the
+ current match.  You must run these commands via their key sequences to
+ stay in the search - typing M-x @var{comand-name} will always
+ terminate a search.
+ 
+   You can give prefix arguments to these commands in the usual way.
+ The current match cannot be scrolled out of the window - this is
+ intentional.
+ 
+   Several other commands, such as @kbd{C-x 2}
+ (@code{split-window-vertically}) and @kbd{C-x ^}
+ (@code{enlarge-window}) which don't scroll the window, are
+ nevertheless made available under this rubric, since they are likewise
+ handy during a search.
+ 
+   For a list of commands which are configured as scrolling commands by
+ default and instructions on how thus to configure other commands, see
+ @ref{Configuring Scrolling}.
+ 
  @subsection Slow Terminal Incremental Search
  
    Incremental search on a slow terminal uses a modified style of display
***************
*** 762,768 ****
  for matching parens.)
  @end ignore
  
! @node Search Case, Replace, Regexps, Search
  @section Searching and Case
  
    Incremental searches in Emacs normally ignore the case of the text
--- 791,797 ----
  for matching parens.)
  @end ignore
  
! @node Search Case, Configuring Scrolling, Regexps, Search
  @section Searching and Case
  
    Incremental searches in Emacs normally ignore the case of the text
***************
*** 792,798 ****
  performed by the replace commands (@pxref{Replace}) and the minibuffer
  history matching commands (@pxref{Minibuffer History}).
  
! @node Replace, Other Repeating Search, Search Case, Search
  @section Replacement Commands
  @cindex replacement
  @cindex search-and-replace commands
--- 821,902 ----
  performed by the replace commands (@pxref{Replace}) and the minibuffer
  history matching commands (@pxref{Minibuffer History}).
  
! @node Configuring Scrolling, Replace, Search Case, Search
! @section Configuring Scrolling
! @cindex scrolling in incremental search
! @vindex isearch-allow-scroll
! 
! Scrolling, etc., during incremental search is enabled by setting the
! customizable variable @code{isearch-allow-scroll} to a non-nil value.
! 
! @c See Subject: Info file:  How do I get an itemized list without blank lines?
! @c Date: Sat, 12 Apr 2003 09:45:31 +0000  in gnu.emacs.help
! @subsection Standard scrolling commands
! Here is the list of commands which are configured by default to be
! ``scrolling'' commands in an incremental search, together with their
! usual bindings:
! @subsubsection Commands which scroll the window:
! @table @asis
! @item @code{scroll-bar-toolkit-scroll} (@kbd{@key{vertical-scroll-bar}@key{mouse-1}} in X-Windows)
! @itemx @code{mac-handle-scroll-bar-event} (@kbd{@key{vertical-scroll-bar}@key{mouse-1}} on a Mac)
! @itemx @code{w32-handle-scroll-bar-event} (@kbd{@key{vertical-scroll-bar}@key{mouse-1}} in MS-Windows)
! @item @code{recenter} (@kbd{C-l}) @xref{Scrolling}.
! @itemx @code{reposition-window} (@kbd{C-M-l}) @xref{Scrolling}.
! @itemx @code{scroll-up} (@kbd{@key{NEXT}}) @xref{Scrolling}.
! @itemx @code{scroll-down} (@kbd{@key{PRIOR}}) @xref{Scrolling}.
! @end table
! 
! @subsubsection Commands which act on the other window:
! @table @asis
! @item @code{list-buffers} (@kbd{C-x C-b}) @xref{List Buffers}.
! @itemx @code{scroll-other-window} (@kbd{C-M-v}) @xref{Other Window}.
! @itemx @code{scroll-other-window-down} (@kbd{C-M-S-v}) @xref{Other Window}.
! @itemx @code{beginning-of-buffer-other-window} (@kbd{M-@key{home}})
! @itemx @code{end-of-buffer-other-window} (@kbd{M-@key{end}})
! @end table
! 
! @subsubsection Commands which change the window layout:
! @table @asis
! @item @code{delete-other-windows} (@kbd{C-x 1}) @xref{Change Window}.
! @itemx @code{balance-windows} (@kbd{C-x +}) @xref{Change Window}.
! @itemx @code{split-window-vertically} (@kbd{C-x 2}) @xref{Split Window}.
! @itemx @code{enlarge-window} (@kbd{C-x ^}) @xref{Change Window}.
! @end table
! 
! @subsection Configuring other commands as scrolling commands
! To do this, set a command's isearch-scroll property to the value t.
! For example:
! 
! @example
! @code{(put 'my-command 'isearch-scroll t)}
! @end example
! 
! You should only thus configure commands which are ``safe'': i.e., they
! won't leave emacs in an inconsistent state when executed within a
! search - that is to say, the following things may be changed by a
! command only temporarily, and must be restored before the command
! finishes:
! 
! @enumerate
! @item
! Point.
! @item
! The buffer contents.
! @item
! The selected window and selected frame.
! @item
! The current match-data @xref{Match Data,,,elisp}.
! @end enumerate
! 
! Additionally, the command must not delete the current window and must
! not itself attempt an incremental search.  It may, however, change the
! window's size, or create or delete other windows and frames.
! 
! Note that an attempt by a command to scroll the text
! @emph{horizontally} won't work, although it will do no harm - any such
! scrolling will be overriden and nullified by the display code.
! 
! @node Replace, Other Repeating Search, Configuring Scrolling, Search
  @section Replacement Commands
  @cindex replacement
  @cindex search-and-replace commands
***************
*** 814,823 ****
  (@pxref{Expanding Abbrevs}).
  
  @menu
! * Unconditional Replace::  Replacing all matches for a string.
! * Regexp Replace::         Replacing all matches for a regexp.
! * Replacement and Case::   How replacements preserve case of letters.
! * Query Replace::          How to use querying.
  @end menu
  
  @node Unconditional Replace, Regexp Replace, Replace, Replace
--- 918,927 ----
  (@pxref{Expanding Abbrevs}).
  
  @menu
! * Unconditional Replace::	Replacing all matches for a string.
! * Regexp Replace::		Replacing all matches for a regexp.
! * Replacement and Case::	How replacements preserve case of letters.
! * Query Replace::		How to use querying.
  @end menu
  
  @node Unconditional Replace, Regexp Replace, Replace, Replace

[-- Attachment #6: man.Changelog --]
[-- Type: TEXT/PLAIN, Size: 114 bytes --]

2003-10-21  Alan Mackenzie  <acm@muc.de>

	* search.texi: Document a new scrolling facility in isearch mode.


[-- Attachment #7: Type: text/plain, Size: 141 bytes --]

_______________________________________________
Emacs-devel mailing list
Emacs-devel@gnu.org
http://mail.gnu.org/mailman/listinfo/emacs-devel

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Request for enhancement: Scrolling (etc.) in incremental search.
  2003-10-23 21:48   ` Alan Mackenzie
@ 2003-10-24 23:24     ` Richard Stallman
  2003-10-27  9:09       ` Alan Mackenzie
  2003-11-10  6:49     ` Juri Linkov
  1 sibling, 1 reply; 12+ messages in thread
From: Richard Stallman @ 2003-10-24 23:24 UTC (permalink / raw)
  Cc: emacs-devel

Now if you send a set of changelog entries, someone can install your
patch.  Please try to follow the conventions used in lisp/ChangeLog.

    Is this complete repetition the least painful way to submit such a "patch
    to a patch" or would it be prefered to submit literally a "patch to a
    patch", saving bandwidth at the cost of convenience?

Until the patch is installed, what we want is revised versions of it,
not add-on patches to it.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Request for enhancement: Scrolling (etc.) in incremental search.
  2003-10-24 23:24     ` Richard Stallman
@ 2003-10-27  9:09       ` Alan Mackenzie
  0 siblings, 0 replies; 12+ messages in thread
From: Alan Mackenzie @ 2003-10-27  9:09 UTC (permalink / raw)


[-- Attachment #1: Type: TEXT/PLAIN, Size: 580 bytes --]

On Fri, 24 Oct 2003, Richard Stallman wrote:

>Now if you send a set of changelog entries, someone can install your
>patch.  Please try to follow the conventions used in lisp/ChangeLog.

OK:  Here goes!

Manifest of attached files:
1. isearch.1.222.acm.el.diff:  Patch to isearch.el.
2. simple.1.621.acm.el.diff:   Patch to simple.el.
3. lisp.ChangeLog:             ChangeLog entry for ..../lisp/ChangeLog
4. search.1.40.acm.texi.diff:  Patch to search.texi.
5. man.Changelog               ChangeLog entry for ..../man/ChangeLog 

-- 
Alan Mackenzie (Munich, Germany)
acm@muc.de


[-- Attachment #2: isearch.1.222.acm.el.diff --]
[-- Type: TEXT/PLAIN, Size: 14939 bytes --]

*** isearch.1.222.el	Tue Sep 23 21:04:28 2003
--- isearch.1.222.acm.el	Sun Oct 26 21:09:21 2003
***************
*** 242,248 ****
        (while l
  	(set-char-table-default table (car l) 'isearch-printing-char)
  	(setq l (cdr l))))
!     ;; Make function keys, etc, exit the search.
      (define-key map [t] 'isearch-other-control-char)
      ;; Control chars, by default, end isearch mode transparently.
      ;; We need these explicit definitions because, in a dense keymap,
--- 242,249 ----
        (while l
  	(set-char-table-default table (car l) 'isearch-printing-char)
  	(setq l (cdr l))))
!     ;; Make function keys, etc, which aren't bound to a scrolling-function
!     ;; exit the search.
      (define-key map [t] 'isearch-other-control-char)
      ;; Control chars, by default, end isearch mode transparently.
      ;; We need these explicit definitions because, in a dense keymap,
***************
*** 1224,1241 ****
  	(goto-char isearch-barrier)))
    (isearch-process-search-char last-command-char))
  
  
  (defalias 'isearch-other-control-char 'isearch-other-meta-char)
  
! (defun isearch-other-meta-char ()
!   "Exit the search normally and reread this key sequence.
! But only if `search-exit-option' is non-nil, the default.
! If it is the symbol `edit', the search string is edited in the minibuffer
! and the meta character is unread so that it applies to editing the string."
!   (interactive)
!   (let* ((key (this-command-keys))
  	 (main-event (aref key 0))
! 	 (keylist (listify-key-sequence key)))
      (cond ((and (= (length key) 1)
  		(let ((lookup (lookup-key function-key-map key)))
  		  (not (or (null lookup) (integerp lookup)
--- 1225,1400 ----
  	(goto-char isearch-barrier)))
    (isearch-process-search-char last-command-char))
  
+ (defun isearch-unread-key-sequence (keylist)
+   "Unread the given key-sequence KEYLIST.
+ Scroll-bar or mode-line events are processed appropriately."
+   (cancel-kbd-macro-events)
+   (apply 'isearch-unread keylist)
+   ;; If the event was a scroll-bar or mode-line click, the event will have
+   ;; been prefixed by a symbol such as vertical-scroll-bar.  We must remove
+   ;; it here, because this symbol will be attached to the event again next
+   ;; time it gets read by read-key-sequence.
+   ;;
+   ;; (Old comment from isearch-other-meta-char: "Note that we don't have to
+   ;; modify the event anymore in 21 because read_key_sequence no longer
+   ;; modifies events to produce fake prefix keys.")
+   (if (and (> (length keylist) 1)
+            (symbolp (car keylist))
+            (listp (cadr keylist))
+            (not (numberp (posn-point
+                           (event-start (cadr keylist)  )))))
+       (pop unread-command-events)))
+ 
+ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+ ;; scrolling within Isearch mode.  Alan Mackenzie (acm@muc.de), 2003/2/24
+ ;;
+ ;; The idea here is that certain vertical scrolling commands (like C-l
+ ;; `recenter') should be usable WITHIN Isearch mode.  For a command to be
+ ;; suitable, it must NOT alter the buffer, swap to another buffer or frame,
+ ;; tamper with isearch's state, or move point.  It is unacceptable for the
+ ;; search string to be scrolled out of the current window.  If a command
+ ;; attempts this, we scroll the text back again.
+ ;;
+ ;; We implement this feature with a property called `isearch-scroll'.
+ ;; If a command's symbol has the value t for this property it is a
+ ;; scrolling command.  The feature needs to be enabled by setting the
+ ;; customizable variable `isearch-allow-scroll' to a non-nil value.
+ ;;
+ ;; The universal argument commands (e.g. C-u) in simple.el are marked
+ ;; as scrolling commands, and isearch.el has been amended to allow
+ ;; prefix arguments to be passed through to scrolling commands.  Thus
+ ;; M-0 C-l will scroll point to the top of the window.
+ ;;
+ ;; Horizontal scrolling commands are currently not catered for.
+ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+ 
+ ;; Set the isearch-scroll property on some standard functions:
+ ;; Scroll-bar functions:
+ (if (fboundp 'scroll-bar-toolkit-scroll)
+     (put 'scroll-bar-toolkit-scroll 'isearch-scroll t))
+ (if (fboundp 'mac-handle-scroll-bar-event)
+     (put 'mac-handle-scroll-bar-event 'isearch-scroll t))
+ (if (fboundp 'w32-handle-scroll-bar-event)
+     (put 'w32-handle-scroll-bar-event 'isearch-scroll t))
+ 
+ ;; Commands which scroll the window:
+ (put 'recenter 'isearch-scroll t)
+ (put 'reposition-window 'isearch-scroll t)
+ (put 'scroll-up 'isearch-scroll t)
+ (put 'scroll-down 'isearch-scroll t)
+ 
+ ;; Commands which act on the other window
+ (put 'list-buffers 'isearch-scroll t)
+ (put 'scroll-other-window 'isearch-scroll t)
+ (put 'scroll-other-window-down 'isearch-scroll t)
+ (put 'beginning-of-buffer-other-window 'isearch-scroll t)
+ (put 'end-of-buffer-other-window 'isearch-scroll t)
+ 
+ ;; Commands which change the window layout
+ (put 'delete-other-windows 'isearch-scroll t)
+ (put 'balance-windows 'isearch-scroll t)
+ (put 'split-window-vertically 'isearch-scroll t)
+ (put 'enlarge-window 'isearch-scroll t)
+ 
+ ;; Universal argument commands
+ (put 'universal-argument 'isearch-scroll t)
+ (put 'negative-argument 'isearch-scroll t)
+ (put 'digit-argument 'isearch-scroll t)
+ 
+ (defcustom isearch-allow-scroll nil
+   "If non-nil, scrolling commands are allowed during incremental search."
+   :type 'boolean
+   :group 'isearch)
+ 
+ (defun isearch-string-out-of-window (isearch-point)
+   "Test whether the search string is currently outside of the window.
+ 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)))
+         start end)                  ; start and end of search string in buffer
+     (if isearch-forward
+         (setq end isearch-point  start (or isearch-other-end isearch-point))
+       (setq start isearch-point  end (or isearch-other-end isearch-point)))
+     (cond ((or (and (>= start w-start) (<= end w-end))
+                (if isearch-forward
+                    (and (>= isearch-point w-L-1) (< isearch-point w-end)) ; point on Line -1
+                  (and (>= isearch-point w-start) (< isearch-point w-L1)))) ; point on Line 0
+            nil)
+           ((and (< start w-start)
+                 (< isearch-point w-L-1))
+            'above)
+           (t 'below))))
+ 
+ (defun isearch-back-into-window (above isearch-point)
+   "Scroll the window to bring the search string back into view.
+ Restore point to ISEARCH-POINT in the process.  ABOVE is t when the
+ search string is above the top of the window, nil when it is beneath
+ the bottom."
+   (let (start end)
+     (if isearch-forward
+         (setq end isearch-point  start (or isearch-other-end isearch-point))
+       (setq start isearch-point  end (or isearch-other-end isearch-point)))
+     (if above
+         (progn
+           (goto-char start)
+           (recenter 0)
+           (when (>= isearch-point (window-end nil t))
+             (goto-char isearch-point)
+             (recenter -1)))
+       (goto-char end)
+       (recenter -1)
+       (when (< isearch-point (window-start))
+         (goto-char isearch-point)
+         (recenter 0))))
+   (goto-char isearch-point))
+ 
+ (defun isearch-reread-key-sequence-naturally (keylist)
+   "Reread key sequence KEYLIST with Isearch mode's keymap deactivated.
+ Return the key sequence as a string/vector."
+   (isearch-unread-key-sequence keylist)
+   (let (overriding-terminal-local-map)
+     (read-key-sequence nil)))  ; This will go through function-key-map, if nec.
+ 
+ (defun isearch-lookup-scroll-key (key-seq)
+   "If KEY-SEQ is bound to a scrolling command, return it as a symbol.
+ Otherwise return nil."
+   (let* ((overriding-terminal-local-map nil)
+          (binding (key-binding key-seq)))
+     (and binding (symbolp binding) (commandp binding)
+          (eq (get binding 'isearch-scroll) t)
+          binding)))
  
  (defalias 'isearch-other-control-char 'isearch-other-meta-char)
  
! (defun isearch-other-meta-char (&optional arg)
!   "Process a miscellaneous key sequence in Isearch mode.
! 
! Try to convert the current key-sequence to something usable in Isearch
! mode, either by converting it with `function-key-map', downcasing a
! key with C-<upper case>, or finding a \"scrolling command\" bound to
! it.  \(In the last case, we may have to read more events.)  If so,
! either unread the converted sequence or execute the command.
! 
! Otherwise, if `search-exit-option' is non-nil (the default) unread the
! key-sequence and exit the search normally.  If it is the symbol
! `edit', the search string is edited in the minibuffer and the meta
! character is unread so that it applies to editing the string.
! 
! ARG is the prefix argument.  It will be transmitted through to the
! scrolling command or to the command whose key-sequence exits
! Isearch mode."
!   (interactive "P")
!   (let* ((key (if current-prefix-arg    ; not nec the same as ARG
!                   (substring (this-command-keys) universal-argument-num-events)
!                 (this-command-keys)))
  	 (main-event (aref key 0))
! 	 (keylist (listify-key-sequence key))
!          scroll-command isearch-point)
      (cond ((and (= (length key) 1)
  		(let ((lookup (lookup-key function-key-map key)))
  		  (not (or (null lookup) (integerp lookup)
***************
*** 1287,1309 ****
  	  ((eq search-exit-option 'edit)
  	   (apply 'isearch-unread keylist)
  	   (isearch-edit-string))
  	  (search-exit-option
  	   (let (window)
! 	     (cancel-kbd-macro-events)
! 	     (apply 'isearch-unread keylist)
! 
! 	     ;; Properly handle scroll-bar and mode-line clicks for
! 	     ;; which a dummy prefix event was generated as (aref key
! 	     ;; 0).  Note that we don't have to modify the event
! 	     ;; anymore in 21 because read_key_sequence no longer modifies
! 	     ;; events to produce fake prefix keys.
! 	     (when (and (> (length key) 1)
! 			(symbolp (aref key 0))
! 			(listp (aref key 1))
! 			(not (numberp (posn-point
! 				       (event-start (aref key 1))))))
! 	       (pop unread-command-events)
! 	       (setq main-event (car unread-command-events)))
  
  	     ;; If we got a mouse click event, that event contains the
  	     ;; window clicked on. maybe it was read with the buffer
--- 1446,1472 ----
  	  ((eq search-exit-option 'edit)
  	   (apply 'isearch-unread keylist)
  	   (isearch-edit-string))
+           ;; Handle a scrolling function.
+           ((and isearch-allow-scroll
+                 (progn (setq key (isearch-reread-key-sequence-naturally keylist))
+                        (setq keylist (listify-key-sequence key))
+                        (setq main-event (aref key 0))
+                        (setq scroll-command (isearch-lookup-scroll-key key))))
+            ;; From this point onwards, KEY, KEYLIST and MAIN-EVENT hold a
+            ;; complete key sequence, possibly as modified by function-key-map,
+            ;; not merely the one or two event fragment which invoked
+            ;; isearch-other-meta-char in the first place.
+            (setq isearch-point (point))
+            (setq prefix-arg arg)
+            (command-execute scroll-command)
+            (let ((ab-bel (isearch-string-out-of-window isearch-point)))
+              (if ab-bel
+                  (isearch-back-into-window (eq ab-bel 'above) isearch-point)))
+            (isearch-update))
  	  (search-exit-option
  	   (let (window)
!              (isearch-unread-key-sequence keylist)
!              (setq main-event (car unread-command-events))
  
  	     ;; If we got a mouse click event, that event contains the
  	     ;; window clicked on. maybe it was read with the buffer
***************
*** 1333,1340 ****
  		   (isearch-done)
  		   (isearch-clean-overlays))
  	       (isearch-done)
! 	       (isearch-clean-overlays))))
! 	  (t;; otherwise nil
  	   (isearch-process-search-string key key)))))
  
  (defun isearch-quote-char ()
--- 1496,1504 ----
  		   (isearch-done)
  		   (isearch-clean-overlays))
  	       (isearch-done)
! 	       (isearch-clean-overlays)
!                (setq prefix-arg arg))))
!           (t;; otherwise nil
  	   (isearch-process-search-string key key)))))
  
  (defun isearch-quote-char ()
***************
*** 1997,2002 ****
--- 2161,2167 ----
  (defvar isearch-lazy-highlight-last-string nil)
  (defvar isearch-lazy-highlight-window nil)
  (defvar isearch-lazy-highlight-window-start nil)
+ (defvar isearch-lazy-highlight-window-end nil)
  (defvar isearch-lazy-highlight-case-fold-search nil)
  (defvar isearch-lazy-highlight-regexp nil)
  
***************
*** 2031,2042 ****
  		 (not (eq isearch-lazy-highlight-regexp
  			  isearch-regexp))
                   (not (= (window-start)
!                          isearch-lazy-highlight-window-start))))
      ;; something important did indeed change
      (isearch-lazy-highlight-cleanup t) ;kill old loop & remove overlays
      (when (not isearch-invalid-regexp)
        (setq isearch-lazy-highlight-window       (selected-window)
              isearch-lazy-highlight-window-start (window-start)
              isearch-lazy-highlight-start        (point)
              isearch-lazy-highlight-end          (point)
              isearch-lazy-highlight-last-string  isearch-string
--- 2196,2210 ----
  		 (not (eq isearch-lazy-highlight-regexp
  			  isearch-regexp))
                   (not (= (window-start)
!                          isearch-lazy-highlight-window-start))
!                  (not (= (window-end)   ; Window may have been split/joined.
!                          isearch-lazy-highlight-window-end))))
      ;; something important did indeed change
      (isearch-lazy-highlight-cleanup t) ;kill old loop & remove overlays
      (when (not isearch-invalid-regexp)
        (setq isearch-lazy-highlight-window       (selected-window)
              isearch-lazy-highlight-window-start (window-start)
+             isearch-lazy-highlight-window-end   (window-end)
              isearch-lazy-highlight-start        (point)
              isearch-lazy-highlight-end          (point)
              isearch-lazy-highlight-last-string  isearch-string

[-- Attachment #3: simple.1.621.acm.el.diff --]
[-- Type: TEXT/PLAIN, Size: 4938 bytes --]

*** simple.1.621.el	Sat Oct 11 12:26:50 2003
--- simple.1.621.acm.el	Sun Oct 26 21:09:27 2003
***************
*** 1657,1662 ****
--- 1657,1682 ----
  `universal-argument-other-key' uses this to discard those events
  from (this-command-keys), and reread only the final command.")
  
+ (defvar overriding-map-is-bound nil
+   "Non-nil when `overriding-terminal-local-map' is `universal-argument-map'.")
+ 
+ (defvar saved-overriding-map nil
+   "The saved value of `overriding-terminal-local-map'.
+ That variable gets restored to this value on exiting \"universal
+ argument mode\".")
+ 
+ (defun ensure-overriding-map-is-bound ()
+   "Check `overriding-terminal-local-map' is `universal-argument-map'."
+   (unless overriding-map-is-bound
+     (setq saved-overriding-map overriding-terminal-local-map)
+     (setq overriding-terminal-local-map universal-argument-map)
+     (setq overriding-map-is-bound t)))
+ 
+ (defun restore-overriding-map ()
+   "Restore `overriding-terminal-local-map' to its saved value."
+   (setq overriding-terminal-local-map saved-overriding-map)
+   (setq overriding-map-is-bound nil))
+ 
  (defun universal-argument ()
    "Begin a numeric argument for the following command.
  Digits or minus sign following \\[universal-argument] make up the numeric argument.
***************
*** 1670,1676 ****
    (interactive)
    (setq prefix-arg (list 4))
    (setq universal-argument-num-events (length (this-command-keys)))
!   (setq overriding-terminal-local-map universal-argument-map))
  
  ;; A subsequent C-u means to multiply the factor by 4 if we've typed
  ;; nothing but C-u's; otherwise it means to terminate the prefix arg.
--- 1690,1696 ----
    (interactive)
    (setq prefix-arg (list 4))
    (setq universal-argument-num-events (length (this-command-keys)))
!   (ensure-overriding-map-is-bound))
  
  ;; A subsequent C-u means to multiply the factor by 4 if we've typed
  ;; nothing but C-u's; otherwise it means to terminate the prefix arg.
***************
*** 1681,1687 ****
      (if (eq arg '-)
  	(setq prefix-arg (list -4))
        (setq prefix-arg arg)
!       (setq overriding-terminal-local-map nil)))
    (setq universal-argument-num-events (length (this-command-keys))))
  
  (defun negative-argument (arg)
--- 1701,1707 ----
      (if (eq arg '-)
  	(setq prefix-arg (list -4))
        (setq prefix-arg arg)
!       (restore-overriding-map)))
    (setq universal-argument-num-events (length (this-command-keys))))
  
  (defun negative-argument (arg)
***************
*** 1695,1701 ****
  	(t
  	 (setq prefix-arg '-)))
    (setq universal-argument-num-events (length (this-command-keys)))
!   (setq overriding-terminal-local-map universal-argument-map))
  
  (defun digit-argument (arg)
    "Part of the numeric argument for the next command.
--- 1715,1721 ----
  	(t
  	 (setq prefix-arg '-)))
    (setq universal-argument-num-events (length (this-command-keys)))
!   (ensure-overriding-map-is-bound))
  
  (defun digit-argument (arg)
    "Part of the numeric argument for the next command.
***************
*** 1714,1720 ****
  	  (t
  	   (setq prefix-arg digit))))
    (setq universal-argument-num-events (length (this-command-keys)))
!   (setq overriding-terminal-local-map universal-argument-map))
  
  ;; For backward compatibility, minus with no modifiers is an ordinary
  ;; command if digits have already been entered.
--- 1734,1740 ----
  	  (t
  	   (setq prefix-arg digit))))
    (setq universal-argument-num-events (length (this-command-keys)))
!   (ensure-overriding-map-is-bound))
  
  ;; For backward compatibility, minus with no modifiers is an ordinary
  ;; command if digits have already been entered.
***************
*** 1735,1741 ****
  	  (append (nthcdr universal-argument-num-events keylist)
  		  unread-command-events)))
    (reset-this-command-lengths)
!   (setq overriding-terminal-local-map nil))
  \f
  ;;;; Window system cut and paste hooks.
  
--- 1755,1761 ----
  	  (append (nthcdr universal-argument-num-events keylist)
  		  unread-command-events)))
    (reset-this-command-lengths)
!   (restore-overriding-map))
  \f
  ;;;; Window system cut and paste hooks.
  
***************
*** 3348,3354 ****
        (setq arg (current-column)))
    (if (not (integerp arg))
        ;; Disallow missing argument; it's probably a typo for C-x C-f.
!       (error "set-fill-column requires an explicit argument")
      (message "Fill column set to %d (was %d)" arg fill-column)
      (setq fill-column arg)))
  \f
--- 3368,3374 ----
        (setq arg (current-column)))
    (if (not (integerp arg))
        ;; Disallow missing argument; it's probably a typo for C-x C-f.
!       (error "Set-fill-column requires an explicit argument")
      (message "Fill column set to %d (was %d)" arg fill-column)
      (setq fill-column arg)))
  \f

[-- Attachment #4: lisp.ChangeLog --]
[-- Type: TEXT/PLAIN, Size: 1040 bytes --]

2003-10-27  Alan Mackenzie  <acm@muc.de>

	Add changes to allow scrolling whilst in isearch mode:

	* isearch.el:
	(isearch-unread-key-sequence): New function, extracted from
	isearch-other-meta-char.
	(put 'foo 'isearch-scroll) on all Emacs's "scrollable" standard
	functions.
	(isearch-allow-scroll): New customizable variable.
	(isearch-string-out-of-window): New function.
	(isearch-back-into-window): New function.
	(isearch-reread-key-sequence-naturally): New function.
	(isearch-lookup-scroll-key): New function.
	(isearch-other-meta-char): Doc string and functionality enhanced.
	Now accepts a prefix argument.
	(isearch-lazy-highlight-window-end): New variable.
	(isearch-lazy-highlight-new-loop): Minor enhancements.
	
	* simple.el:
	(overriding-map-is-bound, saved-overriding-map): New variables.
	(ensure-overriding-map-is-bound, restore-overriding-map): New
	functions.
	(universal-argument, universal-argument-more, negative-argument,
	digit-argument, universal-argument-other-key): Minor changes.
	

[-- Attachment #5: search.1.40.acm.texi.diff --]
[-- Type: TEXT/PLAIN, Size: 8234 bytes --]

*** search.1.40.texi	Tue Sep 23 21:00:35 2003
--- search.1.40.acm.texi	Tue Oct 21 21:05:11 2003
***************
*** 19,32 ****
  asks interactively which occurrences to replace.
  
  @menu
! * Incremental Search::	   Search happens as you type the string.
! * Nonincremental Search::  Specify entire string and then search.
! * Word Search::		   Search for sequence of words.
! * Regexp Search::	   Search for match for a regexp.
! * Regexps::		   Syntax of regular expressions.
! * Search Case::		   To ignore case while searching, or not.
! * Replace::		   Search, and replace some or all matches.
! * Other Repeating Search:: Operating on all matches for some regexp.
  @end menu
  
  @node Incremental Search, Nonincremental Search, Search, Search
--- 19,33 ----
  asks interactively which occurrences to replace.
  
  @menu
! * Incremental Search::		Search happens as you type the string.
! * Nonincremental Search::	Specify entire string and then search.
! * Word Search::			Search for sequence of words.
! * Regexp Search::		Search for match for a regexp.
! * Regexps::			Syntax of regular expressions.
! * Search Case::			To ignore case while searching, or not.
! * Configuring Scrolling::	Scrolling within incremental search.
! * Replace::			Search, and replace some or all matches.
! * Other Repeating Search::	Operating on all matches for some regexp.
  @end menu
  
  @node Incremental Search, Nonincremental Search, Search, Search
***************
*** 226,231 ****
--- 227,260 ----
  of bindings, look at the documentation of @code{isearch-mode} with
  @kbd{C-h f isearch-mode @key{RET}}.
  
+ @subsection Scrolling During Incremental Search
+ 
+   Vertical scrolling during incremental search can be enabled by
+ setting the customizable variable @code{isearch-allow-scroll} to a
+ non-nil value.
+ 
+   You can then use the vertical scroll-bar or certain keyboard
+ commands such as @kbd{@key{PRIOR}} (@code{scroll-down}),
+ @kbd{@key{NEXT}} (@code{scroll-up}) and @kbd{C-l} (@code{recenter})
+ within the search, thus letting you see more of the text near the
+ current match.  You must run these commands via their key sequences to
+ stay in the search - typing M-x @var{comand-name} will always
+ terminate a search.
+ 
+   You can give prefix arguments to these commands in the usual way.
+ The current match cannot be scrolled out of the window - this is
+ intentional.
+ 
+   Several other commands, such as @kbd{C-x 2}
+ (@code{split-window-vertically}) and @kbd{C-x ^}
+ (@code{enlarge-window}) which don't scroll the window, are
+ nevertheless made available under this rubric, since they are likewise
+ handy during a search.
+ 
+   For a list of commands which are configured as scrolling commands by
+ default and instructions on how thus to configure other commands, see
+ @ref{Configuring Scrolling}.
+ 
  @subsection Slow Terminal Incremental Search
  
    Incremental search on a slow terminal uses a modified style of display
***************
*** 762,768 ****
  for matching parens.)
  @end ignore
  
! @node Search Case, Replace, Regexps, Search
  @section Searching and Case
  
    Incremental searches in Emacs normally ignore the case of the text
--- 791,797 ----
  for matching parens.)
  @end ignore
  
! @node Search Case, Configuring Scrolling, Regexps, Search
  @section Searching and Case
  
    Incremental searches in Emacs normally ignore the case of the text
***************
*** 792,798 ****
  performed by the replace commands (@pxref{Replace}) and the minibuffer
  history matching commands (@pxref{Minibuffer History}).
  
! @node Replace, Other Repeating Search, Search Case, Search
  @section Replacement Commands
  @cindex replacement
  @cindex search-and-replace commands
--- 821,902 ----
  performed by the replace commands (@pxref{Replace}) and the minibuffer
  history matching commands (@pxref{Minibuffer History}).
  
! @node Configuring Scrolling, Replace, Search Case, Search
! @section Configuring Scrolling
! @cindex scrolling in incremental search
! @vindex isearch-allow-scroll
! 
! Scrolling, etc., during incremental search is enabled by setting the
! customizable variable @code{isearch-allow-scroll} to a non-nil value.
! 
! @c See Subject: Info file:  How do I get an itemized list without blank lines?
! @c Date: Sat, 12 Apr 2003 09:45:31 +0000  in gnu.emacs.help
! @subsection Standard scrolling commands
! Here is the list of commands which are configured by default to be
! ``scrolling'' commands in an incremental search, together with their
! usual bindings:
! @subsubsection Commands which scroll the window:
! @table @asis
! @item @code{scroll-bar-toolkit-scroll} (@kbd{@key{vertical-scroll-bar}@key{mouse-1}} in X-Windows)
! @itemx @code{mac-handle-scroll-bar-event} (@kbd{@key{vertical-scroll-bar}@key{mouse-1}} on a Mac)
! @itemx @code{w32-handle-scroll-bar-event} (@kbd{@key{vertical-scroll-bar}@key{mouse-1}} in MS-Windows)
! @item @code{recenter} (@kbd{C-l}) @xref{Scrolling}.
! @itemx @code{reposition-window} (@kbd{C-M-l}) @xref{Scrolling}.
! @itemx @code{scroll-up} (@kbd{@key{NEXT}}) @xref{Scrolling}.
! @itemx @code{scroll-down} (@kbd{@key{PRIOR}}) @xref{Scrolling}.
! @end table
! 
! @subsubsection Commands which act on the other window:
! @table @asis
! @item @code{list-buffers} (@kbd{C-x C-b}) @xref{List Buffers}.
! @itemx @code{scroll-other-window} (@kbd{C-M-v}) @xref{Other Window}.
! @itemx @code{scroll-other-window-down} (@kbd{C-M-S-v}) @xref{Other Window}.
! @itemx @code{beginning-of-buffer-other-window} (@kbd{M-@key{home}})
! @itemx @code{end-of-buffer-other-window} (@kbd{M-@key{end}})
! @end table
! 
! @subsubsection Commands which change the window layout:
! @table @asis
! @item @code{delete-other-windows} (@kbd{C-x 1}) @xref{Change Window}.
! @itemx @code{balance-windows} (@kbd{C-x +}) @xref{Change Window}.
! @itemx @code{split-window-vertically} (@kbd{C-x 2}) @xref{Split Window}.
! @itemx @code{enlarge-window} (@kbd{C-x ^}) @xref{Change Window}.
! @end table
! 
! @subsection Configuring other commands as scrolling commands
! To do this, set a command's isearch-scroll property to the value t.
! For example:
! 
! @example
! @code{(put 'my-command 'isearch-scroll t)}
! @end example
! 
! You should only thus configure commands which are ``safe'': i.e., they
! won't leave emacs in an inconsistent state when executed within a
! search - that is to say, the following things may be changed by a
! command only temporarily, and must be restored before the command
! finishes:
! 
! @enumerate
! @item
! Point.
! @item
! The buffer contents.
! @item
! The selected window and selected frame.
! @item
! The current match-data @xref{Match Data,,,elisp}.
! @end enumerate
! 
! Additionally, the command must not delete the current window and must
! not itself attempt an incremental search.  It may, however, change the
! window's size, or create or delete other windows and frames.
! 
! Note that an attempt by a command to scroll the text
! @emph{horizontally} won't work, although it will do no harm - any such
! scrolling will be overriden and nullified by the display code.
! 
! @node Replace, Other Repeating Search, Configuring Scrolling, Search
  @section Replacement Commands
  @cindex replacement
  @cindex search-and-replace commands
***************
*** 814,823 ****
  (@pxref{Expanding Abbrevs}).
  
  @menu
! * Unconditional Replace::  Replacing all matches for a string.
! * Regexp Replace::         Replacing all matches for a regexp.
! * Replacement and Case::   How replacements preserve case of letters.
! * Query Replace::          How to use querying.
  @end menu
  
  @node Unconditional Replace, Regexp Replace, Replace, Replace
--- 918,927 ----
  (@pxref{Expanding Abbrevs}).
  
  @menu
! * Unconditional Replace::	Replacing all matches for a string.
! * Regexp Replace::		Replacing all matches for a regexp.
! * Replacement and Case::	How replacements preserve case of letters.
! * Query Replace::		How to use querying.
  @end menu
  
  @node Unconditional Replace, Regexp Replace, Replace, Replace

[-- Attachment #6: man.Changelog --]
[-- Type: TEXT/PLAIN, Size: 114 bytes --]

2003-10-27  Alan Mackenzie  <acm@muc.de>

	* search.texi: Document a new scrolling facility in isearch mode.


[-- Attachment #7: Type: text/plain, Size: 141 bytes --]

_______________________________________________
Emacs-devel mailing list
Emacs-devel@gnu.org
http://mail.gnu.org/mailman/listinfo/emacs-devel

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Request for enhancement: Scrolling (etc.) in incremental search.
  2003-10-23 21:48   ` Alan Mackenzie
  2003-10-24 23:24     ` Richard Stallman
@ 2003-11-10  6:49     ` Juri Linkov
  1 sibling, 0 replies; 12+ messages in thread
From: Juri Linkov @ 2003-11-10  6:49 UTC (permalink / raw)
  Cc: emacs-devel

Alan Mackenzie <acm@muc.de> writes:
> [A quick reminder of what this is for:  it lets you scroll the window
> during incremental search, so that you can see more of what's around
> point without leaving the search.  I've been using it for months, and
> wouldn't want to be without it now.  :-]

Until you presented this patch, I used a simple C-l keybinding to
isearch-mode-map to recenter.  But your patch is a big improvement
over it.  Thank you!

However, I found one glitch with new code: due to a bug in the display
engine, sometimes point moves to a wrong position after scrolling, and
isearch completely stumbles over.  The following patch fixes this by
setting the point back to its original position.  This patch is also
helpful for scrolling with scroll-preserve-screen-position set to t.

Index: emacs/lisp/isearch.el
===================================================================
RCS file: /cvsroot/emacs/emacs/lisp/isearch.el,v
retrieving revision 1.223
diff -c -r1.223 isearch.el
*** emacs/lisp/isearch.el	1 Nov 2003 17:00:02 -0000	1.223
--- emacs/lisp/isearch.el	10 Nov 2003 05:03:27 -0000
***************
*** 1461,1467 ****
             (command-execute scroll-command)
             (let ((ab-bel (isearch-string-out-of-window isearch-point)))
               (if ab-bel
!                  (isearch-back-into-window (eq ab-bel 'above) isearch-point)))
             (isearch-update))
  	  (search-exit-option
  	   (let (window)
--- 1461,1469 ----
             (command-execute scroll-command)
             (let ((ab-bel (isearch-string-out-of-window isearch-point)))
               (if ab-bel
!                  (isearch-back-into-window (eq ab-bel 'above) isearch-point)
!                (or (eq (point) isearch-point)
!                    (goto-char isearch-point))))
             (isearch-update))
  	  (search-exit-option
  	   (let (window)

-- 
http://www.jurta.org/emacs/

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2003-11-10  6:49 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-10-21 22:03 Request for enhancement: Scrolling (etc.) in incremental search Alan Mackenzie
2003-10-22  8:09 ` Alan Mackenzie
2003-10-23  9:23 ` Richard Stallman
2003-10-23 21:48   ` Alan Mackenzie
2003-10-24 23:24     ` Richard Stallman
2003-10-27  9:09       ` Alan Mackenzie
2003-11-10  6:49     ` Juri Linkov
     [not found] <E18kfaI-0007iR-00@fencepost.gnu.org>
2003-02-26 13:36 ` Alan Mackenzie
2003-03-01  2:26   ` Richard Stallman
     [not found] <it1e3b.75.ln@acm.acm>
2003-02-25 16:57 ` Richard Stallman
2003-02-25 22:37 ` Kim F. Storm
2003-02-26 10:57   ` Alan Mackenzie

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).