GNU bug report logs - #15200
isearch-other-meta-char and shift

Previous Next

Package: emacs;

Reported by: Juri Linkov <juri <at> jurta.org>

Date: Tue, 27 Aug 2013 16:30:02 UTC

Severity: normal

Merged with 15383, 15544

Found in version 24.3.50

Done: Juri Linkov <juri <at> jurta.org>

Bug is archived. No further changes may be made.

To add a comment to this bug, you must first unarchive it, by sending
a message to control AT debbugs.gnu.org, with unarchive 15200 in the body.
You can then email your comments to 15200 AT debbugs.gnu.org in the normal way.

Toggle the display of automated, internal messages from the tracker.

View this report as an mbox folder, status mbox, maintainer mbox


Report forwarded to bug-gnu-emacs <at> gnu.org:
bug#15200; Package emacs. (Tue, 27 Aug 2013 16:30:02 GMT) Full text and rfc822 format available.

Acknowledgement sent to Juri Linkov <juri <at> jurta.org>:
New bug report received and forwarded. Copy sent to bug-gnu-emacs <at> gnu.org. (Tue, 27 Aug 2013 16:30:03 GMT) Full text and rfc822 format available.

Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Juri Linkov <juri <at> jurta.org>
To: bug-gnu-emacs <at> gnu.org
Subject: isearch-other-meta-char and shift
Date: Tue, 27 Aug 2013 19:28:22 +0300
There is a problem in `isearch-other-meta-char' with shifted characters.
Typing <S-kp-0> exits Isearch instead of adding 0 to the search string.

A possible fix is to handle shifted kp-numbers like
shifted control characters are handled in the second
`cond' branch of `isearch-other-meta-char':

