mdempsky / gocode

An autocompletion daemon for the Go programming language

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

gocode: autocomplete broken in VS Code

joeyak opened this issue · comments

Please answer these questions before submitting your issue. Thanks!
Also, remember that to restart gocode, you have to run gocode close.

What version of Go are you using (go version)?

go version go1.12.1 windows/amd64

What operating system and processor architecture are you using (go env)?

set GOARCH=amd64
set GOBIN=
set GOCACHE=C:\Users\Joey\AppData\Local\go-build
set GOEXE=.exe
set GOFLAGS=
set GOHOSTARCH=amd64
set GOHOSTOS=windows
set GOOS=windows
set GOPATH=C:\Users\Joey\go
set GOPROXY=
set GORACE=
set GOROOT=C:\Go
set GOTMPDIR=
set GOTOOLDIR=C:\Go\pkg\tool\windows_amd64
set GCCGO=gccgo
set CC=gcc
set CXX=g++
set CGO_ENABLED=1
set GOMOD=C:\Code\github\zorchenhimer\MovieNight\go.mod
set CGO_CFLAGS=-g -O2
set CGO_CPPFLAGS=
set CGO_CXXFLAGS=-g -O2
set CGO_FFLAGS=-g -O2
set CGO_LDFLAGS=-g -O2
set PKG_CONFIG=pkg-config
set GOGCCFLAGS=-m64 -mthreads -fmessage-length=0 -fdebug-prefix-map=C:\Users\Joey\AppData\Local\Temp\go-build805985042=/tmp/go-build -gno-record-gcc-switches

What is the debug output of gocode?

2019/04/11 18:42:06 Got autocompletion request for 'c:\Code\github\zorchenhimer\MovieNight\wasm\main.go'
2019/04/11 18:42:06 Cursor at: 272
2019/04/11 18:42:06 -------------------------------------------------------
// +build js,wasm

package main

import (
        "encoding/json"
        "fmt"
        "sort"
        "strings"
        "time"

        "github.com/dennwc/dom/js"
        "github.com/zorchenhimer/MovieNight/common"
)

var (
        timestamp bool
        color     string
        auth      common.CommandLevel
)

func join(v []js.Value) {
        j#
}

func recieve(v []js.Value) {
        if len(v) == 0 {
                fmt.Println("No data received")
                return
        }

        chatJSON, err := common.DecodeData(v[0].String())
        if err != nil {
                fmt.Printf("Error decoding data: %s\n", err)
                js.Call("appendMessages", fmt.Sprintf("<div>%v</div>", v))
                return
        }

        chat, err := chatJSON.ToData()
        if err != nil {
                fmt.Printf("Error converting ChatDataJSON to ChatData of type %d: %v", chatJSON.Type, err)
        }

        switch chat.Type {
        case common.DTHidden:
                h := chat.Data.(common.HiddenMessage)
                switch h.Type {
                case common.CdUsers:
                        names = nil
                        for _, i := range h.Data.([]interface{}) {
                                names = append(names, i.(string))
                        }
                        sort.Strings(names)
                case common.CdAuth:
                        auth = h.Data.(common.CommandLevel)
                case common.CdColor:
                        color = h.Data.(string)
                        js.Get("document").Set("cookie", fmt.Sprintf("color=%s;", color))
                case common.CdEmote:
                        data := h.Data.(map[string]interface{})
                        emoteNames = make([]string, 0, len(data))
                        emotes = make(map[string]string)
                        for k, v := range data {
                                emoteNames = append(emoteNames, k)
                                emotes[k] = v.(string)
                        }
                        sort.Strings(emoteNames)
                }
        case common.DTEvent:
                d := chat.Data.(common.DataEvent)
                // A server message is the only event that doesn't deal with names.
                if d.Event != common.EvServerMessage {
                        websocketSend("", common.CdUsers)
                }
                // on join or leave, update list of possible user names
                fallthrough
        case common.DTChat:
                appendMessage(chat.Data.HTML())
        case common.DTCommand:
                d := chat.Data.(common.DataCommand)

                switch d.Command {
                case common.CmdPlaying:
                        if d.Arguments == nil || len(d.Arguments) == 0 {
                                js.Call("setPlaying", "", "")

                        } else if len(d.Arguments) == 1 {
                                js.Call("setPlaying", d.Arguments[0], "")

                        } else if len(d.Arguments) == 2 {
                                js.Call("setPlaying", d.Arguments[0], d.Arguments[1])
                        }
                case common.CmdRefreshPlayer:
                        js.Call("initPlayer", nil)
                case common.CmdPurgeChat:
                        js.Call("purgeChat", nil)
                        appendMessage(d.HTML())
                case common.CmdHelp:
                        url := "/help"
                        if d.Arguments != nil && len(d.Arguments) > 0 {
                                url = d.Arguments[0]
                        }
                        appendMessage(d.HTML())
                        js.Get("window").Call("open", url, "_blank", "menubar=0,status=0,toolbar=0,width=300,height=600")
                }
        }
}

