Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

problem with using backspace for Chinese characters(one char of 2 bytes) #422

Closed
jonnyliang opened this issue Feb 3, 2023 · 9 comments

Comments

@jonnyliang
Copy link

Describe the bug
Chinese (one char of 2 bytes ) input support is not very good when using Backspace key,
pelases check the eraseNPreviousChars in the file “/sshd/terminal)/terminal.go”,
I guess the n is wrong as below, because it real moved two place,so there n should be 2 not 1,

405 for i := 0; i < n; i++ {
406 t.queue(space)
407 }
408 t.advanceCursor(n)

Versions

  • Client version: CentOS Linux release 7.9.2009 (Core)
  • Server version:CentOS Linux release 7.9.2009 (Core)
  • Latest server version available: [v1.11-rc5]

To Reproduce
Steps to reproduce the behavior:

  1. login in
  2. Enter any Chinese characters,For example:啊飒飒的
  3. press Backspace key , you will see the problem

thank you for you sharing,it is help for my work!

@sleibrock
Copy link
Contributor

This might not be entirely supported yet, since the EraseNPreviousChars(n) function erases N amount of characters at a time. You can see how the backspace function is implemented a few lines down on that file here

case keyBackspace:
if t.pos == 0 {
return
}
t.eraseNPreviousChars(1)

I am not super familiar enough with the keyboard I/O code personally, but I don't think ssh-chat is contextually aware of what your user locale is going to be exactly. The server side is responsible for key inputs and rendering the readline functionality, but its probable that ssh-chat doesn't have enough contextual information for each user to be able to do this. To ssh-chat, when you enter a 2-byte character, ssh-chat sees exactly 2-bytes. It doesn't process whether or not that might be a rune, it only handles it at an individual byte level.

@shazow
Copy link
Owner

shazow commented Feb 3, 2023

Hi @jonnyliang, I'm not able to reproduce this. It may be an issue with your terminal, or compatibility between your terminal and how we handle unicode character width counting:

image

What terminal are you using? Could you try a modern terminal like kitty or alacritty?

@sheng-ri
Copy link

sheng-ri commented Feb 5, 2023

I reproduce it. That is terminal compatibility issue.
In alacritty,it works perfect.
In cmd/powershell/windows temiernal, It will leave char after chinese in buffer(I guess)

(Delete chinese from the end of input)
image
(Delete chinese from the middle of input.And enf of input " g g" is display after delete)
image

Versions

Client version: Ubuntu 22.04
Server version:Windows 11
ssh-chat version: 1.10,1.11-rc5

@shazow
Copy link
Owner

shazow commented Feb 5, 2023

Yea, that's a terminal issue unfortunately, they don't count character width the same way as modern terminals. There's no way to support both.

@shazow shazow closed this as completed Feb 5, 2023
@jonnyliang
Copy link
Author

Hi @jonnyliang, I'm not able to reproduce this. It may be an issue with your terminal, or compatibility between your terminal and how we handle unicode character width counting:

image

What terminal are you using? Could you try a modern terminal like kitty or alacritty?

You are right, this a terminal issue unfortunately, it will leave half of a char when I using XSHELL 5. it work by using alacritty! thanks!

@jonnyliang
Copy link
Author

Yea, that's a terminal issue unfortunately, they don't count character width the same way as modern terminals. There's no way to support both.
By the way, I fixed the problem on my local code as below, it seems work well on alacritty and XSHELL,but I not sure its ok.

//
_, _, left, _ := t.moveCursorToPos(t.pos)
copy(t.line[t.pos:], t.line[n+t.pos:])
t.line = t.line[:len(t.line)-n]
if t.echo {
t.writeLine(t.line[t.pos:])
for i := 0; i < left; i++ {
t.queue(space)
}
t.advanceCursor(left)
....

@jonnyliang
Copy link
Author

reproduce on alacritty~!
截图_1675848773743

@shazow
Copy link
Owner

shazow commented Feb 12, 2023

If you have a patch that fixes this and doesn't break other things, please make a PR and I'll take a look. :)

@jonnyliang
Copy link
Author

jonnyliang commented Feb 13, 2023

I just modified content of two functions,Hope for better solution!

ssh-chat/sshd/terminal/terminal.go


func (t *Terminal) moveCursorToPos(pos int) (up, down, left, right int) {
  ...
  return up, down, left, right
}

func` (t *Terminal) eraseNPreviousChars(n int) {
        if n == 0 {
                return
        }

        if t.pos < n {
                n = t.pos
        }
        t.pos -= n
        //t.moveCursorToPos(t.pos)
       //-----------fixed begin------------------------------ 
        up, _, left, _ := t.moveCursorToPos(t.pos) 
        if left ==0{
            if up == 1{left =up}
        }
        //-----------fixed end------------------------------ 
        copy(t.line[t.pos:], t.line[n+t.pos:])
        t.line = t.line[:len(t.line)-n]
        if t.echo {
                t.writeLine(t.line[t.pos:])
                for i := 0; i < left; i++ { // left  replace n 
                        t.queue(space)
                }
                t.advanceCursor(left)
                t.moveCursorToPos(t.pos)
        }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants