From 82f7521ab2b6074e7eb22dd5726db621d9165c45 Mon Sep 17 00:00:00 2001 From: Fatih Arslan Date: Thu, 26 Nov 2015 00:54:29 +0200 Subject: [PATCH 1/6] Add list.vim, location list based functions --- autoload/go/list.vim | 47 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 autoload/go/list.vim diff --git a/autoload/go/list.vim b/autoload/go/list.vim new file mode 100644 index 0000000000..a3afa107c9 --- /dev/null +++ b/autoload/go/list.vim @@ -0,0 +1,47 @@ +" Window opens the location list with the given height up to 10 lines maximum. +" Otherwise g:go_location_height is used. If no or zero height is given it +" closes the window +function! go#list#Window(...) + " we don't use lwindow to close the location list as we need also the + " ability to resize the window. So, we are going to use lopen and cclose + " for a better user experience. If the number of errors in a current + " location list increases/decreases, cwindow will not resize when a new + " updated height is passed. lopen in the other hand resizes the screen. + if !a:0 || a:1 == 0 + lclose + return + endif + + let height = get(g:, "go_location_height", 0) + if height == 0 + " prevent creating a large location height for a large set of numbers + if a:1 > 10 + let height = 10 + else + let height = a:1 + endif + endif + + exe 'lopen '. height +endfunction + + +" Get returns the current list of items from the location list +function! go#list#Get() + return getloclist(0) +endfunction + +" Populate populate the location list with the given items +function! go#list#Populate(items) + call setloclist(0, a:items, 'r') +endfunction + +" JumpToFirst jumps to the first item in the location list +function! go#list#JumpToFirst() + ll 1 +endfunction + +" Clean cleans the location list +function! go#list#Clean() + lex [] +endfunction From 8d2b81e50d6daf43f097779dd5eb4f1faf27c225 Mon Sep 17 00:00:00 2001 From: Fatih Arslan Date: Thu, 26 Nov 2015 00:54:50 +0200 Subject: [PATCH 2/6] util: remove old wrapper --- autoload/go/util.vim | 30 ------------------------------ 1 file changed, 30 deletions(-) diff --git a/autoload/go/util.vim b/autoload/go/util.vim index 3997b422ae..ce34d15e0c 100644 --- a/autoload/go/util.vim +++ b/autoload/go/util.vim @@ -57,33 +57,3 @@ function! go#util#Shelljoin(arglist, ...) return join(map(copy(a:arglist), 'shellescape(v:val)'), ' ') endif endfunction - - -" Cwindow opens the quickfix window with the given height up to 10 lines -" maximum. Otherwise g:go_quickfix_height is used. If no or zero height is -" given it closes the window -function! go#util#Cwindow(...) - " we don't use cwindow to close the quickfix window as we need also the - " ability to resize the window. So, we are going to use copen and cclose - " for a better user experience. If the number of errors in a current - " quickfix list increases/decreases, cwindow will not resize when a new - " updated height is passed. copen in the other hand resizes the screen. - if !a:0 || a:1 == 0 - cclose - return - endif - - let height = get(g:, "go_quickfix_height", 0) - if height == 0 - " prevent creating a large quickfix height for a large set of numbers - if a:1 > 10 - let height = 10 - else - let height = a:1 - endif - endif - - exe 'copen '. height -endfunction - -" vim:ts=4:sw=4:et From d073ea11266939a5806b468a8ad704f5a75b31d3 Mon Sep 17 00:00:00 2001 From: Fatih Arslan Date: Thu, 26 Nov 2015 01:02:27 +0200 Subject: [PATCH 3/6] cmd: make :GoBuild, :GoRun and :GoList use llist --- autoload/go/cmd.vim | 39 ++++++++++++++++++++------------------- autoload/go/tool.vim | 29 ++++++++++++++++++----------- 2 files changed, 38 insertions(+), 30 deletions(-) diff --git a/autoload/go/cmd.vim b/autoload/go/cmd.vim index 3720598c70..1b5b60f91f 100644 --- a/autoload/go/cmd.vim +++ b/autoload/go/cmd.vim @@ -34,17 +34,17 @@ function! go#cmd#Build(bang, ...) if g:go_dispatch_enabled && exists(':Make') == 2 silent! exe 'Make' else - silent! exe 'make!' + silent! exe 'lmake!' endif redraw! - let errors = getqflist() - call go#util#Cwindow(len(errors)) + let errors = go#list#Get() + call go#list#Window(len(errors)) if !empty(errors) if !a:bang - cc 1 "jump to first error if there is any + call go#list#JumpToFirst() endif else redraws! | echon "vim-go: " | echohl Function | echon "[build] SUCCESS"| echohl None @@ -87,16 +87,17 @@ function! go#cmd#Run(bang, ...) if g:go_dispatch_enabled && exists(':Make') == 2 silent! exe 'Make' else - exe 'make!' + exe 'lmake!' endif - " Remove any nonvalid filename from the qflist to avoid opening an empty - " buffer. See https://github.com/fatih/vim-go/issues/287 for details. - let qflist = getqflist() + " Remove any nonvalid filename from the location list to avoid opening an + " empty buffer. See https://github.com/fatih/vim-go/issues/287 for + " details. + let items = go#list#Get() let errors = [] let is_readable = {} - for item in qflist + for item in items let filename = bufname(item.bufnr) if !has_key(is_readable, filename) let is_readable[filename] = filereadable(filename) @@ -111,11 +112,10 @@ function! go#cmd#Run(bang, ...) echohl Identifier | echon " from QuickFix list (nonvalid filename)" | echohl None endfor - call go#util#Cwindow(len(errors)) - - call setqflist(errors) + call go#list#Populate(errors) + call go#list#Window(len(errors)) if !empty(errors) && !a:bang - cc 1 "jump to first error if there is any + call go#list#JumpToFirst() endif let $GOPATH = old_gopath @@ -130,16 +130,17 @@ function! go#cmd#Install(bang, ...) call go#cmd#autowrite() let out = go#tool#ExecuteInDir(command) if v:shell_error - call go#tool#ShowErrors(out) - let errors = getqflist() - call go#util#Cwindow(len(errors)) + let errors = go#tool#ParseErrors(split(out, '\n')) + + call go#list#Populate(errors) + call go#list#Window(len(errors)) if !empty(errors) && !a:bang - cc 1 "jump to first error if there is any + call go#list#JumpToFirst() endif return else - call setqflist([]) - call go#util#Cwindow() + call go#list#Clean() + call go#list#Window() endif echon "vim-go: " | echohl Function | echon "installed to ". $GOPATH | echohl None diff --git a/autoload/go/tool.vim b/autoload/go/tool.vim index 64bc026744..788a91cd44 100644 --- a/autoload/go/tool.vim +++ b/autoload/go/tool.vim @@ -40,19 +40,10 @@ function! go#tool#Imports() return imports endfunction -function! go#tool#ShowErrors(out) - " cd into the current files directory. This is important so fnamemodify - " does create a full path for outputs when the token is only a single file - " name (such as for a go test output, i.e.: 'demo_test.go'). For other - " outputs, such as 'go install' we already get an absolute path (i.e.: - " '../foo/foo.go') and fnamemodify successfuly creates the full path. - let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd ' : 'cd ' - let current_dir = getcwd() - execute cd . fnameescape(expand("%:p:h")) - +function! go#tool#ParseErrors(lines) let errors = [] - for line in split(a:out, '\n') + for line in a:lines let fatalerrors = matchlist(line, '^\(fatal error:.*\)$') let tokens = matchlist(line, '^\s*\(.\{-}\):\(\d\+\):\s*\(.*\)') @@ -71,6 +62,22 @@ function! go#tool#ShowErrors(out) endif endfor + return errors +endfunction + + +function! go#tool#ShowErrors(out) + " cd into the current files directory. This is important so fnamemodify + " does create a full path for outputs when the token is only a single file + " name (such as for a go test output, i.e.: 'demo_test.go'). For other + " outputs, such as 'go install' we already get an absolute path (i.e.: + " '../foo/foo.go') and fnamemodify successfuly creates the full path. + let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd ' : 'cd ' + let current_dir = getcwd() + execute cd . fnameescape(expand("%:p:h")) + + let errors = go#tool#ParseErrors(split(a:out, '\n')) + " return back to old dir once we are finished with populating the errors execute cd . fnameescape(current_dir) From 0ee6e9135c93bb8b0e5dbbf81c8327ba11d1b3e4 Mon Sep 17 00:00:00 2001 From: Fatih Arslan Date: Thu, 26 Nov 2015 18:13:35 +0200 Subject: [PATCH 4/6] list: convert more commands to list.vim --- autoload/go/cmd.vim | 41 ++++++++++++------------- autoload/go/lint.vim | 71 ++++++++++++++++++++------------------------ autoload/go/list.vim | 20 +++++++++++++ 3 files changed, 74 insertions(+), 58 deletions(-) diff --git a/autoload/go/cmd.vim b/autoload/go/cmd.vim index 1b5b60f91f..e1271292c8 100644 --- a/autoload/go/cmd.vim +++ b/autoload/go/cmd.vim @@ -117,7 +117,7 @@ function! go#cmd#Run(bang, ...) if !empty(errors) && !a:bang call go#list#JumpToFirst() endif - + let $GOPATH = old_gopath let &makeprg = default_makeprg endfunction @@ -131,7 +131,6 @@ function! go#cmd#Install(bang, ...) let out = go#tool#ExecuteInDir(command) if v:shell_error let errors = go#tool#ParseErrors(split(out, '\n')) - call go#list#Populate(errors) call go#list#Window(len(errors)) if !empty(errors) && !a:bang @@ -176,16 +175,16 @@ function! go#cmd#Test(bang, compile, ...) redraw let out = go#tool#ExecuteInDir(command) if v:shell_error - call go#tool#ShowErrors(out) - let errors = getqflist() - call go#util#Cwindow(len(errors)) + let errors = go#tool#ParseErrors(split(out, '\n')) + call go#list#Populate(errors) + call go#list#Window(len(errors)) if !empty(errors) && !a:bang - cc 1 "jump to first error if there is any + call go#list#JumpToFirst() endif echon "vim-go: " | echohl ErrorMsg | echon "[test] FAIL" | echohl None else - call setqflist([]) - call go#util#Cwindow() + call go#list#Clean() + call go#list#Window() if a:compile echon "vim-go: " | echohl Function | echon "[test] SUCCESS" | echohl None @@ -234,19 +233,21 @@ function! go#cmd#Coverage(bang, ...) call go#cmd#autowrite() let out = go#tool#ExecuteInDir(command) if v:shell_error - call go#tool#ShowErrors(out) + let errors = go#tool#ParseErrors(split(out, '\n')) + call go#list#Populate(errors) + call go#list#Window(len(errors)) + if !empty(errors) && !a:bang + call go#list#JumpToFirst() + endif else - " clear previous quick fix window - call setqflist([]) + " clear previous location list + call go#list#Clean() + call go#list#Window() let openHTML = 'go tool cover -html='.l:tmpname call go#tool#ExecuteInDir(openHTML) endif - let errors = getqflist() - call go#util#Cwindow(len(errors)) - if !empty(errors) && !a:bang - cc 1 "jump to first error if there is any - endif + call delete(l:tmpname) endfunction @@ -270,15 +271,15 @@ function! go#cmd#Generate(bang, ...) if g:go_dispatch_enabled && exists(':Make') == 2 silent! exe 'Make' else - silent! exe 'make!' + silent! exe 'lmake!' endif redraw! - let errors = getqflist() - call go#util#Cwindow(len(errors)) + let errors = go#list#Get() + call go#list#Window(len(errors)) if !empty(errors) if !a:bang - cc 1 "jump to first error if there is any + call go#list#JumpToFirst() endif else redraws! | echon "vim-go: " | echohl Function | echon "[generate] SUCCESS"| echohl None diff --git a/autoload/go/lint.vim b/autoload/go/lint.vim index a65acbddc4..64c8ca8862 100644 --- a/autoload/go/lint.vim +++ b/autoload/go/lint.vim @@ -58,30 +58,27 @@ function! go#lint#Gometa(...) abort if v:shell_error == 0 redraw | echo - call setqflist([]) + call go#list#Clean() + call go#list#Window() echon "vim-go: " | echohl Function | echon "[metalinter] PASS" | echohl None - call go#util#Cwindow() else - " backup users errorformat, will be restored once we are finished - let old_errorformat = &errorformat - - " GoMetaLinter can output one of the two, so we look for both of them + " GoMetaLinter can output one of the two, so we look for both: " ::[]: () " ::: () - let &errorformat = "%f:%l:%c:%t%*[^:]:\ %m,%f:%l::%t%*[^:]:\ %m" + " This can be defined by the following errorformat: + let errformat = "%f:%l:%c:%t%*[^:]:\ %m,%f:%l::%t%*[^:]:\ %m" - " create the quickfix list and open it - cgetexpr split(out, "\n") - let errors = getqflist() - call go#util#Cwindow(len(errors)) - cc 1 + " Parse and populate our location list + call go#list#ParseFormat(errformat, split(out, "\n")) - let &errorformat = old_errorformat + let errors = go#list#Get() + call go#list#Window(len(errors)) + call go#list#JumpToFirst() endif endfunction " Golint calls 'golint' on the current directory. Any warnings are populated in -" the quickfix window +" the location list function! go#lint#Golint(...) abort let bin_path = go#path#CheckBinPath(g:go_golint_bin) if empty(bin_path) @@ -100,14 +97,14 @@ function! go#lint#Golint(...) abort return endif - cgetexpr out - let errors = getqflist() - call go#util#Cwindow(len(errors)) - cc 1 + call go#list#Parse(out) + let errors = go#list#Get() + call go#list#Window(len(errors)) + call go#list#JumpToFirst() endfunction " Vet calls 'go vet' on the current directory. Any warnings are populated in -" the quickfix window +" the location list function! go#lint#Vet(bang, ...) call go#cmd#autowrite() echon "vim-go: " | echohl Identifier | echon "calling vet..." | echohl None @@ -117,25 +114,22 @@ function! go#lint#Vet(bang, ...) let out = go#tool#ExecuteInDir('go tool vet ' . go#util#Shelljoin(a:000)) endif if v:shell_error - call go#tool#ShowErrors(out) - else - call setqflist([]) - endif - - let errors = getqflist() - call go#util#Cwindow(len(errors)) - if !empty(errors) - if !a:bang - cc 1 "jump to first error if there is any + let errors = go#tool#ParseErrors(split(out, '\n')) + call go#list#Populate(errors) + call go#list#Window(len(errors)) + if !empty(errors) && !a:bang + call go#list#JumpToFirst() endif + echon "vim-go: " | echohl ErrorMsg | echon "[vet] FAIL" | echohl None else - call go#util#Cwindow() + call go#list#Clean() + call go#list#Window() redraw | echon "vim-go: " | echohl Function | echon "[vet] PASS" | echohl None endif endfunction " ErrCheck calls 'errcheck' for the given packages. Any warnings are populated in -" the quickfix window. +" the location list function! go#lint#Errcheck(...) abort if a:0 == 0 let goargs = go#package#ImportPath(expand('%:p:h')) @@ -174,18 +168,19 @@ function! go#lint#Errcheck(...) abort if empty(errors) echohl Error | echomsg "GoErrCheck returned error" | echohl None echo out + return endif if !empty(errors) - redraw | echo - call setqflist(errors, 'r') - call go#util#Cwindow(len(errors)) - cc 1 "jump to first error if there is any + call go#list#Populate(errors) + call go#list#Window(len(errors)) + if !empty(errors) + call go#list#JumpToFirst() + endif endif else - redraw | echo - call setqflist([]) - call go#util#Cwindow() + call go#list#Clean() + call go#list#Window() echon "vim-go: " | echohl Function | echon "[errcheck] PASS" | echohl None endif diff --git a/autoload/go/list.vim b/autoload/go/list.vim index a3afa107c9..a36f161921 100644 --- a/autoload/go/list.vim +++ b/autoload/go/list.vim @@ -36,6 +36,26 @@ function! go#list#Populate(items) call setloclist(0, a:items, 'r') endfunction +" Parse parses the given items based on the specified errorformat nad +" populates the location list. +function! go#list#ParseFormat(errformat, items) + " backup users errorformat, will be restored once we are finished + let old_errorformat = &errorformat + + " parse and populate the location list + let &errorformat = a:errformat + lgetexpr a:items + + "restore back + let &errorformat = old_errorformat +endfunction + +" Parse parses the given items based on the global errorformat nad +" populates the location list. +function! go#list#Parse(items) + lgetexpr a:items +endfunction + " JumpToFirst jumps to the first item in the location list function! go#list#JumpToFirst() ll 1 From 056a91144b8d8f7407f3af5cffdc13db504ebfb1 Mon Sep 17 00:00:00 2001 From: Fatih Arslan Date: Thu, 26 Nov 2015 19:00:14 +0200 Subject: [PATCH 5/6] list: finalize location list displaying --- README.md | 6 ++-- autoload/go/cmd.vim | 6 ++-- autoload/go/fmt.vim | 22 +++++-------- autoload/go/oracle.vim | 45 +++++++++++++------------- autoload/go/rename.vim | 16 +++++----- autoload/go/tool.vim | 27 ---------------- compiler/go.vim | 8 +++-- doc/vim-go.txt | 71 ++++++++++++++++++++++++------------------ 8 files changed, 91 insertions(+), 110 deletions(-) diff --git a/README.md b/README.md index 8baef4438b..7b176e8a21 100644 --- a/README.md +++ b/README.md @@ -18,9 +18,9 @@ disabled/enabled easily. * Go to symbol/declaration with `:GoDef` * Look up documentation with `:GoDoc` inside Vim or open it in browser * Automatically import packages via `:GoImport` or plug it into autosave -* Compile your package with `:GoBuild`, install it with `:GoInstall` +* Compile your package with `:GoBuild`, install it with `:GoInstall` or test + them with `:GoTest` (also supports running single tests via `:GoTestFunc`) * Quickly execute your current file/files with `:GoRun` -* Run `:GoTest` and see any errors in the quickfix window * Automatic `GOPATH` detection based on the directory structure (i.e. `gb` projects, `godep` vendored projects) * Change or display `GOPATH` with `:GoPath` @@ -41,6 +41,8 @@ disabled/enabled easily. your custom vim function. * Tagbar support to show tags of the source code in a sidebar with `gotags` * Custom vim text objects such as `a function` or `inner function` +* All commands support collecting and displaying errors in Vim's location + list. ## Install diff --git a/autoload/go/cmd.vim b/autoload/go/cmd.vim index e1271292c8..d3ce7b0446 100644 --- a/autoload/go/cmd.vim +++ b/autoload/go/cmd.vim @@ -109,7 +109,7 @@ function! go#cmd#Run(bang, ...) for k in keys(filter(is_readable, '!v:val')) echo "vim-go: " | echohl Identifier | echon "[run] Dropped " | echohl Constant | echon '"' . k . '"' - echohl Identifier | echon " from QuickFix list (nonvalid filename)" | echohl None + echohl Identifier | echon " from location list (nonvalid filename)" | echohl None endfor call go#list#Populate(errors) @@ -123,8 +123,8 @@ function! go#cmd#Run(bang, ...) endfunction " Install installs the package by simple calling 'go install'. If any argument -" is given(which are passed directly to 'go insta'') it tries to install those -" packages. Errors are populated in the quickfix window. +" is given(which are passed directly to 'go instal') it tries to install those +" packages. Errors are populated in the location window. function! go#cmd#Install(bang, ...) let command = 'go install ' . go#util#Shelljoin(a:000) call go#cmd#autowrite() diff --git a/autoload/go/fmt.vim b/autoload/go/fmt.vim index 4b9c9abea9..936ed14b91 100644 --- a/autoload/go/fmt.vim +++ b/autoload/go/fmt.vim @@ -43,8 +43,6 @@ if !exists("g:go_fmt_experimental") let g:go_fmt_experimental = 0 endif -let s:got_fmt_error = 0 - " we have those problems : " http://stackoverflow.com/questions/12741977/prevent-vim-from-updating-its-undo-tree " http://stackoverflow.com/questions/18532692/golang-formatter-and-vim-how-to-destroy-history-record?rq=1 @@ -106,7 +104,6 @@ function! go#fmt#Format(withGoimport) let $GOPATH = old_gopath endif - "if there is no error on the temp file replace the output with the current "file (if this fails, we can always check the outputs first line with: "splitted =~ 'package \w\+') @@ -119,16 +116,12 @@ function! go#fmt#Format(withGoimport) silent edit! let &syntax = &syntax - " only clear quickfix if it was previously set, this prevents closing - " other quickfixes - if s:got_fmt_error - let s:got_fmt_error = 0 - call setqflist([]) - call go#util#Cwindow() - endif + " clean up previous location list + call go#list#Clean() + call go#list#Window() elseif g:go_fmt_fail_silently == 0 let splitted = split(out, '\n') - "otherwise get the errors and put them to quickfix window + "otherwise get the errors and put them to location list let errors = [] for line in splitted let tokens = matchlist(line, '^\(.\{-}\):\(\d\+\):\(\d\+\)\s*\(.*\)') @@ -143,11 +136,12 @@ function! go#fmt#Format(withGoimport) % | " Couldn't detect gofmt error format, output errors endif if !empty(errors) - call setqflist(errors, 'r') + call go#list#Populate(errors) echohl Error | echomsg "Gofmt returned error" | echohl None endif - let s:got_fmt_error = 1 - call go#util#Cwindow(len(errors)) + + call go#list#Window(len(errors)) + " We didn't use the temp file, so clean up call delete(l:tmpname) endif diff --git a/autoload/go/oracle.vim b/autoload/go/oracle.vim index 22b3dfcd6c..19efd773cc 100644 --- a/autoload/go/oracle.vim +++ b/autoload/go/oracle.vim @@ -10,9 +10,9 @@ if !exists("g:go_oracle_bin") endif " Parses (via regex) Oracle's 'plain' format output and puts them into a -" quickfix list. -func! s:qflist(output) - let qflist = [] +" location list +func! s:loclist(output) + let llist = [] " Parse GNU-style 'file:line.col-line.col: message' format. let mx = '^\(\a:[\\/][^:]\+\|[^:]\+\):\(\d\+\):\(\d\+\):\(.*\)$' for line in split(a:output, "\n") @@ -33,17 +33,17 @@ func! s:qflist(output) if bnr != -1 let item['bufnr'] = bnr endif - call add(qflist, item) + call add(llist, item) endfor - call setqflist(qflist) - call go#util#Cwindow(len(qflist)) + call go#list#Populate(llist) + call go#list#Window(len(llist)) endfun " This uses Vim's errorformat to parse the output from Oracle's 'plain output -" and put it into quickfix list. I believe using errorformat is much more +" and put it into location list. I believe using errorformat is much more " easier to use. If we need more power we can always switch back to parse it " via regex. -func! s:qflistSecond(output) +func! s:loclistSecond(output) " backup users errorformat, will be restored once we are finished let old_errorformat = &errorformat @@ -53,16 +53,13 @@ func! s:qflistSecond(output) " 'file:line:col: message' " " We discard line2 and col2 for the first errorformat, because it's not - " useful and quickfix only has the ability to show one line and column + " useful and location only has the ability to show one line and column " number - let &errorformat = "%f:%l.%c-%[%^:]%#:\ %m,%f:%l:%c:\ %m" + let errformat = "%f:%l.%c-%[%^:]%#:\ %m,%f:%l:%c:\ %m" + call go#list#ParseFormat(errformat, split(a:output, "\n")) - " create the quickfix list and open it - cgetexpr split(a:output, "\n") - let errors = getqflist() - call go#util#Cwindow(len(errors)) - - let &errorformat = old_errorformat + let errors = go#list#Get() + call go#list#Window(len(errors)) endfun func! s:getpos(l, c) @@ -186,31 +183,31 @@ endfunction " Show 'implements' relation for selected package function! go#oracle#Implements(selected) let out = s:RunOracle('implements', a:selected, 0) - call s:qflistSecond(out) + call s:loclistSecond(out) endfunction " Describe selected syntax: definition, methods, etc function! go#oracle#Describe(selected) let out = s:RunOracle('describe', a:selected, 0) - call s:qflistSecond(out) + call s:loclistSecond(out) endfunction " Show possible targets of selected function call function! go#oracle#Callees(selected) let out = s:RunOracle('callees', a:selected, 1) - call s:qflistSecond(out) + call s:loclistSecond(out) endfunction " Show possible callers of selected function function! go#oracle#Callers(selected) let out = s:RunOracle('callers', a:selected, 1) - call s:qflistSecond(out) + call s:loclistSecond(out) endfunction " Show path from callgraph root to selected function function! go#oracle#Callstack(selected) let out = s:RunOracle('callstack', a:selected, 1) - call s:qflistSecond(out) + call s:loclistSecond(out) endfunction " Show free variables of selection @@ -222,19 +219,19 @@ function! go#oracle#Freevars(selected) endif let out = s:RunOracle('freevars', a:selected, 0) - call s:qflistSecond(out) + call s:loclistSecond(out) endfunction " Show send/receive corresponding to selected channel op function! go#oracle#ChannelPeers(selected) let out = s:RunOracle('peers', a:selected, 1) - call s:qflistSecond(out) + call s:loclistSecond(out) endfunction " Show all refs to entity denoted by selected identifier function! go#oracle#Referrers(selected) let out = s:RunOracle('referrers', a:selected, 0) - call s:qflistSecond(out) + call s:loclistSecond(out) endfunction " vim:ts=4:sw=4:et diff --git a/autoload/go/rename.vim b/autoload/go/rename.vim index ca6808fa91..f08d567105 100644 --- a/autoload/go/rename.vim +++ b/autoload/go/rename.vim @@ -13,7 +13,6 @@ function! go#rename#Rename(bang, ...) let to = a:1 endif - "return with a warning if the bin doesn't exist let bin_path = go#path#CheckBinPath(g:go_gorename_bin) if empty(bin_path) @@ -31,20 +30,23 @@ function! go#rename#Rename(bang, ...) let clean = split(out, '\n') if v:shell_error - call go#tool#ShowErrors(out) - let errors = getqflist() - call go#util#Cwindow(len(errors)) + let errors = go#tool#ParseErrors(split(out, '\n')) + call go#list#Populate(errors) + call go#list#Window(len(errors)) if !empty(errors) && !a:bang - cc 1 "jump to first error if there is any + call go#list#JumpToFirst() endif return else - call setqflist([]) - call go#util#Cwindow() + call go#list#Clean() + call go#list#Window() redraw | echon "vim-go: " | echohl Function | echon clean[0] | echohl None endif " refresh the buffer so we can see the new content + " TODO(arslan): also find all other buffers and refresh them too. For this + " we need a way to get the list of changes from gorename upon an success + " change. silent execute ":e" endfunction diff --git a/autoload/go/tool.vim b/autoload/go/tool.vim index 788a91cd44..ed339ab7fa 100644 --- a/autoload/go/tool.vim +++ b/autoload/go/tool.vim @@ -65,33 +65,6 @@ function! go#tool#ParseErrors(lines) return errors endfunction - -function! go#tool#ShowErrors(out) - " cd into the current files directory. This is important so fnamemodify - " does create a full path for outputs when the token is only a single file - " name (such as for a go test output, i.e.: 'demo_test.go'). For other - " outputs, such as 'go install' we already get an absolute path (i.e.: - " '../foo/foo.go') and fnamemodify successfuly creates the full path. - let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd ' : 'cd ' - let current_dir = getcwd() - execute cd . fnameescape(expand("%:p:h")) - - let errors = go#tool#ParseErrors(split(a:out, '\n')) - - " return back to old dir once we are finished with populating the errors - execute cd . fnameescape(current_dir) - - if !empty(errors) - call setqflist(errors, 'r') - return - endif - - if empty(errors) - " Couldn't detect error format, output errors - echo a:out - endif -endfunction - function! go#tool#ExecuteInDir(cmd) abort let old_gopath = $GOPATH let $GOPATH = go#path#Detect() diff --git a/compiler/go.vim b/compiler/go.vim index e7b90bb717..7b5a0255ac 100644 --- a/compiler/go.vim +++ b/compiler/go.vim @@ -21,8 +21,12 @@ else CompilerSet makeprg=go\ build endif -" Define the patterns that will be recognized by QuickFix when parsing the output of GoRun. -" More information at http://vimdoc.sourceforge.net/htmldoc/quickfix.html#errorformat +" Define the patterns that will be recognized by QuickFix when parsing the +" output of Go command that use this errorforamt (when called make, cexpr or +" lmake, lexpr). This is the global errorformat, however some command might +" use a different output, for those we define them directly and modify the +" errorformat ourselves. More information at: +" http://vimdoc.sourceforge.net/htmldoc/quickfix.html#errorformat CompilerSet errorformat =%-G#\ %.%# " Ignore lines beginning with '#' ('# command-line-arguments' line sometimes appears?) CompilerSet errorformat+=%-G%.%#panic:\ %m " Ignore lines containing 'panic: message' CompilerSet errorformat+=%Ecan\'t\ load\ package:\ %m " Start of multiline error string is 'can\'t load package' diff --git a/doc/vim-go.txt b/doc/vim-go.txt index 457e583a42..52bce34940 100755 --- a/doc/vim-go.txt +++ b/doc/vim-go.txt @@ -33,29 +33,38 @@ support, improved syntax highlighting, go toolchain commands, etc... It's highly customizable and each individual feature can be disabled/enabled easily. - * Improved Syntax highlighting, such as Functions, Operators, Methods.. + * Improved Syntax highlighting with items such as Functions, Operators, Methods. * Auto completion support via `gocode` - * Better `gofmt` on save, keeps cursor position and doesn't break your undo + * Better `gofmt` on save, which keeps cursor position and doesn't break your undo history - * Go to symbol/declaration with `godef` - * Look up documentation with `godoc` inside Vim or open it in browser. - * Automatically import packages via `goimports` - * Compile and `go build` your package, install it with `go install` - * `go run` quickly your current file/files - * Run `go test` and see any errors in quickfix window - * Create a coverage profile and display annotated source code in browser to - see which functions are covered. - * Lint your code with `golint` - * Run your code trough `go vet` to catch static errors. - * Advanced source analysis tool with `oracle` - * Precise type-safe renaming of identifiers with `gorename` + * Go to symbol/declaration with `:GoDef` + * Look up documentation with `:GoDoc` inside Vim or open it in browser + * Automatically import packages via `:GoImport` or plug it into autosave + * Compile your package with `:GoBuild`, install it with `:GoInstall` or test + them with `:GoTest` (also supports running single tests via `:GoTestFunc`) + * Quickly execute your current file/files with `:GoRun` + * Automatic `GOPATH` detection based on the directory structure (i.e. `gb` + projects, `godep` vendored projects) + * Change or display `GOPATH` with `:GoPath` + * Create a coverage profile and display annotated source code in browser to see + which functions are covered with `:GoCoverage` + * Call `gometalinter` with `:GoMetaLinter`, which invokes all possible linters + (golint, vet, errcheck, deadcode, etc..) and shows the warnings/errors + * Lint your code with `:GoLint` + * Run your code through `:GoVet` to catch static errors + * Advanced source analysis tools utilizing oracle, such as `:GoImplements`, + `:GoCallees`, and `:GoReferrers` + * Precise type-safe renaming of identifiers with `:GoRename` * List all source files and dependencies - * Checking with `errcheck` for unchecked errors. - * Integrated and improved snippets. Supports `ultisnips` or `neosnippet` - * Share your current code to play.golang.org - * On-the-fly type information about the word under the cursor + * Unchecked error checking with `:GoErrCheck` + * Integrated and improved snippets, supporting `ultisnips` or `neosnippet` + * Share your current code to [play.golang.org](http://play.golang.org) with `:GoPlay` + * On-the-fly type information about the word under the cursor. Plug it into + your custom vim function. * Tagbar support to show tags of the source code in a sidebar with `gotags` - * Custom vim text objects, such a `a function` or `inner function` + * Custom vim text objects such as `a function` or `inner function` + * All commands support collecting and displaying errors in Vim's location + list. =============================================================================== INSTALL *go-install* @@ -257,7 +266,7 @@ COMMANDS *go-commands* :GoTest[!] [expand] Run the tests on your _test.go files via in your current directory. Errors - are populated in quickfix window. If an argument is passed, 'expand' is + are populated in location list. If an argument is passed, 'expand' is used as file selector (useful for cases like `:GoTest ./...`). You may optionally pass any valid go test flags/options. For a full list @@ -285,7 +294,7 @@ COMMANDS *go-commands* :GoTestCompile[!] [expand] Compile your _test.go files via in your current directory. Errors are - populated in quickfix window. If an argument is passed, 'expand' is used + populated in location list. If an argument is passed, 'expand' is used as file selector (useful for cases like `:GoTest ./...`). Useful to not run the tests and capture/fix errors before running the tests or to create test binary. @@ -307,7 +316,7 @@ COMMANDS *go-commands* :GoErrCheck [options] Check for unchecked errors in you current package. Errors are populated in - quickfix window. + location list. You may optionally pass any valid errcheck flags/options. For a full list please see `errcheck -h`. @@ -340,7 +349,7 @@ COMMANDS *go-commands* Show 'implements' relation for a selected package. A list of interfaces for the type that implements an interface under the cursor (or selected - package) is shown quickfix list. + package) is shown location list. *:GoRename* :GoRename[!] [to] @@ -363,13 +372,13 @@ COMMANDS *go-commands* Show 'callees' relation for a selected package. A list of possible call targets for the type under the cursor (or selected package) is shown in a - quickfix list. + location list. *:GoCallers* :GoCallers Show 'callers' relation for a selected function. A list of possible - callers for the selected function under the cursor is shown in a quickfix + callers for the selected function under the cursor is shown in a location list. *:GoDescribe* @@ -386,7 +395,7 @@ COMMANDS *go-commands* Shows 'callstack' relation for the selected function. An arbitrary path from the root of the callgraph to the selected function is showed in a - quickfix list. This may be useful to understand how the function is + location list. This may be useful to understand how the function is reached in a given program. *:GoFreevars* @@ -426,7 +435,7 @@ COMMANDS *go-commands* :GoMetaLinter [path] Calls the underlying `gometalinter` tool and displays all warnings and - errors in a quickfix window. By default the following linters are enabled: + errors in a location list. By default the following linters are enabled: "'vet', 'golint', 'errcheck'". This can be changed with the |g:go_metalinter_enabled| variable. To override the command completely use the variable |g:go_metalinter_command|. To override the maximum linters @@ -681,7 +690,7 @@ is empty. > *'g:go_fmt_fail_silently'* -Use this option to disable showing a quickfix window when |g:go_fmt_command| +Use this option to disable showing a location list when |g:go_fmt_command| fails. By default it's disabled. > let g:go_fmt_fail_silently = 0 @@ -878,14 +887,14 @@ seconds. > let g:go_metalinter_deadline = "5s" < - *'g:go_quickfix_height'* + *'g:go_location_height'* -Specifies the current quickfix height for all quickfix windows. The default +Specifies the current location list height for all location lists. The default value (empty) sets automatically the height to the number of errors (maximum up to 10 errors to prevent large heights). Setting the value explicitly overrides this behavior. To get default Vim behavior set it to 10. > - let g:go_quickfix_height = 0 + let g:go_location_height = 0 =============================================================================== TROUBLESHOOTING *go-troubleshooting* From ddfc8f4b0ab6698e6f5b10b995b6f4b1f13d9ada Mon Sep 17 00:00:00 2001 From: Fatih Arslan Date: Thu, 26 Nov 2015 19:11:12 +0200 Subject: [PATCH 6/6] list: rename setting name --- autoload/go/list.vim | 4 ++-- doc/vim-go.txt | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/autoload/go/list.vim b/autoload/go/list.vim index a36f161921..366c558903 100644 --- a/autoload/go/list.vim +++ b/autoload/go/list.vim @@ -1,5 +1,5 @@ " Window opens the location list with the given height up to 10 lines maximum. -" Otherwise g:go_location_height is used. If no or zero height is given it +" Otherwise g:go_loclist_height is used. If no or zero height is given it " closes the window function! go#list#Window(...) " we don't use lwindow to close the location list as we need also the @@ -12,7 +12,7 @@ function! go#list#Window(...) return endif - let height = get(g:, "go_location_height", 0) + let height = get(g:, "go_loclist_height", 0) if height == 0 " prevent creating a large location height for a large set of numbers if a:1 > 10 diff --git a/doc/vim-go.txt b/doc/vim-go.txt index 52bce34940..6d5370971f 100755 --- a/doc/vim-go.txt +++ b/doc/vim-go.txt @@ -887,14 +887,14 @@ seconds. > let g:go_metalinter_deadline = "5s" < - *'g:go_location_height'* + *'g:go_loclist_height'* Specifies the current location list height for all location lists. The default value (empty) sets automatically the height to the number of errors (maximum up to 10 errors to prevent large heights). Setting the value explicitly overrides this behavior. To get default Vim behavior set it to 10. > - let g:go_location_height = 0 + let g:go_loclist_height = 0 =============================================================================== TROUBLESHOOTING *go-troubleshooting*