xtermjs / xterm.js

A terminal for the web
https://xtermjs.org/
MIT License
17.77k stars 1.64k forks source link

Support Sogou Chinese IME #3533

Closed Tyriar closed 2 years ago

Tyriar commented 3 years ago

Originally reported at https://github.com/microsoft/vscode/issues/135940

Characters get doubled when using Sogou.

image

Code pointer: https://github.com/xtermjs/xterm.js/blob/master/src/browser/input/CompositionHelper.ts

Eugeny commented 3 years ago

Seems specific to Linux - Sogou works without doubling on Win and Mac

Eugeny commented 3 years ago

Repro event dump: image

yithanglee commented 3 years ago

image

aveyuan commented 3 years ago

When will this problem be solved?It has been around for a long time, the previous version did not have this problem。No matter what input method conversion will be repeated。on the linux(zsh,bash)

one theree two . Test: use Pinyin not repeated 2021-11-23_10-12 2021-11-23_10-13 .

aveyuan commented 3 years ago

I'm vevery Sad, there was no such problem in the previous version. This problem has not been resolved for more than a month after it appeared.

yithanglee commented 3 years ago
<!doctype html>
<html>

<head>
    <title>Mohamed Elgharbawy</title>
    <link rel="stylesheet" href="css/xterm.css"/>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/xterm/3.14.5/xterm.min.js"></script>

    <!-- Favicons -->
    <link href="img/m.png" rel="icon">
    <link href="img/m.png" rel="apple-touch-icon">
</head>

<body>
    <div id="terminal"></div>
    <script>
        var term = new Terminal({
            cursorBlink: "block"
        });

        var curr_line = '';
        var entries = [];
        var currPos = 0;
        var pos = 0;
    var prev_line = '';

        term.open(document.getElementById('terminal'));
        term.prompt = () => {
            term.write('\n\r' + curr_line + '\r\n\u001b[32mscm> \u001b[37m');
        };
        term.write('Welcome to my Scheme web intepreter!');
        term.prompt();
    term.on('data', function(key) {
      prev_line = key;
      console.log('key:  ' + key)
      // if the key here entered 
      console.log(key.match(/[\u3400-\u9FBF]/))

      if (key.match(/[\u3400-\u9FBF]/) != null) {

                    pos = curr_line.length - term.buffer.cursorX + 4;
                    curr_line = [curr_line.slice(0, term.buffer.cursorX - 5), prev_line, curr_line.slice(term.buffer.cursorX - 5)].join('');
                    term.write('\33[2K\r\u001b[32mscm> \u001b[37m' + curr_line);
                    term.write('\033['.concat(pos.toString()).concat('D')); 

      }

    })

        term.on('key', function(key, ev) {
            const printable = !ev.altKey && !ev.altGraphKey && !ev.ctrlKey && !ev.metaKey &&
                !(ev.keyCode === 37 && term.buffer.cursorX < 6);

            if (ev.keyCode === 13) { // Enter key
                if (curr_line.replace(/^\s+|\s+$/g, '').length != 0) { // Check if string is all whitespace
                    entries.push(curr_line);
                    currPos = entries.length - 1;
                    term.prompt();
                } else {
                    term.write('\n\33[2K\r\u001b[32mscm> \u001b[37m');
                }
                curr_line = '';
            } else if (ev.keyCode === 8) { // Backspace
                if (term.buffer.cursorX > 5) {
                    curr_line = curr_line.slice(0, term.buffer.cursorX - 6) + curr_line.slice(term.buffer.cursorX - 5);
                    pos = curr_line.length - term.buffer.cursorX + 6;
                    term.write('\33[2K\r\u001b[32mscm> \u001b[37m' + curr_line);
                    term.write('\033['.concat(pos.toString()).concat('D')); //term.write('\033[<N>D');
                    if (term.buffer.cursorX == 5 || term.buffer.cursorX == curr_line.length + 6) {
                        term.write('\033[1C')
                    }
                }
            } else if (ev.keyCode === 38) { // Up arrow
                if (entries.length > 0) {
                    if (currPos > 0) {
                        currPos -= 1;
                    }
                    curr_line = entries[currPos];
                    term.write('\33[2K\r\u001b[32mscm> \u001b[37m' + curr_line);
                }
            } else if (ev.keyCode === 40) { // Down arrow
                currPos += 1;
                if (currPos === entries.length || entries.length === 0) {
                    currPos -= 1;
                    curr_line = '';
                    term.write('\33[2K\r\u001b[32mscm> \u001b[37m');
                } else {
                    curr_line = entries[currPos];
                    term.write('\33[2K\r\u001b[32mscm> \u001b[37m' + curr_line);

                }
            } else if (printable && !(ev.keyCode === 39 && term.buffer.cursorX > curr_line.length + 4)) {
                if (ev.keyCode != 37 && ev.keyCode != 39) {
                    var input = ev.key;
                    if (ev.keyCode == 9) { // Tab
                        input = "    ";
                    }
          console.log(prev_line)
                    pos = curr_line.length - term.buffer.cursorX + 4;
                    curr_line = [curr_line.slice(0, term.buffer.cursorX - 5), input, curr_line.slice(term.buffer.cursorX - 5)].join('');
                    term.write('\33[2K\r\u001b[32mscm> \u001b[37m' + curr_line);
                    term.write('\033['.concat(pos.toString()).concat('D')); //term.write('\033[<N>D');
                } else {
                    term.write(key);
                }
            }
        });

        term.on('paste', function(data) {
            curr_line += data;
            term.write(curr_line);
        });
    </script>
