unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
* bug#44266: Transient input methods
@ 2020-10-27 20:43 Juri Linkov
  2020-10-28 11:40 ` Lars Ingebrigtsen
                   ` (2 more replies)
  0 siblings, 3 replies; 9+ messages in thread
From: Juri Linkov @ 2020-10-27 20:43 UTC (permalink / raw)
  To: 44266

[-- Attachment #1: Type: text/plain, Size: 1439 bytes --]

Tags: patch

[Creating a separate feature request from bug#43866]

>> How about making a new input method for those?  It seems to me that
>> C-x 8 is already too "fat".
>
> That may be useful, but it has a drawback compared with C-x 8.
>
> It is inconvenient to change input methods just for one character and
> then change back.

The following patch addresses such issues of the current input method
implementation by providing a new feature of transient input methods.

A transient input method is enabled temporarily for entering a key sequence,
and is disabled automatically afterwards.

The command that temporarily activates an one-off transient input method
is bound to the mnemonic key 'C-x \'.  A prefix key is used to select
the default transient input method, e.g.:

C-u C-x \ compose RET   - selects the 'compose' input method
                          as the default transient input method;
C-x \ E =   - activates the default transient input method,
              inserts the EURO SIGN character,
              and disables the transient input method;
C-x \ ^ 3   - inserts the character SUPERSCRIPT THREE.

The same with the help of the 'TeX' input method:

C-u C-x \ TeX RET
C-x \ \ e u r o   - inserts the character EURO SIGN

Also it's possible to create a new input method from the existing
'C-x 8' keymap, and set it as the default method, e.g.:

C-u C-x \ iso-transl RET
C-x \ * E   - inserts the character EURO SIGN


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: transient-input-method.patch --]
[-- Type: text/x-diff, Size: 2724 bytes --]

diff --git a/lisp/international/mule-cmds.el b/lisp/international/mule-cmds.el
index e3155dfc52..c5a0145163 100644
--- a/lisp/international/mule-cmds.el
+++ b/lisp/international/mule-cmds.el
@@ -55,6 +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)
 
 (defvar describe-language-environment-map
   (let ((map (make-sparse-keymap "Describe Language Environment")))
@@ -1344,6 +1345,16 @@ default-input-method
                  mule-input-method-string)
   :set-after '(current-language-environment))
 
+(defcustom transient-input-method nil
+  "Default transient input method.
+This is the input method activated automatically by the command
+`transient-input-method' (\\[transient-input-method])."
+  :link  '(custom-manual "(emacs)Input Methods")
+  :group 'mule
+  :type '(choice (const nil)
+                 mule-input-method-string)
+  :set-after '(current-language-environment))
+
 (put 'input-method-function 'permanent-local t)
 
 (defvar input-method-history nil
@@ -1519,6 +1530,35 @@ set-input-method
 (defvar toggle-input-method-active nil
   "Non-nil inside `toggle-input-method'.")
 
+(defun transient-input-method (&optional arg interactive)
+  "Enable transient input method for the current buffer."
+  (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.

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* bug#44266: Transient input methods
  2020-10-27 20:43 bug#44266: Transient input methods Juri Linkov
@ 2020-10-28 11:40 ` Lars Ingebrigtsen
  2020-10-29  4:48 ` Richard Stallman
  2020-11-01 14:37 ` Lars Ingebrigtsen
  2 siblings, 0 replies; 9+ messages in thread
From: Lars Ingebrigtsen @ 2020-10-28 11:40 UTC (permalink / raw)
  To: Juri Linkov; +Cc: 44266

Heh, never mind --

+(define-key ctl-x-map "\\" 'transient-input-method)

is in the next bug report.

-- 
(domestic pets only, the antidote for overdose, milk.)
   bloggy blog: http://lars.ingebrigtsen.no






^ permalink raw reply	[flat|nested] 9+ messages in thread

* bug#44266: Transient input methods
  2020-10-27 20:43 bug#44266: Transient input methods Juri Linkov
  2020-10-28 11:40 ` Lars Ingebrigtsen
@ 2020-10-29  4:48 ` Richard Stallman
  2020-11-01 21:36   ` Juri Linkov
  2020-11-01 14:37 ` Lars Ingebrigtsen
  2 siblings, 1 reply; 9+ messages in thread
From: Richard Stallman @ 2020-10-29  4:48 UTC (permalink / raw)
  To: Juri Linkov; +Cc: 44266

[[[ To any NSA and FBI agents reading my email: please consider    ]]]
[[[ whether defending the US Constitution against all enemies,     ]]]
[[[ foreign or domestic, requires you to follow Snowden's example. ]]]

This idea looks good to me.

-- 
Dr Richard Stallman
Chief GNUisance of the GNU Project (https://gnu.org)
Founder, Free Software Foundation (https://fsf.org)
Internet Hall-of-Famer (https://internethalloffame.org)







^ permalink raw reply	[flat|nested] 9+ messages in thread

* bug#44266: Transient input methods
  2020-10-27 20:43 bug#44266: Transient input methods Juri Linkov
  2020-10-28 11:40 ` Lars Ingebrigtsen
  2020-10-29  4:48 ` Richard Stallman
@ 2020-11-01 14:37 ` Lars Ingebrigtsen
  2020-11-01 18:24   ` Juri Linkov
  2020-11-02  5:41   ` Richard Stallman
  2 siblings, 2 replies; 9+ messages in thread
From: Lars Ingebrigtsen @ 2020-11-01 14:37 UTC (permalink / raw)
  To: Juri Linkov; +Cc: 44266

Juri Linkov <juri@linkov.net> writes:

> The following patch addresses such issues of the current input method
> implementation by providing a new feature of transient input methods.

> A transient input method is enabled temporarily for entering a key sequence,
> and is disabled automatically afterwards.

I like the idea, I think.  But just thinking out loud without having
read the code closely -- would it perhaps be even more useful to have
the transient method in place until you `C-x \' again?

Then you could

`C-x \ ...  type a couple of words in that method C-x \'

I'm not at all sure, but I think that perhaps people would more often
type in a couple of words than just a single key sequence?

-- 
(domestic pets only, the antidote for overdose, milk.)
   bloggy blog: http://lars.ingebrigtsen.no





^ permalink raw reply	[flat|nested] 9+ messages in thread

* bug#44266: Transient input methods
  2020-11-01 14:37 ` Lars Ingebrigtsen
@ 2020-11-01 18:24   ` Juri Linkov
  2020-11-02  5:41   ` Richard Stallman
  1 sibling, 0 replies; 9+ messages in thread
From: Juri Linkov @ 2020-11-01 18:24 UTC (permalink / raw)
  To: Lars Ingebrigtsen; +Cc: 44266

>> The following patch addresses such issues of the current input method
>> implementation by providing a new feature of transient input methods.
>
>> A transient input method is enabled temporarily for entering a key sequence,
>> and is disabled automatically afterwards.
>
> I like the idea, I think.  But just thinking out loud without having
> read the code closely -- would it perhaps be even more useful to have
> the transient method in place until you `C-x \' again?
>
> Then you could
>
> `C-x \ ...  type a couple of words in that method C-x \'

This is achievable already by shorter key sequence:
`C-\ ...  type a couple of words in that method C-\'

> I'm not at all sure, but I think that perhaps people would more often
> type in a couple of words than just a single key sequence?

This feature is intended as an equivalent of the X Compose Multi_key
that inserts a single character, whereas X layouts switcher that activates
a layout to insert a couple of words corresponds to Emacs non-transient
input methods switched by C-\.





^ permalink raw reply	[flat|nested] 9+ messages in thread

* bug#44266: Transient input methods
  2020-10-29  4:48 ` Richard Stallman
@ 2020-11-01 21:36   ` Juri Linkov
  2020-11-05 20:14     ` Juri Linkov
  0 siblings, 1 reply; 9+ messages in thread
From: Juri Linkov @ 2020-11-01 21:36 UTC (permalink / raw)
  To: Richard Stallman; +Cc: 44266

> [[[ To any NSA and FBI agents reading my email: please consider    ]]]
> [[[ whether defending the US Constitution against all enemies,     ]]]
> [[[ foreign or domestic, requires you to follow Snowden's example. ]]]
>
> This idea looks good to me.

Now installed.





^ permalink raw reply	[flat|nested] 9+ messages in thread

* bug#44266: Transient input methods
  2020-11-01 14:37 ` Lars Ingebrigtsen
  2020-11-01 18:24   ` Juri Linkov
@ 2020-11-02  5:41   ` Richard Stallman
  1 sibling, 0 replies; 9+ messages in thread
From: Richard Stallman @ 2020-11-02  5:41 UTC (permalink / raw)
  To: Lars Ingebrigtsen; +Cc: 44266, juri

[[[ To any NSA and FBI agents reading my email: please consider    ]]]
[[[ whether defending the US Constitution against all enemies,     ]]]
[[[ foreign or domestic, requires you to follow Snowden's example. ]]]

  > `C-x \ ...  type a couple of words in that method C-x \'

  > I'm not at all sure, but I think that perhaps people would more often
  > type in a couple of words than just a single key sequence?

In my usage, I would type the occasional character, not whole words.

How about if C-X \ selects the temporary input method for one character
and C-x \ \ selects it for a longer period?
Maybe until the next space.

-- 
Dr Richard Stallman
Chief GNUisance of the GNU Project (https://gnu.org)
Founder, Free Software Foundation (https://fsf.org)
Internet Hall-of-Famer (https://internethalloffame.org)







^ permalink raw reply	[flat|nested] 9+ messages in thread

* bug#44266: Transient input methods
  2020-11-01 21:36   ` Juri Linkov
@ 2020-11-05 20:14     ` Juri Linkov
  2020-11-06  8:33       ` Juri Linkov
  0 siblings, 1 reply; 9+ messages in thread
From: Juri Linkov @ 2020-11-05 20:14 UTC (permalink / raw)
  To: 44266

[-- Attachment #1: Type: text/plain, Size: 664 bytes --]

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:


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: isearch-transient-input-method.patch --]
[-- Type: text/x-diff, Size: 7587 bytes --]

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.

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* bug#44266: Transient input methods
  2020-11-05 20:14     ` Juri Linkov
@ 2020-11-06  8:33       ` Juri Linkov
  0 siblings, 0 replies; 9+ messages in thread
From: Juri Linkov @ 2020-11-06  8:33 UTC (permalink / raw)
  To: 44266

> Here is a patch that implements support for transient input methods
> in Isearch mode.

Pushed to master.





^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2020-11-06  8:33 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-10-27 20:43 bug#44266: Transient input methods Juri Linkov
2020-10-28 11:40 ` Lars Ingebrigtsen
2020-10-29  4:48 ` Richard Stallman
2020-11-01 21:36   ` Juri Linkov
2020-11-05 20:14     ` Juri Linkov
2020-11-06  8:33       ` Juri Linkov
2020-11-01 14:37 ` Lars Ingebrigtsen
2020-11-01 18:24   ` Juri Linkov
2020-11-02  5:41   ` Richard Stallman

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).