func appendMessage(msg string) {
        if timestamp {
                h, m, _ := time.Now().Clock()
                msg = fmt.Sprintf(`<span class="time">%02d:%02d</span> %s`, h, m, msg)
        }
        js.Call("appendMessages", "<div>"+msg+"</div>")
}

func websocketSend(msg string, dataType common.ClientDataType) error {
        if strings.TrimSpace(msg) == "" && dataType == common.CdMessage {
                return nil
        }

        data, err := json.Marshal(common.ClientData{
                Type:    dataType,
                Message: msg,
        })
        if err != nil {
                return fmt.Errorf("could not marshal data: %v", err)
        }

        js.Call("websocketSend", string(data))
        return nil
}

func send(this js.Value, v []js.Value) interface{} {
        if len(v) != 1 {
                showChatError(fmt.Errorf("expected 1 parameter, got %d", len(v)))
                return false
        }

        err := websocketSend(v[0].String(), common.CdMessage)
        if err != nil {
                showChatError(err)
                return false
        }
        return true
}

func showChatError(err error) {
        if err != nil {
                fmt.Printf("Could not send: %v\n", err)
                js.Call("appendMessages", `<div><span style="color: red;">Could not send message</span></div>`)
        }
}

func showTimestamp(v []js.Value) {
        if len(v) != 1 {
                // Don't bother with returning a value
                return
        }
        timestamp = v[0].Bool()
}

func isValidColor(this js.Value, v []js.Value) interface{} {
        if len(v) != 1 {
                return false
        }
        return common.IsValidColor(v[0].String())
}

func isValidName(this js.Value, v []js.Value) interface{} {
        if len(v) != 1 {
                return false
        }
        return common.IsValidName(v[0].String())
}

func debugValues(v []js.Value) {
        for k, v := range map[string]interface{}{
                "timestamp":               timestamp,
                "auth":                    auth,
                "color":                   color,
                "current suggestion":      currentSug,
                "current suggestion type": currentSugType,
                "filtered suggestions":    filteredSug,
                "user names":              names,
                "emote names":             emoteNames,
        } {
                fmt.Printf("%s: %#v\n", k, v)
        }
}

func main() {
        js.Set("processMessageKey", js.FuncOf(processMessageKey))
        js.Set("sendMessage", js.FuncOf(send))
        js.Set("isValidColor", js.FuncOf(isValidColor))
        js.Set("isValidName", js.FuncOf(isValidName))

        js.Set("recieveMessage", js.CallbackOf(recieve))
        js.Set("processMessage", js.CallbackOf(processMessage))
        js.Set("debugValues", js.CallbackOf(debugValues))
        js.Set("showTimestamp", js.CallbackOf(showTimestamp))
        js.Set("join", js.CallbackOf(join))

        go func() {
                time.Sleep(time.Second * 1)
                inner := `<option value=""></option>`
                for _, c := range common.Colors {
                        inner += fmt.Sprintf(`<option value="%s">%s</option>\n`, c, c)
                }

                js.Get("colorSelect").Set("innerHTML", inner)
        }()

        // This is needed so the goroutine does not end
        for {
                // heatbeat to keep connection alive to deal with nginx
                if js.Get("inChat").Bool() {
                        websocketSend("", common.CdPing)
                }
                time.Sleep(time.Second * 10)
        }
}
2019/04/11 18:42:06 -------------------------------------------------------
2019/04/11 18:42:06 Elapsed duration: 17.9517ms
2019/04/11 18:42:06 Offset: 0
2019/04/11 18:42:06 Number of candidates found: 3
2019/04/11 18:42:06 Candidates are:
2019/04/11 18:42:06   func join(v []js.Value)
2019/04/11 18:42:06   package js
2019/04/11 18:42:06   package json
2019/04/11 18:42:06 =======================================================
2019/04/11 18:42:08 Got autocompletion request for 'c:\Code\github\zorchenhimer\MovieNight\wasm\main.go'
2019/04/11 18:42:08 Cursor at: 274
2019/04/11 18:42:08 -------------------------------------------------------
// +build js,wasm

package main

import (
        "encoding/json"
        "fmt"
        "sort"
        "strings"
        "time"

        "github.com/dennwc/dom/js"
        "github.com/zorchenhimer/MovieNight/common"
)

var (
        timestamp bool
        color     string
        auth      common.CommandLevel
)

func join(v []js.Value) {
        js.#
}

