├── internal ├── suggest │ ├── testdata │ │ ├── test.0063 │ │ │ ├── test.go.in │ │ │ └── out.expected │ │ ├── test.0006 │ │ │ ├── out.expected │ │ │ ├── test.go.in │ │ │ └── b.go │ │ ├── test.0047 │ │ │ ├── out.expected │ │ │ └── test.go.in │ │ ├── test.0057 │ │ │ ├── out.expected │ │ │ └── test.go.in │ │ ├── test.0064 │ │ │ ├── config.json │ │ │ ├── out.expected │ │ │ └── test.go.in │ │ ├── test.0065 │ │ │ ├── config.json │ │ │ ├── test.go.in │ │ │ └── out.expected │ │ ├── test.0066 │ │ │ ├── config.json │ │ │ ├── out.expected │ │ │ └── test.go.in │ │ ├── test.0067 │ │ │ ├── config.json │ │ │ ├── out.expected │ │ │ └── test.go.in │ │ ├── test.0068 │ │ │ ├── config.json │ │ │ ├── out.expected │ │ │ └── test.go.in │ │ ├── test.0069 │ │ │ ├── config.json │ │ │ ├── out.expected │ │ │ └── test.go.in │ │ ├── test.0070 │ │ │ ├── out.expected │ │ │ ├── config.json │ │ │ └── test.go.in │ │ ├── test.0071 │ │ │ ├── out.expected │ │ │ └── test.go.in │ │ ├── test.0072 │ │ │ ├── out.expected │ │ │ └── test.go.in │ │ ├── test.0073 │ │ │ ├── out.expected │ │ │ └── test.go.in │ │ ├── test.0049 │ │ │ ├── out.expected │ │ │ └── test.go.in │ │ ├── test.0050 │ │ │ ├── out.expected │ │ │ └── test.go.in │ │ ├── test.0059 │ │ │ ├── out.expected │ │ │ └── test.go.in │ │ ├── test.0060 │ │ │ ├── out.expected │ │ │ └── test.go.in │ │ ├── test.0061 │ │ │ ├── out.expected │ │ │ └── test.go.in │ │ ├── test.0062 │ │ │ ├── out.expected │ │ │ └── test.go.in │ │ ├── test.0056 │ │ │ ├── out.expected │ │ │ └── test.go.in │ │ ├── test.0011 │ │ │ ├── out.expected │ │ │ └── test.go.in │ │ ├── test.0028 │ │ │ ├── out.expected │ │ │ └── test.go.in │ │ ├── test.0031 │ │ │ ├── out.expected │ │ │ └── test.go.in │ │ ├── test.0038 │ │ │ ├── out.expected │ │ │ └── test.go.in │ │ ├── test.0039 │ │ │ ├── out.expected │ │ │ └── test.go.in │ │ ├── test.0042 │ │ │ ├── out.expected │ │ │ └── test.go.in │ │ ├── test.0044 │ │ │ ├── out.expected │ │ │ └── test.go.in │ │ ├── test.0053 │ │ │ ├── out.expected │ │ │ ├── test.go.in │ │ │ └── b.go │ │ ├── test.0055 │ │ │ ├── out.expected │ │ │ └── test.go.in │ │ ├── test.0058 │ │ │ ├── out.expected │ │ │ └── test.go.in │ │ ├── test.0009 │ │ │ ├── out.expected │ │ │ └── test.go.in │ │ ├── test.0018 │ │ │ ├── out.expected │ │ │ └── test.go.in │ │ ├── test.0027 │ │ │ ├── out.expected │ │ │ └── test.go.in │ │ ├── test.0024 │ │ │ ├── out.expected │ │ │ └── test.go.in │ │ ├── test.0030 │ │ │ ├── out.expected │ │ │ └── test.go.in │ │ ├── test.0041 │ │ │ ├── out.expected │ │ │ └── test.go.in │ │ ├── test.0052 │ │ │ ├── out.expected │ │ │ └── test.go.in │ │ ├── test.0001 │ │ │ ├── test.go.in │ │ │ └── out.expected │ │ ├── test.0045 │ │ │ ├── test.go.in │ │ │ └── out.expected │ │ ├── test.0025 │ │ │ ├── test.go.in │ │ │ └── out.expected │ │ ├── test.0046 │ │ │ ├── test.go.in │ │ │ └── out.expected │ │ ├── test.0048 │ │ │ ├── test.go.in │ │ │ └── out.expected │ │ ├── test.0007 │ │ │ ├── test.go.in │ │ │ └── out.expected │ │ ├── test.0040 │ │ │ ├── out.expected │ │ │ └── test.go.in │ │ ├── test.0043 │ │ │ ├── out.expected │ │ │ └── test.go.in │ │ ├── test.0016 │ │ │ ├── out.expected │ │ │ └── test.go.in │ │ ├── test.0029 │ │ │ ├── test.go.in │ │ │ └── out.expected │ │ ├── test.0036 │ │ │ ├── test.go.in │ │ │ └── out.expected │ │ ├── test.0051 │ │ │ ├── out.expected │ │ │ └── test.go.in │ │ ├── test.0054 │ │ │ ├── out.expected │ │ │ ├── test.go.in │ │ │ └── b.go │ │ ├── test.0019 │ │ │ ├── test.go.in │ │ │ └── out.expected │ │ ├── test.0020 │ │ │ ├── out.expected │ │ │ └── test.go.in │ │ ├── test.0021 │ │ │ ├── test.go.in │ │ │ └── out.expected │ │ ├── test.0034 │ │ │ ├── test.go.in │ │ │ └── out.expected │ │ ├── test.0035 │ │ │ ├── out.expected │ │ │ └── test.go.in │ │ ├── test.0017 │ │ │ ├── out.expected │ │ │ └── test.go.in │ │ ├── test.0023 │ │ │ ├── test.go.in │ │ │ └── out.expected │ │ ├── test.0002 │ │ │ ├── out.expected │ │ │ └── test.go.in │ │ ├── test.0012 │ │ │ ├── out.expected │ │ │ └── test.go.in │ │ ├── test.0026 │ │ │ ├── out.expected │ │ │ └── test.go.in │ │ ├── test.0010 │ │ │ ├── test.go.in │ │ │ └── out.expected │ │ ├── test.0022 │ │ │ ├── out.expected │ │ │ └── test.go.in │ │ ├── test.0005 │ │ │ ├── out.expected │ │ │ ├── b.go │ │ │ └── test.go.in │ │ ├── test.0008 │ │ │ ├── out.expected │ │ │ └── test.go.in │ │ ├── test.0033 │ │ │ ├── out.expected │ │ │ └── test.go.in │ │ ├── test.0037 │ │ │ ├── out.expected │ │ │ └── test.go.in │ │ ├── test.0004 │ │ │ ├── out.expected │ │ │ └── test.go.in │ │ ├── test.0015 │ │ │ ├── test.go.in │ │ │ └── out.expected │ │ ├── test.0003 │ │ │ ├── out.expected │ │ │ └── test.go.in │ │ ├── test.0014 │ │ │ ├── out.expected │ │ │ └── test.go.in │ │ ├── test.0013 │ │ │ ├── out.expected │ │ │ └── test.go.in │ │ └── test.0032 │ │ │ ├── test.go.in │ │ │ └── out.expected │ ├── formatters.go │ ├── suggest_test.go │ └── candidate.go └── lookdot │ ├── lookdot_test.go │ └── lookdot.go ├── nvim ├── ftplugin │ └── go │ │ └── gocomplete.vim ├── update.sh ├── symlink.sh ├── pathogen_update.sh └── autoload │ └── gocomplete.vim ├── vim ├── ftplugin │ └── go │ │ └── gocomplete.vim ├── update.sh ├── symlink.sh ├── pathogen_update.sh └── autoload │ └── gocomplete.vim ├── vendor ├── github.com │ └── keegancsmith │ │ └── rpc │ │ ├── go.mod │ │ ├── .travis.yml │ │ ├── LICENSE │ │ ├── internal │ │ └── svc │ │ │ └── svc.go │ │ ├── README.md │ │ └── debug.go ├── golang.org │ └── x │ │ └── tools │ │ ├── AUTHORS │ │ ├── CONTRIBUTORS │ │ ├── internal │ │ ├── fastwalk │ │ │ ├── fastwalk_dirent_fileno.go │ │ │ ├── fastwalk_dirent_ino.go │ │ │ ├── fastwalk_dirent_namlen_bsd.go │ │ │ ├── fastwalk_dirent_namlen_linux.go │ │ │ ├── fastwalk_portable.go │ │ │ ├── fastwalk_unix.go │ │ │ └── fastwalk.go │ │ └── span │ │ │ ├── token112.go │ │ │ ├── token111.go │ │ │ ├── parse.go │ │ │ ├── utf16.go │ │ │ ├── uri.go │ │ │ └── token.go │ │ ├── go │ │ ├── internal │ │ │ ├── gcimporter │ │ │ │ ├── newInterface11.go │ │ │ │ ├── newInterface10.go │ │ │ │ └── exportdata.go │ │ │ └── packagesdriver │ │ │ │ └── sizes.go │ │ ├── packages │ │ │ ├── visit.go │ │ │ └── external.go │ │ └── gcexportdata │ │ │ ├── importer.go │ │ │ └── gcexportdata.go │ │ ├── PATENTS │ │ └── LICENSE └── modules.txt ├── .travis.yml ├── go.mod ├── .gitignore ├── subl3 ├── syntax │ ├── GoSublime-HTML.tmLanguage.json │ ├── GoSublime-HTML.tmLanguage │ ├── LICENSE.md │ ├── GoSublime-Template.tmLanguage.json │ ├── GoSublime-Template.tmLanguage │ └── GoSublime-Go.tmLanguage.json ├── README.md └── gocode.py ├── utils.go ├── os_windows.go ├── os_posix.go ├── .github └── ISSUE_TEMPLATE ├── go.sum ├── LICENSE ├── emacs-company └── README.md ├── gocode.go ├── docs ├── IDE_integration.md └── autocomplete_formats.md ├── gocode_test.go ├── server.go └── client.go /internal/suggest/testdata/test.0063/test.go.in: -------------------------------------------------------------------------------- 1 | pa@ 2 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0006/out.expected: -------------------------------------------------------------------------------- 1 | Nothing to complete. 2 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0047/out.expected: -------------------------------------------------------------------------------- 1 | Nothing to complete. 2 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0057/out.expected: -------------------------------------------------------------------------------- 1 | Nothing to complete. 2 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0063/out.expected: -------------------------------------------------------------------------------- 1 | Nothing to complete. 2 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0064/config.json: -------------------------------------------------------------------------------- 1 | {"Builtin": true} 2 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0065/config.json: -------------------------------------------------------------------------------- 1 | {"Builtin": true} 2 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0066/config.json: -------------------------------------------------------------------------------- 1 | {"IgnoreCase": false} 2 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0067/config.json: -------------------------------------------------------------------------------- 1 | {"IgnoreCase": false} 2 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0068/config.json: -------------------------------------------------------------------------------- 1 | {"IgnoreCase": true} 2 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0069/config.json: -------------------------------------------------------------------------------- 1 | {"IgnoreCase": true} 2 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0069/out.expected: -------------------------------------------------------------------------------- 1 | Nothing to complete. 2 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0070/out.expected: -------------------------------------------------------------------------------- 1 | Nothing to complete. 2 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0071/out.expected: -------------------------------------------------------------------------------- 1 | Nothing to complete. 2 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0072/out.expected: -------------------------------------------------------------------------------- 1 | Nothing to complete. 2 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0073/out.expected: -------------------------------------------------------------------------------- 1 | Nothing to complete. 2 | -------------------------------------------------------------------------------- /nvim/ftplugin/go/gocomplete.vim: -------------------------------------------------------------------------------- 1 | setlocal omnifunc=gocomplete#Complete 2 | -------------------------------------------------------------------------------- /vim/ftplugin/go/gocomplete.vim: -------------------------------------------------------------------------------- 1 | setlocal omnifunc=gocomplete#Complete 2 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0070/config.json: -------------------------------------------------------------------------------- 1 | {"UnimportedPackages": true} 2 | -------------------------------------------------------------------------------- /vendor/github.com/keegancsmith/rpc/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/keegancsmith/rpc 2 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0049/out.expected: -------------------------------------------------------------------------------- 1 | Found 1 candidates: 2 | var i int 3 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0050/out.expected: -------------------------------------------------------------------------------- 1 | Found 1 candidates: 2 | var i int 3 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0057/test.go.in: -------------------------------------------------------------------------------- 1 | package p 2 | 3 | var _ = (*[]int).@ 4 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0059/out.expected: -------------------------------------------------------------------------------- 1 | Found 1 candidates: 2 | func B() 3 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0060/out.expected: -------------------------------------------------------------------------------- 1 | Found 1 candidates: 2 | func M2() 3 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0061/out.expected: -------------------------------------------------------------------------------- 1 | Found 1 candidates: 2 | var buf int 3 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0062/out.expected: -------------------------------------------------------------------------------- 1 | Found 1 candidates: 2 | type S struct 3 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0066/out.expected: -------------------------------------------------------------------------------- 1 | Found 1 candidates: 2 | func FuncX() 3 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0067/out.expected: -------------------------------------------------------------------------------- 1 | Found 1 candidates: 2 | func funcY() 3 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0056/out.expected: -------------------------------------------------------------------------------- 1 | Found 1 candidates: 2 | var L sync.Locker 3 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0064/out.expected: -------------------------------------------------------------------------------- 1 | Found 1 candidates: 2 | type string string 3 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0011/out.expected: -------------------------------------------------------------------------------- 1 | Found 1 candidates: 2 | func String() string 3 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0028/out.expected: -------------------------------------------------------------------------------- 1 | Found 1 candidates: 2 | func PowerOfTwo() int 3 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0064/test.go.in: -------------------------------------------------------------------------------- 1 | package p 2 | 3 | func f() { 4 | var s str@ 5 | } 6 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0070/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | func main() { 4 | fmt.@ 5 | } 6 | -------------------------------------------------------------------------------- /vendor/github.com/keegancsmith/rpc/.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | sudo: false 3 | go: 4 | - 1.x 5 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0031/out.expected: -------------------------------------------------------------------------------- 1 | Found 2 candidates: 2 | func main() 3 | var c int 4 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0038/out.expected: -------------------------------------------------------------------------------- 1 | Found 2 candidates: 2 | func main() 3 | var x int 4 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0039/out.expected: -------------------------------------------------------------------------------- 1 | Found 2 candidates: 2 | func main() 3 | var z int 4 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0042/out.expected: -------------------------------------------------------------------------------- 1 | Found 2 candidates: 2 | var Ya int 3 | var Yb int 4 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0044/out.expected: -------------------------------------------------------------------------------- 1 | Found 2 candidates: 2 | var Xa int 3 | var Xb int 4 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0053/out.expected: -------------------------------------------------------------------------------- 1 | Found 2 candidates: 2 | func SetC() 3 | func SetD() 4 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0055/out.expected: -------------------------------------------------------------------------------- 1 | Found 2 candidates: 2 | var x int 3 | var y int 4 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0058/out.expected: -------------------------------------------------------------------------------- 1 | Found 1 candidates: 2 | var str func(myint) string 3 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0009/out.expected: -------------------------------------------------------------------------------- 1 | Found 2 candidates: 2 | func Lock() 3 | func Unlock() 4 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0018/out.expected: -------------------------------------------------------------------------------- 1 | Found 2 candidates: 2 | func Bark() 3 | var Legs int 4 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0047/test.go.in: -------------------------------------------------------------------------------- 1 | package p 2 | 3 | type T struct{ X } 4 | 5 | var _ = T.x.@ 6 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0056/test.go.in: -------------------------------------------------------------------------------- 1 | package p 2 | 3 | import "sync" 4 | 5 | var _ = sync.Cond{@ 6 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0068/out.expected: -------------------------------------------------------------------------------- 1 | Found 2 candidates: 2 | func FuncX() 3 | func funcY() 4 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0069/test.go.in: -------------------------------------------------------------------------------- 1 | package p 2 | 3 | var x int 4 | 5 | func _() { 6 | 10.@ 7 | } -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0027/out.expected: -------------------------------------------------------------------------------- 1 | Found 2 candidates: 2 | func String() 3 | var name string 4 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0062/test.go.in: -------------------------------------------------------------------------------- 1 | package p 2 | 3 | type S struct{ x int } 4 | 5 | var _ = []S{ @ } 6 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0024/out.expected: -------------------------------------------------------------------------------- 1 | Found 3 candidates: 2 | var a int 3 | var b int 4 | var c int 5 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0030/out.expected: -------------------------------------------------------------------------------- 1 | Found 3 candidates: 2 | var F1 int 3 | var F2 int 4 | var F3 int 5 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0041/out.expected: -------------------------------------------------------------------------------- 1 | Found 3 candidates: 2 | var Xa int 3 | var Xb int 4 | var Xy Y 5 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0049/test.go.in: -------------------------------------------------------------------------------- 1 | package p 2 | 3 | func t(a struct { 4 | i int 5 | }) { 6 | a.@ 7 | } 8 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0050/test.go.in: -------------------------------------------------------------------------------- 1 | package p 2 | 3 | func t(a *struct { 4 | i int 5 | }) { 6 | a.@ 7 | } 8 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0052/out.expected: -------------------------------------------------------------------------------- 1 | Found 3 candidates: 2 | var a int 3 | var b int 4 | var c int 5 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0001/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | fmt.@ 7 | } 8 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0045/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | if fmt. 7 | @} 8 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0055/test.go.in: -------------------------------------------------------------------------------- 1 | package p 2 | 3 | var _ = struct { 4 | x int 5 | y int 6 | }{ 7 | @ 8 | } 9 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0071/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | // fmt.@ 6 | func main() { 7 | } 8 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0072/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | /* fmt.@ 6 | func main() { 7 | } 8 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0025/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "unsafe" 4 | 5 | func main() { 6 | unsafe.@ 7 | } 8 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0046/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | x := fmt. 7 | @} 8 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0048/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | x := fmt.F@pr 7 | } 8 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0007/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "syscall" 4 | 5 | func main() { 6 | syscall.var@ 7 | } 8 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0040/out.expected: -------------------------------------------------------------------------------- 1 | Found 3 candidates: 2 | func create_foo() Foo 3 | type Foo struct 4 | var t Foo 5 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0043/out.expected: -------------------------------------------------------------------------------- 1 | Found 4 candidates: 2 | func foo() 3 | var Xa int 4 | var Xb int 5 | var Xy Y 6 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0065/test.go.in: -------------------------------------------------------------------------------- 1 | package p 2 | 3 | import ( 4 | "fmt" 5 | banana "io" 6 | ) 7 | 8 | var _ = fmt.@ 9 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | 3 | go: 4 | - 1.11.x 5 | - 1.12.x 6 | - 1.13.x 7 | - 1.14.x 8 | - 1.15.x 9 | - master 10 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0016/out.expected: -------------------------------------------------------------------------------- 1 | Found 4 candidates: 2 | func main() 3 | var a int 4 | var b string 5 | var d bool 6 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0066/test.go.in: -------------------------------------------------------------------------------- 1 | package p 2 | 3 | func FuncX() {} 4 | func funcY() {} 5 | 6 | func f() { 7 | Fun@ 8 | } 9 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0067/test.go.in: -------------------------------------------------------------------------------- 1 | package p 2 | 3 | func FuncX() {} 4 | func funcY() {} 5 | 6 | func f() { 7 | fun@ 8 | } 9 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0068/test.go.in: -------------------------------------------------------------------------------- 1 | package p 2 | 3 | func FuncX() {} 4 | func funcY() {} 5 | 6 | func f() { 7 | fun@ 8 | } 9 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0029/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import . "fmt" 4 | 5 | func main() { 6 | var a Formatter 7 | @ 8 | } 9 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0036/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "debug/elf" 4 | 5 | func main() { 6 | var f elf.File 7 | f.@ 8 | } -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0051/out.expected: -------------------------------------------------------------------------------- 1 | Found 3 candidates: 2 | var NumApples int 3 | var NumBananas int 4 | var NumOranges int 5 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0054/out.expected: -------------------------------------------------------------------------------- 1 | Found 4 candidates: 2 | func SetA() 3 | func SetB() 4 | func SetC() 5 | func SetD() 6 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0011/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | var test fmt.Stringer 7 | test.@ 8 | } 9 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0019/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "compress/zlib" 4 | 5 | func main() { 6 | var b map[int]zlib.@ 7 | } 8 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0073/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | /* 6 | * fmt.@ 7 | */ 8 | func main() { 9 | } 10 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0020/out.expected: -------------------------------------------------------------------------------- 1 | Found 4 candidates: 2 | func Lock() 3 | func Unlock() 4 | var Dummy Dummy 5 | var Mutex sync.Mutex 6 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0021/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "go/ast" 4 | 5 | func main() { 6 | var test *ast.ImportSpec 7 | test.Name.@ 8 | } 9 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0034/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "image/png" 4 | 5 | func test() { 6 | img, err := png.Decode(nil) 7 | img.@ 8 | } 9 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0035/out.expected: -------------------------------------------------------------------------------- 1 | Found 5 candidates: 2 | func main() 3 | var err error 4 | var offset int 5 | var r rune 6 | var s string 7 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0038/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | func main() { 4 | if y := 20; y == 0 { 5 | } 6 | if x := 10; x == 0 { 7 | } else if 8 | @} 9 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0024/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | type X struct { 4 | a,b,c int 5 | } 6 | 7 | func main() { 8 | var X *X 9 | X.@ 10 | } 11 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0017/out.expected: -------------------------------------------------------------------------------- 1 | Found 3 candidates: 2 | func a(a int, b int, c int) int 3 | func b(a string, b string, c string) string 4 | func main() 5 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0023/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | // Simple check for unicode awareness 4 | 5 | import ъ "fmt" 6 | 7 | func main() { 8 | ъ.@ 9 | } 10 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/stamblerre/gocode 2 | 3 | go 1.13 4 | 5 | require ( 6 | github.com/keegancsmith/rpc v1.1.0 7 | golang.org/x/tools v0.0.0-20191030062658-86caa796c7ab 8 | ) 9 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0034/out.expected: -------------------------------------------------------------------------------- 1 | Found 3 candidates: 2 | func At(x int, y int) color.Color 3 | func Bounds() image.Rectangle 4 | func ColorModel() color.Model 5 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0039/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | func main() { 4 | z := 5 5 | if y := 20; y == 0 { 6 | } 7 | if x := 10; x == 0 { 8 | } 9 | 10 | @} 11 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0035/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | func main() { 4 | var err error 5 | s := err.Error() 6 | for offset, r := range s { 7 | @ 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0002/out.expected: -------------------------------------------------------------------------------- 1 | Found 5 candidates: 2 | func main() 3 | package os 4 | var key string 5 | var test map[string]invalid type 6 | var value invalid type 7 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0012/out.expected: -------------------------------------------------------------------------------- 1 | Found 6 candidates: 2 | func main() 3 | type MyMap map[string]int 4 | var key string 5 | var m MyMap 6 | var value int 7 | var z int 8 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0026/out.expected: -------------------------------------------------------------------------------- 1 | Found 7 candidates: 2 | func main() 3 | var A struct 4 | var B struct 5 | var C struct 6 | var a int 7 | var d int 8 | var g int 9 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0030/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | type A struct { 4 | F1, F2, F3 int 5 | } 6 | 7 | type B A 8 | 9 | func main() { 10 | var b B 11 | b.@ 12 | } 13 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0040/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | type Foo struct {} 4 | 5 | func (f *Foo) Bar() {} 6 | 7 | func create_foo() Foo { 8 | t := Foo{} 9 | 10 | @} 11 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0007/out.expected: -------------------------------------------------------------------------------- 1 | Found 5 candidates: 2 | var ForkLock sync.RWMutex 3 | var SocketDisableIPv6 bool 4 | var Stderr int 5 | var Stdin int 6 | var Stdout int 7 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0010/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "go/ast" 4 | 5 | func main() { 6 | var gd *ast.GenDecl 7 | v := gd.Specs[0].(*ast.ValueSpec) 8 | v.@ 9 | } 10 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0022/out.expected: -------------------------------------------------------------------------------- 1 | Found 5 candidates: 2 | func getMap() map[string]invalid type 3 | func main() 4 | package os 5 | var key string 6 | var value invalid type 7 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0031/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | func main() { 4 | var c chan int 5 | select { 6 | case c := <-c: 7 | _ = c 8 | @ 9 | default: 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.8 2 | *.a 3 | *.out 4 | gocode 5 | gocode.exe 6 | goremote 7 | gocodetest 8 | *.swp 9 | listidents 10 | showcursor 11 | showsmap 12 | rename 13 | internal/cache 14 | internal/gbimporter -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0005/out.expected: -------------------------------------------------------------------------------- 1 | Found 5 candidates: 2 | func A() invalid type 3 | func B() invalid type 4 | package localos 5 | type Tester struct 6 | var test invalid type 7 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0060/test.go.in: -------------------------------------------------------------------------------- 1 | package p 2 | 3 | type S1 struct { *S2 } 4 | type S2 struct { *S1 } 5 | 6 | func (*S1) M1() {} 7 | func (*S2) M2() {} 8 | 9 | var _ = (S1).@ 10 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0025/out.expected: -------------------------------------------------------------------------------- 1 | Found 4 candidates: 2 | func Alignof(x Type) uintptr 3 | func Offsetof(x Type) uintptr 4 | func Sizeof(x Type) uintptr 5 | type Pointer unsafe.Pointer 6 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0061/test.go.in: -------------------------------------------------------------------------------- 1 | package p 2 | 3 | import "bytes" 4 | 5 | type S struct { buf int } 6 | type T struct { S; bytes.Buffer } 7 | 8 | func _(t T) { 9 | _ = t.b@ 10 | } 11 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0002/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "os" 4 | 5 | var test map[string]os.Error 6 | 7 | func main() { 8 | for key, value := range test { 9 | @ 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0008/out.expected: -------------------------------------------------------------------------------- 1 | Found 6 candidates: 2 | func Lock() 3 | func Unlock() 4 | var Mutex sync.Mutex 5 | var data map[string][]string 6 | var path string 7 | var time int64 8 | -------------------------------------------------------------------------------- /vendor/golang.org/x/tools/AUTHORS: -------------------------------------------------------------------------------- 1 | # This source code refers to The Go Authors for copyright purposes. 2 | # The master list of authors is in the main Go distribution, 3 | # visible at http://tip.golang.org/AUTHORS. 4 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0012/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | type MyMap map[string]int 4 | 5 | func main() { 6 | var m MyMap 7 | for key, value := range m { 8 | z := m["15"] 9 | @ 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0033/out.expected: -------------------------------------------------------------------------------- 1 | Found 6 candidates: 2 | func testEllipsis(dummies ...*Dummy) 3 | type Dummy struct 4 | var d *Dummy 5 | var dummies []*Dummy 6 | var i int 7 | var x *Dummy 8 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0037/out.expected: -------------------------------------------------------------------------------- 1 | Found 7 candidates: 2 | func main() 3 | type Array [5]int 4 | var a Array 5 | var s []string 6 | var s1 []string 7 | var s2 []int 8 | var s3 invalid type 9 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0059/test.go.in: -------------------------------------------------------------------------------- 1 | package p 2 | 3 | type A int 4 | type B []A 5 | 6 | func (A) A() {} 7 | func (B) B() {} 8 | 9 | func test(x B) { 10 | for _, x := range x.@ { 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /vendor/golang.org/x/tools/CONTRIBUTORS: -------------------------------------------------------------------------------- 1 | # This source code was written by the Go contributors. 2 | # The master list of contributors is in the main Go distribution, 3 | # visible at http://tip.golang.org/CONTRIBUTORS. 4 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0058/test.go.in: -------------------------------------------------------------------------------- 1 | package p 2 | 3 | type myint int 4 | 5 | func (i myint) String() string { 6 | return "int" 7 | } 8 | 9 | func main() { 10 | str := myint.String 11 | st@ 12 | } 13 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0004/out.expected: -------------------------------------------------------------------------------- 1 | Found 6 candidates: 2 | func PrettyPrintTypeExpr(out io.Writer, e ast.Expr) 3 | package ast 4 | package io 5 | var e ast.Expr 6 | var out io.Writer 7 | var t ast.Expr 8 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0044/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | type X struct { 4 | Xa int 5 | Xb int 6 | } 7 | 8 | func (x X) foo() { 9 | return 10 | } 11 | 12 | func main() { 13 | x := X{ 14 | 15 | @} 16 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0052/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | type Dummy struct { 4 | a, b, c int 5 | } 6 | 7 | func testEllipsis(dummies ...*Dummy) { 8 | for _, d := range dummies { 9 | d.@ 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /vim/update.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | mkdir -p "$HOME/.vim/autoload" 3 | mkdir -p "$HOME/.vim/ftplugin/go" 4 | cp "${0%/*}/autoload/gocomplete.vim" "$HOME/.vim/autoload" 5 | cp "${0%/*}/ftplugin/go/gocomplete.vim" "$HOME/.vim/ftplugin/go" 6 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0017/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | func a(a, b, c int) int { 4 | return 123 5 | } 6 | 7 | func main() { 8 | @ 9 | } 10 | 11 | func b(a, b, c string) string { 12 | return "abc" 13 | } 14 | 15 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0027/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | type file struct { 4 | name string 5 | } 6 | 7 | func (file *file) String() { 8 | file.@ 9 | return file.name 10 | } 11 | 12 | func main() { 13 | 14 | } 15 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0015/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | func main() { 4 | var a int 5 | var b bool 6 | var c chan bool 7 | uadd := +a 8 | usub := -a 9 | unot := !b 10 | uxor := ^b 11 | arro := <-c 12 | @ 13 | } 14 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0016/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | func main() { 4 | var a int 5 | for { 6 | var b string 7 | if a == len(b) { 8 | var c bool 9 | } else { 10 | var d bool 11 | @ 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0028/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | type X int 4 | 5 | func (x X) PowerOfTwo() int { 6 | return int(x * x) 7 | } 8 | 9 | func main() { 10 | a := X(56) 11 | i := a + 67 12 | j := ^i 13 | j.@ 14 | } 15 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0033/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | type Dummy struct { 4 | a, b, c int 5 | } 6 | 7 | func testEllipsis(dummies ...*Dummy) { 8 | for i, d := range dummies { 9 | x := dummies[0] 10 | @ 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0037/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | type Array [5]int 4 | 5 | func main() { 6 | var s []string 7 | var a Array 8 | s1 := append(s[:], "123") 9 | s2 := a[0:100500] 10 | s3 := append() 11 | @ 12 | } 13 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0003/out.expected: -------------------------------------------------------------------------------- 1 | Found 7 candidates: 2 | func End() token.Pos 3 | func IsExported() bool 4 | func Pos() token.Pos 5 | func String() string 6 | var Name string 7 | var NamePos token.Pos 8 | var Obj *ast.Object 9 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0021/out.expected: -------------------------------------------------------------------------------- 1 | Found 7 candidates: 2 | func End() token.Pos 3 | func IsExported() bool 4 | func Pos() token.Pos 5 | func String() string 6 | var Name string 7 | var NamePos token.Pos 8 | var Obj *ast.Object 9 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0008/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "sync" 4 | 5 | var hosts struct { 6 | sync.Mutex 7 | data map[string][]string 8 | time int64 9 | path string 10 | } 11 | 12 | hosts.@ 13 | 14 | func main() { 15 | } 16 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0015/out.expected: -------------------------------------------------------------------------------- 1 | Found 9 candidates: 2 | func main() 3 | var a int 4 | var arro bool 5 | var b bool 6 | var c chan bool 7 | var uadd int 8 | var unot bool 9 | var usub int 10 | var uxor invalid type 11 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0009/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "sync" 4 | 5 | var hosts struct { 6 | sync.Mutex 7 | data map[string][]string 8 | time int64 9 | path string 10 | } 11 | 12 | hosts.Mutex.@ 13 | 14 | func main() { 15 | } 16 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0042/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | type X struct { 4 | Xa int 5 | Xb int 6 | Xy Y 7 | } 8 | 9 | type Y struct { 10 | Ya int 11 | Yb int 12 | } 13 | 14 | func main() { 15 | x := X{ 16 | Xy: Y{ 17 | 18 | @} 19 | -------------------------------------------------------------------------------- /nvim/update.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | mkdir -p "$HOME/.config/nvim/autoload" 3 | mkdir -p "$HOME/.config/nvim/ftplugin/go" 4 | cp "${0%/*}/autoload/gocomplete.vim" "$HOME/.config/nvim/autoload" 5 | cp "${0%/*}/ftplugin/go/gocomplete.vim" "$HOME/.config/nvim/ftplugin/go" 6 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0010/out.expected: -------------------------------------------------------------------------------- 1 | Found 7 candidates: 2 | func End() token.Pos 3 | func Pos() token.Pos 4 | var Comment *ast.CommentGroup 5 | var Doc *ast.CommentGroup 6 | var Names []*ast.Ident 7 | var Type ast.Expr 8 | var Values []ast.Expr 9 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0026/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | var A = struct { a, b, c int }{1,2,3} 4 | var B struct { d, e, f int } 5 | 6 | func main() { 7 | C := struct { g, h, i int }{1,2,3} 8 | 9 | a := A.a 10 | d := B.d 11 | g := C.g 12 | @ 13 | } 14 | -------------------------------------------------------------------------------- /vim/symlink.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | cd "${0%/*}" 3 | ROOTDIR=`pwd` 4 | mkdir -p "$HOME/.vim/autoload" 5 | mkdir -p "$HOME/.vim/ftplugin/go" 6 | ln -sf "$ROOTDIR/autoload/gocomplete.vim" "$HOME/.vim/autoload/" 7 | ln -sf "$ROOTDIR/ftplugin/go/gocomplete.vim" "$HOME/.vim/ftplugin/go/" 8 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0022/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "os" 4 | 5 | func main() { 6 | for key, value := range getMap() { 7 | @ 8 | } 9 | } 10 | 11 | func getMap() map[string]os.Error { 12 | // simply to trick type inference 13 | return nil 14 | } 15 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0041/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | type X struct { 4 | Xa int 5 | Xb int 6 | Xy Y 7 | } 8 | 9 | type Y struct { 10 | Ya int 11 | Yb int 12 | } 13 | 14 | func main() { 15 | x := X{ 16 | Xy: Y{ 17 | Ya: 1, 18 | }, 19 | 20 | @} 21 | -------------------------------------------------------------------------------- /vim/pathogen_update.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | mkdir -p "$HOME/.vim/bundle/gocode/autoload" 3 | mkdir -p "$HOME/.vim/bundle/gocode/ftplugin/go" 4 | cp "${0%/*}/autoload/gocomplete.vim" "$HOME/.vim/bundle/gocode/autoload" 5 | cp "${0%/*}/ftplugin/go/gocomplete.vim" "$HOME/.vim/bundle/gocode/ftplugin/go" 6 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0014/out.expected: -------------------------------------------------------------------------------- 1 | Found 11 candidates: 2 | func main() 3 | type MyPtrInt *int 4 | var a *int 5 | var aa int 6 | var b int 7 | var bb *MyPtrInt 8 | var c *int 9 | var d **int 10 | var megaptr **int 11 | var superint int 12 | var typeptr MyPtrInt 13 | -------------------------------------------------------------------------------- /nvim/symlink.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | cd "${0%/*}" 3 | ROOTDIR=`pwd` 4 | mkdir -p "$HOME/.config/nvim/autoload" 5 | mkdir -p "$HOME/.config/nvim/ftplugin/go" 6 | ln -s "$ROOTDIR/autoload/gocomplete.vim" "$HOME/.config/nvim/autoload/" 7 | ln -s "$ROOTDIR/ftplugin/go/gocomplete.vim" "$HOME/.config/nvim/ftplugin/go/" 8 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0014/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | type MyPtrInt *int 4 | 5 | func main() { 6 | var megaptr **int 7 | a := *megaptr 8 | b := *a 9 | 10 | var superint int 11 | c := &superint 12 | d := &c 13 | 14 | var typeptr MyPtrInt 15 | aa := *typeptr 16 | bb := &typeptr 17 | @ 18 | } 19 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0020/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "sync" 4 | 5 | type Dummy struct { 6 | sync.Mutex 7 | } 8 | 9 | type Bar struct { 10 | Dummy 11 | } 12 | 13 | func (b *Bar) Lock() { 14 | } 15 | 16 | func (b *Bar) Unlock() { 17 | } 18 | 19 | func main() { 20 | var b Bar 21 | b.@ 22 | } 23 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0043/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | type X struct { 4 | Xa int 5 | Xb int 6 | Xy Y 7 | } 8 | 9 | type Y struct { 10 | Ya int 11 | Yb int 12 | } 13 | 14 | func (x X) foo() { 15 | return 16 | } 17 | 18 | func main() { 19 | x := X{ 20 | Xa: 1, 21 | Xb: 2, 22 | } 23 | y := Y{ 24 | Ya: x. 25 | @} 26 | -------------------------------------------------------------------------------- /subl3/syntax/GoSublime-HTML.tmLanguage.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "GoSublime: HTML", 3 | "uuid": "78c486ec-0101-11e2-a85a-00262d996a67", 4 | "scopeName": "text.html.gohtml", 5 | "fileTypes": ["gohtml"], 6 | 7 | "patterns": [ 8 | { 9 | "include": "text.html.basic", 10 | }, 11 | { 12 | "include": "source.gotemplate", 13 | }, 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /nvim/pathogen_update.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | if [ -z $XDG_CONFIG_HOME ]; then 3 | XDG_CONFIG_HOME="$HOME/.config" 4 | fi 5 | mkdir -p "$XDG_CONFIG_HOME/nvim/bundle/gocode/autoload" 6 | mkdir -p "$XDG_CONFIG_HOME/nvim/bundle/gocode/ftplugin/go" 7 | cp "${0%/*}/autoload/gocomplete.vim" "$XDG_CONFIG_HOME/nvim/bundle/gocode/autoload" 8 | cp "${0%/*}/ftplugin/go/gocomplete.vim" "$XDG_CONFIG_HOME/nvim/bundle/gocode/ftplugin/go" 9 | -------------------------------------------------------------------------------- /vendor/golang.org/x/tools/internal/fastwalk/fastwalk_dirent_fileno.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build freebsd openbsd netbsd 6 | 7 | package fastwalk 8 | 9 | import "syscall" 10 | 11 | func direntInode(dirent *syscall.Dirent) uint64 { 12 | return uint64(dirent.Fileno) 13 | } 14 | -------------------------------------------------------------------------------- /utils.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "os" 5 | "unicode/utf8" 6 | ) 7 | 8 | func fileExists(filename string) bool { 9 | _, err := os.Stat(filename) 10 | return err == nil 11 | } 12 | 13 | func runeToByteOffset(s []byte, offset_c int) (offset_b int) { 14 | for offset_b = 0; offset_c > 0 && offset_b < len(s); offset_b++ { 15 | if utf8.RuneStart(s[offset_b]) { 16 | offset_c-- 17 | } 18 | } 19 | return offset_b 20 | } 21 | -------------------------------------------------------------------------------- /vendor/golang.org/x/tools/internal/fastwalk/fastwalk_dirent_ino.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build linux darwin 6 | // +build !appengine 7 | 8 | package fastwalk 9 | 10 | import "syscall" 11 | 12 | func direntInode(dirent *syscall.Dirent) uint64 { 13 | return uint64(dirent.Ino) 14 | } 15 | -------------------------------------------------------------------------------- /vendor/golang.org/x/tools/internal/fastwalk/fastwalk_dirent_namlen_bsd.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build darwin freebsd openbsd netbsd 6 | 7 | package fastwalk 8 | 9 | import "syscall" 10 | 11 | func direntNamlen(dirent *syscall.Dirent) uint64 { 12 | return uint64(dirent.Namlen) 13 | } 14 | -------------------------------------------------------------------------------- /vendor/golang.org/x/tools/go/internal/gcimporter/newInterface11.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build go1.11 6 | 7 | package gcimporter 8 | 9 | import "go/types" 10 | 11 | func newInterface(methods []*types.Func, embeddeds []types.Type) *types.Interface { 12 | return types.NewInterfaceType(methods, embeddeds) 13 | } 14 | -------------------------------------------------------------------------------- /vendor/golang.org/x/tools/internal/span/token112.go: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build go1.12 6 | 7 | package span 8 | 9 | import ( 10 | "go/token" 11 | ) 12 | 13 | // TODO(rstambler): Delete this file when we no longer support Go 1.11. 14 | func lineStart(f *token.File, line int) token.Pos { 15 | return f.LineStart(line) 16 | } 17 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0006/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | // this is a file 'a.go' 4 | 5 | import ( 6 | localos "os" 7 | ) 8 | 9 | func A() localos.Error { 10 | return nil 11 | } 12 | 13 | // B() is defined in file 'b.go' 14 | var test = B() 15 | 16 | type Tester struct { 17 | a, b, c, d int 18 | } 19 | 20 | func (t *Tester) SetA() { 21 | t.a = 31337 22 | } 23 | 24 | func (t *Tester) SetB() { 25 | t.b = 31337 26 | } 27 | 28 | Tester.@ 29 | 30 | // methods SetC and SetD are defined in 'b.go' 31 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0053/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | // this is a file 'a.go' 4 | 5 | import ( 6 | localos "os" 7 | ) 8 | 9 | func A() localos.Error { 10 | return nil 11 | } 12 | 13 | // B() is defined in file 'b.go' 14 | var test = B() 15 | 16 | type Tester struct { 17 | a, b, c, d int 18 | } 19 | 20 | func (t *Tester) SetA() { 21 | t.a = 31337 22 | } 23 | 24 | func (t *Tester) SetB() { 25 | t.b = 31337 26 | } 27 | 28 | Tester.@ 29 | 30 | // methods SetC and SetD are defined in 'b.go' 31 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0054/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | // this is a file 'a.go' 4 | 5 | import ( 6 | localos "os" 7 | ) 8 | 9 | func A() localos.Error { 10 | return nil 11 | } 12 | 13 | // B() is defined in file 'b.go' 14 | var test = B() 15 | 16 | type Tester struct { 17 | a, b, c, d int 18 | } 19 | 20 | func (t *Tester) SetA() { 21 | t.a = 31337 22 | } 23 | 24 | func (t *Tester) SetB() { 25 | t.b = 31337 26 | } 27 | 28 | (*Tester).@ 29 | 30 | // methods SetC and SetD are defined in 'b.go' 31 | -------------------------------------------------------------------------------- /vendor/modules.txt: -------------------------------------------------------------------------------- 1 | # github.com/keegancsmith/rpc v1.1.0 2 | github.com/keegancsmith/rpc 3 | github.com/keegancsmith/rpc/internal/svc 4 | # golang.org/x/tools v0.0.0-20191030062658-86caa796c7ab 5 | golang.org/x/tools/go/gcexportdata 6 | golang.org/x/tools/go/internal/gcimporter 7 | golang.org/x/tools/go/internal/packagesdriver 8 | golang.org/x/tools/go/packages 9 | golang.org/x/tools/internal/fastwalk 10 | golang.org/x/tools/internal/gopathwalk 11 | golang.org/x/tools/internal/semver 12 | golang.org/x/tools/internal/span 13 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0013/out.expected: -------------------------------------------------------------------------------- 1 | Found 24 candidates: 2 | func main() 3 | var a int 4 | var add int 5 | var and int 6 | var andnot int 7 | var b int 8 | var c bool 9 | var d bool 10 | var div int 11 | var eq bool 12 | var geq bool 13 | var greater bool 14 | var leq bool 15 | var less bool 16 | var logand bool 17 | var logor bool 18 | var mul int 19 | var neq bool 20 | var or int 21 | var rem int 22 | var shl int 23 | var shr int 24 | var sub int 25 | var xor int 26 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0048/out.expected: -------------------------------------------------------------------------------- 1 | Found 7 candidates: 2 | func Fprint(w io.Writer, a ...interface{}) (n int, err error) 3 | func Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error) 4 | func Fprintln(w io.Writer, a ...interface{}) (n int, err error) 5 | func Fscan(r io.Reader, a ...interface{}) (n int, err error) 6 | func Fscanf(r io.Reader, format string, a ...interface{}) (n int, err error) 7 | func Fscanln(r io.Reader, a ...interface{}) (n int, err error) 8 | type Formatter interface 9 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0053/b.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | // this is a file 'a.go' 4 | 5 | import ( 6 | superos "os" 7 | ) 8 | 9 | func B() superos.Error { 10 | return nil 11 | } 12 | 13 | // notice how changing type of a return function in one file, 14 | // the inferred type of a variable in another file changes also 15 | 16 | func (t Tester) SetC() { 17 | t.c = 31337 18 | } 19 | 20 | func (t Tester) SetD() { 21 | t.d = 31337 22 | } 23 | 24 | // support for multifile packages, including correct namespace handling 25 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0054/b.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | // this is a file 'a.go' 4 | 5 | import ( 6 | superos "os" 7 | ) 8 | 9 | func B() superos.Error { 10 | return nil 11 | } 12 | 13 | // notice how changing type of a return function in one file, 14 | // the inferred type of a variable in another file changes also 15 | 16 | func (t Tester) SetC() { 17 | t.c = 31337 18 | } 19 | 20 | func (t Tester) SetD() { 21 | t.d = 31337 22 | } 23 | 24 | // support for multifile packages, including correct namespace handling 25 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0005/b.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | // this is a file 'a.go' 4 | 5 | import ( 6 | superos "os" 7 | ) 8 | 9 | func B() superos.Error { 10 | return nil 11 | } 12 | 13 | // notice how changing type of a return function in one file, 14 | // the inferred type of a variable in another file changes also 15 | 16 | func (t *Tester) SetC() { 17 | t.c = 31337 18 | } 19 | 20 | func (t *Tester) SetD() { 21 | t.d = 31337 22 | } 23 | 24 | // support for multifile packages, including correct namespace handling 25 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0005/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | // this is a file 'a.go' 4 | 5 | import ( 6 | localos "os" 7 | ) 8 | 9 | func A() localos.Error { 10 | return nil 11 | } 12 | 13 | // B() is defined in file 'b.go' 14 | var test = B() 15 | 16 | type Tester struct { 17 | a, b, c, d int 18 | } 19 | 20 | func (t *Tester) SetA() { 21 | t.a = 31337 22 | } 23 | 24 | func (t *Tester) SetB() { 25 | t.b = 31337 26 | } 27 | 28 | // methods SetC and SetD are defined in 'b.go' 29 | 30 | func _() {} 31 | 32 | @ 33 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0006/b.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | // this is a file 'a.go' 4 | 5 | import ( 6 | superos "os" 7 | ) 8 | 9 | func B() superos.Error { 10 | return nil 11 | } 12 | 13 | // notice how changing type of a return function in one file, 14 | // the inferred type of a variable in another file changes also 15 | 16 | func (t *Tester) SetC() { 17 | t.c = 31337 18 | } 19 | 20 | func (t *Tester) SetD() { 21 | t.d = 31337 22 | } 23 | 24 | // support for multifile packages, including correct namespace handling 25 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0013/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | func main() { 4 | var a, b int 5 | add := a + b 6 | sub := a - b 7 | mul := a * b 8 | div := a / b 9 | or := a | b 10 | xor := a ^ b 11 | rem := a % b 12 | shr := a >> uint(b) 13 | shl := a << uint(b) 14 | and := a & b 15 | andnot := a &^ b 16 | 17 | eq := a == b 18 | neq := a != b 19 | less := a < b 20 | leq := a <= b 21 | greater := a > b 22 | geq := a >= b 23 | 24 | var c, d bool 25 | logor := c || d 26 | logand := c && d 27 | @ 28 | } 29 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0018/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | // just a dummy example 8 | type Dog struct { 9 | Legs int 10 | } 11 | 12 | func (d *Dog) Bark() { 13 | fmt.Printf("Bark!\n") 14 | } 15 | 16 | // another one 17 | type Test struct { 18 | // map of slices of pointer to a *Dog 19 | MoreTests map[string][]**Dog 20 | } 21 | 22 | func (t *Test) GetMe() *Test { 23 | return t 24 | } 25 | 26 | func main() { 27 | t := new(Test) 28 | (*t.GetMe().MoreTests["blabla"][10]).@ 29 | } 30 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0051/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | type Item struct { 4 | Quantity int 5 | Name string 6 | } 7 | 8 | type Config struct { 9 | NumApples int 10 | NumOranges int 11 | NumBananas int 12 | } 13 | 14 | func main() { 15 | var cfg Config 16 | items := []Item{ 17 | {cfg.NumApples, "apple"}, 18 | {cfg.NumOranges, "orange"}, 19 | {cfg.@NumApples, "banana"}, 20 | } 21 | 22 | var a int 23 | var b int 24 | var c int 25 | var d int 26 | var e int 27 | var f int 28 | var g int 29 | var h int 30 | var i int 31 | var j int 32 | } 33 | -------------------------------------------------------------------------------- /os_windows.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "syscall" 6 | "unsafe" 7 | ) 8 | 9 | const defaultSocketType = "tcp" 10 | 11 | var ( 12 | kernel32 = syscall.NewLazyDLL("kernel32.dll") 13 | 14 | proc_get_module_file_name = kernel32.NewProc("GetModuleFileNameW") 15 | ) 16 | 17 | // Full path of the current executable 18 | func get_executable_filename() string { 19 | b := make([]uint16, syscall.MAX_PATH) 20 | ret, _, err := syscall.Syscall(proc_get_module_file_name.Addr(), 3, 21 | 0, uintptr(unsafe.Pointer(&b[0])), uintptr(len(b))) 22 | if int(ret) == 0 { 23 | panic(fmt.Sprintf("GetModuleFileNameW : err %d", int(err))) 24 | } 25 | return syscall.UTF16ToString(b) 26 | } 27 | -------------------------------------------------------------------------------- /vendor/golang.org/x/tools/go/internal/gcimporter/newInterface10.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build !go1.11 6 | 7 | package gcimporter 8 | 9 | import "go/types" 10 | 11 | func newInterface(methods []*types.Func, embeddeds []types.Type) *types.Interface { 12 | named := make([]*types.Named, len(embeddeds)) 13 | for i, e := range embeddeds { 14 | var ok bool 15 | named[i], ok = e.(*types.Named) 16 | if !ok { 17 | panic("embedding of non-defined interfaces in interfaces is not supported before Go 1.11") 18 | } 19 | } 20 | return types.NewInterface(methods, named) 21 | } 22 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0019/out.expected: -------------------------------------------------------------------------------- 1 | Found 15 candidates: 2 | const BestCompression untyped int 3 | const BestSpeed untyped int 4 | const DefaultCompression untyped int 5 | const HuffmanOnly untyped int 6 | const NoCompression untyped int 7 | func NewReader(r io.Reader) (io.ReadCloser, error) 8 | func NewReaderDict(r io.Reader, dict []byte) (io.ReadCloser, error) 9 | func NewWriter(w io.Writer) *zlib.Writer 10 | func NewWriterLevel(w io.Writer, level int) (*zlib.Writer, error) 11 | func NewWriterLevelDict(w io.Writer, level int, dict []byte) (*zlib.Writer, error) 12 | type Resetter interface 13 | type Writer struct 14 | var ErrChecksum error 15 | var ErrDictionary error 16 | var ErrHeader error 17 | -------------------------------------------------------------------------------- /os_posix.go: -------------------------------------------------------------------------------- 1 | // +build !windows 2 | 3 | package main 4 | 5 | import ( 6 | "os" 7 | "os/exec" 8 | "path/filepath" 9 | ) 10 | 11 | const defaultSocketType = "unix" 12 | 13 | // Full path of the current executable 14 | func get_executable_filename() string { 15 | // try readlink first 16 | path, err := os.Readlink("/proc/self/exe") 17 | if err == nil { 18 | return path 19 | } 20 | // use argv[0] 21 | path = os.Args[0] 22 | if !filepath.IsAbs(path) { 23 | cwd, _ := os.Getwd() 24 | path = filepath.Join(cwd, path) 25 | } 26 | if fileExists(path) { 27 | return path 28 | } 29 | // Fallback : use "gocode" and assume we are in the PATH... 30 | path, err = exec.LookPath("gocode") 31 | if err == nil { 32 | return path 33 | } 34 | return "" 35 | } 36 | -------------------------------------------------------------------------------- /subl3/syntax/GoSublime-HTML.tmLanguage: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | fileTypes 6 | 7 | gohtml 8 | 9 | name 10 | GoSublime: HTML 11 | patterns 12 | 13 | 14 | include 15 | text.html.basic 16 | 17 | 18 | include 19 | source.gotemplate 20 | 21 | 22 | scopeName 23 | text.html.gohtml 24 | uuid 25 | 78c486ec-0101-11e2-a85a-00262d996a67 26 | 27 | 28 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE: -------------------------------------------------------------------------------- 1 | Please answer these questions before submitting your issue. Thanks! 2 | Also, remember that to restart gocode, you have to run `gocode close`. 3 | 4 | 5 | ### What version of Go are you using (`go version`)? 6 | 7 | 8 | ### What operating system and processor architecture are you using (`go env`)? 9 | 10 | 11 | ### What is the debug output of `gocode`? 12 | 13 | Run `gocode close` and then run `gocode -s -debug` to restart gocode in debug mode. 14 | Try to complete once again from your editor, and paste the output printed by gocode here. 15 | 16 | ### What (client-side) flags are you passing into `gocode`? 17 | 18 | Please note here if you are using `-source`, `-builtin`, `-ignore-case`, `-unimported-packages`, or `-fallback-to-source`. 19 | 20 | ### What editor are using? 21 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0036/out.expected: -------------------------------------------------------------------------------- 1 | Found 21 candidates: 2 | func Close() error 3 | func DWARF() (*dwarf.Data, error) 4 | func DynString(tag elf.DynTag) ([]string, error) 5 | func DynamicSymbols() ([]elf.Symbol, error) 6 | func ImportedLibraries() ([]string, error) 7 | func ImportedSymbols() ([]elf.ImportedSymbol, error) 8 | func Section(name string) *elf.Section 9 | func SectionByType(typ elf.SectionType) *elf.Section 10 | func Symbols() ([]elf.Symbol, error) 11 | var ABIVersion uint8 12 | var ByteOrder binary.ByteOrder 13 | var Class elf.Class 14 | var Data elf.Data 15 | var Entry uint64 16 | var FileHeader elf.FileHeader 17 | var Machine elf.Machine 18 | var OSABI elf.OSABI 19 | var Progs []*elf.Prog 20 | var Sections []*elf.Section 21 | var Type elf.Type 22 | var Version elf.Version 23 | -------------------------------------------------------------------------------- /vendor/golang.org/x/tools/internal/fastwalk/fastwalk_dirent_namlen_linux.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build linux 6 | // +build !appengine 7 | 8 | package fastwalk 9 | 10 | import ( 11 | "bytes" 12 | "syscall" 13 | "unsafe" 14 | ) 15 | 16 | func direntNamlen(dirent *syscall.Dirent) uint64 { 17 | const fixedHdr = uint16(unsafe.Offsetof(syscall.Dirent{}.Name)) 18 | nameBuf := (*[unsafe.Sizeof(dirent.Name)]byte)(unsafe.Pointer(&dirent.Name[0])) 19 | const nameBufLen = uint16(len(nameBuf)) 20 | limit := dirent.Reclen - fixedHdr 21 | if limit > nameBufLen { 22 | limit = nameBufLen 23 | } 24 | nameLen := bytes.IndexByte(nameBuf[:limit], 0) 25 | if nameLen < 0 { 26 | panic("failed to find terminating 0 byte in dirent") 27 | } 28 | return uint64(nameLen) 29 | } 30 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/keegancsmith/rpc v1.1.0 h1:bXVRk3EzbtrEegTGKxNTc+St1lR7t/Z1PAO8misBnCc= 2 | github.com/keegancsmith/rpc v1.1.0/go.mod h1:Xow74TKX34OPPiPCdz6x1o9c0SCxRqGxDuKGk7ZOo8s= 3 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 4 | golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 5 | golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 6 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 7 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 8 | golang.org/x/tools v0.0.0-20191030062658-86caa796c7ab h1:tpc/nJ4vD66vAk/2KN0sw/DvQIz2sKmCpWvyKtPmfMQ= 9 | golang.org/x/tools v0.0.0-20191030062658-86caa796c7ab/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 10 | golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 11 | -------------------------------------------------------------------------------- /subl3/syntax/LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012 The GoSublime Authors 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 8 | -------------------------------------------------------------------------------- /vendor/golang.org/x/tools/internal/span/token111.go: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build !go1.12 6 | 7 | package span 8 | 9 | import ( 10 | "go/token" 11 | ) 12 | 13 | // lineStart is the pre-Go 1.12 version of (*token.File).LineStart. For Go 14 | // versions <= 1.11, we borrow logic from the analysisutil package. 15 | // TODO(rstambler): Delete this file when we no longer support Go 1.11. 16 | func lineStart(f *token.File, line int) token.Pos { 17 | // Use binary search to find the start offset of this line. 18 | 19 | min := 0 // inclusive 20 | max := f.Size() // exclusive 21 | for { 22 | offset := (min + max) / 2 23 | pos := f.Pos(offset) 24 | posn := f.Position(pos) 25 | if posn.Line == line { 26 | return pos - (token.Pos(posn.Column) - 1) 27 | } 28 | 29 | if min+1 >= max { 30 | return token.NoPos 31 | } 32 | 33 | if posn.Line < line { 34 | min = offset 35 | } else { 36 | max = offset 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /vendor/golang.org/x/tools/internal/fastwalk/fastwalk_portable.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build appengine !linux,!darwin,!freebsd,!openbsd,!netbsd 6 | 7 | package fastwalk 8 | 9 | import ( 10 | "io/ioutil" 11 | "os" 12 | ) 13 | 14 | // readDir calls fn for each directory entry in dirName. 15 | // It does not descend into directories or follow symlinks. 16 | // If fn returns a non-nil error, readDir returns with that error 17 | // immediately. 18 | func readDir(dirName string, fn func(dirName, entName string, typ os.FileMode) error) error { 19 | fis, err := ioutil.ReadDir(dirName) 20 | if err != nil { 21 | return err 22 | } 23 | skipFiles := false 24 | for _, fi := range fis { 25 | if fi.Mode().IsRegular() && skipFiles { 26 | continue 27 | } 28 | if err := fn(dirName, fi.Name(), fi.Mode()&os.ModeType); err != nil { 29 | if err == SkipFiles { 30 | skipFiles = true 31 | continue 32 | } 33 | return err 34 | } 35 | } 36 | return nil 37 | } 38 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (C) 2010 nsf 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /vendor/golang.org/x/tools/PATENTS: -------------------------------------------------------------------------------- 1 | Additional IP Rights Grant (Patents) 2 | 3 | "This implementation" means the copyrightable works distributed by 4 | Google as part of the Go project. 5 | 6 | Google hereby grants to You a perpetual, worldwide, non-exclusive, 7 | no-charge, royalty-free, irrevocable (except as stated in this section) 8 | patent license to make, have made, use, offer to sell, sell, import, 9 | transfer and otherwise run, modify and propagate the contents of this 10 | implementation of Go, where such license applies only to those patent 11 | claims, both currently owned or controlled by Google and acquired in 12 | the future, licensable by Google that are necessarily infringed by this 13 | implementation of Go. This grant does not include claims that would be 14 | infringed only as a consequence of further modification of this 15 | implementation. If you or your agent or exclusive licensee institute or 16 | order or agree to the institution of patent litigation against any 17 | entity (including a cross-claim or counterclaim in a lawsuit) alleging 18 | that this implementation of Go or any code incorporated within this 19 | implementation of Go constitutes direct or contributory patent 20 | infringement, or inducement of patent infringement, then any patent 21 | rights granted to you under this License for this implementation of Go 22 | shall terminate as of the date such litigation is filed. 23 | -------------------------------------------------------------------------------- /subl3/README.md: -------------------------------------------------------------------------------- 1 | # Sublime Text 3 plugin 2 | 3 | If you want full Go experience in sublime, use [GoSublime](https://github.com/DisposaBoy/GoSublime). 4 | 5 | This plugin is written by me (nsf) as a result of frustration with GoSublime. I wanted something simpler and plugin has to use system version of the gocode. As you may know, GoSublime uses a fork of gocode, which is integrated into its own daemon called MarGo (as far as I know). 6 | 7 | The plugin does: 8 | 9 | 1. Basic gocode autocompletion. I did my best presenting the results to the user. Maybe it's possible to improve that part a bit, not quite sure yet. For functions I use "{**class**} {**name**}\t{**returns**}", for everything else "{**class**} {**name**}\t{**type**}". In addition to that functions are properly augmented with argument snippets. 10 | 11 | 2. Gofmt on save. Here I use difflib to calculate differences, which results in line by line changes. GoSublime uses [google-diff-match-patch](https://code.google.com/archive/p/google-diff-match-patch/) library, which calculates changes on finer granularity, maybe I should switch to that lib as well. 12 | 13 | I don't have any big plans on this plugin. The reason why I moved to sublime in the first place is, again, frustration, but with Atom (too slow). We'll see how it goes. 14 | 15 | Oh yes, this plugin uses GoSublime syntax files for Go. Well, they use a fork of gocode, I'll use the fork of their syntax files, fair deal. 16 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0001/out.expected: -------------------------------------------------------------------------------- 1 | Found 25 candidates: 2 | func Errorf(format string, a ...interface{}) error 3 | func Fprint(w io.Writer, a ...interface{}) (n int, err error) 4 | func Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error) 5 | func Fprintln(w io.Writer, a ...interface{}) (n int, err error) 6 | func Fscan(r io.Reader, a ...interface{}) (n int, err error) 7 | func Fscanf(r io.Reader, format string, a ...interface{}) (n int, err error) 8 | func Fscanln(r io.Reader, a ...interface{}) (n int, err error) 9 | func Print(a ...interface{}) (n int, err error) 10 | func Printf(format string, a ...interface{}) (n int, err error) 11 | func Println(a ...interface{}) (n int, err error) 12 | func Scan(a ...interface{}) (n int, err error) 13 | func Scanf(format string, a ...interface{}) (n int, err error) 14 | func Scanln(a ...interface{}) (n int, err error) 15 | func Sprint(a ...interface{}) string 16 | func Sprintf(format string, a ...interface{}) string 17 | func Sprintln(a ...interface{}) string 18 | func Sscan(str string, a ...interface{}) (n int, err error) 19 | func Sscanf(str string, format string, a ...interface{}) (n int, err error) 20 | func Sscanln(str string, a ...interface{}) (n int, err error) 21 | type Formatter interface 22 | type GoStringer interface 23 | type ScanState interface 24 | type Scanner interface 25 | type State interface 26 | type Stringer interface 27 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0023/out.expected: -------------------------------------------------------------------------------- 1 | Found 25 candidates: 2 | func Errorf(format string, a ...interface{}) error 3 | func Fprint(w io.Writer, a ...interface{}) (n int, err error) 4 | func Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error) 5 | func Fprintln(w io.Writer, a ...interface{}) (n int, err error) 6 | func Fscan(r io.Reader, a ...interface{}) (n int, err error) 7 | func Fscanf(r io.Reader, format string, a ...interface{}) (n int, err error) 8 | func Fscanln(r io.Reader, a ...interface{}) (n int, err error) 9 | func Print(a ...interface{}) (n int, err error) 10 | func Printf(format string, a ...interface{}) (n int, err error) 11 | func Println(a ...interface{}) (n int, err error) 12 | func Scan(a ...interface{}) (n int, err error) 13 | func Scanf(format string, a ...interface{}) (n int, err error) 14 | func Scanln(a ...interface{}) (n int, err error) 15 | func Sprint(a ...interface{}) string 16 | func Sprintf(format string, a ...interface{}) string 17 | func Sprintln(a ...interface{}) string 18 | func Sscan(str string, a ...interface{}) (n int, err error) 19 | func Sscanf(str string, format string, a ...interface{}) (n int, err error) 20 | func Sscanln(str string, a ...interface{}) (n int, err error) 21 | type Formatter interface 22 | type GoStringer interface 23 | type ScanState interface 24 | type Scanner interface 25 | type State interface 26 | type Stringer interface 27 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0045/out.expected: -------------------------------------------------------------------------------- 1 | Found 25 candidates: 2 | func Errorf(format string, a ...interface{}) error 3 | func Fprint(w io.Writer, a ...interface{}) (n int, err error) 4 | func Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error) 5 | func Fprintln(w io.Writer, a ...interface{}) (n int, err error) 6 | func Fscan(r io.Reader, a ...interface{}) (n int, err error) 7 | func Fscanf(r io.Reader, format string, a ...interface{}) (n int, err error) 8 | func Fscanln(r io.Reader, a ...interface{}) (n int, err error) 9 | func Print(a ...interface{}) (n int, err error) 10 | func Printf(format string, a ...interface{}) (n int, err error) 11 | func Println(a ...interface{}) (n int, err error) 12 | func Scan(a ...interface{}) (n int, err error) 13 | func Scanf(format string, a ...interface{}) (n int, err error) 14 | func Scanln(a ...interface{}) (n int, err error) 15 | func Sprint(a ...interface{}) string 16 | func Sprintf(format string, a ...interface{}) string 17 | func Sprintln(a ...interface{}) string 18 | func Sscan(str string, a ...interface{}) (n int, err error) 19 | func Sscanf(str string, format string, a ...interface{}) (n int, err error) 20 | func Sscanln(str string, a ...interface{}) (n int, err error) 21 | type Formatter interface 22 | type GoStringer interface 23 | type ScanState interface 24 | type Scanner interface 25 | type State interface 26 | type Stringer interface 27 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0046/out.expected: -------------------------------------------------------------------------------- 1 | Found 25 candidates: 2 | func Errorf(format string, a ...interface{}) error 3 | func Fprint(w io.Writer, a ...interface{}) (n int, err error) 4 | func Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error) 5 | func Fprintln(w io.Writer, a ...interface{}) (n int, err error) 6 | func Fscan(r io.Reader, a ...interface{}) (n int, err error) 7 | func Fscanf(r io.Reader, format string, a ...interface{}) (n int, err error) 8 | func Fscanln(r io.Reader, a ...interface{}) (n int, err error) 9 | func Print(a ...interface{}) (n int, err error) 10 | func Printf(format string, a ...interface{}) (n int, err error) 11 | func Println(a ...interface{}) (n int, err error) 12 | func Scan(a ...interface{}) (n int, err error) 13 | func Scanf(format string, a ...interface{}) (n int, err error) 14 | func Scanln(a ...interface{}) (n int, err error) 15 | func Sprint(a ...interface{}) string 16 | func Sprintf(format string, a ...interface{}) string 17 | func Sprintln(a ...interface{}) string 18 | func Sscan(str string, a ...interface{}) (n int, err error) 19 | func Sscanf(str string, format string, a ...interface{}) (n int, err error) 20 | func Sscanln(str string, a ...interface{}) (n int, err error) 21 | type Formatter interface 22 | type GoStringer interface 23 | type ScanState interface 24 | type Scanner interface 25 | type State interface 26 | type Stringer interface 27 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0065/out.expected: -------------------------------------------------------------------------------- 1 | Found 25 candidates: 2 | func Errorf(format string, a ...interface{}) error 3 | func Fprint(w banana.Writer, a ...interface{}) (n int, err error) 4 | func Fprintf(w banana.Writer, format string, a ...interface{}) (n int, err error) 5 | func Fprintln(w banana.Writer, a ...interface{}) (n int, err error) 6 | func Fscan(r banana.Reader, a ...interface{}) (n int, err error) 7 | func Fscanf(r banana.Reader, format string, a ...interface{}) (n int, err error) 8 | func Fscanln(r banana.Reader, a ...interface{}) (n int, err error) 9 | func Print(a ...interface{}) (n int, err error) 10 | func Printf(format string, a ...interface{}) (n int, err error) 11 | func Println(a ...interface{}) (n int, err error) 12 | func Scan(a ...interface{}) (n int, err error) 13 | func Scanf(format string, a ...interface{}) (n int, err error) 14 | func Scanln(a ...interface{}) (n int, err error) 15 | func Sprint(a ...interface{}) string 16 | func Sprintf(format string, a ...interface{}) string 17 | func Sprintln(a ...interface{}) string 18 | func Sscan(str string, a ...interface{}) (n int, err error) 19 | func Sscanf(str string, format string, a ...interface{}) (n int, err error) 20 | func Sscanln(str string, a ...interface{}) (n int, err error) 21 | type Formatter interface 22 | type GoStringer interface 23 | type ScanState interface 24 | type Scanner interface 25 | type State interface 26 | type Stringer interface 27 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0029/out.expected: -------------------------------------------------------------------------------- 1 | Found 27 candidates: 2 | func Errorf(format string, a ...interface{}) error 3 | func Fprint(w io.Writer, a ...interface{}) (n int, err error) 4 | func Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error) 5 | func Fprintln(w io.Writer, a ...interface{}) (n int, err error) 6 | func Fscan(r io.Reader, a ...interface{}) (n int, err error) 7 | func Fscanf(r io.Reader, format string, a ...interface{}) (n int, err error) 8 | func Fscanln(r io.Reader, a ...interface{}) (n int, err error) 9 | func Print(a ...interface{}) (n int, err error) 10 | func Printf(format string, a ...interface{}) (n int, err error) 11 | func Println(a ...interface{}) (n int, err error) 12 | func Scan(a ...interface{}) (n int, err error) 13 | func Scanf(format string, a ...interface{}) (n int, err error) 14 | func Scanln(a ...interface{}) (n int, err error) 15 | func Sprint(a ...interface{}) string 16 | func Sprintf(format string, a ...interface{}) string 17 | func Sprintln(a ...interface{}) string 18 | func Sscan(str string, a ...interface{}) (n int, err error) 19 | func Sscanf(str string, format string, a ...interface{}) (n int, err error) 20 | func Sscanln(str string, a ...interface{}) (n int, err error) 21 | func main() 22 | type Formatter interface 23 | type GoStringer interface 24 | type ScanState interface 25 | type Scanner interface 26 | type State interface 27 | type Stringer interface 28 | var a fmt.Formatter 29 | -------------------------------------------------------------------------------- /vendor/golang.org/x/tools/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2009 The Go Authors. All rights reserved. 2 | 3 | Redistribution and use in source and binary forms, with or without 4 | modification, are permitted provided that the following conditions are 5 | met: 6 | 7 | * Redistributions of source code must retain the above copyright 8 | notice, this list of conditions and the following disclaimer. 9 | * Redistributions in binary form must reproduce the above 10 | copyright notice, this list of conditions and the following disclaimer 11 | in the documentation and/or other materials provided with the 12 | distribution. 13 | * Neither the name of Google Inc. nor the names of its 14 | contributors may be used to endorse or promote products derived from 15 | this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /vendor/github.com/keegancsmith/rpc/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2009 The Go Authors. All rights reserved. 2 | 3 | Redistribution and use in source and binary forms, with or without 4 | modification, are permitted provided that the following conditions are 5 | met: 6 | 7 | * Redistributions of source code must retain the above copyright 8 | notice, this list of conditions and the following disclaimer. 9 | * Redistributions in binary form must reproduce the above 10 | copyright notice, this list of conditions and the following disclaimer 11 | in the documentation and/or other materials provided with the 12 | distribution. 13 | * Neither the name of Google Inc. nor the names of its 14 | contributors may be used to endorse or promote products derived from 15 | this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /vendor/golang.org/x/tools/go/packages/visit.go: -------------------------------------------------------------------------------- 1 | package packages 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "sort" 7 | ) 8 | 9 | // Visit visits all the packages in the import graph whose roots are 10 | // pkgs, calling the optional pre function the first time each package 11 | // is encountered (preorder), and the optional post function after a 12 | // package's dependencies have been visited (postorder). 13 | // The boolean result of pre(pkg) determines whether 14 | // the imports of package pkg are visited. 15 | func Visit(pkgs []*Package, pre func(*Package) bool, post func(*Package)) { 16 | seen := make(map[*Package]bool) 17 | var visit func(*Package) 18 | visit = func(pkg *Package) { 19 | if !seen[pkg] { 20 | seen[pkg] = true 21 | 22 | if pre == nil || pre(pkg) { 23 | paths := make([]string, 0, len(pkg.Imports)) 24 | for path := range pkg.Imports { 25 | paths = append(paths, path) 26 | } 27 | sort.Strings(paths) // Imports is a map, this makes visit stable 28 | for _, path := range paths { 29 | visit(pkg.Imports[path]) 30 | } 31 | } 32 | 33 | if post != nil { 34 | post(pkg) 35 | } 36 | } 37 | } 38 | for _, pkg := range pkgs { 39 | visit(pkg) 40 | } 41 | } 42 | 43 | // PrintErrors prints to os.Stderr the accumulated errors of all 44 | // packages in the import graph rooted at pkgs, dependencies first. 45 | // PrintErrors returns the number of errors printed. 46 | func PrintErrors(pkgs []*Package) int { 47 | var n int 48 | Visit(pkgs, nil, func(pkg *Package) { 49 | for _, err := range pkg.Errors { 50 | fmt.Fprintln(os.Stderr, err) 51 | n++ 52 | } 53 | }) 54 | return n 55 | } 56 | -------------------------------------------------------------------------------- /vendor/github.com/keegancsmith/rpc/internal/svc/svc.go: -------------------------------------------------------------------------------- 1 | package svc 2 | 3 | import ( 4 | "context" 5 | "sync" 6 | ) 7 | 8 | // Pending manages a map of all pending requests to a rpc.Service for a 9 | // connection (an rpc.ServerCodec). 10 | type Pending struct { 11 | mu sync.Mutex 12 | m map[uint64]context.CancelFunc // seq -> cancel 13 | } 14 | 15 | func NewPending() *Pending { 16 | return &Pending{m: make(map[uint64]context.CancelFunc)} 17 | } 18 | 19 | func (s *Pending) Start(seq uint64) context.Context { 20 | ctx, cancel := context.WithCancel(context.Background()) 21 | s.mu.Lock() 22 | // we assume seq is not already in map. If not, the client is broken. 23 | s.m[seq] = cancel 24 | s.mu.Unlock() 25 | return ctx 26 | } 27 | 28 | func (s *Pending) Cancel(seq uint64) { 29 | s.mu.Lock() 30 | cancel, ok := s.m[seq] 31 | if ok { 32 | delete(s.m, seq) 33 | } 34 | s.mu.Unlock() 35 | if ok { 36 | cancel() 37 | } 38 | } 39 | 40 | type CancelArgs struct { 41 | // Seq is the sequence number for the rpc.Call to cancel. 42 | Seq uint64 43 | 44 | // pending is the DS used by rpc.Server to track the ongoing calls for 45 | // this connection. It should not be set by the client, the Service will 46 | // set it. 47 | pending *Pending 48 | } 49 | 50 | // SetPending sets the pending map for the server to use. Do not use on the 51 | // client. 52 | func (a *CancelArgs) SetPending(p *Pending) { 53 | a.pending = p 54 | } 55 | 56 | // GoRPC is an internal service used by rpc. 57 | type GoRPC struct{} 58 | 59 | func (s *GoRPC) Cancel(ctx context.Context, args *CancelArgs, reply *bool) error { 60 | args.pending.Cancel(args.Seq) 61 | return nil 62 | } 63 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0003/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "go/ast" 5 | "io" 6 | ) 7 | 8 | func PrettyPrintTypeExpr(out io.Writer, e ast.Expr) { 9 | switch t := e.(type) { 10 | case *ast.StarExpr: 11 | fmt.Fprintf(out, "*") 12 | PrettyPrintTypeExpr(out, t.X) 13 | case *ast.Ident: 14 | // ast.Ident type decl as a reminder (note embedded type): 15 | // 16 | // type Ident struct { 17 | // token.Position // identifier position 18 | // Obj *Object // denoted object 19 | // } 20 | // 21 | // Correct type inference in complex type switch statements + 22 | // support for type embedding 23 | fmt.Fprintf(out, t.Name()) 24 | t.@ 25 | case *ast.ArrayType: 26 | fmt.Fprintf(out, "[]") 27 | PrettyPrintTypeExpr(out, t.Elt) 28 | case *ast.SelectorExpr: 29 | PrettyPrintTypeExpr(out, t.X) 30 | fmt.Fprintf(out, ".%s", t.Sel.Name()) 31 | case *ast.FuncType: 32 | // SKIP THIS FOR DEMO 33 | case *ast.MapType: 34 | fmt.Fprintf(out, "map[") 35 | PrettyPrintTypeExpr(out, t.Key) 36 | fmt.Fprintf(out, "]") 37 | PrettyPrintTypeExpr(out, t.Value) 38 | case *ast.InterfaceType: 39 | fmt.Fprintf(out, "interface{}") 40 | case *ast.Ellipsis: 41 | fmt.Fprintf(out, "...") 42 | PrettyPrintTypeExpr(out, t.Elt) 43 | case *ast.StructType: 44 | fmt.Fprintf(out, "struct") 45 | case *ast.ChanType: 46 | switch t.Dir { 47 | case ast.RECV: 48 | fmt.Fprintf(out, "<-chan ") 49 | case ast.SEND: 50 | fmt.Fprintf(out, "chan<- ") 51 | case ast.SEND | ast.RECV: 52 | fmt.Fprintf(out, "chan ") 53 | } 54 | PrettyPrintTypeExpr(out, t.Value) 55 | default: 56 | panic("OMGWTFBBQ!") 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0004/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "go/ast" 5 | "io" 6 | ) 7 | 8 | func PrettyPrintTypeExpr(out io.Writer, e ast.Expr) { 9 | switch t := e.(type) { 10 | case *ast.StarExpr: 11 | fmt.Fprintf(out, "*") 12 | PrettyPrintTypeExpr(out, t.X) 13 | case *ast.Ident: 14 | // ast.Ident type decl as a reminder (note embedded type): 15 | // 16 | // type Ident struct { 17 | // token.Position // identifier position 18 | // Obj *Object // denoted object 19 | // } 20 | // 21 | // Correct type inference in complex type switch statements + 22 | // support for type embedding 23 | fmt.Fprintf(out, t.Name()) 24 | case *ast.ArrayType: 25 | fmt.Fprintf(out, "[]") 26 | PrettyPrintTypeExpr(out, t.Elt) 27 | case *ast.SelectorExpr: 28 | PrettyPrintTypeExpr(out, t.X) 29 | fmt.Fprintf(out, ".%s", t.Sel.Name()) 30 | case *ast.FuncType: 31 | // SKIP THIS FOR DEMO 32 | case *ast.MapType: 33 | fmt.Fprintf(out, "map[") 34 | PrettyPrintTypeExpr(out, t.Key) 35 | fmt.Fprintf(out, "]") 36 | PrettyPrintTypeExpr(out, t.Value) 37 | case *ast.InterfaceType: 38 | fmt.Fprintf(out, "interface{}") 39 | case *ast.Ellipsis: 40 | fmt.Fprintf(out, "...") 41 | PrettyPrintTypeExpr(out, t.Elt) 42 | case *ast.StructType: 43 | fmt.Fprintf(out, "struct") 44 | case *ast.ChanType: 45 | switch t.Dir { 46 | case ast.RECV: 47 | fmt.Fprintf(out, "<-chan ") 48 | case ast.SEND: 49 | fmt.Fprintf(out, "chan<- ") 50 | case ast.SEND | ast.RECV: 51 | fmt.Fprintf(out, "chan ") 52 | } 53 | PrettyPrintTypeExpr(out, t.Value) 54 | default: 55 | @ 56 | panic("OMGWTFBBQ!") 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /vendor/github.com/keegancsmith/rpc/README.md: -------------------------------------------------------------------------------- 1 | # rpc [![Build Status](https://travis-ci.org/keegancsmith/rpc.svg?branch=master)](https://travis-ci.org/keegancsmith/rpc) 2 | 3 | This is a fork of the stdlib [net/rpc](https://golang.org/pkg/net/rpc/) which 4 | is frozen. It adds support for `context.Context` on the client and server, 5 | including propagating cancellation. 6 | 7 | The API is exactly the same, except `Client.Call` takes a `context.Context`, 8 | and Server methods are expected to take a `context.Context` as the first 9 | argument. Additionally the wire protocol is unchanged, so is backwards 10 | compatible with `net/rpc` clients. 11 | 12 | `DialHTTPPathTimeout` function is also added. A future release of rpc may 13 | update all Dial functions to instead take a context. 14 | 15 | ## Why use net/rpc 16 | 17 | There are many alternatives for RPC in Go, the most popular being 18 | [GRPC](https://grpc.io/). However, `net/rpc` has the following nice 19 | properties: 20 | 21 | - Nice API 22 | - No need for IDL 23 | - Good performance 24 | 25 | The nice API is subjective. However, the API is small, simple and composable. 26 | which makes it quite powerful. IDL tools are things like GRPC requiring protoc 27 | to generate go code from the protobuf files. `net/rpc` has no third party 28 | dependencies nor code generation step, simplify the use of it. A benchmark 29 | done on the [6 Sep 30 | 2016](https://github.com/golang/go/issues/16844#issuecomment-245261755) 31 | indicated `net/rpc` was 4x faster than GRPC. This is an outdated benchmark, 32 | but is an indication at the surprisingly good performance `net/rpc` provides. 33 | 34 | For more discussion on the pros and cons of `net/rpc` see the issue [proposal: 35 | freeze net/rpc](https://github.com/golang/go/issues/16844). 36 | 37 | ## Details 38 | 39 | Last forked from commit [08ab820](https://github.com/golang/go/commit/08ab820) 40 | on 25 September 2018. 41 | 42 | Cancellation implemented via the rpc call `_goRPC_.Cancel`. 43 | -------------------------------------------------------------------------------- /emacs-company/README.md: -------------------------------------------------------------------------------- 1 | # Company-go 2 | Company-go is an alternative emacs plugin for autocompletion. It uses [company-mode](http://company-mode.github.io). 3 | Completion will start automatically whenever the current symbol is preceded by a `.`, or after you type `company-minimum-prefix-length` letters. 4 | 5 | ## Setup 6 | Install `company` and `company-go`. 7 | 8 | Add the following to your emacs-config: 9 | 10 | ```lisp 11 | (require 'company) ; load company mode 12 | (require 'company-go) ; load company mode go backend 13 | ``` 14 | 15 | ## Possible improvements 16 | 17 | ```lisp 18 | (setq company-tooltip-limit 20) ; bigger popup window 19 | (setq company-idle-delay .3) ; decrease delay before autocompletion popup shows 20 | (setq company-echo-delay 0) ; remove annoying blinking 21 | (setq company-begin-commands '(self-insert-command)) ; start autocompletion only after typing 22 | ``` 23 | 24 | ### Only use company-mode with company-go in go-mode 25 | By default company-mode loads every backend it has. If you want to only have company-mode enabled in go-mode add the following to your emacs-config: 26 | 27 | ```lisp 28 | (add-hook 'go-mode-hook (lambda () 29 | (set (make-local-variable 'company-backends) '(company-go)) 30 | (company-mode))) 31 | ``` 32 | 33 | ### Color customization 34 | 35 | ```lisp 36 | (custom-set-faces 37 | '(company-preview 38 | ((t (:foreground "darkgray" :underline t)))) 39 | '(company-preview-common 40 | ((t (:inherit company-preview)))) 41 | '(company-tooltip 42 | ((t (:background "lightgray" :foreground "black")))) 43 | '(company-tooltip-selection 44 | ((t (:background "steelblue" :foreground "white")))) 45 | '(company-tooltip-common 46 | ((((type x)) (:inherit company-tooltip :weight bold)) 47 | (t (:inherit company-tooltip)))) 48 | '(company-tooltip-common-selection 49 | ((((type x)) (:inherit company-tooltip-selection :weight bold)) 50 | (t (:inherit company-tooltip-selection))))) 51 | ``` 52 | -------------------------------------------------------------------------------- /vendor/golang.org/x/tools/go/gcexportdata/importer.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package gcexportdata 6 | 7 | import ( 8 | "fmt" 9 | "go/token" 10 | "go/types" 11 | "os" 12 | ) 13 | 14 | // NewImporter returns a new instance of the types.Importer interface 15 | // that reads type information from export data files written by gc. 16 | // The Importer also satisfies types.ImporterFrom. 17 | // 18 | // Export data files are located using "go build" workspace conventions 19 | // and the build.Default context. 20 | // 21 | // Use this importer instead of go/importer.For("gc", ...) to avoid the 22 | // version-skew problems described in the documentation of this package, 23 | // or to control the FileSet or access the imports map populated during 24 | // package loading. 25 | // 26 | func NewImporter(fset *token.FileSet, imports map[string]*types.Package) types.ImporterFrom { 27 | return importer{fset, imports} 28 | } 29 | 30 | type importer struct { 31 | fset *token.FileSet 32 | imports map[string]*types.Package 33 | } 34 | 35 | func (imp importer) Import(importPath string) (*types.Package, error) { 36 | return imp.ImportFrom(importPath, "", 0) 37 | } 38 | 39 | func (imp importer) ImportFrom(importPath, srcDir string, mode types.ImportMode) (_ *types.Package, err error) { 40 | filename, path := Find(importPath, srcDir) 41 | if filename == "" { 42 | if importPath == "unsafe" { 43 | // Even for unsafe, call Find first in case 44 | // the package was vendored. 45 | return types.Unsafe, nil 46 | } 47 | return nil, fmt.Errorf("can't find import: %s", importPath) 48 | } 49 | 50 | if pkg, ok := imp.imports[path]; ok && pkg.Complete() { 51 | return pkg, nil // cache hit 52 | } 53 | 54 | // open file 55 | f, err := os.Open(filename) 56 | if err != nil { 57 | return nil, err 58 | } 59 | defer func() { 60 | f.Close() 61 | if err != nil { 62 | // add file name to error 63 | err = fmt.Errorf("reading export data: %s: %v", filename, err) 64 | } 65 | }() 66 | 67 | r, err := NewReader(f) 68 | if err != nil { 69 | return nil, err 70 | } 71 | 72 | return Read(r, imp.fset, imp.imports, path) 73 | } 74 | -------------------------------------------------------------------------------- /internal/suggest/formatters.go: -------------------------------------------------------------------------------- 1 | package suggest 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | "io" 7 | ) 8 | 9 | type Formatter func(w io.Writer, candidates []Candidate, num int) 10 | 11 | var Formatters = map[string]Formatter{ 12 | "csv": csvFormat, 13 | "csv-with-package": csvFormat, 14 | "emacs": emacsFormat, 15 | "godit": goditFormat, 16 | "json": jsonFormat, 17 | "nice": NiceFormat, 18 | "vim": vimFormat, 19 | } 20 | 21 | func NiceFormat(w io.Writer, candidates []Candidate, num int) { 22 | if candidates == nil { 23 | fmt.Fprintf(w, "Nothing to complete.\n") 24 | return 25 | } 26 | 27 | fmt.Fprintf(w, "Found %d candidates:\n", len(candidates)) 28 | for _, c := range candidates { 29 | fmt.Fprintf(w, " %s\n", c.String()) 30 | } 31 | } 32 | 33 | func vimFormat(w io.Writer, candidates []Candidate, num int) { 34 | if candidates == nil { 35 | fmt.Fprint(w, "[0, []]") 36 | return 37 | } 38 | 39 | fmt.Fprintf(w, "[%d, [", num) 40 | for i, c := range candidates { 41 | if i != 0 { 42 | fmt.Fprintf(w, ", ") 43 | } 44 | 45 | word := c.Suggestion() 46 | abbr := c.String() 47 | fmt.Fprintf(w, "{'word': '%s', 'abbr': '%s', 'info': '%s'}", word, abbr, abbr) 48 | } 49 | fmt.Fprintf(w, "]]") 50 | } 51 | 52 | func goditFormat(w io.Writer, candidates []Candidate, num int) { 53 | fmt.Fprintf(w, "%d,,%d\n", num, len(candidates)) 54 | for _, c := range candidates { 55 | fmt.Fprintf(w, "%s,,%s\n", c.String(), c.Suggestion()) 56 | } 57 | } 58 | 59 | func emacsFormat(w io.Writer, candidates []Candidate, num int) { 60 | for _, c := range candidates { 61 | var hint string 62 | switch { 63 | case c.Class == "func": 64 | hint = c.Type 65 | case c.Type == "": 66 | hint = c.Class 67 | default: 68 | hint = c.Class + " " + c.Type 69 | } 70 | fmt.Fprintf(w, "%s,,%s\n", c.Name, hint) 71 | } 72 | } 73 | 74 | func csvFormat(w io.Writer, candidates []Candidate, num int) { 75 | for _, c := range candidates { 76 | fmt.Fprintf(w, "%s,,%s,,%s,,%s\n", c.Class, c.Name, c.Type, c.PkgPath) 77 | } 78 | } 79 | 80 | func jsonFormat(w io.Writer, candidates []Candidate, num int) { 81 | var x []interface{} 82 | if candidates != nil { 83 | x = []interface{}{num, candidates} 84 | } 85 | json.NewEncoder(w).Encode(x) 86 | } 87 | -------------------------------------------------------------------------------- /gocode.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "flag" 6 | "fmt" 7 | "os" 8 | "os/signal" 9 | "path/filepath" 10 | "syscall" 11 | ) 12 | 13 | var ( 14 | g_is_server = flag.Bool("s", false, "run a server instead of a client") 15 | g_cache = flag.Bool("cache", false, "use the cache importer") 16 | g_format = flag.String("f", "nice", "output format (vim | emacs | nice | csv | json)") 17 | g_input = flag.String("in", "", "use this file instead of stdin input") 18 | g_sock = flag.String("sock", defaultSocketType, "socket type (unix | tcp | none)") 19 | g_addr = flag.String("addr", "127.0.0.1:37373", "address for tcp socket") 20 | g_debug = flag.Bool("debug", false, "enable server-side debug mode") 21 | g_source = flag.Bool("source", false, "use source importer") 22 | g_builtin = flag.Bool("builtin", false, "propose completions for built-in functions and types") 23 | g_ignore_case = flag.Bool("ignore-case", false, "do case-insensitive matching") 24 | g_unimported_packages = flag.Bool("unimported-packages", false, "propose completions for standard library packages not explicitly imported") 25 | g_fallback_to_source = flag.Bool("fallback-to-source", false, "if importing a package fails, fallback to the source importer") 26 | ) 27 | 28 | func getSocketPath() string { 29 | user := os.Getenv("USER") 30 | if user == "" { 31 | user = "all" 32 | } 33 | program := filepath.Base(os.Args[0]) 34 | return filepath.Join(os.TempDir(), fmt.Sprintf("%s-daemon.%s", program, user)) 35 | } 36 | 37 | func usage() { 38 | fmt.Fprintf(os.Stderr, 39 | "Usage: %s [-s] [-f=] [-in=] [-sock=] [-addr=]\n"+ 40 | " []\n\n", 41 | os.Args[0]) 42 | fmt.Fprintf(os.Stderr, 43 | "Flags:\n") 44 | flag.PrintDefaults() 45 | fmt.Fprintf(os.Stderr, 46 | "\nCommands:\n"+ 47 | " autocomplete [] main autocompletion command\n"+ 48 | " exit terminate the gocode daemon\n") 49 | } 50 | 51 | func main() { 52 | flag.Usage = usage 53 | flag.Parse() 54 | 55 | ctx, cancel := context.WithCancel(context.Background()) 56 | defer cancel() 57 | 58 | sigs := make(chan os.Signal) 59 | signal.Notify(sigs, os.Interrupt, syscall.SIGTERM) 60 | go func() { 61 | <-sigs 62 | cancel() 63 | }() 64 | 65 | if *g_is_server { 66 | doServer(ctx, *g_cache) 67 | } else { 68 | doClient(ctx) 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0032/test.go.in: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "archive/tar" 5 | "archive/zip" 6 | "bufio" 7 | "bytes" 8 | "compress/bzip2" 9 | "compress/flate" 10 | "compress/gzip" 11 | "compress/lzw" 12 | "compress/zlib" 13 | "container/heap" 14 | "container/list" 15 | "container/ring" 16 | "crypto" 17 | "crypto/aes" 18 | "crypto/cipher" 19 | "crypto/des" 20 | "crypto/dsa" 21 | "crypto/ecdsa" 22 | "crypto/elliptic" 23 | "crypto/hmac" 24 | "crypto/md5" 25 | "crypto/rand" 26 | "crypto/rc4" 27 | "crypto/rsa" 28 | "crypto/sha1" 29 | "crypto/sha256" 30 | "crypto/sha512" 31 | "crypto/subtle" 32 | "crypto/tls" 33 | "crypto/x509" 34 | "crypto/x509/pkix" 35 | "database/sql" 36 | "database/sql/driver" 37 | "debug/dwarf" 38 | "debug/elf" 39 | "debug/gosym" 40 | "debug/macho" 41 | "debug/pe" 42 | "encoding/ascii85" 43 | "encoding/asn1" 44 | "encoding/base32" 45 | "encoding/base64" 46 | "encoding/binary" 47 | "encoding/csv" 48 | "encoding/gob" 49 | "encoding/hex" 50 | "encoding/json" 51 | "encoding/pem" 52 | "encoding/xml" 53 | "errors" 54 | "expvar" 55 | "flag" 56 | "fmt" 57 | "go/ast" 58 | "go/build" 59 | "go/doc" 60 | "go/parser" 61 | "go/printer" 62 | "go/scanner" 63 | "go/token" 64 | "hash" 65 | "hash/adler32" 66 | "hash/crc32" 67 | "hash/crc64" 68 | "hash/fnv" 69 | "html" 70 | "html/template" 71 | "image" 72 | "image/color" 73 | "image/draw" 74 | "image/gif" 75 | "image/jpeg" 76 | "image/png" 77 | "index/suffixarray" 78 | "io" 79 | "io/ioutil" 80 | "log" 81 | "log/syslog" 82 | "math" 83 | "math/big" 84 | "math/cmplx" 85 | "math/rand" 86 | "mime" 87 | "mime/multipart" 88 | "net" 89 | "net/http" 90 | "net/http/cgi" 91 | "net/http/fcgi" 92 | "net/http/httptest" 93 | "net/http/httputil" 94 | "net/http/pprof" 95 | "net/mail" 96 | "net/rpc" 97 | "net/rpc/jsonrpc" 98 | "net/smtp" 99 | "net/textproto" 100 | "net/url" 101 | "os" 102 | "os/exec" 103 | "os/signal" 104 | "os/user" 105 | "path" 106 | "path/filepath" 107 | "reflect" 108 | "regexp" 109 | "regexp/syntax" 110 | "runtime" 111 | "runtime/cgo" 112 | "runtime/debug" 113 | "runtime/pprof" 114 | "sort" 115 | "strconv" 116 | "strings" 117 | "sync" 118 | "sync/atomic" 119 | "syscall" 120 | "testing" 121 | "testing/iotest" 122 | "testing/quick" 123 | "text/scanner" 124 | "text/tabwriter" 125 | "text/template" 126 | "text/template/parse" 127 | "time" 128 | "unicode" 129 | "unicode/utf16" 130 | "unicode/utf8" 131 | ) 132 | 133 | func main() { 134 | 135 | @} 136 | -------------------------------------------------------------------------------- /vendor/github.com/keegancsmith/rpc/debug.go: -------------------------------------------------------------------------------- 1 | // Copyright 2009 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package rpc 6 | 7 | /* 8 | Some HTML presented at http://machine:port/debug/rpc 9 | Lists services, their methods, and some statistics, still rudimentary. 10 | */ 11 | 12 | import ( 13 | "fmt" 14 | "html/template" 15 | "net/http" 16 | "sort" 17 | ) 18 | 19 | const debugText = ` 20 | 21 | Services 22 | {{range .}} 23 |
24 | Service {{.Name}} 25 |
26 | 27 | 28 | {{range .Method}} 29 | 30 | 31 | 32 | 33 | {{end}} 34 |
MethodCalls
{{.Name}}({{.Type.ArgType}}, {{.Type.ReplyType}}) error{{.Type.NumCalls}}
35 | {{end}} 36 | 37 | ` 38 | 39 | var debug = template.Must(template.New("RPC debug").Parse(debugText)) 40 | 41 | // If set, print log statements for internal and I/O errors. 42 | var debugLog = false 43 | 44 | type debugMethod struct { 45 | Type *methodType 46 | Name string 47 | } 48 | 49 | type methodArray []debugMethod 50 | 51 | type debugService struct { 52 | Service *service 53 | Name string 54 | Method methodArray 55 | } 56 | 57 | type serviceArray []debugService 58 | 59 | func (s serviceArray) Len() int { return len(s) } 60 | func (s serviceArray) Less(i, j int) bool { return s[i].Name < s[j].Name } 61 | func (s serviceArray) Swap(i, j int) { s[i], s[j] = s[j], s[i] } 62 | 63 | func (m methodArray) Len() int { return len(m) } 64 | func (m methodArray) Less(i, j int) bool { return m[i].Name < m[j].Name } 65 | func (m methodArray) Swap(i, j int) { m[i], m[j] = m[j], m[i] } 66 | 67 | type debugHTTP struct { 68 | *Server 69 | } 70 | 71 | // Runs at /debug/rpc 72 | func (server debugHTTP) ServeHTTP(w http.ResponseWriter, req *http.Request) { 73 | // Build a sorted version of the data. 74 | var services serviceArray 75 | server.serviceMap.Range(func(snamei, svci interface{}) bool { 76 | svc := svci.(*service) 77 | ds := debugService{svc, snamei.(string), make(methodArray, 0, len(svc.method))} 78 | for mname, method := range svc.method { 79 | ds.Method = append(ds.Method, debugMethod{method, mname}) 80 | } 81 | sort.Sort(ds.Method) 82 | services = append(services, ds) 83 | return true 84 | }) 85 | sort.Sort(services) 86 | err := debug.Execute(w, services) 87 | if err != nil { 88 | fmt.Fprintln(w, "rpc: error executing template:", err.Error()) 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /vim/autoload/gocomplete.vim: -------------------------------------------------------------------------------- 1 | if exists('g:loaded_gocode') 2 | finish 3 | endif 4 | let g:loaded_gocode = 1 5 | 6 | fu! s:gocodeCurrentBuffer() 7 | let buf = getline(1, '$') 8 | if &encoding != 'utf-8' 9 | let buf = map(buf, 'iconv(v:val, &encoding, "utf-8")') 10 | endif 11 | if &l:fileformat == 'dos' 12 | " XXX: line2byte() depend on 'fileformat' option. 13 | " so if fileformat is 'dos', 'buf' must include '\r'. 14 | let buf = map(buf, 'v:val."\r"') 15 | endif 16 | let file = tempname() 17 | call writefile(buf, file) 18 | return file 19 | endf 20 | 21 | let s:vim_system = get(g:, 'gocomplete#system_function', 'system') 22 | 23 | fu! s:system(str, ...) 24 | return call(s:vim_system, [a:str] + a:000) 25 | endf 26 | 27 | fu! s:gocodeShellescape(arg) 28 | try 29 | let ssl_save = &shellslash 30 | set noshellslash 31 | return shellescape(a:arg) 32 | finally 33 | let &shellslash = ssl_save 34 | endtry 35 | endf 36 | 37 | fu! s:gocodeCommand(cmd, preargs, args) 38 | for i in range(0, len(a:args) - 1) 39 | let a:args[i] = s:gocodeShellescape(a:args[i]) 40 | endfor 41 | for i in range(0, len(a:preargs) - 1) 42 | let a:preargs[i] = s:gocodeShellescape(a:preargs[i]) 43 | endfor 44 | let result = s:system(printf('gocode %s %s %s', join(a:preargs), a:cmd, join(a:args))) 45 | if v:shell_error != 0 46 | return "[\"0\", []]" 47 | else 48 | if &encoding != 'utf-8' 49 | let result = iconv(result, 'utf-8', &encoding) 50 | endif 51 | return result 52 | endif 53 | endf 54 | 55 | fu! s:gocodeCurrentBufferOpt(filename) 56 | return '-in=' . a:filename 57 | endf 58 | 59 | fu! s:gocodeCursor() 60 | if &encoding != 'utf-8' 61 | let c = col('.') 62 | let buf = line('.') == 1 ? "" : (join(getline(1, line('.')-1), "\n") . "\n") 63 | let buf .= c == 1 ? "" : getline('.')[:c-2] 64 | return printf('%d', len(iconv(buf, &encoding, "utf-8"))) 65 | endif 66 | return printf('%d', line2byte(line('.')) + (col('.')-2)) 67 | endf 68 | 69 | fu! s:gocodeAutocomplete() 70 | let filename = s:gocodeCurrentBuffer() 71 | let result = s:gocodeCommand('autocomplete', 72 | \ [s:gocodeCurrentBufferOpt(filename), '-f=vim'], 73 | \ [expand('%:p'), s:gocodeCursor()]) 74 | call delete(filename) 75 | return result 76 | endf 77 | 78 | fu! gocomplete#Complete(findstart, base) 79 | "findstart = 1 when we need to get the text length 80 | if a:findstart == 1 81 | execute "silent let g:gocomplete_completions = " . s:gocodeAutocomplete() 82 | return col('.') - g:gocomplete_completions[0] - 1 83 | "findstart = 0 when we need to return the list of completions 84 | else 85 | return g:gocomplete_completions[1] 86 | endif 87 | endf 88 | -------------------------------------------------------------------------------- /nvim/autoload/gocomplete.vim: -------------------------------------------------------------------------------- 1 | if exists('g:loaded_gocode') 2 | finish 3 | endif 4 | let g:loaded_gocode = 1 5 | 6 | fu! s:gocodeCurrentBuffer() 7 | let buf = getline(1, '$') 8 | if &encoding != 'utf-8' 9 | let buf = map(buf, 'iconv(v:val, &encoding, "utf-8")') 10 | endif 11 | if &l:fileformat == 'dos' 12 | " XXX: line2byte() depend on 'fileformat' option. 13 | " so if fileformat is 'dos', 'buf' must include '\r'. 14 | let buf = map(buf, 'v:val."\r"') 15 | endif 16 | let file = tempname() 17 | call writefile(buf, file) 18 | return file 19 | endf 20 | 21 | let s:vim_system = get(g:, 'gocomplete#system_function', 'system') 22 | 23 | fu! s:system(str, ...) 24 | return call(s:vim_system, [a:str] + a:000) 25 | endf 26 | 27 | fu! s:gocodeShellescape(arg) 28 | try 29 | let ssl_save = &shellslash 30 | set noshellslash 31 | return shellescape(a:arg) 32 | finally 33 | let &shellslash = ssl_save 34 | endtry 35 | endf 36 | 37 | fu! s:gocodeCommand(cmd, preargs, args) 38 | for i in range(0, len(a:args) - 1) 39 | let a:args[i] = s:gocodeShellescape(a:args[i]) 40 | endfor 41 | for i in range(0, len(a:preargs) - 1) 42 | let a:preargs[i] = s:gocodeShellescape(a:preargs[i]) 43 | endfor 44 | let result = s:system(printf('gocode %s %s %s', join(a:preargs), a:cmd, join(a:args))) 45 | if v:shell_error != 0 46 | return "[\"0\", []]" 47 | else 48 | if &encoding != 'utf-8' 49 | let result = iconv(result, 'utf-8', &encoding) 50 | endif 51 | return result 52 | endif 53 | endf 54 | 55 | fu! s:gocodeCurrentBufferOpt(filename) 56 | return '-in=' . a:filename 57 | endf 58 | 59 | fu! s:gocodeCursor() 60 | if &encoding != 'utf-8' 61 | let c = col('.') 62 | let buf = line('.') == 1 ? "" : (join(getline(1, line('.')-1), "\n") . "\n") 63 | let buf .= c == 1 ? "" : getline('.')[:c-2] 64 | return printf('%d', len(iconv(buf, &encoding, "utf-8"))) 65 | endif 66 | return printf('%d', line2byte(line('.')) + (col('.')-2)) 67 | endf 68 | 69 | fu! s:gocodeAutocomplete() 70 | let filename = s:gocodeCurrentBuffer() 71 | let result = s:gocodeCommand('autocomplete', 72 | \ [s:gocodeCurrentBufferOpt(filename), '-f=vim'], 73 | \ [expand('%:p'), s:gocodeCursor()]) 74 | call delete(filename) 75 | return result 76 | endf 77 | 78 | fu! gocomplete#Complete(findstart, base) 79 | "findstart = 1 when we need to get the text length 80 | if a:findstart == 1 81 | execute "silent let g:gocomplete_completions = " . s:gocodeAutocomplete() 82 | return col('.') - g:gocomplete_completions[0] - 1 83 | "findstart = 0 when we need to return the list of completions 84 | else 85 | return g:gocomplete_completions[1] 86 | endif 87 | endf 88 | -------------------------------------------------------------------------------- /internal/suggest/testdata/test.0032/out.expected: -------------------------------------------------------------------------------- 1 | Found 124 candidates: 2 | func main() 3 | package adler32 4 | package aes 5 | package ascii85 6 | package asn1 7 | package ast 8 | package atomic 9 | package base32 10 | package base64 11 | package big 12 | package binary 13 | package bufio 14 | package build 15 | package bytes 16 | package bzip2 17 | package cgi 18 | package cgo 19 | package cipher 20 | package cmplx 21 | package color 22 | package crc32 23 | package crc64 24 | package crypto 25 | package csv 26 | package debug 27 | package des 28 | package doc 29 | package draw 30 | package driver 31 | package dsa 32 | package dwarf 33 | package ecdsa 34 | package elf 35 | package elliptic 36 | package errors 37 | package exec 38 | package expvar 39 | package fcgi 40 | package filepath 41 | package flag 42 | package flate 43 | package fmt 44 | package fnv 45 | package gif 46 | package gob 47 | package gosym 48 | package gzip 49 | package hash 50 | package heap 51 | package hex 52 | package hmac 53 | package html 54 | package http 55 | package httptest 56 | package httputil 57 | package image 58 | package io 59 | package iotest 60 | package ioutil 61 | package jpeg 62 | package json 63 | package jsonrpc 64 | package list 65 | package log 66 | package lzw 67 | package macho 68 | package mail 69 | package math 70 | package md5 71 | package mime 72 | package multipart 73 | package net 74 | package os 75 | package parse 76 | package parser 77 | package path 78 | package pe 79 | package pem 80 | package pkix 81 | package png 82 | package pprof 83 | package printer 84 | package quick 85 | package rand 86 | package rc4 87 | package reflect 88 | package regexp 89 | package ring 90 | package rpc 91 | package rsa 92 | package runtime 93 | package scanner 94 | package sha1 95 | package sha256 96 | package sha512 97 | package signal 98 | package smtp 99 | package sort 100 | package sql 101 | package strconv 102 | package strings 103 | package subtle 104 | package suffixarray 105 | package sync 106 | package syntax 107 | package syscall 108 | package syslog 109 | package tabwriter 110 | package tar 111 | package template 112 | package testing 113 | package textproto 114 | package time 115 | package tls 116 | package token 117 | package unicode 118 | package url 119 | package user 120 | package utf16 121 | package utf8 122 | package x509 123 | package xml 124 | package zip 125 | package zlib 126 | -------------------------------------------------------------------------------- /vendor/golang.org/x/tools/go/internal/gcimporter/exportdata.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // This file is a copy of $GOROOT/src/go/internal/gcimporter/exportdata.go. 6 | 7 | // This file implements FindExportData. 8 | 9 | package gcimporter 10 | 11 | import ( 12 | "bufio" 13 | "fmt" 14 | "io" 15 | "strconv" 16 | "strings" 17 | ) 18 | 19 | func readGopackHeader(r *bufio.Reader) (name string, size int, err error) { 20 | // See $GOROOT/include/ar.h. 21 | hdr := make([]byte, 16+12+6+6+8+10+2) 22 | _, err = io.ReadFull(r, hdr) 23 | if err != nil { 24 | return 25 | } 26 | // leave for debugging 27 | if false { 28 | fmt.Printf("header: %s", hdr) 29 | } 30 | s := strings.TrimSpace(string(hdr[16+12+6+6+8:][:10])) 31 | size, err = strconv.Atoi(s) 32 | if err != nil || hdr[len(hdr)-2] != '`' || hdr[len(hdr)-1] != '\n' { 33 | err = fmt.Errorf("invalid archive header") 34 | return 35 | } 36 | name = strings.TrimSpace(string(hdr[:16])) 37 | return 38 | } 39 | 40 | // FindExportData positions the reader r at the beginning of the 41 | // export data section of an underlying GC-created object/archive 42 | // file by reading from it. The reader must be positioned at the 43 | // start of the file before calling this function. The hdr result 44 | // is the string before the export data, either "$$" or "$$B". 45 | // 46 | func FindExportData(r *bufio.Reader) (hdr string, err error) { 47 | // Read first line to make sure this is an object file. 48 | line, err := r.ReadSlice('\n') 49 | if err != nil { 50 | err = fmt.Errorf("can't find export data (%v)", err) 51 | return 52 | } 53 | 54 | if string(line) == "!\n" { 55 | // Archive file. Scan to __.PKGDEF. 56 | var name string 57 | if name, _, err = readGopackHeader(r); err != nil { 58 | return 59 | } 60 | 61 | // First entry should be __.PKGDEF. 62 | if name != "__.PKGDEF" { 63 | err = fmt.Errorf("go archive is missing __.PKGDEF") 64 | return 65 | } 66 | 67 | // Read first line of __.PKGDEF data, so that line 68 | // is once again the first line of the input. 69 | if line, err = r.ReadSlice('\n'); err != nil { 70 | err = fmt.Errorf("can't find export data (%v)", err) 71 | return 72 | } 73 | } 74 | 75 | // Now at __.PKGDEF in archive or still at beginning of file. 76 | // Either way, line should begin with "go object ". 77 | if !strings.HasPrefix(string(line), "go object ") { 78 | err = fmt.Errorf("not a Go object file") 79 | return 80 | } 81 | 82 | // Skip over object header to export data. 83 | // Begins after first line starting with $$. 84 | for line[0] != '$' { 85 | if line, err = r.ReadSlice('\n'); err != nil { 86 | err = fmt.Errorf("can't find export data (%v)", err) 87 | return 88 | } 89 | } 90 | hdr = string(line) 91 | 92 | return 93 | } 94 | -------------------------------------------------------------------------------- /vendor/golang.org/x/tools/internal/span/parse.go: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package span 6 | 7 | import ( 8 | "strconv" 9 | "strings" 10 | "unicode/utf8" 11 | ) 12 | 13 | // Parse returns the location represented by the input. 14 | // All inputs are valid locations, as they can always be a pure filename. 15 | // The returned span will be normalized, and thus if printed may produce a 16 | // different string. 17 | func Parse(input string) Span { 18 | // :0:0#0-0:0#0 19 | valid := input 20 | var hold, offset int 21 | hadCol := false 22 | suf := rstripSuffix(input) 23 | if suf.sep == "#" { 24 | offset = suf.num 25 | suf = rstripSuffix(suf.remains) 26 | } 27 | if suf.sep == ":" { 28 | valid = suf.remains 29 | hold = suf.num 30 | hadCol = true 31 | suf = rstripSuffix(suf.remains) 32 | } 33 | switch { 34 | case suf.sep == ":": 35 | return New(NewURI(suf.remains), NewPoint(suf.num, hold, offset), Point{}) 36 | case suf.sep == "-": 37 | // we have a span, fall out of the case to continue 38 | default: 39 | // separator not valid, rewind to either the : or the start 40 | return New(NewURI(valid), NewPoint(hold, 0, offset), Point{}) 41 | } 42 | // only the span form can get here 43 | // at this point we still don't know what the numbers we have mean 44 | // if have not yet seen a : then we might have either a line or a column depending 45 | // on whether start has a column or not 46 | // we build an end point and will fix it later if needed 47 | end := NewPoint(suf.num, hold, offset) 48 | hold, offset = 0, 0 49 | suf = rstripSuffix(suf.remains) 50 | if suf.sep == "#" { 51 | offset = suf.num 52 | suf = rstripSuffix(suf.remains) 53 | } 54 | if suf.sep != ":" { 55 | // turns out we don't have a span after all, rewind 56 | return New(NewURI(valid), end, Point{}) 57 | } 58 | valid = suf.remains 59 | hold = suf.num 60 | suf = rstripSuffix(suf.remains) 61 | if suf.sep != ":" { 62 | // line#offset only 63 | return New(NewURI(valid), NewPoint(hold, 0, offset), end) 64 | } 65 | // we have a column, so if end only had one number, it is also the column 66 | if !hadCol { 67 | end = NewPoint(suf.num, end.v.Line, end.v.Offset) 68 | } 69 | return New(NewURI(suf.remains), NewPoint(suf.num, hold, offset), end) 70 | } 71 | 72 | type suffix struct { 73 | remains string 74 | sep string 75 | num int 76 | } 77 | 78 | func rstripSuffix(input string) suffix { 79 | if len(input) == 0 { 80 | return suffix{"", "", -1} 81 | } 82 | remains := input 83 | num := -1 84 | // first see if we have a number at the end 85 | last := strings.LastIndexFunc(remains, func(r rune) bool { return r < '0' || r > '9' }) 86 | if last >= 0 && last < len(remains)-1 { 87 | number, err := strconv.ParseInt(remains[last+1:], 10, 64) 88 | if err == nil { 89 | num = int(number) 90 | remains = remains[:last+1] 91 | } 92 | } 93 | // now see if we have a trailing separator 94 | r, w := utf8.DecodeLastRuneInString(remains) 95 | if r != ':' && r != '#' && r == '#' { 96 | return suffix{input, "", -1} 97 | } 98 | remains = remains[:len(remains)-w] 99 | return suffix{remains, string(r), num} 100 | } 101 | -------------------------------------------------------------------------------- /vendor/golang.org/x/tools/internal/span/utf16.go: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package span 6 | 7 | import ( 8 | "fmt" 9 | "unicode/utf16" 10 | "unicode/utf8" 11 | ) 12 | 13 | // ToUTF16Column calculates the utf16 column expressed by the point given the 14 | // supplied file contents. 15 | // This is used to convert from the native (always in bytes) column 16 | // representation and the utf16 counts used by some editors. 17 | func ToUTF16Column(p Point, content []byte) (int, error) { 18 | if content == nil { 19 | return -1, fmt.Errorf("ToUTF16Column: missing content") 20 | } 21 | if !p.HasPosition() { 22 | return -1, fmt.Errorf("ToUTF16Column: point is missing position") 23 | } 24 | if !p.HasOffset() { 25 | return -1, fmt.Errorf("ToUTF16Column: point is missing offset") 26 | } 27 | offset := p.Offset() // 0-based 28 | colZero := p.Column() - 1 // 0-based 29 | if colZero == 0 { 30 | // 0-based column 0, so it must be chr 1 31 | return 1, nil 32 | } else if colZero < 0 { 33 | return -1, fmt.Errorf("ToUTF16Column: column is invalid (%v)", colZero) 34 | } 35 | // work out the offset at the start of the line using the column 36 | lineOffset := offset - colZero 37 | if lineOffset < 0 || offset > len(content) { 38 | return -1, fmt.Errorf("ToUTF16Column: offsets %v-%v outside file contents (%v)", lineOffset, offset, len(content)) 39 | } 40 | // Use the offset to pick out the line start. 41 | // This cannot panic: offset > len(content) and lineOffset < offset. 42 | start := content[lineOffset:] 43 | 44 | // Now, truncate down to the supplied column. 45 | start = start[:colZero] 46 | 47 | // and count the number of utf16 characters 48 | // in theory we could do this by hand more efficiently... 49 | return len(utf16.Encode([]rune(string(start)))) + 1, nil 50 | } 51 | 52 | // FromUTF16Column advances the point by the utf16 character offset given the 53 | // supplied line contents. 54 | // This is used to convert from the utf16 counts used by some editors to the 55 | // native (always in bytes) column representation. 56 | func FromUTF16Column(p Point, chr int, content []byte) (Point, error) { 57 | if !p.HasOffset() { 58 | return Point{}, fmt.Errorf("FromUTF16Column: point is missing offset") 59 | } 60 | // if chr is 1 then no adjustment needed 61 | if chr <= 1 { 62 | return p, nil 63 | } 64 | if p.Offset() >= len(content) { 65 | return p, fmt.Errorf("FromUTF16Column: offset (%v) greater than length of content (%v)", p.Offset(), len(content)) 66 | } 67 | remains := content[p.Offset():] 68 | // scan forward the specified number of characters 69 | for count := 1; count < chr; count++ { 70 | if len(remains) <= 0 { 71 | return Point{}, fmt.Errorf("FromUTF16Column: chr goes beyond the content") 72 | } 73 | r, w := utf8.DecodeRune(remains) 74 | if r == '\n' { 75 | // Per the LSP spec: 76 | // 77 | // > If the character value is greater than the line length it 78 | // > defaults back to the line length. 79 | break 80 | } 81 | remains = remains[w:] 82 | if r >= 0x10000 { 83 | // a two point rune 84 | count++ 85 | // if we finished in a two point rune, do not advance past the first 86 | if count >= chr { 87 | break 88 | } 89 | } 90 | p.v.Column += w 91 | p.v.Offset += w 92 | } 93 | return p, nil 94 | } 95 | -------------------------------------------------------------------------------- /internal/lookdot/lookdot_test.go: -------------------------------------------------------------------------------- 1 | package lookdot_test 2 | 3 | import ( 4 | "go/ast" 5 | "go/build" 6 | "go/importer" 7 | "go/parser" 8 | "go/token" 9 | "go/types" 10 | "reflect" 11 | "sort" 12 | "testing" 13 | 14 | "github.com/stamblerre/gocode/internal/lookdot" 15 | ) 16 | 17 | const src = ` 18 | package p 19 | 20 | import "time" 21 | 22 | type S struct { x int; y int } 23 | func (S) Sv() 24 | func (*S) Sp() 25 | var s S 26 | 27 | type Q struct { Z } 28 | var q Q 29 | 30 | type I interface { f(); g() } 31 | 32 | type P *S 33 | 34 | type T1 struct { *T2 } 35 | type T2 struct { *T1 } 36 | func (*T1) t1() 37 | func (*T2) t2() 38 | 39 | type X int 40 | func (*X) x() 41 | type X1 struct { X } 42 | type X2 struct { *X } 43 | type X12 struct { X1; X2 } 44 | 45 | type A1 int 46 | func (A1) A() int 47 | type A2 int 48 | func (A2) A() int 49 | type A struct { A1; A2; } 50 | 51 | type B1 int 52 | func (B1) b() 53 | type B2 struct { b int; B1 } 54 | 55 | var loc time.Location 56 | ` 57 | 58 | var tests = []struct { 59 | lhs string 60 | want []string 61 | }{ 62 | {"S", []string{"Sv"}}, 63 | {"*S", []string{"Sv", "Sp"}}, 64 | {"S{}", []string{"Sv", "x", "y"}}, 65 | {"s", []string{"Sv", "Sp", "x", "y"}}, 66 | 67 | {"I", []string{"f", "g"}}, 68 | {"I(nil)", []string{"f", "g"}}, 69 | {"(*I)(nil)", nil}, 70 | 71 | // golang.org/issue/15708 72 | {"*T1", []string{"t1", "t2"}}, 73 | {"T1", []string{"t2"}}, 74 | 75 | // golang.org/issue/9060 76 | {"error", []string{"Error"}}, 77 | {"struct { error }", []string{"Error"}}, 78 | {"interface { error }", []string{"Error"}}, 79 | 80 | // golang.org/issue/15722 81 | {"P", nil}, 82 | 83 | {"X1", nil}, 84 | {"X2", []string{"x"}}, 85 | {"X12", nil}, 86 | 87 | {"A", nil}, 88 | 89 | {"B2", nil}, 90 | 91 | {"loc", []string{"String"}}, 92 | } 93 | 94 | func TestWalk(t *testing.T) { 95 | fset := token.NewFileSet() 96 | file, err := parser.ParseFile(fset, "src.go", src, 0) 97 | if file == nil { 98 | t.Fatal(err) 99 | } 100 | 101 | cfg := types.Config{ 102 | Importer: importer.Default(), 103 | Error: func(error) {}, 104 | } 105 | pkg, err := cfg.Check("p", fset, []*ast.File{file}, nil) 106 | if pkg == nil { 107 | t.Fatal(err) 108 | } 109 | 110 | // Add a test case for Go 1.11. 111 | if contains(build.Default.ReleaseTags, "go1.11") { 112 | tests = append(tests, struct { 113 | lhs string 114 | want []string 115 | }{"q", []string{"Z"}}) 116 | } 117 | 118 | for _, test := range tests { 119 | tv, err := types.Eval(fset, pkg, token.NoPos, test.lhs) 120 | if err != nil { 121 | t.Errorf("Eval(%q) failed: %v", test.lhs, err) 122 | continue 123 | } 124 | 125 | var got []string 126 | visitor := func(obj types.Object) { 127 | // TODO(mdempsky): Should Walk be responsible 128 | // for filtering out inaccessible objects? 129 | if obj.Exported() || obj.Pkg() == pkg { 130 | got = append(got, obj.Name()) 131 | } 132 | } 133 | 134 | if !lookdot.Walk(&tv, visitor) { 135 | t.Errorf("Walk(%q) returned false", test.lhs) 136 | continue 137 | } 138 | 139 | sort.Strings(got) 140 | sort.Strings(test.want) 141 | 142 | if !reflect.DeepEqual(got, test.want) { 143 | t.Errorf("Look(%q): got %v, want %v", test.lhs, got, test.want) 144 | continue 145 | } 146 | } 147 | } 148 | 149 | func contains(haystack []string, needle string) bool { 150 | for _, item := range haystack { 151 | if item == needle { 152 | return true 153 | } 154 | } 155 | return false 156 | } 157 | -------------------------------------------------------------------------------- /vendor/golang.org/x/tools/go/packages/external.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // This file enables an external tool to intercept package requests. 6 | // If the tool is present then its results are used in preference to 7 | // the go list command. 8 | 9 | package packages 10 | 11 | import ( 12 | "bytes" 13 | "encoding/json" 14 | "fmt" 15 | "os/exec" 16 | "strings" 17 | ) 18 | 19 | // The Driver Protocol 20 | // 21 | // The driver, given the inputs to a call to Load, returns metadata about the packages specified. 22 | // This allows for different build systems to support go/packages by telling go/packages how the 23 | // packages' source is organized. 24 | // The driver is a binary, either specified by the GOPACKAGESDRIVER environment variable or in 25 | // the path as gopackagesdriver. It's given the inputs to load in its argv. See the package 26 | // documentation in doc.go for the full description of the patterns that need to be supported. 27 | // A driver receives as a JSON-serialized driverRequest struct in standard input and will 28 | // produce a JSON-serialized driverResponse (see definition in packages.go) in its standard output. 29 | 30 | // driverRequest is used to provide the portion of Load's Config that is needed by a driver. 31 | type driverRequest struct { 32 | Mode LoadMode `json:"mode"` 33 | // Env specifies the environment the underlying build system should be run in. 34 | Env []string `json:"env"` 35 | // BuildFlags are flags that should be passed to the underlying build system. 36 | BuildFlags []string `json:"build_flags"` 37 | // Tests specifies whether the patterns should also return test packages. 38 | Tests bool `json:"tests"` 39 | // Overlay maps file paths (relative to the driver's working directory) to the byte contents 40 | // of overlay files. 41 | Overlay map[string][]byte `json:"overlay"` 42 | } 43 | 44 | // findExternalDriver returns the file path of a tool that supplies 45 | // the build system package structure, or "" if not found." 46 | // If GOPACKAGESDRIVER is set in the environment findExternalTool returns its 47 | // value, otherwise it searches for a binary named gopackagesdriver on the PATH. 48 | func findExternalDriver(cfg *Config) driver { 49 | const toolPrefix = "GOPACKAGESDRIVER=" 50 | tool := "" 51 | for _, env := range cfg.Env { 52 | if val := strings.TrimPrefix(env, toolPrefix); val != env { 53 | tool = val 54 | } 55 | } 56 | if tool != "" && tool == "off" { 57 | return nil 58 | } 59 | if tool == "" { 60 | var err error 61 | tool, err = exec.LookPath("gopackagesdriver") 62 | if err != nil { 63 | return nil 64 | } 65 | } 66 | return func(cfg *Config, words ...string) (*driverResponse, error) { 67 | req, err := json.Marshal(driverRequest{ 68 | Mode: cfg.Mode, 69 | Env: cfg.Env, 70 | BuildFlags: cfg.BuildFlags, 71 | Tests: cfg.Tests, 72 | Overlay: cfg.Overlay, 73 | }) 74 | if err != nil { 75 | return nil, fmt.Errorf("failed to encode message to driver tool: %v", err) 76 | } 77 | 78 | buf := new(bytes.Buffer) 79 | cmd := exec.CommandContext(cfg.Context, tool, words...) 80 | cmd.Dir = cfg.Dir 81 | cmd.Env = cfg.Env 82 | cmd.Stdin = bytes.NewReader(req) 83 | cmd.Stdout = buf 84 | cmd.Stderr = new(bytes.Buffer) 85 | if err := cmd.Run(); err != nil { 86 | return nil, fmt.Errorf("%v: %v: %s", tool, err, cmd.Stderr) 87 | } 88 | var response driverResponse 89 | if err := json.Unmarshal(buf.Bytes(), &response); err != nil { 90 | return nil, err 91 | } 92 | return &response, nil 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /docs/IDE_integration.md: -------------------------------------------------------------------------------- 1 | 2 | # IDE Integration Guide # 3 | 4 | This guide should help programmers to develop Go lang plugins for IDEs and editors. It documents command arguments and output formats, and also mentions common pitfails. Note that gocode is not intended to be used from command-line by human. 5 | 6 | ## Code Completion Assistance ## 7 | 8 | Gocode proposes completion depending on current scope and context. Currently some obvious features are missed: 9 | * No keywords completion (no context-sensitive neither absolute) 10 | * No package names completion 11 | * No completion proposal priority 12 | * Information about context not passed to output, i.e. gocode does not report if you've typed `st.` or `fn(` 13 | 14 | Also keep in mind following things: 15 | * Editor keeps unsaved file copy in memory, so you should pass file content via stdin, or mirror it to temporary file and use `-in=*` parameter. Gocode does not support more than one unsaved file. 16 | * You should also pass full path (relative or absolute) to target file as parameter, otherwise completion will be incomplete because other files from the same package will not be resolved. 17 | * If coder started to type identifier like `Pr`, gocode will produce completions `Printf`, `Produce`, etc. In other words, completion contains identifier prefix and is already filtered. Filtering uses case-sensitive comparison if possible, and fallbacks to case-insensitive comparison. 18 | * If you want to see built-in identifiers like `uint32`, `error`, etc, you can call `gocode set propose-builtins yes` once. 19 | 20 | Use autocomplete command to produce completion assistance for particular position at file: 21 | ```bash 22 | # Read source from file and show completions for character at offset 449 from beginning 23 | gocode -f=json --in=server.go autocomplete 449 24 | # Read source from stdin (more suitable for editor since it keeps unsaved file copy in memory) 25 | gocode -f=json autocomplete 449 26 | # You can also pass target file path along with position, it's used to find other files from the same package 27 | gocode -f=json autocomplete server.go 889 28 | # By default gocode interprets offset as bytes offset, but 'c' or 'C' prefix means that offset is unicode code points offset 29 | gocode -f=json autocomplete server.go c619 30 | ``` 31 | 32 | ## Server-side Debug Mode ## 33 | 34 | There is a special server-side debug mode available in order to help developers with gocode integration. Invoke the gocode's server manually passing the following arguments: 35 | ```bash 36 | # make sure gocode server isn't running 37 | gocode close 38 | # -s for "server" 39 | # -debug for special server-side debug mode 40 | gocode -s -debug 41 | ``` 42 | 43 | After that when your editor sends autocompletion requests, the server will print some information about them to the stdout, for example: 44 | ``` 45 | Got autocompletion request for '/home/nsf/tmp/gobug/main.go' 46 | Cursor at: 52 47 | ------------------------------------------------------- 48 | package main 49 | 50 | import "bytes" 51 | 52 | func main() { 53 | bytes.F# 54 | } 55 | ------------------------------------------------------- 56 | Offset: 1 57 | Number of candidates found: 2 58 | Candidates are: 59 | func Fields(s []byte) [][]byte 60 | func FieldsFunc(s []byte, f func(rune) bool) [][]byte 61 | ======================================================= 62 | ``` 63 | 64 | Note that '#' symbol is inserted at the cursor location as gocode sees it. This debug mode is useful when you need to make sure your editor sends the right position in all cases. Keep in mind that Go source files are UTF-8 files, try inserting non-english comments before the completion location to check if everything works properly. 65 | 66 | [Output formats reference.](autocomplete_formats.md) 67 | -------------------------------------------------------------------------------- /subl3/syntax/GoSublime-Template.tmLanguage.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "GoSublime: Template", 3 | "uuid": "43606de8-c638-11e2-b661-6711676f99ca", 4 | "scopeName": "source.gotemplate", 5 | 6 | "foldingStartMarker": "\\{\\{\\s*(?:if|with|range)\\b", 7 | "foldingStopMarker": "\\{\\{\\s*(?:else|end)\\b", 8 | 9 | "patterns": [ 10 | { 11 | "begin": "\\{\\{", 12 | "beginCaptures": { 13 | "0": { 14 | "name": "punctuation.section.embedded.begin.gotemplate" 15 | } 16 | }, 17 | 18 | "end": "\\}\\}", 19 | "endCaptures": { 20 | "0": { 21 | "name": "punctuation.section.embedded.end.gotemplate" 22 | } 23 | }, 24 | 25 | "patterns": [ 26 | { 27 | "match": ":=", 28 | "name": "keyword.operator.initialize.gotemplate" 29 | }, 30 | { 31 | "match": "\\|", 32 | "name": "keyword.operator.pipe.gotemplate" 33 | }, 34 | { 35 | "match": "[.$][\\w]*", 36 | "name": "variable.other.gotemplate" 37 | }, 38 | { 39 | "match": "\\b(if|else|range|template|with|end|nil|with|define)\\b", 40 | "name": "keyword.control.gotemplate" 41 | }, 42 | { 43 | "match": "\\b(and|call|html|index|js|len|not|or|print|printf|println|urlquery|eq|ne|lt|le|gt|ge)\\b", 44 | "name": "support.function.builtin.gotemplate" 45 | }, 46 | { 47 | "begin": "/\\*", 48 | "end": "\\*/", 49 | "name": "comment.block.gotemplate" 50 | }, 51 | { 52 | "begin": "\"", 53 | "beginCaptures": { 54 | "0": { 55 | "name": "punctuation.definition.string.begin.gotemplate" 56 | } 57 | }, 58 | "end": "\"", 59 | "endCaptures": { 60 | "0": { 61 | "name": "punctuation.definition.string.end.gotemplate" 62 | } 63 | }, 64 | "name": "string.quoted.double.gotemplate", 65 | "patterns": [ 66 | { 67 | "include": "#string_placeholder" 68 | }, 69 | { 70 | "include": "#string_escaped_char" 71 | } 72 | ] 73 | }, 74 | { 75 | "begin": "`", 76 | "beginCaptures": { 77 | "0": { 78 | "name": "punctuation.definition.string.begin.gotemplate" 79 | } 80 | }, 81 | "end": "`", 82 | "endCaptures": { 83 | "0": { 84 | "name": "punctuation.definition.string.end.gotemplate" 85 | } 86 | }, 87 | "name": "string.quoted.raw.gotemplate", 88 | "patterns": [ 89 | { 90 | "include": "#string_placeholder" 91 | } 92 | ] 93 | } 94 | ], 95 | } 96 | ], 97 | "repository": { 98 | "string_escaped_char": { 99 | "patterns": [ 100 | { 101 | // note: keep this in sync with constant.other.rune.go 102 | "match": "\\\\(\\\\|[abfnrtv'\"]|x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|U[0-9a-fA-F]{8}|[0-7]{3})", 103 | "name": "constant.character.escape.gotemplate" 104 | }, 105 | { 106 | "match": "\\\\.", 107 | "name": "invalid.illegal.unknown-escape.gotemplate" 108 | } 109 | ] 110 | }, 111 | "string_placeholder": { 112 | "patterns": [ 113 | { 114 | "match": "(?x)%\n (\\d+\\$)? # field (argument #)\n [#0\\- +']* # flags\n [,;:_]? # separator character (AltiVec)\n ((-?\\d+)|\\*(-?\\d+\\$)?)? # minimum field width\n (\\.((-?\\d+)|\\*(-?\\d+\\$)?)?)? # precision\n [diouxXDOUeEfFgGaAcCsSqpnvtTbyYhHmMzZ%] # conversion type\n ", 115 | "name": "constant.other.placeholder.gotemplate" 116 | }, 117 | { 118 | "match": "%", 119 | "name": "invalid.illegal.placeholder.gotemplate" 120 | } 121 | ] 122 | } 123 | }, 124 | } 125 | -------------------------------------------------------------------------------- /gocode_test.go: -------------------------------------------------------------------------------- 1 | package main_test 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "io/ioutil" 7 | "os" 8 | "os/exec" 9 | "path" 10 | "path/filepath" 11 | "strconv" 12 | "strings" 13 | "sync" 14 | "testing" 15 | "time" 16 | ) 17 | 18 | func compile(t testing.TB, pkg string) (executable string, cleanup func()) { 19 | t.Helper() 20 | 21 | dir, err := ioutil.TempDir("", "gocode") 22 | if err != nil { 23 | t.Fatal(err) 24 | } 25 | 26 | cleanup = func() { 27 | if err := os.RemoveAll(dir); err != nil { 28 | t.Error(err) 29 | } 30 | } 31 | 32 | executable = filepath.Join(dir, path.Base(pkg)+".exe") 33 | out, err := exec.Command("go", "build", "-o", executable, pkg).CombinedOutput() 34 | if err != nil { 35 | cleanup() 36 | t.Error(string(out)) 37 | t.Fatal(err) 38 | } 39 | 40 | return executable, cleanup 41 | } 42 | 43 | // TestCancellation_Panic checks that neither client nor server panic on cancellation. 44 | func TestCancellation_Panic(t *testing.T) { 45 | const testServerAddress = "127.0.0.1:38383" 46 | 47 | var buffer buffer 48 | defer func() { 49 | if t.Failed() { 50 | t.Log("\n" + string(buffer.text)) 51 | } 52 | }() 53 | 54 | gocode, cleanup := compile(t, "github.com/stamblerre/gocode") 55 | defer cleanup() 56 | 57 | serverCtx, serverCancel := context.WithCancel(context.Background()) 58 | 59 | // start the server 60 | cmd := exec.CommandContext(serverCtx, gocode, "-s", // "-debug", 61 | "-sock", "tcp", 62 | "-addr", testServerAddress, 63 | ) 64 | cmd.Stderr, cmd.Stdout = buffer.prefixed("server | "), buffer.prefixed("server | ") 65 | 66 | // stop server after five seconds 67 | go func() { 68 | time.Sleep(5 * time.Second) 69 | serverCancel() 70 | }() 71 | 72 | // start server 73 | if err := cmd.Start(); err != nil { 74 | t.Fatal(err) 75 | } 76 | 77 | runClients(t, gocode, testServerAddress) 78 | 79 | time.Sleep(time.Second) 80 | 81 | // cancel server when any of the clients fails 82 | serverCancel() 83 | 84 | _ = cmd.Wait() 85 | 86 | if strings.Contains(strings.ToLower(string(buffer.text)), "panic") { 87 | t.Fail() 88 | } 89 | } 90 | 91 | func runClients(t *testing.T, gocode, serverAddr string) { 92 | const N = 10 93 | const testFile = "gocode_test.go" 94 | 95 | var buffer buffer 96 | defer func() { 97 | if t.Failed() { 98 | t.Log("\n" + string(buffer.text)) 99 | } 100 | }() 101 | 102 | clientCtx, cancelClient := context.WithCancel(context.Background()) 103 | 104 | var wg sync.WaitGroup 105 | wg.Add(N) 106 | 107 | // start bunch of clients 108 | for i := 0; i < N; i++ { 109 | offset := i * 5 110 | stdout := buffer.prefixed(fmt.Sprintf("client %d |", i)) 111 | go func() { 112 | defer wg.Done() 113 | 114 | cmd := exec.CommandContext(clientCtx, gocode, 115 | "-sock", "tcp", 116 | "-addr", serverAddr, 117 | "-in", testFile, 118 | "autocomplete", testFile, strconv.Itoa(offset)) 119 | 120 | cmd.Stderr, cmd.Stdout = stdout, stdout 121 | _ = cmd.Run() 122 | }() 123 | } 124 | 125 | time.Sleep(300 * time.Millisecond) 126 | cancelClient() 127 | 128 | wg.Wait() 129 | 130 | if strings.Contains(string(buffer.text), "panic") || strings.Contains(string(buffer.text), "PANIC") { 131 | t.Fail() 132 | } 133 | } 134 | 135 | type buffer struct { 136 | mu sync.Mutex 137 | text []byte 138 | } 139 | 140 | func (b *buffer) Write(prefix string, data []byte) (int, error) { 141 | b.mu.Lock() 142 | b.text = append(b.text, []byte(prefix)...) 143 | b.text = append(b.text, data...) 144 | if len(data) > 0 && data[len(data)-1] != '\n' { 145 | b.text = append(b.text, '\n') 146 | } 147 | b.mu.Unlock() 148 | return len(data), nil 149 | } 150 | 151 | func (buffer *buffer) prefixed(prefix string) *writer { 152 | return &writer{ 153 | prefix: prefix, 154 | buffer: buffer, 155 | } 156 | } 157 | 158 | type writer struct { 159 | prefix string 160 | buffer *buffer 161 | } 162 | 163 | func (w *writer) Write(data []byte) (int, error) { 164 | return w.buffer.Write(w.prefix, data) 165 | } 166 | -------------------------------------------------------------------------------- /vendor/golang.org/x/tools/internal/fastwalk/fastwalk_unix.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build linux darwin freebsd openbsd netbsd 6 | // +build !appengine 7 | 8 | package fastwalk 9 | 10 | import ( 11 | "fmt" 12 | "os" 13 | "syscall" 14 | "unsafe" 15 | ) 16 | 17 | const blockSize = 8 << 10 18 | 19 | // unknownFileMode is a sentinel (and bogus) os.FileMode 20 | // value used to represent a syscall.DT_UNKNOWN Dirent.Type. 21 | const unknownFileMode os.FileMode = os.ModeNamedPipe | os.ModeSocket | os.ModeDevice 22 | 23 | func readDir(dirName string, fn func(dirName, entName string, typ os.FileMode) error) error { 24 | fd, err := syscall.Open(dirName, 0, 0) 25 | if err != nil { 26 | return &os.PathError{Op: "open", Path: dirName, Err: err} 27 | } 28 | defer syscall.Close(fd) 29 | 30 | // The buffer must be at least a block long. 31 | buf := make([]byte, blockSize) // stack-allocated; doesn't escape 32 | bufp := 0 // starting read position in buf 33 | nbuf := 0 // end valid data in buf 34 | skipFiles := false 35 | for { 36 | if bufp >= nbuf { 37 | bufp = 0 38 | nbuf, err = syscall.ReadDirent(fd, buf) 39 | if err != nil { 40 | return os.NewSyscallError("readdirent", err) 41 | } 42 | if nbuf <= 0 { 43 | return nil 44 | } 45 | } 46 | consumed, name, typ := parseDirEnt(buf[bufp:nbuf]) 47 | bufp += consumed 48 | if name == "" || name == "." || name == ".." { 49 | continue 50 | } 51 | // Fallback for filesystems (like old XFS) that don't 52 | // support Dirent.Type and have DT_UNKNOWN (0) there 53 | // instead. 54 | if typ == unknownFileMode { 55 | fi, err := os.Lstat(dirName + "/" + name) 56 | if err != nil { 57 | // It got deleted in the meantime. 58 | if os.IsNotExist(err) { 59 | continue 60 | } 61 | return err 62 | } 63 | typ = fi.Mode() & os.ModeType 64 | } 65 | if skipFiles && typ.IsRegular() { 66 | continue 67 | } 68 | if err := fn(dirName, name, typ); err != nil { 69 | if err == SkipFiles { 70 | skipFiles = true 71 | continue 72 | } 73 | return err 74 | } 75 | } 76 | } 77 | 78 | func parseDirEnt(buf []byte) (consumed int, name string, typ os.FileMode) { 79 | // golang.org/issue/15653 80 | dirent := (*syscall.Dirent)(unsafe.Pointer(&buf[0])) 81 | if v := unsafe.Offsetof(dirent.Reclen) + unsafe.Sizeof(dirent.Reclen); uintptr(len(buf)) < v { 82 | panic(fmt.Sprintf("buf size of %d smaller than dirent header size %d", len(buf), v)) 83 | } 84 | if len(buf) < int(dirent.Reclen) { 85 | panic(fmt.Sprintf("buf size %d < record length %d", len(buf), dirent.Reclen)) 86 | } 87 | consumed = int(dirent.Reclen) 88 | if direntInode(dirent) == 0 { // File absent in directory. 89 | return 90 | } 91 | switch dirent.Type { 92 | case syscall.DT_REG: 93 | typ = 0 94 | case syscall.DT_DIR: 95 | typ = os.ModeDir 96 | case syscall.DT_LNK: 97 | typ = os.ModeSymlink 98 | case syscall.DT_BLK: 99 | typ = os.ModeDevice 100 | case syscall.DT_FIFO: 101 | typ = os.ModeNamedPipe 102 | case syscall.DT_SOCK: 103 | typ = os.ModeSocket 104 | case syscall.DT_UNKNOWN: 105 | typ = unknownFileMode 106 | default: 107 | // Skip weird things. 108 | // It's probably a DT_WHT (http://lwn.net/Articles/325369/) 109 | // or something. Revisit if/when this package is moved outside 110 | // of goimports. goimports only cares about regular files, 111 | // symlinks, and directories. 112 | return 113 | } 114 | 115 | nameBuf := (*[unsafe.Sizeof(dirent.Name)]byte)(unsafe.Pointer(&dirent.Name[0])) 116 | nameLen := direntNamlen(dirent) 117 | 118 | // Special cases for common things: 119 | if nameLen == 1 && nameBuf[0] == '.' { 120 | name = "." 121 | } else if nameLen == 2 && nameBuf[0] == '.' && nameBuf[1] == '.' { 122 | name = ".." 123 | } else { 124 | name = string(nameBuf[:nameLen]) 125 | } 126 | return 127 | } 128 | -------------------------------------------------------------------------------- /server.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bytes" 5 | "context" 6 | "fmt" 7 | "log" 8 | "net" 9 | "os" 10 | "runtime/debug" 11 | "strings" 12 | "time" 13 | 14 | "github.com/keegancsmith/rpc" 15 | "github.com/stamblerre/gocode/internal/suggest" 16 | ) 17 | 18 | func doServer(ctx context.Context, _ bool) { 19 | for _, v := range strings.Fields(suggest.GoosList) { 20 | suggest.KnownOS[v] = true 21 | } 22 | for _, v := range strings.Fields(suggest.GoarchList) { 23 | suggest.KnownArch[v] = true 24 | } 25 | 26 | addr := *g_addr 27 | if *g_sock == "unix" { 28 | addr = getSocketPath() 29 | } 30 | 31 | lis, err := net.Listen(*g_sock, addr) 32 | if err != nil { 33 | log.Fatal(err) 34 | } 35 | 36 | go func() { 37 | <-ctx.Done() 38 | exitServer() 39 | }() 40 | 41 | if err = rpc.Register(&Server{ctx, false}); err != nil { 42 | log.Fatal(err) 43 | } 44 | rpc.Accept(lis) 45 | } 46 | 47 | func exitServer() { 48 | if *g_sock == "unix" { 49 | _ = os.Remove(getSocketPath()) 50 | } 51 | os.Exit(0) 52 | } 53 | 54 | type Server struct { 55 | context context.Context 56 | cache bool 57 | } 58 | 59 | type AutoCompleteRequest struct { 60 | Filename string 61 | Data []byte 62 | Cursor int 63 | Context *suggest.PackedContext 64 | Source bool 65 | Builtin bool 66 | IgnoreCase bool 67 | UnimportedPackages bool 68 | FallbackToSource bool 69 | } 70 | 71 | type AutoCompleteReply struct { 72 | Candidates []suggest.Candidate 73 | Len int 74 | } 75 | 76 | func (s *Server) AutoComplete(ctx context.Context, req *AutoCompleteRequest, res *AutoCompleteReply) error { 77 | defer func() { 78 | if err := recover(); err != nil { 79 | fmt.Printf("panic: %s\n\n", err) 80 | debug.PrintStack() 81 | 82 | res.Candidates = []suggest.Candidate{ 83 | {Class: "PANIC", Name: "PANIC", Type: "PANIC"}, 84 | } 85 | } 86 | }() 87 | 88 | // cancel any pending request when server is shuting down 89 | ctx, cancel := context.WithCancel(ctx) 90 | defer cancel() 91 | go func() { 92 | select { 93 | case <-ctx.Done(): 94 | cancel() 95 | case <-s.context.Done(): 96 | cancel() 97 | } 98 | }() 99 | 100 | if *g_debug { 101 | var buf bytes.Buffer 102 | log.Printf("Got autocompletion request for '%s'\n", req.Filename) 103 | log.Printf("Cursor at: %d\n", req.Cursor) 104 | if req.Cursor <= len(req.Data) { 105 | buf.WriteString("-------------------------------------------------------\n") 106 | buf.Write(req.Data[:req.Cursor]) 107 | buf.WriteString("#") 108 | buf.Write(req.Data[req.Cursor:]) 109 | log.Print(buf.String()) 110 | log.Println("-------------------------------------------------------") 111 | } 112 | } 113 | 114 | now := time.Now() 115 | cfg := suggest.Config{ 116 | RequestContext: ctx, 117 | Context: req.Context, 118 | Builtin: req.Builtin, 119 | IgnoreCase: req.IgnoreCase, 120 | UnimportedPackages: req.UnimportedPackages, 121 | Logf: func(string, ...interface{}) {}, 122 | } 123 | cfg.Logf = func(string, ...interface{}) {} 124 | if *g_debug { 125 | cfg.Logf = log.Printf 126 | } 127 | candidates, d := cfg.Suggest(req.Filename, req.Data, req.Cursor) 128 | if candidates == nil { 129 | candidates = []suggest.Candidate{} 130 | } 131 | elapsed := time.Since(now) 132 | if *g_debug { 133 | log.Printf("Elapsed duration: %v\n", elapsed) 134 | log.Printf("Offset: %d\n", res.Len) 135 | log.Printf("Number of candidates found: %d\n", len(candidates)) 136 | log.Printf("Candidates are:\n") 137 | for _, c := range candidates { 138 | log.Printf(" %s\n", c.String()) 139 | } 140 | log.Println("=======================================================") 141 | } 142 | res.Candidates, res.Len = candidates, d 143 | return nil 144 | } 145 | 146 | type ExitRequest struct{} 147 | type ExitReply struct{} 148 | 149 | func (s *Server) Exit(ctx context.Context, req *ExitRequest, res *ExitReply) error { 150 | go func() { 151 | time.Sleep(time.Second) 152 | exitServer() 153 | }() 154 | return nil 155 | } 156 | -------------------------------------------------------------------------------- /internal/lookdot/lookdot.go: -------------------------------------------------------------------------------- 1 | package lookdot 2 | 3 | import "go/types" 4 | 5 | type Visitor func(obj types.Object) 6 | 7 | func Walk(tv *types.TypeAndValue, v Visitor) bool { 8 | switch { 9 | case tv.IsType(): 10 | walk(tv.Type, false, false, v) 11 | case tv.IsValue(): 12 | walk(tv.Type, tv.Addressable(), true, v) 13 | default: 14 | return false 15 | } 16 | return true 17 | } 18 | 19 | func walk(typ0 types.Type, addable0, value bool, v Visitor) { 20 | // Enumerating valid selector expression identifiers is 21 | // surprisingly nuanced. 22 | 23 | // found is a map from selector identifiers to the objects 24 | // they select. Nil entries are used to track objects that 25 | // have already been reported to the visitor and to indicate 26 | // ambiguous identifiers. 27 | found := make(map[string]types.Object) 28 | 29 | addObj := func(obj types.Object, valid bool) { 30 | id := obj.Id() 31 | switch otherObj, isPresent := found[id]; { 32 | case !isPresent: 33 | if valid { 34 | found[id] = obj 35 | } else { 36 | found[id] = nil 37 | } 38 | case otherObj != nil: 39 | // Ambiguous selector. 40 | found[id] = nil 41 | } 42 | } 43 | 44 | // visited keeps track of named types that we've already 45 | // visited. We only need to track named types, because 46 | // recursion can only happen through embedded struct fields, 47 | // which must be either a named type or a pointer to a named 48 | // type. 49 | visited := make(map[*types.Named]bool) 50 | 51 | type todo struct { 52 | typ types.Type 53 | addable bool 54 | } 55 | 56 | var cur, next []todo 57 | cur = []todo{{typ0, addable0}} 58 | 59 | for { 60 | if len(cur) == 0 { 61 | // Flush discovered objects to visitor function. 62 | for id, obj := range found { 63 | if obj != nil { 64 | v(obj) 65 | found[id] = nil 66 | } 67 | } 68 | 69 | // Move unvisited types from next to cur. 70 | // It's important to check between levels to 71 | // ensure that ambiguous selections are 72 | // correctly handled. 73 | cur = next[:0] 74 | for _, t := range next { 75 | nt := namedOf(t.typ) 76 | if nt == nil { 77 | if _, ok := t.typ.(*types.Basic); ok { 78 | continue 79 | } 80 | panic("panic: embedded struct field without name?") 81 | } 82 | if !visited[nt] { 83 | cur = append(cur, t) 84 | } 85 | } 86 | next = nil 87 | 88 | if len(cur) == 0 { 89 | break 90 | } 91 | } 92 | 93 | now := cur[0] 94 | cur = cur[1:] 95 | 96 | // Look for methods declared on a named type. 97 | { 98 | typ, addable := chasePointer(now.typ) 99 | if !addable { 100 | addable = now.addable 101 | } 102 | if typ, ok := typ.(*types.Named); ok { 103 | visited[typ] = true 104 | for i, n := 0, typ.NumMethods(); i < n; i++ { 105 | m := typ.Method(i) 106 | addObj(m, addable || !hasPtrRecv(m)) 107 | } 108 | } 109 | } 110 | 111 | // Look for interface methods. 112 | if typ, ok := now.typ.Underlying().(*types.Interface); ok { 113 | for i, n := 0, typ.NumMethods(); i < n; i++ { 114 | addObj(typ.Method(i), true) 115 | } 116 | } 117 | 118 | // Look for struct fields. 119 | { 120 | typ, addable := chasePointer(now.typ.Underlying()) 121 | if !addable { 122 | addable = now.addable 123 | } 124 | if typ, ok := typ.Underlying().(*types.Struct); ok { 125 | for i, n := 0, typ.NumFields(); i < n; i++ { 126 | f := typ.Field(i) 127 | addObj(f, value) 128 | if f.Anonymous() { 129 | next = append(next, todo{f.Type(), addable}) 130 | } 131 | } 132 | } 133 | } 134 | } 135 | } 136 | 137 | // namedOf returns the named type T when given T or *T. 138 | // Otherwise, it returns nil. 139 | func namedOf(typ types.Type) *types.Named { 140 | if ptr, isPtr := typ.(*types.Pointer); isPtr { 141 | typ = ptr.Elem() 142 | } 143 | res, _ := typ.(*types.Named) 144 | return res 145 | } 146 | 147 | func hasPtrRecv(m *types.Func) bool { 148 | _, ok := m.Type().(*types.Signature).Recv().Type().(*types.Pointer) 149 | return ok 150 | } 151 | 152 | func chasePointer(typ types.Type) (types.Type, bool) { 153 | if ptr, isPtr := typ.(*types.Pointer); isPtr { 154 | return ptr.Elem(), true 155 | } 156 | return typ, false 157 | } 158 | -------------------------------------------------------------------------------- /vendor/golang.org/x/tools/internal/span/uri.go: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package span 6 | 7 | import ( 8 | "fmt" 9 | "net/url" 10 | "os" 11 | "path" 12 | "path/filepath" 13 | "runtime" 14 | "strings" 15 | "unicode" 16 | ) 17 | 18 | const fileScheme = "file" 19 | 20 | // URI represents the full URI for a file. 21 | type URI string 22 | 23 | // Filename returns the file path for the given URI. 24 | // It is an error to call this on a URI that is not a valid filename. 25 | func (uri URI) Filename() string { 26 | filename, err := filename(uri) 27 | if err != nil { 28 | panic(err) 29 | } 30 | return filepath.FromSlash(filename) 31 | } 32 | 33 | func filename(uri URI) (string, error) { 34 | if uri == "" { 35 | return "", nil 36 | } 37 | u, err := url.ParseRequestURI(string(uri)) 38 | if err != nil { 39 | return "", err 40 | } 41 | if u.Scheme != fileScheme { 42 | return "", fmt.Errorf("only file URIs are supported, got %q from %q", u.Scheme, uri) 43 | } 44 | if isWindowsDriveURI(u.Path) { 45 | u.Path = u.Path[1:] 46 | } 47 | return u.Path, nil 48 | } 49 | 50 | // NewURI returns a span URI for the string. 51 | // It will attempt to detect if the string is a file path or uri. 52 | func NewURI(s string) URI { 53 | if u, err := url.PathUnescape(s); err == nil { 54 | s = u 55 | } 56 | if strings.HasPrefix(s, fileScheme+"://") { 57 | return URI(s) 58 | } 59 | return FileURI(s) 60 | } 61 | 62 | func CompareURI(a, b URI) int { 63 | if equalURI(a, b) { 64 | return 0 65 | } 66 | if a < b { 67 | return -1 68 | } 69 | return 1 70 | } 71 | 72 | func equalURI(a, b URI) bool { 73 | if a == b { 74 | return true 75 | } 76 | // If we have the same URI basename, we may still have the same file URIs. 77 | if !strings.EqualFold(path.Base(string(a)), path.Base(string(b))) { 78 | return false 79 | } 80 | fa, err := filename(a) 81 | if err != nil { 82 | return false 83 | } 84 | fb, err := filename(b) 85 | if err != nil { 86 | return false 87 | } 88 | // Stat the files to check if they are equal. 89 | infoa, err := os.Stat(filepath.FromSlash(fa)) 90 | if err != nil { 91 | return false 92 | } 93 | infob, err := os.Stat(filepath.FromSlash(fb)) 94 | if err != nil { 95 | return false 96 | } 97 | return os.SameFile(infoa, infob) 98 | } 99 | 100 | // FileURI returns a span URI for the supplied file path. 101 | // It will always have the file scheme. 102 | func FileURI(path string) URI { 103 | if path == "" { 104 | return "" 105 | } 106 | // Handle standard library paths that contain the literal "$GOROOT". 107 | // TODO(rstambler): The go/packages API should allow one to determine a user's $GOROOT. 108 | const prefix = "$GOROOT" 109 | if len(path) >= len(prefix) && strings.EqualFold(prefix, path[:len(prefix)]) { 110 | suffix := path[len(prefix):] 111 | path = runtime.GOROOT() + suffix 112 | } 113 | if !isWindowsDrivePath(path) { 114 | if abs, err := filepath.Abs(path); err == nil { 115 | path = abs 116 | } 117 | } 118 | // Check the file path again, in case it became absolute. 119 | if isWindowsDrivePath(path) { 120 | path = "/" + path 121 | } 122 | path = filepath.ToSlash(path) 123 | u := url.URL{ 124 | Scheme: fileScheme, 125 | Path: path, 126 | } 127 | uri := u.String() 128 | if unescaped, err := url.PathUnescape(uri); err == nil { 129 | uri = unescaped 130 | } 131 | return URI(uri) 132 | } 133 | 134 | // isWindowsDrivePath returns true if the file path is of the form used by 135 | // Windows. We check if the path begins with a drive letter, followed by a ":". 136 | func isWindowsDrivePath(path string) bool { 137 | if len(path) < 4 { 138 | return false 139 | } 140 | return unicode.IsLetter(rune(path[0])) && path[1] == ':' 141 | } 142 | 143 | // isWindowsDriveURI returns true if the file URI is of the format used by 144 | // Windows URIs. The url.Parse package does not specially handle Windows paths 145 | // (see https://golang.org/issue/6027). We check if the URI path has 146 | // a drive prefix (e.g. "/C:"). If so, we trim the leading "/". 147 | func isWindowsDriveURI(uri string) bool { 148 | if len(uri) < 4 { 149 | return false 150 | } 151 | return uri[0] == '/' && unicode.IsLetter(rune(uri[1])) && uri[2] == ':' 152 | } 153 | -------------------------------------------------------------------------------- /vendor/golang.org/x/tools/go/gcexportdata/gcexportdata.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // Package gcexportdata provides functions for locating, reading, and 6 | // writing export data files containing type information produced by the 7 | // gc compiler. This package supports go1.7 export data format and all 8 | // later versions. 9 | // 10 | // Although it might seem convenient for this package to live alongside 11 | // go/types in the standard library, this would cause version skew 12 | // problems for developer tools that use it, since they must be able to 13 | // consume the outputs of the gc compiler both before and after a Go 14 | // update such as from Go 1.7 to Go 1.8. Because this package lives in 15 | // golang.org/x/tools, sites can update their version of this repo some 16 | // time before the Go 1.8 release and rebuild and redeploy their 17 | // developer tools, which will then be able to consume both Go 1.7 and 18 | // Go 1.8 export data files, so they will work before and after the 19 | // Go update. (See discussion at https://golang.org/issue/15651.) 20 | // 21 | package gcexportdata // import "golang.org/x/tools/go/gcexportdata" 22 | 23 | import ( 24 | "bufio" 25 | "bytes" 26 | "fmt" 27 | "go/token" 28 | "go/types" 29 | "io" 30 | "io/ioutil" 31 | 32 | "golang.org/x/tools/go/internal/gcimporter" 33 | ) 34 | 35 | // Find returns the name of an object (.o) or archive (.a) file 36 | // containing type information for the specified import path, 37 | // using the workspace layout conventions of go/build. 38 | // If no file was found, an empty filename is returned. 39 | // 40 | // A relative srcDir is interpreted relative to the current working directory. 41 | // 42 | // Find also returns the package's resolved (canonical) import path, 43 | // reflecting the effects of srcDir and vendoring on importPath. 44 | func Find(importPath, srcDir string) (filename, path string) { 45 | return gcimporter.FindPkg(importPath, srcDir) 46 | } 47 | 48 | // NewReader returns a reader for the export data section of an object 49 | // (.o) or archive (.a) file read from r. The new reader may provide 50 | // additional trailing data beyond the end of the export data. 51 | func NewReader(r io.Reader) (io.Reader, error) { 52 | buf := bufio.NewReader(r) 53 | _, err := gcimporter.FindExportData(buf) 54 | // If we ever switch to a zip-like archive format with the ToC 55 | // at the end, we can return the correct portion of export data, 56 | // but for now we must return the entire rest of the file. 57 | return buf, err 58 | } 59 | 60 | // Read reads export data from in, decodes it, and returns type 61 | // information for the package. 62 | // The package name is specified by path. 63 | // File position information is added to fset. 64 | // 65 | // Read may inspect and add to the imports map to ensure that references 66 | // within the export data to other packages are consistent. The caller 67 | // must ensure that imports[path] does not exist, or exists but is 68 | // incomplete (see types.Package.Complete), and Read inserts the 69 | // resulting package into this map entry. 70 | // 71 | // On return, the state of the reader is undefined. 72 | func Read(in io.Reader, fset *token.FileSet, imports map[string]*types.Package, path string) (*types.Package, error) { 73 | data, err := ioutil.ReadAll(in) 74 | if err != nil { 75 | return nil, fmt.Errorf("reading export data for %q: %v", path, err) 76 | } 77 | 78 | if bytes.HasPrefix(data, []byte("!")) { 79 | return nil, fmt.Errorf("can't read export data for %q directly from an archive file (call gcexportdata.NewReader first to extract export data)", path) 80 | } 81 | 82 | // The App Engine Go runtime v1.6 uses the old export data format. 83 | // TODO(adonovan): delete once v1.7 has been around for a while. 84 | if bytes.HasPrefix(data, []byte("package ")) { 85 | return gcimporter.ImportData(imports, path, path, bytes.NewReader(data)) 86 | } 87 | 88 | // The indexed export format starts with an 'i'; the older 89 | // binary export format starts with a 'c', 'd', or 'v' 90 | // (from "version"). Select appropriate importer. 91 | if len(data) > 0 && data[0] == 'i' { 92 | _, pkg, err := gcimporter.IImportData(fset, imports, data[1:], path) 93 | return pkg, err 94 | } 95 | 96 | _, pkg, err := gcimporter.BImportData(fset, imports, data, path) 97 | return pkg, err 98 | } 99 | 100 | // Write writes encoded type information for the specified package to out. 101 | // The FileSet provides file position information for named objects. 102 | func Write(out io.Writer, fset *token.FileSet, pkg *types.Package) error { 103 | b, err := gcimporter.IExportData(fset, pkg) 104 | if err != nil { 105 | return err 106 | } 107 | _, err = out.Write(b) 108 | return err 109 | } 110 | -------------------------------------------------------------------------------- /internal/suggest/suggest_test.go: -------------------------------------------------------------------------------- 1 | package suggest_test 2 | 3 | import ( 4 | "bytes" 5 | "context" 6 | "encoding/json" 7 | "flag" 8 | "io/ioutil" 9 | "os" 10 | "path/filepath" 11 | "runtime" 12 | "strings" 13 | "testing" 14 | 15 | "github.com/stamblerre/gocode/internal/suggest" 16 | ) 17 | 18 | var testDirFlag = flag.String("testdir", "", "specify a directory to run the test on") 19 | 20 | func TestRegress(t *testing.T) { 21 | testDirs, err := filepath.Glob("testdata/test.*") 22 | if err != nil { 23 | t.Fatal(err) 24 | } 25 | tmpDir, err := filepath.Abs("tmp") 26 | if err != nil { 27 | t.Fatal(err) 28 | } 29 | if err := os.MkdirAll(tmpDir, 0775); err != nil { 30 | t.Fatal(err) 31 | } 32 | defer os.Remove(tmpDir) 33 | if *testDirFlag != "" { 34 | t.Run(*testDirFlag, func(t *testing.T) { 35 | testRegress(t, "testdata/test."+*testDirFlag) 36 | }) 37 | } else { 38 | t.Run("all", func(t *testing.T) { 39 | for _, testDir := range testDirs { 40 | // Skip test.0011 for Go <= 1.11 because a method was added to reflect.Value. 41 | // TODO(rstambler): Change this when Go 1.12 comes out. 42 | if !strings.HasPrefix(runtime.Version(), "devel") && strings.HasSuffix(testDir, "test.0011") { 43 | continue 44 | } 45 | testDir := testDir // capture 46 | name := strings.TrimPrefix(testDir, "testdata/") 47 | t.Run(name, func(t *testing.T) { 48 | t.Parallel() 49 | testRegress(t, testDir) 50 | }) 51 | } 52 | }) 53 | } 54 | } 55 | 56 | func testRegress(t *testing.T, testDir string) { 57 | testDir, err := filepath.Abs(testDir) 58 | if err != nil { 59 | t.Errorf("Abs failed: %v", err) 60 | return 61 | } 62 | tmpTestDir := strings.Replace(testDir, "testdata", "tmp", 1) 63 | if err := os.MkdirAll(tmpTestDir, 0775); err != nil { 64 | t.Errorf("MkdirAll failed: %v", err) 65 | return 66 | } 67 | defer os.RemoveAll(tmpTestDir) 68 | 69 | files, err := ioutil.ReadDir(testDir) 70 | if err != nil { 71 | t.Error(err) 72 | } 73 | var tmpTestFile string 74 | var data []byte 75 | var cursor int 76 | for _, file := range files { 77 | if strings.HasSuffix(file.Name(), ".go") { 78 | // Copy any Go files to a temporary directory. 79 | filename := filepath.Join(testDir, file.Name()) 80 | d, err := ioutil.ReadFile(filename) 81 | if err != nil { 82 | t.Errorf("ReadFile failed: %v", err) 83 | return 84 | } 85 | tmpTestFile = filepath.Join(tmpTestDir, file.Name()) 86 | if err := ioutil.WriteFile(tmpTestFile, d, 0775); err != nil { 87 | t.Errorf("WriteFile failed: %v", err) 88 | return 89 | } 90 | } else if strings.HasSuffix(file.Name(), ".go.in") { 91 | // Copy the test files to the temporary directory and save information. 92 | filename := filepath.Join(testDir, file.Name()) 93 | var err error 94 | data, err = ioutil.ReadFile(filename) 95 | if err != nil { 96 | t.Errorf("ReadFile failed: %v", err) 97 | return 98 | } 99 | cursor = bytes.IndexByte(data, '@') 100 | if cursor < 0 { 101 | t.Errorf("Missing @") 102 | return 103 | } 104 | data = append(data[:cursor], data[cursor+1:]...) 105 | tmpTestFile = filepath.Join(tmpTestDir, strings.TrimSuffix(file.Name(), ".in")) 106 | if err := ioutil.WriteFile(tmpTestFile, data, 0775); err != nil { 107 | t.Errorf("WriteFile failed: %v", err) 108 | return 109 | } 110 | } 111 | } 112 | cfg := suggest.Config{ 113 | Logf: func(string, ...interface{}) {}, 114 | Context: &suggest.PackedContext{}, 115 | } 116 | if testing.Verbose() { 117 | cfg.Logf = t.Logf 118 | } 119 | 120 | if cfgJSON, err := os.Open(filepath.Join(testDir, "config.json")); err == nil { 121 | if err := json.NewDecoder(cfgJSON).Decode(&cfg); err != nil { 122 | t.Errorf("Decode failed: %v", err) 123 | return 124 | } 125 | } else if !os.IsNotExist(err) { 126 | t.Errorf("Open failed: %v", err) 127 | return 128 | } 129 | candidates, prefixLen := cfg.Suggest(tmpTestFile, data, cursor) 130 | 131 | var out bytes.Buffer 132 | suggest.NiceFormat(&out, candidates, prefixLen) 133 | want, _ := ioutil.ReadFile(filepath.Join(testDir, "out.expected")) 134 | if got := out.Bytes(); !bytes.Equal(got, want) { 135 | t.Errorf("%s:\nGot:\n%s\nWant:\n%s\n", testDir, got, want) 136 | return 137 | } 138 | return 139 | } 140 | 141 | func TestCancellation(t *testing.T) { 142 | // sanity check for cancellation 143 | ctx, cancel := context.WithCancel(context.Background()) 144 | 145 | cfg := suggest.Config{ 146 | RequestContext: ctx, 147 | Logf: func(string, ...interface{}) {}, 148 | Context: &suggest.PackedContext{}, 149 | } 150 | if testing.Verbose() { 151 | cfg.Logf = t.Logf 152 | } 153 | 154 | data, err := ioutil.ReadFile("suggest_test.go") 155 | if err != nil { 156 | t.Fatal(err) 157 | } 158 | 159 | cancel() 160 | _, _ = cfg.Suggest("suggest_test.go", data, 100) 161 | } 162 | -------------------------------------------------------------------------------- /vendor/golang.org/x/tools/internal/span/token.go: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package span 6 | 7 | import ( 8 | "fmt" 9 | "go/token" 10 | ) 11 | 12 | // Range represents a source code range in token.Pos form. 13 | // It also carries the FileSet that produced the positions, so that it is 14 | // self contained. 15 | type Range struct { 16 | FileSet *token.FileSet 17 | Start token.Pos 18 | End token.Pos 19 | } 20 | 21 | // TokenConverter is a Converter backed by a token file set and file. 22 | // It uses the file set methods to work out the conversions, which 23 | // makes it fast and does not require the file contents. 24 | type TokenConverter struct { 25 | fset *token.FileSet 26 | file *token.File 27 | } 28 | 29 | // NewRange creates a new Range from a FileSet and two positions. 30 | // To represent a point pass a 0 as the end pos. 31 | func NewRange(fset *token.FileSet, start, end token.Pos) Range { 32 | return Range{ 33 | FileSet: fset, 34 | Start: start, 35 | End: end, 36 | } 37 | } 38 | 39 | // NewTokenConverter returns an implementation of Converter backed by a 40 | // token.File. 41 | func NewTokenConverter(fset *token.FileSet, f *token.File) *TokenConverter { 42 | return &TokenConverter{fset: fset, file: f} 43 | } 44 | 45 | // NewContentConverter returns an implementation of Converter for the 46 | // given file content. 47 | func NewContentConverter(filename string, content []byte) *TokenConverter { 48 | fset := token.NewFileSet() 49 | f := fset.AddFile(filename, -1, len(content)) 50 | f.SetLinesForContent(content) 51 | return &TokenConverter{fset: fset, file: f} 52 | } 53 | 54 | // IsPoint returns true if the range represents a single point. 55 | func (r Range) IsPoint() bool { 56 | return r.Start == r.End 57 | } 58 | 59 | // Span converts a Range to a Span that represents the Range. 60 | // It will fill in all the members of the Span, calculating the line and column 61 | // information. 62 | func (r Range) Span() (Span, error) { 63 | f := r.FileSet.File(r.Start) 64 | if f == nil { 65 | return Span{}, fmt.Errorf("file not found in FileSet") 66 | } 67 | s := Span{v: span{URI: FileURI(f.Name())}} 68 | var err error 69 | s.v.Start.Offset, err = offset(f, r.Start) 70 | if err != nil { 71 | return Span{}, err 72 | } 73 | if r.End.IsValid() { 74 | s.v.End.Offset, err = offset(f, r.End) 75 | if err != nil { 76 | return Span{}, err 77 | } 78 | } 79 | s.v.Start.clean() 80 | s.v.End.clean() 81 | s.v.clean() 82 | converter := NewTokenConverter(r.FileSet, f) 83 | return s.WithPosition(converter) 84 | } 85 | 86 | // offset is a copy of the Offset function in go/token, but with the adjustment 87 | // that it does not panic on invalid positions. 88 | func offset(f *token.File, pos token.Pos) (int, error) { 89 | if int(pos) < f.Base() || int(pos) > f.Base()+f.Size() { 90 | return 0, fmt.Errorf("invalid pos") 91 | } 92 | return int(pos) - f.Base(), nil 93 | } 94 | 95 | // Range converts a Span to a Range that represents the Span for the supplied 96 | // File. 97 | func (s Span) Range(converter *TokenConverter) (Range, error) { 98 | s, err := s.WithOffset(converter) 99 | if err != nil { 100 | return Range{}, err 101 | } 102 | // go/token will panic if the offset is larger than the file's size, 103 | // so check here to avoid panicking. 104 | if s.Start().Offset() > converter.file.Size() { 105 | return Range{}, fmt.Errorf("start offset %v is past the end of the file %v", s.Start(), converter.file.Size()) 106 | } 107 | if s.End().Offset() > converter.file.Size() { 108 | return Range{}, fmt.Errorf("end offset %v is past the end of the file %v", s.End(), converter.file.Size()) 109 | } 110 | return Range{ 111 | FileSet: converter.fset, 112 | Start: converter.file.Pos(s.Start().Offset()), 113 | End: converter.file.Pos(s.End().Offset()), 114 | }, nil 115 | } 116 | 117 | func (l *TokenConverter) ToPosition(offset int) (int, int, error) { 118 | if offset > l.file.Size() { 119 | return 0, 0, fmt.Errorf("offset %v is past the end of the file %v", offset, l.file.Size()) 120 | } 121 | pos := l.file.Pos(offset) 122 | p := l.fset.Position(pos) 123 | if offset == l.file.Size() { 124 | return p.Line + 1, 1, nil 125 | } 126 | return p.Line, p.Column, nil 127 | } 128 | 129 | func (l *TokenConverter) ToOffset(line, col int) (int, error) { 130 | if line < 0 { 131 | return -1, fmt.Errorf("line is not valid") 132 | } 133 | lineMax := l.file.LineCount() + 1 134 | if line > lineMax { 135 | return -1, fmt.Errorf("line is beyond end of file %v", lineMax) 136 | } else if line == lineMax { 137 | if col > 1 { 138 | return -1, fmt.Errorf("column is beyond end of file") 139 | } 140 | // at the end of the file, allowing for a trailing eol 141 | return l.file.Size(), nil 142 | } 143 | pos := lineStart(l.file, line) 144 | if !pos.IsValid() { 145 | return -1, fmt.Errorf("line is not in file") 146 | } 147 | // we assume that column is in bytes here, and that the first byte of a 148 | // line is at column 1 149 | pos += token.Pos(col - 1) 150 | return offset(l.file, pos) 151 | } 152 | -------------------------------------------------------------------------------- /client.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "flag" 6 | "fmt" 7 | "io/ioutil" 8 | "log" 9 | "os" 10 | "path/filepath" 11 | "runtime/debug" 12 | "strconv" 13 | "time" 14 | 15 | "github.com/keegancsmith/rpc" 16 | 17 | "github.com/stamblerre/gocode/internal/suggest" 18 | ) 19 | 20 | func doClient(ctx context.Context) { 21 | // Client is a short-lived program. 22 | // Disable GC to make it faster 23 | debug.SetGCPercent(-1) 24 | 25 | if *g_debug { 26 | start := time.Now() 27 | defer func() { 28 | elapsed := time.Since(start) 29 | log.Printf("Elapsed duration: %v\n", elapsed) 30 | }() 31 | } 32 | 33 | var command string 34 | if flag.NArg() > 0 { 35 | command = flag.Arg(0) 36 | switch command { 37 | case "autocomplete", "exit": 38 | // these are valid commands 39 | case "close": 40 | // "close" is an alias for "exit" 41 | command = "exit" 42 | default: 43 | fmt.Printf("gocode: unknown subcommand: %q\nRun 'gocode -help' for usage.\n", command) 44 | os.Exit(2) 45 | } 46 | } 47 | 48 | // client 49 | var client *rpc.Client 50 | if *g_sock != "none" { 51 | addr := *g_addr 52 | if *g_sock == "unix" { 53 | addr = getSocketPath() 54 | } 55 | 56 | var err error 57 | client, err = rpc.Dial(*g_sock, addr) 58 | if err != nil { 59 | if command == "exit" { 60 | log.Fatal(err) 61 | } 62 | 63 | if *g_sock == "unix" { 64 | _ = os.Remove(addr) 65 | } 66 | err = tryStartServer() 67 | if err != nil { 68 | log.Fatalf("Failed to start server: %s\n", err) 69 | } 70 | client, err = tryToConnect(*g_sock, addr) 71 | if err != nil { 72 | log.Fatalf("Failed to connect to %q: %s\n", addr, err) 73 | } 74 | } 75 | defer client.Close() 76 | } 77 | 78 | switch command { 79 | case "autocomplete": 80 | cmdAutoComplete(ctx, client) 81 | case "exit": 82 | cmdExit(ctx, client) 83 | } 84 | } 85 | 86 | func tryStartServer() error { 87 | path := get_executable_filename() 88 | args := []string{os.Args[0], "-s", "-sock", *g_sock, "-addr", *g_addr} 89 | cwd, _ := os.Getwd() 90 | 91 | var err error 92 | stdin, err := os.Open(os.DevNull) 93 | if err != nil { 94 | return err 95 | } 96 | stdout, err := os.OpenFile(os.DevNull, os.O_WRONLY, 0) 97 | if err != nil { 98 | return err 99 | } 100 | stderr, err := os.OpenFile(os.DevNull, os.O_WRONLY, 0) 101 | if err != nil { 102 | return err 103 | } 104 | 105 | procattr := os.ProcAttr{Dir: cwd, Env: os.Environ(), Files: []*os.File{stdin, stdout, stderr}} 106 | p, err := os.StartProcess(path, args, &procattr) 107 | if err != nil { 108 | return err 109 | } 110 | 111 | return p.Release() 112 | } 113 | 114 | func tryToConnect(network, address string) (*rpc.Client, error) { 115 | start := time.Now() 116 | for { 117 | client, err := rpc.Dial(network, address) 118 | if err != nil && time.Since(start) < time.Second { 119 | continue 120 | } 121 | return client, err 122 | } 123 | } 124 | 125 | func cmdAutoComplete(ctx context.Context, c *rpc.Client) { 126 | var req AutoCompleteRequest 127 | req.Filename, req.Data, req.Cursor = prepareFilenameDataCursor() 128 | // TODO(rstambler): Client can specify GOOS, GOARCH, etc. 129 | // For now, assume same environment for server and client. 130 | req.Context = &suggest.PackedContext{ 131 | Dir: filepath.Dir(req.Filename), 132 | } 133 | req.Source = *g_source 134 | req.Builtin = *g_builtin 135 | req.IgnoreCase = *g_ignore_case 136 | req.UnimportedPackages = *g_unimported_packages 137 | req.FallbackToSource = *g_fallback_to_source 138 | 139 | var res AutoCompleteReply 140 | var err error 141 | if c == nil { 142 | s := Server{} 143 | err = s.AutoComplete(ctx, &req, &res) 144 | } else { 145 | err = c.Call(ctx, "Server.AutoComplete", &req, &res) 146 | } 147 | if err != nil { 148 | log.Fatal(err) 149 | } 150 | 151 | fmt := suggest.Formatters[*g_format] 152 | if fmt == nil { 153 | fmt = suggest.NiceFormat 154 | } 155 | fmt(os.Stdout, res.Candidates, res.Len) 156 | } 157 | 158 | func cmdExit(ctx context.Context, c *rpc.Client) { 159 | if c == nil { 160 | return 161 | } 162 | var req ExitRequest 163 | var res ExitReply 164 | if err := c.Call(ctx, "Server.Exit", &req, &res); err != nil { 165 | log.Fatal(err) 166 | } 167 | } 168 | 169 | func prepareFilenameDataCursor() (string, []byte, int) { 170 | var file []byte 171 | var err error 172 | 173 | if *g_input != "" { 174 | file, err = ioutil.ReadFile(*g_input) 175 | } else { 176 | file, err = ioutil.ReadAll(os.Stdin) 177 | } 178 | 179 | if err != nil { 180 | log.Fatal(err) 181 | } 182 | 183 | filename := *g_input 184 | offset := "" 185 | switch flag.NArg() { 186 | case 2: 187 | offset = flag.Arg(1) 188 | case 3: 189 | filename = flag.Arg(1) // Override default filename 190 | offset = flag.Arg(2) 191 | } 192 | 193 | if filename != "" { 194 | filename, _ = filepath.Abs(filename) 195 | } 196 | 197 | cursor := -1 198 | if offset != "" { 199 | if offset[0] == 'c' || offset[0] == 'C' { 200 | cursor, _ = strconv.Atoi(offset[1:]) 201 | cursor = runeToByteOffset(file, cursor) 202 | } else { 203 | cursor, _ = strconv.Atoi(offset) 204 | } 205 | } 206 | 207 | return filename, file, cursor 208 | } 209 | -------------------------------------------------------------------------------- /subl3/syntax/GoSublime-Template.tmLanguage: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | foldingStartMarker 6 | \{\{\s*(?:if|with|range)\b 7 | foldingStopMarker 8 | \{\{\s*(?:else|end)\b 9 | name 10 | GoSublime: Template 11 | patterns 12 | 13 | 14 | begin 15 | \{\{ 16 | beginCaptures 17 | 18 | 0 19 | 20 | name 21 | punctuation.section.embedded.begin.gotemplate 22 | 23 | 24 | end 25 | \}\} 26 | endCaptures 27 | 28 | 0 29 | 30 | name 31 | punctuation.section.embedded.end.gotemplate 32 | 33 | 34 | patterns 35 | 36 | 37 | match 38 | := 39 | name 40 | keyword.operator.initialize.gotemplate 41 | 42 | 43 | match 44 | \| 45 | name 46 | keyword.operator.pipe.gotemplate 47 | 48 | 49 | match 50 | [.$][\w]* 51 | name 52 | variable.other.gotemplate 53 | 54 | 55 | match 56 | \b(if|else|range|template|with|end|nil|with|define)\b 57 | name 58 | keyword.control.gotemplate 59 | 60 | 61 | match 62 | \b(and|call|html|index|js|len|not|or|print|printf|println|urlquery|eq|ne|lt|le|gt|ge)\b 63 | name 64 | support.function.builtin.gotemplate 65 | 66 | 67 | begin 68 | /\* 69 | end 70 | \*/ 71 | name 72 | comment.block.gotemplate 73 | 74 | 75 | begin 76 | " 77 | beginCaptures 78 | 79 | 0 80 | 81 | name 82 | punctuation.definition.string.begin.gotemplate 83 | 84 | 85 | end 86 | " 87 | endCaptures 88 | 89 | 0 90 | 91 | name 92 | punctuation.definition.string.end.gotemplate 93 | 94 | 95 | name 96 | string.quoted.double.gotemplate 97 | patterns 98 | 99 | 100 | include 101 | #string_placeholder 102 | 103 | 104 | include 105 | #string_escaped_char 106 | 107 | 108 | 109 | 110 | begin 111 | ` 112 | beginCaptures 113 | 114 | 0 115 | 116 | name 117 | punctuation.definition.string.begin.gotemplate 118 | 119 | 120 | end 121 | ` 122 | endCaptures 123 | 124 | 0 125 | 126 | name 127 | punctuation.definition.string.end.gotemplate 128 | 129 | 130 | name 131 | string.quoted.raw.gotemplate 132 | patterns 133 | 134 | 135 | include 136 | #string_placeholder 137 | 138 | 139 | 140 | 141 | 142 | 143 | repository 144 | 145 | string_escaped_char 146 | 147 | patterns 148 | 149 | 150 | match 151 | \\(\\|[abfnrtv'"]|x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|U[0-9a-fA-F]{8}|[0-7]{3}) 152 | name 153 | constant.character.escape.gotemplate 154 | 155 | 156 | match 157 | \\. 158 | name 159 | invalid.illegal.unknown-escape.gotemplate 160 | 161 | 162 | 163 | string_placeholder 164 | 165 | patterns 166 | 167 | 168 | match 169 | (?x)% 170 | (\d+\$)? # field (argument #) 171 | [#0\- +']* # flags 172 | [,;:_]? # separator character (AltiVec) 173 | ((-?\d+)|\*(-?\d+\$)?)? # minimum field width 174 | (\.((-?\d+)|\*(-?\d+\$)?)?)? # precision 175 | [diouxXDOUeEfFgGaAcCsSqpnvtTbyYhHmMzZ%] # conversion type 176 | 177 | name 178 | constant.other.placeholder.gotemplate 179 | 180 | 181 | match 182 | % 183 | name 184 | invalid.illegal.placeholder.gotemplate 185 | 186 | 187 | 188 | 189 | scopeName 190 | source.gotemplate 191 | uuid 192 | 43606de8-c638-11e2-b661-6711676f99ca 193 | 194 | 195 | -------------------------------------------------------------------------------- /internal/suggest/candidate.go: -------------------------------------------------------------------------------- 1 | package suggest 2 | 3 | import ( 4 | "fmt" 5 | "go/ast" 6 | "go/types" 7 | "sort" 8 | "strings" 9 | ) 10 | 11 | type Candidate struct { 12 | Class string `json:"class"` 13 | PkgPath string `json:"package"` 14 | Name string `json:"name"` 15 | Type string `json:"type"` 16 | } 17 | 18 | func (c Candidate) Suggestion() string { 19 | switch { 20 | case c.Class != "func": 21 | return c.Name 22 | case strings.HasPrefix(c.Type, "func()"): 23 | return c.Name + "()" 24 | default: 25 | return c.Name + "(" 26 | } 27 | } 28 | 29 | func (c Candidate) String() string { 30 | if c.Class == "func" { 31 | return fmt.Sprintf("%s %s%s", c.Class, c.Name, strings.TrimPrefix(c.Type, "func")) 32 | } 33 | return fmt.Sprintf("%s %s %s", c.Class, c.Name, c.Type) 34 | } 35 | 36 | type candidatesByClassAndName []Candidate 37 | 38 | func (s candidatesByClassAndName) Len() int { return len(s) } 39 | func (s candidatesByClassAndName) Swap(i, j int) { s[i], s[j] = s[j], s[i] } 40 | 41 | func (s candidatesByClassAndName) Less(i, j int) bool { 42 | if s[i].Class != s[j].Class { 43 | return s[i].Class < s[j].Class 44 | } 45 | return s[i].Name < s[j].Name 46 | } 47 | 48 | type objectFilter func(types.Object) bool 49 | 50 | var objectFilters = map[string]objectFilter{ 51 | "const": func(obj types.Object) bool { _, ok := obj.(*types.Const); return ok }, 52 | "func": func(obj types.Object) bool { _, ok := obj.(*types.Func); return ok }, 53 | "package": func(obj types.Object) bool { _, ok := obj.(*types.PkgName); return ok }, 54 | "type": func(obj types.Object) bool { _, ok := obj.(*types.TypeName); return ok }, 55 | "var": func(obj types.Object) bool { _, ok := obj.(*types.Var); return ok }, 56 | } 57 | 58 | func classifyObject(obj types.Object) string { 59 | switch obj.(type) { 60 | case *types.Builtin: 61 | return "func" 62 | case *types.Const: 63 | return "const" 64 | case *types.Func: 65 | return "func" 66 | case *types.Nil: 67 | return "const" 68 | case *types.PkgName: 69 | return "package" 70 | case *types.TypeName: 71 | return "type" 72 | case *types.Var: 73 | return "var" 74 | } 75 | panic(fmt.Sprintf("unhandled types.Object: %T", obj)) 76 | } 77 | 78 | type candidateCollector struct { 79 | exact []types.Object 80 | badcase []types.Object 81 | imports []*ast.ImportSpec 82 | localpkg *types.Package 83 | partial string 84 | filter objectFilter 85 | builtin bool 86 | ignoreCase bool 87 | } 88 | 89 | func (b *candidateCollector) getCandidates() []Candidate { 90 | objs := b.exact 91 | if objs == nil { 92 | objs = b.badcase 93 | } 94 | 95 | var res []Candidate 96 | for _, obj := range objs { 97 | res = append(res, b.asCandidate(obj)) 98 | } 99 | sort.Sort(candidatesByClassAndName(res)) 100 | return res 101 | } 102 | 103 | func (b *candidateCollector) asCandidate(obj types.Object) Candidate { 104 | objClass := classifyObject(obj) 105 | var typ types.Type 106 | switch objClass { 107 | case "const", "func", "var": 108 | typ = obj.Type() 109 | case "type": 110 | typ = obj.Type().Underlying() 111 | } 112 | 113 | var typStr string 114 | switch t := typ.(type) { 115 | case *types.Interface: 116 | typStr = "interface" 117 | case *types.Struct: 118 | typStr = "struct" 119 | default: 120 | if _, isBuiltin := obj.(*types.Builtin); isBuiltin { 121 | typStr = builtinTypes[obj.Name()] 122 | } else if t != nil { 123 | typStr = types.TypeString(t, b.qualify) 124 | } 125 | } 126 | 127 | path := "builtin" 128 | if pkg := obj.Pkg(); pkg != nil { 129 | path = pkg.Path() 130 | } 131 | 132 | return Candidate{ 133 | Class: objClass, 134 | PkgPath: path, 135 | Name: obj.Name(), 136 | Type: typStr, 137 | } 138 | } 139 | 140 | var builtinTypes = map[string]string{ 141 | // Universe. 142 | "append": "func(slice []Type, elems ..Type) []Type", 143 | "cap": "func(v Type) int", 144 | "close": "func(c chan<- Type)", 145 | "complex": "func(real FloatType, imag FloatType) ComplexType", 146 | "copy": "func(dst []Type, src []Type) int", 147 | "delete": "func(m map[Key]Type, key Key)", 148 | "imag": "func(c ComplexType) FloatType", 149 | "len": "func(v Type) int", 150 | "make": "func(Type, size IntegerType) Type", 151 | "new": "func(Type) *Type", 152 | "panic": "func(v interface{})", 153 | "print": "func(args ...Type)", 154 | "println": "func(args ...Type)", 155 | "real": "func(c ComplexType) FloatType", 156 | "recover": "func() interface{}", 157 | 158 | // Package unsafe. 159 | "Alignof": "func(x Type) uintptr", 160 | "Sizeof": "func(x Type) uintptr", 161 | "Offsetof": "func(x Type) uintptr", 162 | } 163 | 164 | func (b *candidateCollector) qualify(pkg *types.Package) string { 165 | if pkg == b.localpkg { 166 | return "" 167 | } 168 | 169 | // the *types.Package we are asked to qualify might _not_ be imported 170 | // by the file in which we are asking for candidates. Hence... we retain 171 | // the default of pkg.Name() as the qualifier 172 | 173 | for _, i := range b.imports { 174 | // given the import spec has been correctly parsed (by virtue of 175 | // its existence) we can safely byte-index the path value knowing 176 | // that len("\"") == 1 177 | iPath := i.Path.Value[1 : len(i.Path.Value)-1] 178 | 179 | if iPath == pkg.Path() { 180 | if i.Name != nil && i.Name.Name != "." { 181 | return i.Name.Name 182 | } else { 183 | return pkg.Name() 184 | } 185 | } 186 | } 187 | 188 | return pkg.Name() 189 | } 190 | 191 | func (b *candidateCollector) appendObject(obj types.Object) { 192 | if obj.Pkg() != b.localpkg { 193 | if obj.Parent() == types.Universe { 194 | if !b.builtin { 195 | return 196 | } 197 | } else if !obj.Exported() { 198 | return 199 | } 200 | } 201 | 202 | // TODO(mdempsky): Reconsider this functionality. 203 | if b.filter != nil && !b.filter(obj) { 204 | return 205 | } 206 | if !b.ignoreCase && (b.filter != nil || strings.HasPrefix(obj.Name(), b.partial)) { 207 | b.exact = append(b.exact, obj) 208 | } else if strings.HasPrefix(strings.ToLower(obj.Name()), strings.ToLower(b.partial)) { 209 | b.badcase = append(b.badcase, obj) 210 | } 211 | } 212 | -------------------------------------------------------------------------------- /docs/autocomplete_formats.md: -------------------------------------------------------------------------------- 1 | 2 | # Description of Completion Assistance Formats # 3 | 4 | Use `-f` parameter for `autocomplete` command to set format. "nice" format is the default and fallback. 5 | 6 | Following formats supported: 7 | * json 8 | * nice 9 | * vim 10 | * godit 11 | * emacs 12 | * csv 13 | 14 | ## json ### 15 | Generic JSON format. Example (manually formatted): 16 | ```json 17 | [6, [{ 18 | "class": "func", 19 | "name": "client_auto_complete", 20 | "type": "func(cli *rpc.Client, Arg0 []byte, Arg1 string, Arg2 int, Arg3 gocode_env) (c []candidate, d int)" 21 | }, { 22 | "class": "func", 23 | "name": "client_close", 24 | "type": "func(cli *rpc.Client, Arg0 int) int" 25 | }, { 26 | "class": "func", 27 | "name": "client_cursor_type_pkg", 28 | "type": "func(cli *rpc.Client, Arg0 []byte, Arg1 string, Arg2 int) (typ, pkg string)" 29 | }, { 30 | "class": "func", 31 | "name": "client_drop_cache", 32 | "type": "func(cli *rpc.Client, Arg0 int) int" 33 | }, { 34 | "class": "func", 35 | "name": "client_highlight", 36 | "type": "func(cli *rpc.Client, Arg0 []byte, Arg1 string, Arg2 gocode_env) (c []highlight_range, d int)" 37 | }, { 38 | "class": "func", 39 | "name": "client_set", 40 | "type": "func(cli *rpc.Client, Arg0, Arg1 string) string" 41 | }, { 42 | "class": "func", 43 | "name": "client_status", 44 | "type": "func(cli *rpc.Client, Arg0 int) string" 45 | } 46 | ]] 47 | ``` 48 | Limitations: 49 | * `class` can be one of: `func`, `package`, `var`, `type`, `const`, `PANIC` 50 | * `PANIC` means suspicious error inside gocode 51 | * `name` is text which can be inserted 52 | * `type` can be used to create code assistance hint 53 | * You can re-format type by using following approach: if `class` is prefix of `type`, delete this prefix and add another prefix `class` + " " + `name`. 54 | 55 | ## nice ## 56 | You can use it to test from command-line. 57 | ``` 58 | Found 7 candidates: 59 | func client_auto_complete(cli *rpc.Client, Arg0 []byte, Arg1 string, Arg2 int, Arg3 gocode_env) (c []candidate, d int) 60 | func client_close(cli *rpc.Client, Arg0 int) int 61 | func client_cursor_type_pkg(cli *rpc.Client, Arg0 []byte, Arg1 string, Arg2 int) (typ, pkg string) 62 | func client_drop_cache(cli *rpc.Client, Arg0 int) int 63 | func client_highlight(cli *rpc.Client, Arg0 []byte, Arg1 string, Arg2 gocode_env) (c []highlight_range, d int) 64 | func client_set(cli *rpc.Client, Arg0, Arg1 string) string 65 | func client_status(cli *rpc.Client, Arg0 int) string 66 | ``` 67 | 68 | ## vim ## 69 | Format designed to be used in VIM scripts. Example: 70 | ``` 71 | [6, [{'word': 'client_auto_complete(', 'abbr': 'func client_auto_complete(cli *rpc.Client, Arg0 []byte, Arg1 string, Arg2 int, Arg3 gocode_env) (c []candidate, d int)', 'info': 'func client_auto_complete(cli *rpc.Client, Arg0 []byte, Arg1 string, Arg2 int, Arg3 gocode_env) (c []candidate, d int)'}, {'word': 'client_close(', 'abbr': 'func client_close(cli *rpc.Client, Arg0 int) int', 'info': 'func client_close(cli *rpc.Client, Arg0 int) int'}, {'word': 'client_cursor_type_pkg(', 'abbr': 'func client_cursor_type_pkg(cli *rpc.Client, Arg0 []byte, Arg1 string, Arg2 int) (typ, pkg string)', 'info': 'func client_cursor_type_pkg(cli *rpc.Client, Arg0 []byte, Arg1 string, Arg2 int) (typ, pkg string)'}, {'word': 'client_drop_cache(', 'abbr': 'func client_drop_cache(cli *rpc.Client, Arg0 int) int', 'info': 'func client_drop_cache(cli *rpc.Client, Arg0 int) int'}, {'word': 'client_highlight(', 'abbr': 'func client_highlight(cli *rpc.Client, Arg0 []byte, Arg1 string, Arg2 gocode_env) (c []highlight_range, d int)', 'info': 'func client_highlight(cli *rpc.Client, Arg0 []byte, Arg1 string, Arg2 gocode_env) (c []highlight_range, d int)'}, {'word': 'client_set(', 'abbr': 'func client_set(cli *rpc.Client, Arg0, Arg1 string) string', 'info': 'func client_set(cli *rpc.Client, Arg0, Arg1 string) string'}, {'word': 'client_status(', 'abbr': 'func client_status(cli *rpc.Client, Arg0 int) string', 'info': 'func client_status(cli *rpc.Client, Arg0 int) string'}]] 72 | ``` 73 | 74 | ## godit ## 75 | Example: 76 | ``` 77 | 6,,7 78 | func client_auto_complete(cli *rpc.Client, Arg0 []byte, Arg1 string, Arg2 int, Arg3 gocode_env) (c []candidate, d int),,client_auto_complete( 79 | func client_close(cli *rpc.Client, Arg0 int) int,,client_close( 80 | func client_cursor_type_pkg(cli *rpc.Client, Arg0 []byte, Arg1 string, Arg2 int) (typ, pkg string),,client_cursor_type_pkg( 81 | func client_drop_cache(cli *rpc.Client, Arg0 int) int,,client_drop_cache( 82 | func client_highlight(cli *rpc.Client, Arg0 []byte, Arg1 string, Arg2 gocode_env) (c []highlight_range, d int),,client_highlight( 83 | func client_set(cli *rpc.Client, Arg0, Arg1 string) string,,client_set( 84 | func client_status(cli *rpc.Client, Arg0 int) string,,client_status( 85 | ``` 86 | 87 | ## emacs ## 88 | Format designed to be used in Emacs scripts. Example: 89 | ``` 90 | client_auto_complete,,func(cli *rpc.Client, Arg0 []byte, Arg1 string, Arg2 int, Arg3 gocode_env) (c []candidate, d int) 91 | client_close,,func(cli *rpc.Client, Arg0 int) int 92 | client_cursor_type_pkg,,func(cli *rpc.Client, Arg0 []byte, Arg1 string, Arg2 int) (typ, pkg string) 93 | client_drop_cache,,func(cli *rpc.Client, Arg0 int) int 94 | client_highlight,,func(cli *rpc.Client, Arg0 []byte, Arg1 string, Arg2 gocode_env) (c []highlight_range, d int) 95 | client_set,,func(cli *rpc.Client, Arg0, Arg1 string) string 96 | client_status,,func(cli *rpc.Client, Arg0 int) string 97 | ``` 98 | 99 | ## csv ## 100 | Comma-separated values format which has small size. Example: 101 | ```csv 102 | func,,client_auto_complete,,func(cli *rpc.Client, Arg0 []byte, Arg1 string, Arg2 int, Arg3 gocode_env) (c []candidate, d int) 103 | func,,client_close,,func(cli *rpc.Client, Arg0 int) int 104 | func,,client_cursor_type_pkg,,func(cli *rpc.Client, Arg0 []byte, Arg1 string, Arg2 int) (typ, pkg string) 105 | func,,client_drop_cache,,func(cli *rpc.Client, Arg0 int) int 106 | func,,client_highlight,,func(cli *rpc.Client, Arg0 []byte, Arg1 string, Arg2 gocode_env) (c []highlight_range, d int) 107 | func,,client_set,,func(cli *rpc.Client, Arg0, Arg1 string) string 108 | func,,client_status,,func(cli *rpc.Client, Arg0 int) string 109 | ``` 110 | -------------------------------------------------------------------------------- /vendor/golang.org/x/tools/go/internal/packagesdriver/sizes.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // Package packagesdriver fetches type sizes for go/packages and go/analysis. 6 | package packagesdriver 7 | 8 | import ( 9 | "bytes" 10 | "context" 11 | "encoding/json" 12 | "fmt" 13 | "go/types" 14 | "log" 15 | "os" 16 | "os/exec" 17 | "strings" 18 | "time" 19 | ) 20 | 21 | var debug = false 22 | 23 | // GetSizes returns the sizes used by the underlying driver with the given parameters. 24 | func GetSizes(ctx context.Context, buildFlags, env []string, dir string, usesExportData bool) (types.Sizes, error) { 25 | // TODO(matloob): Clean this up. This code is mostly a copy of packages.findExternalDriver. 26 | const toolPrefix = "GOPACKAGESDRIVER=" 27 | tool := "" 28 | for _, env := range env { 29 | if val := strings.TrimPrefix(env, toolPrefix); val != env { 30 | tool = val 31 | } 32 | } 33 | 34 | if tool == "" { 35 | var err error 36 | tool, err = exec.LookPath("gopackagesdriver") 37 | if err != nil { 38 | // We did not find the driver, so use "go list". 39 | tool = "off" 40 | } 41 | } 42 | 43 | if tool == "off" { 44 | return GetSizesGolist(ctx, buildFlags, env, dir, usesExportData) 45 | } 46 | 47 | req, err := json.Marshal(struct { 48 | Command string `json:"command"` 49 | Env []string `json:"env"` 50 | BuildFlags []string `json:"build_flags"` 51 | }{ 52 | Command: "sizes", 53 | Env: env, 54 | BuildFlags: buildFlags, 55 | }) 56 | if err != nil { 57 | return nil, fmt.Errorf("failed to encode message to driver tool: %v", err) 58 | } 59 | 60 | buf := new(bytes.Buffer) 61 | cmd := exec.CommandContext(ctx, tool) 62 | cmd.Dir = dir 63 | cmd.Env = env 64 | cmd.Stdin = bytes.NewReader(req) 65 | cmd.Stdout = buf 66 | cmd.Stderr = new(bytes.Buffer) 67 | if err := cmd.Run(); err != nil { 68 | return nil, fmt.Errorf("%v: %v: %s", tool, err, cmd.Stderr) 69 | } 70 | var response struct { 71 | // Sizes, if not nil, is the types.Sizes to use when type checking. 72 | Sizes *types.StdSizes 73 | } 74 | if err := json.Unmarshal(buf.Bytes(), &response); err != nil { 75 | return nil, err 76 | } 77 | return response.Sizes, nil 78 | } 79 | 80 | func GetSizesGolist(ctx context.Context, buildFlags, env []string, dir string, usesExportData bool) (types.Sizes, error) { 81 | args := []string{"list", "-f", "{{context.GOARCH}} {{context.Compiler}}"} 82 | args = append(args, buildFlags...) 83 | args = append(args, "--", "unsafe") 84 | stdout, err := InvokeGo(ctx, env, dir, usesExportData, args...) 85 | var goarch, compiler string 86 | if err != nil { 87 | if strings.Contains(err.Error(), "cannot find main module") { 88 | // User's running outside of a module. All bets are off. Get GOARCH and guess compiler is gc. 89 | // TODO(matloob): Is this a problem in practice? 90 | envout, enverr := InvokeGo(ctx, env, dir, usesExportData, "env", "GOARCH") 91 | if enverr != nil { 92 | return nil, err 93 | } 94 | goarch = strings.TrimSpace(envout.String()) 95 | compiler = "gc" 96 | } else { 97 | return nil, err 98 | } 99 | } else { 100 | fields := strings.Fields(stdout.String()) 101 | if len(fields) < 2 { 102 | return nil, fmt.Errorf("could not determine GOARCH and Go compiler") 103 | } 104 | goarch = fields[0] 105 | compiler = fields[1] 106 | } 107 | return types.SizesFor(compiler, goarch), nil 108 | } 109 | 110 | // InvokeGo returns the stdout of a go command invocation. 111 | func InvokeGo(ctx context.Context, env []string, dir string, usesExportData bool, args ...string) (*bytes.Buffer, error) { 112 | if debug { 113 | defer func(start time.Time) { log.Printf("%s for %v", time.Since(start), cmdDebugStr(env, args...)) }(time.Now()) 114 | } 115 | stdout := new(bytes.Buffer) 116 | stderr := new(bytes.Buffer) 117 | cmd := exec.CommandContext(ctx, "go", args...) 118 | // On darwin the cwd gets resolved to the real path, which breaks anything that 119 | // expects the working directory to keep the original path, including the 120 | // go command when dealing with modules. 121 | // The Go stdlib has a special feature where if the cwd and the PWD are the 122 | // same node then it trusts the PWD, so by setting it in the env for the child 123 | // process we fix up all the paths returned by the go command. 124 | cmd.Env = append(append([]string{}, env...), "PWD="+dir) 125 | cmd.Dir = dir 126 | cmd.Stdout = stdout 127 | cmd.Stderr = stderr 128 | if err := cmd.Run(); err != nil { 129 | exitErr, ok := err.(*exec.ExitError) 130 | if !ok { 131 | // Catastrophic error: 132 | // - executable not found 133 | // - context cancellation 134 | return nil, fmt.Errorf("couldn't exec 'go %v': %s %T", args, err, err) 135 | } 136 | 137 | // Export mode entails a build. 138 | // If that build fails, errors appear on stderr 139 | // (despite the -e flag) and the Export field is blank. 140 | // Do not fail in that case. 141 | if !usesExportData { 142 | return nil, fmt.Errorf("go %v: %s: %s", args, exitErr, stderr) 143 | } 144 | } 145 | 146 | // As of writing, go list -export prints some non-fatal compilation 147 | // errors to stderr, even with -e set. We would prefer that it put 148 | // them in the Package.Error JSON (see https://golang.org/issue/26319). 149 | // In the meantime, there's nowhere good to put them, but they can 150 | // be useful for debugging. Print them if $GOPACKAGESPRINTGOLISTERRORS 151 | // is set. 152 | if len(stderr.Bytes()) != 0 && os.Getenv("GOPACKAGESPRINTGOLISTERRORS") != "" { 153 | fmt.Fprintf(os.Stderr, "%s stderr: <<%s>>\n", cmdDebugStr(env, args...), stderr) 154 | } 155 | 156 | // debugging 157 | if false { 158 | fmt.Fprintf(os.Stderr, "%s stdout: <<%s>>\n", cmdDebugStr(env, args...), stdout) 159 | } 160 | 161 | return stdout, nil 162 | } 163 | 164 | func cmdDebugStr(envlist []string, args ...string) string { 165 | env := make(map[string]string) 166 | for _, kv := range envlist { 167 | split := strings.Split(kv, "=") 168 | k, v := split[0], split[1] 169 | env[k] = v 170 | } 171 | 172 | return fmt.Sprintf("GOROOT=%v GOPATH=%v GO111MODULE=%v PWD=%v go %v", env["GOROOT"], env["GOPATH"], env["GO111MODULE"], env["PWD"], args) 173 | } 174 | -------------------------------------------------------------------------------- /subl3/syntax/GoSublime-Go.tmLanguage.json: -------------------------------------------------------------------------------- 1 | { 2 | "comment": "Based on work from github.com/frou/GoFeather and github.com/DisposaBoy/GoSublime", 3 | "fileTypes": [ 4 | "go" 5 | ], 6 | "firstLineMatch": "-[*]-( Mode:)? Go -[*]-", 7 | "keyEquivalent": "^~G", 8 | "name": "GoSublime: Go", 9 | "patterns": [ 10 | { 11 | "begin": "/\\*", 12 | "end": "\\*/", 13 | "name": "comment.block.go" 14 | }, 15 | { 16 | "begin": "//", 17 | "end": "\\z", 18 | "name": "comment.line.double-slash.go" 19 | }, 20 | { 21 | "begin": "\"", 22 | "beginCaptures": { 23 | "0": { 24 | "name": "punctuation.definition.string.begin.go" 25 | } 26 | }, 27 | "end": "\"", 28 | "endCaptures": { 29 | "0": { 30 | "name": "punctuation.definition.string.end.go" 31 | } 32 | }, 33 | "name": "string.quoted.double.go", 34 | "patterns": [ 35 | { 36 | "include": "#string_placeholder" 37 | }, 38 | { 39 | "include": "#string_escaped_char" 40 | } 41 | ] 42 | }, 43 | { 44 | "begin": "`", 45 | "beginCaptures": { 46 | "0": { 47 | "name": "punctuation.definition.string.begin.go" 48 | } 49 | }, 50 | "end": "`", 51 | "endCaptures": { 52 | "0": { 53 | "name": "punctuation.definition.string.end.go" 54 | } 55 | }, 56 | "name": "string.quoted.raw.go", 57 | "patterns": [ 58 | { 59 | "include": "#string_placeholder" 60 | }, 61 | { 62 | "include": "source.gotemplate" 63 | } 64 | ] 65 | }, 66 | { 67 | "match": "\\b(true|false|nil|iota)\\b", 68 | "name": "constant.language.go" 69 | }, 70 | { 71 | "match": "\\b((\\d+\\.(\\d+)?([eE][+-]?\\d+)?|\\d+[eE][+-]?\\d+|\\.\\d+([eE][+-]?\\d+)?)i?)\\b", 72 | "name": "constant.numeric.floating-point.go" 73 | }, 74 | { 75 | "match": "\\b(\\d+i|0[xX][0-9A-Fa-f]+|0[0-7]*|[1-9][0-9]*)\\b", 76 | "name": "constant.numeric.integer.go" 77 | }, 78 | { 79 | "name": "constant.other.rune.go", 80 | "match": "'(?:[^'\\\\]|\\\\(?:\\\\|[abfnrtv']|x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|U[0-9a-fA-F]{8}|[0-7]{3}))'" 81 | }, 82 | { 83 | "match": "\\b(bool|byte|complex(64|128)|error|float(32|64)|rune|string|u?int(8|16|32|64)?|uintptr)\\b", 84 | "name": "storage.type.go" 85 | }, 86 | { 87 | "comment": "A subset of keyword.other.go for flow control keywords.", 88 | "match": "\\b(break|case|continue|default|defer|else|for|go|goto|if|range|return|select|switch)\\b", 89 | "name": "keyword.control.go" 90 | }, 91 | { 92 | "match": "\\b(break|case|chan|const|continue|default|defer|else|fallthrough|for|func|go|goto|if|import|interface|map|package|range|return|select|struct|switch|type|var)\\b", 93 | "name": "keyword.other.go" 94 | }, 95 | { 96 | "captures": { 97 | "0": { 98 | "name": "variable.other.go" 99 | }, 100 | "1": { 101 | "name": "keyword.operator.initialize.go" 102 | } 103 | }, 104 | "comment": "This matches the 'x := 0' style of variable declaration.", 105 | "match": "(?:[[:alpha:]_][[:alnum:]_]*)(?:,\\s+[[:alpha:]_][[:alnum:]_]*)*\\s*(:=)", 106 | "name": "meta.initialization.short.go" 107 | }, 108 | { 109 | "match": "(?<=(\\Afunc|...\\))\\s)\\b(\\w+)\\b(?=\\()", 110 | "name": "entity.name.function.go" 111 | }, 112 | { 113 | "match": "(?<=(\\sfunc|....\\))\\s)\\b(\\w+)\\b(?=\\()", 114 | "name": "entity.name.function.go" 115 | }, 116 | { 117 | "match": "(?<=\\Atype\\s)\\b(\\w+)\\b", 118 | "name": "entity.name.type.go" 119 | }, 120 | { 121 | "match": "(?<=\\stype\\s)\\b(\\w+)\\b", 122 | "name": "entity.name.type.go" 123 | }, 124 | { 125 | "match": "\\b(append|cap|close|complex|copy|delete|imag|len|make|new|panic|print|println|real|recover)\\b", 126 | "name": "support.function.builtin.go" 127 | }, 128 | { 129 | "match": "\\b(\\w+)\\b(?=\\()", 130 | "name": "support.function.go" 131 | }, 132 | { 133 | "match": "(<-)", 134 | "name": "keyword.operator.channel.go" 135 | }, 136 | { 137 | "match": "(==|!=|<|<=|>|>=)", 138 | "name": "keyword.operator.comparison.go" 139 | }, 140 | { 141 | "match": "(&&|[|]{2}|!)", 142 | "name": "keyword.operator.logical.go" 143 | }, 144 | { 145 | "match": "([+]{2})", 146 | "name": "keyword.operator.increment.go" 147 | }, 148 | { 149 | "match": "(--)", 150 | "name": "keyword.decrement.go" 151 | }, 152 | { 153 | "match": "(=|(?:[+]|-|[|]|^|[*]|/|%|<<|>>|&|&^)=)", 154 | "name": "keyword.operator.assignment.go" 155 | }, 156 | { 157 | "match": "([+]|-|[*]|/|%|&|[|]|^|&^|<<|>>)", 158 | "name": "keyword.operator.arithmetic.go" 159 | }, 160 | { 161 | "match": "(;)", 162 | "name": "keyword.operator.semi-colon.go" 163 | }, 164 | { 165 | "match": "(,)", 166 | "name": "punctuation.definition.comma.go" 167 | }, 168 | { 169 | "match": "([.])", 170 | "name": "punctuation.definition.dot.go" 171 | }, 172 | { 173 | "match": "(:)", 174 | "name": "punctuation.definition.colon.go" 175 | }, 176 | { 177 | "match": "(\\[|\\]|{|}|\\(|\\))", 178 | "name": "punctuation.definition.bracket.go" 179 | } 180 | ], 181 | // note: keep this in sync with GoTemplate 182 | "repository": { 183 | "string_escaped_char": { 184 | "patterns": [ 185 | { 186 | // note: keep this in sync with constant.other.rune.go 187 | "match": "\\\\(\\\\|[abfnrtv'\"]|x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|U[0-9a-fA-F]{8}|[0-7]{3})", 188 | "name": "constant.character.escape.go" 189 | }, 190 | { 191 | "match": "\\\\.", 192 | "name": "invalid.illegal.unknown-escape.go" 193 | } 194 | ] 195 | }, 196 | "string_placeholder": { 197 | "patterns": [ 198 | { 199 | "match": "(?x)%\n (\\d+\\$)? # field (argument #)\n [#0\\- +']* # flags\n [,;:_]? # separator character (AltiVec)\n ((-?\\d+)|\\*(-?\\d+\\$)?)? # minimum field width\n (\\.((-?\\d+)|\\*(-?\\d+\\$)?)?)? # precision\n [diouxXDOUeEfFgGaAcCsSqpnvtTbyYhHmMzZ%] # conversion type\n ", 200 | "name": "constant.other.placeholder.go" 201 | } 202 | ] 203 | } 204 | }, 205 | "scopeName": "source.go", 206 | "uuid": "1caaa75c-b61d-11e2-ba93-138feb5db969" 207 | } 208 | -------------------------------------------------------------------------------- /vendor/golang.org/x/tools/internal/fastwalk/fastwalk.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // Package fastwalk provides a faster version of filepath.Walk for file system 6 | // scanning tools. 7 | package fastwalk 8 | 9 | import ( 10 | "errors" 11 | "os" 12 | "path/filepath" 13 | "runtime" 14 | "sync" 15 | ) 16 | 17 | // TraverseLink is used as a return value from WalkFuncs to indicate that the 18 | // symlink named in the call may be traversed. 19 | var TraverseLink = errors.New("fastwalk: traverse symlink, assuming target is a directory") 20 | 21 | // SkipFiles is a used as a return value from WalkFuncs to indicate that the 22 | // callback should not be called for any other files in the current directory. 23 | // Child directories will still be traversed. 24 | var SkipFiles = errors.New("fastwalk: skip remaining files in directory") 25 | 26 | // Walk is a faster implementation of filepath.Walk. 27 | // 28 | // filepath.Walk's design necessarily calls os.Lstat on each file, 29 | // even if the caller needs less info. 30 | // Many tools need only the type of each file. 31 | // On some platforms, this information is provided directly by the readdir 32 | // system call, avoiding the need to stat each file individually. 33 | // fastwalk_unix.go contains a fork of the syscall routines. 34 | // 35 | // See golang.org/issue/16399 36 | // 37 | // Walk walks the file tree rooted at root, calling walkFn for 38 | // each file or directory in the tree, including root. 39 | // 40 | // If fastWalk returns filepath.SkipDir, the directory is skipped. 41 | // 42 | // Unlike filepath.Walk: 43 | // * file stat calls must be done by the user. 44 | // The only provided metadata is the file type, which does not include 45 | // any permission bits. 46 | // * multiple goroutines stat the filesystem concurrently. The provided 47 | // walkFn must be safe for concurrent use. 48 | // * fastWalk can follow symlinks if walkFn returns the TraverseLink 49 | // sentinel error. It is the walkFn's responsibility to prevent 50 | // fastWalk from going into symlink cycles. 51 | func Walk(root string, walkFn func(path string, typ os.FileMode) error) error { 52 | // TODO(bradfitz): make numWorkers configurable? We used a 53 | // minimum of 4 to give the kernel more info about multiple 54 | // things we want, in hopes its I/O scheduling can take 55 | // advantage of that. Hopefully most are in cache. Maybe 4 is 56 | // even too low of a minimum. Profile more. 57 | numWorkers := 4 58 | if n := runtime.NumCPU(); n > numWorkers { 59 | numWorkers = n 60 | } 61 | 62 | // Make sure to wait for all workers to finish, otherwise 63 | // walkFn could still be called after returning. This Wait call 64 | // runs after close(e.donec) below. 65 | var wg sync.WaitGroup 66 | defer wg.Wait() 67 | 68 | w := &walker{ 69 | fn: walkFn, 70 | enqueuec: make(chan walkItem, numWorkers), // buffered for performance 71 | workc: make(chan walkItem, numWorkers), // buffered for performance 72 | donec: make(chan struct{}), 73 | 74 | // buffered for correctness & not leaking goroutines: 75 | resc: make(chan error, numWorkers), 76 | } 77 | defer close(w.donec) 78 | 79 | for i := 0; i < numWorkers; i++ { 80 | wg.Add(1) 81 | go w.doWork(&wg) 82 | } 83 | todo := []walkItem{{dir: root}} 84 | out := 0 85 | for { 86 | workc := w.workc 87 | var workItem walkItem 88 | if len(todo) == 0 { 89 | workc = nil 90 | } else { 91 | workItem = todo[len(todo)-1] 92 | } 93 | select { 94 | case workc <- workItem: 95 | todo = todo[:len(todo)-1] 96 | out++ 97 | case it := <-w.enqueuec: 98 | todo = append(todo, it) 99 | case err := <-w.resc: 100 | out-- 101 | if err != nil { 102 | return err 103 | } 104 | if out == 0 && len(todo) == 0 { 105 | // It's safe to quit here, as long as the buffered 106 | // enqueue channel isn't also readable, which might 107 | // happen if the worker sends both another unit of 108 | // work and its result before the other select was 109 | // scheduled and both w.resc and w.enqueuec were 110 | // readable. 111 | select { 112 | case it := <-w.enqueuec: 113 | todo = append(todo, it) 114 | default: 115 | return nil 116 | } 117 | } 118 | } 119 | } 120 | } 121 | 122 | // doWork reads directories as instructed (via workc) and runs the 123 | // user's callback function. 124 | func (w *walker) doWork(wg *sync.WaitGroup) { 125 | defer wg.Done() 126 | for { 127 | select { 128 | case <-w.donec: 129 | return 130 | case it := <-w.workc: 131 | select { 132 | case <-w.donec: 133 | return 134 | case w.resc <- w.walk(it.dir, !it.callbackDone): 135 | } 136 | } 137 | } 138 | } 139 | 140 | type walker struct { 141 | fn func(path string, typ os.FileMode) error 142 | 143 | donec chan struct{} // closed on fastWalk's return 144 | workc chan walkItem // to workers 145 | enqueuec chan walkItem // from workers 146 | resc chan error // from workers 147 | } 148 | 149 | type walkItem struct { 150 | dir string 151 | callbackDone bool // callback already called; don't do it again 152 | } 153 | 154 | func (w *walker) enqueue(it walkItem) { 155 | select { 156 | case w.enqueuec <- it: 157 | case <-w.donec: 158 | } 159 | } 160 | 161 | func (w *walker) onDirEnt(dirName, baseName string, typ os.FileMode) error { 162 | joined := dirName + string(os.PathSeparator) + baseName 163 | if typ == os.ModeDir { 164 | w.enqueue(walkItem{dir: joined}) 165 | return nil 166 | } 167 | 168 | err := w.fn(joined, typ) 169 | if typ == os.ModeSymlink { 170 | if err == TraverseLink { 171 | // Set callbackDone so we don't call it twice for both the 172 | // symlink-as-symlink and the symlink-as-directory later: 173 | w.enqueue(walkItem{dir: joined, callbackDone: true}) 174 | return nil 175 | } 176 | if err == filepath.SkipDir { 177 | // Permit SkipDir on symlinks too. 178 | return nil 179 | } 180 | } 181 | return err 182 | } 183 | 184 | func (w *walker) walk(root string, runUserCallback bool) error { 185 | if runUserCallback { 186 | err := w.fn(root, os.ModeDir) 187 | if err == filepath.SkipDir { 188 | return nil 189 | } 190 | if err != nil { 191 | return err 192 | } 193 | } 194 | 195 | return readDir(root, w.onDirEnt) 196 | } 197 | -------------------------------------------------------------------------------- /subl3/gocode.py: -------------------------------------------------------------------------------- 1 | import sublime, sublime_plugin, subprocess, difflib, threading 2 | 3 | # go to balanced pair, e.g.: 4 | # ((abc(def))) 5 | # ^ 6 | # \--------->^ 7 | # 8 | # returns -1 on failure 9 | def skip_to_balanced_pair(str, i, open, close): 10 | count = 1 11 | i += 1 12 | while i < len(str): 13 | if str[i] == open: 14 | count += 1 15 | elif str[i] == close: 16 | count -= 1 17 | 18 | if count == 0: 19 | break 20 | i += 1 21 | if i >= len(str): 22 | return -1 23 | return i 24 | 25 | # split balanced parens string using comma as separator 26 | # e.g.: "ab, (1, 2), cd" -> ["ab", "(1, 2)", "cd"] 27 | # filters out empty strings 28 | def split_balanced(s): 29 | out = [] 30 | i = 0 31 | beg = 0 32 | while i < len(s): 33 | if s[i] == ',': 34 | out.append(s[beg:i].strip()) 35 | beg = i+1 36 | i += 1 37 | elif s[i] == '(': 38 | i = skip_to_balanced_pair(s, i, "(", ")") 39 | if i == -1: 40 | i = len(s) 41 | else: 42 | i += 1 43 | 44 | out.append(s[beg:i].strip()) 45 | return list(filter(bool, out)) 46 | 47 | 48 | def extract_arguments_and_returns(sig): 49 | sig = sig.strip() 50 | if not sig.startswith("func"): 51 | return [], [] 52 | 53 | # find first pair of parens, these are arguments 54 | beg = sig.find("(") 55 | if beg == -1: 56 | return [], [] 57 | end = skip_to_balanced_pair(sig, beg, "(", ")") 58 | if end == -1: 59 | return [], [] 60 | args = split_balanced(sig[beg+1:end]) 61 | 62 | # find the rest of the string, these are returns 63 | sig = sig[end+1:].strip() 64 | sig = sig[1:-1] if sig.startswith("(") and sig.endswith(")") else sig 65 | returns = split_balanced(sig) 66 | 67 | return args, returns 68 | 69 | # takes gocode's candidate and returns sublime's hint and subj 70 | def hint_and_subj(cls, name, type): 71 | subj = name 72 | if cls == "func": 73 | hint = cls + " " + name 74 | args, returns = extract_arguments_and_returns(type) 75 | if returns: 76 | hint += "\t" + ", ".join(returns) 77 | if args: 78 | sargs = [] 79 | for i, a in enumerate(args): 80 | ea = a.replace("{", "\\{").replace("}", "\\}") 81 | sargs.append("${{{0}:{1}}}".format(i+1, ea)) 82 | subj += "(" + ", ".join(sargs) + ")" 83 | else: 84 | subj += "()" 85 | else: 86 | hint = cls + " " + name + "\t" + type 87 | return hint, subj 88 | 89 | def diff_sanity_check(a, b): 90 | if a != b: 91 | raise Exception("diff sanity check mismatch\n-%s\n+%s" % (a, b)) 92 | 93 | class GocodeGofmtCommand(sublime_plugin.TextCommand): 94 | def run(self, edit): 95 | view = self.view 96 | src = view.substr(sublime.Region(0, view.size())) 97 | gofmt = subprocess.Popen(["gofmt"], 98 | stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) 99 | sout, serr = gofmt.communicate(src.encode()) 100 | if gofmt.returncode != 0: 101 | print(serr.decode(), end="") 102 | return 103 | 104 | newsrc = sout.decode() 105 | diff = difflib.ndiff(src.splitlines(), newsrc.splitlines()) 106 | i = 0 107 | for line in diff: 108 | if line.startswith("?"): # skip hint lines 109 | continue 110 | 111 | l = (len(line)-2)+1 112 | if line.startswith("-"): 113 | diff_sanity_check(view.substr(sublime.Region(i, i+l-1)), line[2:]) 114 | view.erase(edit, sublime.Region(i, i+l)) 115 | elif line.startswith("+"): 116 | view.insert(edit, i, line[2:]+"\n") 117 | i += l 118 | else: 119 | diff_sanity_check(view.substr(sublime.Region(i, i+l-1)), line[2:]) 120 | i += l 121 | 122 | class Gocode(sublime_plugin.EventListener): 123 | """Sublime Text gocode integration.""" 124 | 125 | def __init__(self): 126 | self.completions = None 127 | 128 | def fetch_query_completions(self, view, prefix, location): 129 | """Fetches the query completions of for the given location 130 | 131 | Execute gocode and parse the returned csv. Once the results are generated 132 | are the results in as a list stored in `completions`. Once stored is the query completions 133 | window opened (forced). 134 | 135 | :param view: currently active sublime view 136 | :type view: sublime.View 137 | :param prefix: string for completions 138 | :type prefix: basestring 139 | :param locations: offset from beginning 140 | :type locations: int 141 | """ 142 | 143 | self._location = location 144 | 145 | src = view.substr(sublime.Region(0, view.size())) 146 | filename = view.file_name() 147 | cloc = "c{0}".format(location) 148 | gocode = subprocess.Popen(["gocode", "-f=csv", "autocomplete", filename, cloc], stdin=subprocess.PIPE, stdout=subprocess.PIPE) 149 | 150 | out = gocode.communicate(src.encode())[0].decode() 151 | results = self.generate_completions(out) 152 | 153 | # Exit conditions: 154 | if len(results) == 0: 155 | return 156 | 157 | self.completions = results 158 | self.open_query_completions(view) 159 | 160 | def generate_completions(self, out): 161 | """ Parses the returned gocode results and generates a usable autocomplete list """ 162 | 163 | results = [] 164 | for line in filter(bool, out.split("\n")): 165 | arg = line.split(",,") 166 | hint, subj = hint_and_subj(arg[0], arg[1], arg[2]) 167 | results.append([hint, subj]) 168 | 169 | return results 170 | 171 | def open_query_completions(self, view): 172 | """Opens (forced) the sublime autocomplete window""" 173 | 174 | view.run_command("hide_auto_complete") 175 | view.run_command("auto_complete", { 176 | "disable_auto_insert": True, 177 | "next_completion_if_showing": False, 178 | "auto_complete_commit_on_tab": True, 179 | }) 180 | 181 | def on_query_completions(self, view, prefix, locations): 182 | """Sublime autocomplete event handler. 183 | 184 | Get completions depends on current cursor position and return 185 | them as list of ('possible completion', 'completion type') 186 | 187 | :param view: currently active sublime view 188 | :type view: sublime.View 189 | :param prefix: string for completions 190 | :type prefix: basestring 191 | :param locations: offset from beginning 192 | :type locations: int 193 | 194 | :return: list of tuple(str, str) 195 | """ 196 | location = locations[0] 197 | 198 | if not view.match_selector(location, "source.go"): 199 | return 200 | 201 | if self.completions: 202 | completions = self.completions 203 | self.completions = None 204 | return completions 205 | 206 | thread = threading.Thread(target=self.fetch_query_completions, args=(view, prefix, location)) 207 | thread.start() 208 | 209 | def on_pre_save(self, view): 210 | if not view.match_selector(0, "source.go"): 211 | return 212 | view.run_command('gocode_gofmt') 213 | --------------------------------------------------------------------------------