</body></html>
yithanglee commented 3 years ago

can you try the above code and see if your entry got doubled? @aveyuan

aveyuan commented 3 years ago

can you try the above code and see if your entry got doubled? @aveyuan

I'm in Vscode console input. how to do?

yithanglee commented 2 years ago

just run it as a html page.

aveyuan commented 2 years ago

Look at it's ok. image

yithanglee commented 2 years ago

looks good. so i think we're done here? 如果还有其他问题就私聊吧。

ccat3z commented 2 years ago

I wrote a workaround script based on https://github.com/xtermjs/xterm.js/pull/3535 for vscode users. Please make sure asar is installed and replace ASAR_ARCHIVE with the correct path to node_modules.asar, which may be different in different Linux distributions. sudo may also required.

#! /bin/sh

ASAR_ARCHIVE=/opt/visual-studio-code/resources/app/node_modules.asar

set -ex

temp_dir="$(mktemp -d)"
trap 'rm -rf $temp_dir' EXIT

node_modules_dir="$temp_dir/node_modules"
asar extract "$ASAR_ARCHIVE" "$node_modules_dir"
sed -i 's/"insertText"===\([a-zA-Z]\{1,\}\).inputType/"insertText"===\1.inputType\&\&!\1.composed/' "$node_modules_dir/xterm/lib/xterm.js"
asar pack "$node_modules_dir" "$ASAR_ARCHIVE"
aveyuan commented 2 years ago

@yithanglee Look at this video. https://user-images.githubusercontent.com/10907648/146708548-1737cb45-943c-42c3-a308-e152a95d5cc1.mp4

aveyuan commented 2 years ago

@yithanglee Look at this video. https://user-images.githubusercontent.com/10907648/146708548-1737cb45-943c-42c3-a308-e152a95d5cc1.mp4

@Tyriar Can you help it ? I upload a video display that question.

Tyriar commented 2 years ago

@aveyuan we haven't released the fix yet. Also, fyi your demo page is missing xterm.css

yithanglee commented 2 years ago

@aveyuan can you describe the problem? for clarity purpose, what are you trying to build?

aveyuan commented 2 years ago

@aveyuan we haven't released the fix yet. Also, fyi your demo page is missing xterm.css

ok,Thanks, I will waiting fixed.

aveyuan commented 2 years ago

@aveyuan 你能描述一下这个问题吗? 为了清楚起见,您要构建什么?

Just input one word it's ok.But input two or more words will repeated.the video can show.

aveyuan commented 2 years ago

Hi,This issue has been resolved in Vsocde 1.64.0