emacs-diffs
[Top][All Lists]
Advanced

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

master f3cfd47: New user options to move between isearch matches


From: Lars Ingebrigtsen
Subject: master f3cfd47: New user options to move between isearch matches
Date: Fri, 10 Sep 2021 06:43:55 -0400 (EDT)

branch: master
commit f3cfd478980749d18d7fbc7be941a1e8bc145c5f
Author: Gregory Heytings <gregory@heytings.org>
Commit: Lars Ingebrigtsen <larsi@gnus.org>

    New user options to move between isearch matches
    
    * lisp/isearch.el (isearch-allow-motion,
    isearch-motion-changes-direction): New user options.
    (isearch-pre-command-hook): Handle the new options.
    
    * etc/NEWS: Mention the new user options.
    
    * doc/emacs/search.texi: Document the new user options.
---
 doc/emacs/search.texi | 13 ++++++++++++
 etc/NEWS              | 12 +++++++++++
 lisp/isearch.el       | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++-
 3 files changed, 81 insertions(+), 1 deletion(-)

diff --git a/doc/emacs/search.texi b/doc/emacs/search.texi
index a1760ad..e4322e3 100644
--- a/doc/emacs/search.texi
+++ b/doc/emacs/search.texi
@@ -593,6 +593,19 @@ or the selected window and frame.  The command must not 
itself attempt
 an incremental search.  This feature is disabled if
 @code{isearch-allow-scroll} is @code{nil} (which it is by default).
 
+@vindex isearch-allow-motion
+@vindex isearch-motion-changes-direction
+  Likewise, if you change the variable @code{isearch-allow-motion}
+to a non-@code{nil} value, this enables the use of the keyboard motion
+commands @kbd{M-<}, @kbd{M->}, @kbd{C-v} and @kbd{M-v}, to move
+respectively to the first occurrence of the current search string in
+the buffer, the last one, the first one after the current window,
+and the last one before the current window.  The search direction
+does not change when these motion commands are used, unless you change
+the variable @code{isearch-motion-changes-direction} to a non-@code{nil}
+value, in which case the search direction is forward after @kbd{M-<} and
+@kbd{C-v}, and backward after @kbd{M->} and @kbd{M-v}.
+
 @item Motion Commands
 @cindex motion commands, during incremental search
 When @code{isearch-yank-on-move} is customized to @code{shift},
diff --git a/etc/NEWS b/etc/NEWS
index 01eb2a5..e8dde45 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -1132,6 +1132,18 @@ keys, add the following to your init file:
 Using it instead of 'read-char-choice' allows using 'C-x o'
 to switch to the help window displayed after typing 'C-h'.
 
++++
+** New user option 'isearch-allow-motion'.
+When 'isearch-allow-motion' is set, the commands 'beginning-of-buffer',
+'end-of-buffer', 'scroll-up-command' and 'scroll-down-command', when
+invoked during I-search, move respectively to the first occurrence of
+the current search string in the buffer, the last one, the first one
+after the current window, and the last one before the current window.
+Additionally, users can change the meaning of other motion commands
+during I-search by using their 'isearch-motion' property.  The
+option 'isearch-motion-changes-direction' controls whether the
+direction of the search changes after a motion command.
+
 ** Outline
 
 +++
diff --git a/lisp/isearch.el b/lisp/isearch.el
index 133c604..8a79fd5 100644
--- a/lisp/isearch.el
+++ b/lisp/isearch.el
@@ -2927,12 +2927,49 @@ If non-nil, scrolling commands can be used in Isearch 
mode.
 However, you cannot scroll far enough that the current match is
 no longer visible (is off screen).  But if the value is `unlimited'
 that limitation is removed and you can scroll any distance off screen.
-If nil, scrolling commands exit Isearch mode."
+If nil, scrolling commands exit Isearch mode.
+See also the related option `isearch-allow-motion'."
   :type '(choice (const :tag "Scrolling exits Isearch" nil)
                  (const :tag "Scrolling with current match on screen" t)
                  (const :tag "Scrolling with current match off screen" 
unlimited))
   :group 'isearch)
 
+(put 'beginning-of-buffer 'isearch-motion
+     '((lambda () (goto-char (point-min))) . forward))
+(put 'end-of-buffer 'isearch-motion
+     '((lambda () (goto-char (point-max))) . backward))
+(put 'scroll-up-command 'isearch-motion
+     '((lambda () (goto-char (window-end)) (recenter 1 t)) . forward))
+(put 'scroll-down-command 'isearch-motion
+     '((lambda () (goto-char (window-start)) (recenter -1 t)) . backward))
+
+(defcustom isearch-allow-motion nil
+  "Whether to allow movement between isearch matches by cursor motion commands.
+If non-nil, the four motion commands \\[beginning-of-buffer], 
\\[end-of-buffer], \
+\\[scroll-up-command] and \\[scroll-down-command], when invoked during
+Isearch, move respectively to the first occurrence of the current search string
+in the buffer, the last one, the first one after the current window, and the
+last one before the current window.
+If nil, these motion commands normally exit Isearch and are executed.
+See also the related options `isearch-motion-changes-direction' and
+`isearch-allow-scroll'."
+  :type '(choice (const :tag "Off" nil)
+                 (const :tag "On" t))
+  :group 'isearch
+  :version "28.1")
+
+(defcustom isearch-motion-changes-direction nil
+  "Whether motion commands during incremental search change search direction.
+If nil, the search direction (forward or backward) does not change when
+motion commands are used during incremental search, except when wrapping.
+If non-nil, the search direction is forward after \\[beginning-of-buffer] and \
+\\[scroll-up-command], and
+backward after \\[end-of-buffer] and \\[scroll-down-command]."
+  :type '(choice (const :tag "Off" nil)
+                 (const :tag "On" t))
+  :group 'isearch
+  :version "28.1")
+
 (defcustom isearch-allow-prefix t
   "Whether prefix arguments are allowed during incremental search.
 If non-nil, entering a prefix argument will not terminate the
@@ -3034,6 +3071,24 @@ See more for options in `search-exit-option'."
      ;; Optionally edit the search string instead of exiting.
      ((eq search-exit-option 'edit)
       (setq this-command 'isearch-edit-string))
+     ;; Handle motion command functions.
+     ((and isearch-allow-motion
+           (symbolp this-command)
+           (get this-command 'isearch-motion))
+      (let* ((property (get this-command 'isearch-motion))
+             (function (car property))
+             (current-direction (if isearch-forward 'forward 'backward))
+             (direction (or (cdr property)
+                            (if isearch-forward 'forward 'backward))))
+        (funcall function)
+        (setq isearch-just-started t)
+        (let ((isearch-repeat-on-direction-change nil))
+          (isearch-repeat direction))
+        (when (and isearch-success (not isearch-motion-changes-direction))
+          (unless (eq direction current-direction)
+            (let ((isearch-repeat-on-direction-change nil))
+              (isearch-repeat current-direction))))
+        (setq this-command 'ignore)))
      ;; Handle a scrolling function or prefix argument.
      ((or (and isearch-allow-prefix
                (memq this-command '(universal-argument universal-argument-more



reply via email to

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