vim-go: import "/Users/felix/code/go/src/github.com/some/project/mypkg": cannot import absolute path
guru: no initial packages were loaded
See actual behavior. I suspect the problem is https://github.com/fatih/vim-go/blob/master/autoload/go/guru.vim#L11 resolving the pkg name to an absolute path, rather than a relative one.
$ go version
go version go1.6.3 darwin/amd64
$ uname -a
Darwin Felix-MBP-2012.local 15.6.0 Darwin Kernel Version 15.6.0: Thu Jun 23 18:25:34 PDT 2016; root:xnu-3248.60.10~1/RELEASE_X86_64 x86_64
$ sw_vers -productVersion
10.11.6
$ cd ~/.vim/bundle/vim-go && git rev-parse HEAD
8575d9e3c9e23508f9b7d0c3992cb683b1e47ae6
$ vim --version
VIM - Vi IMproved 7.4 (2013 Aug 10, compiled Aug 29 2016 12:51:13)
MacOS X (unix) version
Included patches: 1-2290
Compiled by Homebrew
Huge version without GUI. Features included (+) or not (-):
+acl +file_in_path +mouse_sgr +tag_old_static
+arabic +find_in_path -mouse_sysmouse -tag_any_white
+autocmd +float +mouse_urxvt -tcl
-balloon_eval +folding +mouse_xterm +termguicolors
-browse -footer +multi_byte +terminfo
++builtin_terms +fork() +multi_lang +termresponse
+byte_offset -gettext -mzscheme +textobjects
+channel -hangul_input +netbeans_intg +timers
+cindent +iconv +num64 +title
-clientserver +insert_expand +packages -toolbar
+clipboard +job +path_extra +user_commands
+cmdline_compl +jumplist +perl +vertsplit
+cmdline_hist +keymap +persistent_undo +virtualedit
+cmdline_info +lambda +postscript +visual
+comments +langmap +printer +visualextra
+conceal +libcall +profile +viminfo
+cryptv +linebreak +python +vreplace
+cscope +lispindent -python3 +wildignore
+cursorbind +listcmds +quickfix +wildmenu
+cursorshape +localmap +reltime +windows
+dialog_con -lua +rightleft +writebackup
+diff +menu +ruby -X11
+digraphs +mksession +scrollbind -xfontset
-dnd +modify_fname +signs -xim
-ebcdic +mouse +smartindent -xpm
+emacs_tags -mouseshape +startuptime -xsmp
+eval +mouse_dec +statusline -xterm_clipboard
+ex_extra -mouse_gpm -sun_workshop -xterm_save
+extra_search -mouse_jsbterm +syntax
+farsi +mouse_netterm +tag_binary
system vimrc file: "$VIM/vimrc"
user vimrc file: "$HOME/.vimrc"
2nd user vimrc file: "~/.vim/vimrc"
user exrc file: "$HOME/.exrc"
defaults file: "$VIMRUNTIME/defaults.vim"
fall-back for $VIM: "/usr/local/share/vim"
Compilation: clang -c -I. -Iproto -DHAVE_CONFIG_H -DMACOS_X_UNIX -g -O2 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=1
Linking: clang -L. -fstack-protector -L/usr/local/lib -L/usr/local/opt/libyaml/lib -L/usr/local/opt/openssl/lib -L/usr/local/opt/readline/lib -L/usr/local/lib -o vim -lncurses -liconv -framework Cocoa -mmacosx-version-min=10.11 -fstack-protector-strong -L/usr/local/lib -L/usr/local/Cellar/perl/5.24.0_1/lib/perl5/5.24.0/darwin-thread-multi-2level/CORE -lperl -lm -lutil -lc -F/usr/local/Cellar/python/2.7.12/Frameworks -framework Python -lruby.2.3.0 -lobjc -L/usr/local/Cellar/ruby/2.3.1/lib
Thanks for looking into this!
Hi @felixge
Can you please provide a source code I can test? Because locally it works for me. Please give something I can try step by step. Thanks.
Sure.
$ cat /Users/felix/code/go/src/github.com/felixge/vim-go-test/main.go
package main
func main() {
bar()
}
func bar() {
}
I place my cursor over the word 'bar' on line 7, type ':GoCallers' and see this error:
vim-go: import "/Users/felix/code/go/src/github.com/felixge/vim-go-test": cannot import absolute path
guru: no initial packages were loaded
Come to think of it, perhaps the issue is related to my GOPATH containing multiple go paths (due to using gvm)
$ echo $GOPATH
/Users/felix/code/go:/Users/felix/.gvm/pkgsets/go1.6.3/global
Yeah, if I change my GOPATH to have only one path, the example I provided seems to work.
But for my actual project I'm now getting this error:
vim-go: guru: analysis scope has no main and no tests
Let me know if you have any ideas.
Unfortunately I can't share the code of the project.
Okay, I think I figured out the new problem.
By default, guru uses the scope: github.com/felixge/myproject. However, I'm working inside pkg foo within my project. So I think the scope should default to github.com/felixge/myproject/... instead. Manually setting :GoGuruScope github.com/felixge/myproject/... fixes the problem.
Let me know if that makes sense.
That's great to know. That's how Guru works. But vim-go tries to be helpful by choosing a simple scope so these commands work. Otherwise I receive a lot of complaints and issues that the command doesn't work.
That's great to know. That's how Guru works. But vim-go tries to be helpful by choosing a simple scope so these commands work. Otherwise I receive a lot of complaints and issues that the command doesn't work.
Does this default really work well for people? I'd assume a lot of people want to use :GoCallers within sub pkgs?
That being said, I don't mind if the default stays as is. But maybe it would be possible to have an option that allows the behavior I suggested above?
The option is :GoGuruScope. People already have an option, but nobody reads the manual (http://golang.org/s/using-guru) so they end up with this issue. The default is just the current package. It's good enough in most cases, for other cases everyone should use :GoGuruScope
Look at the scope section:
Pointer analysis scope: some queries involve pointer analysis, a technique for
answering questions of the form “what might this pointer point to?”. It is
usually too expensive to run pointer analysis over all the packages in the
workspace, so these queries require an additional configuration parameter
called the scope, which determines the set of packages to analyze. Set the
scope to the application (or set of applications---a client and server,
perhaps) on which you are currently working. Pointer analysis is a
whole-program analysis, so the only packages in the scope that matter are the
main and test packages.
The scope is typically specified as a comma-separated set of packages, or
wildcarded subtrees like github.com/my/dir/...; consult the specific
documentation for your editor to find out how to set and vary the scope.
I understand how :GoGuruScope works, but how do I use it to accomplish my goal?
I don't want to hard code my project pkg in my .vimrc. I just want to append '/...' to the default guru scope.
@felixge you set the scope and then use :GoCallers. Isn't something clear here? Do you mean you shouldn't set the scope? I didn't understand your problem.
@fatih I don't want to modify the scope manually every time I need to use :GoCallers.
Adding this to my .vimrc seems to do the trick:
au FileType go silent exe "GoGuruScope " . go#package#ImportPath(expand('%:p:h')) . "..."
But IMO it's quite hacky.
Anyway, do you see what I'm trying to accomplish now?
Oh ok, so you mean we should change the current default in vim-go from current_package to current_package/... ?
Otherwise I know it's cumbersome to change it everytime.
Yes! Exactly :). If that makes sense, I propose to:
I am also having the same issue, though adding the line for GoGuruScope in my .vimrc file doesn't seem to fix it. Is there any other workarounds other than having to change my GOPATH?
Thanks
@smousa you might also need to change your build tags with :GoBuildTags or let g:go_build_tags = "yourtag" (and even then, you may have to correct some errors in a project that builds just fine: guru is more sensitive to unread variables than go build, for example).
Actually just setting the guru scope to current_package/... may lead to undesired behaviour especially with vendored dependencies (inside a vendor directory). Example: My project is github.com/justsocialapps/kafkabeat and all its deps are in the vendor directory so I set GoGuruScope to github.com/justsocialapps/kafkabeat/.... Then issuing GoCallers on a function inside one of my deps led to a complete lock-up of my computer for some minutes.
Just for a reference and for someone that has found this issue with hope of solution:
I have managed to add bits and pieces and (re)create this
" from https://gist.github.com/tyru/984296
" Substitute a:from => a:to by string.
" To substitute by pattern, use substitute() instead.
function! s:substring(str, from, to)
if a:str ==# '' || a:from ==# ''
return a:str
endif
let str = a:str
let idx = stridx(str, a:from)
while idx !=# -1
let left = idx ==# 0 ? '' : str[: idx - 1]
let right = str[idx + strlen(a:from) :]
let str = left . a:to . right
let idx = stridx(str, a:from)
endwhile
return str
endfunction
function! s:chomp(string)
return substitute(a:string, '\n\+$', '', '')
endfunction
function! s:go_guru_scope_from_git_root()
" chomp because get rev-parse returns line with newline at the end
return s:chomp(s:substring(system("git rev-parse --show-toplevel"),$GOPATH . "/src/","")) . "/..."
endfunction
au FileType go silent exe "GoGuruScope " . s:go_guru_scope_from_git_root()
which produces import path from current git repo's import path and sets it with GoGuruScope
So if you happen to be in $GOPATH/src/github.com/USER/PROJECT/DIRA/DIRB/ and open a .go file you will get go_guru_scope == github.com/USER/PROJECT/...
I found it useful, maybe someone else will as well.
@pmalek that script was amazingly helpful
FWIW I found it useful to use go#util#gopath() rather than $GOPATH (if GOPATH is unset then go#util#gopath() will use a default), or alternatively system(go env GOPATH) would also work. I also find it useful to ignore vendor
I did a bit of vimscript golfing as well:
function! s:go_guru_scope_from_git_root()
let gitroot = system("git rev-parse --show-toplevel | tr -d '\n'")
let pattern = escape(go#util#gopath() . "/src/", '\ /')
return substitute(gitroot, pattern, "", "") . "/... -vendor/"
endfunction
au FileType go silent exe "GoGuruScope " . s:go_guru_scope_from_git_root()
Most helpful comment
The option is
:GoGuruScope. People already have an option, but nobody reads the manual (http://golang.org/s/using-guru) so they end up with this issue. The default is just the current package. It's good enough in most cases, for other cases everyone should use:GoGuruScope