unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
From: Juri Linkov <juri@jurta.org>
To: "Drew Adams" <drew.adams@oracle.com>
Cc: emacs-devel@gnu.org
Subject: Re: Why is `C-x 8' limited to Latin-1 for search?
Date: Mon, 10 Dec 2012 23:57:17 +0200	[thread overview]
Message-ID: <87zk1lfu4j.fsf@mail.jurta.org> (raw)
In-Reply-To: <9CE95F039B2A4295BA1273CD98924B43@us.oracle.com> (Drew Adams's message of "Mon, 10 Dec 2012 06:24:24 -0800")

> But I don't know what you mean by "except the part that changes
> `isearch-new-string' and `isearch-new-message'.  I do change both, to reflect
> the added char.  No doubt you had a slightly different macro in mind.

I meant that `isearch-edit-string' does more than needed for the command
that will read and insert an Unicode char.  For example, currently
it binds `history-add-new-input' to nil.  This means that your code
doesn't add the char name to the minibuffer's history.

Executing any code in the macro's body will also allow doing more
amazing things like temporarily going into a recursive edit with:

(define-key isearch-mode-map "\M-r"
  (lambda ()
    (interactive)
    (with-isearch-suspend (recursive-edit))))

where `C-M-c' will continue the suspended isearch.

This will be possible to do with this patch:

=== modified file 'lisp/isearch.el'
--- lisp/isearch.el	2012-11-21 10:32:38 +0000
+++ lisp/isearch.el	2012-12-10 21:57:00 +0000
@@ -534,7 +534,7 @@ (defvar isearch-mode-map
     (define-key map "\C-x" nil)
     (define-key map [?\C-x t] 'isearch-other-control-char)
     (define-key map "\C-x8" nil)
-    (define-key map "\C-x8\r" 'isearch-other-control-char)
+    (define-key map "\C-x8\r" 'isearch-insert-char-by-name)
 
     map)
   "Keymap for `isearch-mode'.")
@@ -1140,23 +1140,17 @@ (defun isearch-fail-pos (&optional msg)
 	  (length succ-msg)
 	0))))
 
-(defun isearch-edit-string ()
-  "Edit the search string in the minibuffer.
-The following additional command keys are active while editing.
-\\<minibuffer-local-isearch-map>
-\\[exit-minibuffer] to resume incremental searching with the edited string.
-\\[isearch-nonincremental-exit-minibuffer] to do one nonincremental search.
-\\[isearch-forward-exit-minibuffer] to resume isearching forward.
-\\[isearch-reverse-exit-minibuffer] to resume isearching backward.
-\\[isearch-complete-edit] to complete the search string using the search ring."
-
+(defmacro with-isearch-suspend (&rest body)
+  "Exit Isearch mode, run BODY, and reinvoke the pending search.
+You can update the global isearch variables by setting new values to
+`isearch-new-string', `isearch-new-message', `isearch-new-forward',
+`isearch-new-word', `isearch-new-case-fold'."
   ;; This code is very hairy for several reasons, explained in the code.
   ;; Mainly, isearch-mode must be terminated while editing and then restarted.
   ;; If there were a way to catch any change of buffer from the minibuffer,
   ;; this could be simplified greatly.
   ;; Editing doesn't back up the search point.  Should it?
-  (interactive)
-  (condition-case nil
+  `(condition-case nil
       (progn
 	(let ((isearch-nonincremental isearch-nonincremental)
 
@@ -1219,29 +1213,7 @@ (defun isearch-edit-string ()
 	  (setq old-point (point) old-other-end isearch-other-end)
 
 	  (unwind-protect
-	      (let* ((message-log-max nil)
-		     ;; Don't add a new search string to the search ring here
-		     ;; in `read-from-minibuffer'. It should be added only
-		     ;; by `isearch-update-ring' called from `isearch-done'.
-		     (history-add-new-input nil)
-		     ;; Binding minibuffer-history-symbol to nil is a work-around
-		     ;; for some incompatibility with gmhist.
-		     (minibuffer-history-symbol))
-		(setq isearch-new-string
-                      (read-from-minibuffer
-                       (isearch-message-prefix nil isearch-nonincremental)
-		       (cons isearch-string (1+ (or (isearch-fail-pos)
-						    (length isearch-string))))
-                       minibuffer-local-isearch-map nil
-                       (if isearch-regexp
-			   (cons 'regexp-search-ring
-				 (1+ (or regexp-search-ring-yank-pointer -1)))
-			 (cons 'search-ring
-			       (1+ (or search-ring-yank-pointer -1))))
-                       nil t)
-		      isearch-new-message
-		      (mapconcat 'isearch-text-char-description
-				 isearch-new-string "")))
+	      (progn ,@body)
 
 	    ;; Set point at the start (end) of old match if forward (backward),
 	    ;; so after exiting minibuffer isearch resumes at the start (end)
@@ -1300,6 +1272,41 @@ (defun isearch-edit-string ()
      (isearch-abort)  ;; outside of let to restore outside global values
      )))
 
