1
0
Fork 0
mirror of synced 2024-11-16 05:55:35 -05:00
ultimate-vim/sources_non_forked/vim-go/autoload/go/util.vim

295 lines
8.6 KiB
VimL
Raw Normal View History

2015-07-13 06:22:46 -04:00
" PathSep returns the appropriate OS specific path separator.
2016-12-27 09:46:49 -05:00
function! go#util#PathSep() abort
2016-06-26 07:12:36 -04:00
if go#util#IsWin()
return '\'
endif
return '/'
2015-07-13 06:22:46 -04:00
endfunction
" PathListSep returns the appropriate OS specific path list separator.
2016-12-27 09:46:49 -05:00
function! go#util#PathListSep() abort
2016-06-26 07:12:36 -04:00
if go#util#IsWin()
return ";"
endif
return ":"
2015-07-13 06:22:46 -04:00
endfunction
" LineEnding returns the correct line ending, based on the current fileformat
2016-12-27 09:46:49 -05:00
function! go#util#LineEnding() abort
2016-06-26 07:12:36 -04:00
if &fileformat == 'dos'
return "\r\n"
elseif &fileformat == 'mac'
return "\r"
endif
2015-07-13 06:22:46 -04:00
2016-06-26 07:12:36 -04:00
return "\n"
2015-07-13 06:22:46 -04:00
endfunction
2016-07-03 07:53:59 -04:00
" Join joins any number of path elements into a single path, adding a
" Separator if necessary and returns the result
2016-12-27 09:46:49 -05:00
function! go#util#Join(...) abort
2016-07-03 07:53:59 -04:00
return join(a:000, go#util#PathSep())
endfunction
2015-07-13 06:22:46 -04:00
" IsWin returns 1 if current OS is Windows or 0 otherwise
2016-12-27 09:46:49 -05:00
function! go#util#IsWin() abort
2016-06-26 07:12:36 -04:00
let win = ['win16', 'win32', 'win64', 'win95']
for w in win
if (has(w))
return 1
endif
endfor
2016-02-20 08:13:10 -05:00
2016-06-26 07:12:36 -04:00
return 0
2015-07-13 06:22:46 -04:00
endfunction
2016-12-27 09:46:49 -05:00
function! go#util#has_job() abort
" job was introduced in 7.4.xxx however there are multiple bug fixes and one
" of the latest is 8.0.0087 which is required for a stable async API.
return has('job') && has("patch-8.0.0087")
endfunction
2016-11-09 12:22:55 -05:00
let s:env_cache = {}
" env returns the go environment variable for the given key. Where key can be
" GOARCH, GOOS, GOROOT, etc... It caches the result and returns the cached
2017-08-03 11:21:37 -04:00
" version.
2016-12-27 09:46:49 -05:00
function! go#util#env(key) abort
2016-11-09 12:22:55 -05:00
let l:key = tolower(a:key)
if has_key(s:env_cache, l:key)
return s:env_cache[l:key]
endif
if executable('go')
let l:var = call('go#util#'.l:key, [])
if go#util#ShellError() != 0
call go#util#EchoError(printf("'go env %s' failed", toupper(l:key)))
return ''
endif
else
let l:var = eval("$".toupper(a:key))
endif
let s:env_cache[l:key] = l:var
return l:var
endfunction
2017-08-03 11:21:37 -04:00
" goarch returns 'go env GOARCH'. This is an internal function and shouldn't
" be used. Instead use 'go#util#env("goarch")'
2016-12-27 09:46:49 -05:00
function! go#util#goarch() abort
2016-06-26 07:12:36 -04:00
return substitute(go#util#System('go env GOARCH'), '\n', '', 'g')
2016-05-14 07:57:54 -04:00
endfunction
2017-08-03 11:21:37 -04:00
" goos returns 'go env GOOS'. This is an internal function and shouldn't
" be used. Instead use 'go#util#env("goos")'
2016-12-27 09:46:49 -05:00
function! go#util#goos() abort
2016-06-26 07:12:36 -04:00
return substitute(go#util#System('go env GOOS'), '\n', '', 'g')
2016-05-14 07:57:54 -04:00
endfunction
2017-08-03 11:21:37 -04:00
" goroot returns 'go env GOROOT'. This is an internal function and shouldn't
" be used. Instead use 'go#util#env("goroot")'
2016-12-27 09:46:49 -05:00
function! go#util#goroot() abort
2016-06-26 07:12:36 -04:00
return substitute(go#util#System('go env GOROOT'), '\n', '', 'g')
2016-05-14 07:57:54 -04:00
endfunction
2017-08-03 11:21:37 -04:00
" gopath returns 'go env GOPATH'. This is an internal function and shouldn't
" be used. Instead use 'go#util#env("gopath")'
2016-12-27 09:46:49 -05:00
function! go#util#gopath() abort
2016-06-26 07:12:36 -04:00
return substitute(go#util#System('go env GOPATH'), '\n', '', 'g')
2016-05-14 07:57:54 -04:00
endfunction
2016-12-27 09:46:49 -05:00
function! go#util#osarch() abort
2017-08-03 11:21:37 -04:00
return go#util#env("goos") . '_' . go#util#env("goarch")
2016-05-14 07:57:54 -04:00
endfunction
2017-08-03 11:21:37 -04:00
" System runs a shell command. If possible, it will temporary set
" the shell to /bin/sh for Unix-like systems providing a Bourne
" POSIX like environment.
2016-12-27 09:46:49 -05:00
function! go#util#System(str, ...) abort
2017-08-03 11:21:37 -04:00
" Preserve original shell and shellredir values
2016-08-02 08:48:32 -04:00
let l:shell = &shell
2017-08-03 11:21:37 -04:00
let l:shellredir = &shellredir
" Use a Bourne POSIX like shell. Some parts of vim-go expect
" commands to be executed using bourne semantics #988 and #1276.
" Alter shellredir to match bourne. Especially important if login shell
" is set to any of the csh or zsh family #1276.
2016-08-02 08:48:32 -04:00
if !go#util#IsWin() && executable('/bin/sh')
2017-08-03 11:21:37 -04:00
set shell=/bin/sh shellredir=>%s\ 2>&1
2016-08-02 08:48:32 -04:00
endif
try
2016-12-27 09:46:49 -05:00
let l:output = call('system', [a:str] + a:000)
2016-08-02 08:48:32 -04:00
return l:output
finally
2017-08-03 11:21:37 -04:00
" Restore original values
2016-08-02 08:48:32 -04:00
let &shell = l:shell
2017-08-03 11:21:37 -04:00
let &shellredir = l:shellredir
2016-08-02 08:48:32 -04:00
endtry
2016-05-14 07:57:54 -04:00
endfunction
2016-12-27 09:46:49 -05:00
function! go#util#ShellError() abort
return v:shell_error
2016-05-14 07:57:54 -04:00
endfunction
2015-07-13 06:22:46 -04:00
" StripPath strips the path's last character if it's a path separator.
" example: '/foo/bar/' -> '/foo/bar'
2016-12-27 09:46:49 -05:00
function! go#util#StripPathSep(path) abort
2016-06-26 07:12:36 -04:00
let last_char = strlen(a:path) - 1
if a:path[last_char] == go#util#PathSep()
return strpart(a:path, 0, last_char)
endif
2015-07-13 06:22:46 -04:00
2016-06-26 07:12:36 -04:00
return a:path
2015-07-13 06:22:46 -04:00
endfunction
2016-03-14 06:04:57 -04:00
" StripTrailingSlash strips the trailing slash from the given path list.
" example: ['/foo/bar/'] -> ['/foo/bar']
2016-12-27 09:46:49 -05:00
function! go#util#StripTrailingSlash(paths) abort
2016-03-14 06:04:57 -04:00
return map(copy(a:paths), 'go#util#StripPathSep(v:val)')
endfunction
2015-12-08 08:20:04 -05:00
" Shelljoin returns a shell-safe string representation of arglist. The
" {special} argument of shellescape() may optionally be passed.
2016-12-27 09:46:49 -05:00
function! go#util#Shelljoin(arglist, ...) abort
2016-06-26 07:12:36 -04:00
try
let ssl_save = &shellslash
set noshellslash
if a:0
return join(map(copy(a:arglist), 'shellescape(v:val, ' . a:1 . ')'), ' ')
endif
2016-02-20 08:13:10 -05:00
2016-07-16 14:30:35 -04:00
return join(map(copy(a:arglist), 'shellescape(v:val)'), ' ')
finally
let &shellslash = ssl_save
endtry
2015-12-16 08:53:53 -05:00
endfunction
2016-05-14 07:57:54 -04:00
fu! go#util#Shellescape(arg)
2016-07-16 14:30:35 -04:00
try
let ssl_save = &shellslash
set noshellslash
return shellescape(a:arg)
finally
let &shellslash = ssl_save
endtry
2016-05-14 07:57:54 -04:00
endf
2016-02-20 08:13:10 -05:00
" Shelllist returns a shell-safe representation of the items in the given
2015-12-16 08:53:53 -05:00
" arglist. The {special} argument of shellescape() may optionally be passed.
2016-12-27 09:46:49 -05:00
function! go#util#Shelllist(arglist, ...) abort
2016-07-16 14:30:35 -04:00
try
let ssl_save = &shellslash
set noshellslash
if a:0
return map(copy(a:arglist), 'shellescape(v:val, ' . a:1 . ')')
endif
return map(copy(a:arglist), 'shellescape(v:val)')
finally
let &shellslash = ssl_save
endtry
2015-12-16 08:53:53 -05:00
endfunction
2016-03-20 14:01:44 -04:00
" Returns the byte offset for line and column
2016-12-27 09:46:49 -05:00
function! go#util#Offset(line, col) abort
2016-07-16 14:30:35 -04:00
if &encoding != 'utf-8'
let sep = go#util#LineEnding()
let buf = a:line == 1 ? '' : (join(getline(1, a:line-1), sep) . sep)
let buf .= a:col == 1 ? '' : getline('.')[:a:col-2]
return len(iconv(buf, &encoding, 'utf-8'))
endif
return line2byte(a:line) + (a:col-2)
2016-03-20 14:01:44 -04:00
endfunction
"
" Returns the byte offset for the cursor
2016-12-27 09:46:49 -05:00
function! go#util#OffsetCursor() abort
2016-07-16 14:30:35 -04:00
return go#util#Offset(line('.'), col('.'))
2016-03-20 14:01:44 -04:00
endfunction
2016-04-12 04:31:09 -04:00
" Windo is like the built-in :windo, only it returns to the window the command
" was issued from
2016-12-27 09:46:49 -05:00
function! go#util#Windo(command) abort
2016-07-16 14:30:35 -04:00
let s:currentWindow = winnr()
try
execute "windo " . a:command
finally
execute s:currentWindow. "wincmd w"
unlet s:currentWindow
endtry
endfunction
" snippetcase converts the given word to given preferred snippet setting type
" case.
2016-12-27 09:46:49 -05:00
function! go#util#snippetcase(word) abort
2017-08-03 11:21:37 -04:00
let l:snippet_case = get(g:, 'go_addtags_transform', "snakecase")
2016-07-16 14:30:35 -04:00
if l:snippet_case == "snakecase"
return go#util#snakecase(a:word)
elseif l:snippet_case == "camelcase"
return go#util#camelcase(a:word)
else
return a:word " do nothing
endif
2016-04-12 04:31:09 -04:00
endfunction
2016-07-16 14:30:35 -04:00
" snakecase converts a string to snake case. i.e: FooBar -> foo_bar
" Copied from tpope/vim-abolish
2016-12-27 09:46:49 -05:00
function! go#util#snakecase(word) abort
2016-07-16 14:30:35 -04:00
let word = substitute(a:word,'::','/','g')
let word = substitute(word,'\(\u\+\)\(\u\l\)','\1_\2','g')
let word = substitute(word,'\(\l\|\d\)\(\u\)','\1_\2','g')
let word = substitute(word,'[.-]','_','g')
let word = tolower(word)
return word
endfunction
" camelcase converts a string to camel case. i.e: FooBar -> fooBar
" Copied from tpope/vim-abolish
2016-12-27 09:46:49 -05:00
function! go#util#camelcase(word) abort
2016-07-16 14:30:35 -04:00
let word = substitute(a:word, '-', '_', 'g')
if word !~# '_' && word =~# '\l'
return substitute(word,'^.','\l&','')
else
return substitute(word,'\C\(_\)\=\(.\)','\=submatch(1)==""?tolower(submatch(2)) : toupper(submatch(2))','g')
endif
endfunction
2015-12-16 08:53:53 -05:00
" TODO(arslan): I couldn't parameterize the highlight types. Check if we can
" simplify the following functions
2016-12-27 09:46:49 -05:00
"
" NOTE(arslan): echon doesn't work well with redraw, thus echo doesn't print
" even though we order it. However echom seems to be work fine.
2015-12-16 08:53:53 -05:00
function! go#util#EchoSuccess(msg)
2016-12-27 09:46:49 -05:00
redraw | echohl Function | echom "vim-go: " . a:msg | echohl None
2015-12-08 08:20:04 -05:00
endfunction
2015-12-16 08:53:53 -05:00
function! go#util#EchoError(msg)
2016-12-27 09:46:49 -05:00
redraw | echohl ErrorMsg | echom "vim-go: " . a:msg | echohl None
2015-12-16 08:53:53 -05:00
endfunction
function! go#util#EchoWarning(msg)
2016-12-27 09:46:49 -05:00
redraw | echohl WarningMsg | echom "vim-go: " . a:msg | echohl None
2015-12-16 08:53:53 -05:00
endfunction
function! go#util#EchoProgress(msg)
2016-12-27 09:46:49 -05:00
redraw | echohl Identifier | echom "vim-go: " . a:msg | echohl None
endfunction
function! go#util#EchoInfo(msg)
redraw | echohl Debug | echom "vim-go: " . a:msg | echohl None
2015-12-16 08:53:53 -05:00
endfunction
2017-08-03 11:21:37 -04:00
function! go#util#GetLines()
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
return buf
endfunction
2016-06-26 07:12:36 -04:00
" vim: sw=2 ts=2 et