func recieve(v []js.Value) {
        if len(v) == 0 {
                fmt.Println("No data received")
                return
        }

        chatJSON, err := common.DecodeData(v[0].String())
        if err != nil {
                fmt.Printf("Error decoding data: %s\n", err)
                js.Call("appendMessages", fmt.Sprintf("<div>%v</div>", v))
                return
        }

        chat, err := chatJSON.ToData()
        if err != nil {
                fmt.Printf("Error converting ChatDataJSON to ChatData of type %d: %v", chatJSON.Type, err)
        }

        switch chat.Type {
        case common.DTHidden:
                h := chat.Data.(common.HiddenMessage)
                switch h.Type {
                case common.CdUsers:
                        names = nil
                        for _, i := range h.Data.([]interface{}) {
                                names = append(names, i.(string))
                        }
                        sort.Strings(names)
                case common.CdAuth:
                        auth = h.Data.(common.CommandLevel)
                case common.CdColor:
                        color = h.Data.(string)
                        js.Get("document").Set("cookie", fmt.Sprintf("color=%s;", color))
                case common.CdEmote:
                        data := h.Data.(map[string]interface{})
                        emoteNames = make([]string, 0, len(data))
                        emotes = make(map[string]string)
                        for k, v := range data {
                                emoteNames = append(emoteNames, k)
                                emotes[k] = v.(string)
                        }
                        sort.Strings(emoteNames)
                }
        case common.DTEvent:
                d := chat.Data.(common.DataEvent)
                // A server message is the only event that doesn't deal with names.
                if d.Event != common.EvServerMessage {
                        websocketSend("", common.CdUsers)
                }
                // on join or leave, update list of possible user names
                fallthrough
        case common.DTChat:
                appendMessage(chat.Data.HTML())
        case common.DTCommand:
                d := chat.Data.(common.DataCommand)

                switch d.Command {
                case common.CmdPlaying:
                        if d.Arguments == nil || len(d.Arguments) == 0 {
                                js.Call("setPlaying", "", "")

                        } else if len(d.Arguments) == 1 {
                                js.Call("setPlaying", d.Arguments[0], "")

                        } else if len(d.Arguments) == 2 {
                                js.Call("setPlaying", d.Arguments[0], d.Arguments[1])
                        }
                case common.CmdRefreshPlayer:
                        js.Call("initPlayer", nil)
                case common.CmdPurgeChat:
                        js.Call("purgeChat", nil)
                        appendMessage(d.HTML())
                case common.CmdHelp:
                        url := "/help"
                        if d.Arguments != nil && len(d.Arguments) > 0 {
                                url = d.Arguments[0]
                        }
                        appendMessage(d.HTML())
                        js.Get("window").Call("open", url, "_blank", "menubar=0,status=0,toolbar=0,width=300,height=600")
                }
        }
}

func appendMessage(msg string) {
        if timestamp {
                h, m, _ := time.Now().Clock()
                msg = fmt.Sprintf(`<span class="time">%02d:%02d</span> %s`, h, m, msg)
        }
        js.Call("appendMessages", "<div>"+msg+"</div>")
}

func websocketSend(msg string, dataType common.ClientDataType) error {
        if strings.TrimSpace(msg) == "" && dataType == common.CdMessage {
                return nil
        }

        data, err := json.Marshal(common.ClientData{
                Type:    dataType,
                Message: msg,
        })
        if err != nil {
                return fmt.Errorf("could not marshal data: %v", err)
        }

        js.Call("websocketSend", string(data))
        return nil
}

func send(this js.Value, v []js.Value) interface{} {
        if len(v) != 1 {
                showChatError(fmt.Errorf("expected 1 parameter, got %d", len(v)))
                return false
        }

        err := websocketSend(v[0].String(), common.CdMessage)
        if err != nil {
                showChatError(err)
                return false
        }
        return true
}

func showChatError(err error) {
        if err != nil {
                fmt.Printf("Could not send: %v\n", err)
                js.Call("appendMessages", `<div><span style="color: red;">Could not send message</span></div>`)
        }
}

func showTimestamp(v []js.Value) {
        if len(v) != 1 {
                // Don't bother with returning a value
                return
        }
        timestamp = v[0].Bool()
}

func isValidColor(this js.Value, v []js.Value) interface{} {
        if len(v) != 1 {
                return false
        }
        return common.IsValidColor(v[0].String())
}

func isValidName(this js.Value, v []js.Value) interface{} {
        if len(v) != 1 {
                return false
        }
        return common.IsValidName(v[0].String())
}

func debugValues(v []js.Value) {
        for k, v := range map[string]interface{}{
                "timestamp":               timestamp,
                "auth":                    auth,
                "color":                   color,
                "current suggestion":      currentSug,
                "current suggestion type": currentSugType,
                "filtered suggestions":    filteredSug,
                "user names":              names,
                "emote names":             emoteNames,
        } {
                fmt.Printf("%s: %#v\n", k, v)
        }
}

