From: Juri Linkov Date: Fri, 6 Nov 2020 08:31:58 +0000 (+0200) Subject: Support transient input methods in Isearch mode (bug#44266) X-Git-Tag: emacs-28.0.90~5229 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=af6891629d48f348b6458384898a637cc7ce16e7;p=emacs.git Support transient input methods in Isearch mode (bug#44266) * doc/emacs/mule.texi (Select Input Method): Rename transient-input-method to activate-transient-input-method. * doc/emacs/search.texi (Special Isearch): Document isearch-transient-input-method. * lisp/international/isearch-x.el (isearch-transient-input-method): New function. (isearch-process-search-multibyte-characters): Call 'deactivate-transient-input-method' after 'read-string'. * lisp/international/mule-cmds.el (mule-menu-keymap): Remove duplicate menu item 'describe-input-method'. Add new menu item 'activate-transient-input-method'. (default-transient-input-method): Rename from transient-input-method. (current-transient-input-method) (previous-transient-input-method): New buffer-local variables. (deactivate-input-method): Don't add current-transient-input-method to input-method-history. (toggle-input-method): Call deactivate-transient-input-method when current-transient-input-method is non-nil. (activate-transient-input-method): Rename from transient-input-method. (deactivate-transient-input-method): New function with body from renamed function transient-input-method. * lisp/isearch.el (isearch-menu-bar-map): Add new menu item 'isearch-transient-input-method'. (isearch-mode-map): Bind 'C-x \' to isearch-transient-input-method. (isearch-forward): Add isearch-transient-input-method to docstring. (isearch-message-prefix): Use shorter string for narrowed buffer. --- diff --git a/doc/emacs/mule.texi b/doc/emacs/mule.texi index 2fca4a544ca..200937c9d71 100644 --- a/doc/emacs/mule.texi +++ b/doc/emacs/mule.texi @@ -581,7 +581,7 @@ Select a new input method for the current buffer (@code{set-input-method}). @item C-x \ @var{method} @key{RET} Temporarily enable the selected transient input method ; it will be automatically disabled after inserting a single character -(@code{transient-input-method}). +(@code{activate-transient-input-method}). @item C-h I @var{method} @key{RET} @itemx C-h C-\ @var{method} @key{RET} @@ -680,13 +680,13 @@ character. input methods. The list gives information about each input method, including the string that stands for it in the mode line. -@findex transient-input-method +@findex activate-transient-input-method @kindex C-x \ Sometimes it can be convenient to enable an input method @dfn{transiently}, for inserting only a single character. Typing -@kbd{C-x \} (@code{transient-input-method}) will temporarily enable an -input method, let you insert a single character using the input method -rules, and then automatically disable the input method. If no +@kbd{C-x \} (@code{activate-transient-input-method}) will temporarily +enable an input method, let you insert a single character using the input +method rules, and then automatically disable the input method. If no transient input method was selected yet, @kbd{C-x \} will prompt you for an input method; subsequent invocations of this command will enable the selected transient input method. To select a different diff --git a/doc/emacs/search.texi b/doc/emacs/search.texi index 91b433f1738..f33c71db229 100644 --- a/doc/emacs/search.texi +++ b/doc/emacs/search.texi @@ -419,6 +419,7 @@ character into the search string, similar to the usual @kindex C-^ @r{(Incremental Search)} @findex isearch-toggle-input-method @findex isearch-toggle-specified-input-method +@findex isearch-transient-input-method Use an input method (@pxref{Input Methods}). If an input method is enabled in the current buffer when you start the search, the same method will be active in the minibuffer when you type the search @@ -437,7 +438,10 @@ I-search [@var{im}]: @noindent where @var{im} is the mnemonic of the active input method. Any input method you enable during incremental search remains enabled in the -current buffer afterwards. +current buffer afterwards. You can temporarily enable a transient +input method with @kbd{C-x \} (@code{isearch-transient-input-method}) +to insert a single character to the search string and automatically +disable the input method afterwards. @end itemize @kindex M-s o @r{(Incremental Search)} diff --git a/etc/NEWS b/etc/NEWS index ca8f71fe269..1a1cfc3751d 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -652,6 +652,8 @@ transient input method (which can be different from the input method enabled by 'C-\'). For example, 'C-u C-x \ compose RET' selects the 'compose' input method; then typing 'C-x \ 1 2' will insert the character '½', and disable the 'compose' input method afterwards. +You can use 'C-x \' in incremental search to insert a single character +to the search string. --- *** New input method 'compose' based on X Multi_key sequences. diff --git a/lisp/international/isearch-x.el b/lisp/international/isearch-x.el index d77234ec77b..f50f86a035f 100644 --- a/lisp/international/isearch-x.el +++ b/lisp/international/isearch-x.el @@ -51,6 +51,17 @@ (setq input-method-function nil) (isearch-update)) +;;;###autoload +(defun isearch-transient-input-method () + "Activate transient input method in interactive search." + (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 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 +128,7 @@ (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 dc435d9b170..439843aaf8e 100644 --- a/lisp/international/mule-cmds.el +++ b/lisp/international/mule-cmds.el @@ -55,7 +55,7 @@ ;; 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"))) @@ -140,8 +140,8 @@ `(menu-item "Set Coding Systems" ,set-coding-system-map)) (bindings--define-key map [separator-input-method] menu-bar-separator) - (bindings--define-key map [describe-input-method] - '(menu-item "Describe Input Method" describe-input-method)) + (bindings--define-key map [activate-transient-input-method] + '(menu-item "Transient Input Method" activate-transient-input-method)) (bindings--define-key map [set-input-method] '(menu-item "Select Input Method..." set-input-method)) (bindings--define-key map [toggle-input-method] @@ -1345,10 +1345,10 @@ This is the input method activated automatically by the command 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 @@ This is the input method activated by the command :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 active 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 @@ -1490,7 +1502,8 @@ If INPUT-METHOD is nil, deactivate any current input method." (defun deactivate-input-method () "Turn off the current input method." (when current-input-method - (add-to-history 'input-method-history current-input-method) + (unless current-transient-input-method + (add-to-history 'input-method-history current-input-method)) (unwind-protect (progn (setq input-method-function nil @@ -1531,36 +1544,6 @@ To deactivate it programmatically, use `deactivate-input-method'." (defvar toggle-input-method-active nil "Non-nil inside `toggle-input-method'.") -(defun 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." - (interactive "P\np") - (when (or arg (not 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) - (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")) - (exitfun - (lambda () - (deactivate-input-method) - (when previous-input-method - (activate-input-method previous-input-method)) - (setq input-method-history history) - (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) - exitfun)) - (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. @@ -1582,7 +1565,9 @@ which marks the variable `default-input-method' as set for Custom buffers." (if toggle-input-method-active (error "Recursive use of `toggle-input-method'")) (if (and current-input-method (not arg)) - (deactivate-input-method) + (if current-transient-input-method + (deactivate-transient-input-method) + (deactivate-input-method)) (let ((toggle-input-method-active t) (default (or (car input-method-history) default-input-method))) (if (and arg default (equal current-input-method default) @@ -1601,6 +1586,42 @@ which marks the variable `default-input-method' as set for Custom buffers." (when interactive (customize-mark-as-set 'default-input-method))))))) +(defun activate-transient-input-method (&optional arg interactive) + "Select and enable a transient input method for the current buffer. +If `default-transient-input-method' was not yet defined, prompt for it." + (interactive "P\np") + (when (or arg (not default-transient-input-method)) + (let* ((default (or (car input-method-history) default-input-method)) + (input-method + (read-input-method-name + (format-prompt "Transient input method" default) + default t))) + (setq default-transient-input-method input-method) + (when interactive + (customize-mark-as-set 'default-transient-input-method)))) + (let* ((clearfun (make-symbol "clear-transient-input-method")) + (exitfun + (lambda () + (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) + (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 () + "Disable currently active transient input method for the current buffer." + (when current-transient-input-method + (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))) + (autoload 'help-buffer "help-mode") (defun describe-input-method (input-method) diff --git a/lisp/isearch.el b/lisp/isearch.el index 245bf452b1f..4fba4370d98 100644 --- a/lisp/isearch.el +++ b/lisp/isearch.el @@ -565,6 +565,10 @@ This is like `describe-bindings', but displays only Isearch keys." :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 @@ This is like `describe-bindings', but displays only Isearch keys." ;; 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 @@ To use a different input method for searching, type \ \\[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 @@ -3263,7 +3270,7 @@ the word mode." "over") (if isearch-wrapped "wrapped ") (if (and (not isearch-success) (buffer-narrowed-p) widen-automatically) - "narrowed-buffer " "") + "narrowed " "") (if (and (not isearch-success) (not isearch-case-fold-search)) "case-sensitive ") (let ((prefix ""))