1
0
Fork 0
mirror of synced 2024-11-29 20:25:34 -05:00
ultimate-vim/sources_non_forked/vim-go/plugin/go.vim

314 lines
10 KiB
VimL
Raw Normal View History

2014-10-31 17:30:24 -04:00
" install necessary Go tools
if exists("g:go_loaded_install")
2016-06-26 07:12:36 -04:00
finish
2014-10-31 17:30:24 -04:00
endif
let g:go_loaded_install = 1
2018-12-17 06:28:27 -05:00
" don't spam the user when Vim is started in Vi compatibility mode
let s:cpo_save = &cpo
set cpo&vim
2018-09-30 16:58:57 -04:00
function! s:checkVersion() abort
let l:unsupported = 0
if go#config#VersionWarning() != 0
if has('nvim')
2019-08-22 11:36:17 -04:00
let l:unsupported = !has('nvim-0.3.2')
2018-09-30 16:58:57 -04:00
else
2019-11-16 10:28:42 -05:00
let l:unsupported = !has('patch-8.0.1453')
2018-09-30 16:58:57 -04:00
endif
if l:unsupported == 1
echohl Error
2019-11-16 10:28:42 -05:00
echom "vim-go requires at least Vim 8.0.1453 or Neovim 0.3.2, but you're using an older version."
2018-09-30 16:58:57 -04:00
echom "Please update your Vim for the best vim-go experience."
echom "If you really want to continue you can set this to make the error go away:"
echom " let g:go_version_warning = 0"
echom "Note that some features may error out or behave incorrectly."
2019-11-16 10:28:42 -05:00
echom "Please do not report bugs unless you're using at least Vim 8.0.1453 or Neovim 0.3.2."
2018-09-30 16:58:57 -04:00
echohl None
" Make sure people see this.
sleep 2
endif
endif
endfunction
call s:checkVersion()
2014-10-31 17:30:24 -04:00
" these packages are used by vim-go and can be automatically installed if
2018-09-24 20:40:17 -04:00
" needed by the user with GoInstallBinaries.
2019-11-16 10:28:42 -05:00
" NOTE(bc): varying the binary name and the tail of the import path (e.g.
" gocode-gomod) does not yet work in module aware mode.
let s:packages = {
2019-11-16 10:28:42 -05:00
\ 'asmfmt': ['github.com/klauspost/asmfmt/cmd/asmfmt@master'],
\ 'dlv': ['github.com/go-delve/delve/cmd/dlv@master'],
\ 'errcheck': ['github.com/kisielk/errcheck@master'],
\ 'fillstruct': ['github.com/davidrjenni/reftools/cmd/fillstruct@master'],
\ 'gocode': ['github.com/mdempsky/gocode@master', {'windows': ['-ldflags', '-H=windowsgui']}],
2018-11-01 06:03:42 -04:00
\ 'gocode-gomod': ['github.com/stamblerre/gocode'],
2019-11-16 10:28:42 -05:00
\ 'godef': ['github.com/rogpeppe/godef@master'],
\ 'gogetdoc': ['github.com/zmb3/gogetdoc@master'],
\ 'goimports': ['golang.org/x/tools/cmd/goimports@master'],
\ 'golint': ['golang.org/x/lint/golint@master'],
2019-08-22 11:36:17 -04:00
\ 'gopls': ['golang.org/x/tools/gopls@latest', {}, {'after': function('go#lsp#Restart', [])}],
2019-11-16 10:28:42 -05:00
\ 'golangci-lint': ['github.com/golangci/golangci-lint/cmd/golangci-lint@master'],
\ 'gomodifytags': ['github.com/fatih/gomodifytags@master'],
\ 'gorename': ['golang.org/x/tools/cmd/gorename@master'],
\ 'gotags': ['github.com/jstemmer/gotags@master'],
\ 'guru': ['golang.org/x/tools/cmd/guru@master'],
\ 'impl': ['github.com/josharian/impl@master'],
\ 'keyify': ['honnef.co/go/tools/cmd/keyify@master'],
\ 'motion': ['github.com/fatih/motion@master'],
\ 'iferr': ['github.com/koron/iferr@master'],
\ }
2014-10-31 17:30:24 -04:00
2015-07-13 06:22:46 -04:00
" These commands are available on any filetypes
command! -nargs=* -complete=customlist,s:complete GoInstallBinaries call s:GoInstallBinaries(-1, <f-args>)
command! -nargs=* -complete=customlist,s:complete GoUpdateBinaries call s:GoInstallBinaries(1, <f-args>)
2015-07-13 06:22:46 -04:00
command! -nargs=? -complete=dir GoPath call go#path#GoPath(<f-args>)
2014-10-31 17:30:24 -04:00
fun! s:complete(lead, cmdline, cursor)
return filter(keys(s:packages), 'strpart(v:val, 0, len(a:lead)) == a:lead')
endfun
" GoInstallBinaries downloads and installs binaries defined in s:packages to
" $GOBIN or $GOPATH/bin. GoInstallBinaries will update already installed
" binaries only if updateBinaries = 1. By default, all packages in s:packages
" will be installed, but the set can be limited by passing the desired
" packages in the unnamed arguments.
function! s:GoInstallBinaries(updateBinaries, ...)
2017-04-01 07:22:06 -04:00
let err = s:CheckBinaries()
if err != 0
2016-06-26 07:12:36 -04:00
return
endif
2017-04-01 07:22:06 -04:00
if go#path#Default() == ""
2019-11-16 10:28:42 -05:00
call go#util#EchoError('$GOPATH is not set and `go env GOPATH` returns empty')
2016-06-26 07:12:36 -04:00
return
endif
let go_bin_path = go#path#BinPath()
" change $GOBIN so go get can automatically install to it
2019-11-16 10:28:42 -05:00
let Restore_gobin = go#util#SetEnv('GOBIN', go_bin_path)
2016-06-26 07:12:36 -04:00
" vim's executable path is looking in PATH so add our go_bin path to it
2019-05-17 10:09:13 -04:00
let Restore_path = go#util#SetEnv('PATH', go_bin_path . go#util#PathListSep() . $PATH)
2016-06-26 07:12:36 -04:00
" 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
2019-08-22 11:36:17 -04:00
let l:get_base_cmd = ['go', 'get', '-v']
2016-06-26 07:12:36 -04:00
" Filter packages from arguments (if any).
let l:packages = {}
if a:0 > 0
for l:bin in a:000
let l:pkg = get(s:packages, l:bin, [])
if len(l:pkg) == 0
call go#util#EchoError('unknown binary: ' . l:bin)
return
endif
let l:packages[l:bin] = l:pkg
endfor
else
let l:packages = s:packages
endif
2016-06-26 07:12:36 -04:00
let l:platform = ''
if go#util#IsWin()
let l:platform = 'windows'
endif
2019-08-22 11:36:17 -04:00
let l:oldmore = &more
let &more = 0
2018-06-14 06:31:12 -04:00
2019-08-22 11:36:17 -04:00
for [l:binary, l:pkg] in items(l:packages)
let l:importPath = l:pkg[0]
2019-08-22 11:36:17 -04:00
" TODO(bc): how to support this with modules? Do we have to clone and then
" install manually? Probably not. I suspect that we can just use GOPATH
" mode and then do the legacy method.
let bin_setting_name = "go_" . l:binary . "_bin"
2018-09-24 20:40:17 -04:00
if exists("g:{bin_setting_name}")
let bin = g:{bin_setting_name}
else
if go#util#IsWin()
2019-08-22 11:36:17 -04:00
let bin = l:binary . '.exe'
2018-09-24 20:40:17 -04:00
else
2019-08-22 11:36:17 -04:00
let bin = l:binary
2018-09-24 20:40:17 -04:00
endif
2016-06-26 07:12:36 -04:00
endif
if !executable(bin) || a:updateBinaries == 1
if a:updateBinaries == 1
2019-08-22 11:36:17 -04:00
echo "vim-go: Updating " . l:binary . ". Reinstalling ". importPath . " to folder " . go_bin_path
2016-06-26 07:12:36 -04:00
else
2019-08-22 11:36:17 -04:00
echo "vim-go: ". l:binary ." not found. Installing ". importPath . " to folder " . go_bin_path
2016-06-26 07:12:36 -04:00
endif
2019-08-22 11:36:17 -04:00
if l:importPath =~ "@"
let Restore_modules = go#util#SetEnv('GO111MODULE', 'on')
let l:tmpdir = go#util#tempdir('vim-go')
let l:cd = exists('*haslocaldir') && haslocaldir() ? 'lcd ' : 'cd '
let l:dir = getcwd()
try
execute l:cd . fnameescape(l:tmpdir)
let l:get_cmd = copy(l:get_base_cmd)
2019-11-16 10:28:42 -05:00
if len(l:pkg) > 1 && get(l:pkg[1], l:platform, []) isnot []
let l:get_cmd += get(l:pkg[1], l:platform, [])
endif
" TODO(bc): how to install the bin to a different name than the
" binary path? go get does not support -o
" let l:get_cmd += ['-o', printf('%s%s%s', go_bin_path, go#util#PathSep(), bin)]
2019-08-22 11:36:17 -04:00
let [l:out, l:err] = go#util#Exec(l:get_cmd + [l:importPath])
if l:err
2019-11-16 10:28:42 -05:00
call go#util#EchoError(printf('Error installing %s: %s', l:importPath, l:out))
2019-08-22 11:36:17 -04:00
endif
call call(Restore_modules, [])
finally
execute l:cd . fnameescape(l:dir)
endtry
call call(Restore_modules, [])
else
let l:get_cmd = copy(l:get_base_cmd)
let l:get_cmd += ['-d']
if get(g:, "go_get_update", 1) != 0
let l:get_cmd += ['-u']
endif
let Restore_modules = go#util#SetEnv('GO111MODULE', 'off')
" first download the binary
let [l:out, l:err] = go#util#Exec(l:get_cmd + [l:importPath])
if l:err
2019-11-16 10:28:42 -05:00
call go#util#EchoError(printf('Error downloading %s: %s', l:importPath, l:out))
2019-08-22 11:36:17 -04:00
endif
" and then build and install it
2019-11-16 10:28:42 -05:00
let l:build_cmd = ['go', 'build']
if len(l:pkg) > 1 && get(l:pkg[1], l:platform, []) isnot []
let l:build_cmd += get(l:pkg[1], l:platform, [])
2019-08-22 11:36:17 -04:00
endif
2019-11-16 10:28:42 -05:00
let l:build_cmd += ['-o', printf('%s%s%s', go_bin_path, go#util#PathSep(), bin), l:importPath]
2019-08-22 11:36:17 -04:00
let [l:out, l:err] = go#util#Exec(l:build_cmd)
if l:err
2019-11-16 10:28:42 -05:00
call go#util#EchoError(printf('Error installing %s: %s', l:importPath, l:out))
2019-08-22 11:36:17 -04:00
endif
call call(Restore_modules, [])
2018-09-24 20:40:17 -04:00
endif
2019-08-22 11:36:17 -04:00
if len(l:pkg) > 2
call call(get(l:pkg[2], 'after', function('s:noop', [])), [])
2016-06-26 07:12:36 -04:00
endif
endif
endfor
" restore back!
2019-05-17 10:09:13 -04:00
call call(Restore_path, [])
2019-11-16 10:28:42 -05:00
call call(Restore_gobin, [])
2019-05-17 10:09:13 -04:00
2016-06-26 07:12:36 -04:00
if resetshellslash
set shellslash
endif
2018-09-24 20:40:17 -04:00
if a:updateBinaries == 1
call go#util#EchoInfo('updating finished!')
else
call go#util#EchoInfo('installing finished!')
endif
2019-08-22 11:36:17 -04:00
let &more = l:oldmore
2014-10-31 17:30:24 -04:00
endfunction
" CheckBinaries checks if the necessary binaries to install the Go tool
" commands are available.
function! s:CheckBinaries()
2016-06-26 07:12:36 -04:00
if !executable('go')
2019-11-16 10:28:42 -05:00
call go#util#EchoError('go executable not found.')
2016-06-26 07:12:36 -04:00
return -1
endif
if !executable('git')
2019-11-16 10:28:42 -05:00
call go#util#EchoError('git executable not found.')
2016-06-26 07:12:36 -04:00
return -1
endif
2014-10-31 17:30:24 -04:00
endfunction
2015-01-18 07:58:28 -05:00
" Autocommands
" ============================================================================
2016-02-20 08:13:10 -05:00
"
2016-06-26 07:12:36 -04:00
2019-03-08 06:04:56 -05:00
" We take care to preserve the user's fileencodings and fileformats,
" because those settings are global (not buffer local), yet we want
" to override them for loading Go files, which are defined to be UTF-8.
let s:current_fileformats = ''
let s:current_fileencodings = ''
" define fileencodings to open as utf-8 encoding even if it's ascii.
function! s:gofiletype_pre()
let s:current_fileformats = &g:fileformats
let s:current_fileencodings = &g:fileencodings
set fileencodings=utf-8 fileformats=unix
2016-08-02 08:48:32 -04:00
endfunction
2016-07-03 07:53:59 -04:00
2019-03-08 06:04:56 -05:00
" restore fileencodings as others
function! s:gofiletype_post()
let &g:fileformats = s:current_fileformats
let &g:fileencodings = s:current_fileencodings
2016-08-02 08:48:32 -04:00
endfunction
2019-05-17 10:09:13 -04:00
function! s:register()
if !(&modifiable && expand('<amatch>') ==# 'go')
return
endif
let l:RestoreGopath = function('s:noop')
if go#config#AutodetectGopath()
let l:RestoreGopath = go#util#SetEnv('GOPATH', go#path#Detect())
endif
call go#lsp#DidOpen(expand('<afile>:p'))
call call(l:RestoreGopath, [])
endfunction
function! s:noop(...) abort
endfunction
2016-08-02 08:48:32 -04:00
augroup vim-go
autocmd!
2019-03-08 06:04:56 -05:00
autocmd BufNewFile *.go if &modifiable | setlocal fileencoding=utf-8 fileformat=unix | endif
autocmd BufNewFile *.go call go#auto#template_autocreate()
autocmd BufRead *.go call s:gofiletype_pre()
autocmd BufReadPost *.go call s:gofiletype_post()
2016-08-02 08:48:32 -04:00
2019-03-08 06:04:56 -05:00
autocmd BufNewFile *.s if &modifiable | setlocal fileencoding=utf-8 fileformat=unix | endif
autocmd BufRead *.s call s:gofiletype_pre()
autocmd BufReadPost *.s call s:gofiletype_post()
2019-05-17 10:09:13 -04:00
if go#util#has_job()
autocmd FileType * call s:register()
endif
augroup end
2015-01-18 07:58:28 -05:00
2018-12-17 06:28:27 -05:00
" restore Vi compatibility settings
let &cpo = s:cpo_save
unlet s:cpo_save
2016-06-26 07:12:36 -04:00
" vim: sw=2 ts=2 et