func main() {
        js.Set("processMessageKey", js.FuncOf(processMessageKey))
        js.Set("sendMessage", js.FuncOf(send))
        js.Set("isValidColor", js.FuncOf(isValidColor))
        js.Set("isValidName", js.FuncOf(isValidName))

        js.Set("recieveMessage", js.CallbackOf(recieve))
        js.Set("processMessage", js.CallbackOf(processMessage))
        js.Set("debugValues", js.CallbackOf(debugValues))
        js.Set("showTimestamp", js.CallbackOf(showTimestamp))
        js.Set("join", js.CallbackOf(join))

        go func() {
                time.Sleep(time.Second * 1)
                inner := `<option value=""></option>`
                for _, c := range common.Colors {
                        inner += fmt.Sprintf(`<option value="%s">%s</option>\n`, c, c)
                }

                js.Get("colorSelect").Set("innerHTML", inner)
        }()

        // This is needed so the goroutine does not end
        for {
                // heatbeat to keep connection alive to deal with nginx
                if js.Get("inChat").Bool() {
                        websocketSend("", common.CdPing)
                }
                time.Sleep(time.Second * 10)
        }
}
2019/04/11 18:42:08 -------------------------------------------------------
2019/04/11 18:42:08 Error parsing input file (outer block):
2019/04/11 18:42:08  c:\Code\github\zorchenhimer\MovieNight\wasm\main.go:23:5: expected selector or type assertion, found ';'
2019/04/11 18:42:08 Elapsed duration: 15.9576ms
2019/04/11 18:42:08 Offset: 0
2019/04/11 18:42:08 Number of candidates found: 33
2019/04/11 18:42:08 Candidates are:
2019/04/11 18:42:08   const TypeFunction js.Type
2019/04/11 18:42:08   const TypeObject js.Type
2019/04/11 18:42:08   func Array() js.Value
2019/04/11 18:42:08   func AsyncCallbackOf(fnc func(v []js.Value)) js.Func
2019/04/11 18:42:08   func Call(name string, args ...interface{}) js.Value
2019/04/11 18:42:08   func CallbackOf(fnc func(v []js.Value)) js.Func
2019/04/11 18:42:08   func Class(class string) js.Value
2019/04/11 18:42:08   func FuncOf(fnc func(this js.Value, args []js.Value) interface{}) js.Func
2019/04/11 18:42:08   func Get(name string, path ...string) js.Value
2019/04/11 18:42:08   func MMap(p []byte) *js.Memory
2019/04/11 18:42:08   func NativeFuncOf(argsAndCode ...string) js.Value
2019/04/11 18:42:08   func New(class string, args ...interface{}) js.Value
2019/04/11 18:42:08   func NewArray() js.Value
2019/04/11 18:42:08   func NewError(e interface{JSValue() js.Ref}) error
2019/04/11 18:42:08   func NewEventCallback(fnc func(v js.Value)) js.Func
2019/04/11 18:42:08   func NewObject() js.Value
2019/04/11 18:42:08   func NewPromise(fnc func() ([]interface{}, error)) js.Value
2019/04/11 18:42:08   func Object() js.Value
2019/04/11 18:42:08   func Set(name string, v interface{})
2019/04/11 18:42:08   func TypedArrayOf(o interface{}) js.TypedArray
2019/04/11 18:42:08   func ValueOf(o interface{}) js.Value
2019/04/11 18:42:08   type Arr []interface{}
2019/04/11 18:42:08   type Error struct
2019/04/11 18:42:08   type Func struct
2019/04/11 18:42:08   type FuncGroup struct
2019/04/11 18:42:08   type Memory struct
2019/04/11 18:42:08   type Obj map[string]interface{}
2019/04/11 18:42:08   type Promise struct
2019/04/11 18:42:08   type Ref struct
2019/04/11 18:42:08   type Type int
2019/04/11 18:42:08   type TypedArray struct
2019/04/11 18:42:08   type Value struct
2019/04/11 18:42:08   type Wrapper interface
2019/04/11 18:42:08 =======================================================

What (client-side) flags are you passing into gocode?

Please note here if you are using -source, -builtin, -ignore-case, -unimported-packages, or -fallback-to-source.

What editor are using?

VSCode

The problem I am having is when working in a file that will be compiled for wasm, the suggestions just show the two packages. Tab or enter does nothing.
image

When I run gocode -s -debug, it works properly.
image

I ran it with this file and I got the same problem
main.zip

@joeyak: My apologies for the delay in replying. Is this still an issue for you?

I tested it again, and it is not an issue.