mirror of
https://github.com/amix/vimrc
synced 2025-06-16 01:25:00 +08:00
Updated plugins, also experimenting with a new font
The font is IBM Plex Mono: https://ibm.github.io/type/
This commit is contained in:
@ -93,10 +93,6 @@ function! ctrlp#decls#enter() abort
|
||||
return
|
||||
endif
|
||||
|
||||
if exists("l:tmpname")
|
||||
call delete(l:tmpname)
|
||||
endif
|
||||
|
||||
let result = eval(out)
|
||||
if type(result) != 4 || !has_key(result, 'decls')
|
||||
return
|
||||
|
@ -9,20 +9,17 @@ 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, ...) abort
|
||||
" 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
|
||||
if !has('nvim')
|
||||
let goargs = go#util#Shelllist(goargs, 1)
|
||||
endif
|
||||
" create our command arguments. go build discards any results when it
|
||||
" 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 '.'). We also pass -i
|
||||
" that tries to install the dependencies, this has the side effect that it
|
||||
" caches the build results, so every other build is faster.
|
||||
let args = ["build"] + goargs + ["-i", ".", "errors"]
|
||||
let args =
|
||||
\ ["build"] +
|
||||
\ map(copy(a:000), "expand(v:val)") +
|
||||
\ ["-i", ".", "errors"]
|
||||
|
||||
" Vim async.
|
||||
if go#util#has_job()
|
||||
if get(g:, 'go_echo_command_info', 1)
|
||||
call go#util#EchoProgress("building dispatched ...")
|
||||
@ -31,50 +28,52 @@ function! go#cmd#Build(bang, ...) abort
|
||||
call s:cmd_job({
|
||||
\ 'cmd': ['go'] + args,
|
||||
\ 'bang': a:bang,
|
||||
\ 'for': 'GoBuild',
|
||||
\})
|
||||
return
|
||||
|
||||
" Nvim async.
|
||||
elseif has('nvim')
|
||||
if get(g:, 'go_echo_command_info', 1)
|
||||
call go#util#EchoProgress("building dispatched ...")
|
||||
endif
|
||||
|
||||
" if we have nvim, call it asynchronously and return early ;)
|
||||
call go#jobcontrol#Spawn(a:bang, "build", args)
|
||||
return
|
||||
endif
|
||||
call go#jobcontrol#Spawn(a:bang, "build", "GoBuild", args)
|
||||
|
||||
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 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) && !a:bang
|
||||
call go#list#JumpToFirst(l:listtype)
|
||||
" Vim 7.4 without async
|
||||
else
|
||||
call go#util#EchoSuccess("[build] SUCCESS")
|
||||
endif
|
||||
let old_gopath = $GOPATH
|
||||
let $GOPATH = go#path#Detect()
|
||||
let default_makeprg = &makeprg
|
||||
let &makeprg = "go " . join(go#util#Shelllist(args), ' ')
|
||||
|
||||
let &makeprg = default_makeprg
|
||||
let $GOPATH = old_gopath
|
||||
let l:listtype = go#list#Type("GoBuild")
|
||||
" 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 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) && !a:bang
|
||||
call go#list#JumpToFirst(l:listtype)
|
||||
else
|
||||
call go#util#EchoSuccess("[build] SUCCESS")
|
||||
endif
|
||||
|
||||
let &makeprg = default_makeprg
|
||||
let $GOPATH = old_gopath
|
||||
endif
|
||||
endfunction
|
||||
|
||||
|
||||
@ -149,7 +148,7 @@ function! go#cmd#Run(bang, ...) abort
|
||||
let &makeprg = "go run " . go#util#Shelljoin(map(copy(a:000), "expand(v:val)"), 1)
|
||||
endif
|
||||
|
||||
let l:listtype = go#list#Type("quickfix")
|
||||
let l:listtype = go#list#Type("GoRun")
|
||||
|
||||
if l:listtype == "locationlist"
|
||||
exe 'lmake!'
|
||||
@ -186,6 +185,7 @@ function! go#cmd#Install(bang, ...) abort
|
||||
call s:cmd_job({
|
||||
\ 'cmd': ['go', 'install'] + goargs,
|
||||
\ 'bang': a:bang,
|
||||
\ 'for': 'GoInstall',
|
||||
\})
|
||||
return
|
||||
endif
|
||||
@ -198,7 +198,7 @@ function! go#cmd#Install(bang, ...) abort
|
||||
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")
|
||||
let l:listtype = go#list#Type("GoInstall")
|
||||
" execute make inside the source folder so we can parse the errors
|
||||
" correctly
|
||||
let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd ' : 'cd '
|
||||
@ -243,7 +243,7 @@ function! go#cmd#Generate(bang, ...) abort
|
||||
let &makeprg = "go generate " . goargs . ' ' . gofiles
|
||||
endif
|
||||
|
||||
let l:listtype = go#list#Type("quickfix")
|
||||
let l:listtype = go#list#Type("GoGenerate")
|
||||
|
||||
echon "vim-go: " | echohl Identifier | echon "generating ..."| echohl None
|
||||
if l:listtype == "locationlist"
|
||||
|
@ -53,6 +53,7 @@ function! go#coverage#Buffer(bang, ...) abort
|
||||
\ 'cmd': ['go', 'test', '-coverprofile', l:tmpname] + a:000,
|
||||
\ 'custom_cb': function('s:coverage_callback', [l:tmpname]),
|
||||
\ 'bang': a:bang,
|
||||
\ 'for': 'GoTest',
|
||||
\ })
|
||||
return
|
||||
endif
|
||||
@ -94,9 +95,9 @@ function! go#coverage#Clear() abort
|
||||
if exists("s:toggle") | let s:toggle = 0 | endif
|
||||
|
||||
" remove the autocmd we defined
|
||||
if exists("#BufWinLeave#<buffer>")
|
||||
autocmd! BufWinLeave <buffer>
|
||||
endif
|
||||
augroup vim-go-coverage
|
||||
autocmd!
|
||||
augroup end
|
||||
endfunction
|
||||
|
||||
" Browser creates a new cover profile with 'go test -coverprofile' and opens
|
||||
@ -108,6 +109,7 @@ function! go#coverage#Browser(bang, ...) abort
|
||||
\ 'cmd': ['go', 'test', '-coverprofile', l:tmpname],
|
||||
\ 'custom_cb': function('s:coverage_browser_callback', [l:tmpname]),
|
||||
\ 'bang': a:bang,
|
||||
\ 'for': 'GoTest',
|
||||
\ })
|
||||
return
|
||||
endif
|
||||
@ -256,7 +258,10 @@ function! go#coverage#overlay(file) abort
|
||||
endfor
|
||||
|
||||
" clear the matches if we leave the buffer
|
||||
autocmd BufWinLeave <buffer> call go#coverage#Clear()
|
||||
augroup vim-go-coverage
|
||||
autocmd!
|
||||
autocmd BufWinLeave <buffer> call go#coverage#Clear()
|
||||
augroup end
|
||||
|
||||
for m in matches
|
||||
call matchaddpos(m.group, m.pos)
|
||||
|
@ -168,7 +168,7 @@ function! go#def#jump_to_declaration(out, mode, bin_name) abort
|
||||
endif
|
||||
|
||||
" open the file and jump to line and column
|
||||
exec cmd fnameescape(filename)
|
||||
exec cmd fnameescape(fnamemodify(filename, ':.'))
|
||||
endif
|
||||
endif
|
||||
call cursor(line, col)
|
||||
|
@ -1,32 +1,37 @@
|
||||
func Test_jump_to_declaration_guru()
|
||||
let file_name = "test-fixtures/def/jump.go"
|
||||
let lnum = 5
|
||||
let col = 6
|
||||
func! Test_jump_to_declaration_guru() abort
|
||||
try
|
||||
let l:filename = 'def/jump.go'
|
||||
let lnum = 5
|
||||
let col = 6
|
||||
let l:tmp = gotest#load_fixture(l:filename)
|
||||
|
||||
let out = printf("%s:%d:%d: defined here as func main", file_name, lnum, col)
|
||||
let bin_name = "guru"
|
||||
let guru_out = printf("%s:%d:%d: defined here as func main", filename, lnum, col)
|
||||
call go#def#jump_to_declaration(guru_out, "", 'guru')
|
||||
|
||||
call go#def#jump_to_declaration(out, "", bin_name)
|
||||
|
||||
call assert_equal(file_name, bufname("%"))
|
||||
call assert_equal(lnum, getcurpos()[1])
|
||||
call assert_equal(col, getcurpos()[2])
|
||||
call assert_equal(filename, bufname("%"))
|
||||
call assert_equal(lnum, getcurpos()[1])
|
||||
call assert_equal(col, getcurpos()[2])
|
||||
finally
|
||||
call delete(l:tmp, 'rf')
|
||||
endtry
|
||||
endfunc
|
||||
|
||||
func Test_jump_to_declaration_godef()
|
||||
let file_name = "test-fixtures/def/jump.go"
|
||||
let lnum = 5
|
||||
let col = 6
|
||||
func! Test_jump_to_declaration_godef() abort
|
||||
try
|
||||
let filename = 'def/jump.go'
|
||||
let lnum = 5
|
||||
let col = 6
|
||||
let l:tmp = gotest#load_fixture(l:filename)
|
||||
|
||||
" note that the output of godef has two lines
|
||||
let out = printf("%s:%d:%d\ndefined here as func main", file_name, lnum, col)
|
||||
let bin_name = "godef"
|
||||
let godef_out = printf("%s:%d:%d\ndefined here as func main", filename, lnum, col)
|
||||
call go#def#jump_to_declaration(godef_out, "", 'godef')
|
||||
|
||||
call go#def#jump_to_declaration(out, "", bin_name)
|
||||
|
||||
call assert_equal(file_name, bufname("%"))
|
||||
call assert_equal(lnum, getcurpos()[1])
|
||||
call assert_equal(col, getcurpos()[2])
|
||||
call assert_equal(filename, bufname("%"))
|
||||
call assert_equal(lnum, getcurpos()[1])
|
||||
call assert_equal(col, getcurpos()[2])
|
||||
finally
|
||||
call delete(l:tmp, 'rf')
|
||||
endtry
|
||||
endfunc
|
||||
|
||||
" vim: sw=2 ts=2 et
|
||||
|
@ -5,11 +5,7 @@
|
||||
let s:buf_nr = -1
|
||||
|
||||
if !exists("g:go_doc_command")
|
||||
let g:go_doc_command = "godoc"
|
||||
endif
|
||||
|
||||
if !exists("g:go_doc_options")
|
||||
let g:go_doc_options = ""
|
||||
let g:go_doc_command = ["godoc"]
|
||||
endif
|
||||
|
||||
function! go#doc#OpenBrowser(...) abort
|
||||
@ -60,12 +56,11 @@ endfunction
|
||||
function! go#doc#Open(newmode, mode, ...) abort
|
||||
" With argument: run "godoc [arg]".
|
||||
if len(a:000)
|
||||
let bin_path = go#path#CheckBinPath('godoc')
|
||||
if empty(bin_path)
|
||||
if empty(go#path#CheckBinPath(g:go_doc_command[0]))
|
||||
return
|
||||
endif
|
||||
|
||||
let command = printf("%s %s", go#util#Shellescape(bin_path), join(a:000, ' '))
|
||||
let command = printf("%s %s", go#util#Shelljoin(g:go_doc_command), join(a:000, ' '))
|
||||
let out = go#util#System(command)
|
||||
" Without argument: run gogetdoc on cursor position.
|
||||
else
|
||||
@ -85,6 +80,7 @@ endfunction
|
||||
|
||||
function! s:GodocView(newposition, position, content) abort
|
||||
" reuse existing buffer window if it exists otherwise create a new one
|
||||
let is_visible = bufexists(s:buf_nr) && bufwinnr(s:buf_nr) != -1
|
||||
if !bufexists(s:buf_nr)
|
||||
execute a:newposition
|
||||
sil file `="[Godoc]"`
|
||||
@ -96,20 +92,23 @@ function! s:GodocView(newposition, position, content) abort
|
||||
execute bufwinnr(s:buf_nr) . 'wincmd w'
|
||||
endif
|
||||
|
||||
if a:position == "split"
|
||||
" cap window height to 20, but resize it for smaller contents
|
||||
let max_height = get(g:, "go_doc_max_height", 20)
|
||||
let content_height = len(split(a:content, "\n"))
|
||||
if content_height > max_height
|
||||
exe 'resize ' . max_height
|
||||
" if window was not visible then resize it
|
||||
if !is_visible
|
||||
if a:position == "split"
|
||||
" cap window height to 20, but resize it for smaller contents
|
||||
let max_height = get(g:, "go_doc_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
|
||||
else
|
||||
exe 'resize ' . content_height
|
||||
" set a sane maximum width for vertical splits. In this case the minimum
|
||||
" that fits the godoc for package http without extra linebreaks and line
|
||||
" numbers on
|
||||
exe 'vertical resize 84'
|
||||
endif
|
||||
else
|
||||
" set a sane maximum width for vertical splits. In this case the minimum
|
||||
" that fits the godoc for package http without extra linebreaks and line
|
||||
" numbers on
|
||||
exe 'vertical resize 84'
|
||||
endif
|
||||
|
||||
setlocal filetype=godoc
|
||||
@ -155,18 +154,8 @@ function! s:gogetdoc(json) abort
|
||||
let command = join(cmd, " ")
|
||||
|
||||
if &modified
|
||||
" gogetdoc supports the same archive format as guru for dealing with
|
||||
" modified buffers.
|
||||
" use the -modified flag
|
||||
" write each archive entry on stdin as:
|
||||
" filename followed by newline
|
||||
" file size followed by newline
|
||||
" file contents
|
||||
let in = ""
|
||||
let content = join(go#util#GetLines(), "\n")
|
||||
let in = fname . "\n" . strlen(content) . "\n" . content
|
||||
let command .= " -modified"
|
||||
let out = go#util#System(command, in)
|
||||
let out = go#util#System(command, go#util#archive())
|
||||
else
|
||||
let out = go#util#System(command)
|
||||
endif
|
||||
|
@ -127,17 +127,23 @@ function! go#fmt#update_file(source, target)
|
||||
let &fileformat = old_fileformat
|
||||
let &syntax = &syntax
|
||||
|
||||
let l:listtype = go#list#Type("GoFmt")
|
||||
|
||||
" the title information was introduced with 7.4-2200
|
||||
" https://github.com/vim/vim/commit/d823fa910cca43fec3c31c030ee908a14c272640
|
||||
if !has('patch-7.4-2200')
|
||||
return
|
||||
if has('patch-7.4.2200')
|
||||
" clean up previous list
|
||||
if l:listtype == "quickfix"
|
||||
let l:list_title = getqflist({'title': 1})
|
||||
else
|
||||
let l:list_title = getloclist(0, {'title': 1})
|
||||
endif
|
||||
else
|
||||
" can't check the title, so assume that the list was for go fmt.
|
||||
let l:list_title = {'title': 'Format'}
|
||||
endif
|
||||
|
||||
" clean up previous location list
|
||||
let l:list_title = getqflist({'title': 1})
|
||||
if has_key(l:list_title, "title") && l:list_title['title'] == "Format"
|
||||
let l:listtype = go#list#Type("quickfix")
|
||||
call go#list#Clean(l:listtype)
|
||||
call go#list#Window(l:listtype)
|
||||
endif
|
||||
@ -245,7 +251,7 @@ endfunction
|
||||
" show_errors opens a location list and shows the given errors. If the given
|
||||
" errors is empty, it closes the the location list
|
||||
function! s:show_errors(errors) abort
|
||||
let l:listtype = go#list#Type("quickfix")
|
||||
let l:listtype = go#list#Type("GoFmt")
|
||||
if !empty(a:errors)
|
||||
call go#list#Populate(l:listtype, a:errors, 'Format')
|
||||
echohl Error | echomsg "Gofmt returned error" | echohl None
|
||||
|
@ -1,4 +1,4 @@
|
||||
func Test_run_fmt()
|
||||
func! Test_run_fmt() abort
|
||||
let actual_file = tempname()
|
||||
call writefile(readfile("test-fixtures/fmt/hello.go"), actual_file)
|
||||
|
||||
@ -13,7 +13,7 @@ func Test_run_fmt()
|
||||
call assert_equal(expected, actual)
|
||||
endfunc
|
||||
|
||||
func Test_update_file()
|
||||
func! Test_update_file() abort
|
||||
let expected = join(readfile("test-fixtures/fmt/hello_golden.go"), "\n")
|
||||
let source_file = tempname()
|
||||
call writefile(readfile("test-fixtures/fmt/hello_golden.go"), source_file)
|
||||
@ -30,7 +30,7 @@ func Test_update_file()
|
||||
call assert_equal(expected, actual)
|
||||
endfunc
|
||||
|
||||
func Test_goimports()
|
||||
func! Test_goimports() abort
|
||||
let $GOPATH = 'test-fixtures/fmt/'
|
||||
let actual_file = tempname()
|
||||
call writefile(readfile("test-fixtures/fmt/src/imports/goimports.go"), actual_file)
|
||||
@ -45,3 +45,5 @@ func Test_goimports()
|
||||
|
||||
call assert_equal(expected, actual)
|
||||
endfunc
|
||||
|
||||
" vim: sw=2 ts=2 et
|
||||
|
@ -34,8 +34,7 @@ function! s:guru_cmd(args) range abort
|
||||
|
||||
let filename = fnamemodify(expand("%"), ':p:gs?\\?/?')
|
||||
if &modified
|
||||
let content = join(go#util#GetLines(), "\n")
|
||||
let result.stdin_content = filename . "\n" . strlen(content) . "\n" . content
|
||||
let result.stdin_content = go#util#archive()
|
||||
call add(cmd, "-modified")
|
||||
endif
|
||||
|
||||
@ -112,7 +111,8 @@ function! s:sync_guru(args) abort
|
||||
|
||||
if !has_key(a:args, 'disable_progress')
|
||||
if a:args.needs_scope
|
||||
call go#util#EchoProgress("analysing with scope ". result.scope . " ...")
|
||||
call go#util#EchoProgress("analysing with scope ". result.scope .
|
||||
\ " (see ':help go-guru-scope' if this doesn't work)...")
|
||||
elseif a:args.mode !=# 'what'
|
||||
" the query might take time, let us give some feedback
|
||||
call go#util#EchoProgress("analysing ...")
|
||||
@ -150,7 +150,8 @@ function! s:async_guru(args) abort
|
||||
|
||||
if !has_key(a:args, 'disable_progress')
|
||||
if a:args.needs_scope
|
||||
call go#util#EchoProgress("analysing with scope ". result.scope . " ...")
|
||||
call go#util#EchoProgress("analysing with scope " . result.scope .
|
||||
\ " (see ':help go-guru-scope' if this doesn't work)...")
|
||||
endif
|
||||
endif
|
||||
|
||||
@ -159,9 +160,10 @@ function! s:async_guru(args) abort
|
||||
call add(messages, a:msg)
|
||||
endfunction
|
||||
|
||||
function! s:exit_cb(job, exitval) closure
|
||||
let out = join(messages, "\n")
|
||||
let status = {}
|
||||
let exitval = 0
|
||||
|
||||
function! s:exit_cb(job, exitval) closure
|
||||
let status = {
|
||||
\ 'desc': 'last status',
|
||||
\ 'type': statusline_type,
|
||||
@ -169,21 +171,27 @@ function! s:async_guru(args) abort
|
||||
\ }
|
||||
|
||||
if a:exitval
|
||||
let exitval = a:exitval
|
||||
let status.state = "failed"
|
||||
endif
|
||||
|
||||
call go#statusline#Update(status_dir, status)
|
||||
endfunction
|
||||
|
||||
function! s:close_cb(ch) closure
|
||||
let out = join(messages, "\n")
|
||||
|
||||
if has_key(a:args, 'custom_parse')
|
||||
call a:args.custom_parse(a:exitval, out)
|
||||
call a:args.custom_parse(exitval, out)
|
||||
else
|
||||
call s:parse_guru_output(a:exitval, out, a:args.mode)
|
||||
call s:parse_guru_output(exitval, out, a:args.mode)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
let start_options = {
|
||||
\ 'callback': funcref("s:callback"),
|
||||
\ 'exit_cb': funcref("s:exit_cb"),
|
||||
\ 'close_cb': funcref("s:close_cb"),
|
||||
\ }
|
||||
|
||||
if has_key(result, 'stdin_content')
|
||||
@ -521,28 +529,40 @@ function! s:same_ids_highlight(exit_val, output) abort
|
||||
if get(g:, "go_auto_sameids", 0)
|
||||
" re-apply SameIds at the current cursor position at the time the buffer
|
||||
" is redisplayed: e.g. :edit, :GoRename, etc.
|
||||
autocmd BufWinEnter <buffer> nested call go#guru#SameIds()
|
||||
augroup vim-go-sameids
|
||||
autocmd!
|
||||
autocmd BufWinEnter <buffer> nested call go#guru#SameIds()
|
||||
augroup end
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" ClearSameIds returns 0 when it removes goSameId groups and non-zero if no
|
||||
" goSameId groups are found.
|
||||
function! go#guru#ClearSameIds() abort
|
||||
let l:cleared = 0
|
||||
|
||||
let m = getmatches()
|
||||
for item in m
|
||||
if item['group'] == 'goSameId'
|
||||
call matchdelete(item['id'])
|
||||
let l:cleared = 1
|
||||
endif
|
||||
endfor
|
||||
|
||||
" remove the autocmds we defined
|
||||
if exists("#BufWinEnter#<buffer>")
|
||||
autocmd! BufWinEnter <buffer>
|
||||
if !l:cleared
|
||||
return 1
|
||||
endif
|
||||
|
||||
" remove the autocmds we defined
|
||||
augroup vim-go-sameids
|
||||
autocmd!
|
||||
augroup end
|
||||
|
||||
return 0
|
||||
endfunction
|
||||
|
||||
function! go#guru#ToggleSameIds() abort
|
||||
if len(getmatches()) != 0
|
||||
call go#guru#ClearSameIds()
|
||||
else
|
||||
if go#guru#ClearSameIds() != 0
|
||||
call go#guru#SameIds()
|
||||
endif
|
||||
endfunction
|
||||
@ -583,11 +603,12 @@ function! s:parse_guru_output(exit_val, output, title) abort
|
||||
|
||||
let old_errorformat = &errorformat
|
||||
let errformat = "%f:%l.%c-%[%^:]%#:\ %m,%f:%l:%c:\ %m"
|
||||
call go#list#ParseFormat("locationlist", errformat, a:output, a:title)
|
||||
let l:listtype = go#list#Type("_guru")
|
||||
call go#list#ParseFormat(l:listtype, errformat, a:output, a:title)
|
||||
let &errorformat = old_errorformat
|
||||
|
||||
let errors = go#list#Get("locationlist")
|
||||
call go#list#Window("locationlist", len(errors))
|
||||
let errors = go#list#Get(l:listtype)
|
||||
call go#list#Window(l:listtype, len(errors))
|
||||
endfun
|
||||
|
||||
function! go#guru#Scope(...) abort
|
||||
|
@ -6,11 +6,13 @@ function! go#impl#Impl(...) abort
|
||||
|
||||
let recv = ""
|
||||
let iface = ""
|
||||
let interactive = 0
|
||||
|
||||
let pos = getpos('.')
|
||||
|
||||
if a:0 == 0
|
||||
" user didn't passed anything, just called ':GoImpl'
|
||||
let receiveType = expand("<cword>")
|
||||
let recv = printf("%s *%s", tolower(receiveType)[0], receiveType)
|
||||
" Interactive mode if user didn't pass any arguments.
|
||||
let recv = s:getReceiver()
|
||||
let iface = input("vim-go: generating method stubs for interface: ")
|
||||
redraw!
|
||||
if empty(iface)
|
||||
@ -20,8 +22,7 @@ function! go#impl#Impl(...) abort
|
||||
elseif a:0 == 1
|
||||
" we assume the user only passed the interface type,
|
||||
" i.e: ':GoImpl io.Writer'
|
||||
let receiveType = expand("<cword>")
|
||||
let recv = printf("%s *%s", tolower(receiveType)[0], receiveType)
|
||||
let recv = s:getReceiver()
|
||||
let iface = a:1
|
||||
elseif a:0 > 2
|
||||
" user passed receiver and interface type both,
|
||||
@ -33,20 +34,41 @@ function! go#impl#Impl(...) abort
|
||||
return
|
||||
endif
|
||||
|
||||
let result = go#util#System(join(go#util#Shelllist([binpath, recv, iface], ' ')))
|
||||
if go#util#ShellError() != 0
|
||||
call go#util#EchoError(result)
|
||||
return
|
||||
" Make sure we put the generated code *after* the struct.
|
||||
if getline(".") =~ "struct "
|
||||
normal! $%
|
||||
endif
|
||||
|
||||
if result ==# ''
|
||||
return
|
||||
end
|
||||
try
|
||||
let dirname = fnameescape(expand('%:p:h'))
|
||||
let result = go#util#System(join(go#util#Shelllist([binpath, '-dir', dirname, recv, iface], ' ')))
|
||||
let result = substitute(result, "\n*$", "", "")
|
||||
if go#util#ShellError() != 0
|
||||
call go#util#EchoError(result)
|
||||
return
|
||||
endif
|
||||
|
||||
let pos = getpos('.')
|
||||
put =''
|
||||
put =result
|
||||
call setpos('.', pos)
|
||||
if result ==# ''
|
||||
return
|
||||
end
|
||||
|
||||
put =''
|
||||
put =result
|
||||
finally
|
||||
call setpos('.', pos)
|
||||
endtry
|
||||
endfunction
|
||||
|
||||
function! s:getReceiver()
|
||||
let receiveType = expand("<cword>")
|
||||
if receiveType == "type"
|
||||
normal! w
|
||||
let receiveType = expand("<cword>")
|
||||
elseif receiveType == "struct"
|
||||
normal! ge
|
||||
let receiveType = expand("<cword>")
|
||||
endif
|
||||
return printf("%s *%s", tolower(receiveType)[0], receiveType)
|
||||
endfunction
|
||||
|
||||
if exists('*uniq')
|
||||
|
@ -10,12 +10,17 @@ function go#job#Spawn(args)
|
||||
\ 'messages': [],
|
||||
\ 'args': a:args.cmd,
|
||||
\ 'bang': 0,
|
||||
\ 'for': "_job",
|
||||
\ }
|
||||
|
||||
if has_key(a:args, 'bang')
|
||||
let cbs.bang = a:args.bang
|
||||
endif
|
||||
|
||||
if has_key(a:args, 'for')
|
||||
let cbs.for = a:args.for
|
||||
endif
|
||||
|
||||
" add final callback to be called if async job is finished
|
||||
" The signature should be in form: func(job, exit_status, messages)
|
||||
if has_key(a:args, 'custom_cb')
|
||||
@ -47,7 +52,7 @@ function go#job#Spawn(args)
|
||||
call self.custom_cb(a:job, a:exitval, self.messages)
|
||||
endif
|
||||
|
||||
let l:listtype = go#list#Type("quickfix")
|
||||
let l:listtype = go#list#Type(self.for)
|
||||
if a:exitval == 0
|
||||
call go#list#Clean(l:listtype)
|
||||
call go#list#Window(l:listtype)
|
||||
@ -69,8 +74,7 @@ function go#job#Spawn(args)
|
||||
|
||||
if !len(errors)
|
||||
" failed to parse errors, output the original content
|
||||
call go#util#EchoError(join(self.messages, " "))
|
||||
call go#util#EchoError(self.dir)
|
||||
call go#util#EchoError(self.messages + [self.dir])
|
||||
return
|
||||
endif
|
||||
|
||||
|
@ -9,11 +9,11 @@ let s:handlers = {}
|
||||
" Spawn is a wrapper around s:spawn. It can be executed by other files and
|
||||
" scripts if needed. Desc defines the description for printing the status
|
||||
" during the job execution (useful for statusline integration).
|
||||
function! go#jobcontrol#Spawn(bang, desc, args) abort
|
||||
function! go#jobcontrol#Spawn(bang, desc, for, args) abort
|
||||
" autowrite is not enabled for jobs
|
||||
call go#cmd#autowrite()
|
||||
|
||||
let job = s:spawn(a:bang, a:desc, a:args)
|
||||
let job = s:spawn(a:bang, a:desc, a:for, a:args)
|
||||
return job.id
|
||||
endfunction
|
||||
|
||||
@ -37,7 +37,7 @@ endfunction
|
||||
" a job is started a reference will be stored inside s:jobs. spawn changes the
|
||||
" GOPATH when g:go_autodetect_gopath is enabled. The job is started inside the
|
||||
" current files folder.
|
||||
function! s:spawn(bang, desc, args) abort
|
||||
function! s:spawn(bang, desc, for, args) abort
|
||||
let status_type = a:args[0]
|
||||
let status_dir = expand('%:p:h')
|
||||
let started_at = reltime()
|
||||
@ -62,6 +62,7 @@ function! s:spawn(bang, desc, args) abort
|
||||
\ 'status_type' : status_type,
|
||||
\ 'status_dir' : status_dir,
|
||||
\ 'started_at' : started_at,
|
||||
\ 'for' : a:for,
|
||||
\ }
|
||||
|
||||
" modify GOPATH if needed
|
||||
@ -129,7 +130,7 @@ function! s:on_exit(job_id, exit_status, event) dict abort
|
||||
|
||||
call s:callback_handlers_on_exit(s:jobs[a:job_id], a:exit_status, std_combined)
|
||||
|
||||
let l:listtype = go#list#Type("quickfix")
|
||||
let l:listtype = go#list#Type(self.for)
|
||||
if a:exit_status == 0
|
||||
call go#list#Clean(l:listtype)
|
||||
call go#list#Window(l:listtype)
|
||||
|
@ -57,3 +57,5 @@ endfunction
|
||||
function! s:chomp(string)
|
||||
return substitute(a:string, '\n\+$', '', '')
|
||||
endfunction
|
||||
|
||||
" vim: sw=2 ts=2 et
|
||||
|
@ -48,6 +48,13 @@ function! go#lint#Gometa(autosave, ...) abort
|
||||
let cmd += ["--exclude=".exclude]
|
||||
endfor
|
||||
|
||||
" gometalinter has a --tests flag to tell its linters whether to run
|
||||
" against tests. While not all of its linters respect this flag, for those
|
||||
" that do, it means if we don't pass --tests, the linter won't run against
|
||||
" test files. One example of a linter that will not run against tests if
|
||||
" we do not specify this flag is errcheck.
|
||||
let cmd += ["--tests"]
|
||||
|
||||
" path
|
||||
let cmd += [expand('%:p:h')]
|
||||
else
|
||||
@ -60,7 +67,7 @@ function! go#lint#Gometa(autosave, ...) abort
|
||||
" For async mode (s:lint_job), we want to override the default deadline only
|
||||
" if we have a deadline configured.
|
||||
"
|
||||
" For sync mode (go#tool#ExecuteInDir), always explicitly pass the 5 seconds
|
||||
" For sync mode (go#util#System), always explicitly pass the 5 seconds
|
||||
" deadline if there is no other deadline configured. If a deadline is
|
||||
" configured, then use it.
|
||||
|
||||
@ -87,9 +94,9 @@ function! go#lint#Gometa(autosave, ...) abort
|
||||
|
||||
let meta_command = join(cmd, " ")
|
||||
|
||||
let out = go#tool#ExecuteInDir(meta_command)
|
||||
let out = go#util#System(meta_command)
|
||||
|
||||
let l:listtype = "quickfix"
|
||||
let l:listtype = go#list#Type("GoMetaLinter")
|
||||
if go#util#ShellError() == 0
|
||||
redraw | echo
|
||||
call go#list#Clean(l:listtype)
|
||||
@ -134,7 +141,7 @@ function! go#lint#Golint(...) abort
|
||||
return
|
||||
endif
|
||||
|
||||
let l:listtype = "quickfix"
|
||||
let l:listtype = go#list#Type("GoLint")
|
||||
call go#list#Parse(l:listtype, out)
|
||||
let errors = go#list#Get(l:listtype)
|
||||
call go#list#Window(l:listtype, len(errors))
|
||||
@ -152,7 +159,7 @@ function! go#lint#Vet(bang, ...) abort
|
||||
let out = go#util#System('go tool vet ' . go#util#Shelljoin(a:000))
|
||||
endif
|
||||
|
||||
let l:listtype = "quickfix"
|
||||
let l:listtype = go#list#Type("GoVet")
|
||||
if go#util#ShellError() != 0
|
||||
let errors = go#tool#ParseErrors(split(out, '\n'))
|
||||
call go#list#Populate(l:listtype, errors, 'Vet')
|
||||
@ -192,7 +199,7 @@ function! go#lint#Errcheck(...) abort
|
||||
let command = go#util#Shellescape(bin_path) . ' -abspath ' . import_path
|
||||
let out = go#tool#ExecuteInDir(command)
|
||||
|
||||
let l:listtype = "quickfix"
|
||||
let l:listtype = go#list#Type("GoErrCheck")
|
||||
if go#util#ShellError() != 0
|
||||
let errformat = "%f:%l:%c:\ %m, %f:%l:%c\ %#%m"
|
||||
|
||||
@ -246,7 +253,7 @@ function s:lint_job(args)
|
||||
" autowrite is not enabled for jobs
|
||||
call go#cmd#autowrite()
|
||||
|
||||
let l:listtype = go#list#Type("quickfix")
|
||||
let l:listtype = go#list#Type("GoMetaLinter")
|
||||
let l:errformat = '%f:%l:%c:%t%*[^:]:\ %m,%f:%l::%t%*[^:]:\ %m'
|
||||
|
||||
function! s:callback(chan, msg) closure
|
||||
|
@ -2,13 +2,16 @@ if !exists("g:go_list_type")
|
||||
let g:go_list_type = ""
|
||||
endif
|
||||
|
||||
if !exists("g:go_list_type_commands")
|
||||
let g:go_list_type_commands = {}
|
||||
endif
|
||||
|
||||
" Window opens the list with the given height up to 10 lines maximum.
|
||||
" Otherwise g:go_loclist_height is used.
|
||||
" Otherwise g:go_loclist_height is used.
|
||||
"
|
||||
" If no or zero height is given it closes the window by default.
|
||||
" If no or zero height is given it closes the window by default.
|
||||
" To prevent this, set g:go_list_autoclose = 0
|
||||
function! go#list#Window(listtype, ...) abort
|
||||
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
|
||||
@ -17,7 +20,7 @@ function! go#list#Window(listtype, ...) abort
|
||||
if !a:0 || a:1 == 0
|
||||
let autoclose_window = get(g:, 'go_list_autoclose', 1)
|
||||
if autoclose_window
|
||||
if l:listtype == "locationlist"
|
||||
if a:listtype == "locationlist"
|
||||
lclose
|
||||
else
|
||||
cclose
|
||||
@ -36,7 +39,7 @@ function! go#list#Window(listtype, ...) abort
|
||||
endif
|
||||
endif
|
||||
|
||||
if l:listtype == "locationlist"
|
||||
if a:listtype == "locationlist"
|
||||
exe 'lopen ' . height
|
||||
else
|
||||
exe 'copen ' . height
|
||||
@ -44,20 +47,18 @@ function! go#list#Window(listtype, ...) abort
|
||||
endfunction
|
||||
|
||||
|
||||
" Get returns the current list of items from the location list
|
||||
" Get returns the current items from the list
|
||||
function! go#list#Get(listtype) abort
|
||||
let l:listtype = go#list#Type(a:listtype)
|
||||
if l:listtype == "locationlist"
|
||||
if a:listtype == "locationlist"
|
||||
return getloclist(0)
|
||||
else
|
||||
return getqflist()
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" Populate populate the location list with the given items
|
||||
" Populate populate the list with the given items
|
||||
function! go#list#Populate(listtype, items, title) abort
|
||||
let l:listtype = go#list#Type(a:listtype)
|
||||
if l:listtype == "locationlist"
|
||||
if a:listtype == "locationlist"
|
||||
call setloclist(0, a:items, 'r')
|
||||
|
||||
" The last argument ({what}) is introduced with 7.4.2200:
|
||||
@ -69,20 +70,15 @@ function! go#list#Populate(listtype, items, title) abort
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! go#list#PopulateWin(winnr, items) abort
|
||||
call setloclist(a:winnr, a:items, 'r')
|
||||
endfunction
|
||||
|
||||
" Parse parses the given items based on the specified errorformat and
|
||||
" populates the location list.
|
||||
" populates the list.
|
||||
function! go#list#ParseFormat(listtype, errformat, items, title) abort
|
||||
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"
|
||||
if a:listtype == "locationlist"
|
||||
lgetexpr a:items
|
||||
if has("patch-7.4.2200") | call setloclist(0, [], 'a', {'title': a:title}) | endif
|
||||
else
|
||||
@ -95,10 +91,9 @@ function! go#list#ParseFormat(listtype, errformat, items, title) abort
|
||||
endfunction
|
||||
|
||||
" Parse parses the given items based on the global errorformat and
|
||||
" populates the location list.
|
||||
" populates the list.
|
||||
function! go#list#Parse(listtype, items) abort
|
||||
let l:listtype = go#list#Type(a:listtype)
|
||||
if l:listtype == "locationlist"
|
||||
if a:listtype == "locationlist"
|
||||
lgetexpr a:items
|
||||
else
|
||||
cgetexpr a:items
|
||||
@ -107,8 +102,7 @@ endfunction
|
||||
|
||||
" JumpToFirst jumps to the first item in the location list
|
||||
function! go#list#JumpToFirst(listtype) abort
|
||||
let l:listtype = go#list#Type(a:listtype)
|
||||
if l:listtype == "locationlist"
|
||||
if a:listtype == "locationlist"
|
||||
ll 1
|
||||
else
|
||||
cc 1
|
||||
@ -117,22 +111,57 @@ endfunction
|
||||
|
||||
" Clean cleans the location list
|
||||
function! go#list#Clean(listtype) abort
|
||||
let l:listtype = go#list#Type(a:listtype)
|
||||
if l:listtype == "locationlist"
|
||||
if a:listtype == "locationlist"
|
||||
lex []
|
||||
else
|
||||
cex []
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! go#list#Type(listtype) abort
|
||||
function! s:listtype(listtype) abort
|
||||
if g:go_list_type == "locationlist"
|
||||
return "locationlist"
|
||||
elseif g:go_list_type == "quickfix"
|
||||
return "quickfix"
|
||||
else
|
||||
return a:listtype
|
||||
endif
|
||||
|
||||
return a:listtype
|
||||
endfunction
|
||||
|
||||
" s:default_list_type_commands is the defaults that will be used for each of
|
||||
" the supported commands (see documentation for g:go_list_type_commands). When
|
||||
" defining a default, quickfix should be used if the command operates on
|
||||
" multiple files, while locationlist should be used if the command operates on a
|
||||
" single file or buffer. Keys that begin with an underscore are not supported
|
||||
" in g:go_list_type_commands.
|
||||
let s:default_list_type_commands = {
|
||||
\ "GoBuild": "quickfix",
|
||||
\ "GoErrCheck": "quickfix",
|
||||
\ "GoFmt": "locationlist",
|
||||
\ "GoGenerate": "quickfix",
|
||||
\ "GoInstall": "quickfix",
|
||||
\ "GoLint": "quickfix",
|
||||
\ "GoMetaLinter": "quickfix",
|
||||
\ "GoModifyTags": "locationlist",
|
||||
\ "GoRename": "quickfix",
|
||||
\ "GoRun": "quickfix",
|
||||
\ "GoTest": "quickfix",
|
||||
\ "GoVet": "quickfix",
|
||||
\ "_guru": "locationlist",
|
||||
\ "_term": "locationlist",
|
||||
\ "_job": "locationlist",
|
||||
\ }
|
||||
|
||||
function! go#list#Type(for) abort
|
||||
let l:listtype = s:listtype(get(s:default_list_type_commands, a:for))
|
||||
if l:listtype == "0"
|
||||
call go#util#EchoError(printf(
|
||||
\ "unknown list type command value found ('%s'). Please open a bug report in the vim-go repo.",
|
||||
\ a:for))
|
||||
let l:listtype = "quickfix"
|
||||
endif
|
||||
|
||||
return get(g:go_list_type_commands, a:for, l:listtype)
|
||||
endfunction
|
||||
|
||||
" vim: sw=2 ts=2 et
|
||||
|
@ -80,6 +80,7 @@ function! go#package#FromPath(arg) abort
|
||||
for dir in dirs
|
||||
if len(dir) && match(path, dir) == 0
|
||||
let workspace = dir
|
||||
break
|
||||
endif
|
||||
endfor
|
||||
|
||||
@ -87,10 +88,12 @@ function! go#package#FromPath(arg) abort
|
||||
return -1
|
||||
endif
|
||||
|
||||
let path = substitute(path, '/*$', '', '')
|
||||
let workspace = substitute(workspace . '/src/', '/+', '', '')
|
||||
if isdirectory(path)
|
||||
return substitute(path, workspace . 'src/', '', '')
|
||||
return substitute(path, workspace, '', '')
|
||||
else
|
||||
return substitute(substitute(path, workspace . 'src/', '', ''),
|
||||
return substitute(substitute(path, workspace, '', ''),
|
||||
\ '/' . fnamemodify(path, ':t'), '', '')
|
||||
endif
|
||||
endfunction
|
||||
|
@ -73,7 +73,7 @@ function! go#path#Detect() abort
|
||||
let gopath = go#path#Default()
|
||||
|
||||
" don't lookup for godeps if autodetect is disabled.
|
||||
if !get(g:, "go_autodetect_gopath", 1)
|
||||
if !get(g:, "go_autodetect_gopath", 0)
|
||||
return gopath
|
||||
endif
|
||||
|
||||
@ -179,7 +179,6 @@ function! go#path#CheckBinPath(binpath) abort
|
||||
" 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))
|
||||
|
||||
" restore back!
|
||||
|
@ -70,24 +70,4 @@ function! s:get_visual_selection() abort
|
||||
return join(lines, "\n")
|
||||
endfunction
|
||||
|
||||
" following two functions are from: https://github.com/mattn/gist-vim
|
||||
" thanks @mattn
|
||||
function! s:get_browser_command() abort
|
||||
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
|
||||
endif
|
||||
return go_play_browser_command
|
||||
endfunction
|
||||
|
||||
" vim: sw=2 ts=2 et
|
||||
|
@ -2,17 +2,25 @@ if !exists("g:go_gorename_bin")
|
||||
let g:go_gorename_bin = "gorename"
|
||||
endif
|
||||
|
||||
if !exists("g:go_gorename_prefill")
|
||||
let g:go_gorename_prefill = 1
|
||||
endif
|
||||
" Set the default value. A value of "1" is a shortcut for this, for
|
||||
" compatibility reasons.
|
||||
function! s:default() abort
|
||||
if !exists("g:go_gorename_prefill") || g:go_gorename_prefill == 1
|
||||
let g:go_gorename_prefill = 'expand("<cword>") =~# "^[A-Z]"' .
|
||||
\ '? go#util#pascalcase(expand("<cword>"))' .
|
||||
\ ': go#util#camelcase(expand("<cword>"))'
|
||||
endif
|
||||
endfunction
|
||||
call s:default()
|
||||
|
||||
function! go#rename#Rename(bang, ...) abort
|
||||
call s:default()
|
||||
|
||||
let to_identifier = ""
|
||||
if a:0 == 0
|
||||
let from = expand("<cword>")
|
||||
let ask = printf("vim-go: rename '%s' to: ", from)
|
||||
if g:go_gorename_prefill
|
||||
let to_identifier = input(ask, from)
|
||||
let ask = printf("vim-go: rename '%s' to: ", expand("<cword>"))
|
||||
if g:go_gorename_prefill != ''
|
||||
let to_identifier = input(ask, eval(g:go_gorename_prefill))
|
||||
else
|
||||
let to_identifier = input(ask)
|
||||
endif
|
||||
@ -24,7 +32,7 @@ function! go#rename#Rename(bang, ...) abort
|
||||
let to_identifier = a:1
|
||||
endif
|
||||
|
||||
"return with a warning if the bin doesn't exist
|
||||
" 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
|
||||
@ -117,7 +125,7 @@ function s:parse_errors(exit_val, bang, out)
|
||||
silent! checktime
|
||||
let &autoread = current_autoread
|
||||
|
||||
let l:listtype = "quickfix"
|
||||
let l:listtype = go#list#Type("GoRename")
|
||||
if a:exit_val != 0
|
||||
call go#util#EchoError("FAILED")
|
||||
let errors = go#tool#ParseErrors(a:out)
|
||||
@ -127,7 +135,7 @@ function s:parse_errors(exit_val, bang, out)
|
||||
call go#list#JumpToFirst(l:listtype)
|
||||
elseif empty(errors)
|
||||
" failed to parse errors, output the original content
|
||||
call go#util#EchoError(join(a:out, ""))
|
||||
call go#util#EchoError(a:out)
|
||||
endif
|
||||
|
||||
return
|
||||
@ -146,4 +154,13 @@ function s:parse_errors(exit_val, bang, out)
|
||||
silent execute ":e"
|
||||
endfunction
|
||||
|
||||
" Commandline completion: original, unexported camelCase, and exported
|
||||
" CamelCase.
|
||||
function! go#rename#Complete(lead, cmdline, cursor)
|
||||
let l:word = expand('<cword>')
|
||||
return filter(uniq(sort(
|
||||
\ [l:word, go#util#camelcase(l:word), go#util#pascalcase(l:word)])),
|
||||
\ 'strpart(v:val, 0, len(a:lead)) == a:lead')
|
||||
endfunction
|
||||
|
||||
" vim: sw=2 ts=2 et
|
||||
|
@ -95,12 +95,12 @@ func s:write_out(out) abort
|
||||
|
||||
if has_key(result, 'errors')
|
||||
let l:winnr = winnr()
|
||||
let l:listtype = go#list#Type("quickfix")
|
||||
let l:listtype = go#list#Type("GoModifyTags")
|
||||
call go#list#ParseFormat(l:listtype, "%f:%l:%c:%m", result['errors'], "gomodifytags")
|
||||
call go#list#Window(l:listtype, len(result['errors']))
|
||||
|
||||
"prevent jumping to quickfix list
|
||||
exe l:winnr . "wincmd w"
|
||||
exe l:winnr . "wincmd w"
|
||||
endif
|
||||
endfunc
|
||||
|
||||
@ -210,3 +210,5 @@ func s:create_cmd(args) abort
|
||||
|
||||
return {'cmd': cmd}
|
||||
endfunc
|
||||
|
||||
" vim: sw=2 ts=2 et
|
||||
|
@ -1,28 +1,22 @@
|
||||
func Test_add_tags()
|
||||
let input_file = tempname()
|
||||
call writefile(readfile("test-fixtures/tags/add_all_input.go"), input_file)
|
||||
|
||||
let expected = join(readfile("test-fixtures/tags/add_all_golden.go"), "\n")
|
||||
|
||||
" run for offset 40, which is inside the struct
|
||||
call go#tags#run(0, 0, 40, "add", input_file, 1)
|
||||
|
||||
let actual = join(readfile(input_file), "\n")
|
||||
|
||||
call assert_equal(expected, actual)
|
||||
func! Test_add_tags() abort
|
||||
try
|
||||
let l:tmp = gotest#load_fixture('tags/add_all_input.go')
|
||||
silent call go#tags#run(0, 0, 40, "add", bufname(''), 1)
|
||||
call gotest#assert_fixture('tags/add_all_golden.go')
|
||||
finally
|
||||
call delete(l:tmp, 'rf')
|
||||
endtry
|
||||
endfunc
|
||||
|
||||
|
||||
func Test_remove_tags()
|
||||
let input_file = tempname()
|
||||
call writefile(readfile("test-fixtures/tags/remove_all_input.go"), input_file)
|
||||
|
||||
let expected = join(readfile("test-fixtures/tags/remove_all_golden.go"), "\n")
|
||||
|
||||
" run for offset 40, which is inside the struct
|
||||
call go#tags#run(0, 0, 40, "remove", input_file, 1)
|
||||
|
||||
let actual = join(readfile(input_file), "\n")
|
||||
|
||||
call assert_equal(expected, actual)
|
||||
func! Test_remove_tags() abort
|
||||
try
|
||||
let l:tmp = gotest#load_fixture('tags/remove_all_input.go')
|
||||
silent call go#tags#run(0, 0, 40, "remove", bufname(''), 1)
|
||||
call gotest#assert_fixture('tags/remove_all_golden.go')
|
||||
finally
|
||||
call delete(l:tmp, 'rf')
|
||||
endtry
|
||||
endfunc
|
||||
|
||||
" vim:ts=2:sts=2:sw=2:et
|
||||
|
@ -77,6 +77,7 @@ function! go#term#newmode(bang, cmd, mode) abort
|
||||
call jobresize(id, width, height)
|
||||
|
||||
let s:jobs[id] = job
|
||||
stopinsert
|
||||
return id
|
||||
endfunction
|
||||
|
||||
@ -104,7 +105,7 @@ function! s:on_exit(job_id, exit_status, event) dict abort
|
||||
endif
|
||||
let job = s:jobs[a:job_id]
|
||||
|
||||
let l:listtype = "locationlist"
|
||||
let l:listtype = go#list#Type("_term")
|
||||
|
||||
" usually there is always output so never branch into this clause
|
||||
if empty(job.stdout)
|
||||
|
@ -6,9 +6,13 @@ function! go#test#Test(bang, compile, ...) abort
|
||||
|
||||
" don't run the test, only compile it. Useful to capture and fix errors.
|
||||
if a:compile
|
||||
" we're going to tell to run a test function that doesn't exist. This
|
||||
" triggers a build of the test file itself but no tests will run.
|
||||
call extend(args, ["-run", "499EE4A2-5C85-4D35-98FC-7377CD87F263"])
|
||||
let testfile = tempname() . ".vim-go.test"
|
||||
call extend(args, ["-c", "-o", testfile])
|
||||
endif
|
||||
|
||||
if exists('g:go_build_tags')
|
||||
let tags = get(g:, 'go_build_tags')
|
||||
call extend(args, ["-tags", tags])
|
||||
endif
|
||||
|
||||
if a:0
|
||||
@ -33,9 +37,9 @@ function! go#test#Test(bang, compile, ...) abort
|
||||
|
||||
if get(g:, 'go_echo_command_info', 1)
|
||||
if a:compile
|
||||
echon "vim-go: " | echohl Identifier | echon "compiling tests ..." | echohl None
|
||||
call go#util#EchoProgress("compiling tests ...")
|
||||
else
|
||||
echon "vim-go: " | echohl Identifier | echon "testing ..." | echohl None
|
||||
call go#util#EchoProgress("testing...")
|
||||
endif
|
||||
endif
|
||||
|
||||
@ -57,7 +61,7 @@ function! go#test#Test(bang, compile, ...) abort
|
||||
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)
|
||||
let id = go#jobcontrol#Spawn(a:bang, "test", "GoTest", args)
|
||||
endif
|
||||
|
||||
return id
|
||||
@ -69,7 +73,7 @@ function! go#test#Test(bang, compile, ...) abort
|
||||
let command = "go " . join(args, ' ')
|
||||
let out = go#tool#ExecuteInDir(command)
|
||||
|
||||
let l:listtype = "quickfix"
|
||||
let l:listtype = go#list#Type("GoTest")
|
||||
|
||||
let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd ' : 'cd '
|
||||
let dir = getcwd()
|
||||
@ -87,15 +91,15 @@ function! go#test#Test(bang, compile, ...) abort
|
||||
" failed to parse errors, output the original content
|
||||
call go#util#EchoError(out)
|
||||
endif
|
||||
echon "vim-go: " | echohl ErrorMsg | echon "[test] FAIL" | echohl None
|
||||
call go#util#EchoError("[test] FAIL")
|
||||
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
|
||||
call go#util#EchoSuccess("[test] SUCCESS")
|
||||
else
|
||||
echon "vim-go: " | echohl Function | echon "[test] PASS" | echohl None
|
||||
call go#util#EchoSuccess("[test] PASS")
|
||||
endif
|
||||
endif
|
||||
execute cd . fnameescape(dir)
|
||||
@ -172,12 +176,12 @@ function s:test_job(args) abort
|
||||
if get(g:, 'go_echo_command_info', 1)
|
||||
if a:exitval == 0
|
||||
if a:args.compile_test
|
||||
call go#util#EchoSuccess("SUCCESS")
|
||||
call go#util#EchoSuccess("[test] SUCCESS")
|
||||
else
|
||||
call go#util#EchoSuccess("PASS")
|
||||
call go#util#EchoSuccess("[test] PASS")
|
||||
endif
|
||||
else
|
||||
call go#util#EchoError("FAILED")
|
||||
call go#util#EchoError("[test] FAIL")
|
||||
endif
|
||||
endif
|
||||
|
||||
@ -188,7 +192,7 @@ function s:test_job(args) abort
|
||||
|
||||
call go#statusline#Update(status_dir, status)
|
||||
|
||||
let l:listtype = go#list#Type("quickfix")
|
||||
let l:listtype = go#list#Type("GoTest")
|
||||
if a:exitval == 0
|
||||
call go#list#Clean(l:listtype)
|
||||
call go#list#Window(l:listtype)
|
||||
@ -222,9 +226,9 @@ endfunction
|
||||
|
||||
" show_errors parses the given list of lines of a 'go test' output and returns
|
||||
" a quickfix compatible list of errors. It's intended to be used only for go
|
||||
" test output.
|
||||
" test output.
|
||||
function! s:show_errors(args, exit_val, messages) abort
|
||||
let l:listtype = go#list#Type("quickfix")
|
||||
let l:listtype = go#list#Type("GoTest")
|
||||
|
||||
let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd ' : 'cd '
|
||||
try
|
||||
@ -237,7 +241,7 @@ function! s:show_errors(args, exit_val, messages) abort
|
||||
|
||||
if !len(errors)
|
||||
" failed to parse errors, output the original content
|
||||
call go#util#EchoError(join(a:messages, " "))
|
||||
call go#util#EchoError(a:messages)
|
||||
call go#util#EchoError(a:args.dir)
|
||||
return
|
||||
endif
|
||||
@ -253,28 +257,85 @@ endfunction
|
||||
|
||||
function! s:parse_errors(lines) abort
|
||||
let errors = []
|
||||
let paniced = 0 " signals whether all remaining lines should be included in errors.
|
||||
let test = ''
|
||||
|
||||
" NOTE(arslan): once we get JSON output everything will be easier :)
|
||||
" https://github.com/golang/go/issues/2981
|
||||
for line in a:lines
|
||||
let fatalerrors = matchlist(line, '^\(fatal error:.*\)$')
|
||||
let tokens = matchlist(line, '^\s*\(.\{-}\.go\):\(\d\+\):\s*\(.*\)')
|
||||
|
||||
let fatalerrors = matchlist(line, '^\(\(fatal error\|panic\):.*\)$')
|
||||
if !empty(fatalerrors)
|
||||
call add(errors, {"text": fatalerrors[1]})
|
||||
elseif !empty(tokens)
|
||||
let paniced = 1
|
||||
call add(errors, {"text": line})
|
||||
continue
|
||||
endif
|
||||
|
||||
if !paniced
|
||||
" Matches failure lines. These lines always have zero or more leading spaces followed by '-- FAIL: ', following by the test name followed by a space the duration of the test in parentheses
|
||||
" e.g.:
|
||||
" '--- FAIL: TestSomething (0.00s)'
|
||||
let failure = matchlist(line, '^ *--- FAIL: \(.*\) (.*)$')
|
||||
if get(g:, 'go_test_prepend_name', 0)
|
||||
if !empty(failure)
|
||||
let test = failure[1] . ': '
|
||||
continue
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
let tokens = []
|
||||
if paniced
|
||||
" Matches lines in stacktraces produced by panic. The lines always have
|
||||
" one or more leading tabs, followed by the path to the file. The file
|
||||
" path is followed by a colon and then the line number within the file
|
||||
" where the panic occurred. After that there's a space and hexadecimal
|
||||
" number.
|
||||
"
|
||||
" e.g.:
|
||||
" '\t/usr/local/go/src/time.go:1313 +0x5d'
|
||||
let tokens = matchlist(line, '^\t\+\(.\{-}\.go\):\(\d\+\) \(+0x.*\)')
|
||||
else
|
||||
" matches lines produced by `go test`. All lines produced by `go test`
|
||||
" that we're interested in start with zero or more spaces (increasing
|
||||
" depth of subtests is represented by a similar increase in the number
|
||||
" of spaces at the start of output lines. Top level tests start with
|
||||
" zero leading spaces). Lines that indicate test status (e.g. RUN, FAIL,
|
||||
" PASS) start after the spaces. Lines that indicate test failure
|
||||
" location or test log message location (e.g. "testing.T".Log) begin
|
||||
" with the appropriate number of spaces for the current test level,
|
||||
" followed by a tab, a filename , a colon, the line number, another
|
||||
" colon, a space, and the failure or log message.
|
||||
"
|
||||
" e.g.:
|
||||
" '\ttime_test.go:30: Likely problem: the time zone files have not been installed.'
|
||||
let tokens = matchlist(line, '^ *\t\+\(.\{-}\.go\):\(\d\+\):\s*\(.*\)')
|
||||
endif
|
||||
|
||||
if !empty(tokens) " Check whether the line may refer to a file.
|
||||
" strip endlines of form ^M
|
||||
let out = substitute(tokens[3], '\r$', '', '')
|
||||
let file = fnamemodify(tokens[1], ':p')
|
||||
|
||||
" Preserve the line when the filename is not readable. This is an
|
||||
" unusual case, but possible; any test that produces lines that match
|
||||
" the pattern used in the matchlist assigned to tokens is a potential
|
||||
" source of this condition. For instance, github.com/golang/mock/gomock
|
||||
" will sometimes produce lines that satisfy this condition.
|
||||
if !filereadable(file)
|
||||
call add(errors, {"text": test . line})
|
||||
continue
|
||||
endif
|
||||
|
||||
call add(errors, {
|
||||
\ "filename" : fnamemodify(tokens[1], ':p'),
|
||||
\ "filename" : file,
|
||||
\ "lnum" : tokens[2],
|
||||
\ "text" : out,
|
||||
\ "text" : test . out,
|
||||
\ })
|
||||
elseif paniced
|
||||
call add(errors, {"text": line})
|
||||
elseif !empty(errors)
|
||||
" Preserve indented lines.
|
||||
" This comes up especially with multi-line test output.
|
||||
if match(line, '^\s') >= 0
|
||||
" Preserve indented lines. This comes up especially with multi-line test output.
|
||||
if match(line, '^ *\t\+') >= 0
|
||||
call add(errors, {"text": line})
|
||||
endif
|
||||
endif
|
||||
@ -284,4 +345,3 @@ function! s:parse_errors(lines) abort
|
||||
endfunction
|
||||
|
||||
" vim: sw=2 ts=2 et
|
||||
"
|
||||
|
@ -162,6 +162,18 @@ function! go#tool#FilterValids(items) abort
|
||||
endfunction
|
||||
|
||||
function! go#tool#ExecuteInDir(cmd) abort
|
||||
" Verify that the directory actually exists. If the directory does not
|
||||
" exist, then assume that the a:cmd should not be executed. Callers expect
|
||||
" to check v:shell_error (via go#util#ShellError()), so execute a command
|
||||
" that will return an error as if a:cmd was run and exited with an error.
|
||||
" This helps avoid errors when working with plugins that use virtual files
|
||||
" that don't actually exist on the file system (e.g. vim-fugitive's
|
||||
" GitDiff).
|
||||
if !isdirectory(expand("%:p:h"))
|
||||
let [out, err] = go#util#Exec(["false"])
|
||||
return ''
|
||||
endif
|
||||
|
||||
let old_gopath = $GOPATH
|
||||
let old_goroot = $GOROOT
|
||||
let $GOPATH = go#path#Detect()
|
||||
@ -194,7 +206,6 @@ function! go#tool#Exists(importpath) abort
|
||||
return 0
|
||||
endfunction
|
||||
|
||||
|
||||
" following two functions are from: https://github.com/mattn/gist-vim
|
||||
" thanks @mattn
|
||||
function! s:get_browser_command() abort
|
||||
@ -202,12 +213,14 @@ function! s:get_browser_command() abort
|
||||
if go_play_browser_command == ''
|
||||
if go#util#IsWin()
|
||||
let go_play_browser_command = '!start rundll32 url.dll,FileProtocolHandler %URL%'
|
||||
elseif has('mac') || has('macunix') || has('gui_macvim') || go#util#System('uname') =~? '^darwin'
|
||||
elseif go#util#IsMac()
|
||||
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% &'
|
||||
elseif executable('chromium')
|
||||
let go_play_browser_command = 'chromium %URL% &'
|
||||
else
|
||||
let go_play_browser_command = ''
|
||||
endif
|
||||
|
@ -43,6 +43,14 @@ function! go#util#IsWin() abort
|
||||
return 0
|
||||
endfunction
|
||||
|
||||
" IsMac returns 1 if current OS is macOS or 0 otherwise.
|
||||
function! go#util#IsMac() abort
|
||||
return has('mac') ||
|
||||
\ has('macunix') ||
|
||||
\ has('gui_macvim') ||
|
||||
\ go#util#System('uname') =~? '^darwin'
|
||||
endfunction
|
||||
|
||||
" Checks if using:
|
||||
" 1) Windows system,
|
||||
" 2) And has cygpath executable,
|
||||
@ -110,25 +118,22 @@ function! go#util#osarch() abort
|
||||
return go#util#env("goos") . '_' . go#util#env("goarch")
|
||||
endfunction
|
||||
|
||||
" 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.
|
||||
function! go#util#System(str, ...) abort
|
||||
" Run a shell command.
|
||||
"
|
||||
" It will temporary set the shell to /bin/sh for Unix-like systems if possible,
|
||||
" so that we always use a standard POSIX-compatible Bourne shell (and not e.g.
|
||||
" csh, fish, etc.) See #988 and #1276.
|
||||
function! s:system(cmd, ...) abort
|
||||
" Preserve original shell and shellredir values
|
||||
let l:shell = &shell
|
||||
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.
|
||||
if !go#util#IsWin() && executable('/bin/sh')
|
||||
set shell=/bin/sh shellredir=>%s\ 2>&1
|
||||
endif
|
||||
|
||||
try
|
||||
let l:output = call('system', [a:str] + a:000)
|
||||
return l:output
|
||||
return call('system', [a:cmd] + a:000)
|
||||
finally
|
||||
" Restore original values
|
||||
let &shell = l:shell
|
||||
@ -136,6 +141,31 @@ function! go#util#System(str, ...) abort
|
||||
endtry
|
||||
endfunction
|
||||
|
||||
" System runs a shell command "str". Every arguments after "str" is passed to
|
||||
" stdin.
|
||||
function! go#util#System(str, ...) abort
|
||||
return call('s:system', [a:str] + a:000)
|
||||
endfunction
|
||||
|
||||
" Exec runs a shell command "cmd", which must be a list, one argument per item.
|
||||
" Every list entry will be automatically shell-escaped
|
||||
" Every other argument is passed to stdin.
|
||||
function! go#util#Exec(cmd, ...) abort
|
||||
if len(a:cmd) == 0
|
||||
call go#util#EchoError("go#util#Exec() called with empty a:cmd")
|
||||
return
|
||||
endif
|
||||
|
||||
" CheckBinPath will show a warning for us.
|
||||
let l:bin = go#path#CheckBinPath(a:cmd[0])
|
||||
if empty(l:bin)
|
||||
return ["", 1]
|
||||
endif
|
||||
|
||||
let l:out = call('s:system', [go#util#Shelljoin([l:bin] + a:cmd[1:])] + a:000)
|
||||
return [l:out, go#util#ShellError()]
|
||||
endfunction
|
||||
|
||||
function! go#util#ShellError() abort
|
||||
return v:shell_error
|
||||
endfunction
|
||||
@ -242,50 +272,71 @@ endfunction
|
||||
" snakecase converts a string to snake case. i.e: FooBar -> foo_bar
|
||||
" Copied from tpope/vim-abolish
|
||||
function! go#util#snakecase(word) abort
|
||||
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 = 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
|
||||
" camelcase converts a string to camel case. e.g. FooBar or foo_bar will become
|
||||
" fooBar.
|
||||
" Copied from tpope/vim-abolish.
|
||||
function! go#util#camelcase(word) abort
|
||||
let word = substitute(a:word, '-', '_', 'g')
|
||||
if word !~# '_' && word =~# '\l'
|
||||
return substitute(word,'^.','\l&','')
|
||||
return substitute(word, '^.', '\l&', '')
|
||||
else
|
||||
return substitute(word,'\C\(_\)\=\(.\)','\=submatch(1)==""?tolower(submatch(2)) : toupper(submatch(2))','g')
|
||||
return substitute(word, '\C\(_\)\=\(.\)', '\=submatch(1)==""?tolower(submatch(2)) : toupper(submatch(2))','g')
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" TODO(arslan): I couldn't parameterize the highlight types. Check if we can
|
||||
" simplify the following functions
|
||||
" pascalcase converts a string to 'PascalCase'. e.g. fooBar or foo_bar will
|
||||
" become FooBar.
|
||||
function! go#util#pascalcase(word) abort
|
||||
let word = go#util#camelcase(a:word)
|
||||
return toupper(word[0]) . word[1:]
|
||||
endfunction
|
||||
|
||||
" Echo a message to the screen and highlight it with the group in a:hi.
|
||||
"
|
||||
" 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.
|
||||
" The message can be a list or string; every line with be :echomsg'd separately.
|
||||
function! s:echo(msg, hi)
|
||||
let l:msg = []
|
||||
if type(a:msg) != type([])
|
||||
let l:msg = split(a:msg, "\n")
|
||||
else
|
||||
let l:msg = a:msg
|
||||
endif
|
||||
|
||||
" Tabs display as ^I or <09>, so manually expand them.
|
||||
let l:msg = map(l:msg, 'substitute(v:val, "\t", " ", "")')
|
||||
|
||||
exe 'echohl ' . a:hi
|
||||
for line in l:msg
|
||||
echom "vim-go: " . line
|
||||
endfor
|
||||
echohl None
|
||||
endfunction
|
||||
|
||||
function! go#util#EchoSuccess(msg)
|
||||
redraw | echohl Function | echom "vim-go: " . a:msg | echohl None
|
||||
call s:echo(a:msg, 'Function')
|
||||
endfunction
|
||||
|
||||
function! go#util#EchoError(msg)
|
||||
redraw | echohl ErrorMsg | echom "vim-go: " . a:msg | echohl None
|
||||
call s:echo(a:msg, 'ErrorMsg')
|
||||
endfunction
|
||||
|
||||
function! go#util#EchoWarning(msg)
|
||||
redraw | echohl WarningMsg | echom "vim-go: " . a:msg | echohl None
|
||||
call s:echo(a:msg, 'WarningMsg')
|
||||
endfunction
|
||||
|
||||
function! go#util#EchoProgress(msg)
|
||||
redraw | echohl Identifier | echom "vim-go: " . a:msg | echohl None
|
||||
call s:echo(a:msg, 'Identifier')
|
||||
endfunction
|
||||
|
||||
function! go#util#EchoInfo(msg)
|
||||
redraw | echohl Debug | echom "vim-go: " . a:msg | echohl None
|
||||
call s:echo(a:msg, 'Debug')
|
||||
endfunction
|
||||
|
||||
" Get all lines in the buffer as a a list.
|
||||
function! go#util#GetLines()
|
||||
let buf = getline(1, '$')
|
||||
if &encoding != 'utf-8'
|
||||
@ -299,4 +350,49 @@ function! go#util#GetLines()
|
||||
return buf
|
||||
endfunction
|
||||
|
||||
" Convert the current buffer to the "archive" format of
|
||||
" golang.org/x/tools/go/buildutil:
|
||||
" https://godoc.org/golang.org/x/tools/go/buildutil#ParseOverlayArchive
|
||||
"
|
||||
" > The archive consists of a series of files. Each file consists of a name, a
|
||||
" > decimal file size and the file contents, separated by newlinews. No newline
|
||||
" > follows after the file contents.
|
||||
function! go#util#archive()
|
||||
let l:buffer = join(go#util#GetLines(), "\n")
|
||||
return expand("%:p:gs!\\!/!") . "\n" . strlen(l:buffer) . "\n" . l:buffer
|
||||
endfunction
|
||||
|
||||
|
||||
" Make a named temporary directory which starts with "prefix".
|
||||
"
|
||||
" Unfortunately Vim's tempname() is not portable enough across various systems;
|
||||
" see: https://github.com/mattn/vim-go/pull/3#discussion_r138084911
|
||||
function! go#util#tempdir(prefix) abort
|
||||
" See :help tempfile
|
||||
if go#util#IsWin()
|
||||
let l:dirs = [$TMP, $TEMP, 'c:\tmp', 'c:\temp']
|
||||
else
|
||||
let l:dirs = [$TMPDIR, '/tmp', './', $HOME]
|
||||
endif
|
||||
|
||||
let l:dir = ''
|
||||
for l:d in dirs
|
||||
if !empty(l:d) && filewritable(l:d) == 2
|
||||
let l:dir = l:d
|
||||
break
|
||||
endif
|
||||
endfor
|
||||
|
||||
if l:dir == ''
|
||||
echoerr 'Unable to find directory to store temporary directory in'
|
||||
return
|
||||
endif
|
||||
|
||||
" Not great randomness, but "good enough" for our purpose here.
|
||||
let l:rnd = sha256(printf('%s%s', localtime(), fnamemodify(bufname(''), ":p")))
|
||||
let l:tmp = printf("%s/%s%s", l:dir, a:prefix, l:rnd)
|
||||
call mkdir(l:tmp, 'p', 0700)
|
||||
return l:tmp
|
||||
endfunction
|
||||
|
||||
" vim: sw=2 ts=2 et
|
||||
|
Reference in New Issue
Block a user