[Top][All Lists]

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

isearch-allow-move [Was: isearch-allow-prefix]

From: Juri Linkov
Subject: isearch-allow-move [Was: isearch-allow-prefix]
Date: Thu, 06 Jun 2013 09:07:34 +0300
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/24.3.50 (x86_64-pc-linux-gnu)

> OK, I've committed it.

Thank you, Alan.

Let me reuse your excellent design and create a similar option
`isearch-allow-move' that is like `isearch-allow-scroll' but
instead of scrolling commands it affects point motion commands
to yank text as you go.

So typing `C-f' will pull the next char from the buffer and add it
to the search string, `M-f' - next word, `C-M-f' - next expression,
`M-}' - next paragraph, `C-e' - next line, and so on.

Definitely `isearch-allow-move' should be nil by default,
and I doubt that many users might want to enable it since
it's more useful when motion commands exit Isearch.

But to make this feature available regardless of the value of
`isearch-allow-move' it could be activated temporarily by the
keymap `M-s' to allow key sequences like `M-s C-f M-f C-M-f C-e'
that is implemented by this patch:

=== modified file 'lisp/isearch.el'
--- lisp/isearch.el     2013-06-05 20:57:09 +0000
+++ lisp/isearch.el     2013-06-06 06:04:35 +0000
@@ -513,6 +550,10 @@ (defvar isearch-mode-map
     (define-key map "\M-r" 'isearch-toggle-regexp)
     (define-key map "\M-e" 'isearch-edit-string)
+    (let ((s-map (make-sparse-keymap)))
+      (define-key map "\M-s" s-map)
+      (define-key s-map [t] 'isearch-other-move-char))
     (define-key map "\M-sc" 'isearch-toggle-case-fold)
     (define-key map "\M-si" 'isearch-toggle-invisible)
     (define-key map "\M-sr" 'isearch-toggle-regexp)
@@ -668,6 +732,7 @@ (define-key esc-map "\C-r" 'isearch-back
 (define-key search-map "w" 'isearch-forward-word)
 (define-key search-map "_" 'isearch-forward-symbol)
 (define-key search-map "." 'isearch-forward-symbol-at-point)
+(define-key search-map [t] 'isearch-forward-other-move-char)
 ;; Entry points to isearch-mode.
@@ -987,6 +1057,7 @@ (defun isearch-update ()
   ;; We must prevent the point moving to the end of composition when a
   ;; part of the composition has just been searched.
   (setq disable-point-adjustment t)
+  (setq isearch-allow-move-temporarily nil)
   (run-hooks 'isearch-update-post-hook))
 (defun isearch-done (&optional nopush edit)
@@ -2160,6 +2287,42 @@ (defcustom isearch-allow-prefix t
   :type 'boolean
   :group 'isearch)
+(defcustom isearch-allow-move nil
+  "Whether cursor movement is allowed during incremental search.
+If non-nil, point motion commands can be used in Isearch mode.
+They add the passed text to the search string.
+If nil, motion commands will first cancel Isearch mode."
+  :type 'boolean
+  :version "24.4"
+  :group 'isearch)
+(defvar isearch-allow-move-temporarily nil
+  "Enable yanking text by point motion commands temporarily.
+It is enabled on `M-s' and a subsequent point motion command and allows
+any subsequent point motion command to add the passed text to the
+search string as they go allowing key sequences like `M-s C-f M-f C-M-f'
+to add next character, next word, and next expression to the search string.
+Any subsequent isearch command that is not a point motion command,
+the value of this variable is set to nil.")
+(put 'right-char 'isearch-move t)
+(put 'forward-char 'isearch-move t)
+(put 'forward-word 'isearch-move t)
+(put 'forward-sexp 'isearch-move t)
+(put 'forward-paragraph 'isearch-move t)
+(put 'move-end-of-line 'isearch-move t)
+;; Handle universal argument for motion commands when both
+;; `isearch-allow-scroll' and `isearch-allow-prefix' are nil.
+(put 'universal-argument 'isearch-move t)
+(put 'negative-argument 'isearch-move t)
+(put 'digit-argument 'isearch-move t)
 (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,
@@ -2224,6 +2388,26 @@ (defun isearch-lookup-scroll-key (key-se
             (eq (get binding 'scroll-command) t))
+(defun isearch-lookup-move-key (key-seq)
+  "If KEY-SEQ is bound to a motion 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-move) t)
+         binding)))
+(defun isearch-other-move-char (&optional arg)
+  (interactive "P")
+  (setq isearch-allow-move-temporarily t)
+  (isearch-other-meta-char arg))
+(defun isearch-forward-other-move-char (&optional arg)
+  "Do incremental search starting with a motion command that yanks text."
+  (interactive "P")
+  (isearch-forward nil 1)
+  (isearch-other-move-char arg))
 (defalias 'isearch-other-control-char 'isearch-other-meta-char)
 (defun isearch-other-meta-char (&optional arg)
@@ -2336,7 +2525,22 @@ (defun isearch-other-meta-char (&optiona
              (if ab-bel
                  (isearch-back-into-window (eq ab-bel 'above) isearch-point)
                (goto-char isearch-point)))
-           (isearch-update))
+           (isearch-update)
+           ;; Allow prefix arg for the next motion command.
+           (setq isearch-allow-move-temporarily t))
+         ;; Handle a motion function.
+         ((and (or isearch-allow-move isearch-allow-move-temporarily)
+               (progn (setq key (isearch-reread-key-sequence-naturally 
+                      (setq keylist (listify-key-sequence key))
+                      (setq main-event (aref key 0))
+                      (setq move-command (isearch-lookup-move-key
+                                          ;; Use the last key in the sequence.
+                                          (vector (aref key (1- (length 
+          (setq prefix-arg arg)
+          (isearch-yank-internal
+           (lambda () (command-execute move-command) (point)))
+          (isearch-update)
+          (setq isearch-allow-move-temporarily t))
          ;; A mouse click on the isearch message starts editing the search 
          ((and (eq (car-safe main-event) 'down-mouse-1)
                (window-minibuffer-p (posn-window (event-start main-event))))

reply via email to

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