emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Request for enhancement: Scrolling (etc.) in incremental search.


From: Alan Mackenzie
Subject: Re: Request for enhancement: Scrolling (etc.) in incremental search.
Date: Tue, 21 Oct 2003 22:03:42 +0000 (GMT)

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)
address@hidden

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 (address@hidden), 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)
*** 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))
  
  ;;;; 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))
  
  ;;;; Window system cut and paste hooks.
  
2003-10-21  Alan Mackenzie  <address@hidden>

        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.
        
*** 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 @address@hidden (@code{scroll-down}),
+ @address@hidden (@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} (@address@hidden@key{mouse-1}} in 
X-Windows)
! @itemx @code{mac-handle-scroll-bar-event} (@address@hidden@key{mouse-1}} on a 
Mac)
! @itemx @code{w32-handle-scroll-bar-event} (@address@hidden@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} (@address@hidden) @xref{Scrolling}.
! @itemx @code{scroll-down} (@address@hidden) @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} (@address@hidden)
! @itemx @code{end-of-buffer-other-window} (@address@hidden)
! @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
2003-10-21  Alan Mackenzie  <address@hidden>

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


reply via email to

[Prev in Thread] Current Thread [Next in Thread]