Issue #5 resolved

Input methods

Vegard Øye
created an issue

Michael Markert proposed some code for handling input methods at Since I don't use input methods myself, I'm unsure of what the best way of handling them would be. Thoughts?

Comments (16)

  1. Frank Fischer repo owner
    • changed status to open

    I don't use input-methods, either. But as far as I understand them, they must be disabled in all states in which keys correspond to commands and not to text. This includes normal, operator and visual state and this is what Michael's code does. I see three problems:

    1. set-input-method has to be adviced like toggle-input-method, otherwise it is impossible to set an input-method when evil is activated and in normal state (the variable `evil-input-method' has to be set).

    2. the input-method has to be deactivated in operator mode, too. This seems to happen although not handled by Michael's code. I think this is due to the special key-parser for operator-state and is therefore no problem.

    3. The input method has to be reactivated when a command reads an additional character. Otherwise it would be impossible to, e.g., change a character using 'r' or to search for a character using 'f'. Michael's code enables the input-method whenever normal or visual state is left, but this does never happen when reading the extra character. I'm not sure if we should switch the state when the interactive-forms are evaluated (to input-state temporarily?) or just activate the input-method. In any case, to problem seems to be how to enable the input-method just before the interactive form is executed so that the read-char, which may be in the interactive form, is called with enabled input-method. If the command is an evil command/motion, this should be no problem and can be done in evil-define-command (or evil-eval-interactive). But for non-evil commands this may be more difficult. Perhaps we can advice `call-interactively' but I don't know ... Furthermore, one has to be careful about something like the new surround mode. When read-char is used surround mode should not inherit the input-method when calling read-char, evil-find-char should inherit it (using the third parameter of read-char).

    4. The input-method has to be enabled in ex-mode. As I want to make ex-mode look more like the other modes this should not be too difficult.

    Anyway, I do not know much about input methods so I'm not sure what the best approach is. The points above are just the things that come into my mind when thinking about it.

  2. Michael Markert

    Ad 1) That is a real problem. <strike>But another advice isn't a feasible way to got because it's called by toggle-input-method</strike> Seems my memory tricked me here. I'll look into it.

    Ad 2) It's on enabled on purpose Frank said it should be enabled on the mailing list (don't hold you to it -- just the reason I saw no problem here) and because I thought there may be input methods to type ASCII chars after a cursory look in list-input-methods that's not the case.

    Input method has no say, as Frank said, but it should be treated properly, though. So I'll take care of.

    Ad 3) That's a real problem (or maybe two) with the current hook-based implementation. Maybe it should wander deeper into the code.

    But as read-char goes: There seems to be a bug in emacs24 that seems to reverse the function of inherit-input-method.

    Ad 4) I'm not using ex and my code currently isn't working there. But I don't see big problems there either: If I toggle it inside the prompt it's enabled (though curiously not shown in mode line) and working. A call to set-input-method in evil-ex-setup should be enough and maybe saving it again in teardown to play it safe.

  3. Michael Markert

    I took care of 1) and 2) and updated the merge request.

    Forget my notion about read-char and emacs24, emacs23 doesn't works differently. The issue seems to be with the german-postfix input method.

    Update to 3): A call to `evil-reactivate-input-method' would be better.

  4. Frank Fischer repo owner

    I've just tested german-postfix in my emacs 23.3.1 and inherit-input-method works exactly as expected. I do the following:

    emacs -Q M-x set-input-method german-postfix M-: (read-char "? " t) a e C-\ C-\

    This returns the value 228, which corresponds to 'ä' as expected. In contrast, when executing M-: (read-char "? ") a

    the value 97 ('a') is returned immediately. Should something different happen?

  5. Michael Markert

    228 is returned only after a third key is pressed; this third key is lost. german-prefix returns correctly after "a no third key needed. Maybe I understand something wrong here but to me it feels broken.
    Also no need to toggle input method twice -- normally; in this case this ends the input method and returns the key.

  6. Frank Fischer repo owner

    It seems to me as if 'german-postfix' expects another possible key after the 'e', probably to press another e which would result in 'ae' (and the third key is not lost -- it is send to the currently active buffer, so executing

    M-: (read-char "? " t) aet

    results in 228 and the letter t in the current buffer). You get a similar problem if you inherit the keymap and want to type just 'a'. After pressing 'a' the first time nothing will happen because read-char waits for a possible completion. Pressing 'a' a second time is no good solution because that would immediately start the next character (sending 'a' to the current buffer). Therefore you need a way to tell Emacs that your current key is over. Reading the manual suggests pressing C-\ twice. I do not know if there is a better way.

    Using 'german-prefix' you get the same problem when trying to type a literal " -- the next character will be started.

  7. Michael Markert

    Ok sorry for the noise. Maybe I tested it with evil on and saw no change because of this -- can't remember now.
    But that raises a problem in regard to find-char: User types (evil-input-method set to german-postfix) f a and has to type another char (or 2 with the C-\ trick).

    I think here is another config variable needed if a user really wants to use an input method with find-char and similar commands, because most likely you want an a not an ä in this case. And maybe an easy way to call find-char with that option toggled.

  8. Vegard Øye reporter

    With regard to evil-surround.el, doesn't the same hold for its character arguments as for those of evil-find-char/evil-find-char-backward ("f"/"F")? The commands read a parenthesis or XML tag with the user's input method, and then edit the buffer accordingly.

  9. Frank Fischer repo owner
    • changed status to new

    Well, yes and no. Perhaps. There is a difference between f/F and evil-surround.el. f takes an argument that is a character as it can appear in the buffer. On the other handle, surround can be interpreted as reading a command (which should not use the input-method) -- on the other hand an xml-tag is indeed something that appears in the buffer. So even if parenthesis are not using input-methods, the xml-tags should.

    After all, I do not really have a good idea. If one reads a character then one could discard a following character (i.e., typing aea would create two letters, ä and a but the second one would be dropped), but this would only work for single characters. In contrast, typing an xml-tag requires a final RET anyway (I think).

  10. Vegard Øye reporter

    Does the Emacs function read-key handle input methods? From its docstring: "[E]scape sequences and keyboard encoding are taken into account."

    I recall that Viper's r command went with a quite radical approach to the character-reading problem. It used a custom routine which would create a temporary buffer, read a key sequence calling self-insert-command, and return the character inserted into the buffer. This had the nifty benefit of working with some other insertion commands as well, such as C-q <number>.

    In any case, I think we should just disable input methods in all but Insert state, Emacs state and Ex, and solve the remaining problems as best we can.

  11. Frank Fischer repo owner
    • changed status to open

    At least in my tests read-key seemed not to use input-methods.

    I agree we should enable input-methods only in insert mode. For evil commands it would be easy to add a further interactive-code which may either enable input-methods or does not enable them (perhaps even as customization). This command could follow any rule we can think of (like the 'take-only-first-char' approach I mentioned above). For non evil-commands ... the easiest would be to keep the state input-methods unchanged, i.e., disabled in normal-state and enabled in insert. I think this would be good compromise.

  12. Log in to comment