nsf / gocode

An autocompletion daemon for the Go programming language
MIT License
5.01k stars 656 forks source link

Some utf-8 characters mess up the gocode #460

Closed mileusna closed 4 years ago

mileusna commented 7 years ago

For some reason, gocode stopped working properly for me only in one .go file. Yes, it returned some candidates, but completely wrong. I was watching the gocode debug and it was the gocode issue, not the VS Code or the extension I was using etc. Gocode returned the wrong candidates.

So I started analyzing my entire file. I realized that I have variable with flags emoticons in it. Yes, this code compiles and works as expected with Go, so I haven't seen any reason not to use it, but it definitely mess the gocode since suggested candidates are completely wrong. When I moved this var in separate file, everything started working properly again.

var (
    flags = map[string]string{
        "EUR": "πŸ‡ͺπŸ‡Ί",
        "CHF": "πŸ‡¨πŸ‡­",
        "USD": "πŸ‡ΊπŸ‡Έ",
        "CAD": "πŸ‡¨πŸ‡¦",
        "GBP": "πŸ‡¬πŸ‡§",
        "AUD": "πŸ‡¦πŸ‡Ί",
        "HRK": "πŸ‡­πŸ‡·",
        "RSD": "πŸ‡·πŸ‡Έ",
        "BAM": "πŸ‡§πŸ‡¦",
    }
)

This time it was flags emoticon, but I guess the same issue might happen if you use some language that require utf-8, Cyrillic for example, etc.

nsf commented 7 years ago

Those particular characters look weird. If I copy & paste it to sublime, it looks like this:

aaa

Perhaps those are some fancy unicode characters and vscode being super correct thinks they have a length of 1 character. In that case I should correct myself and say explicitly that gocode accepts offset in bytes or unicode code points, not unicode characters. I'm afraid fixing it on my side will break many editors in that regard. E.g. sublime seems to be working correctly with those characters. But again, it shows them as you can see on the screenshot, as two characters.

Perhaps it's worth reporting this issue to https://github.com/Microsoft/vscode-go, not sure.

The way gocode converts characters into bytes is pretty simple:

https://github.com/nsf/gocode/blob/master/utils.go#L78-L85

And it was written long time ago, I'm pretty sure the function is correct. There is even a simple test for that: https://github.com/nsf/gocode/tree/master/_testing/test.0023

mileusna commented 7 years ago

About the testing, it doesn't mess up on all the places, but it mess up in general (more mess than the right suggestions). For example, I start typing vb. and it works OK. One if{} statement below and, I type again vb. and it is mess up, suggesting general types etc, unrealated to vb. struct.

I guess it has something to do how the gocode parse incomplete code to suggest candidates so it works on one place and do not work on the other, for example.

//
// those flags are somewhere near the top
//

func (vb MyType) Message(uid string) {
    vb.    // here it would suggest correct struct elements

    user, err := vb.user(uid)
    if err != nil {
        return
    }
    vb.     // and here completely off, general go types etc.
}

For the record, this is how it should look, and how it looks in my code (VSCode/macOS), since I'm not even sure that it is presented on every OS on the same way. macOS supports this emoticones, and since this is some mssaging platform, iOS and high-end Android phones also presents the flags correctly in messages sent by this platform.

screen shot 2017-07-19 at 18 51 54

So you are suggesting that VS Code i.e. the Go extension for VS Code which use gocode sends wrongly encoded text, os something like that?

As I said, I was watching the gocode debug, but in terminal it also presents the flags :) so I'm not sure how this bytes are transfered to gocode. This is the screenshot from debug terminal of the gocode.

screen shot 2017-07-19 at 19 17 04
nsf commented 7 years ago

Well, if the UTF-8 symbols are a problem, then editor might send the wrong cursor position, I don't know if that's true or not. Best way to find out is to launch gocode with debug mode as you do, it will show the cursor as # on location where it thinks it should be. If the location matches, then it's correctly passed from editor to the gocode.

Also gocode is far from perfect, there are cases where it would fail to show you the right results. But I need reproducable examples if you want me to fix them.

mileusna commented 7 years ago

Just checked the #, thanks for the tip. That is the case, but in both examples cursor is offset, it looks like that I was just lucky to get the right suggestions in the first example :)

This is where it works fine for vb. on the top line, but the cursor is offset.

screen shot 2017-07-19 at 19 49 16

And this is where the suggestions are far from expected for vb. and by cursor position it is obvius why.

screen shot 2017-07-19 at 19 48 12

It is easily reproducable for me on this code, I just put back the flags map back to the main file.

At least I solved my problem and I know little bit more about gocode debugging if I bump up on similar problem. :)