gocode icon indicating copy to clipboard operation
gocode copied to clipboard

Quoted string always presents irrelevant suggestion list

Open jblachly opened this issue 7 years ago • 6 comments

Hi, first-time gocode user (using with VSC, inspecting output with debugging console). First, gocode is tremendous -- thank you!

I don't know any other way to to describe this behavior succinctly other than: "Every time I close the quotes on a string, I am presented with a list of irrelevant suggestions. This is extremely irritating because if I for example am defining a string:

aString := "A String"

By the time I close the string "A String", gocode suggests a long list of autocompletion, so when I hit enter to go to the next line, I instead get inserted the first suggestion (in this case func append([]type, ...type) []type)

Help!

Debugging output:

Example 1:

package main

import "fmt"#
2016/08/14 19:49:15 -------------------------------------------------------
2016/08/14 19:49:15 -------------------
2016/08/14 19:49:15 rebuilding package
2016/08/14 19:49:15 package import: fmt
2016/08/14 19:49:15 package object: /usr/local/go/pkg/darwin_amd64/fmt.a
2016/08/14 19:49:15 package source dir: /usr/local/go/src/fmt
2016/08/14 19:49:15 package source files: []
2016/08/14 19:49:15 GOPATH: /Users/james/Documents/Development/go
2016/08/14 19:49:15 GOROOT: /usr/local/go
2016/08/14 19:49:16 build out:
2016/08/14 19:49:16 Found "fmt" at "/usr/local/go/pkg/darwin_amd64/fmt.a"
2016/08/14 19:49:16 Offset: 0
2016/08/14 19:49:16 Number of candidates found: 40
2016/08/14 19:49:16 Candidates are:
2016/08/14 19:49:16   const false
2016/08/14 19:49:16   const iota
2016/08/14 19:49:16   const nil
2016/08/14 19:49:16   const true
2016/08/14 19:49:16   func append([]type, ...type) []type
2016/08/14 19:49:16   func cap(container) int
2016/08/14 19:49:16   func close(channel)
2016/08/14 19:49:16   func complex(real, imag) complex
2016/08/14 19:49:16   func copy(dst, src)
2016/08/14 19:49:16   func delete(map[typeA]typeB, typeA)
2016/08/14 19:49:16   func imag(complex)
2016/08/14 19:49:16   func len(container) int
2016/08/14 19:49:16   func make(type, len[, cap]) type
2016/08/14 19:49:16   func new(type) *type
2016/08/14 19:49:16   func panic(interface{})
2016/08/14 19:49:16   func print(...interface{})
2016/08/14 19:49:16   func println(...interface{})
2016/08/14 19:49:16   func real(complex)
2016/08/14 19:49:16   func recover() interface{}
2016/08/14 19:49:16   package fmt
2016/08/14 19:49:16   type bool built-in
2016/08/14 19:49:16   type byte built-in
2016/08/14 19:49:16   type complex128 built-in
2016/08/14 19:49:16   type complex64 built-in
2016/08/14 19:49:16   type error interface
2016/08/14 19:49:16   type float32 built-in
2016/08/14 19:49:16   type float64 built-in
2016/08/14 19:49:16   type int built-in
2016/08/14 19:49:16   type int16 built-in
2016/08/14 19:49:16   type int32 built-in
2016/08/14 19:49:16   type int64 built-in
2016/08/14 19:49:16   type int8 built-in
2016/08/14 19:49:16   type rune built-in
2016/08/14 19:49:16   type string built-in
2016/08/14 19:49:16   type uint built-in
2016/08/14 19:49:16   type uint16 built-in
2016/08/14 19:49:16   type uint32 built-in
2016/08/14 19:49:16   type uint64 built-in
2016/08/14 19:49:16   type uint8 built-in
2016/08/14 19:49:16   type uintptr built-in
2016/08/14 19:49:16 =======================================================

Example 2 (same behavior, different context):

package main

import "fmt"

