unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
From: "Drew Adams" <drew.adams@oracle.com>
To: <emacs-devel@gnu.org>
Subject: RE: Why is `C-x 8' limited to Latin-1 for search?
Date: Sat, 8 Dec 2012 21:33:49 -0800	[thread overview]
Message-ID: <9A96D353A11D47A7A143074DB1E09EE4@us.oracle.com> (raw)
In-Reply-To: <1992681966EA4AE4A56751FA335DD5CE@us.oracle.com>

> To try the latter quickly (no, this is not the way to code 
> this; it's just a quick way to let you try it):
> 
> (unless (fboundp 'ORIG-isearch-edit-string)
>   (defalias 'ORIG-isearch-edit-string
>             (symbol-function 'isearch-edit-string)))
> 
> (defun isearch-edit-string ()
>   (interactive)
>   (let ((enable-recursive-minibuffers  t))
>     (ORIG-isearch-edit-string)))
> 
> In a buffer with some Unicode chars, e.g., `λ':
> 
> C-s M-e C-x 8 RET GREEK SMALL LETTER LAMBDA C-s
> 
> (You have completion for the character name, at least.)

And you can try the former quickly too (i.e., use `C-x 8 RET' directly in
Isearch without going through `M-e') with the code below. Again, I'm not
proposing using this code as is; this is just to let you see how the feature
might act.

E.g., after evaling the code below, to search for `abcλdef', do this (with
completion for the char name):

  C-s a b c C-x 8 RET GREEK SMALL LETTER LAMBDA RET d e f

(define-key isearch-mode-map "\C-x8\r" 'foo)

;; 99% the same as `isearch-edit-string' (`M-e'). This just calls
`read-char-by-name'.
;; The common code could be factored out, if this were how we wanted to
implement the feature.
;; (I didn't try to see if everything else here is needed for this feature, as
it is needed for `M-e'.)
;;
(defun foo ()
  (interactive)
  (condition-case nil
      (progn
	(let ((enable-recursive-minibuffer  t) ; <====== ADDED ====
              (isearch-nonincremental isearch-nonincremental)
	      ;; Locally bind all isearch global variables to protect them
	      ;; from recursive isearching.
	      ;; isearch-string -message and -forward are not bound
	      ;; so they may be changed.  Instead, save the values.
	      (isearch-new-string isearch-string)
	      (isearch-new-message isearch-message)
	      (isearch-new-forward isearch-forward)
	      (isearch-new-word isearch-word)
	      (isearch-new-case-fold isearch-case-fold-search)
	      (isearch-regexp isearch-regexp)
	      (isearch-op-fun isearch-op-fun)
	      (isearch-cmds isearch-cmds)
	      (isearch-success isearch-success)
	      (isearch-wrapped isearch-wrapped)
	      (isearch-barrier isearch-barrier)
	      (isearch-adjusted isearch-adjusted)
	      (isearch-yank-flag isearch-yank-flag)
	      (isearch-error isearch-error)
	      (isearch-opoint isearch-opoint)
	      (isearch-slow-terminal-mode isearch-slow-terminal-mode)
	      (isearch-small-window isearch-small-window)
	      (isearch-recursive-edit isearch-recursive-edit)
	      ;; Save current configuration so we can restore it here.
	      (isearch-window-configuration (current-window-configuration))
	      ;; This could protect the index of the search rings,
	      ;; but we can't reliably count the number of typed M-p
	      ;; in `read-from-minibuffer' to adjust the index accordingly.
	      ;; So when the following is commented out, `isearch-mode'
	      ;; below resets the index to the predictable value nil.
	      ;; (search-ring-yank-pointer search-ring-yank-pointer)
	      ;; (regexp-search-ring-yank-pointer
regexp-search-ring-yank-pointer)
	      ;; Temporarily restore `minibuffer-message-timeout'.
	      (minibuffer-message-timeout
	       isearch-original-minibuffer-message-timeout)
	      (isearch-original-minibuffer-message-timeout
	       isearch-original-minibuffer-message-timeout)
	      old-point old-other-end)
	  ;; Actually terminate isearching until editing is done.
	  ;; This is so that the user can do anything without failure,
	  ;; like switch buffers and start another isearch, and return.
	  (condition-case nil
	      (isearch-done t t)
	    (exit nil))			; was recursive editing
	  ;; Save old point and isearch-other-end before reading from minibuffer
	  ;; that can change their values.
	  (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
                       (concat
                        isearch-string

                       ;; ========= THIS IS ALL THAT'S NEW =========
                        (string (read-char-by-name "Unicode (name or hex): ")))

                       isearch-new-message
                       (mapconcat 'isearch-text-char-description
                                  isearch-new-string "")))
	    ;; Set point at the start (end) of old match if forward (backward),
	    ;; so after exiting minibuffer isearch resumes at the start (end)
	    ;; of this match and can find it again.
	    (if (and old-other-end (eq old-point (point))
		     (eq isearch-forward isearch-new-forward))
		(goto-char old-other-end))
	    ;; Always resume isearching by restarting it.
	    (isearch-mode isearch-forward
			  isearch-regexp
			  isearch-op-fun
			  nil
			  isearch-word)
	    ;; Copy new local values to isearch globals
	    (setq isearch-string isearch-new-string
		  isearch-message isearch-new-message
		  isearch-forward isearch-new-forward
		  isearch-word isearch-new-word
		  isearch-case-fold-search isearch-new-case-fold))
	  ;; Empty isearch-string means use default.
	  (when (= 0 (length isearch-string))
	    (setq isearch-string (or (car (if isearch-regexp
					      regexp-search-ring
					    search-ring))
				     "")
		  isearch-message
		  (mapconcat 'isearch-text-char-description
			     isearch-string ""))
	    ;; After taking the last element, adjust ring to previous one.
	    (isearch-ring-adjust1 nil)))
	;; This used to push the state as of before this C-s, but it adds
	;; an inconsistent state where part of variables are from the
	;; previous search (e.g. `isearch-success'), and part of variables
	;; are just entered from the minibuffer (e.g. `isearch-string').
	;; (isearch-push-state)
	;; Reinvoke the pending search.
	(isearch-search)
	(isearch-push-state)           ; this pushes the correct state
	(isearch-update)
	(if isearch-nonincremental
	    (progn
	      ;; (sit-for 1) ;; needed if isearch-done does: (message "")
	      (isearch-done)
	      ;; The search done message is confusing when the string
	      ;; is empty, so erase it.
	      (if (equal isearch-string "")
		  (message "")))))
    (quit            ; handle abort-recursive-edit
     (isearch-abort) ;; outside of let to restore outside global values
     )))




  reply	other threads:[~2012-12-09  5:33 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 [this message]
2012-12-10  7:46   ` Juri Linkov
2012-12-10 14:24     ` Drew Adams
2012-12-10 21:57       ` Juri Linkov
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=9A96D353A11D47A7A143074DB1E09EE4@us.oracle.com \
    --to=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).