Subject: Re: bug#45005: 28.0.50; input method does not switch back

From: Juri Linkov <[email-masked]>
Date: Tue, 08 Dec 2020 10:43:48 +0200

tags 45005 + patch
quit

> This is report for which I do not think that it is reproducible as I
> tried to invoke it with emacs -Q and I would need to perform some work
> from which I could not find out what invokes the bug.
>
> My other input method is by default set to german-postfix.
>
> My Emacs uptime now is about 1 day, 15 hours. About 15 hours ago, I
> could observe that I cannot turn off the input method with C-\ but
> that it remains engaged.
>
> Mode line may show DE<U: and when I press C-\ it shows U: but again I
> can write ü ö ä and some words in other languages collide. I am using
> other few input methods for other languages, then it becomes difficult
> writing English as some combinations of letters get converted in other
> letters, then I have to delete, etc. If I make new session it will of
> course be alright. For my last 5 years I have not encountered this
> situation that input-method kind of remains turned on even if I turn
> it off.

This problem can happen only when the default global value of
input-method-function is changed, so it still translates keys
while the input method is disabled.

When an input method is activated, 'quail-activate' uses

  (setq-local input-method-function #'quail-input-method)

to set the buffer-local value, and when an input method is deactivated,
removes the buffer-local value:

  (kill-local-variable 'input-method-function)

So it doesn't change its default global value.

The only place on the whole Emacs tree that can change the
default global value of input-method-function is 'isearch-done':

  (if isearch-input-method-local-p
      (setq input-method-function isearch-input-method-function)
     (kill-local-variable 'input-method-function))

Many functions in international/isearch-x.el set isearch-input-method-local-p
to 't', but never set it to 'nil'.  So when after using an input method
in Isearch (enabling and disabling it) on exiting Isearch, this code
always changes the default global value of input-method-function.

Instead of this, this code should use the same logic as used by
'quail-activate': when a previous input method should be re-activated,
then set its buffer-local value, otherwise use kill-local-variable.

This logic will obsolete the variable isearch-input-method-local-p:

diff --git a/lisp/isearch.el b/lisp/isearch.el
index a0aa250c4b..69c553deda 100644
--- a/lisp/isearch.el
+++ b/lisp/isearch.el
@@ -965,10 +965,6 @@ isearch-hidden
 ;; The value of input-method-function when isearch is invoked.
 (defvar isearch-input-method-function nil)
 
-;; A flag to tell if input-method-function is locally bound when
-;; isearch is invoked.
-(defvar isearch-input-method-local-p nil)
-
 (defvar isearch--saved-overriding-local-map nil)
 
 ;; Minor-mode-alist changes - kind of redundant with the
@@ -1238,7 +1234,6 @@ isearch-mode
 	search-ring-yank-pointer nil
 	isearch-opened-overlays nil
 	isearch-input-method-function input-method-function
-	isearch-input-method-local-p (local-variable-p 'input-method-function)
 	regexp-search-ring-yank-pointer nil
 
 	isearch-pre-scroll-point nil
@@ -1259,8 +1254,6 @@ isearch-mode
   ;; We must bypass input method while reading key.  When a user type
   ;; printable character, appropriate input method is turned on in
   ;; minibuffer to read multibyte characters.
-  (or isearch-input-method-local-p
-      (make-local-variable 'input-method-function))
   (setq input-method-function nil)
 
   (looking-at "")
@@ -1418,8 +1411,8 @@ isearch-done
 	(set-window-group-start (selected-window) found-start t))))
 
   (setq isearch-mode nil)
-  (if isearch-input-method-local-p
-      (setq input-method-function isearch-input-method-function)
+  (if isearch-input-method-function
+      (setq-local input-method-function isearch-input-method-function)
     (kill-local-variable 'input-method-function))
 
   (if isearch-tool-bar-old-map
diff --git a/lisp/international/isearch-x.el b/lisp/international/isearch-x.el
index f50f86a035..94716721b5 100644
--- a/lisp/international/isearch-x.el
+++ b/lisp/international/isearch-x.el
@@ -35,8 +35,7 @@ isearch-toggle-specified-input-method
   (interactive)
   (let ((overriding-terminal-local-map nil))
     (toggle-input-method t))
-  (setq isearch-input-method-function input-method-function
-	isearch-input-method-local-p t)
+  (setq isearch-input-method-function input-method-function)
   (setq input-method-function nil)
   (isearch-update))
 
@@ -46,8 +45,7 @@ isearch-toggle-input-method
   (interactive)
   (let ((overriding-terminal-local-map nil))
     (toggle-input-method))
-  (setq isearch-input-method-function input-method-function
-	isearch-input-method-local-p t)
+  (setq isearch-input-method-function input-method-function)
   (setq input-method-function nil)
   (isearch-update))
 
@@ -57,8 +55,7 @@ isearch-transient-input-method
   (interactive)
   (let ((overriding-terminal-local-map nil))
     (activate-transient-input-method))
-  (setq isearch-input-method-function input-method-function
-	isearch-input-method-local-p t)
+  (setq isearch-input-method-function input-method-function)
   (setq input-method-function nil)
   (isearch-update))
 
diff --git a/lisp/language/korea-util.el b/lisp/language/korea-util.el
index 3821785da7..13cd6a015d 100644
--- a/lisp/language/korea-util.el
+++ b/lisp/language/korea-util.el
@@ -70,8 +70,7 @@ isearch-toggle-korean-input-method
   (interactive)
   (let ((overriding-terminal-local-map nil))
     (toggle-korean-input-method))
-  (setq isearch-input-method-function input-method-function
-	isearch-input-method-local-p t)
+  (setq isearch-input-method-function input-method-function)
   (setq input-method-function nil)
   (isearch-update))
 
@@ -79,8 +78,7 @@ isearch-hangul-switch-symbol-ksc
   (interactive)
   (let ((overriding-terminal-local-map nil))
     (quail-hangul-switch-symbol-ksc))
-  (setq isearch-input-method-function input-method-function
-	isearch-input-method-local-p t)
+  (setq isearch-input-method-function input-method-function)
   (setq input-method-function nil)
   (isearch-update))
 
@@ -88,8 +86,7 @@ isearch-hangul-switch-hanja
   (interactive)
   (let ((overriding-terminal-local-map nil))
     (quail-hangul-switch-hanja))
-  (setq isearch-input-method-function input-method-function
-	isearch-input-method-local-p t)
+  (setq isearch-input-method-function input-method-function)
   (setq input-method-function nil)
   (isearch-update))