From 5a4abb5921973e2649d84c8d625e432e19ba9ead Mon Sep 17 00:00:00 2001 From: Fatih Arslan Date: Sat, 25 Jun 2016 03:32:15 +0300 Subject: [PATCH] style: use two spaces for all files I had enough of dealing with various styles in our VimL files. We had a mix of tabs and spaces over all files. Some were using tabs, some were using 4 spaces. From now on the official vim-go style will be the following settings: ``` shiftwidth=2 tabstop=2 expandtab ``` The modeline for this setting is: ``` " vim: sw=2 sw=2 et ``` I've added the modeline for all files and reformatted all the files again. Some might not like the two space setting, but that's ok. The official Vim runtime files are usually like this, and the vim style guide from Google also uses two spaces for indents (no tabs). If someone wants to set a autocmd, this can be used as well: ``` autocmd BufNewFile,BufRead *.vim setlocal expandtab shiftwidth=2 tabstop=2 ``` --- autoload/ctrlp/decls.vim | 255 ++++++++--------- autoload/go/alternate.vim | 2 + autoload/go/asmfmt.vim | 2 + autoload/go/cmd.vim | 542 ++++++++++++++++++------------------- autoload/go/complete.vim | 238 ++++++++-------- autoload/go/coverage.vim | 419 ++++++++++++++-------------- autoload/go/def.vim | 415 ++++++++++++++-------------- autoload/go/doc.vim | 236 ++++++++-------- autoload/go/fmt.vim | 295 ++++++++++---------- autoload/go/guru.vim | 448 +++++++++++++++--------------- autoload/go/impl.vim | 192 ++++++------- autoload/go/import.vim | 376 ++++++++++++------------- autoload/go/jobcontrol.vim | 2 +- autoload/go/lint.vim | 302 ++++++++++----------- autoload/go/list.vim | 156 +++++------ autoload/go/package.vim | 172 ++++++------ autoload/go/path.vim | 156 +++++------ autoload/go/play.vim | 123 +++++---- autoload/go/rename.vim | 117 ++++---- autoload/go/term.vim | 164 +++++------ autoload/go/textobj.vim | 2 +- autoload/go/tool.vim | 206 +++++++------- autoload/go/ui.vim | 177 ++++++------ autoload/go/util.vim | 122 ++++----- compiler/go.vim | 6 +- ftdetect/gofiletype.vim | 14 +- ftplugin/asm.vim | 4 +- ftplugin/go.vim | 46 ++-- ftplugin/go/commands.vim | 2 +- ftplugin/go/mappings.vim | 10 +- ftplugin/go/snippets.vim | 58 ++-- ftplugin/go/tagbar.vim | 74 ++--- ftplugin/gohtmltmpl.vim | 4 +- indent/go.vim | 80 +++--- indent/gohtmltmpl.vim | 2 + plugin/go.vim | 275 ++++++++++--------- syntax/go.vim | 62 +++-- syntax/godefstack.vim | 4 +- syntax/gohtmltmpl.vim | 6 +- syntax/gotexttmpl.vim | 4 +- syntax/vimgo.vim | 4 +- 41 files changed, 2898 insertions(+), 2876 deletions(-) diff --git a/autoload/ctrlp/decls.vim b/autoload/ctrlp/decls.vim index 5a625317b0..7af2cda70b 100644 --- a/autoload/ctrlp/decls.vim +++ b/autoload/ctrlp/decls.vim @@ -1,26 +1,26 @@ let s:go_decls_var = { - \ 'init': 'ctrlp#decls#init()', - \ 'exit': 'ctrlp#decls#exit()', - \ 'enter': 'ctrlp#decls#enter()', - \ 'accept': 'ctrlp#decls#accept', - \ 'lname': 'declarations', - \ 'sname': 'decls', - \ 'type': 'tabs', - \} + \ 'init': 'ctrlp#decls#init()', + \ 'exit': 'ctrlp#decls#exit()', + \ 'enter': 'ctrlp#decls#enter()', + \ 'accept': 'ctrlp#decls#accept', + \ 'lname': 'declarations', + \ 'sname': 'decls', + \ 'type': 'tabs', + \} if exists('g:ctrlp_ext_vars') && !empty(g:ctrlp_ext_vars) - let g:ctrlp_ext_vars = add(g:ctrlp_ext_vars, s:go_decls_var) + let g:ctrlp_ext_vars = add(g:ctrlp_ext_vars, s:go_decls_var) else - let g:ctrlp_ext_vars = [s:go_decls_var] + let g:ctrlp_ext_vars = [s:go_decls_var] endif function! ctrlp#decls#init() - cal s:enable_syntax() - return s:decls + cal s:enable_syntax() + return s:decls endfunction function! ctrlp#decls#exit() - unlet! s:decls s:current_dir s:target + unlet! s:decls s:current_dir s:target endfunction " The action to perform on the selected string @@ -29,130 +29,131 @@ endfunction " the values are 'e', 'v', 't' and 'h', respectively " a:str the selected string function! ctrlp#decls#accept(mode, str) - let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd ' : 'cd ' - let dir = getcwd() - try - " we jump to the file directory so we can get the fullpath via fnamemodify - " below - execute cd . s:current_dir - - let vals = matchlist(a:str, '|\(.\{-}\):\(\d\+\):\(\d\+\)\s*\(.*\)|') - - " i.e: main.go - let filename = vals[1] - let line = vals[2] - let col = vals[3] - - " i.e: /Users/fatih/vim-go/main.go - let filepath = fnamemodify(filename, ":p") - - " acceptile is a very versatile method, - call ctrlp#acceptfile(a:mode, filepath) - call cursor(line, col) - silent! norm! zvzz - finally - "jump back to old dir - execute cd . fnameescape(dir) - endtry + let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd ' : 'cd ' + let dir = getcwd() + try + " we jump to the file directory so we can get the fullpath via fnamemodify + " below + execute cd . s:current_dir + + let vals = matchlist(a:str, '|\(.\{-}\):\(\d\+\):\(\d\+\)\s*\(.*\)|') + + " i.e: main.go + let filename = vals[1] + let line = vals[2] + let col = vals[3] + + " i.e: /Users/fatih/vim-go/main.go + let filepath = fnamemodify(filename, ":p") + + " acceptile is a very versatile method, + call ctrlp#acceptfile(a:mode, filepath) + call cursor(line, col) + silent! norm! zvzz + finally + "jump back to old dir + execute cd . fnameescape(dir) + endtry endfunction function! ctrlp#decls#enter() - let s:current_dir = fnameescape(expand('%:p:h')) - let s:decls = [] - - let bin_path = go#path#CheckBinPath('motion') - if empty(bin_path) - return - endif - let command = printf("%s -format vim -mode decls", bin_path) - let command .= " -include ". get(g:, "go_decls_includes", "func,type") - - call go#cmd#autowrite() - - if s:mode == 0 - " current file mode - let fname = expand("%:p") - if exists('s:target') - let fname = s:target - endif - - let command .= printf(" -file %s", fname) - else - " all functions mode - let dir = expand("%:p:h") - if exists('s:target') - let dir = s:target - endif - - let command .= printf(" -dir %s", dir) - endif - - let out = go#util#System(command) - if go#util#ShellError() != 0 - call go#util#EchoError(out) - return - endif - - if exists("l:tmpname") - call delete(l:tmpname) - endif - - let result = eval(out) - if type(result) != 4 || !has_key(result, 'decls') - return - endif - - let decls = result.decls - - " find the maximum function name - let max_len = 0 - for decl in decls - if len(decl.ident)> max_len - let max_len = len(decl.ident) - endif - endfor - - for decl in decls - " paddings - let space = " " - for i in range(max_len - len(decl.ident)) - let space .= " " - endfor - - call add(s:decls, printf("%s\t%s |%s:%s:%s|\t%s", - \ decl.ident . space, - \ decl.keyword, - \ fnamemodify(decl.filename, ":t"), - \ decl.line, - \ decl.col, - \ decl.full, - \)) - endfor + let s:current_dir = fnameescape(expand('%:p:h')) + let s:decls = [] + + let bin_path = go#path#CheckBinPath('motion') + if empty(bin_path) + return + endif + let command = printf("%s -format vim -mode decls", bin_path) + let command .= " -include ". get(g:, "go_decls_includes", "func,type") + + call go#cmd#autowrite() + + if s:mode == 0 + " current file mode + let fname = expand("%:p") + if exists('s:target') + let fname = s:target + endif + + let command .= printf(" -file %s", fname) + else + " all functions mode + let dir = expand("%:p:h") + if exists('s:target') + let dir = s:target + endif + + let command .= printf(" -dir %s", dir) + endif + + let out = go#util#System(command) + if go#util#ShellError() != 0 + call go#util#EchoError(out) + return + endif + + if exists("l:tmpname") + call delete(l:tmpname) + endif + + let result = eval(out) + if type(result) != 4 || !has_key(result, 'decls') + return + endif + + let decls = result.decls + + " find the maximum function name + let max_len = 0 + for decl in decls + if len(decl.ident)> max_len + let max_len = len(decl.ident) + endif + endfor + + for decl in decls + " paddings + let space = " " + for i in range(max_len - len(decl.ident)) + let space .= " " + endfor + + call add(s:decls, printf("%s\t%s |%s:%s:%s|\t%s", + \ decl.ident . space, + \ decl.keyword, + \ fnamemodify(decl.filename, ":t"), + \ decl.line, + \ decl.col, + \ decl.full, + \)) + endfor endfunc function! s:enable_syntax() - if !(has('syntax') && exists('g:syntax_on')) - return - endif - - syntax match CtrlPIdent '\zs\h\+\ze\s' - syntax match CtrlPKeyword '\zs[^\t|]\+\ze|[^|]\+:\d\+:\d\+|' - syntax match CtrlPFilename '|\zs[^|]\+:\d\+:\d\+\ze|' - syntax match CtrlPSignature '\zs\t.*\ze$' contains=CtrlPKeyWord,CtrlPFilename - - highlight link CtrlPIdent Function - highlight link CtrlPKeyword Keyword - highlight link CtrlPFilename SpecialComment - highlight link CtrlPSignature Comment + if !(has('syntax') && exists('g:syntax_on')) + return + endif + + syntax match CtrlPIdent '\zs\h\+\ze\s' + syntax match CtrlPKeyword '\zs[^\t|]\+\ze|[^|]\+:\d\+:\d\+|' + syntax match CtrlPFilename '|\zs[^|]\+:\d\+:\d\+\ze|' + syntax match CtrlPSignature '\zs\t.*\ze$' contains=CtrlPKeyWord,CtrlPFilename + + highlight link CtrlPIdent Function + highlight link CtrlPKeyword Keyword + highlight link CtrlPFilename SpecialComment + highlight link CtrlPSignature Comment endfunction let s:id = g:ctrlp_builtins + len(g:ctrlp_ext_vars) function! ctrlp#decls#cmd(mode, ...) - let s:mode = a:mode - if a:0 && !empty(a:1) - let s:target = a:1 - endif - return s:id + let s:mode = a:mode + if a:0 && !empty(a:1) + let s:target = a:1 + endif + return s:id endfunction +" vim: sw=2 ts=2 et diff --git a/autoload/go/alternate.vim b/autoload/go/alternate.vim index 1de6a699de..dc5643dcf3 100644 --- a/autoload/go/alternate.vim +++ b/autoload/go/alternate.vim @@ -28,3 +28,5 @@ function! go#alternate#Switch(bang, cmd) execute ":" . a:cmd . " " . alt_file endif endfunction + +" vim: sw=2 ts=2 et diff --git a/autoload/go/asmfmt.vim b/autoload/go/asmfmt.vim index 7fb52670b6..711e327460 100644 --- a/autoload/go/asmfmt.vim +++ b/autoload/go/asmfmt.vim @@ -50,3 +50,5 @@ function! go#asmfmt#Format() " Restore the cursor/window positions. call winrestview(l:curw) endfunction + +" vim: sw=2 ts=2 et diff --git a/autoload/go/cmd.vim b/autoload/go/cmd.vim index 26b9c09d42..a01e30d377 100644 --- a/autoload/go/cmd.vim +++ b/autoload/go/cmd.vim @@ -1,11 +1,11 @@ if !exists("g:go_dispatch_enabled") - let g:go_dispatch_enabled = 0 + let g:go_dispatch_enabled = 0 endif function! go#cmd#autowrite() - if &autowrite == 1 - silent wall - endif + if &autowrite == 1 + silent wall + endif endfunction @@ -14,73 +14,73 @@ endfunction " default it tries to call simply 'go build', but it first tries to get all " dependent files for the current folder and passes it to go build. function! go#cmd#Build(bang, ...) - " expand all wildcards(i.e: '%' to the current file name) - let goargs = map(copy(a:000), "expand(v:val)") - - " escape all shell arguments before we pass it to make - let goargs = go#util#Shelllist(goargs, 1) - - " create our command arguments. go build discards any results when it - " compiles multiple packages. So we pass the `errors` package just as an - " placeholder with the current folder (indicated with '.') - let args = ["build"] + goargs + [".", "errors"] - - " if we have nvim, call it asynchronously and return early ;) - if has('nvim') - call go#util#EchoProgress("building dispatched ...") - call go#jobcontrol#Spawn(a:bang, "build", args) - return + " expand all wildcards(i.e: '%' to the current file name) + let goargs = map(copy(a:000), "expand(v:val)") + + " escape all shell arguments before we pass it to make + let goargs = go#util#Shelllist(goargs, 1) + + " create our command arguments. go build discards any results when it + " compiles multiple packages. So we pass the `errors` package just as an + " placeholder with the current folder (indicated with '.') + let args = ["build"] + goargs + [".", "errors"] + + " if we have nvim, call it asynchronously and return early ;) + if has('nvim') + call go#util#EchoProgress("building dispatched ...") + call go#jobcontrol#Spawn(a:bang, "build", args) + return + endif + + let old_gopath = $GOPATH + let $GOPATH = go#path#Detect() + let default_makeprg = &makeprg + let &makeprg = "go " . join(args, ' ') + + let l:listtype = go#list#Type("quickfix") + " execute make inside the source folder so we can parse the errors + " correctly + let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd ' : 'cd ' + let dir = getcwd() + try + execute cd . fnameescape(expand("%:p:h")) + if g:go_dispatch_enabled && exists(':Make') == 2 + call go#util#EchoProgress("building dispatched ...") + silent! exe 'Make' + elseif l:listtype == "locationlist" + silent! exe 'lmake!' + else + silent! exe 'make!' endif + redraw! + finally + execute cd . fnameescape(dir) + endtry - let old_gopath = $GOPATH - let $GOPATH = go#path#Detect() - let default_makeprg = &makeprg - let &makeprg = "go " . join(args, ' ') - - let l:listtype = go#list#Type("quickfix") - " execute make inside the source folder so we can parse the errors - " correctly - let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd ' : 'cd ' - let dir = getcwd() - try - execute cd . fnameescape(expand("%:p:h")) - if g:go_dispatch_enabled && exists(':Make') == 2 - call go#util#EchoProgress("building dispatched ...") - silent! exe 'Make' - elseif l:listtype == "locationlist" - silent! exe 'lmake!' - else - silent! exe 'make!' - endif - redraw! - finally - execute cd . fnameescape(dir) - endtry - - let errors = go#list#Get(l:listtype) - call go#list#Window(l:listtype, len(errors)) + let errors = go#list#Get(l:listtype) + call go#list#Window(l:listtype, len(errors)) - if !empty(errors) - if !a:bang - call go#list#JumpToFirst(l:listtype) - endif - else - call go#util#EchoSuccess("[build] SUCCESS") + if !empty(errors) + if !a:bang + call go#list#JumpToFirst(l:listtype) endif + else + call go#util#EchoSuccess("[build] SUCCESS") + endif - let &makeprg = default_makeprg - let $GOPATH = old_gopath + let &makeprg = default_makeprg + let $GOPATH = old_gopath endfunction " Run runs the current file (and their dependencies if any) in a new terminal. function! go#cmd#RunTerm(bang, mode, files) - if empty(a:files) - let cmd = "go run ". go#util#Shelljoin(go#tool#Files()) - else - let cmd = "go run ". go#util#Shelljoin(map(copy(a:files), "expand(v:val)"), 1) - endif - call go#term#newmode(a:bang, cmd, a:mode) + if empty(a:files) + let cmd = "go run ". go#util#Shelljoin(go#tool#Files()) + else + let cmd = "go run ". go#util#Shelljoin(map(copy(a:files), "expand(v:val)"), 1) + endif + call go#term#newmode(a:bang, cmd, a:mode) endfunction " Run runs the current file (and their dependencies if any) and outputs it. @@ -88,257 +88,257 @@ endfunction " suitable for long running apps, because vim is blocking by default and " calling long running apps will block the whole UI. function! go#cmd#Run(bang, ...) - if has('nvim') - call go#cmd#RunTerm(a:bang, '', a:000) - return - endif - - let old_gopath = $GOPATH - let $GOPATH = go#path#Detect() - - if go#util#IsWin() - exec '!go run ' . go#util#Shelljoin(go#tool#Files()) - if v:shell_error - redraws! | echon "vim-go: [run] " | echohl ErrorMsg | echon "FAILED"| echohl None - else - redraws! | echon "vim-go: [run] " | echohl Function | echon "SUCCESS"| echohl None - endif - - let $GOPATH = old_gopath - return - endif - - " :make expands '%' and '#' wildcards, so they must also be escaped - let default_makeprg = &makeprg - if a:0 == 0 - let &makeprg = 'go run ' . go#util#Shelljoin(go#tool#Files(), 1) - else - let &makeprg = "go run " . go#util#Shelljoin(map(copy(a:000), "expand(v:val)"), 1) - endif - - let l:listtype = go#list#Type("quickfix") - - if g:go_dispatch_enabled && exists(':Make') == 2 - silent! exe 'Make' - elseif l:listtype == "locationlist" - exe 'lmake!' + if has('nvim') + call go#cmd#RunTerm(a:bang, '', a:000) + return + endif + + let old_gopath = $GOPATH + let $GOPATH = go#path#Detect() + + if go#util#IsWin() + exec '!go run ' . go#util#Shelljoin(go#tool#Files()) + if v:shell_error + redraws! | echon "vim-go: [run] " | echohl ErrorMsg | echon "FAILED"| echohl None else - exe 'make!' - endif - - let items = go#list#Get(l:listtype) - let errors = go#tool#FilterValids(items) - - call go#list#Populate(l:listtype, errors) - call go#list#Window(l:listtype, len(errors)) - if !empty(errors) && !a:bang - call go#list#JumpToFirst(l:listtype) + redraws! | echon "vim-go: [run] " | echohl Function | echon "SUCCESS"| echohl None endif let $GOPATH = old_gopath - let &makeprg = default_makeprg + return + endif + + " :make expands '%' and '#' wildcards, so they must also be escaped + let default_makeprg = &makeprg + if a:0 == 0 + let &makeprg = 'go run ' . go#util#Shelljoin(go#tool#Files(), 1) + else + let &makeprg = "go run " . go#util#Shelljoin(map(copy(a:000), "expand(v:val)"), 1) + endif + + let l:listtype = go#list#Type("quickfix") + + if g:go_dispatch_enabled && exists(':Make') == 2 + silent! exe 'Make' + elseif l:listtype == "locationlist" + exe 'lmake!' + else + exe 'make!' + endif + + let items = go#list#Get(l:listtype) + let errors = go#tool#FilterValids(items) + + call go#list#Populate(l:listtype, errors) + call go#list#Window(l:listtype, len(errors)) + if !empty(errors) && !a:bang + call go#list#JumpToFirst(l:listtype) + endif + + let $GOPATH = old_gopath + let &makeprg = default_makeprg endfunction " Install installs the package by simple calling 'go install'. If any argument " is given(which are passed directly to 'go install') it tries to install those " packages. Errors are populated in the location window. function! go#cmd#Install(bang, ...) - let default_makeprg = &makeprg - - " :make expands '%' and '#' wildcards, so they must also be escaped - let goargs = go#util#Shelljoin(map(copy(a:000), "expand(v:val)"), 1) - let &makeprg = "go install " . goargs - - let l:listtype = go#list#Type("quickfix") - " execute make inside the source folder so we can parse the errors - " correctly - let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd ' : 'cd ' - let dir = getcwd() - try - execute cd . fnameescape(expand("%:p:h")) - if g:go_dispatch_enabled && exists(':Make') == 2 - call go#util#EchoProgress("building dispatched ...") - silent! exe 'Make' - elseif l:listtype == "locationlist" - silent! exe 'lmake!' - else - silent! exe 'make!' - endif - redraw! - finally - execute cd . fnameescape(dir) - endtry - - let errors = go#list#Get(l:listtype) - call go#list#Window(l:listtype, len(errors)) - if !empty(errors) - if !a:bang - call go#list#JumpToFirst(l:listtype) - endif + let default_makeprg = &makeprg + + " :make expands '%' and '#' wildcards, so they must also be escaped + let goargs = go#util#Shelljoin(map(copy(a:000), "expand(v:val)"), 1) + let &makeprg = "go install " . goargs + + let l:listtype = go#list#Type("quickfix") + " execute make inside the source folder so we can parse the errors + " correctly + let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd ' : 'cd ' + let dir = getcwd() + try + execute cd . fnameescape(expand("%:p:h")) + if g:go_dispatch_enabled && exists(':Make') == 2 + call go#util#EchoProgress("building dispatched ...") + silent! exe 'Make' + elseif l:listtype == "locationlist" + silent! exe 'lmake!' else - redraws! | echon "vim-go: " | echohl Function | echon "installed to ". $GOPATH | echohl None + silent! exe 'make!' endif + redraw! + finally + execute cd . fnameescape(dir) + endtry - let &makeprg = default_makeprg + let errors = go#list#Get(l:listtype) + call go#list#Window(l:listtype, len(errors)) + if !empty(errors) + if !a:bang + call go#list#JumpToFirst(l:listtype) + endif + else + redraws! | echon "vim-go: " | echohl Function | echon "installed to ". $GOPATH | echohl None + endif + + let &makeprg = default_makeprg endfunction " Test runs `go test` in the current directory. If compile is true, it'll " compile the tests instead of running them (useful to catch errors in the " test files). Any other argument is appendend to the final `go test` command function! go#cmd#Test(bang, compile, ...) - let args = ["test"] + let args = ["test"] - " don't run the test, only compile it. Useful to capture and fix errors. - if a:compile - let compile_file = "vim-go-test-compile" - call extend(args, ["-c", "-o", compile_file]) - endif + " don't run the test, only compile it. Useful to capture and fix errors. + if a:compile + let compile_file = "vim-go-test-compile" + call extend(args, ["-c", "-o", compile_file]) + endif - if a:0 - " expand all wildcards(i.e: '%' to the current file name) - let goargs = map(copy(a:000), "expand(v:val)") - if !has('nvim') - let goargs = go#util#Shelllist(goargs, 1) - endif + if a:0 + " expand all wildcards(i.e: '%' to the current file name) + let goargs = map(copy(a:000), "expand(v:val)") + if !has('nvim') + let goargs = go#util#Shelllist(goargs, 1) + endif - call extend(args, goargs, 1) + call extend(args, goargs, 1) + else + " only add this if no custom flags are passed + let timeout = get(g:, 'go_test_timeout', '10s') + call add(args, printf("-timeout=%s", timeout)) + endif + + if a:compile + echon "vim-go: " | echohl Identifier | echon "compiling tests ..." | echohl None + else + echon "vim-go: " | echohl Identifier | echon "testing ..." | echohl None + endif + + if has('nvim') + if get(g:, 'go_term_enabled', 0) + let id = go#term#new(a:bang, ["go"] + args) else - " only add this if no custom flags are passed - let timeout = get(g:, 'go_test_timeout', '10s') - call add(args, printf("-timeout=%s", timeout)) + let id = go#jobcontrol#Spawn(a:bang, "test", args) endif if a:compile - echon "vim-go: " | echohl Identifier | echon "compiling tests ..." | echohl None - else - echon "vim-go: " | echohl Identifier | echon "testing ..." | echohl None + call go#jobcontrol#AddHandler(function('s:test_compile_handler')) + let s:test_compile_handlers[id] = compile_file endif + return id + endif - if has('nvim') - if get(g:, 'go_term_enabled', 0) - let id = go#term#new(a:bang, ["go"] + args) - else - let id = go#jobcontrol#Spawn(a:bang, "test", args) - endif - - if a:compile - call go#jobcontrol#AddHandler(function('s:test_compile_handler')) - let s:test_compile_handlers[id] = compile_file - endif - return id - endif + call go#cmd#autowrite() + redraw - call go#cmd#autowrite() - redraw + let command = "go " . join(args, ' ') + let out = go#tool#ExecuteInDir(command) - let command = "go " . join(args, ' ') - let out = go#tool#ExecuteInDir(command) + let l:listtype = "quickfix" - let l:listtype = "quickfix" + let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd ' : 'cd ' + let dir = getcwd() + execute cd fnameescape(expand("%:p:h")) - let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd ' : 'cd ' - let dir = getcwd() - execute cd fnameescape(expand("%:p:h")) + if a:compile + call delete(compile_file) + endif - if a:compile - call delete(compile_file) + if go#util#ShellError() != 0 + let errors = go#tool#ParseErrors(split(out, '\n')) + let errors = go#tool#FilterValids(errors) + + call go#list#Populate(l:listtype, errors) + call go#list#Window(l:listtype, len(errors)) + if !empty(errors) && !a:bang + call go#list#JumpToFirst(l:listtype) + elseif empty(errors) + " failed to parse errors, output the original content + call go#util#EchoError(out) endif + echon "vim-go: " | echohl ErrorMsg | echon "[test] FAIL" | echohl None + else + call go#list#Clean(l:listtype) + call go#list#Window(l:listtype) - if go#util#ShellError() != 0 - let errors = go#tool#ParseErrors(split(out, '\n')) - let errors = go#tool#FilterValids(errors) - - call go#list#Populate(l:listtype, errors) - call go#list#Window(l:listtype, len(errors)) - if !empty(errors) && !a:bang - call go#list#JumpToFirst(l:listtype) - elseif empty(errors) - " failed to parse errors, output the original content - call go#util#EchoError(out) - endif - echon "vim-go: " | echohl ErrorMsg | echon "[test] FAIL" | echohl None + if a:compile + echon "vim-go: " | echohl Function | echon "[test] SUCCESS" | echohl None else - call go#list#Clean(l:listtype) - call go#list#Window(l:listtype) - - if a:compile - echon "vim-go: " | echohl Function | echon "[test] SUCCESS" | echohl None - else - echon "vim-go: " | echohl Function | echon "[test] PASS" | echohl None - endif + echon "vim-go: " | echohl Function | echon "[test] PASS" | echohl None endif - execute cd . fnameescape(dir) + endif + execute cd . fnameescape(dir) endfunction " Testfunc runs a single test that surrounds the current cursor position. " Arguments are passed to the `go test` command. function! go#cmd#TestFunc(bang, ...) - " search flags legend (used only) - " 'b' search backward instead of forward - " 'c' accept a match at the cursor position - " 'n' do Not move the cursor - " 'W' don't wrap around the end of the file - " - " for the full list - " :help search - let test = search('func \(Test\|Example\)', "bcnW") - - if test == 0 - echo "vim-go: [test] no test found immediate to cursor" - return - end - - let line = getline(test) - let name = split(split(line, " ")[1], "(")[0] - let args = [a:bang, 0, "-run", name . "$"] - - if a:0 - call extend(args, a:000) - endif - - call call('go#cmd#Test', args) + " search flags legend (used only) + " 'b' search backward instead of forward + " 'c' accept a match at the cursor position + " 'n' do Not move the cursor + " 'W' don't wrap around the end of the file + " + " for the full list + " :help search + let test = search('func \(Test\|Example\)', "bcnW") + + if test == 0 + echo "vim-go: [test] no test found immediate to cursor" + return + end + + let line = getline(test) + let name = split(split(line, " ")[1], "(")[0] + let args = [a:bang, 0, "-run", name . "$"] + + if a:0 + call extend(args, a:000) + endif + + call call('go#cmd#Test', args) endfunction " Generate runs 'go generate' in similar fashion to go#cmd#Build() function! go#cmd#Generate(bang, ...) - let default_makeprg = &makeprg - - let old_gopath = $GOPATH - let $GOPATH = go#path#Detect() - - " :make expands '%' and '#' wildcards, so they must also be escaped - let goargs = go#util#Shelljoin(map(copy(a:000), "expand(v:val)"), 1) - if go#util#ShellError() != 0 - let &makeprg = "go generate " . goargs - else - let gofiles = go#util#Shelljoin(go#tool#Files(), 1) - let &makeprg = "go generate " . goargs . ' ' . gofiles - endif - - let l:listtype = go#list#Type("quickfix") - - echon "vim-go: " | echohl Identifier | echon "generating ..."| echohl None - if g:go_dispatch_enabled && exists(':Make') == 2 - silent! exe 'Make' - elseif l:listtype == "locationlist" - silent! exe 'lmake!' - else - silent! exe 'make!' + let default_makeprg = &makeprg + + let old_gopath = $GOPATH + let $GOPATH = go#path#Detect() + + " :make expands '%' and '#' wildcards, so they must also be escaped + let goargs = go#util#Shelljoin(map(copy(a:000), "expand(v:val)"), 1) + if go#util#ShellError() != 0 + let &makeprg = "go generate " . goargs + else + let gofiles = go#util#Shelljoin(go#tool#Files(), 1) + let &makeprg = "go generate " . goargs . ' ' . gofiles + endif + + let l:listtype = go#list#Type("quickfix") + + echon "vim-go: " | echohl Identifier | echon "generating ..."| echohl None + if g:go_dispatch_enabled && exists(':Make') == 2 + silent! exe 'Make' + elseif l:listtype == "locationlist" + silent! exe 'lmake!' + else + silent! exe 'make!' + endif + redraw! + + let errors = go#list#Get(l:listtype) + call go#list#Window(l:listtype, len(errors)) + if !empty(errors) + if !a:bang + call go#list#JumpToFirst(l:listtype) endif - redraw! + else + redraws! | echon "vim-go: " | echohl Function | echon "[generate] SUCCESS"| echohl None + endif - let errors = go#list#Get(l:listtype) - call go#list#Window(l:listtype, len(errors)) - if !empty(errors) - if !a:bang - call go#list#JumpToFirst(l:listtype) - endif - else - redraws! | echon "vim-go: " | echohl Function | echon "[generate] SUCCESS"| echohl None - endif - - let &makeprg = default_makeprg - let $GOPATH = old_gopath + let &makeprg = default_makeprg + let $GOPATH = old_gopath endfunction @@ -348,12 +348,12 @@ endfunction let s:test_compile_handlers = {} function! s:test_compile_handler(job, exit_status, data) - if !has_key(s:test_compile_handlers, a:job.id) - return - endif - let l:compile_file = s:test_compile_handlers[a:job.id] - call delete(l:compile_file) - unlet s:test_compile_handlers[a:job.id] + if !has_key(s:test_compile_handlers, a:job.id) + return + endif + let l:compile_file = s:test_compile_handlers[a:job.id] + call delete(l:compile_file) + unlet s:test_compile_handlers[a:job.id] endfunction -" vim:ts=4:sw=4:et +" vim: sw=2 ts=2 et diff --git a/autoload/go/complete.vim b/autoload/go/complete.vim index d7a66be5a4..96fc36c8b9 100644 --- a/autoload/go/complete.vim +++ b/autoload/go/complete.vim @@ -1,156 +1,156 @@ function! s:gocodeCurrentBuffer() - let buf = getline(1, '$') - if &encoding != 'utf-8' - let buf = map(buf, 'iconv(v:val, &encoding, "utf-8")') - endif - if &l:fileformat == 'dos' - " XXX: line2byte() depend on 'fileformat' option. - " so if fileformat is 'dos', 'buf' must include '\r'. - let buf = map(buf, 'v:val."\r"') - endif - let file = tempname() - call writefile(buf, file) - - return file + let buf = getline(1, '$') + if &encoding != 'utf-8' + let buf = map(buf, 'iconv(v:val, &encoding, "utf-8")') + endif + if &l:fileformat == 'dos' + " XXX: line2byte() depend on 'fileformat' option. + " so if fileformat is 'dos', 'buf' must include '\r'. + let buf = map(buf, 'v:val."\r"') + endif + let file = tempname() + call writefile(buf, file) + + return file endfunction function! s:gocodeCommand(cmd, preargs, args) - for i in range(0, len(a:args) - 1) - let a:args[i] = go#util#Shellescape(a:args[i]) - endfor - for i in range(0, len(a:preargs) - 1) - let a:preargs[i] = go#util#Shellescape(a:preargs[i]) - endfor - - let bin_path = go#path#CheckBinPath("gocode") - if empty(bin_path) - return - endif - - " we might hit cache problems, as gocode doesn't handle well different - " GOPATHS: https://github.com/nsf/gocode/issues/239 - let old_gopath = $GOPATH - let $GOPATH = go#path#Detect() - - let result = go#util#System(printf('%s %s %s %s', go#util#Shellescape(bin_path), join(a:preargs), go#util#Shellescape(a:cmd), join(a:args))) - - let $GOPATH = old_gopath - - if go#util#ShellError() != 0 - return "[\"0\", []]" - else - if &encoding != 'utf-8' - let result = iconv(result, 'utf-8', &encoding) - endif - return result + for i in range(0, len(a:args) - 1) + let a:args[i] = go#util#Shellescape(a:args[i]) + endfor + for i in range(0, len(a:preargs) - 1) + let a:preargs[i] = go#util#Shellescape(a:preargs[i]) + endfor + + let bin_path = go#path#CheckBinPath("gocode") + if empty(bin_path) + return + endif + + " we might hit cache problems, as gocode doesn't handle well different + " GOPATHS: https://github.com/nsf/gocode/issues/239 + let old_gopath = $GOPATH + let $GOPATH = go#path#Detect() + + let result = go#util#System(printf('%s %s %s %s', go#util#Shellescape(bin_path), join(a:preargs), go#util#Shellescape(a:cmd), join(a:args))) + + let $GOPATH = old_gopath + + if go#util#ShellError() != 0 + return "[\"0\", []]" + else + if &encoding != 'utf-8' + let result = iconv(result, 'utf-8', &encoding) endif + return result + endif endfunction function! s:gocodeCurrentBufferOpt(filename) - return '-in=' . a:filename + return '-in=' . a:filename endfunction let s:optionsEnabled = 0 function! s:gocodeEnableOptions() - if s:optionsEnabled - return - endif + if s:optionsEnabled + return + endif - let bin_path = go#path#CheckBinPath("gocode") - if empty(bin_path) - return - endif + let bin_path = go#path#CheckBinPath("gocode") + if empty(bin_path) + return + endif - let s:optionsEnabled = 1 + let s:optionsEnabled = 1 - call go#util#System(printf('%s set propose-builtins %s', go#util#Shellescape(bin_path), s:toBool(get(g:, 'go_gocode_propose_builtins', 1)))) - call go#util#System(printf('%s set autobuild %s', go#util#Shellescape(bin_path), s:toBool(get(g:, 'go_gocode_autobuild', 1)))) + call go#util#System(printf('%s set propose-builtins %s', go#util#Shellescape(bin_path), s:toBool(get(g:, 'go_gocode_propose_builtins', 1)))) + call go#util#System(printf('%s set autobuild %s', go#util#Shellescape(bin_path), s:toBool(get(g:, 'go_gocode_autobuild', 1)))) endfunction function! s:toBool(val) - if a:val | return 'true ' | else | return 'false' | endif + if a:val | return 'true ' | else | return 'false' | endif endfunction function! s:gocodeAutocomplete() - call s:gocodeEnableOptions() - - let filename = s:gocodeCurrentBuffer() - let result = s:gocodeCommand('autocomplete', - \ [s:gocodeCurrentBufferOpt(filename), '-f=vim'], - \ [expand('%:p'), go#util#OffsetCursor()]) - call delete(filename) - return result + call s:gocodeEnableOptions() + + let filename = s:gocodeCurrentBuffer() + let result = s:gocodeCommand('autocomplete', + \ [s:gocodeCurrentBufferOpt(filename), '-f=vim'], + \ [expand('%:p'), go#util#OffsetCursor()]) + call delete(filename) + return result endfunction function! go#complete#GetInfo() - let offset = go#util#OffsetCursor()+1 - let filename = s:gocodeCurrentBuffer() - let result = s:gocodeCommand('autocomplete', - \ [s:gocodeCurrentBufferOpt(filename), '-f=godit'], - \ [expand('%:p'), offset]) - call delete(filename) - - " first line is: Charcount,,NumberOfCandidates, i.e: 8,,1 - " following lines are candiates, i.e: func foo(name string),,foo( - let out = split(result, '\n') - - " no candidates are found - if len(out) == 1 - return "" - endif - - " only one candiate is found - if len(out) == 2 - return split(out[1], ',,')[0] - endif - - " to many candidates are available, pick one that maches the word under the - " cursor - let infos = [] - for info in out[1:] - call add(infos, split(info, ',,')[0]) - endfor - - let wordMatch = '\<' . expand("") . '\>' - " escape single quotes in wordMatch before passing it to filter - let wordMatch = substitute(wordMatch, "'", "''", "g") - let filtered = filter(infos, "v:val =~ '".wordMatch."'") - - if len(filtered) == 1 - return filtered[0] - endif - + let offset = go#util#OffsetCursor()+1 + let filename = s:gocodeCurrentBuffer() + let result = s:gocodeCommand('autocomplete', + \ [s:gocodeCurrentBufferOpt(filename), '-f=godit'], + \ [expand('%:p'), offset]) + call delete(filename) + + " first line is: Charcount,,NumberOfCandidates, i.e: 8,,1 + " following lines are candiates, i.e: func foo(name string),,foo( + let out = split(result, '\n') + + " no candidates are found + if len(out) == 1 return "" + endif + + " only one candiate is found + if len(out) == 2 + return split(out[1], ',,')[0] + endif + + " to many candidates are available, pick one that maches the word under the + " cursor + let infos = [] + for info in out[1:] + call add(infos, split(info, ',,')[0]) + endfor + + let wordMatch = '\<' . expand("") . '\>' + " escape single quotes in wordMatch before passing it to filter + let wordMatch = substitute(wordMatch, "'", "''", "g") + let filtered = filter(infos, "v:val =~ '".wordMatch."'") + + if len(filtered) == 1 + return filtered[0] + endif + + return "" endfunction function! go#complete#Info(auto) - " auto is true if we were called by g:go_auto_type_info's autocmd - let result = go#complete#GetInfo() - if !empty(result) - " if auto, and the result is a PANIC by gocode, hide it - if a:auto && result ==# 'PANIC PANIC PANIC' | return | endif - echo "vim-go: " | echohl Function | echon result | echohl None - endif + " auto is true if we were called by g:go_auto_type_info's autocmd + let result = go#complete#GetInfo() + if !empty(result) + " if auto, and the result is a PANIC by gocode, hide it + if a:auto && result ==# 'PANIC PANIC PANIC' | return | endif + echo "vim-go: " | echohl Function | echon result | echohl None + endif endfunction function! s:trim_bracket(val) - let a:val.word = substitute(a:val.word, '[(){}\[\]]\+$', '', '') - return a:val + let a:val.word = substitute(a:val.word, '[(){}\[\]]\+$', '', '') + return a:val endfunction function! go#complete#Complete(findstart, base) - "findstart = 1 when we need to get the text length - if a:findstart == 1 - execute "silent let g:gocomplete_completions = " . s:gocodeAutocomplete() - return col('.') - g:gocomplete_completions[0] - 1 - "findstart = 0 when we need to return the list of completions - else - let s = getline(".")[col('.') - 1] - if s =~ '[(){}\{\}]' - return map(copy(g:gocomplete_completions[1]), 's:trim_bracket(v:val)') - endif - return g:gocomplete_completions[1] + "findstart = 1 when we need to get the text length + if a:findstart == 1 + execute "silent let g:gocomplete_completions = " . s:gocodeAutocomplete() + return col('.') - g:gocomplete_completions[0] - 1 + "findstart = 0 when we need to return the list of completions + else + let s = getline(".")[col('.') - 1] + if s =~ '[(){}\{\}]' + return map(copy(g:gocomplete_completions[1]), 's:trim_bracket(v:val)') endif + return g:gocomplete_completions[1] + endif endf -" vim:ts=4:sw=4:et +" vim: sw=2 ts=2 et diff --git a/autoload/go/coverage.vim b/autoload/go/coverage.vim index 2a45e523bb..83082174f2 100644 --- a/autoload/go/coverage.vim +++ b/autoload/go/coverage.vim @@ -4,16 +4,16 @@ let s:toggle = 0 " the current buffers highlighting to show covered and uncovered sections of " the code. If run again it clears the annotation. function! go#coverage#BufferToggle(bang, ...) - if s:toggle - call go#coverage#Clear() - return - endif + if s:toggle + call go#coverage#Clear() + return + endif - if a:0 == 0 - return call(function('go#coverage#Buffer'), [a:bang]) - endif + if a:0 == 0 + return call(function('go#coverage#Buffer'), [a:bang]) + endif - return call(function('go#coverage#Buffer'), [a:bang] + a:000) + return call(function('go#coverage#Buffer'), [a:bang] + a:000) endfunction " Buffer creates a new cover profile with 'go test -coverprofile' and changes @@ -21,229 +21,229 @@ endfunction " the code. Calling it again reruns the tests and shows the last updated " coverage. function! go#coverage#Buffer(bang, ...) - " we use matchaddpos() which was introduce with 7.4.330, be sure we have - " it: http://ftp.vim.org/vim/patches/7.4/7.4.330 - if !exists("*matchaddpos") - call go#util#EchoError("GoCoverage is supported with Vim version 7.4-330 or later") - return -1 + " we use matchaddpos() which was introduce with 7.4.330, be sure we have + " it: http://ftp.vim.org/vim/patches/7.4/7.4.330 + if !exists("*matchaddpos") + call go#util#EchoError("GoCoverage is supported with Vim version 7.4-330 or later") + return -1 + endif + + " check if there is any test file, if not we just return + let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd ' : 'cd ' + let dir = getcwd() + try + execute cd . fnameescape(expand("%:p:h")) + if empty(glob("*_test.go")) + call go#util#EchoError("no tests files available") + return endif + finally + execute cd . fnameescape(dir) + endtry - " check if there is any test file, if not we just return - let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd ' : 'cd ' - let dir = getcwd() - try - execute cd . fnameescape(expand("%:p:h")) - if empty(glob("*_test.go")) - call go#util#EchoError("no tests files available") - return - endif - finally - execute cd . fnameescape(dir) - endtry - - let s:toggle = 1 - let l:tmpname = tempname() - let args = [a:bang, 0, "-coverprofile", l:tmpname] - - if a:0 - call extend(args, a:000) - endif + let s:toggle = 1 + let l:tmpname = tempname() + let args = [a:bang, 0, "-coverprofile", l:tmpname] - let disabled_term = 0 - if get(g:, 'go_term_enabled') - let disabled_term = 1 - let g:go_term_enabled = 0 - endif + if a:0 + call extend(args, a:000) + endif - let id = call('go#cmd#Test', args) + let disabled_term = 0 + if get(g:, 'go_term_enabled') + let disabled_term = 1 + let g:go_term_enabled = 0 + endif - if disabled_term - let g:go_term_enabled = 1 - endif + let id = call('go#cmd#Test', args) - if has('nvim') - call go#jobcontrol#AddHandler(function('s:coverage_handler')) - let s:coverage_handler_jobs[id] = l:tmpname - return - endif + if disabled_term + let g:go_term_enabled = 1 + endif - if go#util#ShellError() == 0 - call go#coverage#overlay(l:tmpname) - endif + if has('nvim') + call go#jobcontrol#AddHandler(function('s:coverage_handler')) + let s:coverage_handler_jobs[id] = l:tmpname + return + endif + + if go#util#ShellError() == 0 + call go#coverage#overlay(l:tmpname) + endif - call delete(l:tmpname) + call delete(l:tmpname) endfunction " Clear clears and resets the buffer annotation matches function! go#coverage#Clear() - " only reset the syntax if the user has syntax enabled - if !empty(&syntax) - if exists("g:syntax_on") | syntax enable | endif - endif + " only reset the syntax if the user has syntax enabled + if !empty(&syntax) + if exists("g:syntax_on") | syntax enable | endif + endif - if exists("s:toggle") | let s:toggle = 0 | endif + if exists("s:toggle") | let s:toggle = 0 | endif - " remove the autocmd we defined - if exists("#BufWinLeave#") - autocmd! BufWinLeave - endif + " remove the autocmd we defined + if exists("#BufWinLeave#") + autocmd! BufWinLeave + endif - call clearmatches() + call clearmatches() endfunction " Browser creates a new cover profile with 'go test -coverprofile' and opens " a new HTML coverage page from that profile in a new browser function! go#coverage#Browser(bang, ...) - let l:tmpname = tempname() - let args = [a:bang, 0, "-coverprofile", l:tmpname] - - if a:0 - call extend(args, a:000) - endif - let id = call('go#cmd#Test', args) - if has('nvim') - call go#jobcontrol#AddHandler(function('s:coverage_browser_handler')) - let s:coverage_browser_handler_jobs[id] = l:tmpname - return - endif - if go#util#ShellError() == 0 - let openHTML = 'go tool cover -html='.l:tmpname - call go#tool#ExecuteInDir(openHTML) - endif - - call delete(l:tmpname) + let l:tmpname = tempname() + let args = [a:bang, 0, "-coverprofile", l:tmpname] + + if a:0 + call extend(args, a:000) + endif + let id = call('go#cmd#Test', args) + if has('nvim') + call go#jobcontrol#AddHandler(function('s:coverage_browser_handler')) + let s:coverage_browser_handler_jobs[id] = l:tmpname + return + endif + if go#util#ShellError() == 0 + let openHTML = 'go tool cover -html='.l:tmpname + call go#tool#ExecuteInDir(openHTML) + endif + + call delete(l:tmpname) endfunction " Parses a single line from the cover file generated via go test -coverprofile " and returns a single coverage profile block. function! go#coverage#parsegocoverline(line) - " file:startline.col,endline.col numstmt count - let mx = '\([^:]\+\):\(\d\+\)\.\(\d\+\),\(\d\+\)\.\(\d\+\)\s\(\d\+\)\s\(\d\+\)' - let tokens = matchlist(a:line, mx) - let ret = {} - let ret.file = tokens[1] - let ret.startline = str2nr(tokens[2]) - let ret.startcol = str2nr(tokens[3]) - let ret.endline = str2nr(tokens[4]) - let ret.endcol = str2nr(tokens[5]) - let ret.numstmt = tokens[6] - let ret.cnt = tokens[7] - return ret + " file:startline.col,endline.col numstmt count + let mx = '\([^:]\+\):\(\d\+\)\.\(\d\+\),\(\d\+\)\.\(\d\+\)\s\(\d\+\)\s\(\d\+\)' + let tokens = matchlist(a:line, mx) + let ret = {} + let ret.file = tokens[1] + let ret.startline = str2nr(tokens[2]) + let ret.startcol = str2nr(tokens[3]) + let ret.endline = str2nr(tokens[4]) + let ret.endcol = str2nr(tokens[5]) + let ret.numstmt = tokens[6] + let ret.cnt = tokens[7] + return ret endfunction " Generates matches to be added to matchaddpos for the given coverage profile " block function! go#coverage#genmatch(cov) - let color = 'covered' - if a:cov.cnt == 0 - let color = 'uncover' - endif + let color = 'covered' + if a:cov.cnt == 0 + let color = 'uncover' + endif - let matches = [] - - " if start and end are the same, also specify the byte length - " example: foo.go:92.2,92.65 1 0 - if a:cov.startline == a:cov.endline - call add(matches, { - \ 'group': color, - \ 'pos': [[a:cov.startline, a:cov.startcol, a:cov.endcol - a:cov.startcol]], - \ 'priority': 2, - \ }) - return matches - endif + let matches = [] - " add start columns. Because we don't know the length of the of - " the line, we assume it is at maximum 200 bytes. I know this is hacky, - " but that's only way of fixing the issue - call add(matches, { - \ 'group': color, - \ 'pos': [[a:cov.startline, a:cov.startcol, 200]], - \ 'priority': 2, - \ }) - - " and then the remaining lines - let start_line = a:cov.startline - while start_line < a:cov.endline - let start_line += 1 - call add(matches, { - \ 'group': color, - \ 'pos': [[start_line]], - \ 'priority': 2, - \ }) - endwhile - - " finally end columns + " if start and end are the same, also specify the byte length + " example: foo.go:92.2,92.65 1 0 + if a:cov.startline == a:cov.endline call add(matches, { - \ 'group': color, - \ 'pos': [[a:cov.endline, a:cov.endcol-1]], - \ 'priority': 2, - \ }) - + \ 'group': color, + \ 'pos': [[a:cov.startline, a:cov.startcol, a:cov.endcol - a:cov.startcol]], + \ 'priority': 2, + \ }) return matches + endif + + " add start columns. Because we don't know the length of the of + " the line, we assume it is at maximum 200 bytes. I know this is hacky, + " but that's only way of fixing the issue + call add(matches, { + \ 'group': color, + \ 'pos': [[a:cov.startline, a:cov.startcol, 200]], + \ 'priority': 2, + \ }) + + " and then the remaining lines + let start_line = a:cov.startline + while start_line < a:cov.endline + let start_line += 1 + call add(matches, { + \ 'group': color, + \ 'pos': [[start_line]], + \ 'priority': 2, + \ }) + endwhile + + " finally end columns + call add(matches, { + \ 'group': color, + \ 'pos': [[a:cov.endline, a:cov.endcol-1]], + \ 'priority': 2, + \ }) + + return matches endfunction " Reads the given coverprofile file and annotates the current buffer function! go#coverage#overlay(file) - if !filereadable(a:file) - return - endif - let lines = readfile(a:file) - - " cover mode, by default it's 'set'. Just here for debugging purposes - let mode = lines[0] - - " contains matches for matchaddpos() - let matches = [] - - " first mark all lines as normaltext. We use a custom group to not - " interfere with other buffers highlightings. Because the priority is - " lower than the cover and uncover matches, it'll be overriden. - let cnt = 1 - while cnt <= line('$') - call add(matches, {'group': 'normaltext', 'pos': [cnt], 'priority': 1}) - let cnt += 1 - endwhile - - let fname = expand('%:t') - - " when called for a _test.go file, run the coverage for the actuall file - " file - if fname =~# '^\f\+_test\.go$' - let l:root = split(fname, '_test.go$')[0] - let fname = l:root . ".go" - - if !filereadable(fname) - call go#util#EchoError("couldn't find ".fname) - return - endif - - " open the alternate file to show the coverage - exe ":edit ". fnamemodify(fname, ":p") + if !filereadable(a:file) + return + endif + let lines = readfile(a:file) + + " cover mode, by default it's 'set'. Just here for debugging purposes + let mode = lines[0] + + " contains matches for matchaddpos() + let matches = [] + + " first mark all lines as normaltext. We use a custom group to not + " interfere with other buffers highlightings. Because the priority is + " lower than the cover and uncover matches, it'll be overriden. + let cnt = 1 + while cnt <= line('$') + call add(matches, {'group': 'normaltext', 'pos': [cnt], 'priority': 1}) + let cnt += 1 + endwhile + + let fname = expand('%:t') + + " when called for a _test.go file, run the coverage for the actuall file + " file + if fname =~# '^\f\+_test\.go$' + let l:root = split(fname, '_test.go$')[0] + let fname = l:root . ".go" + + if !filereadable(fname) + call go#util#EchoError("couldn't find ".fname) + return endif - for line in lines[1:] - let cov = go#coverage#parsegocoverline(line) + " open the alternate file to show the coverage + exe ":edit ". fnamemodify(fname, ":p") + endif + + for line in lines[1:] + let cov = go#coverage#parsegocoverline(line) - " TODO(arslan): for now only include the coverage for the current - " buffer - if fname != fnamemodify(cov.file, ':t') - continue - endif + " TODO(arslan): for now only include the coverage for the current + " buffer + if fname != fnamemodify(cov.file, ':t') + continue + endif - call extend(matches, go#coverage#genmatch(cov)) - endfor + call extend(matches, go#coverage#genmatch(cov)) + endfor - syntax manual - highlight normaltext term=bold ctermfg=darkgrey guifg=#75715E - highlight covered term=bold ctermfg=green guifg=#A6E22E - highlight uncover term=bold ctermfg=red guifg=#F92672 + syntax manual + highlight normaltext term=bold ctermfg=darkgrey guifg=#75715E + highlight covered term=bold ctermfg=green guifg=#A6E22E + highlight uncover term=bold ctermfg=red guifg=#F92672 - " clear the matches if we leave the buffer - autocmd BufWinLeave call go#coverage#Clear() + " clear the matches if we leave the buffer + autocmd BufWinLeave call go#coverage#Clear() - for m in matches - call matchaddpos(m.group, m.pos) - endfor + for m in matches + call matchaddpos(m.group, m.pos) + endfor endfunction @@ -255,32 +255,31 @@ let s:coverage_handler_jobs = {} let s:coverage_browser_handler_jobs = {} function! s:coverage_handler(job, exit_status, data) - if !has_key(s:coverage_handler_jobs, a:job.id) - return - endif - let l:tmpname = s:coverage_handler_jobs[a:job.id] - if a:exit_status == 0 - call go#coverage#overlay(l:tmpname) - endif - - call delete(l:tmpname) - unlet s:coverage_handler_jobs[a:job.id] + if !has_key(s:coverage_handler_jobs, a:job.id) + return + endif + let l:tmpname = s:coverage_handler_jobs[a:job.id] + if a:exit_status == 0 + call go#coverage#overlay(l:tmpname) + endif + + call delete(l:tmpname) + unlet s:coverage_handler_jobs[a:job.id] endfunction function! s:coverage_browser_handler(job, exit_status, data) - if !has_key(s:coverage_browser_handler_jobs, a:job.id) - return - endif - - let l:tmpname = s:coverage_browser_handler_jobs[a:job.id] - if a:exit_status == 0 - let openHTML = 'go tool cover -html='.l:tmpname - call go#tool#ExecuteInDir(openHTML) - endif - - call delete(l:tmpname) - unlet s:coverage_browser_handler_jobs[a:job.id] + if !has_key(s:coverage_browser_handler_jobs, a:job.id) + return + endif + + let l:tmpname = s:coverage_browser_handler_jobs[a:job.id] + if a:exit_status == 0 + let openHTML = 'go tool cover -html='.l:tmpname + call go#tool#ExecuteInDir(openHTML) + endif + + call delete(l:tmpname) + unlet s:coverage_browser_handler_jobs[a:job.id] endfunction - -" vim:ts=4:sw=4:et +" vim: sw=2 ts=2 et diff --git a/autoload/go/def.vim b/autoload/go/def.vim index 969230cbcd..bea951178f 100644 --- a/autoload/go/def.vim +++ b/autoload/go/def.vim @@ -2,237 +2,238 @@ let s:go_stack = [] let s:go_stack_level = 0 function! go#def#Jump(mode) - let old_gopath = $GOPATH - let $GOPATH = go#path#Detect() - - let fname = fnamemodify(expand("%"), ':p:gs?\\?/?') - if &modified - " Write current unsaved buffer to a temp file and use the modified content - let l:tmpname = tempname() - call writefile(getline(1, '$'), l:tmpname) - let fname = l:tmpname - endif - - " so guru right now is slow for some people. previously we were using - " godef which also has it's own quirks. But this issue come up so many - " times I've decided to support both. By default we still use guru as it - " covers all edge cases, but now anyone can switch to godef if they wish - let bin_name = get(g:, 'go_def_mode', 'guru') - if bin_name == 'godef' - let bin_path = go#path#CheckBinPath("godef") - if empty(bin_path) - let $GOPATH = old_gopath - return - endif - let command = printf("%s -f=%s -o=%s -t", bin_path, fname, go#util#OffsetCursor()) - let out = go#util#System(command) - - " append the type information to the same line so our - " jump_to_declaration() function can parse it. This makes it - " compatible with guru definition as well too - let out = join(split(out, '\n'), ':') - elseif bin_name == 'guru' - let bin_path = go#path#CheckBinPath("guru") - if empty(bin_path) - let $GOPATH = old_gopath - return - endif - - let flags = "" - if exists('g:go_guru_tags') - let tags = get(g:, 'go_guru_tags') - let flags = printf(" -tags %s", tags) - endif - - let fname = shellescape(fname.':#'.go#util#OffsetCursor()) - let command = printf("%s %s definition %s", bin_path, flags, fname) - let out = go#util#System(command) - else - call go#util#EchoError('go_def_mode value: '. bin_name .' is not valid. Valid values are: [godef, guru]') - return - endif - - if exists("l:tmpname") - call delete(l:tmpname) - endif - - if go#util#ShellError() != 0 - call go#util#EchoError(out) - return - endif - - call s:jump_to_declaration(out, a:mode) - let $GOPATH = old_gopath + let old_gopath = $GOPATH + let $GOPATH = go#path#Detect() + + let fname = fnamemodify(expand("%"), ':p:gs?\\?/?') + if &modified + " Write current unsaved buffer to a temp file and use the modified content + let l:tmpname = tempname() + call writefile(getline(1, '$'), l:tmpname) + let fname = l:tmpname + endif + + " so guru right now is slow for some people. previously we were using + " godef which also has it's own quirks. But this issue come up so many + " times I've decided to support both. By default we still use guru as it + " covers all edge cases, but now anyone can switch to godef if they wish + let bin_name = get(g:, 'go_def_mode', 'guru') + if bin_name == 'godef' + let bin_path = go#path#CheckBinPath("godef") + if empty(bin_path) + let $GOPATH = old_gopath + return + endif + let command = printf("%s -f=%s -o=%s -t", bin_path, fname, go#util#OffsetCursor()) + let out = go#util#System(command) + + " append the type information to the same line so our + " jump_to_declaration() function can parse it. This makes it + " compatible with guru definition as well too + let out = join(split(out, '\n'), ':') + elseif bin_name == 'guru' + let bin_path = go#path#CheckBinPath("guru") + if empty(bin_path) + let $GOPATH = old_gopath + return + endif + + let flags = "" + if exists('g:go_guru_tags') + let tags = get(g:, 'go_guru_tags') + let flags = printf(" -tags %s", tags) + endif + + let fname = shellescape(fname.':#'.go#util#OffsetCursor()) + let command = printf("%s %s definition %s", bin_path, flags, fname) + let out = go#util#System(command) + else + call go#util#EchoError('go_def_mode value: '. bin_name .' is not valid. Valid values are: [godef, guru]') + return + endif + + if exists("l:tmpname") + call delete(l:tmpname) + endif + + if go#util#ShellError() != 0 + call go#util#EchoError(out) + return + endif + + call s:jump_to_declaration(out, a:mode) + let $GOPATH = old_gopath endfunction function! s:jump_to_declaration(out, mode) - " strip line ending - let out = split(a:out, go#util#LineEnding())[0] - if go#util#IsWin() - let parts = split(out, '\(^[a-zA-Z]\)\@,:navigate :jump ,q:exit'] + let stackOut = ['" ,:navigate :jump ,q:exit'] - let i = 0 - while i < len(s:go_stack) - let entry = s:go_stack[i] - let prefix = "" + let i = 0 + while i < len(s:go_stack) + let entry = s:go_stack[i] + let prefix = "" - if i == s:go_stack_level - let prefix = ">" - else - let prefix = " " - endif + if i == s:go_stack_level + let prefix = ">" + else + let prefix = " " + endif - call add(stackOut, printf("%s %d %s|%d col %d|%s", - \ prefix, i+1, entry["file"], entry["line"], entry["col"], entry["ident"])) - let i += 1 - endwhile + call add(stackOut, printf("%s %d %s|%d col %d|%s", + \ prefix, i+1, entry["file"], entry["line"], entry["col"], entry["ident"])) + let i += 1 + endwhile - if s:go_stack_level == i - call add(stackOut, "> ") - endif + if s:go_stack_level == i + call add(stackOut, "> ") + endif - call go#ui#OpenWindow("GoDef Stack", stackOut, "godefstack") + call go#ui#OpenWindow("GoDef Stack", stackOut, "godefstack") - noremap :call go#def#SelectStackEntry() - noremap :call go#ui#CloseWindow() - noremap q :call go#ui#CloseWindow() + noremap :call go#def#SelectStackEntry() + noremap :call go#ui#CloseWindow() + noremap q :call go#ui#CloseWindow() endfunction function! go#def#StackClear(...) - let s:go_stack = [] - let s:go_stack_level = 0 + let s:go_stack = [] + let s:go_stack_level = 0 endfunction function! go#def#StackPop(...) - if len(s:go_stack) == 0 - call go#util#EchoError("godef stack empty") - return - endif - - if s:go_stack_level == 0 - call go#util#EchoError("at bottom of the godef stack") - return - endif - - if !len(a:000) - let numPop = 1 - else - let numPop = a:1 - endif - - let newLevel = str2nr(s:go_stack_level) - str2nr(numPop) - call go#def#Stack(newLevel + 1) + if len(s:go_stack) == 0 + call go#util#EchoError("godef stack empty") + return + endif + + if s:go_stack_level == 0 + call go#util#EchoError("at bottom of the godef stack") + return + endif + + if !len(a:000) + let numPop = 1 + else + let numPop = a:1 + endif + + let newLevel = str2nr(s:go_stack_level) - str2nr(numPop) + call go#def#Stack(newLevel + 1) endfunction function! go#def#Stack(...) - if len(s:go_stack) == 0 - call go#util#EchoError("godef stack empty") - return - endif - - if !len(a:000) - " Display interactive stack - call go#def#StackUI() - return - else - let jumpTarget = a:1 - endif - - if jumpTarget !~ '^\d\+$' - if jumpTarget !~ '^\s*$' - call go#util#EchoError("location must be a number") - endif - return - endif - - let jumpTarget = str2nr(jumpTarget) - 1 - - if jumpTarget >= 0 && jumpTarget < len(s:go_stack) - let s:go_stack_level = jumpTarget - let target = s:go_stack[s:go_stack_level] - - " jump - exec 'edit '.target["file"] - call cursor(target["line"], target["col"]) - normal! zz - else - call go#util#EchoError("invalid location. Try :GoDefStack to see the list of valid entries") - endif + if len(s:go_stack) == 0 + call go#util#EchoError("godef stack empty") + return + endif + + if !len(a:000) + " Display interactive stack + call go#def#StackUI() + return + else + let jumpTarget = a:1 + endif + + if jumpTarget !~ '^\d\+$' + if jumpTarget !~ '^\s*$' + call go#util#EchoError("location must be a number") + endif + return + endif + + let jumpTarget = str2nr(jumpTarget) - 1 + + if jumpTarget >= 0 && jumpTarget < len(s:go_stack) + let s:go_stack_level = jumpTarget + let target = s:go_stack[s:go_stack_level] + + " jump + exec 'edit '.target["file"] + call cursor(target["line"], target["col"]) + normal! zz + else + call go#util#EchoError("invalid location. Try :GoDefStack to see the list of valid entries") + endif endfunction +" vim: sw=2 ts=2 et diff --git a/autoload/go/doc.vim b/autoload/go/doc.vim index a380f0aab5..03d319f970 100644 --- a/autoload/go/doc.vim +++ b/autoload/go/doc.vim @@ -5,151 +5,151 @@ let s:buf_nr = -1 if !exists("g:go_doc_command") - let g:go_doc_command = "godoc" + let g:go_doc_command = "godoc" endif if !exists("g:go_doc_options") - let g:go_doc_options = "" + let g:go_doc_options = "" endif " returns the package and exported name. exported name might be empty. " ie: fmt and Println " ie: github.com/fatih/set and New function! s:godocWord(args) - if !executable('godoc') - let msg = "godoc command not found." - let msg .= " install with: go get golang.org/x/tools/cmd/godoc" - call go#util#echoWarning(msg) - return [] - endif - - if !len(a:args) - let oldiskeyword = &iskeyword - setlocal iskeyword+=. - let word = expand('') - let &iskeyword = oldiskeyword - let word = substitute(word, '[^a-zA-Z0-9\\/._~-]', '', 'g') - let words = split(word, '\.\ze[^./]\+$') - else - let words = a:args - endif - - if !len(words) - return [] - endif - - let pkg = words[0] - if len(words) == 1 - let exported_name = "" - else - let exported_name = words[1] - endif - - let packages = go#tool#Imports() - - if has_key(packages, pkg) - let pkg = packages[pkg] - endif - - return [pkg, exported_name] + if !executable('godoc') + let msg = "godoc command not found." + let msg .= " install with: go get golang.org/x/tools/cmd/godoc" + call go#util#echoWarning(msg) + return [] + endif + + if !len(a:args) + let oldiskeyword = &iskeyword + setlocal iskeyword+=. + let word = expand('') + let &iskeyword = oldiskeyword + let word = substitute(word, '[^a-zA-Z0-9\\/._~-]', '', 'g') + let words = split(word, '\.\ze[^./]\+$') + else + let words = a:args + endif + + if !len(words) + return [] + endif + + let pkg = words[0] + if len(words) == 1 + let exported_name = "" + else + let exported_name = words[1] + endif + + let packages = go#tool#Imports() + + if has_key(packages, pkg) + let pkg = packages[pkg] + endif + + return [pkg, exported_name] endfunction function! s:godocNotFound(content) - if len(a:content) == 0 - return 1 - endif + if len(a:content) == 0 + return 1 + endif - return a:content =~# '^.*: no such file or directory\n$' + return a:content =~# '^.*: no such file or directory\n$' endfunction function! go#doc#OpenBrowser(...) - let pkgs = s:godocWord(a:000) - if empty(pkgs) - return - endif + let pkgs = s:godocWord(a:000) + if empty(pkgs) + return + endif - let pkg = pkgs[0] - let exported_name = pkgs[1] + let pkg = pkgs[0] + let exported_name = pkgs[1] - " example url: https://godoc.org/github.com/fatih/set#Set - let godoc_url = "https://godoc.org/" . pkg . "#" . exported_name - call go#tool#OpenBrowser(godoc_url) + " example url: https://godoc.org/github.com/fatih/set#Set + let godoc_url = "https://godoc.org/" . pkg . "#" . exported_name + call go#tool#OpenBrowser(godoc_url) endfunction function! go#doc#Open(newmode, mode, ...) - if len(a:000) - " check if we have 'godoc' and use it automatically - let bin_path = go#path#CheckBinPath('godoc') - if empty(bin_path) - return - endif - - let command = printf("%s %s", bin_path, join(a:000, ' ')) - else - " check if we have 'gogetdoc' and use it automatically - let bin_path = go#path#CheckBinPath('gogetdoc') - if empty(bin_path) - return - endif - - let offset = go#util#OffsetCursor() - let fname = expand("%:p:gs!\\!/!") - let pos = shellescape(fname.':#'.offset) - - let command = printf("%s -pos %s", bin_path, pos) + if len(a:000) + " check if we have 'godoc' and use it automatically + let bin_path = go#path#CheckBinPath('godoc') + if empty(bin_path) + return endif - let out = go#util#System(command) - if go#util#ShellError() != 0 - call go#util#EchoError(out) - return + let command = printf("%s %s", bin_path, join(a:000, ' ')) + else + " check if we have 'gogetdoc' and use it automatically + let bin_path = go#path#CheckBinPath('gogetdoc') + if empty(bin_path) + return endif - call s:GodocView(a:newmode, a:mode, out) -endfunction + let offset = go#util#OffsetCursor() + let fname = expand("%:p:gs!\\!/!") + let pos = shellescape(fname.':#'.offset) -function! s:GodocView(newposition, position, content) - " reuse existing buffer window if it exists otherwise create a new one - if !bufexists(s:buf_nr) - execute a:newposition - sil file `="[Godoc]"` - let s:buf_nr = bufnr('%') - elseif bufwinnr(s:buf_nr) == -1 - execute a:position - execute s:buf_nr . 'buffer' - elseif bufwinnr(s:buf_nr) != bufwinnr('%') - execute bufwinnr(s:buf_nr) . 'wincmd w' - endif + let command = printf("%s -pos %s", bin_path, pos) + endif - " cap buffer height to 20, but resize it for smaller contents - let max_height = 20 - let content_height = len(split(a:content, "\n")) - if content_height > max_height - exe 'resize ' . max_height - else - exe 'resize ' . content_height - endif + let out = go#util#System(command) + if go#util#ShellError() != 0 + call go#util#EchoError(out) + return + endif - setlocal filetype=godoc - setlocal bufhidden=delete - setlocal buftype=nofile - setlocal noswapfile - setlocal nobuflisted - setlocal nocursorline - setlocal nocursorcolumn - setlocal iskeyword+=: - setlocal iskeyword-=- - - setlocal modifiable - %delete _ - call append(0, split(a:content, "\n")) - sil $delete _ - setlocal nomodifiable - sil normal! gg - - " close easily with or enter - noremap :close - noremap :close + call s:GodocView(a:newmode, a:mode, out) +endfunction + +function! s:GodocView(newposition, position, content) + " reuse existing buffer window if it exists otherwise create a new one + if !bufexists(s:buf_nr) + execute a:newposition + sil file `="[Godoc]"` + let s:buf_nr = bufnr('%') + elseif bufwinnr(s:buf_nr) == -1 + execute a:position + execute s:buf_nr . 'buffer' + elseif bufwinnr(s:buf_nr) != bufwinnr('%') + execute bufwinnr(s:buf_nr) . 'wincmd w' + endif + + " cap buffer height to 20, but resize it for smaller contents + let max_height = 20 + let content_height = len(split(a:content, "\n")) + if content_height > max_height + exe 'resize ' . max_height + else + exe 'resize ' . content_height + endif + + setlocal filetype=godoc + setlocal bufhidden=delete + setlocal buftype=nofile + setlocal noswapfile + setlocal nobuflisted + setlocal nocursorline + setlocal nocursorcolumn + setlocal iskeyword+=: + setlocal iskeyword-=- + + setlocal modifiable + %delete _ + call append(0, split(a:content, "\n")) + sil $delete _ + setlocal nomodifiable + sil normal! gg + + " close easily with or enter + noremap :close + noremap :close endfunction -" vim:ts=2:sw=2:et +" vim: sw=2 ts=2 et diff --git a/autoload/go/fmt.vim b/autoload/go/fmt.vim index f5070090d4..eb49553d9e 100644 --- a/autoload/go/fmt.vim +++ b/autoload/go/fmt.vim @@ -24,23 +24,23 @@ " if !exists("g:go_fmt_command") - let g:go_fmt_command = "gofmt" + let g:go_fmt_command = "gofmt" endif if !exists("g:go_goimports_bin") - let g:go_goimports_bin = "goimports" + let g:go_goimports_bin = "goimports" endif if !exists('g:go_fmt_fail_silently') - let g:go_fmt_fail_silently = 0 + let g:go_fmt_fail_silently = 0 endif if !exists('g:go_fmt_options') - let g:go_fmt_options = '' + let g:go_fmt_options = '' endif if !exists("g:go_fmt_experimental") - let g:go_fmt_experimental = 0 + let g:go_fmt_experimental = 0 endif " we have those problems : @@ -52,160 +52,159 @@ endif " this and have VimL experience, please look at the function for " improvements, patches are welcome :) function! go#fmt#Format(withGoimport) - if g:go_fmt_experimental == 1 - " Using winsaveview to save/restore cursor state has the problem of - " closing folds on save: - " https://github.com/fatih/vim-go/issues/502 - " One fix is to use mkview instead. Unfortunately, this sometimes causes - " other bad side effects: - " https://github.com/fatih/vim-go/issues/728 - " and still closes all folds if foldlevel>0: - " https://github.com/fatih/vim-go/issues/732 - let l:curw = {} - try - mkview! - catch - let l:curw = winsaveview() - endtry - else - " Save cursor position and many other things. - let l:curw = winsaveview() - endif - - " Write current unsaved buffer to a temp file - let l:tmpname = tempname() - call writefile(getline(1, '$'), l:tmpname) - - if g:go_fmt_experimental == 1 - " save our undo file to be restored after we are done. This is needed to - " prevent an additional undo jump due to BufWritePre auto command and also - " restore 'redo' history because it's getting being destroyed every - " BufWritePre - let tmpundofile = tempname() - exe 'wundo! ' . tmpundofile - endif - - " get the command first so we can test it - let bin_name = g:go_fmt_command - if a:withGoimport == 1 - let bin_name = g:go_goimports_bin - endif - - " check if the user has installed command binary. - " For example if it's goimports, let us check if it's installed, - " if not the user get's a warning via go#path#CheckBinPath() - let bin_path = go#path#CheckBinPath(bin_name) - if empty(bin_path) - return + if g:go_fmt_experimental == 1 + " Using winsaveview to save/restore cursor state has the problem of + " closing folds on save: + " https://github.com/fatih/vim-go/issues/502 + " One fix is to use mkview instead. Unfortunately, this sometimes causes + " other bad side effects: + " https://github.com/fatih/vim-go/issues/728 + " and still closes all folds if foldlevel>0: + " https://github.com/fatih/vim-go/issues/732 + let l:curw = {} + try + mkview! + catch + let l:curw = winsaveview() + endtry + else + " Save cursor position and many other things. + let l:curw = winsaveview() + endif + + " Write current unsaved buffer to a temp file + let l:tmpname = tempname() + call writefile(getline(1, '$'), l:tmpname) + + if g:go_fmt_experimental == 1 + " save our undo file to be restored after we are done. This is needed to + " prevent an additional undo jump due to BufWritePre auto command and also + " restore 'redo' history because it's getting being destroyed every + " BufWritePre + let tmpundofile = tempname() + exe 'wundo! ' . tmpundofile + endif + + " get the command first so we can test it + let bin_name = g:go_fmt_command + if a:withGoimport == 1 + let bin_name = g:go_goimports_bin + endif + + " check if the user has installed command binary. + " For example if it's goimports, let us check if it's installed, + " if not the user get's a warning via go#path#CheckBinPath() + let bin_path = go#path#CheckBinPath(bin_name) + if empty(bin_path) + return + endif + + if bin_name != "gofmt" + " change GOPATH too, so goimports can pick up the correct library + let old_gopath = $GOPATH + let $GOPATH = go#path#Detect() + endif + + " populate the final command with user based fmt options + let command = bin_path . ' -w ' + if a:withGoimport != 1 + let command = command . g:go_fmt_options + endif + + if bin_name == "goimports" + if !exists('b:goimports_vendor_compatible') + let out = go#util#System(bin_path . " --help") + if out !~ "-srcdir" + call go#util#EchoWarning("vim-go: goimports does not support srcdir. update with: :GoUpdateBinaries") + else + let b:goimports_vendor_compatible = 1 + endif endif - if bin_name != "gofmt" - " change GOPATH too, so goimports can pick up the correct library - let old_gopath = $GOPATH - let $GOPATH = go#path#Detect() + if exists('b:goimports_vendor_compatible') && b:goimports_vendor_compatible + let ssl_save = &shellslash + set noshellslash + let command = command . '-srcdir ' . shellescape(expand("%:p:h")) + let &shellslash = ssl_save endif - - " populate the final command with user based fmt options - let command = bin_path . ' -w ' - if a:withGoimport != 1 - let command = command . g:go_fmt_options + endif + + " execute our command... + if go#util#IsWin() + let l:tmpname = tr(l:tmpname, '\', '/') + endif + let out = go#util#System(command . " " . l:tmpname) + + if bin_name != "gofmt" + let $GOPATH = old_gopath + endif + + let l:listtype = "locationlist" + "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\+') + if go#util#ShellError() == 0 + " remove undo point caused via BufWritePre + try | silent undojoin | catch | endtry + + " Replace current file with temp file, then reload buffer + let old_fileformat = &fileformat + call rename(l:tmpname, expand('%')) + silent edit! + let &fileformat = old_fileformat + let &syntax = &syntax + + " clean up previous location list, but only if it's due to fmt + if exists('b:got_fmt_error') && b:got_fmt_error + let b:got_fmt_error = 0 + call go#list#Clean(l:listtype) + call go#list#Window(l:listtype) endif - - if bin_name == "goimports" - if !exists('b:goimports_vendor_compatible') - let out = go#util#System(bin_path . " --help") - if out !~ "-srcdir" - call go#util#EchoWarning("vim-go: goimports does not support srcdir. update with: :GoUpdateBinaries") - else - let b:goimports_vendor_compatible = 1 - endif - endif - - if exists('b:goimports_vendor_compatible') && b:goimports_vendor_compatible - let ssl_save = &shellslash - set noshellslash - let command = command . '-srcdir ' . shellescape(expand("%:p:h")) - let &shellslash = ssl_save - endif + elseif g:go_fmt_fail_silently == 0 + let splitted = split(out, '\n') + "otherwise get the errors and put them to location list + let errors = [] + for line in splitted + let tokens = matchlist(line, '^\(.\{-}\):\(\d\+\):\(\d\+\)\s*\(.*\)') + if !empty(tokens) + call add(errors, {"filename": @%, + \"lnum": tokens[2], + \"col": tokens[3], + \"text": tokens[4]}) + endif + endfor + if empty(errors) + % | " Couldn't detect gofmt error format, output errors endif - - " execute our command... - if go#util#IsWin() - let l:tmpname = tr(l:tmpname, '\', '/') + if !empty(errors) + call go#list#Populate(l:listtype, errors) + echohl Error | echomsg "Gofmt returned error" | echohl None endif - let out = go#util#System(command . " " . l:tmpname) - if bin_name != "gofmt" - let $GOPATH = old_gopath - endif + let b:got_fmt_error = 1 + call go#list#Window(l:listtype, len(errors)) - let l:listtype = "locationlist" - "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\+') - if go#util#ShellError() == 0 - " remove undo point caused via BufWritePre - try | silent undojoin | catch | endtry - - " Replace current file with temp file, then reload buffer - let old_fileformat = &fileformat - call rename(l:tmpname, expand('%')) - silent edit! - let &fileformat = old_fileformat - let &syntax = &syntax - - " clean up previous location list, but only if it's due to fmt - if exists('b:got_fmt_error') && b:got_fmt_error - let b:got_fmt_error = 0 - call go#list#Clean(l:listtype) - call go#list#Window(l:listtype) - endif - elseif g:go_fmt_fail_silently == 0 - let splitted = split(out, '\n') - "otherwise get the errors and put them to location list - let errors = [] - for line in splitted - let tokens = matchlist(line, '^\(.\{-}\):\(\d\+\):\(\d\+\)\s*\(.*\)') - if !empty(tokens) - call add(errors, {"filename": @%, - \"lnum": tokens[2], - \"col": tokens[3], - \"text": tokens[4]}) - endif - endfor - if empty(errors) - % | " Couldn't detect gofmt error format, output errors - endif - if !empty(errors) - call go#list#Populate(l:listtype, errors) - echohl Error | echomsg "Gofmt returned error" | echohl None - endif - - let b:got_fmt_error = 1 - call go#list#Window(l:listtype, len(errors)) - - " We didn't use the temp file, so clean up - call delete(l:tmpname) - endif + " We didn't use the temp file, so clean up + call delete(l:tmpname) + endif - if g:go_fmt_experimental == 1 - " restore our undo history - silent! exe 'rundo ' . tmpundofile - call delete(tmpundofile) - endif + if g:go_fmt_experimental == 1 + " restore our undo history + silent! exe 'rundo ' . tmpundofile + call delete(tmpundofile) + endif - if g:go_fmt_experimental == 1 - " Restore our cursor/windows positions, folds, etc. - if empty(l:curw) - silent! loadview - else - call winrestview(l:curw) - endif + if g:go_fmt_experimental == 1 + " Restore our cursor/windows positions, folds, etc. + if empty(l:curw) + silent! loadview else - " Restore our cursor/windows positions. - call winrestview(l:curw) + call winrestview(l:curw) endif + else + " Restore our cursor/windows positions. + call winrestview(l:curw) + endif endfunction - -" vim:ts=4:sw=4:et +" vim: sw=2 ts=2 et diff --git a/autoload/go/guru.vim b/autoload/go/guru.vim index 72e36b65f4..053d53101a 100644 --- a/autoload/go/guru.vim +++ b/autoload/go/guru.vim @@ -1,98 +1,98 @@ " guru.vim -- Vim integration for the Go guru. func! s:RunGuru(mode, format, selected, needs_scope) range abort - "return with a warning if the binary doesn't exist - let bin_path = go#path#CheckBinPath("guru") - if empty(bin_path) - return {'err': "bin path not found"} + "return with a warning if the binary doesn't exist + let bin_path = go#path#CheckBinPath("guru") + if empty(bin_path) + return {'err': "bin path not found"} + endif + + let filename = expand('%:p') + let dirname = expand('%:p:h') + let pkg = go#package#ImportPath(dirname) + + " this is important, check it! + if pkg == -1 && a:needs_scope + return {'err': "current directory is not inside of a valid GOPATH"} + endif + + " start constructing the 'command' variable + let command = bin_path + + " enable outputting in json format + if a:format == "json" + let command .= " -json" + endif + + " check for any tags + if exists('g:go_guru_tags') + let tags = get(g:, 'go_guru_tags') + let command .= printf(" -tags %s", tags) + endif + + " some modes require scope to be defined (such as callers). For these we + " choose a sensible setting, which is using the current file's package + let scopes = [] + if a:needs_scope + let scopes = [pkg] + endif + + " check for any user defined scope setting. users can define the scope, + " in package pattern form. examples: + " golang.org/x/tools/cmd/guru # a single package + " golang.org/x/tools/... # all packages beneath dir + " ... # the entire workspace. + if exists('g:go_guru_scope') + " check that the setting is of type list + if type(get(g:, 'go_guru_scope')) != type([]) + return {'err' : "go_guru_scope should of type list"} endif - let filename = expand('%:p') - let dirname = expand('%:p:h') - let pkg = go#package#ImportPath(dirname) + let scopes = get(g:, 'go_guru_scope') + endif - " this is important, check it! - if pkg == -1 && a:needs_scope - return {'err': "current directory is not inside of a valid GOPATH"} - endif - - " start constructing the 'command' variable - let command = bin_path - - " enable outputting in json format - if a:format == "json" - let command .= " -json" - endif - - " check for any tags - if exists('g:go_guru_tags') - let tags = get(g:, 'go_guru_tags') - let command .= printf(" -tags %s", tags) - endif + " now add the scope to our command if there is any + if !empty(scopes) + " strip trailing slashes for each path in scoped. bug: + " https://github.com/golang/go/issues/14584 + let scopes = go#util#StripTrailingSlash(scopes) - " some modes require scope to be defined (such as callers). For these we - " choose a sensible setting, which is using the current file's package - let scopes = [] - if a:needs_scope - let scopes = [pkg] - endif - - " check for any user defined scope setting. users can define the scope, - " in package pattern form. examples: - " golang.org/x/tools/cmd/guru # a single package - " golang.org/x/tools/... # all packages beneath dir - " ... # the entire workspace. - if exists('g:go_guru_scope') - " check that the setting is of type list - if type(get(g:, 'go_guru_scope')) != type([]) - return {'err' : "go_guru_scope should of type list"} - endif - - let scopes = get(g:, 'go_guru_scope') - endif + " create shell-safe entries of the list + let scopes = go#util#Shelllist(scopes) - " now add the scope to our command if there is any - if !empty(scopes) - " strip trailing slashes for each path in scoped. bug: - " https://github.com/golang/go/issues/14584 - let scopes = go#util#StripTrailingSlash(scopes) - - " create shell-safe entries of the list - let scopes = go#util#Shelllist(scopes) - - " guru expect a comma-separated list of patterns, construct it - let scope = join(scopes, ",") - let command .= printf(" -scope %s", scope) - endif + " guru expect a comma-separated list of patterns, construct it + let scope = join(scopes, ",") + let command .= printf(" -scope %s", scope) + endif - let pos = printf("#%s", go#util#OffsetCursor()) - if a:selected != -1 - " means we have a range, get it - let pos1 = go#util#Offset(line("'<"), col("'<")) - let pos2 = go#util#Offset(line("'>"), col("'>")) - let pos = printf("#%s,#%s", pos1, pos2) - endif + let pos = printf("#%s", go#util#OffsetCursor()) + if a:selected != -1 + " means we have a range, get it + let pos1 = go#util#Offset(line("'<"), col("'<")) + let pos2 = go#util#Offset(line("'>"), col("'>")) + let pos = printf("#%s,#%s", pos1, pos2) + endif - " this is our final command - let filename .= ':'.pos - let command .= printf(' %s %s', a:mode, shellescape(filename)) + " this is our final command + let filename .= ':'.pos + let command .= printf(' %s %s', a:mode, shellescape(filename)) - let old_gopath = $GOPATH - let $GOPATH = go#path#Detect() + let old_gopath = $GOPATH + let $GOPATH = go#path#Detect() - " the query might take time, let us give some feedback - call go#util#EchoProgress("analysing ...") + " the query might take time, let us give some feedback + call go#util#EchoProgress("analysing ...") - " run, forrest run!!! - let out = go#util#System(command) + " run, forrest run!!! + let out = go#util#System(command) - let $GOPATH = old_gopath - if go#util#ShellError() != 0 - " the output contains the error message - return {'err' : out} - endif + let $GOPATH = old_gopath + if go#util#ShellError() != 0 + " the output contains the error message + return {'err' : out} + endif - return {'out': out} + return {'out': out} endfunc " This uses Vim's errorformat to parse the output from Guru's 'plain output @@ -100,205 +100,205 @@ endfunc " easier to use. If we need more power we can always switch back to parse it " via regex. func! s:loclistSecond(output) - " backup users errorformat, will be restored once we are finished - let old_errorformat = &errorformat - - " match two possible styles of errorformats: - " - " 'file:line.col-line2.col2: message' - " 'file:line:col: message' - " - " We discard line2 and col2 for the first errorformat, because it's not - " useful and location only has the ability to show one line and column - " number - let errformat = "%f:%l.%c-%[%^:]%#:\ %m,%f:%l:%c:\ %m" - call go#list#ParseFormat("locationlist", errformat, split(a:output, "\n")) - - let errors = go#list#Get("locationlist") - call go#list#Window("locationlist", len(errors)) + " backup users errorformat, will be restored once we are finished + let old_errorformat = &errorformat + + " match two possible styles of errorformats: + " + " 'file:line.col-line2.col2: message' + " 'file:line:col: message' + " + " We discard line2 and col2 for the first errorformat, because it's not + " useful and location only has the ability to show one line and column + " number + let errformat = "%f:%l.%c-%[%^:]%#:\ %m,%f:%l:%c:\ %m" + call go#list#ParseFormat("locationlist", errformat, split(a:output, "\n")) + + let errors = go#list#Get("locationlist") + call go#list#Window("locationlist", len(errors)) endfun function! go#guru#Scope(...) - if a:0 - if a:0 == 1 && a:1 == '""' - unlet g:go_guru_scope - call go#util#EchoSuccess("guru scope is cleared") - else - let g:go_guru_scope = a:000 - call go#util#EchoSuccess("guru scope changed to: ". join(a:000, ",")) - endif - - return - endif - - if !exists('g:go_guru_scope') - call go#util#EchoError("guru scope is not set") + if a:0 + if a:0 == 1 && a:1 == '""' + unlet g:go_guru_scope + call go#util#EchoSuccess("guru scope is cleared") else - call go#util#EchoSuccess("current guru scope: ". join(g:go_guru_scope, ",")) + let g:go_guru_scope = a:000 + call go#util#EchoSuccess("guru scope changed to: ". join(a:000, ",")) endif + + return + endif + + if !exists('g:go_guru_scope') + call go#util#EchoError("guru scope is not set") + else + call go#util#EchoSuccess("current guru scope: ". join(g:go_guru_scope, ",")) + endif endfunction function! go#guru#Tags(...) - if a:0 - if a:0 == 1 && a:1 == '""' - unlet g:go_guru_tags - call go#util#EchoSuccess("guru tags is cleared") - else - let g:go_guru_tags = a:1 - call go#util#EchoSuccess("guru tags changed to: ". a:1) - endif - - return - endif - - if !exists('g:go_guru_tags') - call go#util#EchoSuccess("guru tags is not set") + if a:0 + if a:0 == 1 && a:1 == '""' + unlet g:go_guru_tags + call go#util#EchoSuccess("guru tags is cleared") else - call go#util#EchoSuccess("current guru tags: ". a:1) + let g:go_guru_tags = a:1 + call go#util#EchoSuccess("guru tags changed to: ". a:1) endif + + return + endif + + if !exists('g:go_guru_tags') + call go#util#EchoSuccess("guru tags is not set") + else + call go#util#EchoSuccess("current guru tags: ". a:1) + endif endfunction " Show 'implements' relation for selected package function! go#guru#Implements(selected) - let out = s:RunGuru('implements', 'plain', a:selected, 1) - if has_key(out, 'err') - call go#util#EchoError(out.err) - return - endif + let out = s:RunGuru('implements', 'plain', a:selected, 1) + if has_key(out, 'err') + call go#util#EchoError(out.err) + return + endif - call s:loclistSecond(out.out) + call s:loclistSecond(out.out) endfunction " Describe selected syntax: definition, methods, etc function! go#guru#Describe(selected) - let out = s:RunGuru('describe', 'plain', a:selected, 0) - if has_key(out, 'err') - call go#util#EchoError(out.err) - return - endif + let out = s:RunGuru('describe', 'plain', a:selected, 0) + if has_key(out, 'err') + call go#util#EchoError(out.err) + return + endif - call s:loclistSecond(out.out) + call s:loclistSecond(out.out) endfunction " Show possible targets of selected function call function! go#guru#Callees(selected) - let out = s:RunGuru('callees', 'plain', a:selected, 1) - if has_key(out, 'err') - call go#util#EchoError(out.err) - return - endif + let out = s:RunGuru('callees', 'plain', a:selected, 1) + if has_key(out, 'err') + call go#util#EchoError(out.err) + return + endif - call s:loclistSecond(out.out) + call s:loclistSecond(out.out) endfunction " Show possible callers of selected function function! go#guru#Callers(selected) - let out = s:RunGuru('callers', 'plain', a:selected, 1) - if has_key(out, 'err') - call go#util#EchoError(out.err) - return - endif + let out = s:RunGuru('callers', 'plain', a:selected, 1) + if has_key(out, 'err') + call go#util#EchoError(out.err) + return + endif - call s:loclistSecond(out.out) + call s:loclistSecond(out.out) endfunction " Show path from callgraph root to selected function function! go#guru#Callstack(selected) - let out = s:RunGuru('callstack', 'plain', a:selected, 1) - if has_key(out, 'err') - call go#util#EchoError(out.err) - return - endif + let out = s:RunGuru('callstack', 'plain', a:selected, 1) + if has_key(out, 'err') + call go#util#EchoError(out.err) + return + endif - call s:loclistSecond(out.out) + call s:loclistSecond(out.out) endfunction " Show free variables of selection function! go#guru#Freevars(selected) - " Freevars requires a selection - if a:selected == -1 - call go#util#EchoError("GoFreevars requires a selection (range) of code") - return - endif - - let out = s:RunGuru('freevars', 'plain', a:selected, 0) - if has_key(out, 'err') - call go#util#EchoError(out.err) - return - endif - - call s:loclistSecond(out.out) + " Freevars requires a selection + if a:selected == -1 + call go#util#EchoError("GoFreevars requires a selection (range) of code") + return + endif + + let out = s:RunGuru('freevars', 'plain', a:selected, 0) + if has_key(out, 'err') + call go#util#EchoError(out.err) + return + endif + + call s:loclistSecond(out.out) endfunction " Show send/receive corresponding to selected channel op function! go#guru#ChannelPeers(selected) - let out = s:RunGuru('peers', 'plain', a:selected, 1) - if has_key(out, 'err') - call go#util#EchoError(out.err) - return - endif + let out = s:RunGuru('peers', 'plain', a:selected, 1) + if has_key(out, 'err') + call go#util#EchoError(out.err) + return + endif - call s:loclistSecond(out.out) + call s:loclistSecond(out.out) endfunction " Show all refs to entity denoted by selected identifier function! go#guru#Referrers(selected) - let out = s:RunGuru('referrers', 'plain', a:selected, 0) - if has_key(out, 'err') - call go#util#EchoError(out.err) - return - endif + let out = s:RunGuru('referrers', 'plain', a:selected, 0) + if has_key(out, 'err') + call go#util#EchoError(out.err) + return + endif - call s:loclistSecond(out.out) + call s:loclistSecond(out.out) endfunction function! go#guru#What(selected) - " nvim doesn't have JSON support, though they work on it: - " https://github.com/neovim/neovim/pull/4131 - if has('nvim') - return {'err': "GoWhat is not supported in Neovim"} - endif - - " json_encode() and friends are introduced with this patch - " https://groups.google.com/d/msg/vim_dev/vLupTNhQhZ8/cDGIk0JEDgAJ - if !has('patch-7.4.1304') - return {'err': "GoWhat is supported with Vim version 7.4-1304 or later"} - endif - - let out = s:RunGuru('what', 'json', a:selected, 0) - if has_key(out, 'err') - return out.err - endif - - call s:loclistSecond(out.out) - let result = json_decode(out.out) - - if type(result) != type({}) - return {'err': "malformed output from guru"} - endif - - if !has_key(result, 'what') - return {'err': "no what query found for the given identifier"} - endif - - return {'out': result.what} + " nvim doesn't have JSON support, though they work on it: + " https://github.com/neovim/neovim/pull/4131 + if has('nvim') + return {'err': "GoWhat is not supported in Neovim"} + endif + + " json_encode() and friends are introduced with this patch + " https://groups.google.com/d/msg/vim_dev/vLupTNhQhZ8/cDGIk0JEDgAJ + if !has('patch-7.4.1304') + return {'err': "GoWhat is supported with Vim version 7.4-1304 or later"} + endif + + let out = s:RunGuru('what', 'json', a:selected, 0) + if has_key(out, 'err') + return out.err + endif + + call s:loclistSecond(out.out) + let result = json_decode(out.out) + + if type(result) != type({}) + return {'err': "malformed output from guru"} + endif + + if !has_key(result, 'what') + return {'err': "no what query found for the given identifier"} + endif + + return {'out': result.what} endfunction function! go#guru#SameIds(selected) - let result = go#guru#What(a:selected) - if has_key(out, 'err') - call go#util#EchoError(out.err) - return - endif - - if !has_key(result.out, 'sameids') - call go#util#EchoError("no same_ids founds for the given identifier") - return -1 - endif - - let same_ids = result.what.sameids - echo same_ids + let result = go#guru#What(a:selected) + if has_key(out, 'err') + call go#util#EchoError(out.err) + return + endif + + if !has_key(result.out, 'sameids') + call go#util#EchoError("no same_ids founds for the given identifier") + return -1 + endif + + let same_ids = result.what.sameids + echo same_ids endfunction -" vim:ts=4:sw=4:et +" vim: sw=2 ts=2 et diff --git a/autoload/go/impl.vim b/autoload/go/impl.vim index 678b078ee3..e0ffac455f 100644 --- a/autoload/go/impl.vim +++ b/autoload/go/impl.vim @@ -1,124 +1,126 @@ function! go#impl#Impl(...) - let binpath = go#path#CheckBinPath('impl') - if empty(binpath) - return - endif + let binpath = go#path#CheckBinPath('impl') + if empty(binpath) + return + endif - let recv = "" - let iface = "" + let recv = "" + let iface = "" - if a:0 == 0 - " user didn't passed anything, just called ':GoImpl' - let receiveType = expand("") - let recv = printf("%s *%s", tolower(receiveType)[0], receiveType) - let iface = input("vim-go: generating method stubs for interface: ") - redraw! - if empty(iface) - call go#util#EchoError('usage: interface type is not provided') - return - endif - elseif a:0 == 1 - " we assume the user only passed the interface type, - " i.e: ':GoImpl io.Writer' - let receiveType = expand("") - let recv = printf("%s *%s", tolower(receiveType)[0], receiveType) - let iface = a:1 - elseif a:0 > 2 - " user passed receiver and interface type both, - " i.e: 'GoImpl f *Foo io.Writer' - let recv = join(a:000[:-2], ' ') - let iface = a:000[-1] - else - call go#util#EchoError('usage: GoImpl {receiver} {interface}') - return + if a:0 == 0 + " user didn't passed anything, just called ':GoImpl' + let receiveType = expand("") + let recv = printf("%s *%s", tolower(receiveType)[0], receiveType) + let iface = input("vim-go: generating method stubs for interface: ") + redraw! + if empty(iface) + call go#util#EchoError('usage: interface type is not provided') + return endif + elseif a:0 == 1 + " we assume the user only passed the interface type, + " i.e: ':GoImpl io.Writer' + let receiveType = expand("") + let recv = printf("%s *%s", tolower(receiveType)[0], receiveType) + let iface = a:1 + elseif a:0 > 2 + " user passed receiver and interface type both, + " i.e: 'GoImpl f *Foo io.Writer' + let recv = join(a:000[:-2], ' ') + let iface = a:000[-1] + else + call go#util#EchoError('usage: GoImpl {receiver} {interface}') + return + endif - let result = go#util#System(printf("%s '%s' '%s'", binpath, recv, iface)) - if go#util#ShellError() != 0 - call go#util#EchoError(result) - return - endif + let result = go#util#System(printf("%s '%s' '%s'", binpath, recv, iface)) + if go#util#ShellError() != 0 + call go#util#EchoError(result) + return + endif - if result ==# '' - return - end + if result ==# '' + return + end - let pos = getpos('.') - put ='' - put =result - call setpos('.', pos) + let pos = getpos('.') + put ='' + put =result + call setpos('.', pos) endfunction if exists('*uniq') - function! s:uniq(list) - return uniq(a:list) - endfunction + function! s:uniq(list) + return uniq(a:list) + endfunction else - " Note: Believe that the list is sorted - function! s:uniq(list) - let i = len(a:list) - 1 - while 0 < i - if a:list[i-1] ==# a:list[i] - call remove(a:list, i) - let i -= 2 - else - let i -= 1 - endif - endwhile - return a:list - endfunction + " Note: Believe that the list is sorted + function! s:uniq(list) + let i = len(a:list) - 1 + while 0 < i + if a:list[i-1] ==# a:list[i] + call remove(a:list, i) + let i -= 2 + else + let i -= 1 + endif + endwhile + return a:list + endfunction endif function! s:root_dirs() - let dirs = [] - let root = go#util#GOROOT() - if root !=# '' && isdirectory(root) - call add(dirs, root) - endif + let dirs = [] + let root = go#util#GOROOT() + if root !=# '' && isdirectory(root) + call add(dirs, root) + endif - let paths = map(split(go#util#GOPATH(), go#util#PathListSep()), "substitute(v:val, '\\\\', '/', 'g')") - if go#util#ShellError() - return [] - endif + let paths = map(split(go#util#GOPATH(), go#util#PathListSep()), "substitute(v:val, '\\\\', '/', 'g')") + if go#util#ShellError() + return [] + endif - if !empty(filter(paths, 'isdirectory(v:val)')) - call extend(dirs, paths) - endif + if !empty(filter(paths, 'isdirectory(v:val)')) + call extend(dirs, paths) + endif - return dirs + return dirs endfunction function! s:go_packages(dirs) - let pkgs = [] - for d in a:dirs - let pkg_root = expand(d . '/pkg/' . go#util#OSARCH()) - call extend(pkgs, split(globpath(pkg_root, '**/*.a', 1), "\n")) - endfor - return map(pkgs, "fnamemodify(v:val, ':t:r')") + let pkgs = [] + for d in a:dirs + let pkg_root = expand(d . '/pkg/' . go#util#OSARCH()) + call extend(pkgs, split(globpath(pkg_root, '**/*.a', 1), "\n")) + endfor + return map(pkgs, "fnamemodify(v:val, ':t:r')") endfunction function! s:interface_list(pkg) - let contents = split(go#util#System('go doc ' . a:pkg), "\n") - if go#util#ShellError() - return [] - endif + let contents = split(go#util#System('go doc ' . a:pkg), "\n") + if go#util#ShellError() + return [] + endif - call filter(contents, 'v:val =~# ''^type\s\+\h\w*\s\+interface''') - return map(contents, 'a:pkg . "." . matchstr(v:val, ''^type\s\+\zs\h\w*\ze\s\+interface'')') + call filter(contents, 'v:val =~# ''^type\s\+\h\w*\s\+interface''') + return map(contents, 'a:pkg . "." . matchstr(v:val, ''^type\s\+\zs\h\w*\ze\s\+interface'')') endfunction " Complete package and interface for {interface} function! go#impl#Complete(arglead, cmdline, cursorpos) - let words = split(a:cmdline, '\s\+', 1) - if words[-1] ==# '' - return s:uniq(sort(s:go_packages(s:root_dirs()))) - elseif words[-1] =~# '^\h\w*$' - return s:uniq(sort(filter(s:go_packages(s:root_dirs()), 'stridx(v:val, words[-1]) == 0'))) - elseif words[-1] =~# '^\h\w*\.\%(\h\w*\)\=$' - let [pkg, interface] = split(words[-1], '\.', 1) - echomsg pkg - return s:uniq(sort(filter(s:interface_list(pkg), 'v:val =~? words[-1]'))) - else - return [] - endif + let words = split(a:cmdline, '\s\+', 1) + if words[-1] ==# '' + return s:uniq(sort(s:go_packages(s:root_dirs()))) + elseif words[-1] =~# '^\h\w*$' + return s:uniq(sort(filter(s:go_packages(s:root_dirs()), 'stridx(v:val, words[-1]) == 0'))) + elseif words[-1] =~# '^\h\w*\.\%(\h\w*\)\=$' + let [pkg, interface] = split(words[-1], '\.', 1) + echomsg pkg + return s:uniq(sort(filter(s:interface_list(pkg), 'v:val =~? words[-1]'))) + else + return [] + endif endfunction + +" vim: sw=2 ts=2 et diff --git a/autoload/go/import.vim b/autoload/go/import.vim index f5a6f372c4..6965891613 100644 --- a/autoload/go/import.vim +++ b/autoload/go/import.vim @@ -5,209 +5,209 @@ " Check out the docs for more information at /doc/vim-go.txt " function! go#import#SwitchImport(enabled, localname, path, bang) - let view = winsaveview() - let path = substitute(a:path, '^\s*\(.\{-}\)\s*$', '\1', '') - - " Quotes are not necessary, so remove them if provided. - if path[0] == '"' - let path = strpart(path, 1) - endif - if path[len(path)-1] == '"' - let path = strpart(path, 0, len(path) - 1) + let view = winsaveview() + let path = substitute(a:path, '^\s*\(.\{-}\)\s*$', '\1', '') + + " Quotes are not necessary, so remove them if provided. + if path[0] == '"' + let path = strpart(path, 1) + endif + if path[len(path)-1] == '"' + let path = strpart(path, 0, len(path) - 1) + endif + + " if given a trailing slash, eg. `github.com/user/pkg/`, remove it + if path[len(path)-1] == '/' + let path = strpart(path, 0, len(path) - 1) + endif + + if path == '' + call s:Error('Import path not provided') + return + endif + + if a:bang == "!" + let out = go#util#System("go get -u -v ".shellescape(path)) + if go#util#ShellError() != 0 + call s:Error("Can't find import: " . path . ":" . out) endif - - " if given a trailing slash, eg. `github.com/user/pkg/`, remove it - if path[len(path)-1] == '/' - let path = strpart(path, 0, len(path) - 1) - endif - - if path == '' - call s:Error('Import path not provided') - return - endif - - if a:bang == "!" - let out = go#util#System("go get -u -v ".shellescape(path)) - if go#util#ShellError() != 0 - call s:Error("Can't find import: " . path . ":" . out) + endif + let exists = go#tool#Exists(path) + if exists == -1 + call s:Error("Can't find import: " . path) + return + endif + + " Extract any site prefix (e.g. github.com/). + " If other imports with the same prefix are grouped separately, + " we will add this new import with them. + " Only up to and including the first slash is used. + let siteprefix = matchstr(path, "^[^/]*/") + + let qpath = '"' . path . '"' + if a:localname != '' + let qlocalpath = a:localname . ' ' . qpath + else + let qlocalpath = qpath + endif + let indentstr = 0 + let packageline = -1 " Position of package name statement + let appendline = -1 " Position to introduce new import + let deleteline = -1 " Position of line with existing import + let linesdelta = 0 " Lines added/removed + + " Find proper place to add/remove import. + let line = 0 + while line <= line('$') + let linestr = getline(line) + + if linestr =~# '^package\s' + let packageline = line + let appendline = line + + elseif linestr =~# '^import\s\+(' + let appendstr = qlocalpath + let indentstr = 1 + let appendline = line + let firstblank = -1 + let lastprefix = "" + while line <= line("$") + let line = line + 1 + let linestr = getline(line) + let m = matchlist(getline(line), '^\()\|\(\s\+\)\(\S*\s*\)"\(.\+\)"\)') + if empty(m) + if siteprefix == "" && a:enabled + " must be in the first group + break + endif + " record this position, but keep looking + if firstblank < 0 + let firstblank = line + endif + continue endif - endif - let exists = go#tool#Exists(path) - if exists == -1 - call s:Error("Can't find import: " . path) - return - endif + if m[1] == ')' + " if there's no match, add it to the first group + if appendline < 0 && firstblank >= 0 + let appendline = firstblank + endif + break + endif + let lastprefix = matchstr(m[4], "^[^/]*/") + if a:localname != '' && m[3] != '' + let qlocalpath = printf('%-' . (len(m[3])-1) . 's %s', a:localname, qpath) + endif + let appendstr = m[2] . qlocalpath + let indentstr = 0 + if m[4] == path + let appendline = -1 + let deleteline = line + break + elseif m[4] < path + " don't set candidate position if we have a site prefix, + " we've passed a blank line, and this doesn't share the same + " site prefix. + if siteprefix == "" || firstblank < 0 || match(m[4], "^" . siteprefix) >= 0 + let appendline = line + endif + elseif siteprefix != "" && match(m[4], "^" . siteprefix) >= 0 + " first entry of site group + let appendline = line - 1 + break + endif + endwhile + break + + elseif linestr =~# '^import ' + if appendline == packageline + let appendstr = 'import ' . qlocalpath + let appendline = line - 1 + endif + let m = matchlist(linestr, '^import\(\s\+\)\(\S*\s*\)"\(.\+\)"') + if !empty(m) + if m[3] == path + let appendline = -1 + let deleteline = line + break + endif + if m[3] < path + let appendline = line + endif + if a:localname != '' && m[2] != '' + let qlocalpath = printf("%s %" . len(m[2])-1 . "s", a:localname, qpath) + endif + let appendstr = 'import' . m[1] . qlocalpath + endif - " Extract any site prefix (e.g. github.com/). - " If other imports with the same prefix are grouped separately, - " we will add this new import with them. - " Only up to and including the first slash is used. - let siteprefix = matchstr(path, "^[^/]*/") + elseif linestr =~# '^\(var\|const\|type\|func\)\>' + break - let qpath = '"' . path . '"' - if a:localname != '' - let qlocalpath = a:localname . ' ' . qpath + endif + let line = line + 1 + endwhile + + " Append or remove the package import, as requested. + if a:enabled + if deleteline != -1 + call s:Error(qpath . ' already being imported') + elseif appendline == -1 + call s:Error('No package line found') else - let qlocalpath = qpath + if appendline == packageline + call append(appendline + 0, '') + call append(appendline + 1, 'import (') + call append(appendline + 2, ')') + let appendline += 2 + let linesdelta += 3 + let appendstr = qlocalpath + let indentstr = 1 + endif + call append(appendline, appendstr) + execute appendline + 1 + if indentstr + execute 'normal! >>' + endif + let linesdelta += 1 endif - let indentstr = 0 - let packageline = -1 " Position of package name statement - let appendline = -1 " Position to introduce new import - let deleteline = -1 " Position of line with existing import - let linesdelta = 0 " Lines added/removed - - " Find proper place to add/remove import. - let line = 0 - while line <= line('$') - let linestr = getline(line) - - if linestr =~# '^package\s' - let packageline = line - let appendline = line - - elseif linestr =~# '^import\s\+(' - let appendstr = qlocalpath - let indentstr = 1 - let appendline = line - let firstblank = -1 - let lastprefix = "" - while line <= line("$") - let line = line + 1 - let linestr = getline(line) - let m = matchlist(getline(line), '^\()\|\(\s\+\)\(\S*\s*\)"\(.\+\)"\)') - if empty(m) - if siteprefix == "" && a:enabled - " must be in the first group - break - endif - " record this position, but keep looking - if firstblank < 0 - let firstblank = line - endif - continue - endif - if m[1] == ')' - " if there's no match, add it to the first group - if appendline < 0 && firstblank >= 0 - let appendline = firstblank - endif - break - endif - let lastprefix = matchstr(m[4], "^[^/]*/") - if a:localname != '' && m[3] != '' - let qlocalpath = printf('%-' . (len(m[3])-1) . 's %s', a:localname, qpath) - endif - let appendstr = m[2] . qlocalpath - let indentstr = 0 - if m[4] == path - let appendline = -1 - let deleteline = line - break - elseif m[4] < path - " don't set candidate position if we have a site prefix, - " we've passed a blank line, and this doesn't share the same - " site prefix. - if siteprefix == "" || firstblank < 0 || match(m[4], "^" . siteprefix) >= 0 - let appendline = line - endif - elseif siteprefix != "" && match(m[4], "^" . siteprefix) >= 0 - " first entry of site group - let appendline = line - 1 - break - endif - endwhile - break - - elseif linestr =~# '^import ' - if appendline == packageline - let appendstr = 'import ' . qlocalpath - let appendline = line - 1 - endif - let m = matchlist(linestr, '^import\(\s\+\)\(\S*\s*\)"\(.\+\)"') - if !empty(m) - if m[3] == path - let appendline = -1 - let deleteline = line - break - endif - if m[3] < path - let appendline = line - endif - if a:localname != '' && m[2] != '' - let qlocalpath = printf("%s %" . len(m[2])-1 . "s", a:localname, qpath) - endif - let appendstr = 'import' . m[1] . qlocalpath - endif - - elseif linestr =~# '^\(var\|const\|type\|func\)\>' - break - - endif - let line = line + 1 - endwhile - - " Append or remove the package import, as requested. - if a:enabled - if deleteline != -1 - call s:Error(qpath . ' already being imported') - elseif appendline == -1 - call s:Error('No package line found') - else - if appendline == packageline - call append(appendline + 0, '') - call append(appendline + 1, 'import (') - call append(appendline + 2, ')') - let appendline += 2 - let linesdelta += 3 - let appendstr = qlocalpath - let indentstr = 1 - endif - call append(appendline, appendstr) - execute appendline + 1 - if indentstr - execute 'normal! >>' - endif - let linesdelta += 1 - endif + else + if deleteline == -1 + call s:Error(qpath . ' not being imported') else - if deleteline == -1 - call s:Error(qpath . ' not being imported') - else - execute deleteline . 'd' - let linesdelta -= 1 - - if getline(deleteline-1) =~# '^import\s\+(' && getline(deleteline) =~# '^)' - " Delete empty import block - let deleteline -= 1 - execute deleteline . "d" - execute deleteline . "d" - let linesdelta -= 2 - endif - - if getline(deleteline) == '' && getline(deleteline - 1) == '' - " Delete spacing for removed line too. - execute deleteline . "d" - let linesdelta -= 1 - endif - endif + execute deleteline . 'd' + let linesdelta -= 1 + + if getline(deleteline-1) =~# '^import\s\+(' && getline(deleteline) =~# '^)' + " Delete empty import block + let deleteline -= 1 + execute deleteline . "d" + execute deleteline . "d" + let linesdelta -= 2 + endif + + if getline(deleteline) == '' && getline(deleteline - 1) == '' + " Delete spacing for removed line too. + execute deleteline . "d" + let linesdelta -= 1 + endif endif + endif - " Adjust view for any changes. - let view.lnum += linesdelta - let view.topline += linesdelta - if view.topline < 0 - let view.topline = 0 - endif + " Adjust view for any changes. + let view.lnum += linesdelta + let view.topline += linesdelta + if view.topline < 0 + let view.topline = 0 + endif - " Put buffer back where it was. - call winrestview(view) + " Put buffer back where it was. + call winrestview(view) endfunction function! s:Error(s) - echohl Error | echo a:s | echohl None + echohl Error | echo a:s | echohl None endfunction -" vim:ts=4:sw=4:et +" vim: sw=2 ts=2 et diff --git a/autoload/go/jobcontrol.vim b/autoload/go/jobcontrol.vim index dd994809c7..e03c75d66b 100644 --- a/autoload/go/jobcontrol.vim +++ b/autoload/go/jobcontrol.vim @@ -211,4 +211,4 @@ function! s:abort(path) endfor endfunction -" vim:ts=2:sw=2:et +" vim: sw=2 ts=2 et diff --git a/autoload/go/lint.vim b/autoload/go/lint.vim index 34ff7f6f58..1a2ef9aa23 100644 --- a/autoload/go/lint.vim +++ b/autoload/go/lint.vim @@ -1,199 +1,199 @@ if !exists("g:go_metalinter_command") - let g:go_metalinter_command = "" + let g:go_metalinter_command = "" endif if !exists("g:go_metalinter_autosave_enabled") - let g:go_metalinter_autosave_enabled = ['vet', 'golint'] + let g:go_metalinter_autosave_enabled = ['vet', 'golint'] endif if !exists("g:go_metalinter_enabled") - let g:go_metalinter_enabled = ['vet', 'golint', 'errcheck'] + let g:go_metalinter_enabled = ['vet', 'golint', 'errcheck'] endif if !exists("g:go_metalinter_deadline") - let g:go_metalinter_deadline = "5s" + let g:go_metalinter_deadline = "5s" endif if !exists("g:go_golint_bin") - let g:go_golint_bin = "golint" + let g:go_golint_bin = "golint" endif if !exists("g:go_errcheck_bin") - let g:go_errcheck_bin = "errcheck" + let g:go_errcheck_bin = "errcheck" endif function! go#lint#Gometa(autosave, ...) abort - if a:0 == 0 - let goargs = shellescape(expand('%:p:h')) - else - let goargs = go#util#Shelljoin(a:000) + if a:0 == 0 + let goargs = shellescape(expand('%:p:h')) + else + let goargs = go#util#Shelljoin(a:000) + endif + + let meta_command = "gometalinter --disable-all" + if a:autosave || empty(g:go_metalinter_command) + let bin_path = go#path#CheckBinPath("gometalinter") + if empty(bin_path) + return endif - let meta_command = "gometalinter --disable-all" - if a:autosave || empty(g:go_metalinter_command) - let bin_path = go#path#CheckBinPath("gometalinter") - if empty(bin_path) - return - endif - - if a:autosave - " include only messages for the active buffer - let meta_command .= " --include='^" . expand('%:p') . ".*$'" - endif - - " linters - let linters = a:autosave ? g:go_metalinter_autosave_enabled : g:go_metalinter_enabled - for linter in linters - let meta_command .= " --enable=".linter - endfor - - " deadline - let meta_command .= " --deadline=" . g:go_metalinter_deadline - - " path - let meta_command .= " " . goargs - else - " the user wants something else, let us use it. - let meta_command = g:go_metalinter_command + if a:autosave + " include only messages for the active buffer + let meta_command .= " --include='^" . expand('%:p') . ".*$'" endif - " comment out the following two lines for debugging - " echo meta_command - " return - - let out = go#tool#ExecuteInDir(meta_command) - - let l:listtype = "quickfix" - if go#util#ShellError() == 0 - redraw | echo - call go#list#Clean(l:listtype) - call go#list#Window(l:listtype) - echon "vim-go: " | echohl Function | echon "[metalinter] PASS" | echohl None - else - " GoMetaLinter can output one of the two, so we look for both: - " ::[]: () - " ::: () - " This can be defined by the following errorformat: - let errformat = "%f:%l:%c:%t%*[^:]:\ %m,%f:%l::%t%*[^:]:\ %m" - - " Parse and populate our location list - call go#list#ParseFormat(l:listtype, errformat, split(out, "\n")) - - let errors = go#list#Get(l:listtype) - call go#list#Window(l:listtype, len(errors)) - - if !a:autosave - call go#list#JumpToFirst(l:listtype) - endif + " linters + let linters = a:autosave ? g:go_metalinter_autosave_enabled : g:go_metalinter_enabled + for linter in linters + let meta_command .= " --enable=".linter + endfor + + " deadline + let meta_command .= " --deadline=" . g:go_metalinter_deadline + + " path + let meta_command .= " " . goargs + else + " the user wants something else, let us use it. + let meta_command = g:go_metalinter_command + endif + + " comment out the following two lines for debugging + " echo meta_command + " return + + let out = go#tool#ExecuteInDir(meta_command) + + let l:listtype = "quickfix" + if go#util#ShellError() == 0 + redraw | echo + call go#list#Clean(l:listtype) + call go#list#Window(l:listtype) + echon "vim-go: " | echohl Function | echon "[metalinter] PASS" | echohl None + else + " GoMetaLinter can output one of the two, so we look for both: + " ::[]: () + " ::: () + " This can be defined by the following errorformat: + let errformat = "%f:%l:%c:%t%*[^:]:\ %m,%f:%l::%t%*[^:]:\ %m" + + " Parse and populate our location list + call go#list#ParseFormat(l:listtype, errformat, split(out, "\n")) + + let errors = go#list#Get(l:listtype) + call go#list#Window(l:listtype, len(errors)) + + if !a:autosave + call go#list#JumpToFirst(l:listtype) endif + endif endfunction " Golint calls 'golint' on the current directory. Any warnings are populated in " the location list function! go#lint#Golint(...) abort - let bin_path = go#path#CheckBinPath(g:go_golint_bin) - if empty(bin_path) - return - endif - - if a:0 == 0 - let goargs = shellescape(expand('%')) - else - let goargs = go#util#Shelljoin(a:000) - endif - - let out = go#util#System(bin_path . " " . goargs) - if empty(out) - echon "vim-go: " | echohl Function | echon "[lint] PASS" | echohl None - return - endif - - let l:listtype = "quickfix" - call go#list#Parse(l:listtype, out) - let errors = go#list#Get(l:listtype) - call go#list#Window(l:listtype, len(errors)) - call go#list#JumpToFirst(l:listtype) + let bin_path = go#path#CheckBinPath(g:go_golint_bin) + if empty(bin_path) + return + endif + + if a:0 == 0 + let goargs = shellescape(expand('%')) + else + let goargs = go#util#Shelljoin(a:000) + endif + + let out = go#util#System(bin_path . " " . goargs) + if empty(out) + echon "vim-go: " | echohl Function | echon "[lint] PASS" | echohl None + return + endif + + let l:listtype = "quickfix" + call go#list#Parse(l:listtype, out) + let errors = go#list#Get(l:listtype) + call go#list#Window(l:listtype, len(errors)) + call go#list#JumpToFirst(l:listtype) endfunction " Vet calls 'go vet' on the current directory. Any warnings are populated in " the location list function! go#lint#Vet(bang, ...) - call go#cmd#autowrite() - echon "vim-go: " | echohl Identifier | echon "calling vet..." | echohl None - if a:0 == 0 - let out = go#tool#ExecuteInDir('go vet') - else - let out = go#tool#ExecuteInDir('go tool vet ' . go#util#Shelljoin(a:000)) - endif - - let l:listtype = "quickfix" - if go#util#ShellError() != 0 - let errors = go#tool#ParseErrors(split(out, '\n')) - call go#list#Populate(l:listtype, errors) - call go#list#Window(l:listtype, len(errors)) - if !empty(errors) && !a:bang - call go#list#JumpToFirst(l:listtype) - endif - echon "vim-go: " | echohl ErrorMsg | echon "[vet] FAIL" | echohl None - else - call go#list#Clean(l:listtype) - call go#list#Window(l:listtype) - redraw | echon "vim-go: " | echohl Function | echon "[vet] PASS" | echohl None + call go#cmd#autowrite() + echon "vim-go: " | echohl Identifier | echon "calling vet..." | echohl None + if a:0 == 0 + let out = go#tool#ExecuteInDir('go vet') + else + let out = go#tool#ExecuteInDir('go tool vet ' . go#util#Shelljoin(a:000)) + endif + + let l:listtype = "quickfix" + if go#util#ShellError() != 0 + let errors = go#tool#ParseErrors(split(out, '\n')) + call go#list#Populate(l:listtype, errors) + call go#list#Window(l:listtype, len(errors)) + if !empty(errors) && !a:bang + call go#list#JumpToFirst(l:listtype) endif + echon "vim-go: " | echohl ErrorMsg | echon "[vet] FAIL" | echohl None + else + call go#list#Clean(l:listtype) + call go#list#Window(l:listtype) + 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 location list function! go#lint#Errcheck(...) abort - if a:0 == 0 - let goargs = go#package#ImportPath(expand('%:p:h')) - if goargs == -1 - echohl Error | echomsg "vim-go: package is not inside GOPATH src" | echohl None - return - endif - else - let goargs = go#util#Shelljoin(a:000) + if a:0 == 0 + let goargs = go#package#ImportPath(expand('%:p:h')) + if goargs == -1 + echohl Error | echomsg "vim-go: package is not inside GOPATH src" | echohl None + return endif + else + let goargs = go#util#Shelljoin(a:000) + endif - let bin_path = go#path#CheckBinPath(g:go_errcheck_bin) - if empty(bin_path) - return + let bin_path = go#path#CheckBinPath(g:go_errcheck_bin) + if empty(bin_path) + return + endif + + echon "vim-go: " | echohl Identifier | echon "errcheck analysing ..." | echohl None + redraw + + let command = bin_path . ' -abspath ' . goargs + let out = go#tool#ExecuteInDir(command) + + let l:listtype = "quickfix" + if go#util#ShellError() != 0 + let errformat = "%f:%l:%c:\ %m, %f:%l:%c\ %#%m" + + " Parse and populate our location list + call go#list#ParseFormat(l:listtype, errformat, split(out, "\n")) + + let errors = go#list#Get(l:listtype) + + if empty(errors) + echohl Error | echomsg "GoErrCheck returned error" | echohl None + echo out + return endif - echon "vim-go: " | echohl Identifier | echon "errcheck analysing ..." | echohl None - redraw - - let command = bin_path . ' -abspath ' . goargs - let out = go#tool#ExecuteInDir(command) - - let l:listtype = "quickfix" - if go#util#ShellError() != 0 - let errformat = "%f:%l:%c:\ %m, %f:%l:%c\ %#%m" - - " Parse and populate our location list - call go#list#ParseFormat(l:listtype, errformat, split(out, "\n")) - - let errors = go#list#Get(l:listtype) - - if empty(errors) - echohl Error | echomsg "GoErrCheck returned error" | echohl None - echo out - return - endif - - if !empty(errors) - call go#list#Populate(l:listtype, errors) - call go#list#Window(l:listtype, len(errors)) - if !empty(errors) - call go#list#JumpToFirst(l:listtype) - endif - endif - else - call go#list#Clean(l:listtype) - call go#list#Window(l:listtype) - echon "vim-go: " | echohl Function | echon "[errcheck] PASS" | echohl None + if !empty(errors) + call go#list#Populate(l:listtype, errors) + call go#list#Window(l:listtype, len(errors)) + if !empty(errors) + call go#list#JumpToFirst(l:listtype) + endif endif + else + call go#list#Clean(l:listtype) + call go#list#Window(l:listtype) + echon "vim-go: " | echohl Function | echon "[errcheck] PASS" | echohl None + endif endfunction -" vim:ts=4:sw=4:et +" vim: sw=2 ts=2 et diff --git a/autoload/go/list.vim b/autoload/go/list.vim index d91cfb12a8..6859a9f3e9 100644 --- a/autoload/go/list.vim +++ b/autoload/go/list.vim @@ -1,126 +1,126 @@ if !exists("g:go_list_type") - let g:go_list_type = "" + let g:go_list_type = "" endif " Window opens the list with the given height up to 10 lines maximum. " Otherwise g:go_loclist_height is used. If no or zero height is given it " closes the window function! go#list#Window(listtype, ...) - let l:listtype = go#list#Type(a:listtype) - " 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 lclose - " 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 - if l:listtype == "locationlist" - lclose - else - cclose - endif - return - endif - - let height = get(g:, "go_list_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 + let l:listtype = go#list#Type(a:listtype) + " 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 lclose + " 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 + if l:listtype == "locationlist" + lclose + else + cclose endif + return + endif - if l:listtype == "locationlist" - exe 'lopen ' . height + let height = get(g:, "go_list_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 - exe 'copen ' . height + let height = a:1 endif + endif + + if l:listtype == "locationlist" + exe 'lopen ' . height + else + exe 'copen ' . height + endif endfunction " Get returns the current list of items from the location list function! go#list#Get(listtype) - let l:listtype = go#list#Type(a:listtype) - if l:listtype == "locationlist" - return getloclist(0) - else - return getqflist() - endif + let l:listtype = go#list#Type(a:listtype) + if l:listtype == "locationlist" + return getloclist(0) + else + return getqflist() + endif endfunction " Populate populate the location list with the given items function! go#list#Populate(listtype, items) - let l:listtype = go#list#Type(a:listtype) - if l:listtype == "locationlist" - call setloclist(0, a:items, 'r') - else - call setqflist(a:items, 'r') - endif + let l:listtype = go#list#Type(a:listtype) + if l:listtype == "locationlist" + call setloclist(0, a:items, 'r') + else + call setqflist(a:items, 'r') + endif endfunction function! go#list#PopulateWin(winnr, items) - call setloclist(a:winnr, a:items, 'r') + call setloclist(a:winnr, a:items, 'r') endfunction " Parse parses the given items based on the specified errorformat nad " populates the location list. function! go#list#ParseFormat(listtype, errformat, items) - let l:listtype = go#list#Type(a:listtype) - " backup users errorformat, will be restored once we are finished - let old_errorformat = &errorformat + let l:listtype = go#list#Type(a:listtype) + " backup users errorformat, will be restored once we are finished + let old_errorformat = &errorformat - " parse and populate the location list - let &errorformat = a:errformat - if l:listtype == "locationlist" - lgetexpr a:items - else - cgetexpr a:items - endif + " parse and populate the location list + let &errorformat = a:errformat + if l:listtype == "locationlist" + lgetexpr a:items + else + cgetexpr a:items + endif - "restore back - let &errorformat = old_errorformat + "restore back + let &errorformat = old_errorformat endfunction " Parse parses the given items based on the global errorformat and " populates the location list. function! go#list#Parse(listtype, items) - let l:listtype = go#list#Type(a:listtype) - if l:listtype == "locationlist" - lgetexpr a:items - else - cgetexpr a:items - endif + let l:listtype = go#list#Type(a:listtype) + if l:listtype == "locationlist" + lgetexpr a:items + else + cgetexpr a:items + endif endfunction " JumpToFirst jumps to the first item in the location list function! go#list#JumpToFirst(listtype) - let l:listtype = go#list#Type(a:listtype) - if l:listtype == "locationlist" - ll 1 - else - cc 1 - endif + let l:listtype = go#list#Type(a:listtype) + if l:listtype == "locationlist" + ll 1 + else + cc 1 + endif endfunction " Clean cleans the location list function! go#list#Clean(listtype) - let l:listtype = go#list#Type(a:listtype) - if l:listtype == "locationlist" - lex [] - else - cex [] - endif + let l:listtype = go#list#Type(a:listtype) + if l:listtype == "locationlist" + lex [] + else + cex [] + endif endfunction function! go#list#Type(listtype) - if g:go_list_type == "locationlist" - return "locationlist" - elseif g:go_list_type == "quickfix" - return "quickfix" - else - return a:listtype - endif + if g:go_list_type == "locationlist" + return "locationlist" + elseif g:go_list_type == "quickfix" + return "quickfix" + else + return a:listtype + endif endfunction -" vim:ts=4:sw=4:et +" vim: sw=2 ts=2 et diff --git a/autoload/go/package.vim b/autoload/go/package.vim index 4f756135a9..2aefd5d650 100644 --- a/autoload/go/package.vim +++ b/autoload/go/package.vim @@ -9,120 +9,120 @@ let s:goos = $GOOS let s:goarch = $GOARCH if len(s:goos) == 0 - if exists('g:golang_goos') - let s:goos = g:golang_goos - elseif has('win32') || has('win64') - let s:goos = 'windows' - elseif has('macunix') - let s:goos = 'darwin' - else - let s:goos = '*' - endif + if exists('g:golang_goos') + let s:goos = g:golang_goos + elseif has('win32') || has('win64') + let s:goos = 'windows' + elseif has('macunix') + let s:goos = 'darwin' + else + let s:goos = '*' + endif endif if len(s:goarch) == 0 - if exists('g:golang_goarch') - let s:goarch = g:golang_goarch - else - let s:goarch = '*' - endif + if exists('g:golang_goarch') + let s:goarch = g:golang_goarch + else + let s:goarch = '*' + endif endif function! go#package#Paths() - let dirs = [] - - if !exists("s:goroot") - if executable('go') - let s:goroot = substitute(go#util#System('go env GOROOT'), '\n', '', 'g') - if go#util#ShellError() != 0 - echomsg '''go env GOROOT'' failed' - endif - else - let s:goroot = $GOROOT - endif + let dirs = [] + + if !exists("s:goroot") + if executable('go') + let s:goroot = substitute(go#util#System('go env GOROOT'), '\n', '', 'g') + if go#util#ShellError() != 0 + echomsg '''go env GOROOT'' failed' + endif + else + let s:goroot = $GOROOT endif + endif - if len(s:goroot) != 0 && isdirectory(s:goroot) - let dirs += [s:goroot] - endif + if len(s:goroot) != 0 && isdirectory(s:goroot) + let dirs += [s:goroot] + endif - let workspaces = split(go#path#Detect(), go#util#PathListSep()) - if workspaces != [] - let dirs += workspaces - endif + let workspaces = split(go#path#Detect(), go#util#PathListSep()) + if workspaces != [] + let dirs += workspaces + endif - return dirs + return dirs endfunction function! go#package#ImportPath(arg) - let path = fnamemodify(resolve(a:arg), ':p') - let dirs = go#package#Paths() - - for dir in dirs - if len(dir) && match(path, dir) == 0 - let workspace = dir - endif - endfor + let path = fnamemodify(resolve(a:arg), ':p') + let dirs = go#package#Paths() - if !exists('workspace') - return -1 + for dir in dirs + if len(dir) && match(path, dir) == 0 + let workspace = dir endif + endfor + + if !exists('workspace') + return -1 + endif - let srcdir = substitute(workspace . '/src/', '//', '/', '') - return substitute(path, srcdir, '', '') + let srcdir = substitute(workspace . '/src/', '//', '/', '') + return substitute(path, srcdir, '', '') endfunction function! go#package#FromPath(arg) - let path = fnamemodify(resolve(a:arg), ':p') - let dirs = go#package#Paths() - - for dir in dirs - if len(dir) && match(path, dir) == 0 - let workspace = dir - endif - endfor + let path = fnamemodify(resolve(a:arg), ':p') + let dirs = go#package#Paths() - if !exists('workspace') - return -1 - endif - - if isdirectory(path) - return substitute(path, workspace . 'src/', '', '') - else - return substitute(substitute(path, workspace . 'src/', '', ''), - \ '/' . fnamemodify(path, ':t'), '', '') + for dir in dirs + if len(dir) && match(path, dir) == 0 + let workspace = dir endif + endfor + + if !exists('workspace') + return -1 + endif + + if isdirectory(path) + return substitute(path, workspace . 'src/', '', '') + else + return substitute(substitute(path, workspace . 'src/', '', ''), + \ '/' . fnamemodify(path, ':t'), '', '') + endif endfunction function! go#package#CompleteMembers(package, member) - silent! let content = go#util#System('godoc ' . a:package) - if go#util#ShellError() || !len(content) - return [] - endif - let lines = filter(split(content, "\n"),"v:val !~ '^\\s\\+$'") - try - let mx1 = '^\s\+\(\S+\)\s\+=\s\+.*' - let mx2 = '^\%(const\|var\|type\|func\) \([A-Z][^ (]\+\).*' - let candidates = map(filter(copy(lines), 'v:val =~ mx1'), - \ 'substitute(v:val, mx1, "\\1", "")') - \ + map(filter(copy(lines), 'v:val =~ mx2'), - \ 'substitute(v:val, mx2, "\\1", "")') - return filter(candidates, '!stridx(v:val, a:member)') - catch - return [] - endtry + silent! let content = go#util#System('godoc ' . a:package) + if go#util#ShellError() || !len(content) + return [] + endif + let lines = filter(split(content, "\n"),"v:val !~ '^\\s\\+$'") + try + let mx1 = '^\s\+\(\S+\)\s\+=\s\+.*' + let mx2 = '^\%(const\|var\|type\|func\) \([A-Z][^ (]\+\).*' + let candidates = map(filter(copy(lines), 'v:val =~ mx1'), + \ 'substitute(v:val, mx1, "\\1", "")') + \ + map(filter(copy(lines), 'v:val =~ mx2'), + \ 'substitute(v:val, mx2, "\\1", "")') + return filter(candidates, '!stridx(v:val, a:member)') + catch + return [] + endtry endfunction function! go#package#Complete(ArgLead, CmdLine, CursorPos) - let words = split(a:CmdLine, '\s\+', 1) + let words = split(a:CmdLine, '\s\+', 1) - " do not complete package members for these commands - let neglect_commands = ["GoImportAs", "GoGuruScope"] + " do not complete package members for these commands + let neglect_commands = ["GoImportAs", "GoGuruScope"] - if len(words) > 2 && index(neglect_commands, words[0]) == -1 - " Complete package members - return go#package#CompleteMembers(words[1], words[2]) - endif + if len(words) > 2 && index(neglect_commands, words[0]) == -1 + " Complete package members + return go#package#CompleteMembers(words[1], words[2]) + endif let dirs = go#package#Paths() @@ -157,4 +157,4 @@ function! go#package#Complete(ArgLead, CmdLine, CursorPos) return sort(keys(ret)) endfunction -" vim:sw=4:et +" vim: sw=2 ts=2 et diff --git a/autoload/go/path.vim b/autoload/go/path.vim index 8afe8f166e..16c4d92617 100644 --- a/autoload/go/path.vim +++ b/autoload/go/path.vim @@ -9,60 +9,60 @@ let s:initial_go_path = "" " GOPATH with it. If two double quotes are passed (the empty string in go), " it'll clear the GOPATH and will restore to the initial GOPATH. function! go#path#GoPath(...) - " we have an argument, replace GOPATH - if len(a:000) - " clears the current manually set GOPATH and restores it to the - " initial GOPATH, which was set when Vim was started. - if len(a:000) == 1 && a:1 == '""' - if !empty(s:initial_go_path) - let $GOPATH = s:initial_go_path - let s:initial_go_path = "" - endif - - echon "vim-go: " | echohl Function | echon "GOPATH restored to ". $GOPATH | echohl None - return - endif - - echon "vim-go: " | echohl Function | echon "GOPATH changed to ". a:1 | echohl None - let s:initial_go_path = $GOPATH - let $GOPATH = a:1 - return + " we have an argument, replace GOPATH + if len(a:000) + " clears the current manually set GOPATH and restores it to the + " initial GOPATH, which was set when Vim was started. + if len(a:000) == 1 && a:1 == '""' + if !empty(s:initial_go_path) + let $GOPATH = s:initial_go_path + let s:initial_go_path = "" + endif + + echon "vim-go: " | echohl Function | echon "GOPATH restored to ". $GOPATH | echohl None + return endif - echo go#path#Detect() + echon "vim-go: " | echohl Function | echon "GOPATH changed to ". a:1 | echohl None + let s:initial_go_path = $GOPATH + let $GOPATH = a:1 + return + endif + + echo go#path#Detect() endfunction " Default returns the default GOPATH. If there is a single GOPATH it returns " it. For multiple GOPATHS separated with a the OS specific separator, only " the first one is returned function! go#path#Default() - let go_paths = split($GOPATH, go#util#PathListSep()) + let go_paths = split($GOPATH, go#util#PathListSep()) - if len(go_paths) == 1 - return $GOPATH - endif + if len(go_paths) == 1 + return $GOPATH + endif - return go_paths[0] + return go_paths[0] endfunction " HasPath checks whether the given path exists in GOPATH environment variable " or not function! go#path#HasPath(path) - let go_paths = split($GOPATH, go#util#PathListSep()) - let last_char = strlen(a:path) - 1 - - " check cases of '/foo/bar/' and '/foo/bar' - if a:path[last_char] == go#util#PathSep() - let withSep = a:path - let noSep = strpart(a:path, 0, last_char) - else - let withSep = a:path . go#util#PathSep() - let noSep = a:path - endif - - let hasA = index(go_paths, withSep) != -1 - let hasB = index(go_paths, noSep) != -1 - return hasA || hasB + let go_paths = split($GOPATH, go#util#PathListSep()) + let last_char = strlen(a:path) - 1 + + " check cases of '/foo/bar/' and '/foo/bar' + if a:path[last_char] == go#util#PathSep() + let withSep = a:path + let noSep = strpart(a:path, 0, last_char) + else + let withSep = a:path . go#util#PathSep() + let noSep = a:path + endif + + let hasA = index(go_paths, withSep) != -1 + let hasB = index(go_paths, noSep) != -1 + return hasA || hasB endfunction " Detect returns the current GOPATH. If a package manager is used, such as @@ -70,60 +70,60 @@ endfunction " over the current GOPATH. It also detects diretories whose are outside " GOPATH. function! go#path#Detect() - let gopath = $GOPATH + let gopath = $GOPATH - " don't lookup for godeps if autodetect is disabled. - if !get(g:, "go_autodetect_gopath", 1) - return gopath - endif + " don't lookup for godeps if autodetect is disabled. + if !get(g:, "go_autodetect_gopath", 1) + return gopath + endif - let current_dir = fnameescape(expand('%:p:h')) + let current_dir = fnameescape(expand('%:p:h')) - " TODO(arslan): this should be changed so folders or files should be - " fetched from a customizable list. The user should define any new package - " management tool by it's own. + " TODO(arslan): this should be changed so folders or files should be + " fetched from a customizable list. The user should define any new package + " management tool by it's own. - " src folder outside $GOPATH - let src_root = finddir("src", current_dir .";") - if !empty(src_root) - let src_path = fnamemodify(src_root, ':p:h:h') . go#util#PathSep() + " src folder outside $GOPATH + let src_root = finddir("src", current_dir .";") + if !empty(src_root) + let src_path = fnamemodify(src_root, ':p:h:h') . go#util#PathSep() - " gb vendor plugin - " (https://github.com/constabulary/gb/tree/master/cmd/gb-vendor) - let gb_vendor_root = src_path . "vendor" . go#util#PathSep() - if isdirectory(gb_vendor_root) && !go#path#HasPath(gb_vendor_root) - let gopath = gb_vendor_root . go#util#PathListSep() . gopath - endif + " gb vendor plugin + " (https://github.com/constabulary/gb/tree/master/cmd/gb-vendor) + let gb_vendor_root = src_path . "vendor" . go#util#PathSep() + if isdirectory(gb_vendor_root) && !go#path#HasPath(gb_vendor_root) + let gopath = gb_vendor_root . go#util#PathListSep() . gopath + endif - if !go#path#HasPath(src_path) - let gopath = src_path . go#util#PathListSep() . gopath - endif + if !go#path#HasPath(src_path) + let gopath = src_path . go#util#PathListSep() . gopath endif + endif - " Godeps - let godeps_root = finddir("Godeps", current_dir .";") - if !empty(godeps_root) - let godeps_path = join([fnamemodify(godeps_root, ':p:h:h'), "Godeps", "_workspace" ], go#util#PathSep()) + " Godeps + let godeps_root = finddir("Godeps", current_dir .";") + if !empty(godeps_root) + let godeps_path = join([fnamemodify(godeps_root, ':p:h:h'), "Godeps", "_workspace" ], go#util#PathSep()) - if !go#path#HasPath(godeps_path) - let gopath = godeps_path . go#util#PathListSep() . gopath - endif + if !go#path#HasPath(godeps_path) + let gopath = godeps_path . go#util#PathListSep() . gopath endif + endif - return gopath + return gopath endfunction " BinPath returns the binary path of installed go tools. function! go#path#BinPath() - let bin_path = "" - - " check if our global custom path is set, if not check if $GOBIN is set so - " we can use it, otherwise use $GOPATH + '/bin' - if exists("g:go_bin_path") - let bin_path = g:go_bin_path - elseif $GOBIN != "" - let bin_path = $GOBIN + let bin_path = "" + + " check if our global custom path is set, if not check if $GOBIN is set so + " we can use it, otherwise use $GOPATH + '/bin' + if exists("g:go_bin_path") + let bin_path = g:go_bin_path + elseif $GOBIN != "" + let bin_path = $GOBIN elseif $GOPATH != "" let bin_path = expand(go#path#Default() . "/bin/") else @@ -172,4 +172,4 @@ function! go#path#CheckBinPath(binpath) return go_bin_path . go#util#PathSep() . basename endfunction -" vim:ts=4:sw=4:et +" vim: sw=2 ts=2 et diff --git a/autoload/go/play.vim b/autoload/go/play.vim index 6a1363792b..44cf3eca4e 100644 --- a/autoload/go/play.vim +++ b/autoload/go/play.vim @@ -1,54 +1,54 @@ if !exists("g:go_play_open_browser") - let g:go_play_open_browser = 1 + let g:go_play_open_browser = 1 endif function! go#play#Share(count, line1, line2) - if !executable('curl') - echohl ErrorMsg | echomsg "vim-go: require 'curl' command" | echohl None - return - endif + if !executable('curl') + echohl ErrorMsg | echomsg "vim-go: require 'curl' command" | echohl None + return + endif - let content = join(getline(a:line1, a:line2), "\n") - let share_file = tempname() - call writefile(split(content, "\n"), share_file, "b") + let content = join(getline(a:line1, a:line2), "\n") + let share_file = tempname() + call writefile(split(content, "\n"), share_file, "b") - let command = "curl -s -X POST https://play.golang.org/share --data-binary '@".share_file."'" - let snippet_id = go#util#System(command) + let command = "curl -s -X POST https://play.golang.org/share --data-binary '@".share_file."'" + let snippet_id = go#util#System(command) - " we can remove the temp file because it's now posted. - call delete(share_file) + " we can remove the temp file because it's now posted. + call delete(share_file) - if go#util#ShellError() != 0 - echo 'A error has occured. Run this command to see what the problem is:' - echo command - return - endif + if go#util#ShellError() != 0 + echo 'A error has occured. Run this command to see what the problem is:' + echo command + return + endif - let url = "http://play.golang.org/p/".snippet_id + let url = "http://play.golang.org/p/".snippet_id - " copy to clipboard - if has('unix') && !has('xterm_clipboard') && !has('clipboard') - let @" = url - else - let @+ = url - endif + " copy to clipboard + if has('unix') && !has('xterm_clipboard') && !has('clipboard') + let @" = url + else + let @+ = url + endif - if g:go_play_open_browser != 0 - call go#tool#OpenBrowser(url) - endif + if g:go_play_open_browser != 0 + call go#tool#OpenBrowser(url) + endif - echo "vim-go: snippet uploaded: ".url + echo "vim-go: snippet uploaded: ".url endfunction function! s:get_visual_content() - let save_regcont = @" - let save_regtype = getregtype('"') - silent! normal! gvy - let content = @" - call setreg('"', save_regcont, save_regtype) - return content + let save_regcont = @" + let save_regtype = getregtype('"') + silent! normal! gvy + let content = @" + call setreg('"', save_regcont, save_regtype) + return content endfunction " modified version of @@ -56,39 +56,38 @@ endfunction " another function that returns the content of visual selection, it's not used " but might be useful in the future function! s:get_visual_selection() - let [lnum1, col1] = getpos("'<")[1:2] - let [lnum2, col2] = getpos("'>")[1:2] - - " check if the the visual mode is used before - if lnum1 == 0 || lnum2 == 0 || col1 == 0 || col2 == 0 - return - endif - - let lines = getline(lnum1, lnum2) - let lines[-1] = lines[-1][: col2 - (&selection == 'inclusive' ? 1 : 2)] - let lines[0] = lines[0][col1 - 1:] - return join(lines, "\n") + let [lnum1, col1] = getpos("'<")[1:2] + let [lnum2, col2] = getpos("'>")[1:2] + + " check if the the visual mode is used before + if lnum1 == 0 || lnum2 == 0 || col1 == 0 || col2 == 0 + return + endif + + let lines = getline(lnum1, lnum2) + let lines[-1] = lines[-1][: col2 - (&selection == 'inclusive' ? 1 : 2)] + let lines[0] = lines[0][col1 - 1:] + return join(lines, "\n") endfunction " following two functions are from: https://github.com/mattn/gist-vim " thanks @mattn function! s:get_browser_command() - let go_play_browser_command = get(g:, 'go_play_browser_command', '') - if go_play_browser_command == '' - if has('win32') || has('win64') - let go_play_browser_command = '!start rundll32 url.dll,FileProtocolHandler %URL%' - elseif has('mac') || has('macunix') || has('gui_macvim') || go#util#System('uname') =~? '^darwin' - let go_play_browser_command = 'open %URL%' - elseif executable('xdg-open') - let go_play_browser_command = 'xdg-open %URL%' - elseif executable('firefox') - let go_play_browser_command = 'firefox %URL% &' - else - let go_play_browser_command = '' - endif + let go_play_browser_command = get(g:, 'go_play_browser_command', '') + if go_play_browser_command == '' + if has('win32') || has('win64') + let go_play_browser_command = '!start rundll32 url.dll,FileProtocolHandler %URL%' + elseif has('mac') || has('macunix') || has('gui_macvim') || go#util#System('uname') =~? '^darwin' + let go_play_browser_command = 'open %URL%' + elseif executable('xdg-open') + let go_play_browser_command = 'xdg-open %URL%' + elseif executable('firefox') + let go_play_browser_command = 'firefox %URL% &' + else + let go_play_browser_command = '' endif - return go_play_browser_command + endif + return go_play_browser_command endfunction - -" vim:ts=4:sw=4:et +" vim: sw=2 ts=2 et diff --git a/autoload/go/rename.vim b/autoload/go/rename.vim index cb92dc9fbe..d65256c517 100644 --- a/autoload/go/rename.vim +++ b/autoload/go/rename.vim @@ -1,78 +1,77 @@ if !exists("g:go_gorename_bin") - let g:go_gorename_bin = "gorename" + let g:go_gorename_bin = "gorename" endif if !exists("g:go_gorename_prefill") - let g:go_gorename_prefill = 1 + let g:go_gorename_prefill = 1 endif function! go#rename#Rename(bang, ...) - let to = "" - if a:0 == 0 - let from = expand("") - let ask = printf("vim-go: rename '%s' to: ", from) - if g:go_gorename_prefill - let to = input(ask, from) - else - let to = input(ask) - endif - redraw! - if empty(to) - return - endif + let to = "" + if a:0 == 0 + let from = expand("") + let ask = printf("vim-go: rename '%s' to: ", from) + if g:go_gorename_prefill + let to = input(ask, from) else - let to = a:1 + let to = input(ask) 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) - return + redraw! + if empty(to) + return endif + else + let to = a:1 + endif - let fname = expand('%:p') - let pos = go#util#OffsetCursor() - let cmd = printf('%s -offset %s -to %s', shellescape(bin_path), shellescape(printf('%s:#%d', fname, pos)), shellescape(to)) + "return with a warning if the bin doesn't exist + let bin_path = go#path#CheckBinPath(g:go_gorename_bin) + if empty(bin_path) + return + endif - let out = go#tool#ExecuteInDir(cmd) + let fname = expand('%:p') + let pos = go#util#OffsetCursor() + let cmd = printf('%s -offset %s -to %s', shellescape(bin_path), shellescape(printf('%s:#%d', fname, pos)), shellescape(to)) - " reload all files to reflect the new changes. We explicitly call - " checktime to trigger a reload of all files. See - " http://www.mail-archive.com/vim@vim.org/msg05900.html for more info - " about the autoread bug - let current_autoread = &autoread - set autoread - silent! checktime - let &autoread = current_autoread + let out = go#tool#ExecuteInDir(cmd) - " strip out newline on the end that gorename puts. If we don't remove, it - " will trigger the 'Hit ENTER to continue' prompt - let clean = split(out, '\n') + " reload all files to reflect the new changes. We explicitly call + " checktime to trigger a reload of all files. See + " http://www.mail-archive.com/vim@vim.org/msg05900.html for more info + " about the autoread bug + let current_autoread = &autoread + set autoread + silent! checktime + let &autoread = current_autoread - let l:listtype = "quickfix" - if go#util#ShellError() != 0 - let errors = go#tool#ParseErrors(split(out, '\n')) - call go#list#Populate(l:listtype, errors) - call go#list#Window(l:listtype, len(errors)) - if !empty(errors) && !a:bang - call go#list#JumpToFirst(l:listtype) - elseif empty(errors) - " failed to parse errors, output the original content - call go#util#EchoError(out) - endif - return - else - call go#list#Clean(l:listtype) - call go#list#Window(l:listtype) - redraw | echon "vim-go: " | echohl Function | echon clean[0] | echohl None + " strip out newline on the end that gorename puts. If we don't remove, it + " will trigger the 'Hit ENTER to continue' prompt + let clean = split(out, '\n') + + let l:listtype = "quickfix" + if go#util#ShellError() != 0 + let errors = go#tool#ParseErrors(split(out, '\n')) + call go#list#Populate(l:listtype, errors) + call go#list#Window(l:listtype, len(errors)) + if !empty(errors) && !a:bang + call go#list#JumpToFirst(l:listtype) + elseif empty(errors) + " failed to parse errors, output the original content + call go#util#EchoError(out) endif + return + else + call go#list#Clean(l:listtype) + call go#list#Window(l:listtype) + 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" + " 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 -" vim:ts=4:sw=4:et -" +" vim: sw=2 ts=2 et diff --git a/autoload/go/term.vim b/autoload/go/term.vim index f6fe150eb9..08947fa947 100644 --- a/autoload/go/term.vim +++ b/autoload/go/term.vim @@ -1,5 +1,5 @@ if has('nvim') && !exists("g:go_term_mode") - let g:go_term_mode = 'vsplit' + let g:go_term_mode = 'vsplit' endif " s:jobs is a global reference to all jobs started with new() @@ -8,121 +8,121 @@ let s:jobs = {} " new creates a new terminal with the given command. Mode is set based on the " global variable g:go_term_mode, which is by default set to :vsplit function! go#term#new(bang, cmd) - return go#term#newmode(a:bang, a:cmd, g:go_term_mode) + return go#term#newmode(a:bang, a:cmd, g:go_term_mode) endfunction " new creates a new terminal with the given command and window mode. function! go#term#newmode(bang, cmd, mode) - let mode = a:mode - if empty(mode) - let mode = g:go_term_mode - endif + let mode = a:mode + if empty(mode) + let mode = g:go_term_mode + endif - " modify GOPATH if needed - let old_gopath = $GOPATH - let $GOPATH = go#path#Detect() + " modify GOPATH if needed + let old_gopath = $GOPATH + let $GOPATH = go#path#Detect() - " execute go build in the files directory - let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd ' : 'cd ' - let dir = getcwd() + " execute go build in the files directory + let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd ' : 'cd ' + let dir = getcwd() - execute cd . fnameescape(expand("%:p:h")) + execute cd . fnameescape(expand("%:p:h")) - execute mode.' __go_term__' + execute mode.' __go_term__' - setlocal filetype=goterm - setlocal bufhidden=delete - setlocal winfixheight - setlocal noswapfile - setlocal nobuflisted + setlocal filetype=goterm + setlocal bufhidden=delete + setlocal winfixheight + setlocal noswapfile + setlocal nobuflisted - let job = { - \ 'stderr' : [], - \ 'stdout' : [], - \ 'bang' : a:bang, - \ 'on_stdout': function('s:on_stdout'), - \ 'on_stderr': function('s:on_stderr'), - \ 'on_exit' : function('s:on_exit'), - \ } + let job = { + \ 'stderr' : [], + \ 'stdout' : [], + \ 'bang' : a:bang, + \ 'on_stdout': function('s:on_stdout'), + \ 'on_stderr': function('s:on_stderr'), + \ 'on_exit' : function('s:on_exit'), + \ } - let id = termopen(a:cmd, job) + let id = termopen(a:cmd, job) - execute cd . fnameescape(dir) + execute cd . fnameescape(dir) - " restore back GOPATH - let $GOPATH = old_gopath + " restore back GOPATH + let $GOPATH = old_gopath - let job.id = id - startinsert + let job.id = id + startinsert - " resize new term if needed. - let height = get(g:, 'go_term_height', winheight(0)) - let width = get(g:, 'go_term_width', winwidth(0)) + " resize new term if needed. + let height = get(g:, 'go_term_height', winheight(0)) + let width = get(g:, 'go_term_width', winwidth(0)) - " we are careful how to resize. for example it's vertical we don't change - " the height. The below command resizes the buffer - if a:mode == "split" - exe 'resize ' . height - elseif a:mode == "vertical" - exe 'vertical resize ' . width - endif + " we are careful how to resize. for example it's vertical we don't change + " the height. The below command resizes the buffer + if a:mode == "split" + exe 'resize ' . height + elseif a:mode == "vertical" + exe 'vertical resize ' . width + endif - " we also need to resize the pty, so there you go... - call jobresize(id, width, height) + " we also need to resize the pty, so there you go... + call jobresize(id, width, height) - let s:jobs[id] = job - return id + let s:jobs[id] = job + return id endfunction function! s:on_stdout(job_id, data) - if !has_key(s:jobs, a:job_id) - return - endif - let job = s:jobs[a:job_id] + if !has_key(s:jobs, a:job_id) + return + endif + let job = s:jobs[a:job_id] - call extend(job.stdout, a:data) + call extend(job.stdout, a:data) endfunction function! s:on_stderr(job_id, data) - if !has_key(s:jobs, a:job_id) - return - endif - let job = s:jobs[a:job_id] + if !has_key(s:jobs, a:job_id) + return + endif + let job = s:jobs[a:job_id] - call extend(job.stderr, a:data) + call extend(job.stderr, a:data) endfunction function! s:on_exit(job_id, exit_status) - if !has_key(s:jobs, a:job_id) - return - endif - let job = s:jobs[a:job_id] + if !has_key(s:jobs, a:job_id) + return + endif + let job = s:jobs[a:job_id] - let l:listtype = "locationlist" + let l:listtype = "locationlist" - " usually there is always output so never branch into this clause - if empty(job.stdout) - call go#list#Clean(l:listtype) - call go#list#Window(l:listtype) - unlet s:jobs[a:job_id] - return - endif + " usually there is always output so never branch into this clause + if empty(job.stdout) + call go#list#Clean(l:listtype) + call go#list#Window(l:listtype) + unlet s:jobs[a:job_id] + return + endif - let errors = go#tool#ParseErrors(job.stdout) - let errors = go#tool#FilterValids(errors) + let errors = go#tool#ParseErrors(job.stdout) + let errors = go#tool#FilterValids(errors) - if !empty(errors) - " close terminal we don't need it anymore - close + if !empty(errors) + " close terminal we don't need it anymore + close - call go#list#Populate(l:listtype, errors) - call go#list#Window(l:listtype, len(errors)) - if !self.bang - call go#list#JumpToFirst(l:listtype) - endif - unlet s:jobs[a:job_id] - return + call go#list#Populate(l:listtype, errors) + call go#list#Window(l:listtype, len(errors)) + if !self.bang + call go#list#JumpToFirst(l:listtype) endif + unlet s:jobs[a:job_id] + return + endif " tests are passing clean the list and close the list. But we only can " close them from a normal view, so jump back, close the list and then @@ -135,4 +135,4 @@ function! s:on_exit(job_id, exit_status) unlet s:jobs[a:job_id] endfunction -" vim:ts=4:sw=4:et +" vim: sw=2 ts=2 et diff --git a/autoload/go/textobj.vim b/autoload/go/textobj.vim index ba1d03eee1..53dfacd46d 100644 --- a/autoload/go/textobj.vim +++ b/autoload/go/textobj.vim @@ -177,4 +177,4 @@ function! go#textobj#FunctionJump(mode, direction) keepjumps call cursor(info.func.line, 1) endfunction -" vim:ts=2:sw=2:et +" vim: sw=2 ts=2 et diff --git a/autoload/go/tool.vim b/autoload/go/tool.vim index a3c80172ff..276e5d02d6 100644 --- a/autoload/go/tool.vim +++ b/autoload/go/tool.vim @@ -1,129 +1,129 @@ function! go#tool#Files() - if go#util#IsWin() - let format = '{{range $f := .GoFiles}}{{$.Dir}}\{{$f}}{{printf \"\n\"}}{{end}}{{range $f := .CgoFiles}}{{$.Dir}}\{{$f}}{{printf \"\n\"}}{{end}}' - else - let format = "{{range $f := .GoFiles}}{{$.Dir}}/{{$f}}{{printf \"\\n\"}}{{end}}{{range $f := .CgoFiles}}{{$.Dir}}/{{$f}}{{printf \"\\n\"}}{{end}}" - endif - let command = 'go list -f '.shellescape(format) - let out = go#tool#ExecuteInDir(command) - return split(out, '\n') + if go#util#IsWin() + let format = '{{range $f := .GoFiles}}{{$.Dir}}\{{$f}}{{printf \"\n\"}}{{end}}{{range $f := .CgoFiles}}{{$.Dir}}\{{$f}}{{printf \"\n\"}}{{end}}' + else + let format = "{{range $f := .GoFiles}}{{$.Dir}}/{{$f}}{{printf \"\\n\"}}{{end}}{{range $f := .CgoFiles}}{{$.Dir}}/{{$f}}{{printf \"\\n\"}}{{end}}" + endif + let command = 'go list -f '.shellescape(format) + let out = go#tool#ExecuteInDir(command) + return split(out, '\n') endfunction function! go#tool#Deps() - if go#util#IsWin() - let format = '{{range $f := .Deps}}{{$f}}{{printf \"\n\"}}{{end}}' - else - let format = "{{range $f := .Deps}}{{$f}}\n{{end}}" - endif - let command = 'go list -f '.shellescape(format) - let out = go#tool#ExecuteInDir(command) - return split(out, '\n') + if go#util#IsWin() + let format = '{{range $f := .Deps}}{{$f}}{{printf \"\n\"}}{{end}}' + else + let format = "{{range $f := .Deps}}{{$f}}\n{{end}}" + endif + let command = 'go list -f '.shellescape(format) + let out = go#tool#ExecuteInDir(command) + return split(out, '\n') endfunction function! go#tool#Imports() - let imports = {} - if go#util#IsWin() - let format = '{{range $f := .Imports}}{{$f}}{{printf \"\n\"}}{{end}}' - else - let format = "{{range $f := .Imports}}{{$f}}{{printf \"\\n\"}}{{end}}" - endif - let command = 'go list -f '.shellescape(format) - let out = go#tool#ExecuteInDir(command) - if go#util#ShellError() != 0 - echo out - return imports - endif + let imports = {} + if go#util#IsWin() + let format = '{{range $f := .Imports}}{{$f}}{{printf \"\n\"}}{{end}}' + else + let format = "{{range $f := .Imports}}{{$f}}{{printf \"\\n\"}}{{end}}" + endif + let command = 'go list -f '.shellescape(format) + let out = go#tool#ExecuteInDir(command) + if go#util#ShellError() != 0 + echo out + return imports + endif - for package_path in split(out, '\n') - let cmd = "go list -f '{{.Name}}' " . shellescape(package_path) - let package_name = substitute(go#tool#ExecuteInDir(cmd), '\n$', '', '') - let imports[package_name] = package_path - endfor + for package_path in split(out, '\n') + let cmd = "go list -f '{{.Name}}' " . shellescape(package_path) + let package_name = substitute(go#tool#ExecuteInDir(cmd), '\n$', '', '') + let imports[package_name] = package_path + endfor - return imports + return imports endfunction function! go#tool#ParseErrors(lines) - let errors = [] - - for line in a:lines - let fatalerrors = matchlist(line, '^\(fatal error:.*\)$') - let tokens = matchlist(line, '^\s*\(.\{-}\):\(\d\+\):\s*\(.*\)') - - if !empty(fatalerrors) - call add(errors, {"text": fatalerrors[1]}) - elseif !empty(tokens) - " strip endlines of form ^M - let out = substitute(tokens[3], '\r$', '', '') - - call add(errors, { - \ "filename" : fnamemodify(tokens[1], ':p'), - \ "lnum" : tokens[2], - \ "text" : out, - \ }) - elseif !empty(errors) - " Preserve indented lines. - " This comes up especially with multi-line test output. - if match(line, '^\s') >= 0 - call add(errors, {"text": line}) - endif - endif - endfor + let errors = [] + + for line in a:lines + let fatalerrors = matchlist(line, '^\(fatal error:.*\)$') + let tokens = matchlist(line, '^\s*\(.\{-}\):\(\d\+\):\s*\(.*\)') + + if !empty(fatalerrors) + call add(errors, {"text": fatalerrors[1]}) + elseif !empty(tokens) + " strip endlines of form ^M + let out = substitute(tokens[3], '\r$', '', '') + + call add(errors, { + \ "filename" : fnamemodify(tokens[1], ':p'), + \ "lnum" : tokens[2], + \ "text" : out, + \ }) + elseif !empty(errors) + " Preserve indented lines. + " This comes up especially with multi-line test output. + if match(line, '^\s') >= 0 + call add(errors, {"text": line}) + endif + endif + endfor - return errors + return errors endfunction "FilterValids filters the given items with only items that have a valid "filename. Any non valid filename is filtered out. function! go#tool#FilterValids(items) - " 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 filtered = [] - let is_readable = {} - - for item in a:items - if has_key(item, 'bufnr') - let filename = bufname(item.bufnr) - elseif has_key(item, 'filename') - let filename = item.filename - else - " nothing to do, add item back to the list - call add(filtered, item) - continue - endif + " 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 filtered = [] + let is_readable = {} + + for item in a:items + if has_key(item, 'bufnr') + let filename = bufname(item.bufnr) + elseif has_key(item, 'filename') + let filename = item.filename + else + " nothing to do, add item back to the list + call add(filtered, item) + continue + endif - if !has_key(is_readable, filename) - let is_readable[filename] = filereadable(filename) - endif - if is_readable[filename] - call add(filtered, item) - endif - endfor + if !has_key(is_readable, filename) + let is_readable[filename] = filereadable(filename) + endif + if is_readable[filename] + call add(filtered, item) + endif + endfor - 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 location list (nonvalid filename)" | echohl None - endfor + 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 location list (nonvalid filename)" | echohl None + endfor - return filtered + return filtered endfunction function! go#tool#ExecuteInDir(cmd) abort - let old_gopath = $GOPATH - let $GOPATH = go#path#Detect() - - let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd ' : 'cd ' - let dir = getcwd() - try - execute cd . fnameescape(expand("%:p:h")) - let out = go#util#System(a:cmd) - finally - execute cd . fnameescape(dir) - endtry - - let $GOPATH = old_gopath - return out + let old_gopath = $GOPATH + let $GOPATH = go#path#Detect() + + let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd ' : 'cd ' + let dir = getcwd() + try + execute cd . fnameescape(expand("%:p:h")) + let out = go#util#System(a:cmd) + finally + execute cd . fnameescape(dir) + endtry + + let $GOPATH = old_gopath + return out endfunction " Exists checks whether the given importpath exists or not. It returns 0 if @@ -182,4 +182,4 @@ function! go#tool#OpenBrowser(url) endif endfunction -" vim:ts=4:sw=4:et +" vim: sw=2 ts=2 et diff --git a/autoload/go/ui.vim b/autoload/go/ui.vim index c4f7abe689..ad8b517bfe 100644 --- a/autoload/go/ui.vim +++ b/autoload/go/ui.vim @@ -2,112 +2,113 @@ let s:buf_nr = -1 "OpenWindow opens a new scratch window and put's the content into the window function! go#ui#OpenWindow(title, content, filetype) - " Ensure there's only one return window in this session/tabpage - call go#util#Windo("unlet! w:vim_go_return_window") - " Mark the window we're leaving as such - let w:vim_go_return_window = 1 - - " reuse existing buffer window if it exists otherwise create a new one - if !bufexists(s:buf_nr) - execute 'botright new' - file `="[" . a:title . "]"` - let s:buf_nr = bufnr('%') - elseif bufwinnr(s:buf_nr) == -1 - execute 'botright new' - execute s:buf_nr . 'buffer' - elseif bufwinnr(s:buf_nr) != bufwinnr('%') - execute bufwinnr(s:buf_nr) . 'wincmd w' - endif - - " Resize window to content length - exe 'resize' . len(a:content) - - execute "setlocal filetype=".a:filetype - - " some sane default values for a readonly buffer - setlocal bufhidden=delete - setlocal buftype=nofile - setlocal noswapfile - setlocal nobuflisted - setlocal winfixheight - setlocal cursorline " make it easy to distinguish - setlocal nonumber - setlocal norelativenumber - setlocal showbreak="" - - " we need this to purge the buffer content - setlocal modifiable - - "delete everything first from the buffer - %delete _ - - " add the content - call append(0, a:content) - - " delete last line that comes from the append call - $delete _ - - " set it back to non modifiable - setlocal nomodifiable - - " Remove the '... [New File]' message line from the command line - echon + " Ensure there's only one return window in this session/tabpage + call go#util#Windo("unlet! w:vim_go_return_window") + " Mark the window we're leaving as such + let w:vim_go_return_window = 1 + + " reuse existing buffer window if it exists otherwise create a new one + if !bufexists(s:buf_nr) + execute 'botright new' + file `="[" . a:title . "]"` + let s:buf_nr = bufnr('%') + elseif bufwinnr(s:buf_nr) == -1 + execute 'botright new' + execute s:buf_nr . 'buffer' + elseif bufwinnr(s:buf_nr) != bufwinnr('%') + execute bufwinnr(s:buf_nr) . 'wincmd w' + endif + + " Resize window to content length + exe 'resize' . len(a:content) + + execute "setlocal filetype=".a:filetype + + " some sane default values for a readonly buffer + setlocal bufhidden=delete + setlocal buftype=nofile + setlocal noswapfile + setlocal nobuflisted + setlocal winfixheight + setlocal cursorline " make it easy to distinguish + setlocal nonumber + setlocal norelativenumber + setlocal showbreak="" + + " we need this to purge the buffer content + setlocal modifiable + + "delete everything first from the buffer + %delete _ + + " add the content + call append(0, a:content) + + " delete last line that comes from the append call + $delete _ + + " set it back to non modifiable + setlocal nomodifiable + + " Remove the '... [New File]' message line from the command line + echon endfunction function! go#ui#GetReturnWindow() - for l:wn in range(1, winnr("$")) - if !empty(getwinvar(l:wn, "vim_go_return_window")) - return l:wn - endif - endfor + for l:wn in range(1, winnr("$")) + if !empty(getwinvar(l:wn, "vim_go_return_window")) + return l:wn + endif + endfor endfunction " CloseWindow closes the current window function! go#ui#CloseWindow() - " Close any window associated with the ui buffer, if it's there - if bufexists(s:buf_nr) - let ui_window_number = bufwinnr(s:buf_nr) - if ui_window_number != -1 - execute ui_window_number . 'close' - endif - endif - - "return to original window, if it's there - let l:rw = go#ui#GetReturnWindow() - if !empty(l:rw) - execute l:rw . 'wincmd w' - unlet! w:vim_go_return_window + " Close any window associated with the ui buffer, if it's there + if bufexists(s:buf_nr) + let ui_window_number = bufwinnr(s:buf_nr) + if ui_window_number != -1 + execute ui_window_number . 'close' endif + endif + + "return to original window, if it's there + let l:rw = go#ui#GetReturnWindow() + if !empty(l:rw) + execute l:rw . 'wincmd w' + unlet! w:vim_go_return_window + endif endfunction " OpenDefinition parses the current line and jumps to it by openening a new " tab function! go#ui#OpenDefinition(filter) - let curline = getline('.') + let curline = getline('.') - " don't touch our first line or any blank line - if curline =~ a:filter || curline =~ "^$" - " suppress information about calling this function - echo "" - return - endif + " don't touch our first line or any blank line + if curline =~ a:filter || curline =~ "^$" + " suppress information about calling this function + echo "" + return + endif - " format: 'interface file:lnum:coln' - let mx = '^\(^\S*\)\s*\(.\{-}\):\(\d\+\):\(\d\+\)' + " format: 'interface file:lnum:coln' + let mx = '^\(^\S*\)\s*\(.\{-}\):\(\d\+\):\(\d\+\)' - " parse it now into the list - let tokens = matchlist(curline, mx) + " parse it now into the list + let tokens = matchlist(curline, mx) - " convert to: 'file:lnum:coln' - let expr = tokens[2] . ":" . tokens[3] . ":" . tokens[4] + " convert to: 'file:lnum:coln' + let expr = tokens[2] . ":" . tokens[3] . ":" . tokens[4] - " jump to it in a new tab, we use explicit lgetexpr so we can later change - " the behaviour via settings (like opening in vsplit instead of tab) - lgetexpr expr - tab split - ll 1 + " jump to it in a new tab, we use explicit lgetexpr so we can later change + " the behaviour via settings (like opening in vsplit instead of tab) + lgetexpr expr + tab split + ll 1 - " center the word - norm! zz + " center the word + norm! zz endfunction +" vim: sw=2 ts=2 et diff --git a/autoload/go/util.vim b/autoload/go/util.vim index ca0e512caa..3553b50429 100644 --- a/autoload/go/util.vim +++ b/autoload/go/util.vim @@ -1,112 +1,112 @@ " PathSep returns the appropriate OS specific path separator. function! go#util#PathSep() - if go#util#IsWin() - return '\' - endif - return '/' + if go#util#IsWin() + return '\' + endif + return '/' endfunction " PathListSep returns the appropriate OS specific path list separator. function! go#util#PathListSep() - if go#util#IsWin() - return ";" - endif - return ":" + if go#util#IsWin() + return ";" + endif + return ":" endfunction " LineEnding returns the correct line ending, based on the current fileformat function! go#util#LineEnding() - if &fileformat == 'dos' - return "\r\n" - elseif &fileformat == 'mac' - return "\r" - endif + if &fileformat == 'dos' + return "\r\n" + elseif &fileformat == 'mac' + return "\r" + endif - return "\n" + return "\n" endfunction " IsWin returns 1 if current OS is Windows or 0 otherwise function! go#util#IsWin() - let win = ['win16', 'win32', 'win64', 'win95'] - for w in win - if (has(w)) - return 1 - endif - endfor + let win = ['win16', 'win32', 'win64', 'win95'] + for w in win + if (has(w)) + return 1 + endif + endfor - return 0 + return 0 endfunction function! go#util#GOARCH() - return substitute(go#util#System('go env GOARCH'), '\n', '', 'g') + return substitute(go#util#System('go env GOARCH'), '\n', '', 'g') endfunction function! go#util#GOOS() - return substitute(go#util#System('go env GOOS'), '\n', '', 'g') + return substitute(go#util#System('go env GOOS'), '\n', '', 'g') endfunction function! go#util#GOROOT() - return substitute(go#util#System('go env GOROOT'), '\n', '', 'g') + return substitute(go#util#System('go env GOROOT'), '\n', '', 'g') endfunction function! go#util#GOPATH() - return substitute(go#util#System('go env GOPATH'), '\n', '', 'g') + return substitute(go#util#System('go env GOPATH'), '\n', '', 'g') endfunction function! go#util#OSARCH() - return go#util#GOOS() . '_' . go#util#GOARCH() + return go#util#GOOS() . '_' . go#util#GOARCH() endfunction "Check if has vimproc function! s:has_vimproc() - if !exists('g:go#use_vimproc') - if go#util#IsWin() - try - call vimproc#version() - let exists_vimproc = 1 - catch - let exists_vimproc = 0 - endtry - else - let exists_vimproc = 0 - endif - - let g:go#use_vimproc = exists_vimproc + if !exists('g:go#use_vimproc') + if go#util#IsWin() + try + call vimproc#version() + let exists_vimproc = 1 + catch + let exists_vimproc = 0 + endtry + else + let exists_vimproc = 0 endif - return g:go#use_vimproc + let g:go#use_vimproc = exists_vimproc + endif + + return g:go#use_vimproc endfunction if s:has_vimproc() - let s:vim_system = get(g:, 'gocomplete#system_function', 'vimproc#system2') - let s:vim_shell_error = get(g:, 'gocomplete#shell_error_function', 'vimproc#get_last_status') + let s:vim_system = get(g:, 'gocomplete#system_function', 'vimproc#system2') + let s:vim_shell_error = get(g:, 'gocomplete#shell_error_function', 'vimproc#get_last_status') else - let s:vim_system = get(g:, 'gocomplete#system_function', 'system') - let s:vim_shell_error = '' + let s:vim_system = get(g:, 'gocomplete#system_function', 'system') + let s:vim_shell_error = '' endif function! go#util#System(str, ...) - return call(s:vim_system, [a:str] + a:000) + return call(s:vim_system, [a:str] + a:000) endfunction function! go#util#ShellError() - if empty(s:vim_shell_error) - return v:shell_error - endif - return call(s:vim_shell_error, []) + if empty(s:vim_shell_error) + return v:shell_error + endif + return call(s:vim_shell_error, []) endfunction " StripPath strips the path's last character if it's a path separator. " example: '/foo/bar/' -> '/foo/bar' function! go#util#StripPathSep(path) - let last_char = strlen(a:path) - 1 - if a:path[last_char] == go#util#PathSep() - return strpart(a:path, 0, last_char) - endif + let last_char = strlen(a:path) - 1 + if a:path[last_char] == go#util#PathSep() + return strpart(a:path, 0, last_char) + endif - return a:path + return a:path endfunction " StripTrailingSlash strips the trailing slash from the given path list. @@ -118,12 +118,12 @@ endfunction " Shelljoin returns a shell-safe string representation of arglist. The " {special} argument of shellescape() may optionally be passed. function! go#util#Shelljoin(arglist, ...) - try - let ssl_save = &shellslash - set noshellslash - if a:0 - return join(map(copy(a:arglist), 'shellescape(v:val, ' . a:1 . ')'), ' ') - endif + try + let ssl_save = &shellslash + set noshellslash + if a:0 + return join(map(copy(a:arglist), 'shellescape(v:val, ' . a:1 . ')'), ' ') + endif return join(map(copy(a:arglist), 'shellescape(v:val)'), ' ') finally @@ -206,4 +206,4 @@ function! go#util#EchoProgress(msg) redraws! | echon "vim-go: " | echohl Identifier | echon a:msg | echohl None endfunction -" vim:ts=4:sw=4:et +" vim: sw=2 ts=2 et diff --git a/compiler/go.vim b/compiler/go.vim index 7b5a0255ac..b2ec1b3c97 100644 --- a/compiler/go.vim +++ b/compiler/go.vim @@ -16,9 +16,9 @@ endif let s:save_cpo = &cpo set cpo-=C if filereadable("makefile") || filereadable("Makefile") - CompilerSet makeprg=make + CompilerSet makeprg=make else - CompilerSet makeprg=go\ build + CompilerSet makeprg=go\ build endif " Define the patterns that will be recognized by QuickFix when parsing the @@ -38,4 +38,4 @@ CompilerSet errorformat+=%-G%.%# " All lines not matching a let &cpo = s:save_cpo unlet s:save_cpo -" vim:ts=4:sw=4:et +" vim: sw=2 ts=2 et diff --git a/ftdetect/gofiletype.vim b/ftdetect/gofiletype.vim index b5578a6e59..267d2cc316 100644 --- a/ftdetect/gofiletype.vim +++ b/ftdetect/gofiletype.vim @@ -6,16 +6,16 @@ let s:current_fileencodings = '' " define fileencodings to open as utf-8 encoding even if it's ascii. function! s:gofiletype_pre(type) - let s:current_fileformats = &g:fileformats - let s:current_fileencodings = &g:fileencodings - set fileencodings=utf-8 fileformats=unix - let &l:filetype = a:type + let s:current_fileformats = &g:fileformats + let s:current_fileencodings = &g:fileencodings + set fileencodings=utf-8 fileformats=unix + let &l:filetype = a:type endfunction " restore fileencodings as others function! s:gofiletype_post() - let &g:fileformats = s:current_fileformats - let &g:fileencodings = s:current_fileencodings + let &g:fileformats = s:current_fileformats + let &g:fileencodings = s:current_fileencodings endfunction au BufNewFile *.go setfiletype go | setlocal fileencoding=utf-8 fileformat=unix @@ -28,4 +28,4 @@ au BufReadPost *.s call s:gofiletype_post() au BufRead,BufNewFile *.tmpl set filetype=gohtmltmpl -" vim:ts=4:sw=4:et +" vim: sw=2 ts=2 et diff --git a/ftplugin/asm.vim b/ftplugin/asm.vim index 0ac3594bf1..99996aac99 100644 --- a/ftplugin/asm.vim +++ b/ftplugin/asm.vim @@ -1,7 +1,7 @@ " asm.vim: Vim filetype plugin for Go assembler. if exists("b:did_ftplugin") - finish + finish endif let b:did_ftplugin = 1 @@ -15,3 +15,5 @@ setlocal commentstring=//\ %s setlocal noexpandtab command! -nargs=0 AsmFmt call go#asmfmt#Format() + +" vim: sw=2 ts=2 et diff --git a/ftplugin/go.vim b/ftplugin/go.vim index f322ea3984..e4e993aa28 100644 --- a/ftplugin/go.vim +++ b/ftplugin/go.vim @@ -5,7 +5,7 @@ " go.vim: Vim filetype plugin for Go. if exists("b:did_ftplugin") - finish + finish endif let b:did_ftplugin = 1 @@ -24,40 +24,40 @@ compiler go setlocal omnifunc=go#complete#Complete if get(g:, "go_doc_keywordprg_enabled", 1) - " keywordprg doesn't allow to use vim commands, override it - nnoremap K :GoDoc + " keywordprg doesn't allow to use vim commands, override it + nnoremap K :GoDoc endif if get(g:, "go_def_mapping_enabled", 1) - " these are default Vim mappings, we're overriding them to make them - " useful again for Go source code - nnoremap gd :GoDef - nnoremap :GoDef - nnoremap :call go#def#Jump("split") - nnoremap ] :call go#def#Jump("split") - nnoremap :call go#def#StackPop(v:count1) + " these are default Vim mappings, we're overriding them to make them + " useful again for Go source code + nnoremap gd :GoDef + nnoremap :GoDef + nnoremap :call go#def#Jump("split") + nnoremap ] :call go#def#Jump("split") + nnoremap :call go#def#StackPop(v:count1) endif if get(g:, "go_textobj_enabled", 1) - onoremap af :call go#textobj#Function('a') - onoremap if :call go#textobj#Function('i') + onoremap af :call go#textobj#Function('a') + onoremap if :call go#textobj#Function('i') - xnoremap af :call go#textobj#Function('a') - xnoremap if :call go#textobj#Function('i') + xnoremap af :call go#textobj#Function('a') + xnoremap if :call go#textobj#Function('i') - " Remap ]] and [[ to jump betweeen functions as they are useless in Go - nnoremap ]] :call go#textobj#FunctionJump('n', 'next') - nnoremap [[ :call go#textobj#FunctionJump('n', 'prev') + " Remap ]] and [[ to jump betweeen functions as they are useless in Go + nnoremap ]] :call go#textobj#FunctionJump('n', 'next') + nnoremap [[ :call go#textobj#FunctionJump('n', 'prev') - onoremap ]] :call go#textobj#FunctionJump('o', 'next') - onoremap [[ :call go#textobj#FunctionJump('o', 'prev') + onoremap ]] :call go#textobj#FunctionJump('o', 'next') + onoremap [[ :call go#textobj#FunctionJump('o', 'prev') - xnoremap ]] :call go#textobj#FunctionJump('v', 'next') - xnoremap [[ :call go#textobj#FunctionJump('v', 'prev') + xnoremap ]] :call go#textobj#FunctionJump('v', 'next') + xnoremap [[ :call go#textobj#FunctionJump('v', 'prev') endif if get(g:, "go_auto_type_info", 0) - setlocal updatetime=800 + setlocal updatetime=800 endif -" vim:ts=4:sw=4:et +" vim: sw=2 ts=2 et diff --git a/ftplugin/go/commands.vim b/ftplugin/go/commands.vim index 44db45a31e..5b60b501d4 100644 --- a/ftplugin/go/commands.vim +++ b/ftplugin/go/commands.vim @@ -76,4 +76,4 @@ endif " -- impl command! -nargs=* -buffer -complete=customlist,go#impl#Complete GoImpl call go#impl#Impl() -" vim:ts=4:sw=4:et +" vim: sw=2 ts=2 et diff --git a/ftplugin/go/mappings.vim b/ftplugin/go/mappings.vim index 70d56eaa28..3dafacc2e3 100644 --- a/ftplugin/go/mappings.vim +++ b/ftplugin/go/mappings.vim @@ -5,16 +5,16 @@ " which by default is enabled. For commands the user has the ability to pass " the '!', such as :GoBuild or :GoBuild! if !exists("g:go_jump_to_error") - let g:go_jump_to_error = 1 + let g:go_jump_to_error = 1 endif " Some handy plug mappings nnoremap (go-run) :call go#cmd#Run(!g:go_jump_to_error) if has("nvim") - nnoremap (go-run-vertical) :call go#cmd#RunTerm(!g:go_jump_to_error, 'vsplit', []) - nnoremap (go-run-split) :call go#cmd#RunTerm(!g:go_jump_to_error, 'split', []) - nnoremap (go-run-tab) :call go#cmd#RunTerm(!g:go_jump_to_error, 'tabe', []) + nnoremap (go-run-vertical) :call go#cmd#RunTerm(!g:go_jump_to_error, 'vsplit', []) + nnoremap (go-run-split) :call go#cmd#RunTerm(!g:go_jump_to_error, 'split', []) + nnoremap (go-run-tab) :call go#cmd#RunTerm(!g:go_jump_to_error, 'tabe', []) endif nnoremap (go-build) :call go#cmd#Build(!g:go_jump_to_error) @@ -70,3 +70,5 @@ nnoremap (go-vet) :call go#lint#Vet(!g:go_jump_to_error) nnoremap (go-alternate-edit) :call go#alternate#Switch(0, "edit") nnoremap (go-alternate-vertical) :call go#alternate#Switch(0, "vsplit") nnoremap (go-alternate-split) :call go#alternate#Switch(0, "split") + +" vim: sw=2 ts=2 et diff --git a/ftplugin/go/snippets.vim b/ftplugin/go/snippets.vim index 3bf13d2c44..56c0811d32 100644 --- a/ftplugin/go/snippets.vim +++ b/ftplugin/go/snippets.vim @@ -5,42 +5,44 @@ let g:go_loaded_gosnippets = 1 " by default UltiSnips if !exists("g:go_snippet_engine") - let g:go_snippet_engine = "ultisnips" + let g:go_snippet_engine = "ultisnips" endif function! s:GoUltiSnips() - if globpath(&rtp, 'plugin/UltiSnips.vim') == "" - return - endif - - if !exists("g:UltiSnipsSnippetDirectories") - let g:UltiSnipsSnippetDirectories = ["gosnippets/UltiSnips"] - else - let g:UltiSnipsSnippetDirectories += ["gosnippets/UltiSnips"] - endif + if globpath(&rtp, 'plugin/UltiSnips.vim') == "" + return + endif + + if !exists("g:UltiSnipsSnippetDirectories") + let g:UltiSnipsSnippetDirectories = ["gosnippets/UltiSnips"] + else + let g:UltiSnipsSnippetDirectories += ["gosnippets/UltiSnips"] + endif endfunction function! s:GoNeosnippet() - if globpath(&rtp, 'plugin/neosnippet.vim') == "" - return - endif - - let g:neosnippet#enable_snipmate_compatibility = 1 - - let gosnippets_dir = globpath(&rtp, 'gosnippets/snippets') - if type(g:neosnippet#snippets_directory) == type([]) - let g:neosnippet#snippets_directory += [gosnippets_dir] - elseif type(g:neosnippet#snippets_directory) == type("") - if strlen(g:neosnippet#snippets_directory) > 0 - let g:neosnippet#snippets_directory = g:neosnippet#snippets_directory . "," . gosnippets_dir - else - let g:neosnippet#snippets_directory = gosnippets_dir - endif - endif + if globpath(&rtp, 'plugin/neosnippet.vim') == "" + return + endif + + let g:neosnippet#enable_snipmate_compatibility = 1 + + let gosnippets_dir = globpath(&rtp, 'gosnippets/snippets') + if type(g:neosnippet#snippets_directory) == type([]) + let g:neosnippet#snippets_directory += [gosnippets_dir] + elseif type(g:neosnippet#snippets_directory) == type("") + if strlen(g:neosnippet#snippets_directory) > 0 + let g:neosnippet#snippets_directory = g:neosnippet#snippets_directory . "," . gosnippets_dir + else + let g:neosnippet#snippets_directory = gosnippets_dir + endif + endif endfunction if g:go_snippet_engine == "ultisnips" - call s:GoUltiSnips() + call s:GoUltiSnips() elseif g:go_snippet_engine == "neosnippet" - call s:GoNeosnippet() + call s:GoNeosnippet() endif + +" vim: sw=2 ts=2 et diff --git a/ftplugin/go/tagbar.vim b/ftplugin/go/tagbar.vim index ca5b184470..e8982aaaff 100644 --- a/ftplugin/go/tagbar.vim +++ b/ftplugin/go/tagbar.vim @@ -4,52 +4,54 @@ " Also make sure the ctags command exists " if !executable('ctags') - finish + finish elseif globpath(&rtp, 'plugin/tagbar.vim') == "" - finish + finish endif if !exists("g:go_gotags_bin") - let g:go_gotags_bin = "gotags" + let g:go_gotags_bin = "gotags" endif function! s:SetTagbar() - let bin_path = go#path#CheckBinPath(g:go_gotags_bin) - if empty(bin_path) - return - endif + let bin_path = go#path#CheckBinPath(g:go_gotags_bin) + if empty(bin_path) + return + endif - if !exists("g:tagbar_type_go") - let g:tagbar_type_go = { - \ 'ctagstype' : 'go', - \ 'kinds' : [ - \ 'p:package', - \ 'i:imports', - \ 'c:constants', - \ 'v:variables', - \ 't:types', - \ 'n:interfaces', - \ 'w:fields', - \ 'e:embedded', - \ 'm:methods', - \ 'r:constructor', - \ 'f:functions' - \ ], - \ 'sro' : '.', - \ 'kind2scope' : { - \ 't' : 'ctype', - \ 'n' : 'ntype' - \ }, - \ 'scope2kind' : { - \ 'ctype' : 't', - \ 'ntype' : 'n' - \ }, - \ 'ctagsbin' : expand(bin_path), - \ 'ctagsargs' : '-sort -silent' - \ } - endif + if !exists("g:tagbar_type_go") + let g:tagbar_type_go = { + \ 'ctagstype' : 'go', + \ 'kinds' : [ + \ 'p:package', + \ 'i:imports', + \ 'c:constants', + \ 'v:variables', + \ 't:types', + \ 'n:interfaces', + \ 'w:fields', + \ 'e:embedded', + \ 'm:methods', + \ 'r:constructor', + \ 'f:functions' + \ ], + \ 'sro' : '.', + \ 'kind2scope' : { + \ 't' : 'ctype', + \ 'n' : 'ntype' + \ }, + \ 'scope2kind' : { + \ 'ctype' : 't', + \ 'ntype' : 'n' + \ }, + \ 'ctagsbin' : expand(bin_path), + \ 'ctagsargs' : '-sort -silent' + \ } + endif endfunction call s:SetTagbar() + +" vim: sw=2 ts=2 et diff --git a/ftplugin/gohtmltmpl.vim b/ftplugin/gohtmltmpl.vim index 56d414ff55..132e3fa53f 100644 --- a/ftplugin/gohtmltmpl.vim +++ b/ftplugin/gohtmltmpl.vim @@ -1,6 +1,8 @@ if exists("b:did_ftplugin") - finish + finish endif let b:did_ftplugin = 1 setlocal commentstring= + +" vim: sw=2 ts=2 et diff --git a/indent/go.vim b/indent/go.vim index a3fa2b7a67..ba99d54dd5 100644 --- a/indent/go.vim +++ b/indent/go.vim @@ -9,7 +9,7 @@ " - general line splits (line ends in an operator) if exists("b:did_indent") - finish + finish endif let b:did_indent = 1 @@ -21,58 +21,58 @@ setlocal indentexpr=GoIndent(v:lnum) setlocal indentkeys+=<:>,0=},0=) if exists("*GoIndent") - finish + finish endif " use shiftwidth function only if it's available if exists('*shiftwidth') - func s:sw() - return shiftwidth() - endfunc + func s:sw() + return shiftwidth() + endfunc else - func s:sw() - return &sw - endfunc + func s:sw() + return &sw + endfunc endif function! GoIndent(lnum) - let prevlnum = prevnonblank(a:lnum-1) - if prevlnum == 0 - " top of file - return 0 - endif + let prevlnum = prevnonblank(a:lnum-1) + if prevlnum == 0 + " top of file + return 0 + endif - " grab the previous and current line, stripping comments. - let prevl = substitute(getline(prevlnum), '//.*$', '', '') - let thisl = substitute(getline(a:lnum), '//.*$', '', '') - let previ = indent(prevlnum) + " grab the previous and current line, stripping comments. + let prevl = substitute(getline(prevlnum), '//.*$', '', '') + let thisl = substitute(getline(a:lnum), '//.*$', '', '') + let previ = indent(prevlnum) - let ind = previ + let ind = previ - if prevl =~ '[({]\s*$' - " previous line opened a block - let ind += s:sw() - endif - if prevl =~# '^\s*\(case .*\|default\):$' - " previous line is part of a switch statement - let ind += s:sw() - endif - " TODO: handle if the previous line is a label. + if prevl =~ '[({]\s*$' + " previous line opened a block + let ind += s:sw() + endif + if prevl =~# '^\s*\(case .*\|default\):$' + " previous line is part of a switch statement + let ind += s:sw() + endif + " TODO: handle if the previous line is a label. - if thisl =~ '^\s*[)}]' - " this line closed a block - let ind -= s:sw() - endif + if thisl =~ '^\s*[)}]' + " this line closed a block + let ind -= s:sw() + endif - " Colons are tricky. - " We want to outdent if it's part of a switch ("case foo:" or "default:"). - " We ignore trying to deal with jump labels because (a) they're rare, and - " (b) they're hard to disambiguate from a composite literal key. - if thisl =~# '^\s*\(case .*\|default\):$' - let ind -= s:sw() - endif + " Colons are tricky. + " We want to outdent if it's part of a switch ("case foo:" or "default:"). + " We ignore trying to deal with jump labels because (a) they're rare, and + " (b) they're hard to disambiguate from a composite literal key. + if thisl =~# '^\s*\(case .*\|default\):$' + let ind -= s:sw() + endif - return ind + return ind endfunction -" vim:ts=4:sw=4:et +" vim: sw=2 ts=2 et diff --git a/indent/gohtmltmpl.vim b/indent/gohtmltmpl.vim index 94ea135a44..d95cbc2463 100644 --- a/indent/gohtmltmpl.vim +++ b/indent/gohtmltmpl.vim @@ -42,3 +42,5 @@ function! GetGoHTMLTmplIndent(lnum) return ind endfunction + +" vim: sw=2 ts=2 et diff --git a/plugin/go.vim b/plugin/go.vim index 779f4e1b92..f0d6c8d3c8 100644 --- a/plugin/go.vim +++ b/plugin/go.vim @@ -1,26 +1,26 @@ " install necessary Go tools if exists("g:go_loaded_install") - finish + finish endif let g:go_loaded_install = 1 " these packages are used by vim-go and can be automatically installed if " needed by the user with GoInstallBinaries let s:packages = [ - \ "github.com/nsf/gocode", - \ "github.com/alecthomas/gometalinter", - \ "golang.org/x/tools/cmd/goimports", - \ "golang.org/x/tools/cmd/guru", - \ "golang.org/x/tools/cmd/gorename", - \ "github.com/golang/lint/golint", - \ "github.com/rogpeppe/godef", - \ "github.com/kisielk/errcheck", - \ "github.com/jstemmer/gotags", - \ "github.com/klauspost/asmfmt/cmd/asmfmt", - \ "github.com/fatih/motion", - \ "github.com/zmb3/gogetdoc", - \ "github.com/josharian/impl", - \ ] + \ "github.com/nsf/gocode", + \ "github.com/alecthomas/gometalinter", + \ "golang.org/x/tools/cmd/goimports", + \ "golang.org/x/tools/cmd/guru", + \ "golang.org/x/tools/cmd/gorename", + \ "github.com/golang/lint/golint", + \ "github.com/rogpeppe/godef", + \ "github.com/kisielk/errcheck", + \ "github.com/jstemmer/gotags", + \ "github.com/klauspost/asmfmt/cmd/asmfmt", + \ "github.com/fatih/motion", + \ "github.com/zmb3/gogetdoc", + \ "github.com/josharian/impl", + \ ] " These commands are available on any filetypes command! GoInstallBinaries call s:GoInstallBinaries(-1) @@ -33,145 +33,144 @@ command! -nargs=? -complete=dir GoPath call go#path#GoPath() " target install directory. GoInstallBinaries doesn't install binaries if they " exist, to update current binaries pass 1 to the argument. function! s:GoInstallBinaries(updateBinaries) - if $GOPATH == "" - echohl Error - echomsg "vim.go: $GOPATH is not set" - echohl None - return - endif - - let err = s:CheckBinaries() - if err != 0 - return - endif - - let go_bin_path = go#path#BinPath() - - " change $GOBIN so go get can automatically install to it - let $GOBIN = go_bin_path - - " old_path is used to restore users own path - let old_path = $PATH - - " vim's executable path is looking in PATH so add our go_bin path to it - let $PATH = go_bin_path . go#util#PathListSep() . $PATH - - " when shellslash is set on MS-* systems, shellescape puts single quotes - " around the output string. cmd on Windows does not handle single quotes - " correctly. Unsetting shellslash forces shellescape to use double quotes - " instead. - let resetshellslash = 0 - if has('win32') && &shellslash - let resetshellslash = 1 - set noshellslash - endif - - let cmd = "go get -v " - if get(g:, "go_get_update", 1) != 0 - let cmd .= "-u " - endif - - let s:go_version = matchstr(go#util#System("go version"), '\d.\d.\d') - - " https://github.com/golang/go/issues/10791 - if s:go_version > "1.4.0" && s:go_version < "1.5.0" - let cmd .= "-f " - endif - - for pkg in s:packages - let basename = fnamemodify(pkg, ":t") - let binname = "go_" . basename . "_bin" - - let bin = basename - if exists("g:{binname}") - let bin = g:{binname} - endif - - if !executable(bin) || a:updateBinaries == 1 - if a:updateBinaries == 1 - echo "vim-go: Updating ". basename .". Reinstalling ". pkg . " to folder " . go_bin_path - else - echo "vim-go: ". basename ." not found. Installing ". pkg . " to folder " . go_bin_path - endif - - - let out = go#util#System(cmd . shellescape(pkg)) - if go#util#ShellError() != 0 - echo "Error installing ". pkg . ": " . out - endif - endif - endfor - - " restore back! - let $PATH = old_path - if resetshellslash - set shellslash - endif + if $GOPATH == "" + echohl Error + echomsg "vim.go: $GOPATH is not set" + echohl None + return + endif + + let err = s:CheckBinaries() + if err != 0 + return + endif + + let go_bin_path = go#path#BinPath() + + " change $GOBIN so go get can automatically install to it + let $GOBIN = go_bin_path + + " old_path is used to restore users own path + let old_path = $PATH + + " vim's executable path is looking in PATH so add our go_bin path to it + let $PATH = go_bin_path . go#util#PathListSep() . $PATH + + " when shellslash is set on MS-* systems, shellescape puts single quotes + " around the output string. cmd on Windows does not handle single quotes + " correctly. Unsetting shellslash forces shellescape to use double quotes + " instead. + let resetshellslash = 0 + if has('win32') && &shellslash + let resetshellslash = 1 + set noshellslash + endif + + let cmd = "go get -v " + if get(g:, "go_get_update", 1) != 0 + let cmd .= "-u " + endif + + let s:go_version = matchstr(go#util#System("go version"), '\d.\d.\d') + + " https://github.com/golang/go/issues/10791 + if s:go_version > "1.4.0" && s:go_version < "1.5.0" + let cmd .= "-f " + endif + + for pkg in s:packages + let basename = fnamemodify(pkg, ":t") + let binname = "go_" . basename . "_bin" + + let bin = basename + if exists("g:{binname}") + let bin = g:{binname} + endif + + if !executable(bin) || a:updateBinaries == 1 + if a:updateBinaries == 1 + echo "vim-go: Updating ". basename .". Reinstalling ". pkg . " to folder " . go_bin_path + else + echo "vim-go: ". basename ." not found. Installing ". pkg . " to folder " . go_bin_path + endif + + + let out = go#util#System(cmd . shellescape(pkg)) + if go#util#ShellError() != 0 + echo "Error installing ". pkg . ": " . out + endif + endif + endfor + + " restore back! + let $PATH = old_path + if resetshellslash + set shellslash + endif endfunction " CheckBinaries checks if the necessary binaries to install the Go tool " commands are available. function! s:CheckBinaries() - if !executable('go') - echohl Error | echomsg "vim-go: go executable not found." | echohl None - return -1 - endif - - if !executable('git') - echohl Error | echomsg "vim-go: git executable not found." | echohl None - return -1 - endif + if !executable('go') + echohl Error | echomsg "vim-go: go executable not found." | echohl None + return -1 + endif + + if !executable('git') + echohl Error | echomsg "vim-go: git executable not found." | echohl None + return -1 + endif endfunction " Autocommands " ============================================================================ " function! s:echo_go_info() - if !exists('v:completed_item') || empty(v:completed_item) - return - endif - let item = v:completed_item + if !exists('v:completed_item') || empty(v:completed_item) + return + endif + let item = v:completed_item - if !has_key(item, "info") - return - endif + if !has_key(item, "info") + return + endif - if empty(item.info) - return - endif + if empty(item.info) + return + endif - redraws! | echo "vim-go: " | echohl Function | echon item.info | echohl None + redraws! | echo "vim-go: " | echohl Function | echon item.info | echohl None endfunction augroup vim-go - autocmd! - - " GoInfo automatic update - if get(g:, "go_auto_type_info", 0) - autocmd CursorHold *.go nested call go#complete#Info(1) - endif - - " Echo the identifier information when completion is done. Useful to see - " the signature of a function, etc... - if exists('##CompleteDone') - autocmd CompleteDone *.go nested call s:echo_go_info() - endif - - " Go code formatting on save - if get(g:, "go_fmt_autosave", 1) - autocmd BufWritePre *.go call go#fmt#Format(-1) - endif - - " Go asm formatting on save - if get(g:, "go_asmfmt_autosave", 1) - autocmd BufWritePre *.s call go#asmfmt#Format() - endif - - " run gometalinter on save - if get(g:, "go_metalinter_autosave", 0) - autocmd BufWritePost *.go call go#lint#Gometa(1) - endif + autocmd! + + " GoInfo automatic update + if get(g:, "go_auto_type_info", 0) + autocmd CursorHold *.go nested call go#complete#Info(1) + endif + + " Echo the identifier information when completion is done. Useful to see + " the signature of a function, etc... + if exists('##CompleteDone') + autocmd CompleteDone *.go nested call s:echo_go_info() + endif + + " Go code formatting on save + if get(g:, "go_fmt_autosave", 1) + autocmd BufWritePre *.go call go#fmt#Format(-1) + endif + + " Go asm formatting on save + if get(g:, "go_asmfmt_autosave", 1) + autocmd BufWritePre *.s call go#asmfmt#Format() + endif + + " run gometalinter on save + if get(g:, "go_metalinter_autosave", 0) + autocmd BufWritePost *.go call go#lint#Gometa(1) + endif augroup END - -" vim:ts=4:sw=4:et +" vim: sw=2 ts=2 et diff --git a/syntax/go.vim b/syntax/go.vim index f9cd2cba0f..f3e73c5cee 100644 --- a/syntax/go.vim +++ b/syntax/go.vim @@ -68,7 +68,7 @@ if !exists("g:go_highlight_methods") endif if !exists("g:go_highlight_fields") - let g:go_highlight_fields = 0 + let g:go_highlight_fields = 0 endif if !exists("g:go_highlight_structs") @@ -336,35 +336,35 @@ hi def link goInterfaceDef Function " Build Constraints if g:go_highlight_build_constraints != 0 - syn match goBuildKeyword display contained "+build" - " Highlight the known values of GOOS, GOARCH, and other +build options. - syn keyword goBuildDirectives contained - \ android darwin dragonfly freebsd linux nacl netbsd openbsd plan9 - \ solaris windows 386 amd64 amd64p32 arm armbe arm64 arm64be ppc64 - \ ppc64le mips mipsle mips64 mips64le mips64p32 mips64p32le ppc - \ s390 s390x sparc sparc64 cgo ignore race - - " Other words in the build directive are build tags not listed above, so - " avoid highlighting them as comments by using a matchgroup just for the - " start of the comment. - " The rs=s+2 option lets the \s*+build portion be part of the inner region - " instead of the matchgroup so it will be highlighted as a goBuildKeyword. - syn region goBuildComment matchgroup=goBuildCommentStart - \ start="//\s*+build\s"rs=s+2 end="$" - \ contains=goBuildKeyword,goBuildDirectives - hi def link goBuildCommentStart Comment - hi def link goBuildDirectives Type - hi def link goBuildKeyword PreProc - - " One or more line comments that are followed immediately by a "package" - " declaration are treated like package documentation, so these must be - " matched as comments to avoid looking like working build constraints. - " The he, me, and re options let the "package" itself be highlighted by - " the usual rules. - syn region goPackageComment start=/\v(\/\/.*\n)+\s*package/ - \ end=/\v\n\s*package/he=e-7,me=e-7,re=e-7 - \ contains=@goCommentGroup,@Spell - hi def link goPackageComment Comment + syn match goBuildKeyword display contained "+build" + " Highlight the known values of GOOS, GOARCH, and other +build options. + syn keyword goBuildDirectives contained + \ android darwin dragonfly freebsd linux nacl netbsd openbsd plan9 + \ solaris windows 386 amd64 amd64p32 arm armbe arm64 arm64be ppc64 + \ ppc64le mips mipsle mips64 mips64le mips64p32 mips64p32le ppc + \ s390 s390x sparc sparc64 cgo ignore race + + " Other words in the build directive are build tags not listed above, so + " avoid highlighting them as comments by using a matchgroup just for the + " start of the comment. + " The rs=s+2 option lets the \s*+build portion be part of the inner region + " instead of the matchgroup so it will be highlighted as a goBuildKeyword. + syn region goBuildComment matchgroup=goBuildCommentStart + \ start="//\s*+build\s"rs=s+2 end="$" + \ contains=goBuildKeyword,goBuildDirectives + hi def link goBuildCommentStart Comment + hi def link goBuildDirectives Type + hi def link goBuildKeyword PreProc + + " One or more line comments that are followed immediately by a "package" + " declaration are treated like package documentation, so these must be + " matched as comments to avoid looking like working build constraints. + " The he, me, and re options let the "package" itself be highlighted by + " the usual rules. + syn region goPackageComment start=/\v(\/\/.*\n)+\s*package/ + \ end=/\v\n\s*package/he=e-7,me=e-7,re=e-7 + \ contains=@goCommentGroup,@Spell + hi def link goPackageComment Comment endif @@ -376,3 +376,5 @@ endif syn sync minlines=500 let b:current_syntax = "go" + +" vim: sw=2 ts=2 et diff --git a/syntax/godefstack.vim b/syntax/godefstack.vim index 7574c21df2..e4eefff4a4 100644 --- a/syntax/godefstack.vim +++ b/syntax/godefstack.vim @@ -1,5 +1,5 @@ if exists("b:current_syntax") - finish + finish endif syn match godefStackComment '^".*' @@ -16,3 +16,5 @@ hi def link godefStackComment Comment hi def link godefStackCurrentPosition Special hi def link godefStackFilename Directory hi def link godefStackEntryLocationNumber LineNr + +" vim: sw=2 ts=2 et diff --git a/syntax/gohtmltmpl.vim b/syntax/gohtmltmpl.vim index 5aa6c98d72..f53fbc67f2 100644 --- a/syntax/gohtmltmpl.vim +++ b/syntax/gohtmltmpl.vim @@ -1,9 +1,9 @@ if exists("b:current_syntax") - finish + finish endif if !exists("main_syntax") - let main_syntax = 'html' + let main_syntax = 'html' endif runtime! syntax/gotexttmpl.vim @@ -12,4 +12,4 @@ unlet b:current_syntax let b:current_syntax = "gohtmltmpl" -" vim:ts=4:sw=4:et +" vim: sw=2 ts=2 et diff --git a/syntax/gotexttmpl.vim b/syntax/gotexttmpl.vim index f8f4e6829e..de21d7fca5 100644 --- a/syntax/gotexttmpl.vim +++ b/syntax/gotexttmpl.vim @@ -6,7 +6,7 @@ " Quit when a (custom) syntax file was already loaded if exists("b:current_syntax") - finish + finish endif syn case match @@ -82,4 +82,4 @@ hi def link goTplComment Comment let b:current_syntax = "gotexttmpl" -" vim:ts=4:sw=4:et +" vim: sw=2 ts=2 et diff --git a/syntax/vimgo.vim b/syntax/vimgo.vim index d62791d3c2..3a2204c414 100644 --- a/syntax/vimgo.vim +++ b/syntax/vimgo.vim @@ -1,5 +1,5 @@ if exists("b:current_syntax") - finish + finish endif let b:current_syntax = "vimgo" @@ -9,3 +9,5 @@ syn region goTitle start="\%1l" end=":" hi def link goInterface Type hi def link goTitle Label + +" vim: sw=2 ts=2 et