unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
From: Drew Adams <drew.adams@oracle.com>
To: Karl Fogel <kfogel@red-bean.com>, Emacs developers <emacs-devel@gnu.org>
Subject: PATCH: isearch-yank-until-match
Date: Wed, 14 Aug 2019 14:08:50 -0700 (PDT)	[thread overview]
Message-ID: <6c21d7af-e071-4c9e-9325-38c6f19794b3@default> (raw)

[-- Attachment #1: Type: text/plain, Size: 2094 bytes --]

This is similar to what Karl submitted today.
Not a replacement for that; something different.

---

During Isearch, hit `C-M-m' (aka `M-RET').
You're prompted for another search pattern.
The text matching the pattern from point,
in the search direction, is yanked to the
search string.

Works for forward and backward searches,
and for regexp and literal searches.

If searching backward, the matched text is
prepended to the search string; else it is
appended.

If you use a prefix arg with `C-M-m' then
the pattern is matched as a regexp, not
literally.

---

I think Karl's `isearch-yank-until-char'
should also be made to support backward
search.

With the attached patch the following
definition does that.  (The attached
patch does not include this command.
The diff is against the isearch.el in
master today.)

(defun isearch-yank-until-char (char)
  "Yank buffer text, up to next instance of CHAR, to search string.
You are prompted for CHAR."
  (interactive "cYank until character: ")
  (isearch-yank-internal
   (lambda ()
     (let ((inhibit-field-text-motion t))
       (funcall (if isearch-forward
		    #'search-forward
		  #'search-backward)
		(char-to-string char))
       (if isearch-forward
           (backward-char)
         (forward-char))
       (point)))))

---

The attached patch also improves these
two functions:

`isearch-process-search-string':

Prepend STRING if searching backward and
search string is not just a single char.
(Otherwise, append, as now.)

Add a doc string.

`isearch-yank-internal':

1. Doc string now talks about arg as being
a function, not a "lambda expression".
Arg name is JUMPFUN, not JUMPFORM.

2. Use fixed version of
`isearch-process-search-string', so no
need to move to other end when searching
backward.

---

I don't think the patch breaks anything
(e.g. uses of `isearch-yank-internal' or
`isearch-process-search-string'), but
I've done limited testing.  Maybe someone
knowledgeable about the isearch.el code
(e.g. Juri) could take a look to be sure.

[-- Attachment #2: isearch-2019-08-14a.patch --]
[-- Type: application/octet-stream, Size: 3657 bytes --]

diff -u isearch.el isearch-2019-08-14a-PATCH.el
--- isearch.el	2019-08-14 13:16:15.200853800 -0700
+++ isearch-2019-08-14a-PATCH.el	2019-08-14 13:25:38.332894300 -0700
@@ -705,6 +705,7 @@
     (define-key map "\M-\C-d" 'isearch-del-char)
     (define-key map "\M-\C-y" 'isearch-yank-char)
     (define-key map    "\C-y" 'isearch-yank-kill)
+    (define-key map (kbd "M-RET") 'isearch-yank-until-match) ; aka `C-M-m'
     (define-key map "\M-s\C-e" 'isearch-yank-line)
 
     (define-key map "\M-s\M-<" 'isearch-beginning-of-buffer)
@@ -2508,17 +2509,16 @@
   (interactive)
   (isearch-yank-string (xterm--pasted-text)))
 
-(defun isearch-yank-internal (jumpform)
-  "Pull the text from point to the point reached by JUMPFORM.
-JUMPFORM is a lambda expression that takes no arguments and returns
-a buffer position, possibly having moved point to that position.
-For example, it might move point forward by a word and return point,
-or it might return the position of the end of the line."
+(defun isearch-yank-internal (jumpfun)
+  "Yank buffer text from point to the position reached by JUMPFUN.
+JUMPFUN is a function that takes no arguments and returns a buffer
+position, possibly having moved point to that position.
+
+For example, JUMPFUN might move forward by a word and return point, or
+it might return the position of the end of the line."
   (isearch-yank-string
    (save-excursion
-     (and (not isearch-forward) isearch-other-end
-	  (goto-char isearch-other-end))
-     (buffer-substring-no-properties (point) (funcall jumpform)))))
+     (buffer-substring-no-properties (point) (funcall jumpfun)))))
 
 (defun isearch-yank-char-in-minibuffer (&optional arg)
   "Pull next character from buffer into end of search string in minibuffer."
@@ -2586,6 +2586,29 @@
 					   (mapconcat 'isearch-text-char-description
 						      string ""))))))))
 
+(defun isearch-yank-until-match (arg)
+  "Yank text through match for another pattern onto the search string.
+You are prompted for the pattern.
+With a prefix arg the pattern is matched as a regexp."
+  (interactive "P")
+  (let (pattern)
+    (with-isearch-suspended
+     (setq pattern  (if arg
+                        (read-regexp "Match regexp: ")
+                      (read-string "Match: "))))
+    (isearch-yank-internal
+     (lambda ()
+       (let ((inhibit-field-text-motion  t))
+         (funcall (if arg
+                      (if isearch-forward
+                          #'search-forward-regexp
+                        #'search-backward-regexp)
+                    (if isearch-forward
+                        #'search-forward
+                      #'search-backward))
+                  pattern)
+         (point))))))
+
 (defun isearch-search-and-update ()
   ;; Do the search and update the display.
   (when (or isearch-success
@@ -3015,10 +3038,17 @@
     (isearch-process-search-string string message)))
 
 (defun isearch-process-search-string (string message)
-  (setq isearch-string (concat isearch-string string)
-	isearch-message (concat isearch-message message))
+  "Add STRING to `isearch-string' and MESSAGE to `isearch-message'.
+Append if searching forward or STRING is only one char.
+Otherwise, prepend."
+  (let ((appendp  (or isearch-forward  (= 1 (length string)))))
+    (setq isearch-string   (if appendp
+                               (concat isearch-string string)
+                             (concat string isearch-string))
+	  isearch-message  (if appendp
+                               (concat isearch-message message)
+                             (concat message isearch-message))))
   (isearch-search-and-update))
-
 \f
 ;; Search Ring
 

             reply	other threads:[~2019-08-14 21:08 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-08-14 21:08 Drew Adams [this message]
2019-08-15 18:16 ` PATCH: isearch-yank-until-match Juri Linkov
2019-08-15 22:15   ` Drew Adams
2019-08-16 17:51     ` Juri Linkov
  -- strict thread matches above, loose matches on Subject: below --
2019-08-20 22:37 Drew Adams
2019-09-16 21:24 ` Drew Adams
2019-09-17 16:03   ` Karl Fogel

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/emacs/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=6c21d7af-e071-4c9e-9325-38c6f19794b3@default \
    --to=drew.adams@oracle.com \
    --cc=emacs-devel@gnu.org \
    --cc=kfogel@red-bean.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).