func main() {
    fmt.Println("Hello"#)
}
2016/08/14 19:50:06 -------------------------------------------------------
2016/08/14 19:50:06 -------------------
2016/08/14 19:50:06 rebuilding package
2016/08/14 19:50:06 package import: fmt
2016/08/14 19:50:06 package object: /usr/local/go/pkg/darwin_amd64/fmt.a
2016/08/14 19:50:06 package source dir: /usr/local/go/src/fmt
2016/08/14 19:50:06 package source files: []
2016/08/14 19:50:06 GOPATH: /Users/james/Documents/Development/go
2016/08/14 19:50:06 GOROOT: /usr/local/go
2016/08/14 19:50:06 build out:
2016/08/14 19:50:06 Found "fmt" at "/usr/local/go/pkg/darwin_amd64/fmt.a"
2016/08/14 19:50:06 Error parsing input file (inner block):
2016/08/14 19:50:06  4:24: missing ',' in argument list
2016/08/14 19:50:06 Offset: 0
2016/08/14 19:50:06 Number of candidates found: 41
2016/08/14 19:50:06 Candidates are:
2016/08/14 19:50:06   const false
2016/08/14 19:50:06   const iota
2016/08/14 19:50:06   const nil
2016/08/14 19:50:06   const true
2016/08/14 19:50:06   func append([]type, ...type) []type
2016/08/14 19:50:06   func cap(container) int
2016/08/14 19:50:06   func close(channel)
2016/08/14 19:50:06   func complex(real, imag) complex
2016/08/14 19:50:06   func copy(dst, src)
2016/08/14 19:50:06   func delete(map[typeA]typeB, typeA)
2016/08/14 19:50:06   func imag(complex)
2016/08/14 19:50:06   func len(container) int
2016/08/14 19:50:06   func main()
2016/08/14 19:50:06   func make(type, len[, cap]) type
2016/08/14 19:50:06   func new(type) *type
2016/08/14 19:50:06   func panic(interface{})
2016/08/14 19:50:06   func print(...interface{})
2016/08/14 19:50:06   func println(...interface{})
2016/08/14 19:50:06   func real(complex)
2016/08/14 19:50:06   func recover() interface{}
2016/08/14 19:50:06   package fmt
2016/08/14 19:50:06   type bool built-in
2016/08/14 19:50:06   type byte built-in
2016/08/14 19:50:06   type complex128 built-in
2016/08/14 19:50:06   type complex64 built-in
2016/08/14 19:50:06   type error interface
2016/08/14 19:50:06   type float32 built-in
2016/08/14 19:50:06   type float64 built-in
2016/08/14 19:50:06   type int built-in
2016/08/14 19:50:06   type int16 built-in
2016/08/14 19:50:06   type int32 built-in
2016/08/14 19:50:06   type int64 built-in
2016/08/14 19:50:06   type int8 built-in
2016/08/14 19:50:06   type rune built-in
2016/08/14 19:50:06   type string built-in
2016/08/14 19:50:06   type uint built-in
2016/08/14 19:50:06   type uint16 built-in
2016/08/14 19:50:06   type uint32 built-in
2016/08/14 19:50:06   type uint64 built-in
2016/08/14 19:50:06   type uint8 built-in
2016/08/14 19:50:06   type uintptr built-in
2016/08/14 19:50:06 =======================================================

jblachly avatar Aug 14 '16 23:08 jblachly

Gocode just tries to find the best completion results it can when you ask it to. If editor triggers completion at weird location it's a problem of an editor. Gocode has no semantics of "valid completion point".

nsf avatar Aug 15 '16 07:08 nsf

I understand your point. However, I am surprised at the wrong suggestions, but after reading point no. 4 in #307 it sounds as if gocode is not looking at the surrounding context (enough). I haven't internalized the details of gocode yet enough to make the fix but it looks like this case could be handled near here:

https://github.com/nsf/gocode/blob/master/cursorcontext.go#L285

If you think that sounds right I'd be happy to work on this small fix, but if this is the wrong location to handle this case I'd love a pointer to elsewhere.

jblachly avatar Aug 15 '16 13:08 jblachly

Well in both of your examples it shows package-level autocompletion list, which means no context is considered. Gocode recognizes only few contexts: 1. when something before the cursor looks like a dot expression (e.g. whatever[0].member.), 2. when cursor is within a struct literal, it works sometimes, but often it fails (e.g. MyStruct{Hello#}, # - cursor), and 3. when cursor appears to be within a string of an import statement, third one is not tested very well, it's a reasonably recent feature.

Gocode doesn't recognize fancier contexts like function arguments and if statements and other things where you might do some better hinting.

nsf avatar Aug 15 '16 14:08 nsf

Oh and what kind of completion do you expect after a string literal?

nsf avatar Aug 15 '16 14:08 nsf

I would expect an empty list (i.e., no suggestions) after completion of a string literal.

Perhaps this can be solved in the editor as you suggest. I have commented on a relevant issue there. Thanks for your help.

jblachly avatar Aug 15 '16 14:08 jblachly

Yeah, gocode never returns an empty result. At least it shouldn't, maybe there are cases with incorrect syntax that you can make it do so, but the intentional logic is to try to narrow down the choice using some context, if no context is found, just return everything that is visible from cursor position.

However if editor triggers autocompletion automatically in such places, I believe it can be prevented. Personally I don't like automatic autocompletions at all, I use a key to trigger it, but most editors have some sort of a prefix regexp which allows and disallows automatic triggering. No idea about visual studio code though, I don't use it for Go.

nsf avatar Aug 15 '16 14:08 nsf