=== modified file 'lisp/isearch.el'
--- lisp/isearch.el	2013-07-05 20:15:32 +0000
+++ lisp/isearch.el	2013-08-27 16:27:45 +0000
@@ -2550,6 +2606,16 @@ (defun isearch-other-meta-char (&optiona
 		    (lookup-key local-function-key-map key)))
 	     (while keylist
 	       (setq key (car keylist))
+	       ;; Handle an undefined shifted printing character
+	       ;; by downshifting it if that makes it printing.
+	       ;; (As read-key-sequence would normally do,
+	       ;; if we didn't have a default definition.)
+	       (if (and (integerp key)
+			(memq 'shift (event-modifiers key))
+			(>= key (+ ?\s (- ?\S-a ?a)))
+			(/= key (+ 127 (- ?\S-a ?a)))
+			(<  key (+ 256 (- ?\S-a ?a))))
+		   (setq key (- key (- ?\S-a ?a))))
 	       ;; If KEY is a printing char, we handle it here
 	       ;; directly to avoid the input method and keyboard
 	       ;; coding system translating it.





Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#15200; Package emacs. (Tue, 27 Aug 2013 16:49:02 GMT) Full text and rfc822 format available.

Message #8 received at 15200 <at> debbugs.gnu.org (full text, mbox):

From: Juri Linkov <juri <at> jurta.org>
To: 15200 <at> debbugs.gnu.org
Subject: Re: bug#15200: isearch-other-meta-char and shift
Date: Tue, 27 Aug 2013 19:45:51 +0300
Another problem is that shifted cursor motion keys
don't activate the region.  Test case:
`C-s S-right' exits isearch (OK),
moves cursor to the right (OK),
but doesn't activate the region (BUG).

The same bug is for other shift-selection keys:
`C-s S-C-right', `C-s S-C-f', `C-s S-M-f' don't activate
the region like they do outside of isearch.

I see that the shift key is swallowed by `read-key-sequence'
in `isearch-reread-key-sequence-naturally' called from
`isearch-other-meta-char'.

However, when the argument DONT-DOWNCASE-LAST of `read-key-sequence'
is non-nil, it doesn't translate shifted keys and leaves
shift-modifiers with them in `unread-command-events':

=== modified file 'lisp/isearch.el'
--- lisp/isearch.el	2013-07-05 20:15:32 +0000
+++ lisp/isearch.el	2013-08-27 16:38:41 +0000
@@ -2502,7 +2556,9 @@ (defun isearch-reread-key-sequence-natur
 Return the key sequence as a string/vector."
   (isearch-unread-key-sequence keylist)
   (let (overriding-terminal-local-map)
-    (read-key-sequence nil)))  ; This will go through function-key-map, if nec.
+    ;; This will go through function-key-map, if nec.
+    ;; The arg DONT-DOWNCASE-LAST prevents premature shift-translation.
+    (read-key-sequence nil nil t)))
 
 (defalias 'isearch-other-control-char 'isearch-other-meta-char)
 




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#15200; Package emacs. (Wed, 28 Aug 2013 00:28:02 GMT) Full text and rfc822 format available.

Message #11 received at 15200 <at> debbugs.gnu.org (full text, mbox):

From: Stefan Monnier <monnier <at> iro.umontreal.ca>
To: Juri Linkov <juri <at> jurta.org>
Cc: 15200 <at> debbugs.gnu.org
Subject: Re: bug#15200: isearch-other-meta-char and shift
Date: Tue, 27 Aug 2013 20:27:18 -0400
> Another problem is that shifted cursor motion keys
> don't activate the region.  Test case:

These are all the kinds of problems one gets into when one reads events
and then want to re-read them in a different context.

My hope is that these kinds of problems would all disappear if we
re-implemented isearch using set-temporary-overlay-map, which would save
us from having to re-read events.


        Stefan




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#15200; Package emacs. (Wed, 28 Aug 2013 16:44:02 GMT) Full text and rfc822 format available.

Message #14 received at 15200 <at> debbugs.gnu.org (full text, mbox):

From: Juri Linkov <juri <at> jurta.org>
To: Stefan Monnier <monnier <at> iro.umontreal.ca>
Cc: 15200 <at> debbugs.gnu.org
Subject: Re: bug#15200: isearch-other-meta-char and shift
Date: Wed, 28 Aug 2013 19:42:28 +0300
> My hope is that these kinds of problems would all disappear if we
> re-implemented isearch using set-temporary-overlay-map, which would save
> us from having to re-read events.

After installing small fixes I'm not closing this report
while trying to re-implement it using set-temporary-overlay-map.

IIUC, the biggest challenge is to add a new argument
to set-temporary-overlay-map that will define a predicate
to decide whether this-command-keys should be applied to
key bindings of the overriding temporary map or passed through
to other less specific keymaps.  This predicate is necessary
when the decision to select a keymap to apply keys
depends on a property put on a bound command's symbol
like isearch-scroll properties.

Such a predicate could be implemented as a hook-like variable
or with the help of add-function like is used now for
isearch-filter-predicate.  Then additional predicates
could be added to the almost empty default function
isearch-other-control-char.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#15200; Package emacs. (Wed, 28 Aug 2013 18:34:01 GMT) Full text and rfc822 format available.

Message #17 received at 15200 <at> debbugs.gnu.org (full text, mbox):

From: Stefan Monnier <monnier <at> IRO.UMontreal.CA>
To: Juri Linkov <juri <at> jurta.org>
Cc: 15200 <at> debbugs.gnu.org
Subject: Re: bug#15200: isearch-other-meta-char and shift
Date: Wed, 28 Aug 2013 14:33:29 -0400
> while trying to re-implement it using set-temporary-overlay-map.

That sounds great.  Keep us informed of your progress.

> IIUC, the biggest challenge is to add a new argument
> to set-temporary-overlay-map that will define a predicate
> to decide whether this-command-keys should be applied to
> key bindings of the overriding temporary map or passed through
> to other less specific keymaps.

Not sure I understand.  Why do we need to look at this-command-keys?
Are you keeping the default [t] binding in isearch-mode-map, maybe?
That would defeat the purpose of using set-temporary-overlay-map,
I think.


        Stefan




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#15200; Package emacs. (Thu, 29 Aug 2013 06:56:01 GMT) Full text and rfc822 format available.

Message #20 received at 15200 <at> debbugs.gnu.org (full text, mbox):

From: Juri Linkov <juri <at> jurta.org>
To: Stefan Monnier <monnier <at> IRO.UMontreal.CA>
Cc: 15200 <at> debbugs.gnu.org
Subject: Re: bug#15200: isearch-other-meta-char and shift
Date: Thu, 29 Aug 2013 09:49:47 +0300
>> IIUC, the biggest challenge is to add a new argument
>> to set-temporary-overlay-map that will define a predicate
>> to decide whether this-command-keys should be applied to
>> key bindings of the overriding temporary map or passed through
>> to other less specific keymaps.
>
> Not sure I understand.  Why do we need to look at this-command-keys?
> Are you keeping the default [t] binding in isearch-mode-map, maybe?
> That would defeat the purpose of using set-temporary-overlay-map,
> I think.

Hmm, I can't imagine how to keep the isearch-allow-scroll feature
and other conditional exiting features like search-exit-option
without keeping the default [t] binding in isearch-mode-map
to the function like the current isearch-other-meta-char
where these conditions can be checked.

Maybe the arg KEEP-PRED set-temporary-overlay-map
can be used to decide whether to exit Isearch and
apply the key sequence to global keymaps?




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#15200; Package emacs. (Thu, 29 Aug 2013 12:31:01 GMT) Full text and rfc822 format available.

Message #23 received at 15200 <at> debbugs.gnu.org (full text, mbox):

From: Stefan Monnier <monnier <at> iro.umontreal.ca>
To: Juri Linkov <juri <at> jurta.org>
Cc: 15200 <at> debbugs.gnu.org
Subject: Re: bug#15200: isearch-other-meta-char and shift
Date: Thu, 29 Aug 2013 08:30:52 -0400
> Maybe the arg KEEP-PRED set-temporary-overlay-map
> can be used to decide whether to exit Isearch and
> apply the key sequence to global keymaps?

Of course:

   KEEP-PRED can also be a function of no arguments: if it returns
   non-nil then MAP stays active.

KEEP-PRED is run in pre-command-hook, so it can check this-command.


        Stefan




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#15200; Package emacs. (Sun, 01 Sep 2013 18:51:01 GMT) Full text and rfc822 format available.

Message #26 received at 15200 <at> debbugs.gnu.org (full text, mbox):

From: Juri Linkov <juri <at> jurta.org>
To: Stefan Monnier <monnier <at> iro.umontreal.ca>
Cc: 15200 <at> debbugs.gnu.org
Subject: Re: bug#15200: isearch-other-meta-char and shift
Date: Sun, 01 Sep 2013 21:45:09 +0300
>> Maybe the arg KEEP-PRED set-temporary-overlay-map
>> can be used to decide whether to exit Isearch and
>> apply the key sequence to global keymaps?
>
> Of course:
>
>    KEEP-PRED can also be a function of no arguments: if it returns
>    non-nil then MAP stays active.
>
> KEEP-PRED is run in pre-command-hook, so it can check this-command.

Surprisingly, I see no problems with this approach.
First I tried to implement the logic of KEEP-PRED
without using set-temporary-overlay-map, i.e.
by adding a new function isearch-mode-keep-pred
to pre-command-hook.  isearch-mode-keep-pred is created
from isearch-other-meta-char by removing all re-reading,
and adding a new condition

  ((lookup-key isearch-mode-map key nil))

to not exit Isearch mode for Isearch key bindings.
Otherwise, Isearch mode is exited by isearch-done
and this-command is executed in global context.

Later isearch-mode-keep-pred could be further simplified,
e.g. instead of calling command-execute for
isearch-allow-scroll, it could pass execution
to global key binding and add isearch post-processing
of isearch-back-into-window to post-command-hook, etc.

=== modified file 'lisp/isearch.el'
--- lisp/isearch.el	2013-08-28 16:39:51 +0000
+++ lisp/isearch.el	2013-09-01 18:42:04 +0000
@@ -349,7 +349,6 @@ (defvar lazy-highlight-face 'lazy-highli
 
 (defvar isearch-help-map
   (let ((map (make-sparse-keymap)))
-    (define-key map [t] 'isearch-other-control-char)
     (define-key map (char-to-string help-char) 'isearch-help-for-help)
     (define-key map [help] 'isearch-help-for-help)
     (define-key map [f1] 'isearch-help-for-help)
@@ -423,9 +422,6 @@ (defvar isearch-mode-map
     ;; Make all multibyte characters search for themselves.
     (set-char-table-range (nth 1 map) (cons #x100 (max-char))
 			  'isearch-printing-char)
-    ;; Make function keys, etc, which aren't bound to a scrolling-function
-    ;; exit the search.
-    (define-key map [t] 'isearch-other-control-char)
 
     ;; Single-byte printing chars extend the search string by default.
     (setq i ?\s)
@@ -440,8 +436,7 @@ (defvar isearch-mode-map
     ;; default local key binding for any key not otherwise bound.
     (let ((meta-map (make-sparse-keymap)))
       (define-key map (char-to-string meta-prefix-char) meta-map)
-      (define-key map [escape] meta-map)
-      (define-key meta-map [t] 'isearch-other-meta-char))
+      (define-key map [escape] meta-map))
 
     ;; Several non-printing chars change the searching behavior.
     (define-key map "\C-s" 'isearch-repeat-forward)
@@ -521,9 +516,6 @@ (defvar isearch-mode-map
 
     ;; The key translations defined in the C-x 8 prefix should add
     ;; characters to the search string.  See iso-transl.el.
-    (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-char-by-name)
 
     map)
@@ -920,6 +912,7 @@ (defun isearch-mode (forward &optional r
 
   (isearch-update)
 
+  (add-hook 'pre-command-hook 'isearch-mode-keep-pred)
   (add-hook 'mouse-leave-buffer-hook 'isearch-done)
   (add-hook 'kbd-macro-termination-hook 'isearch-done)
 
@@ -998,6 +991,7 @@ (defun isearch-done (&optional nopush ed
 	(unless (equal (car command-history) command)
 	  (setq command-history (cons command command-history)))))
 
+  (remove-hook 'pre-command-hook 'isearch-mode-keep-pred)
   (remove-hook 'mouse-leave-buffer-hook 'isearch-done)
   (remove-hook 'kbd-macro-termination-hook 'isearch-done)
   (setq isearch-lazy-highlight-start nil)
@@ -2100,26 +2094,6 @@ (defun isearch-fallback (want-backslash
 			 (min last-other-end isearch-barrier)))
 	    (setq isearch-adjusted t)))))))
 
-(defun isearch-unread-key-sequence (keylist)
-  "Unread the given key-sequence KEYLIST.
-Scroll-bar or mode-line events are processed appropriately."
-  (cancel-kbd-macro-events)
-  (apply 'isearch-unread keylist)
-  ;; If the event was a scroll-bar or mode-line click, the event will have
-  ;; been prefixed by a symbol such as vertical-scroll-bar.  We must remove
-  ;; it here, because this symbol will be attached to the event again next
-  ;; time it gets read by read-key-sequence.
-  ;;
-  ;; (Old comment from isearch-other-meta-char: "Note that we don't have to
-  ;; modify the event anymore in 21 because read_key_sequence no longer
-  ;; modifies events to produce fake prefix keys.")
-  (if (and (> (length keylist) 1)
-           (symbolp (car keylist))
-           (listp (cadr keylist))
-           (not (numberp (posn-point
-                          (event-start (cadr keylist)  )))))
-      (pop unread-command-events)))
-
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; scrolling within Isearch mode.  Alan Mackenzie (acm <at> muc.de), 2003/2/24
 ;;
@@ -2244,15 +2218,6 @@ (defun isearch-back-into-window (above i
         (recenter 0))))
   (goto-char isearch-point))
 
-(defun isearch-reread-key-sequence-naturally (keylist)
-  "Reread key sequence KEYLIST with an inactive Isearch-mode keymap.
-Return the key sequence as a string/vector."
-  (isearch-unread-key-sequence keylist)
-  (let (overriding-terminal-local-map)
-    ;; This will go through function-key-map, if nec.
-    ;; The arg DONT-DOWNCASE-LAST prevents premature shift-translation.
-    (read-key-sequence nil nil t)))
-
 (defun isearch-lookup-scroll-key (key-seq)
   "If KEY-SEQ is bound to a scrolling command, return it as a symbol.
 Otherwise return nil."
@@ -2263,47 +2228,25 @@ (defun isearch-lookup-scroll-key (key-se
 	     (eq (get binding 'scroll-command) t))
          binding)))
 
-(defalias 'isearch-other-control-char 'isearch-other-meta-char)
-
-(defun isearch-other-meta-char (&optional arg)
-  "Process a miscellaneous key sequence in Isearch mode.
-
-Try to convert the current key-sequence to something usable in Isearch
-mode, either by converting it with `function-key-map', downcasing a
-key with C-<upper case>, or finding a \"scrolling command\" bound to
-it.  \(In the last case, we may have to read more events.)  If so,
-either unread the converted sequence or execute the command.
-
-Otherwise, if `search-exit-option' is non-nil (the default) unread the
-key-sequence and exit the search normally.  If it is the symbol
-`edit', the search string is edited in the minibuffer and the meta
-character is unread so that it applies to editing the string.
-
-ARG is the prefix argument.  It will be transmitted through to the
-scrolling command or to the command whose key-sequence exits
-Isearch mode."
-  (interactive "P")
+(defun isearch-mode-keep-pred ()
   (let* ((key (if current-prefix-arg    ; not nec the same as ARG
                   (substring (this-command-keys) universal-argument-num-events)
                 (this-command-keys)))
 	 (main-event (aref key 0))
 	 (keylist (listify-key-sequence key))
          scroll-command isearch-point)
-    (cond ((and (= (length key) 1)
+    (cond ((lookup-key isearch-mode-map key nil))
+	  ((and (= (length key) 1)
 		(let ((lookup (lookup-key local-function-key-map key)))
 		  (not (or (null lookup) (integerp lookup)
 			   (keymapp lookup)))))
 	   ;; Handle a function key that translates into something else.
 	   ;; If the key has a global definition too,
-	   ;; exit and unread the key itself, so its global definition runs.
-	   ;; Otherwise, unread the translation,
-	   ;; so that the translated key takes effect within isearch.
-	   (cancel-kbd-macro-events)
+	   ;; exit, so its global definition runs.
+	   ;; Otherwise, translated key takes effect within isearch.
 	   (if (lookup-key global-map key)
 	       (progn
-		 (isearch-done)
-		 (setq prefix-arg arg)
-		 (apply 'isearch-unread keylist))
+		 (isearch-done))
 	     (setq keylist
 		   (listify-key-sequence
 		    (lookup-key local-function-key-map key)))
@@ -2311,8 +2254,6 @@ (defun isearch-other-meta-char (&optiona
 	       (setq key (car keylist))
 	       ;; Handle an undefined shifted printing character
 	       ;; by downshifting it if that makes it printing.
-	       ;; (As read-key-sequence would normally do,
-	       ;; if we didn't have a default definition.)
 	       (if (and (integerp key)
 			(memq 'shift (event-modifiers key))
 			(>= key (+ ?\s (- ?\S-a ?a)))
@@ -2331,15 +2272,11 @@ (defun isearch-other-meta-char (&optiona
 		     (isearch-process-search-char key)
 		     (setq keylist (cdr keylist)))
 		 ;; As the remaining keys in KEYLIST can't be handled
-		 ;; here, we must reread them.
-		 (setq prefix-arg arg)
-		 (apply 'isearch-unread keylist)
-		 (setq keylist nil)))))
+		 ;; here, exit.
+		 (isearch-done)))))
 	  (
 	   ;; Handle an undefined shifted control character
 	   ;; by downshifting it if that makes it defined.
-	   ;; (As read-key-sequence would normally do,
-	   ;; if we didn't have a default definition.)
 	   (let ((mods (event-modifiers main-event)))
 	     (and (integerp main-event)
 		  (memq 'shift mods)
@@ -2352,20 +2289,13 @@ (defun isearch-other-meta-char (&optiona
 					   copy)
 					 nil)
 			     '(nil
-			       isearch-other-control-char)))))
+			       )))))
 	   (setcar keylist (- main-event (- ?\C-\S-a ?\C-a)))
-	   (cancel-kbd-macro-events)
-	   (setq prefix-arg arg)
-	   (apply 'isearch-unread keylist))
+	   (isearch-done))
 	  ((eq search-exit-option 'edit)
-	   (setq prefix-arg arg)
-	   (apply 'isearch-unread keylist)
 	   (isearch-edit-string))
           ;; Handle a scrolling function or prefix argument.
           ((progn
-	     (setq key (isearch-reread-key-sequence-naturally keylist)
-		   keylist (listify-key-sequence key)
-		   main-event (aref key 0))
 	     (or (and isearch-allow-scroll
 		      (setq scroll-command (isearch-lookup-scroll-key key)))
 		 (and isearch-allow-prefix
@@ -2374,12 +2304,7 @@ (defun isearch-other-meta-char (&optiona
 			(memq scroll-command
 			      '(universal-argument
 				negative-argument digit-argument))))))
-           ;; From this point onwards, KEY, KEYLIST and MAIN-EVENT hold a
-           ;; complete key sequence, possibly as modified by function-key-map,
-           ;; not merely the one or two event fragment which invoked
-           ;; isearch-other-meta-char in the first place.
            (setq isearch-point (point))
-           (setq prefix-arg arg)
            (command-execute scroll-command)
            (let ((ab-bel (isearch-string-out-of-window isearch-point)))
              (if ab-bel
@@ -2394,16 +2319,6 @@ (defun isearch-other-meta-char (&optiona
 	   (isearch-edit-string))
 	  (search-exit-option
 	   (let (window)
-	     (setq prefix-arg arg)
-             (isearch-unread-key-sequence keylist)
-             (setq main-event (car unread-command-events))
-
-	     ;; Don't store special commands in the keyboard macro.
-	     (let (overriding-terminal-local-map)
-	       (when (memq (key-binding key)
-			   '(kmacro-start-macro
-			     kmacro-end-macro kmacro-end-and-call-macro))
-		 (cancel-kbd-macro-events)))
 
 	     ;; If we got a mouse click event, that event contains the
 	     ;; window clicked on. maybe it was read with the buffer
@@ -2432,8 +2347,7 @@ (defun isearch-other-meta-char (&optiona
 		   (isearch-done)
 		   (isearch-clean-overlays))
 	       (isearch-done)
-	       (isearch-clean-overlays)
-               (setq prefix-arg arg))))
+	       (isearch-clean-overlays))))
           (t;; otherwise nil
 	   (isearch-process-search-string key key)))))
 




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#15200; Package emacs. (Tue, 03 Sep 2013 02:13:01 GMT) Full text and rfc822 format available.

Message #29 received at 15200 <at> debbugs.gnu.org (full text, mbox):

From: Stefan Monnier <monnier <at> iro.umontreal.ca>
To: Juri Linkov <juri <at> jurta.org>
Cc: 15200 <at> debbugs.gnu.org
Subject: Re: bug#15200: isearch-other-meta-char and shift
Date: Mon, 02 Sep 2013 22:12:14 -0400
> Surprisingly, I see no problems with this approach.

Oh, right without using set-temporary-overlay-map at all, but only
relying on the new behavior of overriding-terminal-local-map.
Yes, that should work fine.

> +    (cond ((lookup-key isearch-mode-map key nil))
> +	  ((and (= (length key) 1)
>  		(let ((lookup (lookup-key local-function-key-map key)))
>  		  (not (or (null lookup) (integerp lookup)
>  			   (keymapp lookup)))))

We should not need to consider local-function-key-map any more.


        Stefan




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#15200; Package emacs. (Tue, 03 Sep 2013 02:23:01 GMT) Full text and rfc822 format available.

Message #32 received at 15200 <at> debbugs.gnu.org (full text, mbox):

From: Drew Adams <drew.adams <at> oracle.com>
To: Stefan Monnier <monnier <at> iro.umontreal.ca>, Juri Linkov <juri <at> jurta.org>
Cc: 15200 <at> debbugs.gnu.org
Subject: RE: bug#15200: isearch-other-meta-char and shift
Date: Mon, 2 Sep 2013 19:22:34 -0700 (PDT)
> > Surprisingly, I see no problems with this approach.
> 
> Oh, right without using set-temporary-overlay-map at all, but only
> relying on the new behavior of overriding-terminal-local-map.
> Yes, that should work fine.

I hope this kind of thing will be made clear in the Elisp manual by
the time Emacs 24.4 is released.  It's not very clear to me yet; I
look forward to learning a bit more about it.

I see that there is a NEWS item about `overriding-terminal-local-map'
for Emacs 24.4 (good), but the Elisp manual does not seem up-to-date
about it yet.




Merged 15200 15383. Request was from Juri Linkov <juri <at> jurta.org> to control <at> debbugs.gnu.org. (Mon, 16 Sep 2013 21:37:03 GMT) Full text and rfc822 format available.

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#15200; Package emacs. (Mon, 16 Sep 2013 22:18:01 GMT) Full text and rfc822 format available.

Message #37 received at 15200 <at> debbugs.gnu.org (full text, mbox):

From: Juri Linkov <juri <at> jurta.org>
To: Stefan Monnier <monnier <at> iro.umontreal.ca>
Cc: 15200 <at> debbugs.gnu.org
Subject: Re: bug#15200: isearch-other-meta-char and shift
Date: Tue, 17 Sep 2013 01:09:36 +0300
>> Surprisingly, I see no problems with this approach.
>
> Oh, right without using set-temporary-overlay-map at all, but only
> relying on the new behavior of overriding-terminal-local-map.
> Yes, that should work fine.

set-temporary-overlay-map could be added later too if possible.

>> +    (cond ((lookup-key isearch-mode-map key nil))
>> +	  ((and (= (length key) 1)
>>  		(let ((lookup (lookup-key local-function-key-map key)))
>>  		  (not (or (null lookup) (integerp lookup)
>>  			   (keymapp lookup)))))
>
> We should not need to consider local-function-key-map any more.

Maybe I'm missing something, but it seems working without
local-function-key-map and without much of other legacy code.

Also I removed `universal-argument-num-events' in the patch,
but now typing:
`C-s C-3 C-l' doubles the arg 3 in prefix-arg to 33,
`C-s C-4 C-l' doubles the arg 4 in prefix-arg to 44, etc.

This happens after this code:

			(memq scroll-command
			      '(universal-argument
				negative-argument digit-argument))))))
           (command-execute scroll-command)

Perhaps `command-execute' should be removed here.
It's not yet removed in this patch since I'm not sure
because after moving its post-processing code:

           (let ((ab-bel (isearch-string-out-of-window isearch-point)))
             (if ab-bel
                 (isearch-back-into-window (eq ab-bel 'above) isearch-point)
               (goto-char isearch-point)))

to `post-command-hook' will make impossible to use later
`set-temporary-overlay-map' (that doesn't use `post-command-hook'
but maybe this is not a problem).

=== modified file 'lisp/isearch.el'
--- lisp/isearch.el	2013-08-28 16:39:51 +0000
+++ lisp/isearch.el	2013-09-16 22:08:10 +0000
@@ -349,7 +349,6 @@ (defvar lazy-highlight-face 'lazy-highli
 
 (defvar isearch-help-map
   (let ((map (make-sparse-keymap)))
-    (define-key map [t] 'isearch-other-control-char)
     (define-key map (char-to-string help-char) 'isearch-help-for-help)
     (define-key map [help] 'isearch-help-for-help)
     (define-key map [f1] 'isearch-help-for-help)
@@ -423,9 +422,6 @@ (defvar isearch-mode-map
     ;; Make all multibyte characters search for themselves.
     (set-char-table-range (nth 1 map) (cons #x100 (max-char))
 			  'isearch-printing-char)
-    ;; Make function keys, etc, which aren't bound to a scrolling-function
-    ;; exit the search.
-    (define-key map [t] 'isearch-other-control-char)
 
     ;; Single-byte printing chars extend the search string by default.
     (setq i ?\s)
@@ -440,8 +436,7 @@ (defvar isearch-mode-map
     ;; default local key binding for any key not otherwise bound.
     (let ((meta-map (make-sparse-keymap)))
       (define-key map (char-to-string meta-prefix-char) meta-map)
-      (define-key map [escape] meta-map)
-      (define-key meta-map [t] 'isearch-other-meta-char))
+      (define-key map [escape] meta-map))
 
     ;; Several non-printing chars change the searching behavior.
     (define-key map "\C-s" 'isearch-repeat-forward)
@@ -521,9 +516,6 @@ (defvar isearch-mode-map
 
     ;; The key translations defined in the C-x 8 prefix should add
     ;; characters to the search string.  See iso-transl.el.
-    (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-char-by-name)
 
     map)
@@ -920,6 +912,7 @@ (defun isearch-mode (forward &optional r
 
   (isearch-update)
 
+  (add-hook 'pre-command-hook 'isearch-mode-keep-pred)
   (add-hook 'mouse-leave-buffer-hook 'isearch-done)
   (add-hook 'kbd-macro-termination-hook 'isearch-done)
 
@@ -998,6 +991,7 @@ (defun isearch-done (&optional nopush ed
 	(unless (equal (car command-history) command)
 	  (setq command-history (cons command command-history)))))
 
+  (remove-hook 'pre-command-hook 'isearch-mode-keep-pred)
   (remove-hook 'mouse-leave-buffer-hook 'isearch-done)
   (remove-hook 'kbd-macro-termination-hook 'isearch-done)
   (setq isearch-lazy-highlight-start nil)
@@ -2100,26 +2094,6 @@ (defun isearch-fallback (want-backslash
 			 (min last-other-end isearch-barrier)))
 	    (setq isearch-adjusted t)))))))
 
-(defun isearch-unread-key-sequence (keylist)
-  "Unread the given key-sequence KEYLIST.
-Scroll-bar or mode-line events are processed appropriately."
-  (cancel-kbd-macro-events)
-  (apply 'isearch-unread keylist)
-  ;; If the event was a scroll-bar or mode-line click, the event will have
-  ;; been prefixed by a symbol such as vertical-scroll-bar.  We must remove
-  ;; it here, because this symbol will be attached to the event again next
-  ;; time it gets read by read-key-sequence.
-  ;;
-  ;; (Old comment from isearch-other-meta-char: "Note that we don't have to
-  ;; modify the event anymore in 21 because read_key_sequence no longer
-  ;; modifies events to produce fake prefix keys.")
-  (if (and (> (length keylist) 1)
-           (symbolp (car keylist))
-           (listp (cadr keylist))
-           (not (numberp (posn-point
-                          (event-start (cadr keylist)  )))))
-      (pop unread-command-events)))
-
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; scrolling within Isearch mode.  Alan Mackenzie (acm <at> muc.de), 2003/2/24
 ;;
@@ -2244,15 +2218,6 @@ (defun isearch-back-into-window (above i
         (recenter 0))))
   (goto-char isearch-point))
 
-(defun isearch-reread-key-sequence-naturally (keylist)
-  "Reread key sequence KEYLIST with an inactive Isearch-mode keymap.
-Return the key sequence as a string/vector."
-  (isearch-unread-key-sequence keylist)
-  (let (overriding-terminal-local-map)
-    ;; This will go through function-key-map, if nec.
-    ;; The arg DONT-DOWNCASE-LAST prevents premature shift-translation.
-    (read-key-sequence nil nil t)))
-
 (defun isearch-lookup-scroll-key (key-seq)
   "If KEY-SEQ is bound to a scrolling command, return it as a symbol.
 Otherwise return nil."
@@ -2263,109 +2228,16 @@ (defun isearch-lookup-scroll-key (key-se
 	     (eq (get binding 'scroll-command) t))
          binding)))
 
-(defalias 'isearch-other-control-char 'isearch-other-meta-char)
-
-(defun isearch-other-meta-char (&optional arg)
-  "Process a miscellaneous key sequence in Isearch mode.
-
-Try to convert the current key-sequence to something usable in Isearch
-mode, either by converting it with `function-key-map', downcasing a
-key with C-<upper case>, or finding a \"scrolling command\" bound to
-it.  \(In the last case, we may have to read more events.)  If so,
-either unread the converted sequence or execute the command.
-
-Otherwise, if `search-exit-option' is non-nil (the default) unread the
-key-sequence and exit the search normally.  If it is the symbol
-`edit', the search string is edited in the minibuffer and the meta
-character is unread so that it applies to editing the string.
-
-ARG is the prefix argument.  It will be transmitted through to the
-scrolling command or to the command whose key-sequence exits
-Isearch mode."
-  (interactive "P")
-  (let* ((key (if current-prefix-arg    ; not nec the same as ARG
-                  (substring (this-command-keys) universal-argument-num-events)
-                (this-command-keys)))
+(defun isearch-mode-keep-pred ()
+  (let* ((key (this-command-keys))
 	 (main-event (aref key 0))
 	 (keylist (listify-key-sequence key))
          scroll-command isearch-point)
-    (cond ((and (= (length key) 1)
-		(let ((lookup (lookup-key local-function-key-map key)))
-		  (not (or (null lookup) (integerp lookup)
-			   (keymapp lookup)))))
-	   ;; Handle a function key that translates into something else.
-	   ;; If the key has a global definition too,
-	   ;; exit and unread the key itself, so its global definition runs.
-	   ;; Otherwise, unread the translation,
-	   ;; so that the translated key takes effect within isearch.
-	   (cancel-kbd-macro-events)
-	   (if (lookup-key global-map key)
-	       (progn
-		 (isearch-done)
-		 (setq prefix-arg arg)
-		 (apply 'isearch-unread keylist))
-	     (setq keylist
-		   (listify-key-sequence
-		    (lookup-key local-function-key-map key)))
-	     (while keylist
-	       (setq key (car keylist))
-	       ;; Handle an undefined shifted printing character
-	       ;; by downshifting it if that makes it printing.
-	       ;; (As read-key-sequence would normally do,
-	       ;; if we didn't have a default definition.)
-	       (if (and (integerp key)
-			(memq 'shift (event-modifiers key))
-			(>= key (+ ?\s (- ?\S-a ?a)))
-			(/= key (+ 127 (- ?\S-a ?a)))
-			(<  key (+ 256 (- ?\S-a ?a))))
-		   (setq key (- key (- ?\S-a ?a))))
-	       ;; If KEY is a printing char, we handle it here
-	       ;; directly to avoid the input method and keyboard
-	       ;; coding system translating it.
-	       (if (and (integerp key)
-			(>= key ?\s) (/= key 127) (< key 256))
-		   (progn
-		     ;; Ensure that the processed char is recorded in
-		     ;; the keyboard macro, if any (Bug#4894)
-		     (store-kbd-macro-event key)
-		     (isearch-process-search-char key)
-		     (setq keylist (cdr keylist)))
-		 ;; As the remaining keys in KEYLIST can't be handled
-		 ;; here, we must reread them.
-		 (setq prefix-arg arg)
-		 (apply 'isearch-unread keylist)
-		 (setq keylist nil)))))
-	  (
-	   ;; Handle an undefined shifted control character
-	   ;; by downshifting it if that makes it defined.
-	   ;; (As read-key-sequence would normally do,
-	   ;; if we didn't have a default definition.)
-	   (let ((mods (event-modifiers main-event)))
-	     (and (integerp main-event)
-		  (memq 'shift mods)
-		  (memq 'control mods)
-		  (not (memq (lookup-key isearch-mode-map
-					 (let ((copy (copy-sequence key)))
-					   (aset copy 0
-						 (- main-event
-						    (- ?\C-\S-a ?\C-a)))
-					   copy)
-					 nil)
-			     '(nil
-			       isearch-other-control-char)))))
-	   (setcar keylist (- main-event (- ?\C-\S-a ?\C-a)))
-	   (cancel-kbd-macro-events)
-	   (setq prefix-arg arg)
-	   (apply 'isearch-unread keylist))
+    (cond ((lookup-key isearch-mode-map key nil))
 	  ((eq search-exit-option 'edit)
-	   (setq prefix-arg arg)
-	   (apply 'isearch-unread keylist)
 	   (isearch-edit-string))
           ;; Handle a scrolling function or prefix argument.
           ((progn
-	     (setq key (isearch-reread-key-sequence-naturally keylist)
-		   keylist (listify-key-sequence key)
-		   main-event (aref key 0))
 	     (or (and isearch-allow-scroll
 		      (setq scroll-command (isearch-lookup-scroll-key key)))
 		 (and isearch-allow-prefix
@@ -2374,12 +2246,7 @@ (defun isearch-other-meta-char (&optiona
 			(memq scroll-command
 			      '(universal-argument
 				negative-argument digit-argument))))))
-           ;; From this point onwards, KEY, KEYLIST and MAIN-EVENT hold a
-           ;; complete key sequence, possibly as modified by function-key-map,
-           ;; not merely the one or two event fragment which invoked
-           ;; isearch-other-meta-char in the first place.
            (setq isearch-point (point))
-           (setq prefix-arg arg)
            (command-execute scroll-command)
            (let ((ab-bel (isearch-string-out-of-window isearch-point)))
              (if ab-bel
@@ -2394,16 +2261,6 @@ (defun isearch-other-meta-char (&optiona
 	   (isearch-edit-string))
 	  (search-exit-option
 	   (let (window)
-	     (setq prefix-arg arg)
-             (isearch-unread-key-sequence keylist)
-             (setq main-event (car unread-command-events))
-
-	     ;; Don't store special commands in the keyboard macro.
-	     (let (overriding-terminal-local-map)
-	       (when (memq (key-binding key)
-			   '(kmacro-start-macro
-			     kmacro-end-macro kmacro-end-and-call-macro))
-		 (cancel-kbd-macro-events)))
 
 	     ;; If we got a mouse click event, that event contains the
 	     ;; window clicked on. maybe it was read with the buffer
@@ -2432,8 +2289,7 @@ (defun isearch-other-meta-char (&optiona
 		   (isearch-done)
 		   (isearch-clean-overlays))
 	       (isearch-done)
-	       (isearch-clean-overlays)
-               (setq prefix-arg arg))))
+	       (isearch-clean-overlays))))
           (t;; otherwise nil
 	   (isearch-process-search-string key key)))))
 




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#15200; Package emacs. (Tue, 17 Sep 2013 01:22:01 GMT) Full text and rfc822 format available.

Message #40 received at 15200 <at> debbugs.gnu.org (full text, mbox):

From: Stefan Monnier <monnier <at> iro.umontreal.ca>
To: Juri Linkov <juri <at> jurta.org>
Cc: 15200 <at> debbugs.gnu.org
Subject: Re: bug#15200: isearch-other-meta-char and shift
Date: Mon, 16 Sep 2013 21:21:30 -0400
> set-temporary-overlay-map could be added later too if possible.

Why bother?

> Maybe I'm missing something, but it seems working without
> local-function-key-map and without much of other legacy code.

That's the intention.  Much of that code was trying to reproduce the
normal behavior (prevented by the [t] binding), or to undo the direct
effect of the [t] binding.

> Also I removed `universal-argument-num-events' in the patch,
> but now typing:
> `C-s C-3 C-l' doubles the arg 3 in prefix-arg to 33,
> `C-s C-4 C-l' doubles the arg 4 in prefix-arg to 44, etc.

Aha, now it's getting more interesting: the interaction between various
commands using overriding-terminal-local-map.  I'll take a look at it.


        Stefan




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#15200; Package emacs. (Tue, 17 Sep 2013 02:20:01 GMT) Full text and rfc822 format available.

Message #43 received at 15200 <at> debbugs.gnu.org (full text, mbox):

From: Stefan Monnier <monnier <at> iro.umontreal.ca>
To: Juri Linkov <juri <at> jurta.org>
Cc: 15200 <at> debbugs.gnu.org
Subject: Re: bug#15200: isearch-other-meta-char and shift
Date: Mon, 16 Sep 2013 22:19:02 -0400
> This happens after this code:

> 			(memq scroll-command
> 			      '(universal-argument
> 				negative-argument digit-argument))))))
>            (command-execute scroll-command)

This code can be simplified as follows: `scroll-command' can be removed,
instead its value is immediately available as `this-command'.

> Perhaps `command-execute' should be removed here.

Indeed.  For isearch-allow-prefix, that's all that's needed.

> It's not yet removed in this patch since I'm not sure
> because after moving its post-processing code:

>            (let ((ab-bel (isearch-string-out-of-window isearch-point)))
>              (if ab-bel
>                  (isearch-back-into-window (eq ab-bel 'above) isearch-point)
>                (goto-char isearch-point)))

Yes, this needs to be moved to post-command-hook.
Another alternative is to do something like

   (setq this-command
         `(lambda () (interactive)
            (let ((isearch-point (point)))
              (command-execute ',this-command)
              (let ((ab-bel (isearch-string-out-of-window isearch-point)))
                (if ab-bel
                   (isearch-back-into-window (eq ab-bel 'above) isearch-point)
                 (goto-char isearch-point))))))

but this is probably going to bring us more trouble than it's worth.
                 

        Stefan




Merged 15200 15383 15544. Request was from Juri Linkov <juri <at> jurta.org> to control <at> debbugs.gnu.org. (Mon, 07 Oct 2013 00:07:03 GMT) Full text and rfc822 format available.

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#15200; Package emacs. (Tue, 08 Oct 2013 00:07:02 GMT) Full text and rfc822 format available.

Message #48 received at 15200 <at> debbugs.gnu.org (full text, mbox):

From: Juri Linkov <juri <at> jurta.org>
To: Stefan Monnier <monnier <at> iro.umontreal.ca>
Cc: 15200 <at> debbugs.gnu.org
Subject: Re: bug#15200: isearch-other-meta-char and shift
Date: Tue, 08 Oct 2013 02:35:25 +0300
>> 			(memq scroll-command
>> 			      '(universal-argument
>> 				negative-argument digit-argument))))))
>>            (command-execute scroll-command)
>
> This code can be simplified as follows: `scroll-command' can be removed,
> instead its value is immediately available as `this-command'.

In the next patch I replaced `scroll-command' with just `this-command'.

>>            (let ((ab-bel (isearch-string-out-of-window isearch-point)))
>>              (if ab-bel
>>                  (isearch-back-into-window (eq ab-bel 'above) isearch-point)
>>                (goto-char isearch-point)))
>
> Yes, this needs to be moved to post-command-hook.

This is moved now to `isearch-post-command-hook'.

Now everything works as it used to do before this patch,
with one exception: I still can't find a replacement
for universal-argument-num-events.

The problem is that when isearch-allow-prefix is non-nil
and isearch-allow-scroll is nil, then `C-u C-l' (where `C-l'
is bound globally to `recenter-top-bottom') should exit isearch,
but `C-u C-w' should not.  `C-w' is just an example of an isearch
command (isearch-yank-word-or-char).  Some isearch commands currently
don't accept a numeric prefix arg but nevertheless a prefix arg
should be passed to isearch commands without exiting isearch.
But this patch exits isearch and calls the isearch command with a prefix
in inactive isearch.

This is because (lookup-key isearch-mode-map (this-command-keys))
used to check when to exit isearch, with a prepended prefix can't decide
whether a key sequence is bound to an isearch command or not, e.g.:

(lookup-key isearch-mode-map (kbd "C-u C-l")) => 1
(lookup-key isearch-mode-map (kbd "C-u C-w")) => 1

both return 1.

universal-argument-num-events could help to remove the prefix
from this-command-keys to lookup a key without prefix,
but I have no idea what to do without universal-argument-num-events.

The current patch:

=== modified file 'lisp/isearch.el'
--- lisp/isearch.el	2013-08-28 16:39:51 +0000
+++ lisp/isearch.el	2013-10-07 23:31:34 +0000
@@ -349,7 +349,6 @@ (defvar lazy-highlight-face 'lazy-highli
 
 (defvar isearch-help-map
   (let ((map (make-sparse-keymap)))
-    (define-key map [t] 'isearch-other-control-char)
     (define-key map (char-to-string help-char) 'isearch-help-for-help)
     (define-key map [help] 'isearch-help-for-help)
     (define-key map [f1] 'isearch-help-for-help)
@@ -423,9 +422,6 @@ (defvar isearch-mode-map
     ;; Make all multibyte characters search for themselves.
     (set-char-table-range (nth 1 map) (cons #x100 (max-char))
 			  'isearch-printing-char)
-    ;; Make function keys, etc, which aren't bound to a scrolling-function
-    ;; exit the search.
-    (define-key map [t] 'isearch-other-control-char)
 
     ;; Single-byte printing chars extend the search string by default.
     (setq i ?\s)
@@ -440,8 +436,7 @@ (defvar isearch-mode-map
     ;; default local key binding for any key not otherwise bound.
     (let ((meta-map (make-sparse-keymap)))
       (define-key map (char-to-string meta-prefix-char) meta-map)
-      (define-key map [escape] meta-map)
-      (define-key meta-map [t] 'isearch-other-meta-char))
+      (define-key map [escape] meta-map))
 
     ;; Several non-printing chars change the searching behavior.
     (define-key map "\C-s" 'isearch-repeat-forward)
@@ -521,9 +516,6 @@ (defvar isearch-mode-map
 
     ;; The key translations defined in the C-x 8 prefix should add
     ;; characters to the search string.  See iso-transl.el.
-    (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-char-by-name)
 
     map)
@@ -920,6 +912,8 @@ (defun isearch-mode (forward &optional r
 
   (isearch-update)
 
+  (add-hook 'pre-command-hook 'isearch-pre-command-hook)
+  (add-hook 'post-command-hook 'isearch-post-command-hook)
   (add-hook 'mouse-leave-buffer-hook 'isearch-done)
   (add-hook 'kbd-macro-termination-hook 'isearch-done)
 
@@ -998,6 +992,8 @@ (defun isearch-done (&optional nopush ed
 	(unless (equal (car command-history) command)
 	  (setq command-history (cons command command-history)))))
 
+  (remove-hook 'pre-command-hook 'isearch-pre-command-hook)
+  (remove-hook 'post-command-hook 'isearch-post-command-hook)
   (remove-hook 'mouse-leave-buffer-hook 'isearch-done)
   (remove-hook 'kbd-macro-termination-hook 'isearch-done)
   (setq isearch-lazy-highlight-start nil)
@@ -2100,26 +2096,6 @@ (defun isearch-fallback (want-backslash
 			 (min last-other-end isearch-barrier)))
 	    (setq isearch-adjusted t)))))))
 
-(defun isearch-unread-key-sequence (keylist)
-  "Unread the given key-sequence KEYLIST.
-Scroll-bar or mode-line events are processed appropriately."
-  (cancel-kbd-macro-events)
-  (apply 'isearch-unread keylist)
-  ;; If the event was a scroll-bar or mode-line click, the event will have
-  ;; been prefixed by a symbol such as vertical-scroll-bar.  We must remove
-  ;; it here, because this symbol will be attached to the event again next
-  ;; time it gets read by read-key-sequence.
-  ;;
-  ;; (Old comment from isearch-other-meta-char: "Note that we don't have to
-  ;; modify the event anymore in 21 because read_key_sequence no longer
-  ;; modifies events to produce fake prefix keys.")
-  (if (and (> (length keylist) 1)
-           (symbolp (car keylist))
-           (listp (cadr keylist))
-           (not (numberp (posn-point
-                          (event-start (cadr keylist)  )))))
-      (pop unread-command-events)))
-
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; scrolling within Isearch mode.  Alan Mackenzie (acm <at> muc.de), 2003/2/24
 ;;
@@ -2244,198 +2220,74 @@ (defun isearch-back-into-window (above i
         (recenter 0))))
   (goto-char isearch-point))
 
-(defun isearch-reread-key-sequence-naturally (keylist)
-  "Reread key sequence KEYLIST with an inactive Isearch-mode keymap.
-Return the key sequence as a string/vector."
-  (isearch-unread-key-sequence keylist)
-  (let (overriding-terminal-local-map)
-    ;; This will go through function-key-map, if nec.
-    ;; The arg DONT-DOWNCASE-LAST prevents premature shift-translation.
-    (read-key-sequence nil nil t)))
-
-(defun isearch-lookup-scroll-key (key-seq)
-  "If KEY-SEQ is bound to a scrolling 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)
-         (or (eq (get binding 'isearch-scroll) t)
-	     (eq (get binding 'scroll-command) t))
-         binding)))
-
-(defalias 'isearch-other-control-char 'isearch-other-meta-char)
-
-(defun isearch-other-meta-char (&optional arg)
-  "Process a miscellaneous key sequence in Isearch mode.
-
-Try to convert the current key-sequence to something usable in Isearch
-mode, either by converting it with `function-key-map', downcasing a
-key with C-<upper case>, or finding a \"scrolling command\" bound to
-it.  \(In the last case, we may have to read more events.)  If so,
-either unread the converted sequence or execute the command.
-
-Otherwise, if `search-exit-option' is non-nil (the default) unread the
-key-sequence and exit the search normally.  If it is the symbol
-`edit', the search string is edited in the minibuffer and the meta
-character is unread so that it applies to editing the string.
-
-ARG is the prefix argument.  It will be transmitted through to the
-scrolling command or to the command whose key-sequence exits
-Isearch mode."
-  (interactive "P")
-  (let* ((key (if current-prefix-arg    ; not nec the same as ARG
-                  (substring (this-command-keys) universal-argument-num-events)
-                (this-command-keys)))
-	 (main-event (aref key 0))
-	 (keylist (listify-key-sequence key))
-         scroll-command isearch-point)
-    (cond ((and (= (length key) 1)
-		(let ((lookup (lookup-key local-function-key-map key)))
-		  (not (or (null lookup) (integerp lookup)
-			   (keymapp lookup)))))
-	   ;; Handle a function key that translates into something else.
-	   ;; If the key has a global definition too,
-	   ;; exit and unread the key itself, so its global definition runs.
-	   ;; Otherwise, unread the translation,
-	   ;; so that the translated key takes effect within isearch.
-	   (cancel-kbd-macro-events)
-	   (if (lookup-key global-map key)
-	       (progn
-		 (isearch-done)
-		 (setq prefix-arg arg)
-		 (apply 'isearch-unread keylist))
-	     (setq keylist
-		   (listify-key-sequence
-		    (lookup-key local-function-key-map key)))
-	     (while keylist
-	       (setq key (car keylist))
-	       ;; Handle an undefined shifted printing character
-	       ;; by downshifting it if that makes it printing.
-	       ;; (As read-key-sequence would normally do,
-	       ;; if we didn't have a default definition.)
-	       (if (and (integerp key)
-			(memq 'shift (event-modifiers key))
-			(>= key (+ ?\s (- ?\S-a ?a)))
-			(/= key (+ 127 (- ?\S-a ?a)))
-			(<  key (+ 256 (- ?\S-a ?a))))
-		   (setq key (- key (- ?\S-a ?a))))
-	       ;; If KEY is a printing char, we handle it here
-	       ;; directly to avoid the input method and keyboard
-	       ;; coding system translating it.
-	       (if (and (integerp key)
-			(>= key ?\s) (/= key 127) (< key 256))
-		   (progn
-		     ;; Ensure that the processed char is recorded in
-		     ;; the keyboard macro, if any (Bug#4894)
-		     (store-kbd-macro-event key)
-		     (isearch-process-search-char key)
-		     (setq keylist (cdr keylist)))
-		 ;; As the remaining keys in KEYLIST can't be handled
-		 ;; here, we must reread them.
-		 (setq prefix-arg arg)
-		 (apply 'isearch-unread keylist)
-		 (setq keylist nil)))))
-	  (
-	   ;; Handle an undefined shifted control character
-	   ;; by downshifting it if that makes it defined.
-	   ;; (As read-key-sequence would normally do,
-	   ;; if we didn't have a default definition.)
-	   (let ((mods (event-modifiers main-event)))
-	     (and (integerp main-event)
-		  (memq 'shift mods)
-		  (memq 'control mods)
-		  (not (memq (lookup-key isearch-mode-map
-					 (let ((copy (copy-sequence key)))
-					   (aset copy 0
-						 (- main-event
-						    (- ?\C-\S-a ?\C-a)))
-					   copy)
-					 nil)
-			     '(nil
-			       isearch-other-control-char)))))
-	   (setcar keylist (- main-event (- ?\C-\S-a ?\C-a)))
-	   (cancel-kbd-macro-events)
-	   (setq prefix-arg arg)
-	   (apply 'isearch-unread keylist))
-	  ((eq search-exit-option 'edit)
-	   (setq prefix-arg arg)
-	   (apply 'isearch-unread keylist)
-	   (isearch-edit-string))
-          ;; Handle a scrolling function or prefix argument.
-          ((progn
-	     (setq key (isearch-reread-key-sequence-naturally keylist)
-		   keylist (listify-key-sequence key)
-		   main-event (aref key 0))
-	     (or (and isearch-allow-scroll
-		      (setq scroll-command (isearch-lookup-scroll-key key)))
-		 (and isearch-allow-prefix
-		      (let (overriding-terminal-local-map)
-			(setq scroll-command (key-binding key))
-			(memq scroll-command
-			      '(universal-argument
-				negative-argument digit-argument))))))
-           ;; From this point onwards, KEY, KEYLIST and MAIN-EVENT hold a
-           ;; complete key sequence, possibly as modified by function-key-map,
-           ;; not merely the one or two event fragment which invoked
-           ;; isearch-other-meta-char in the first place.
-           (setq isearch-point (point))
-           (setq prefix-arg arg)
-           (command-execute scroll-command)
-           (let ((ab-bel (isearch-string-out-of-window isearch-point)))
-             (if ab-bel
-                 (isearch-back-into-window (eq ab-bel 'above) isearch-point)
-               (goto-char isearch-point)))
-           (isearch-update))
-	  ;; A mouse click on the isearch message starts editing the search string
-	  ((and (eq (car-safe main-event) 'down-mouse-1)
-		(window-minibuffer-p (posn-window (event-start main-event))))
-	   ;; Swallow the up-event.
-	   (read-event)
-	   (isearch-edit-string))
-	  (search-exit-option
-	   (let (window)
-	     (setq prefix-arg arg)
-             (isearch-unread-key-sequence keylist)
-             (setq main-event (car unread-command-events))
-
-	     ;; Don't store special commands in the keyboard macro.
-	     (let (overriding-terminal-local-map)
-	       (when (memq (key-binding key)
-			   '(kmacro-start-macro
-			     kmacro-end-macro kmacro-end-and-call-macro))
-		 (cancel-kbd-macro-events)))
-
-	     ;; If we got a mouse click event, that event contains the
-	     ;; window clicked on. maybe it was read with the buffer
-	     ;; it was clicked on.  If so, that buffer, not the current one,
-	     ;; is in isearch mode.  So end the search in that buffer.
-
-	     ;; ??? I have no idea what this if checks for, but it's
-	     ;; obviously wrong for the case that a down-mouse event
-	     ;; on another window invokes this function.  The event
-	     ;; will contain the window clicked on and that window's
-	     ;; buffer is certainly not always in Isearch mode.
-	     ;;
-	     ;; Leave the code in, but check for current buffer not
-	     ;; being in Isearch mode for now, until someone tells
-	     ;; what it's really supposed to do.
-	     ;;
-	     ;; --gerd 2001-08-10.
-
-	     (if (and (not isearch-mode)
-		      (listp main-event)
-		      (setq window (posn-window (event-start main-event)))
-		      (windowp window)
-		      (or (> (minibuffer-depth) 0)
-			  (not (window-minibuffer-p window))))
-		 (with-current-buffer (window-buffer window)
-		   (isearch-done)
-		   (isearch-clean-overlays))
-	       (isearch-done)
-	       (isearch-clean-overlays)
-               (setq prefix-arg arg))))
-          (t;; otherwise nil
-	   (isearch-process-search-string key key)))))
+(defvar isearch-pre-scroll-point nil)
+
+(defun isearch-pre-command-hook ()
+  (let* ((key (this-command-keys))
+	 (main-event (aref key 0)))
+    (cond
+     ;; Don't exit isearch for isearch key bindings.
+     ((commandp (lookup-key isearch-mode-map key nil)))
+     ((eq search-exit-option 'edit)
+      (isearch-edit-string))
+     ;; Handle a scrolling function or prefix argument.
+     ((or (and isearch-allow-prefix
+	       (memq this-command '(universal-argument
+				    negative-argument
+				    digit-argument)))
+	  (and isearch-allow-scroll
+	       (or (eq (get this-command 'isearch-scroll) t)
+		   (eq (get this-command 'scroll-command) t))))
+      (when isearch-allow-scroll
+	(setq isearch-pre-scroll-point (point))))
+     ;; A mouse click on the isearch message starts editing the search string
+     ((and (eq (car-safe main-event) 'down-mouse-1)
+	   (window-minibuffer-p (posn-window (event-start main-event))))
+      ;; Swallow the up-event.
+      (read-event)
+      (isearch-edit-string))
+     (search-exit-option
+      (let (window)
+	(if (and (not isearch-mode)
+		 (listp main-event)
+		 (setq window (posn-window (event-start main-event)))
+		 (windowp window)
+		 (or (> (minibuffer-depth) 0)
+		     (not (window-minibuffer-p window))))
+	    (with-current-buffer (window-buffer window)
+	      (isearch-done)
+	      (isearch-clean-overlays))
+	  (isearch-done)
+	  (isearch-clean-overlays))))
+     (t	;; otherwise nil
+      (isearch-process-search-string key key)))))
+
+(defun isearch-post-command-hook ()
+  (when isearch-pre-scroll-point
+    (let ((ab-bel (isearch-string-out-of-window isearch-pre-scroll-point)))
+      (if ab-bel
+	  (isearch-back-into-window (eq ab-bel 'above) isearch-pre-scroll-point)
+	(goto-char isearch-pre-scroll-point)))
+    (setq isearch-pre-scroll-point nil)
+    (isearch-update)))
 
 (defun isearch-quote-char (&optional count)
   "Quote special characters for incremental search.





Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#15200; Package emacs. (Tue, 08 Oct 2013 03:08:02 GMT) Full text and rfc822 format available.

Message #51 received at 15200 <at> debbugs.gnu.org (full text, mbox):

From: Stefan Monnier <monnier <at> iro.umontreal.ca>
To: Juri Linkov <juri <at> jurta.org>
Cc: 15200 <at> debbugs.gnu.org
Subject: Re: bug#15200: isearch-other-meta-char and shift
Date: Mon, 07 Oct 2013 23:07:24 -0400
> This is because (lookup-key isearch-mode-map (this-command-keys))
> used to check when to exit isearch, with a prepended prefix can't decide
> whether a key sequence is bound to an isearch command or not, e.g.:

> (lookup-key isearch-mode-map (kbd "C-u C-l")) => 1
> (lookup-key isearch-mode-map (kbd "C-u C-w")) => 1

> both return 1.

OK, don't worry about that: the fix needs to be elsewhere (I happen to
have a work-in-progress patch which fixes that problem).

So, I think you can go ahead and install your patch.
And please make a bug-report for the C-u C-w problem, so we don't forget
about it.


        Stefan




Reply sent to Juri Linkov <juri <at> jurta.org>:
You have taken responsibility. (Tue, 08 Oct 2013 23:30:03 GMT) Full text and rfc822 format available.

Notification sent to Juri Linkov <juri <at> jurta.org>:
bug acknowledged by developer. (Tue, 08 Oct 2013 23:30:05 GMT) Full text and rfc822 format available.

Message #56 received at 15200-done <at> debbugs.gnu.org (full text, mbox):

From: Juri Linkov <juri <at> jurta.org>
To: Stefan Monnier <monnier <at> iro.umontreal.ca>
Cc: 15200-done <at> debbugs.gnu.org
Subject: Re: bug#15200: isearch-other-meta-char and shift
Date: Wed, 09 Oct 2013 02:29:15 +0300
>> (lookup-key isearch-mode-map (kbd "C-u C-l")) => 1
>> (lookup-key isearch-mode-map (kbd "C-u C-w")) => 1
>
>> both return 1.
>
> OK, don't worry about that: the fix needs to be elsewhere (I happen to
> have a work-in-progress patch which fixes that problem).
>
> So, I think you can go ahead and install your patch.
> And please make a bug-report for the C-u C-w problem, so we don't forget
> about it.

I installed the patch (with a FIXME comment) and reported a new bug#15568.




Reply sent to Juri Linkov <juri <at> jurta.org>:
You have taken responsibility. (Tue, 08 Oct 2013 23:30:06 GMT) Full text and rfc822 format available.

Notification sent to Juri Linkov <juri <at> jurta.org>:
bug acknowledged by developer. (Tue, 08 Oct 2013 23:30:08 GMT) Full text and rfc822 format available.

Reply sent to Juri Linkov <juri <at> jurta.org>:
You have taken responsibility. (Tue, 08 Oct 2013 23:30:09 GMT) Full text and rfc822 format available.

Notification sent to Drew Adams <drew.adams <at> oracle.com>:
bug acknowledged by developer. (Tue, 08 Oct 2013 23:30:10 GMT) Full text and rfc822 format available.

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#15200; Package emacs. (Wed, 09 Oct 2013 02:44:01 GMT) Full text and rfc822 format available.

Message #69 received at 15200-done <at> debbugs.gnu.org (full text, mbox):

From: Stefan Monnier <monnier <at> iro.umontreal.ca>
To: Juri Linkov <juri <at> jurta.org>
Cc: 15200-done <at> debbugs.gnu.org
Subject: Re: bug#15200: isearch-other-meta-char and shift
Date: Tue, 08 Oct 2013 22:43:31 -0400
> I installed the patch (with a FIXME comment) and reported a new bug#15568.

Thanks,


        Stefan




bug archived. Request was from Debbugs Internal Request <help-debbugs <at> gnu.org> to internal_control <at> debbugs.gnu.org. (Wed, 06 Nov 2013 12:24:03 GMT) Full text and rfc822 format available.

This bug report was last modified 10 years and 182 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.