[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
bug#44266: Transient input methods
From: |
Juri Linkov |
Subject: |
bug#44266: Transient input methods |
Date: |
Thu, 05 Nov 2020 22:14:24 +0200 |
User-agent: |
Gnus/5.13 (Gnus v5.13) Emacs/28.0.50 (x86_64-pc-linux-gnu) |
Here is a patch that implements support for transient input methods
in Isearch mode.
While 'C-x 8' simply adds own keys to the default isearch-mode-map,
input methods have to rely on isearch-process-search-multibyte-characters
in lisp/international/isearch-x.el. Since it uses 'read-string'
to read a character, currently the activated transient input method
is deactivated in the minibuffer of 'read-string' that is a wrong place,
so needed to introduce a new separate function
deactivate-transient-input-method,
thus renamed the previous function to activate-transient-input-method,
and had to add more global variables. But in result everything works fine:
diff --git a/lisp/isearch.el b/lisp/isearch.el
index 245bf452b1..4fba4370d9 100644
--- a/lisp/isearch.el
+++ b/lisp/isearch.el
@@ -565,6 +565,10 @@ isearch-menu-bar-map
:help "Highlight all matches for current search string"))
(define-key map [isearch-search-replace-separator]
'(menu-item "--"))
+ (define-key map [isearch-transient-input-method]
+ '(menu-item "Turn on transient input method"
+ isearch-transient-input-method
+ :help "Turn on transient input method for search"))
(define-key map [isearch-toggle-specified-input-method]
'(menu-item "Turn on specific input method"
isearch-toggle-specified-input-method
@@ -747,6 +751,7 @@ isearch-mode-map
;; For searching multilingual text.
(define-key map "\C-\\" 'isearch-toggle-input-method)
(define-key map "\C-^" 'isearch-toggle-specified-input-method)
+ (define-key map "\C-x\\" 'isearch-transient-input-method)
;; People expect to be able to paste with the mouse.
(define-key map [mouse-2] #'isearch-mouse-2)
@@ -1078,6 +1083,8 @@ isearch-forward
\\[isearch-toggle-specified-input-method],
and specify an input method you want to use.
+To activate a transient input method, type \\[isearch-transient-input-method].
+
The above keys, bound in `isearch-mode-map', are often controlled by
options; do \\[apropos] on search-.* to find them.
Other control and meta characters terminate the search
diff --git a/lisp/international/isearch-x.el b/lisp/international/isearch-x.el
index d77234ec77..b22d0e968d 100644
--- a/lisp/international/isearch-x.el
+++ b/lisp/international/isearch-x.el
@@ -51,6 +51,18 @@ isearch-toggle-input-method
(setq input-method-function nil)
(isearch-update))
+;;;###autoload
+(defun isearch-transient-input-method ()
+ "Activate transient input method in interactive search."
+ (interactive)
+ (when default-transient-input-method
+ (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 input-method-function nil)
+ (isearch-update)))
+
(defvar isearch-minibuffer-local-map
(let ((map (copy-keymap minibuffer-local-map)))
(define-key map [with-keyboard-coding] 'isearch-with-keyboard-coding)
@@ -117,6 +129,7 @@ isearch-process-search-multibyte-characters
(cons last-char unread-command-events))
;; Inherit current-input-method in a minibuffer.
str (read-string prompt isearch-message 'junk-hist nil t))
+ (deactivate-transient-input-method)
(if (or (not str) (< (length str) (length isearch-message)))
;; All inputs were deleted while the input method
;; was working.
diff --git a/lisp/international/mule-cmds.el b/lisp/international/mule-cmds.el
index dc435d9b17..7eab01d804 100644
--- a/lisp/international/mule-cmds.el
+++ b/lisp/international/mule-cmds.el
@@ -55,7 +55,7 @@ mule-keymap
;; Keep "C-x C-m ..." for mule specific commands.
(define-key ctl-x-map "\C-m" mule-keymap)
-(define-key ctl-x-map "\\" 'transient-input-method)
+(define-key ctl-x-map "\\" 'activate-transient-input-method)
(defvar describe-language-environment-map
(let ((map (make-sparse-keymap "Describe Language Environment")))
@@ -1345,10 +1345,10 @@ default-input-method
mule-input-method-string)
:set-after '(current-language-environment))
-(defcustom transient-input-method nil
+(defcustom default-transient-input-method nil
"Default transient input method.
This is the input method activated by the command
-`transient-input-method' (\\[transient-input-method])."
+`activate-transient-input-method' (\\[activate-transient-input-method])."
:link '(custom-manual "(emacs)Input Methods")
:group 'mule
:type '(choice (const nil)
@@ -1356,6 +1356,18 @@ transient-input-method
:set-after '(current-language-environment)
:version "28.1")
+(defvar current-transient-input-method nil
+ "The current input method temporarily enabled by
`activate-transient-input-method'.
+If nil, that means no transient input method is activated now.")
+(make-variable-buffer-local 'current-transient-input-method)
+(put 'current-transient-input-method 'permanent-local t)
+
+(defvar previous-transient-input-method nil
+ "The input method that was active before enabling the transient input method.
+If nil, that means no previous input method was active.")
+(make-variable-buffer-local 'previous-transient-input-method)
+(put 'previous-transient-input-method 'permanent-local t)
+
(put 'input-method-function 'permanent-local t)
(defvar input-method-history nil
@@ -1531,36 +1543,43 @@ set-input-method
(defvar toggle-input-method-active nil
"Non-nil inside `toggle-input-method'.")
-(defun transient-input-method (&optional arg interactive)
+(defun activate-transient-input-method (&optional arg interactive)
"Enable a transient input method for the current buffer.
-If `transient-input-method' was not yet defined, prompt for it."
+If `default-transient-input-method' was not yet defined, prompt for it."
(interactive "P\np")
- (when (or arg (not transient-input-method))
+ (when (or arg (not default-transient-input-method))
(let* ((default (or (car input-method-history) default-input-method))
(input-method
(read-input-method-name
(if default "Transient input method (default %s): " "Transient
input method: ")
default t)))
- (setq transient-input-method input-method)
+ (setq default-transient-input-method input-method)
(when interactive
- (customize-mark-as-set 'transient-input-method))))
- (let* ((previous-input-method current-input-method)
- (history input-method-history)
- (clearfun (make-symbol "clear-transient-input-method"))
+ (customize-mark-as-set 'default-transient-input-method))))
+ (let* ((clearfun (make-symbol "clear-transient-input-method"))
(exitfun
(lambda ()
- (deactivate-input-method)
- (when previous-input-method
- (activate-input-method previous-input-method))
- (setq input-method-history history)
+ (deactivate-transient-input-method)
(remove-hook 'input-method-after-insert-chunk-hook clearfun))))
(fset clearfun (lambda () (funcall exitfun)))
(add-hook 'input-method-after-insert-chunk-hook clearfun)
- (when previous-input-method
- (deactivate-input-method))
- (activate-input-method transient-input-method)
+ (let ((input-method-history input-method-history))
+ (setq previous-transient-input-method current-input-method)
+ (when previous-transient-input-method
+ (deactivate-input-method))
+ (activate-input-method default-transient-input-method)
+ (setq current-transient-input-method default-transient-input-method))
exitfun))
+(defun deactivate-transient-input-method ()
+ (when current-transient-input-method
+ (let ((input-method-history input-method-history))
+ (deactivate-input-method)
+ (when previous-transient-input-method
+ (activate-input-method previous-transient-input-method)
+ (setq previous-transient-input-method nil))
+ (setq current-transient-input-method nil))))
+
(defun toggle-input-method (&optional arg interactive)
"Enable or disable multilingual text input method for the current buffer.
Only one input method can be enabled at any time in a given buffer.