1
0
mirror of https://github.com/amix/vimrc synced 2025-06-16 09:35:01 +08:00

Updated vimrc

This commit is contained in:
amix
2015-07-13 11:22:46 +01:00
parent 9a2843c2a5
commit d7752b59ae
301 changed files with 4699 additions and 7969 deletions

View File

@ -1,11 +1,63 @@
if !exists("g:go_jump_to_error")
let g:go_jump_to_error = 1
if !exists("g:go_dispatch_enabled")
let g:go_dispatch_enabled = 0
endif
function! go#cmd#autowrite()
if &autowrite == 1
silent wall
endif
endfunction
" Build buils the source code without producting any output binary. We live in
" an editor so the best is to build it to catch errors and fix them. By
" 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, ...)
let default_makeprg = &makeprg
let gofiles = join(go#tool#Files(), '" "')
let old_gopath = $GOPATH
let $GOPATH = go#path#Detect()
if v:shell_error
let &makeprg = "go build . errors"
else
let &makeprg = "go build -o /dev/null " . join(a:000, ' ') . ' "' . gofiles . '"'
endif
echon "vim-go: " | echohl Identifier | echon "building ..."| echohl None
if g:go_dispatch_enabled && exists(':Make') == 2
silent! exe 'Make'
else
silent! exe 'make!'
endif
redraw!
cwindow
let errors = getqflist()
if !empty(errors)
if !a:bang
cc 1 "jump to first error if there is any
endif
else
redraws! | echon "vim-go: " | echohl Function | echon "[build] SUCCESS"| echohl None
endif
let &makeprg = default_makeprg
let $GOPATH = old_gopath
endfunction
" Run runs the current file (and their dependencies if any) and outputs it.
" This is intented to test small programs and play with them. It's not
" 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, ...)
let goFiles = '"' . join(go#tool#Files(), '" "') . '"'
if IsWin()
let old_gopath = $GOPATH
let $GOPATH = go#path#Detect()
if go#util#IsWin()
exec '!go run ' . goFiles
if v:shell_error
redraws! | echon "vim-go: [run] " | echohl ErrorMsg | echon "FAILED"| echohl None
@ -13,6 +65,7 @@ function! go#cmd#Run(bang, ...)
redraws! | echon "vim-go: [run] " | echohl Function | echon "SUCCESS"| echohl None
endif
let $GOPATH = old_gopath
return
endif
@ -23,65 +76,47 @@ function! go#cmd#Run(bang, ...)
let &makeprg = "go run " . expand(a:1)
endif
exe 'make!'
if !a:bang
cwindow
let errors = getqflist()
if !empty(errors)
if g:go_jump_to_error
cc 1 "jump to first error if there is any
endif
endif
if g:go_dispatch_enabled && exists(':Make') == 2
silent! exe 'Make!'
else
exe 'make!'
endif
cwindow
let errors = getqflist()
if !empty(errors) && !a:bang
cc 1 "jump to first error if there is any
endif
let $GOPATH = old_gopath
let &makeprg = default_makeprg
endfunction
function! go#cmd#Install(...)
" Install installs the package by simple calling 'go install'. If any argument
" is given(which are passed directly to 'go insta'') it tries to install those
" packages. Errors are populated in the quickfix window.
function! go#cmd#Install(bang, ...)
let pkgs = join(a:000, '" "')
let command = 'go install "' . pkgs . '"'
call go#cmd#autowrite()
let out = go#tool#ExecuteInDir(command)
if v:shell_error
call go#tool#ShowErrors(out)
cwindow
let errors = getqflist()
if !empty(errors) && !a:bang
cc 1 "jump to first error if there is any
endif
return
endif
if exists("$GOBIN")
echon "vim-go: " | echohl Function | echon "installed to ". $GOBIN | echohl None
else
echon "vim-go: " | echohl Function | echon "installed to ". $GOPATH . "/bin" | echohl None
endif
echon "vim-go: " | echohl Function | echon "installed to ". $GOPATH | echohl None
endfunction
function! go#cmd#Build(bang, ...)
let default_makeprg = &makeprg
let gofiles = join(go#tool#Files(), '" "')
if v:shell_error
let &makeprg = "go build . errors"
else
let &makeprg = "go build -o /dev/null " . join(a:000, ' ') . ' "' . gofiles . '"'
endif
echon "vim-go: " | echohl Identifier | echon "building ..."| echohl None
silent! exe 'make!'
redraw!
if !a:bang
cwindow
let errors = getqflist()
if !empty(errors)
if g:go_jump_to_error
cc 1 "jump to first error if there is any
endif
else
redraws! | echon "vim-go: " | echohl Function | echon "[build] SUCCESS"| echohl None
endif
endif
let &makeprg = default_makeprg
endfunction
function! go#cmd#Test(compile, ...)
" 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 command = "go test "
" don't run the test, only compile it. Useful to capture and fix errors or
@ -94,6 +129,11 @@ function! go#cmd#Test(compile, ...)
let command .= expand(a:1)
endif
if len(a:000) == 2
let command .= a:2
endif
call go#cmd#autowrite()
if a:compile
echon "vim-go: " | echohl Identifier | echon "compiling tests ..." | echohl None
else
@ -106,10 +146,8 @@ function! go#cmd#Test(compile, ...)
call go#tool#ShowErrors(out)
cwindow
let errors = getqflist()
if !empty(errors)
if g:go_jump_to_error
cc 1 "jump to first error if there is any
endif
if !empty(errors) && !a:bang
cc 1 "jump to first error if there is any
endif
echon "vim-go: " | echohl ErrorMsg | echon "[test] FAIL" | echohl None
else
@ -124,11 +162,47 @@ function! go#cmd#Test(compile, ...)
endif
endfunction
function! go#cmd#Coverage(...)
" 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", "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 flag = "-run \"" . name . "$\""
let a1 = ""
if len(a:000)
let a1 = a:1
" add extra space
let flag = " " . flag
endif
call go#cmd#Test(a:bang, 0, a1, flag)
endfunction
" Coverage creates a new cover profile with 'go test -coverprofile' and opens
" a new HTML coverage page from that profile.
function! go#cmd#Coverage(bang, ...)
let l:tmpname=tempname()
let command = "go test -coverprofile=".l:tmpname
call go#cmd#autowrite()
let out = go#tool#ExecuteInDir(command)
if v:shell_error
call go#tool#ShowErrors(out)
@ -140,18 +214,17 @@ function! go#cmd#Coverage(...)
call go#tool#ExecuteInDir(openHTML)
endif
cwindow
let errors = getqflist()
if !empty(errors)
if g:go_jump_to_error
cc 1 "jump to first error if there is any
endif
if !empty(errors) && !a:bang
cc 1 "jump to first error if there is any
endif
call delete(l:tmpname)
endfunction
function! go#cmd#Vet()
" Vet calls "go vet' on the current directory. Any warnings are populated in
" the quickfix window
function! go#cmd#Vet(bang)
call go#cmd#autowrite()
echon "vim-go: " | echohl Identifier | echon "calling vet..." | echohl None
let out = go#tool#ExecuteInDir('go vet')
if v:shell_error
@ -159,17 +232,52 @@ function! go#cmd#Vet()
else
call setqflist([])
endif
cwindow
let errors = getqflist()
if !empty(errors)
if g:go_jump_to_error
if !empty(errors)
if !a:bang
cc 1 "jump to first error if there is any
endif
else
redraw | echon "vim-go: " | echohl Function | echon "[vet] PASS" | echohl None
endif
endfunction
"
" Generate runs 'go generate' in similar fashion to go#cmd#Build()
function! go#cmd#Generate(bang, ...)
let default_makeprg = &makeprg
let gofiles = join(go#tool#Files(), '" "')
let old_gopath = $GOPATH
let $GOPATH = go#path#Detect()
if v:shell_error
let &makeprg = "go generate " . join(a:000, ' ')
else
let &makeprg = "go generate " . join(a:000, ' ') . ' "' . gofiles . '"'
endif
echon "vim-go: " | echohl Identifier | echon "generating ..."| echohl None
if g:go_dispatch_enabled && exists(':Make') == 2
silent! exe 'Make'
else
silent! exe 'make!'
endif
redraw!
cwindow
let errors = getqflist()
if !empty(errors)
if !a:bang
cc 1 "jump to first error if there is any
endif
else
redraws! | echon "vim-go: " | echohl Function | echon "[generate] SUCCESS"| echohl None
endif
let &makeprg = default_makeprg
let $GOPATH = old_gopath
endfunction
" vim:ts=4:sw=4:et
"

View File

@ -31,6 +31,9 @@ fu! s:system(str, ...)
endf
fu! s:gocodeShellescape(arg)
if go#vimproc#has_vimproc()
return vimproc#shellescape(a:arg)
endif
try
let ssl_save = &shellslash
set noshellslash
@ -48,12 +51,20 @@ fu! s:gocodeCommand(cmd, preargs, args)
let a:preargs[i] = s:gocodeShellescape(a:preargs[i])
endfor
let bin_path = go#tool#BinPath(g:go_gocode_bin)
let bin_path = go#path#CheckBinPath(g:go_gocode_bin)
if empty(bin_path)
return
endif
let result = s:system(printf('%s %s %s %s', bin_path, join(a:preargs), a:cmd, join(a:args)))
" 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 = s:system(printf('%s %s %s %s', s:gocodeShellescape(bin_path), join(a:preargs), s:gocodeShellescape(a:cmd), join(a:args)))
let $GOPATH = old_gopath
if v:shell_error != 0
return "[\"0\", []]"
else

View File

@ -13,35 +13,43 @@ function! go#def#Jump(...)
let arg = a:1
endif
let bin_path = go#tool#BinPath(g:go_godef_bin)
let bin_path = go#path#CheckBinPath(g:go_godef_bin)
if empty(bin_path)
return
endif
let command = bin_path . " -f=" . expand("%:p") . " -i " . shellescape(arg)
let old_gopath = $GOPATH
let $GOPATH = go#path#Detect()
let command = bin_path . " -f=" . shellescape(expand("%:p")) . " -i " . shellescape(arg)
" get output of godef
let out=system(command, join(getbufline(bufnr('%'), 1, '$'), LineEnding()))
let out=system(command, join(getbufline(bufnr('%'), 1, '$'), go#util#LineEnding()))
" jump to it
call s:godefJump(out, "")
let $GOPATH = old_gopath
endfunction
function! go#def#JumpMode(mode)
let arg = s:getOffset()
let bin_path = go#tool#BinPath(g:go_godef_bin)
let bin_path = go#path#CheckBinPath(g:go_godef_bin)
if empty(bin_path)
return
endif
let command = bin_path . " -f=" . expand("%:p") . " -i " . shellescape(arg)
let old_gopath = $GOPATH
let $GOPATH = go#path#Detect()
let command = bin_path . " -f=" . shellescape(expand("%:p")) . " -i " . shellescape(arg)
" get output of godef
let out=system(command, join(getbufline(bufnr('%'), 1, '$'), LineEnding()))
let out=system(command, join(getbufline(bufnr('%'), 1, '$'), go#util#LineEnding()))
call s:godefJump(out, a:mode)
let $GOPATH = old_gopath
endfunction
@ -51,7 +59,7 @@ function! s:getOffset()
let offs = line2byte(pos[0]) + pos[1] - 2
else
let c = pos[1]
let buf = line('.') == 1 ? "" : (join(getline(1, pos[0] - 1), LineEnding()) . LineEnding())
let buf = line('.') == 1 ? "" : (join(getline(1, pos[0] - 1), go#util#LineEnding()) . go#util#LineEnding())
let buf .= c == 1 ? "" : getline(pos[0])[:c-2]
let offs = len(iconv(buf, &encoding, "utf-8"))
endif
@ -66,7 +74,7 @@ function! s:godefJump(out, mode)
let &errorformat = "%f:%l:%c"
if a:out =~ 'godef: '
let out=substitute(a:out, LineEnding() . '$', '', '')
let out=substitute(a:out, go#util#LineEnding() . '$', '', '')
echom out
else
let parts = split(a:out, ':')

View File

@ -71,6 +71,14 @@ function! s:godocWord(args)
return [pkg, exported_name]
endfunction
function! s:godocNotFound(content)
if len(a:content) == 0
return 1
endif
return a:content =~# '^.*: no such file or directory\n$'
endfunction
function! go#doc#OpenBrowser(...)
let pkgs = s:godocWord(a:000)
if empty(pkgs)
@ -97,7 +105,7 @@ function! go#doc#Open(newmode, mode, ...)
let command = g:go_doc_command . ' ' . g:go_doc_options . ' ' . pkg
silent! let content = system(command)
if v:shell_error || !len(content)
if v:shell_error || s:godocNotFound(content)
echo 'No documentation found for "' . pkg . '".'
return -1
endif

View File

@ -13,7 +13,7 @@ function! go#errcheck#Run(...) abort
let package = a:1
end
let bin_path = go#tool#BinPath(g:go_errcheck_bin)
let bin_path = go#path#CheckBinPath(g:go_errcheck_bin)
if empty(bin_path)
return
endif
@ -27,7 +27,7 @@ function! go#errcheck#Run(...) abort
let tokens = matchlist(line, mx)
if !empty(tokens)
call add(errors, {"filename": expand(DefaultGoPath() . "/src/" . tokens[1]),
call add(errors, {"filename": expand(go#path#Default() . "/src/" . tokens[1]),
\"lnum": tokens[2],
\"col": tokens[3],
\"text": tokens[4]})
@ -44,6 +44,7 @@ function! go#errcheck#Run(...) abort
call setqflist(errors, 'r')
endif
else
redraw | echo
call setqflist([])
endif

View File

@ -79,14 +79,18 @@ function! go#fmt#Format(withGoimport)
" if it's something else than gofmt, we need to check the existing of that
" binary. For example if it's goimports, let us check if it's installed,
" if not the user get's a warning via go#tool#BinPath()
" if not the user get's a warning via go#path#CheckBinPath()
if fmt_command != "gofmt"
" check if the user has installed goimports
let bin_path = go#tool#BinPath(fmt_command)
let bin_path = go#path#CheckBinPath(fmt_command)
if empty(bin_path)
return
endif
" change GOPATH too, so goimports can pick up the correct library
let old_gopath = $GOPATH
let $GOPATH = go#path#Detect()
let fmt_command = bin_path
endif
@ -95,8 +99,16 @@ function! go#fmt#Format(withGoimport)
" execute our command...
let out = system(command . " " . l:tmpname)
let splitted = split(out, '\n')
"if there is no error on the temp file, gofmt again our original file
if fmt_command != "gofmt"
let $GOPATH = old_gopath
endif
"if there is no error on the temp file replace the output with the current
"file (if this fails, we can always check the outputs first line with:
"splitted =~ 'package \w\+')
if v:shell_error == 0
" remove undo point caused via BufWritePre
try | silent undojoin | catch | endtry
@ -106,8 +118,16 @@ function! go#fmt#Format(withGoimport)
let default_srr = &srr
set srr=>%s
" execufe gofmt on the current buffer and replace it
silent execute "%!" . command
" delete any leftover before we replace the whole file. Suppose the
" file had 20 lines, but new output has 10 lines, only 1-10 are
" replaced with setline, remaining lines 11-20 won't get touched. So
" remove them.
if line('$') > len(splitted)
execute len(splitted) .',$delete'
endif
" setline iterates over the list and replaces each line
call setline(1, splitted)
" only clear quickfix if it was previously set, this prevents closing
" other quickfixes
@ -122,7 +142,7 @@ function! go#fmt#Format(withGoimport)
elseif g:go_fmt_fail_silently == 0
"otherwise get the errors and put them to quickfix window
let errors = []
for line in split(out, '\n')
for line in splitted
let tokens = matchlist(line, '^\(.\{-}\):\(\d\+\):\(\d\+\)\s*\(.*\)')
if !empty(tokens)
call add(errors, {"filename": @%,

View File

@ -50,6 +50,12 @@ function! go#import#SwitchImport(enabled, localname, path)
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

View File

@ -17,7 +17,7 @@ if !exists("g:go_golint_bin")
endif
function! go#lint#Run() abort
let bin_path = go#tool#BinPath(g:go_golint_bin)
let bin_path = go#path#CheckBinPath(g:go_golint_bin)
if empty(bin_path)
return
endif

View File

@ -1,4 +1,3 @@
" -*- text -*-
" oracle.vim -- Vim integration for the Go oracle.
"
" Part of this plugin was taken directly from the oracle repo, however it's
@ -46,7 +45,7 @@ endfun
" via regex.
func! s:qflistSecond(output)
" backup users errorformat, will be restored once we are finished
let old_errorformat = &errorformat
let old_errorformat = &errorformat
" match two possible styles of errorformats:
"
@ -56,13 +55,13 @@ func! s:qflistSecond(output)
" We discard line2 and col2 for the first errorformat, because it's not
" useful and quickfix only has the ability to show one line and column
" number
let &errorformat = "%f:%l.%c-%[%^:]%#:\ %m,%f:%l:%c:\ %m"
let &errorformat = "%f:%l.%c-%[%^:]%#:\ %m,%f:%l:%c:\ %m"
" create the quickfix list and open it
cgetexpr split(a:output, "\n")
cwindow
let &errorformat = old_errorformat
let &errorformat = old_errorformat
endfun
func! s:getpos(l, c)
@ -85,7 +84,7 @@ func! s:RunOracle(mode, selected) range abort
let unescaped_scopes = split(get(g:, 'go_oracle_scope'))
let scopes = []
for unescaped_scope in unescaped_scopes
call add(scopes, shellescape(unescaped_scope))
call add(scopes, shellescape(unescaped_scope))
endfor
elseif exists('g:go_oracle_include_tests') && pkg != -1
" give import path so it includes all _test.go files too
@ -97,7 +96,7 @@ func! s:RunOracle(mode, selected) range abort
endif
"return with a warning if the bin doesn't exist
let bin_path = go#tool#BinPath(g:go_oracle_bin)
let bin_path = go#path#CheckBinPath(g:go_oracle_bin)
if empty(bin_path)
return
endif
@ -120,23 +119,48 @@ func! s:RunOracle(mode, selected) range abort
" info check Oracle's User Manual section about scopes:
" https://docs.google.com/document/d/1SLk36YRjjMgKqe490mSRzOPYEDe0Y_WQNRv-EiFYUyw/view#heading=h.nwso96pj07q8
for scope in scopes
let cmd .= ' ' . scope
let cmd .= ' ' . scope
endfor
echon "vim-go: " | echohl Identifier | echon "analysing ..." | echohl None
let old_gopath = $GOPATH
let $GOPATH = go#path#Detect()
let out = system(cmd)
let $GOPATH = old_gopath
if v:shell_error
" unfortunaly oracle outputs a very long stack trace that is not
" parsable to show the real error. But the main issue is usually the
" package which doesn't build.
redraw | echon "vim-go: " | echohl Statement | echon out | echohl None
return ""
else
endif
return out
endfun
endfunc
function! go#oracle#Scope(...)
if len(a:000)
if len(a:000) == 1 && a:1 == '""'
let g:go_oracle_scope = ""
echon "vim-go: " | echohl Function | echon "oracle scope is cleared"| echohl None
else
let g:go_oracle_scope = join(a:000, ' ')
echon "vim-go: " | echohl Function | echon "oracle scope changed to: '". g:go_oracle_scope ."'" | echohl None
endif
return
endif
if !exists(g:go_oracle_scope)
echon "vim-go: " | echohl Function | echon "oracle scope is not set"| echohl None
else
echon "vim-go: " | echohl Function | echon "current oracle scope: '". g:go_oracle_scope ."'" | echohl None
endif
endfunction
" Show 'implements' relation for selected package
function! go#oracle#Implements(selected)
@ -162,12 +186,6 @@ function! go#oracle#Callers(selected)
call s:qflistSecond(out)
endfunction
" Show the callgraph of the current program.
function! go#oracle#Callgraph(selected)
let out = s:RunOracle('callgraph', a:selected)
call s:qflistSecond(out)
endfunction
" Show path from callgraph root to selected function
function! go#oracle#Callstack(selected)
let out = s:RunOracle('callstack', a:selected)
@ -189,28 +207,8 @@ endfunction
" Show all refs to entity denoted by selected identifier
function! go#oracle#Referrers(selected)
let out = s:RunOracle('referrers', a:selected)
" append line contents from Go source file for some messages:
" '...: referenced here'
" '...: reference to NAME'
let lines = split(out, "\n")
let extlines = []
for line in lines
if line =~# '\v: referenced here$|: reference to [^ :]*$'
let parts = split(line, ':')
" Note: we count -3 from end, to support additional comma in
" Windows-style C:\... paths
let filename = join(parts[0:-3], ':')
let linenum = parts[-2]
let extline = line . ': ' . readfile(filename, '', linenum)[linenum-1]
call add(extlines, extline)
else
call add(extlines, line)
endif
endfor
let out = join(extlines, "\n")
call s:qflistSecond(out)
endfunction
" vim:ts=4:sw=4:et
"

View File

@ -44,11 +44,7 @@ function! go#package#Paths()
let dirs += [goroot]
endif
let pathsep = ':'
if s:goos == 'windows'
let pathsep = ';'
endif
let workspaces = split($GOPATH, pathsep)
let workspaces = split($GOPATH, go#util#PathListSep())
if workspaces != []
let dirs += workspaces
endif
@ -116,7 +112,11 @@ endfunction
function! go#package#Complete(ArgLead, CmdLine, CursorPos)
let words = split(a:CmdLine, '\s\+', 1)
if len(words) > 2 && words[0] != "GoImportAs"
" do not complete package members for these commands
let neglect_commands = ["GoImportAs", "GoOracleScope"]
if len(words) > 2 && index(neglect_commands, words[0]) == -1
" Complete package members
return go#package#CompleteMembers(words[1], words[2])
endif
@ -142,6 +142,11 @@ function! go#package#Complete(ArgLead, CmdLine, CursorPos)
endif
let i = substitute(substitute(i[len(r)+1:], '[\\]', '/', 'g'),
\ '\.a$', '', 'g')
" without this the result can have duplicates in form of
" 'encoding/json' and '/encoding/json/'
let i = go#util#StripPathSep(i)
let ret[i] = i
endfor
endfor

View File

@ -0,0 +1,175 @@
" initial_go_path is used to store the initial GOPATH that was set when Vim
" was started. It's used with :GoPathClear to restore the GOPATH when the user
" changed it explicitly via :GoPath. Initially it's empty. It's being set when
" :GoPath is used
let s:initial_go_path = ""
" GoPath sets or returns the current GOPATH. If no arguments are passed it
" echoes the current GOPATH, if an argument is passed it replaces the current
" 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
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())
if len(go_paths) == 1
return $GOPATH
endif
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
endfunction
" Detect returns the current GOPATH. If a package manager is used, such
" as Godeps or something like gb (not supported yet), it will modify the
" GOPATH so those directories take precedence over the current GOPATH. It also
" detects diretories whose are outside GOPATH.
function! go#path#Detect()
let gopath = $GOPATH
" 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'))
" 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()
" gb vendor plugin
" (https://github.com/constabulary/gb/tree/master/cmd/gb-vendor)
let gb_vendor_root = src_path . "vendor" . go#util#PathSep()
if !empty(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
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())
if !go#path#HasPath(godeps_path)
let gopath = godeps_path . go#util#PathListSep() . gopath
endif
endif
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
elseif $GOPATH != ""
let bin_path = expand(go#path#Default() . "/bin/")
else
" could not find anything
endif
return bin_path
endfunction
" CheckBinPath checks whether the given binary exists or not and returns the
" path of the binary. It returns an empty string doesn't exists.
function! go#path#CheckBinPath(binpath)
" remove whitespaces if user applied something like 'goimports '
let binpath = substitute(a:binpath, '^\s*\(.\{-}\)\s*$', '\1', '')
" if it's in PATH just return it
if executable(binpath)
return binpath
endif
" just get the basename
let basename = fnamemodify(binpath, ":t")
" check if we have an appropriate bin_path
let go_bin_path = go#path#BinPath()
if empty(go_bin_path)
echo "vim-go: could not find '" . basename . "'. Run :GoInstallBinaries to fix it."
return ""
endif
" append our GOBIN and GOPATH paths and be sure they can be found there...
" let us search in our GOBIN and GOPATH paths
let old_path = $PATH
let $PATH = $PATH . go#util#PathListSep() .go_bin_path
if !executable(basename)
echo "vim-go: could not find '" . basename . "'. Run :GoInstallBinaries to fix it."
" restore back!
let $PATH = old_path
return ""
endif
let $PATH = old_path
return go_bin_path . go#util#PathSep() . basename
endfunction
" vim:ts=4:sw=4:et

View File

@ -5,8 +5,9 @@ endif
function! go#rename#Rename(...)
let to = ""
if a:0 == 0
let ask = printf("vim-go: rename '%s' to: ", expand("<cword>"))
let to = input(ask)
let from = expand("<cword>")
let ask = printf("vim-go: rename '%s' to: ", from)
let to = input(ask, from)
redraw
else
let to = a:1
@ -14,12 +15,12 @@ function! go#rename#Rename(...)
"return with a warning if the bin doesn't exist
let bin_path = go#tool#BinPath(g:go_gorename_bin)
let bin_path = go#path#CheckBinPath(g:go_gorename_bin)
if empty(bin_path)
return
endif
let fname = resolve(expand('%:p:t'))
let fname = expand('%:p')
let pos = s:getpos(line('.'), col('.'))
let cmd = printf('%s -offset %s -to %s', shellescape(bin_path), shellescape(printf('%s:#%d', fname, pos)), shellescape(to))

View File

@ -1,5 +1,5 @@
function! go#tool#Files()
if IsWin()
if go#util#IsWin()
let command = 'go list -f "{{range $f := .GoFiles}}{{$.Dir}}\{{$f}}{{printf \"\n\"}}{{end}}{{range $f := .CgoFiles}}{{$.Dir}}\{{$f}}{{printf \"\n\"}}{{end}}"'
else
let command = "go list -f '{{range $f := .GoFiles}}{{$.Dir}}/{{$f}}{{printf \"\\n\"}}{{end}}{{range $f := .CgoFiles}}{{$.Dir}}/{{$f}}{{printf \"\\n\"}}{{end}}'"
@ -9,7 +9,7 @@ function! go#tool#Files()
endfunction
function! go#tool#Deps()
if IsWin()
if go#util#IsWin()
let command = 'go list -f "{{range $f := .Deps}}{{$f}}{{printf \"\n\"}}{{end}}"'
else
let command = "go list -f $'{{range $f := .Deps}}{{$f}}\n{{end}}'"
@ -20,7 +20,7 @@ endfunction
function! go#tool#Imports()
let imports = {}
if IsWin()
if go#util#IsWin()
let command = 'go list -f "{{range $f := .Imports}}{{$f}}{{printf \"\n\"}}{{end}}"'
else
let command = "go list -f $'{{range $f := .Imports}}{{$f}}\n{{end}}'"
@ -41,7 +41,17 @@ function! go#tool#Imports()
endfunction
function! go#tool#ShowErrors(out)
" cd into the current files directory. This is important so fnamemodify
" does create a full path for outputs when the token is only a single file
" name (such as for a go test output, i.e.: 'demo_test.go'). For other
" outputs, such as 'go install' we already get an absolute path (i.e.:
" '../foo/foo.go') and fnamemodify successfuly creates the full path.
let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd ' : 'cd '
let current_dir = getcwd()
execute cd . fnameescape(expand("%:p:h"))
let errors = []
for line in split(a:out, '\n')
let fatalerrors = matchlist(line, '^\(fatal error:.*\)$')
let tokens = matchlist(line, '^\s*\(.\{-}\):\(\d\+\):\s*\(.*\)')
@ -49,7 +59,7 @@ function! go#tool#ShowErrors(out)
if !empty(fatalerrors)
call add(errors, {"text": fatalerrors[1]})
elseif !empty(tokens)
call add(errors, {"filename" : expand("%:p:h:") . "/" . tokens[1],
call add(errors, {"filename" : fnamemodify(tokens[1], ':p'),
\"lnum": tokens[2],
\"text": tokens[3]})
elseif !empty(errors)
@ -61,6 +71,9 @@ function! go#tool#ShowErrors(out)
endif
endfor
" return back to old dir once we are finished with populating the errors
execute cd . fnameescape(current_dir)
if !empty(errors)
call setqflist(errors, 'r')
return
@ -73,14 +86,19 @@ function! go#tool#ShowErrors(out)
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.'`=expand("%:p:h")`'
execute cd . fnameescape(expand("%:p:h"))
let out = system(a:cmd)
finally
execute cd.'`=dir`'
execute cd . fnameescape(dir)
endtry
let $GOPATH = old_gopath
return out
endfunction
@ -97,56 +115,13 @@ function! go#tool#Exists(importpath)
return 0
endfunction
" BinPath checks whether the given binary exists or not and returns the path
" of the binary. It returns an empty string doesn't exists.
function! go#tool#BinPath(binpath)
" remove whitespaces if user applied something like 'goimports '
let binpath = substitute(a:binpath, '^\s*\(.\{-}\)\s*$', '\1', '')
" if it's in PATH just return it
if executable(binpath)
return binpath
endif
" just get the basename
let basename = fnamemodify(binpath, ":t")
" check if we have an appropriate bin_path
let go_bin_path = GetBinPath()
if empty(go_bin_path)
echo "vim-go: could not find '" . basename . "'. Run :GoInstallBinaries to fix it."
return ""
endif
" append our GOBIN and GOPATH paths and be sure they can be found there...
" let us search in our GOBIN and GOPATH paths
let old_path = $PATH
let $PATH = $PATH . PathSep() .go_bin_path
if !executable(basename)
echo "vim-go: could not find '" . basename . "'. Run :GoInstallBinaries to fix it."
" restore back!
let $PATH = old_path
return ""
endif
let $PATH = old_path
let sep = '/'
if IsWin()
let sep = '\'
endif
return go_bin_path . sep . basename
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 IsWin()
if go#util#IsWin()
let go_play_browser_command = '!start rundll32 url.dll,FileProtocolHandler %URL%'
elseif has('mac') || has('macunix') || has('gui_macvim') || system('uname') =~? '^darwin'
let go_play_browser_command = 'open %URL%'
@ -183,5 +158,4 @@ function! go#tool#OpenBrowser(url)
endif
endfunction
" vim:ts=4:sw=4:et

View File

@ -0,0 +1,51 @@
" PathSep returns the appropriate OS specific path separator.
function! go#util#PathSep()
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 ":"
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
return "\n"
endfunction
" IsWin returns 1 if current OS is Windows or 0 otherwise
function! go#util#IsWin()
let win = ['win16', 'win32', 'win32unix', 'win64', 'win95']
for w in win
if (has(w))
return 1
endif
endfor
return 0
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
return a:path
endfunction
" vim:ts=4:sw=4:et

View File

@ -1,7 +1,7 @@
"Check if has vimproc
function! go#vimproc#has_vimproc()
if !exists('g:go#use_vimproc')
if IsWin()
if go#util#IsWin()
try
call vimproc#version()
let exists_vimproc = 1