glacambre / firenvim

Embed Neovim in Chrome, Firefox & others.
GNU General Public License v3.0
4.69k stars 145 forks source link

Strange behavior when typing in Japanese #1431

Closed alanoliveira closed 1 year ago

alanoliveira commented 1 year ago

What I tried to do

When I try to type in Japanese firenvim is kind of echoing all the previous entry. For example if I type あ and press enter, the output is (no problem here)

but then, if I press う the output is

ああう

https://user-images.githubusercontent.com/6012864/193638084-a7692be1-c551-4690-adda-a721e1d6446c.mp4

This same issue happens on my work PC, I don't have access to it right now but it is a Mac OS Catalina. If I use nvim directly on the terminal it works fine. Any idea what this could be this?

glacambre commented 1 year ago

Hi, thanks for the report. I think this is probably the same issue as https://github.com/glacambre/firenvim/issues/1375 . I'll attempt a fix in the coming days :)

alanoliveira commented 1 year ago

Hi! Yes, it seems to be the same issue. Sorry I was searching for "Japanese" related issues before create this one, but make sense Chinese have the same problem. I really appreciate if you could give a look on this. :bow:

glacambre commented 1 year ago

Could you try this version and let me know if it fixes your problem? In order to try it:

KimbingNg commented 1 year ago

Could you try this version and let me know if it fixes your problem? In order to try it:

  • Remove firenvim from Chrome in chrome://extensions
  • Unzip the archive
  • Enable developer mode (top right toggle in chrome://extensions)
  • Click on the load unpacked button
  • Select the directory where you unzipped the archive

Thanks for your quick fix. This version fixes the issue of duplicate characters, but comes with new issues: The Chinese characters I typed only show up when I switch back to normal mode or when I enter an ASCII symbol. My OS: MacOS

KimbingNg commented 1 year ago

This is my dirty hack. It fixes both issues.

document.globalIsComposing = false;   // A dirty way to declare a global variable
function translateKey(key) {
    if (document.globalIsComposing)
        return "";               // avoid unwanted characters.
    if (nonLiteralKeys[key] !== undefined) {
        return nonLiteralKeys[key];
    }
    return key;
}
        const acceptInput = ((evt) => {
            this.emit("input", evt.target.value);
            evt.preventDefault();
            evt.stopImmediatePropagation();
        }).bind(this);
        this.keyHandler.addEventListener("input", (evt) => {
            document.globalIsComposing = evt.isComposing;
            if (evt.isTrusted && !evt.isComposing) {
                acceptInput(evt);
                evt.target.innerText = "";
                evt.target.value = "";
            }
        });
        // if (isChrome()){
            this.keyHandler.addEventListener("compositionend", (e) => {
                document.globalIsComposing = false;
                acceptInput(e);
                e.target.innerText = "";   // clear
                e.target.value = "";     // clear
            });
        // }

I am new to javascript. Can you please let me know what the better way to declare a global variable is?

alanoliveira commented 1 year ago

Apologizes for my delayed feedback. It not worked, as mr. KimbingNg described above, now when I type something the string keeps on the buffer until I left the Japanese input type mode and press any char.

https://user-images.githubusercontent.com/6012864/195160146-207f4abf-bc4d-471c-94ce-9a2b391b0ca8.mp4

glacambre commented 1 year ago

Sorry it took so long, but I've made a huge refactor that hopefully made implementing @KimbingNg's solution a bit cleaner/easier:

diff --git a/src/KeyHandler.ts b/src/KeyHandler.ts
index 07bf4e7..f81ce25 100644
--- a/src/KeyHandler.ts
+++ b/src/KeyHandler.ts
@@ -5,6 +5,7 @@ import { isChrome } from "./utils/utils";

 export class KeyHandler extends EventEmitter<"input", (s: string) => void> {
     private currentMode : NvimMode;
+    private isComposing : boolean;
     constructor(private elem: HTMLElement, settings: GlobalSettings) {
         super();
         const ignoreKeys = settings.ignoreKeys;
@@ -28,6 +29,7 @@ export class KeyHandler extends EventEmitter<"input", (s: string) => void> {
             const specialKeys = [["Alt", "A"], ["Control", "C"], ["OS", "D"], ["Meta", "D"]];
             // The event has to be trusted and either have a modifier or a non-literal representation
             if (evt.isTrusted
+                && !evt.isComposing
                 && (nonLiteralKeys[evt.key] !== undefined
                     || specialKeys.find(([mod, _]: [string, string]) =>
                                         evt.key !== mod && (evt as any).getModifierState(mod)))) {
@@ -55,6 +57,7 @@ export class KeyHandler extends EventEmitter<"input", (s: string) => void> {
         })

         const acceptInput = ((evt: any) => {
+            this.isComposing = evt.isComposing;
             this.emit("input", evt.target.value);
             evt.preventDefault();
             evt.stopImmediatePropagation();

Could you test this version and let me know if the problem is fixed?

alanoliveira commented 1 year ago

Thank you for your hard work @glacambre :pray: In this new version, the previous issue persists (this one https://github.com/glacambre/firenvim/issues/1431#issuecomment-1275014631)

glacambre commented 1 year ago

@alanoliveira Thank you for the prompt reply. I think I understand what's wrong now. Could you try this one? chrome.zip

alanoliveira commented 1 year ago

Thank you for the great job.

On Linux (6.0.1-arch2-1 x86_64) it is working great! There is a minor issue when we press space to select a word from the list, we can't see the preview of the selected word(for me that is not a problem).

https://user-images.githubusercontent.com/6012864/199948958-c2ae7897-688e-4223-b3ab-d9628338130a.mp4

On Mac it seems not working, I could not test it properly today, but tomorrow I'll try to describe the details and make a video.

Thank you very much for the fix!

alanoliveira commented 1 year ago

On mac, when I press enter to accept some word, it also adds a new line before the selected word https://user-images.githubusercontent.com/6012864/200115185-2c074c87-1eca-4341-a85b-864fcfee70c2.mov