func (m *mGocodeComplete) Call() (interface{}, string) {
	e := ""
	res := M{}

	if m.Src == "" {
		// this is here for testing, the client should always send the src
		s, _ := ioutil.ReadFile(m.Fn)
		m.Src = string(s)
	}

	if m.Src == "" {
		return res, "No source"
	}

	pos := 0
	for i, _ := range m.Src {
		pos += 1
		if pos > m.Pos {
			pos = i
			break
		}
	}

	src := []byte(m.Src)
	fn := m.Fn
	if !filepath.IsAbs(fn) {
		fn = filepath.Join(orString(m.Dir, m.Home), orString(fn, "_.go"))
	}

	mGocodeVars.lck.Lock()
	defer mGocodeVars.lck.Unlock()

	builtins := "false"
	if m.Builtins {
		builtins = "true"
	}
	if mGocodeVars.lastBuiltins != builtins {
		gocode.GoSublimeGocodeSet("propose-builtins", builtins)
	}

	gopath := orString(m.Env["GOPATH"], os.Getenv("GOPATH"))
	if gopath != mGocodeVars.lastGopath {
		p := []string{}
		osArch := runtime.GOOS + "_" + runtime.GOARCH
		for _, s := range filepath.SplitList(gopath) {
			p = append(p, filepath.Join(s, "pkg", osArch))
		}
		libpath := strings.Join(p, string(filepath.ListSeparator))
		gocode.GoSublimeGocodeSet("lib-path", libpath)
		mGocodeVars.lastGopath = gopath
	}

	if m.calltip {
		res["calltips"] = completeCalltip(src, fn, pos)
	} else {
		res["completions"] = gocode.GoSublimeGocodeComplete(src, fn, pos)
	}

	return res, e
}
func completeCalltip(src []byte, fn string, offset int) []gocode.GoSublimeGocodeCandidate {
	fset := token.NewFileSet()
	af, _ := parser.ParseFile(fset, fn, src, 0)

	if af != nil {
		vis := &calltipVisitor{
			offset: offset,
			fset:   fset,
		}
		ast.Walk(vis, af)

		if vis.x != nil {
			var id *ast.Ident

			switch v := vis.x.Fun.(type) {
			case *ast.Ident:
				id = v
			case *ast.SelectorExpr:
				id = v.Sel
			}

			if id != nil && id.End().IsValid() {
				line := offsetLine(fset, af, offset)
				cp := fset.Position(id.End())
				cr := cp.Offset
				cl := gocode.GoSublimeGocodeComplete(src, fn, cr)

				if (cp.Line == line || line == 0) && len(cl) > 0 {
					for i, c := range cl {
						if strings.EqualFold(id.Name, c.Name) {
							return cl[i : i+1]
						}
					}
				}
			}
		}
	}

	return []gocode.GoSublimeGocodeCandidate{}
}