+(defun isearch-edit-string ()
+  "Edit the search string in the minibuffer.
+The following additional command keys are active while editing.
+\\<minibuffer-local-isearch-map>
+\\[exit-minibuffer] to resume incremental searching with the edited string.
+\\[isearch-nonincremental-exit-minibuffer] to do one nonincremental search.
+\\[isearch-forward-exit-minibuffer] to resume isearching forward.
+\\[isearch-reverse-exit-minibuffer] to resume isearching backward.
+\\[isearch-complete-edit] to complete the search string using the search ring."
+  (interactive)
+  (with-isearch-suspend
+   (let* ((message-log-max nil)
+	  ;; Don't add a new search string to the search ring here
+	  ;; in `read-from-minibuffer'. It should be added only
+	  ;; by `isearch-update-ring' called from `isearch-done'.
+	  (history-add-new-input nil)
+	  ;; Binding minibuffer-history-symbol to nil is a work-around
+	  ;; for some incompatibility with gmhist.
+	  (minibuffer-history-symbol))
+     (setq isearch-new-string
+	   (read-from-minibuffer
+	    (isearch-message-prefix nil isearch-nonincremental)
+	    (cons isearch-string (1+ (or (isearch-fail-pos)
+					 (length isearch-string))))
+	    minibuffer-local-isearch-map nil
+	    (if isearch-regexp
+		(cons 'regexp-search-ring
+		      (1+ (or regexp-search-ring-yank-pointer -1)))
+	      (cons 'search-ring
+		    (1+ (or search-ring-yank-pointer -1))))
+	    nil t)
+	   isearch-new-message
+	   (mapconcat 'isearch-text-char-description
+		      isearch-new-string "")))))
+
 (defun isearch-nonincremental-exit-minibuffer ()
   (interactive)
   (setq isearch-nonincremental t)
@@ -1870,6 +1877,17 @@ (defun isearch-yank-line ()
    (lambda () (let ((inhibit-field-text-motion t))
 		(line-end-position (if (eolp) 2 1))))))
 
+(defun isearch-insert-char-by-name ()
+  "Read a character by its Unicode name and insert it into search string."
+  (interactive)
+  (with-isearch-suspend
+   (let ((char (read-char-by-name "Insert character (Unicode name or hex): ")))
+     (when char
+       (setq isearch-new-string (concat isearch-string (string char))
+	     isearch-new-message (concat isearch-message
+					 (mapconcat 'isearch-text-char-description
+						    (string char) "")))))))
+
 (defun isearch-search-and-update ()
   ;; Do the search and update the display.
   (when (or isearch-success




  reply	other threads:[~2012-12-10 21:57 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-12-09  4:52 Why is `C-x 8' limited to Latin-1 for search? Drew Adams
2012-12-09  5:33 ` Drew Adams
2012-12-10  7:46   ` Juri Linkov
2012-12-10 14:24     ` Drew Adams
2012-12-10 21:57       ` Juri Linkov [this message]
2012-12-11  0:11         ` Drew Adams
2012-12-10  7:45 ` Juri Linkov
2012-12-10 14:44   ` Drew Adams

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=87zk1lfu4j.fsf@mail.jurta.org \
    --to=juri@jurta.org \
    --cc=drew.adams@oracle.com \
    --cc=emacs-devel@gnu.org \
    /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).