1
0
Fork 0
mirror of synced 2024-11-30 04:35:35 -05:00
ultimate-vim/sources_non_forked/vim-go/autoload/go/path.vim

249 lines
7.3 KiB
VimL
Raw Normal View History

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
2015-07-13 06:22:46 -04:00
" 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 echos the current GOPATH. If no arguments are passed it
2015-07-13 06:22:46 -04:00
" 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.
2016-12-27 09:46:49 -05:00
function! go#path#GoPath(...) abort
2017-04-01 07:22:06 -04:00
" no argument, show GOPATH
if len(a:000) == 0
echo go#path#Default()
2017-04-01 07:22:06 -04:00
return
endif
2016-06-26 07:12:36 -04:00
" we have an argument, replace GOPATH
2017-04-01 07:22:06 -04:00
" 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 = ""
2015-07-13 06:22:46 -04:00
endif
2019-11-16 10:28:42 -05:00
call go#util#EchoInfo("GOPATH restored to ". $GOPATH)
2016-06-26 07:12:36 -04:00
return
endif
2019-11-16 10:28:42 -05:00
call go#util#EchoInfo("GOPATH changed to ". a:1)
2017-04-01 07:22:06 -04:00
let s:initial_go_path = $GOPATH
let $GOPATH = a:1
2015-07-13 06:22:46 -04:00
endfunction
2017-05-26 05:30:32 -04:00
" Default returns the default GOPATH. If GOPATH is not set, it uses the
" default GOPATH set starting with Go 1.8. This GOPATH can be retrieved via
" 'go env GOPATH'
2016-12-27 09:46:49 -05:00
function! go#path#Default() abort
2017-04-01 07:22:06 -04:00
if $GOPATH == ""
" use default GOPATH via go env
2017-07-06 08:57:35 -04:00
return go#util#env("gopath")
2017-04-01 07:22:06 -04:00
endif
2015-07-13 06:22:46 -04:00
2017-05-26 05:30:32 -04:00
return $GOPATH
2015-07-13 06:22:46 -04:00
endfunction
2018-02-04 06:35:08 -05:00
" s:HasPath checks whether the given path exists in GOPATH environment variable
2015-07-13 06:22:46 -04:00
" or not
2018-02-04 06:35:08 -05:00
function! s:HasPath(path) abort
2017-04-01 07:22:06 -04:00
let go_paths = split(go#path#Default(), go#util#PathListSep())
2016-06-26 07:12:36 -04:00
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
2015-07-13 06:22:46 -04:00
endfunction
2015-12-08 08:20:04 -05:00
" Detect returns the current GOPATH. If a package manager is used, such as
" Godeps, GB, it will modify the GOPATH so those directories take precedence
" over the current GOPATH. It also detects diretories whose are outside
" GOPATH.
2016-12-27 09:46:49 -05:00
function! go#path#Detect() abort
2017-04-01 07:22:06 -04:00
let gopath = go#path#Default()
2015-07-13 06:22:46 -04:00
2016-06-26 07:12:36 -04:00
let current_dir = fnameescape(expand('%:p:h'))
2015-07-13 06:22:46 -04:00
2016-06-26 07:12:36 -04:00
" 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.
2015-07-13 06:22:46 -04:00
2017-09-02 06:43:18 -04:00
" src folders outside $GOPATH
let src_roots = finddir("src", current_dir .";", -1)
" for cases like GOPATH/src/foo/src/bar, pick up GOPATH/src instead of
" GOPATH/src/foo/src
let src_root = ""
if len(src_roots) > 0
let src_root = src_roots[-1]
endif
2016-06-26 07:12:36 -04:00
if !empty(src_root)
let src_path = fnamemodify(src_root, ':p:h:h') . go#util#PathSep()
2015-07-13 06:22:46 -04:00
2016-06-26 07:12:36 -04:00
" gb vendor plugin
" (https://github.com/constabulary/gb/tree/master/cmd/gb-vendor)
let gb_vendor_root = src_path . "vendor" . go#util#PathSep()
2018-02-04 06:35:08 -05:00
if isdirectory(gb_vendor_root) && !s:HasPath(gb_vendor_root)
2016-06-26 07:12:36 -04:00
let gopath = gb_vendor_root . go#util#PathListSep() . gopath
endif
2015-07-13 06:22:46 -04:00
2018-02-04 06:35:08 -05:00
if !s:HasPath(src_path)
2016-06-26 07:12:36 -04:00
let gopath = src_path . go#util#PathListSep() . gopath
2015-07-13 06:22:46 -04:00
endif
2016-06-26 07:12:36 -04:00
endif
2015-07-13 06:22:46 -04:00
2016-06-26 07:12:36 -04:00
" 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())
2015-07-13 06:22:46 -04:00
2018-02-04 06:35:08 -05:00
if !s:HasPath(godeps_path)
2016-06-26 07:12:36 -04:00
let gopath = godeps_path . go#util#PathListSep() . gopath
2015-07-13 06:22:46 -04:00
endif
2016-06-26 07:12:36 -04:00
endif
2015-07-13 06:22:46 -04:00
2017-02-11 08:01:38 -05:00
" Fix up the case where initial $GOPATH is empty,
" and we end up with a trailing :
let gopath = substitute(gopath, ":$", "", "")
2016-06-26 07:12:36 -04:00
return gopath
2015-07-13 06:22:46 -04:00
endfunction
" BinPath returns the binary path of installed go tools.
2016-12-27 09:46:49 -05:00
function! go#path#BinPath() abort
2018-06-14 06:31:12 -04:00
let bin_path = go#config#BinPath()
if bin_path != ""
return bin_path
endif
2016-06-26 07:12:36 -04:00
" check if our global custom path is set, if not check if $GOBIN is set so
2017-04-01 07:22:06 -04:00
" we can use it, otherwise use default GOPATH
2018-06-14 06:31:12 -04:00
if $GOBIN != ""
2016-06-26 07:12:36 -04:00
let bin_path = $GOBIN
2017-04-01 07:22:06 -04:00
else
2017-05-26 05:30:32 -04:00
let go_paths = split(go#path#Default(), go#util#PathListSep())
2017-09-02 06:43:18 -04:00
if len(go_paths) == 0
return "" "nothing found
endif
2017-05-26 05:30:32 -04:00
let bin_path = expand(go_paths[0] . "/bin/")
2017-04-01 07:22:06 -04:00
endif
2015-07-13 06:22:46 -04:00
2017-04-01 07:22:06 -04:00
return bin_path
2015-07-13 06:22:46 -04:00
endfunction
" CheckBinPath checks whether the given binary exists or not and returns the
2018-12-17 06:28:27 -05:00
" path of the binary, respecting the go_bin_path and go_search_bin_path_first
" settings. It returns an empty string if the binary doesn't exist.
2016-12-27 09:46:49 -05:00
function! go#path#CheckBinPath(binpath) abort
2017-04-01 07:22:06 -04:00
" remove whitespaces if user applied something like 'goimports '
let binpath = substitute(a:binpath, '^\s*\(.\{-}\)\s*$', '\1', '')
2018-06-14 06:31:12 -04:00
" save original path
2017-04-01 07:22:06 -04:00
let old_path = $PATH
" check if we have an appropriate bin_path
let go_bin_path = go#path#BinPath()
if !empty(go_bin_path)
" append our GOBIN and GOPATH paths and be sure they can be found there...
" let us search in our GOBIN and GOPATH paths
2018-12-17 06:28:27 -05:00
" respect the ordering specified by go_search_bin_path_first
if go#config#SearchBinPathFirst()
let $PATH = go_bin_path . go#util#PathListSep() . $PATH
else
let $PATH = $PATH . go#util#PathListSep() . go_bin_path
endif
2017-04-01 07:22:06 -04:00
endif
2015-07-13 06:22:46 -04:00
2017-04-01 07:22:06 -04:00
" if it's in PATH just return it
if executable(binpath)
if exists('*exepath')
let binpath = exepath(binpath)
2015-07-13 06:22:46 -04:00
endif
2017-04-01 07:22:06 -04:00
let $PATH = old_path
2017-09-02 06:43:18 -04:00
if go#util#IsUsingCygwinShell() == 1
2018-02-04 06:35:08 -05:00
return s:CygwinPath(binpath)
2017-09-02 06:43:18 -04:00
endif
2017-04-01 07:22:06 -04:00
return binpath
endif
2015-07-13 06:22:46 -04:00
2017-04-01 07:22:06 -04:00
" just get the basename
let basename = fnamemodify(binpath, ":t")
if !executable(basename)
call go#util#EchoError(printf("could not find '%s'. Run :GoInstallBinaries to fix it", basename))
2015-07-13 06:22:46 -04:00
2017-04-01 07:22:06 -04:00
" restore back!
2015-07-13 06:22:46 -04:00
let $PATH = old_path
2017-04-01 07:22:06 -04:00
return ""
endif
let $PATH = old_path
2015-07-13 06:22:46 -04:00
2017-09-02 06:43:18 -04:00
if go#util#IsUsingCygwinShell() == 1
2018-02-04 06:35:08 -05:00
return s:CygwinPath(a:binpath)
2017-09-02 06:43:18 -04:00
endif
2017-07-06 08:57:35 -04:00
2017-04-01 07:22:06 -04:00
return go_bin_path . go#util#PathSep() . basename
2015-07-13 06:22:46 -04:00
endfunction
2018-02-04 06:35:08 -05:00
function! s:CygwinPath(path)
2017-09-02 06:43:18 -04:00
return substitute(a:path, '\\', '/', "g")
endfunction
2019-03-27 11:08:56 -04:00
" go#path#ToURI converts path to a file URI. path should be an absolute path.
" Relative paths cannot be properly converted to a URI; when path is a
" relative path, the file scheme will not be prepended.
function! go#path#ToURI(path)
2019-05-17 10:09:13 -04:00
let l:absolute = !go#util#IsWin() && a:path[0] is# '/'
let l:prefix = ''
2019-03-27 11:08:56 -04:00
let l:path = a:path
2019-05-17 10:09:13 -04:00
if go#util#IsWin() && l:path[1:2] is# ':\'
let l:absolute = 1
let l:prefix = '/' . l:path[0:1]
let l:path = l:path[2:]
2019-03-27 11:08:56 -04:00
endif
return substitute(
2019-05-17 10:09:13 -04:00
\ (l:absolute ? 'file://' : '') . l:prefix . go#uri#EncodePath(l:path),
2019-03-27 11:08:56 -04:00
\ '\\',
\ '/',
\ 'g',
\)
endfunction
function! go#path#FromURI(uri) abort
let l:i = len('file://')
let l:encoded_path = a:uri[: l:i - 1] is# 'file://' ? a:uri[l:i :] : a:uri
let l:path = go#uri#Decode(l:encoded_path)
" If the path is like /C:/foo/bar, it should be C:\foo\bar instead.
2019-05-17 10:09:13 -04:00
if go#util#IsWin() && l:path =~# '^/[a-zA-Z]:'
2019-03-27 11:08:56 -04:00
let l:path = substitute(l:path[1:], '/', '\\', 'g')
endif
return l:path
endfunction
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