diff --git a/doc/emacs/search.texi b/doc/emacs/search.texi index a1c987c125..93c26f5c97 100644 --- a/doc/emacs/search.texi +++ b/doc/emacs/search.texi @@ -267,6 +267,14 @@ of the current line to the search string. If point is already at the end of a line, it appends the next line. With a prefix argument @var{n}, it appends the next @var{n} lines. address@hidden M-w @r{(Incremental search)} address@hidden isearch-yank-region + @kbd{M-w} (@code{isearch-yank-region}) appends the text in the +active region if @code{transient-mark-mode} is @code{non-nil}. This is +an easy way to insert the text in the region without needing to exit address@hidden The region is deactivated during the search, but +it is reactivated if the @code{isearch-cancel} is called. + @kindex C-y @r{(Incremental search)} @kindex M-y @r{(Incremental search)} @kindex mouse-2 @r{in the minibuffer (Incremental search)} diff --git a/lisp/isearch.el b/lisp/isearch.el index 6280afebdc..78414dbfcd 100644 --- a/lisp/isearch.el +++ b/lisp/isearch.el @@ -53,7 +53,9 @@ ;;; Code: -(eval-when-compile (require 'cl-lib)) +(eval-when-compile + (require 'cl-lib) + (require 'subr-x)) (declare-function tmm-menubar-keymap "tmm.el") ;; Some additional options and constants. @@ -701,6 +703,7 @@ This is like `describe-bindings', but displays only Isearch keys." (define-key map "\M-\C-y" 'isearch-yank-char) (define-key map "\C-y" 'isearch-yank-kill) (define-key map "\M-s\C-e" 'isearch-yank-line) + (define-key map "\M-w" 'isearch-yank-region) (define-key map "\M-s\M-<" 'isearch-beginning-of-buffer) (define-key map "\M-s\M->" 'isearch-end-of-buffer) @@ -937,6 +940,8 @@ Each element is an `isearch--state' struct where the slots are (defvar isearch--saved-overriding-local-map nil) +(defvar isearch--deactivated-mark nil) + ;; Minor-mode-alist changes - kind of redundant with the ;; echo area, but if isearching in multiple windows, it can be useful. ;; Also, clicking the mode-line indicator pops up @@ -961,6 +966,8 @@ Each element is an `isearch--state' struct where the slots are (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 "\M-w" 'isearch-forward-region) + ;; Entry points to isearch-mode. @@ -1133,6 +1140,22 @@ positive, or search for ARGth symbol backward if ARG is negative." (isearch-push-state) (isearch-update))))) +(defun isearch-forward-region (&optional arg) + "Do incremental search forward for text in active region. +Like ordinary incremental search except that the text in the +active region is added to the search string initially +if`transient-mark-mode' is enabled. See the command +`isearch-forward' for more information. +With a prefix argument, search for ARGth occurrence forward if +ARG is positive, or ARGth occurrence backward if ARG is +negative." + (interactive "P") + (isearch-forward nil 1) + (isearch-yank-region) + (when (and isearch--deactivated-mark + arg) + (isearch-repeat-forward (prefix-numeric-value arg)))) + ;; isearch-mode only sets up incremental search for the minor mode. ;; All the work is done by the isearch-mode commands. @@ -1203,9 +1226,10 @@ used to set the value of `isearch-regexp-function'." isearch-pre-move-point nil ;; Save the original value of `minibuffer-message-timeout', and - ;; set it to nil so that isearch's messages don't get timed out. - isearch-original-minibuffer-message-timeout minibuffer-message-timeout - minibuffer-message-timeout nil) + ;; set it to nil so that isearch's messages don't get timed out. + isearch-original-minibuffer-message-timeout minibuffer-message-timeout + minibuffer-message-timeout nil + isearch--deactivated-mark nil) (if (local-variable-p 'tool-bar-map) (setq isearch-tool-bar-old-map tool-bar-map)) @@ -1783,6 +1807,9 @@ The following additional command keys are active while editing. (goto-char isearch-opoint)) (isearch-done t) ; Exit isearch.. (isearch-clean-overlays) + (when isearch--deactivated-mark + (setq isearch--deactivated-mark nil + mark-active t)) (signal 'quit nil)) ; ..and pass on quit signal. (defun isearch-abort () @@ -2446,6 +2473,27 @@ If search string is empty, just beep." ;; then it "used" the mark which we should hence deactivate. (when select-active-regions (deactivate-mark))) +(defun isearch-yank-region () + "Pull current active region text into search string. +The text in the active region is added to the search string if +variable `transient-mark-mode' is non nil." + (interactive) + (let ((region (and (use-region-p) + (funcall region-extract-function nil)))) + (if (and (stringp region) + (not (string-empty-p region))) + (progn + (when (string-empty-p isearch-string) + (goto-char (region-beginning))) + + (setq isearch--deactivated-mark t) + (deactivate-mark) + (isearch-yank-string region)) + + (setq isearch-error "Invalid region") + (isearch-push-state) + (isearch-update)))) + (defun isearch-mouse-2 (click) "Handle mouse-2 in Isearch mode.