mirror of
https://github.com/amix/vimrc
synced 2025-06-16 09:35:01 +08:00
Updated plugins
This commit is contained in:
@ -6,6 +6,7 @@ coverage:
|
||||
target: auto
|
||||
threshold: 1
|
||||
base: auto
|
||||
patch: off
|
||||
comment: false
|
||||
ignore:
|
||||
- "!autoload/go/*.vim$"
|
||||
|
@ -1,6 +1,6 @@
|
||||
language: go
|
||||
go:
|
||||
- 1.10.x
|
||||
- 1.11.x
|
||||
notifications:
|
||||
email: false
|
||||
matrix:
|
||||
|
@ -1,5 +1,18 @@
|
||||
## unplanned
|
||||
|
||||
FEATURES:
|
||||
|
||||
* **go.mod file support!** This is the first feature for upcoming Go modules
|
||||
support. The followings are added:
|
||||
* Syntax highlighting for the `go.mod` file.
|
||||
* A new `gomod` filetype is set if a `go.mod` file has been opened and starts
|
||||
with the line `module `
|
||||
* New **:GoModFmt** command that formats the `go.mod` file
|
||||
* Auto format on save feature for `:GoModFmt`, enabled automatically. Can be
|
||||
toggled of with the setting `g:go_mod_fmt_autosave` or with the command:
|
||||
`GoModFmtAutoSaveToggle`
|
||||
[[GH-1931]](https://github.com/fatih/vim-go/pull/1931)
|
||||
|
||||
IMPROVEMENTS:
|
||||
* Unify async job handling for Vim8 and Neovim.
|
||||
[[GH-1864]](https://github.com/fatih/vim-go/pull/1864)
|
||||
@ -13,6 +26,36 @@ IMPROVEMENTS:
|
||||
[[GH-1894]](https://github.com/fatih/vim-go/pull/1894)
|
||||
* Install keyify from its canonical import path.
|
||||
[[GH-1924]](https://github.com/fatih/vim-go/pull/1924)
|
||||
* Update the tested version of Neovim to v0.3.1.
|
||||
[[GH-1923]](https://github.com/fatih/vim-go/pull/1923)
|
||||
* Run autocompletion asynchronously in Vim8 and Neovim.
|
||||
[[GH-1926]](https://github.com/fatih/vim-go/pull/1926)
|
||||
* Show statusline update when running `:GoInfo` with `g:go_info_mode='gocode'`.
|
||||
[[GH-1937]](https://github.com/fatih/vim-go/pull/1937)
|
||||
* Do not update statusline when highlighting sameids or showing type info via
|
||||
an autocmd.
|
||||
[[GH-1937]](https://github.com/fatih/vim-go/pull/1937)
|
||||
* Do not indent within a raw string literal.
|
||||
[[GH-1858]](https://github.com/fatih/vim-go/pull/1858)
|
||||
* Highlight Go's predeclared function identifiers (the functions in `builtins`)
|
||||
using keyword groups and highlight them using the `Identifiers` group.
|
||||
[[GH-1939]](https://github.com/fatih/vim-go/pull/1939)
|
||||
* Add a new FAQ entry to instruct users how to modify the vim-go highlight
|
||||
groups.
|
||||
[[GH-1939]](https://github.com/fatih/vim-go/pull/1939)
|
||||
* Improve use of statusline and progress messages.
|
||||
[[GH-1948]](https://github.com/fatih/vim-go/pull/1948)
|
||||
* Add `tt` snippet to create a table test boilerplate (see
|
||||
https://github.com/golang/go/wiki/TableDrivenTests for more information on
|
||||
how to use a table driven test).
|
||||
[[GH-1956]](https://github.com/fatih/vim-go/pull/1956)
|
||||
* Add `<Plug>(go-decls)` and `<Plug>(go-decls-dir)` mappings.
|
||||
[[GH-1964]](https://github.com/fatih/vim-go/pull/1964)
|
||||
* Handle go1.11 test output.
|
||||
[[GH-1978]](https://github.com/fatih/vim-go/pull/1978)
|
||||
* Internal: install tools by their custom names
|
||||
[[GH-1984]](https://github.com/fatih/vim-go/pull/1984)
|
||||
|
||||
|
||||
BUG FIXES:
|
||||
* Fix `:GoRun %` on Windows.
|
||||
@ -23,10 +66,17 @@ BUG FIXES:
|
||||
[[GH-1895]](https://github.com/fatih/vim-go/pull/1895)
|
||||
* Fix `:GoInfo` when `g:go_info_mode` is `gocode`
|
||||
[[GH-1915]](https://github.com/fatih/vim-go/pull/1915)
|
||||
* Fix highlighting of pointer type in var blocks.
|
||||
[[GH-1794]](https://github.com/fatih/vim-go/pull/1794)
|
||||
* Fix `:GoImport` when adding to an empty import block (i.e`import ()`)
|
||||
[[GH-1938]](https://github.com/fatih/vim-go/pull/1938)
|
||||
|
||||
BACKWARDS INCOMPATIBILITIES:
|
||||
* Bump minimum required version of Vim to 7.4.2009.
|
||||
[[GH-1899]](https://github.com/fatih/vim-go/pull/1899)
|
||||
* Switch gocode to github.com/mdempsky/gocode. Several gocode options have been
|
||||
removed and a new one has been added.
|
||||
[[GH-1853]](https://github.com/fatih/vim-go/pull/1853)
|
||||
|
||||
## 1.18 - (July 18, 2018)
|
||||
|
||||
@ -42,7 +92,7 @@ FEATURES:
|
||||
f, err := os.Open("file")
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
Becomes:
|
||||
|
||||
```
|
||||
|
@ -1,4 +1,4 @@
|
||||
FROM golang:1.10.1
|
||||
FROM golang:1.11
|
||||
|
||||
RUN apt-get update -y && \
|
||||
apt-get install -y build-essential curl git libncurses5-dev python3-pip && \
|
||||
|
@ -33,7 +33,7 @@ This plugin adds Go language support for Vim, with the following main features:
|
||||
|
||||
## Install
|
||||
|
||||
vim-go requires at least Vim 7.4.2009 or Neovim 0.2.2.
|
||||
vim-go requires at least Vim 7.4.2009 or Neovim 0.3.1.
|
||||
|
||||
The [**latest stable release**](https://github.com/fatih/vim-go/releases/latest) is the
|
||||
recommended version to use. If you choose to use the master branch instead,
|
||||
|
@ -31,15 +31,12 @@ function! go#cmd#Build(bang, ...) abort
|
||||
\ [".", "errors"]
|
||||
|
||||
" Vim and Neovim async.
|
||||
if go#util#has_job() || has('nvim')
|
||||
if go#config#EchoCommandInfo()
|
||||
call go#util#EchoProgress("building dispatched ...")
|
||||
endif
|
||||
|
||||
if go#util#has_job()
|
||||
call s:cmd_job({
|
||||
\ 'cmd': ['go'] + args,
|
||||
\ 'bang': a:bang,
|
||||
\ 'for': 'GoBuild',
|
||||
\ 'statustype': 'build'
|
||||
\})
|
||||
|
||||
" Vim 7.4 without async
|
||||
@ -195,14 +192,11 @@ function! go#cmd#Install(bang, ...) abort
|
||||
" expand all wildcards(i.e: '%' to the current file name)
|
||||
let goargs = map(copy(a:000), "expand(v:val)")
|
||||
|
||||
if go#config#EchoCommandInfo()
|
||||
call go#util#EchoProgress("installing dispatched ...")
|
||||
endif
|
||||
|
||||
call s:cmd_job({
|
||||
\ 'cmd': ['go', 'install', '-tags', go#config#BuildTags()] + goargs,
|
||||
\ 'bang': a:bang,
|
||||
\ 'for': 'GoInstall',
|
||||
\ 'statustype': 'install'
|
||||
\})
|
||||
return
|
||||
endif
|
||||
@ -281,16 +275,7 @@ endfunction
|
||||
" | Vim job callbacks |
|
||||
" ---------------------
|
||||
|
||||
function s:cmd_job(args) abort
|
||||
let status_dir = expand('%:p:h')
|
||||
let started_at = reltime()
|
||||
|
||||
call go#statusline#Update(status_dir, {
|
||||
\ 'desc': "current status",
|
||||
\ 'type': a:args.cmd[1],
|
||||
\ 'state': "started",
|
||||
\})
|
||||
|
||||
function! s:cmd_job(args) abort
|
||||
" autowrite is not enabled for jobs
|
||||
call go#cmd#autowrite()
|
||||
|
||||
|
@ -9,6 +9,15 @@ function! s:gocodeCommand(cmd, args) abort
|
||||
let cmd = [bin_path]
|
||||
let cmd = extend(cmd, ['-sock', socket_type])
|
||||
let cmd = extend(cmd, ['-f', 'vim'])
|
||||
|
||||
if go#config#GocodeProposeBuiltins()
|
||||
let cmd = extend(cmd, ['-builtin'])
|
||||
endif
|
||||
|
||||
if go#config#GocodeProposeSource()
|
||||
let cmd = extend(cmd, ['-source'])
|
||||
endif
|
||||
|
||||
let cmd = extend(cmd, [a:cmd])
|
||||
let cmd = extend(cmd, a:args)
|
||||
|
||||
@ -43,31 +52,7 @@ function! s:sync_gocode(cmd, args, input) abort
|
||||
return l:result
|
||||
endfunction
|
||||
|
||||
let s:optionsEnabled = 0
|
||||
function! s:gocodeEnableOptions() abort
|
||||
if s:optionsEnabled
|
||||
return
|
||||
endif
|
||||
|
||||
let l:bin_path = go#path#CheckBinPath("gocode")
|
||||
if empty(l:bin_path)
|
||||
return
|
||||
endif
|
||||
|
||||
let s:optionsEnabled = 1
|
||||
|
||||
call go#util#Exec(['gocode', 'set', 'propose-builtins', s:toBool(go#config#GocodeProposeBuiltins())])
|
||||
call go#util#Exec(['gocode', 'set', 'autobuild', s:toBool(go#config#GocodeAutobuild())])
|
||||
call go#util#Exec(['gocode', 'set', 'unimported-packages', s:toBool(go#config#GocodeUnimportedPackages())])
|
||||
endfunction
|
||||
|
||||
function! s:toBool(val) abort
|
||||
if a:val | return 'true' | else | return 'false' | endif
|
||||
endfunction
|
||||
|
||||
function! s:gocodeAutocomplete() abort
|
||||
call s:gocodeEnableOptions()
|
||||
|
||||
" use the offset as is, because the cursor position is the position for
|
||||
" which autocomplete candidates are needed.
|
||||
return s:sync_gocode('autocomplete',
|
||||
@ -81,60 +66,36 @@ function! go#complete#GetInfo() abort
|
||||
return s:sync_info(0)
|
||||
endfunction
|
||||
|
||||
function! go#complete#Info() abort
|
||||
function! go#complete#Info(showstatus) abort
|
||||
if go#util#has_job(1)
|
||||
return s:async_info(1)
|
||||
return s:async_info(1, a:showstatus)
|
||||
else
|
||||
return s:sync_info(1)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:async_info(echo)
|
||||
if exists("s:async_info_job")
|
||||
call job_stop(s:async_info_job)
|
||||
unlet s:async_info_job
|
||||
endif
|
||||
function! s:async_info(echo, showstatus)
|
||||
let state = {'echo': a:echo}
|
||||
|
||||
let state = {
|
||||
\ 'exited': 0,
|
||||
\ 'exit_status': 0,
|
||||
\ 'closed': 0,
|
||||
\ 'messages': [],
|
||||
\ 'echo': a:echo
|
||||
\ }
|
||||
|
||||
function! s:callback(chan, msg) dict
|
||||
let l:msg = a:msg
|
||||
if &encoding != 'utf-8'
|
||||
let l:msg = iconv(l:msg, 'utf-8', &encoding)
|
||||
endif
|
||||
call add(self.messages, l:msg)
|
||||
endfunction
|
||||
|
||||
function! s:exit_cb(job, exitval) dict
|
||||
let self.exit_status = a:exitval
|
||||
let self.exited = 1
|
||||
|
||||
if self.closed
|
||||
call self.complete()
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:close_cb(ch) dict
|
||||
let self.closed = 1
|
||||
if self.exited
|
||||
call self.complete()
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function state.complete() dict
|
||||
if self.exit_status != 0
|
||||
function! s:complete(job, exit_status, messages) abort dict
|
||||
if a:exit_status != 0
|
||||
return
|
||||
endif
|
||||
|
||||
let result = s:info_filter(self.echo, join(self.messages, "\n"))
|
||||
if &encoding != 'utf-8'
|
||||
let i = 0
|
||||
while i < len(a:messages)
|
||||
let a:messages[i] = iconv(a:messages[i], 'utf-8', &encoding)
|
||||
let i += 1
|
||||
endwhile
|
||||
endif
|
||||
|
||||
let result = s:info_filter(self.echo, join(a:messages, "\n"))
|
||||
call s:info_complete(self.echo, result)
|
||||
endfunction
|
||||
" explicitly bind complete to state so that within it, self will
|
||||
" always refer to state. See :help Partial for more information.
|
||||
let state.complete = function('s:complete', [], state)
|
||||
|
||||
" add 1 to the offset, so that the position at the cursor will be included
|
||||
" in gocode's search
|
||||
@ -146,23 +107,32 @@ function! s:async_info(echo)
|
||||
\ "GOROOT": go#util#env("goroot")
|
||||
\ }
|
||||
|
||||
let opts = {
|
||||
\ 'bang': 1,
|
||||
\ 'complete': state.complete,
|
||||
\ 'for': '_',
|
||||
\ }
|
||||
|
||||
if a:showstatus
|
||||
let opts.statustype = 'gocode'
|
||||
endif
|
||||
|
||||
let opts = go#job#Options(l:opts)
|
||||
|
||||
let cmd = s:gocodeCommand('autocomplete',
|
||||
\ [expand('%:p'), offset])
|
||||
|
||||
" TODO(bc): Don't write the buffer to a file; pass the buffer directrly to
|
||||
" TODO(bc): Don't write the buffer to a file; pass the buffer directly to
|
||||
" gocode's stdin. It shouldn't be necessary to use {in_io: 'file', in_name:
|
||||
" s:gocodeFile()}, but unfortunately {in_io: 'buffer', in_buf: bufnr('%')}
|
||||
" should work.
|
||||
let options = {
|
||||
" doesn't work.
|
||||
call extend(opts, {
|
||||
\ 'env': env,
|
||||
\ 'in_io': 'file',
|
||||
\ 'in_name': s:gocodeFile(),
|
||||
\ 'callback': funcref("s:callback", [], state),
|
||||
\ 'exit_cb': funcref("s:exit_cb", [], state),
|
||||
\ 'close_cb': funcref("s:close_cb", [], state)
|
||||
\ }
|
||||
\ })
|
||||
|
||||
let s:async_info_job = job_start(cmd, options)
|
||||
call go#job#Start(cmd, opts)
|
||||
endfunction
|
||||
|
||||
function! s:gocodeFile()
|
||||
|
20
sources_non_forked/vim-go/autoload/go/complete_test.vim
Normal file
20
sources_non_forked/vim-go/autoload/go/complete_test.vim
Normal file
@ -0,0 +1,20 @@
|
||||
func! Test_GetInfo()
|
||||
let l:filename = 'complete/complete.go'
|
||||
let l:tmp = gotest#load_fixture(l:filename)
|
||||
|
||||
call cursor(8, 3)
|
||||
|
||||
let g:go_info_mode = 'gocode'
|
||||
let expected = 'func Example(s string)'
|
||||
let actual = go#complete#GetInfo()
|
||||
call assert_equal(expected, actual)
|
||||
|
||||
let g:go_info_mode = 'guru'
|
||||
call go#config#InfoMode()
|
||||
let actual = go#complete#GetInfo()
|
||||
call assert_equal(expected, actual)
|
||||
|
||||
unlet g:go_info_mode
|
||||
endfunction
|
||||
|
||||
" vim: sw=2 ts=2 et
|
@ -135,10 +135,6 @@ function! go#config#SetGuruScope(scope) abort
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! go#config#GocodeUnimportedPackages() abort
|
||||
return get(g:, 'go_gocode_unimported_packages', 0)
|
||||
endfunction
|
||||
|
||||
let s:sock_type = (has('win32') || has('win64')) ? 'tcp' : 'unix'
|
||||
function! go#config#GocodeSocketType() abort
|
||||
return get(g:, 'go_gocode_socket_type', s:sock_type)
|
||||
@ -148,8 +144,8 @@ function! go#config#GocodeProposeBuiltins() abort
|
||||
return get(g:, 'go_gocode_propose_builtins', 1)
|
||||
endfunction
|
||||
|
||||
function! go#config#GocodeAutobuild() abort
|
||||
return get(g:, 'go_gocode_autobuild', 1)
|
||||
function! go#config#GocodeProposeSource() abort
|
||||
return get(g:, 'go_gocode_propose_source', 1)
|
||||
endfunction
|
||||
|
||||
function! go#config#EchoCommandInfo() abort
|
||||
@ -282,6 +278,14 @@ function! go#config#SetAsmfmtAutosave(value) abort
|
||||
let g:go_asmfmt_autosave = a:value
|
||||
endfunction
|
||||
|
||||
function! go#config#ModFmtAutosave() abort
|
||||
return get(g:, "go_mod_fmt_autosave", 1)
|
||||
endfunction
|
||||
|
||||
function! go#config#SetModFmtAutosave(value) abort
|
||||
let g:go_mod_fmt_autosave = a:value
|
||||
endfunction
|
||||
|
||||
function! go#config#DocMaxHeight() abort
|
||||
return get(g:, "go_doc_max_height", 20)
|
||||
endfunction
|
||||
@ -416,7 +420,7 @@ function! go#config#HighlightVariableDeclarations() abort
|
||||
return get(g:, 'go_highlight_variable_declarations', 0)
|
||||
endfunction
|
||||
|
||||
function go#config#FoldEnable(...) abort
|
||||
function! go#config#FoldEnable(...) abort
|
||||
if a:0 > 0
|
||||
return index(go#config#FoldEnable(), a:1) > -1
|
||||
endif
|
||||
|
@ -44,11 +44,7 @@ function! go#coverage#Buffer(bang, ...) abort
|
||||
let s:toggle = 1
|
||||
let l:tmpname = tempname()
|
||||
|
||||
if go#config#EchoCommandInfo()
|
||||
call go#util#EchoProgress("testing...")
|
||||
endif
|
||||
|
||||
if go#util#has_job() || has('nvim')
|
||||
if go#util#has_job()
|
||||
call s:coverage_job({
|
||||
\ 'cmd': ['go', 'test', '-tags', go#config#BuildTags(), '-coverprofile', l:tmpname] + a:000,
|
||||
\ 'complete': function('s:coverage_callback', [l:tmpname]),
|
||||
@ -59,6 +55,10 @@ function! go#coverage#Buffer(bang, ...) abort
|
||||
return
|
||||
endif
|
||||
|
||||
if go#config#EchoCommandInfo()
|
||||
call go#util#EchoProgress("testing...")
|
||||
endif
|
||||
|
||||
let args = [a:bang, 0, "-coverprofile", l:tmpname]
|
||||
if a:0
|
||||
call extend(args, a:000)
|
||||
@ -89,12 +89,13 @@ endfunction
|
||||
" a new HTML coverage page from that profile in a new browser
|
||||
function! go#coverage#Browser(bang, ...) abort
|
||||
let l:tmpname = tempname()
|
||||
if go#util#has_job() || has('nvim')
|
||||
if go#util#has_job()
|
||||
call s:coverage_job({
|
||||
\ 'cmd': ['go', 'test', '-tags', go#config#BuildTags(), '-coverprofile', l:tmpname],
|
||||
\ 'complete': function('s:coverage_browser_callback', [l:tmpname]),
|
||||
\ 'bang': a:bang,
|
||||
\ 'for': 'GoTest',
|
||||
\ 'statustype': 'coverage',
|
||||
\ })
|
||||
return
|
||||
endif
|
||||
|
@ -25,12 +25,12 @@ function! s:groutineID() abort
|
||||
return s:state['currentThread'].goroutineID
|
||||
endfunction
|
||||
|
||||
function! s:exit(job, status) abort
|
||||
function! s:complete(job, exit_status, data) abort
|
||||
if has_key(s:state, 'job')
|
||||
call remove(s:state, 'job')
|
||||
endif
|
||||
call s:clearState()
|
||||
if a:status > 0
|
||||
if a:exit_status > 0
|
||||
call go#util#EchoError(s:state['message'])
|
||||
endif
|
||||
endfunction
|
||||
@ -567,14 +567,18 @@ function! go#debug#Start(is_test, ...) abort
|
||||
endif
|
||||
let l:cmd += l:args
|
||||
|
||||
call go#util#EchoProgress('Starting GoDebug...')
|
||||
let s:state['message'] = []
|
||||
let s:state['job'] = job_start(l:cmd, {
|
||||
\ 'out_cb': function('s:out_cb'),
|
||||
\ 'err_cb': function('s:err_cb'),
|
||||
\ 'exit_cb': function('s:exit'),
|
||||
\ 'stoponexit': 'kill',
|
||||
\})
|
||||
let l:opts = {
|
||||
\ 'for': '_',
|
||||
\ 'statustype': 'debug',
|
||||
\ 'complete': function('s:complete'),
|
||||
\ }
|
||||
let l:opts = go#job#Options(l:opts)
|
||||
let l:opts.out_cb = function('s:out_cb')
|
||||
let l:opts.err_cb = function('s:err_cb')
|
||||
let l:opts.stoponexit = 'kill'
|
||||
|
||||
let s:state['job'] = go#job#Start(l:cmd, l:opts)
|
||||
catch
|
||||
call go#util#EchoError(v:exception)
|
||||
endtry
|
||||
|
@ -42,20 +42,20 @@ function! go#def#Jump(mode) abort
|
||||
|
||||
call extend(cmd, ["definition", fname . ':#' . go#util#OffsetCursor()])
|
||||
|
||||
if go#util#has_job() || has('nvim')
|
||||
if go#util#has_job()
|
||||
let l:state = {}
|
||||
let l:spawn_args = {
|
||||
\ 'cmd': cmd,
|
||||
\ 'complete': function('s:jump_to_declaration_cb', [a:mode, bin_name]),
|
||||
\ 'complete': function('s:jump_to_declaration_cb', [a:mode, bin_name], l:state),
|
||||
\ 'for': '_',
|
||||
\ 'statustype': 'searching declaration',
|
||||
\ }
|
||||
|
||||
if &modified
|
||||
let l:spawn_args.input = stdin_content
|
||||
endif
|
||||
|
||||
call go#util#EchoProgress("searching declaration ...")
|
||||
|
||||
call s:def_job(spawn_args)
|
||||
call s:def_job(spawn_args, l:state)
|
||||
return
|
||||
endif
|
||||
|
||||
@ -77,13 +77,17 @@ function! go#def#Jump(mode) abort
|
||||
call go#def#jump_to_declaration(out, a:mode, bin_name)
|
||||
endfunction
|
||||
|
||||
function! s:jump_to_declaration_cb(mode, bin_name, job, exit_status, data) abort
|
||||
function! s:jump_to_declaration_cb(mode, bin_name, job, exit_status, data) abort dict
|
||||
if a:exit_status != 0
|
||||
return
|
||||
endif
|
||||
|
||||
call go#def#jump_to_declaration(a:data[0], a:mode, a:bin_name)
|
||||
call go#util#EchoSuccess(fnamemodify(a:data[0], ":t"))
|
||||
|
||||
" capture the active window so that after the exit_cb and close_cb callbacks
|
||||
" can return to it when a:mode caused a split.
|
||||
let self.winid = win_getid(winnr())
|
||||
endfunction
|
||||
|
||||
function! go#def#jump_to_declaration(out, mode, bin_name) abort
|
||||
@ -283,9 +287,26 @@ function! go#def#Stack(...) abort
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function s:def_job(args) abort
|
||||
function s:def_job(args, state) abort
|
||||
let l:start_options = go#job#Options(a:args)
|
||||
|
||||
let l:state = a:state
|
||||
function! s:exit_cb(next, job, exitval) dict
|
||||
call call(a:next, [a:job, a:exitval])
|
||||
if has_key(self, 'winid')
|
||||
call win_gotoid(self.winid)
|
||||
endif
|
||||
endfunction
|
||||
let l:start_options.exit_cb = funcref('s:exit_cb', [l:start_options.exit_cb], l:state)
|
||||
|
||||
function! s:close_cb(next, ch) dict
|
||||
call call(a:next, [a:ch])
|
||||
if has_key(self, 'winid')
|
||||
call win_gotoid(self.winid)
|
||||
endif
|
||||
endfunction
|
||||
let l:start_options.close_cb = funcref('s:close_cb', [l:start_options.close_cb], l:state)
|
||||
|
||||
if &modified
|
||||
let l:tmpname = tempname()
|
||||
call writefile(split(a:args.input, "\n"), l:tmpname, "b")
|
||||
@ -293,7 +314,7 @@ function s:def_job(args) abort
|
||||
let l:start_options.in_name = l:tmpname
|
||||
endif
|
||||
|
||||
call go#job#Start(a:args.cmd, start_options)
|
||||
call go#job#Start(a:args.cmd, l:start_options)
|
||||
endfunction
|
||||
|
||||
" vim: sw=2 ts=2 et
|
||||
|
@ -45,7 +45,7 @@ func! Test_Jump_leaves_lists() abort
|
||||
call setqflist(copy(expected), 'r' )
|
||||
|
||||
let l:bufnr = bufnr('%')
|
||||
call cursor(6, 3)
|
||||
call cursor(6, 7)
|
||||
call go#def#Jump('')
|
||||
|
||||
let start = reltime()
|
||||
|
@ -106,64 +106,6 @@ function! s:sync_guru(args) abort
|
||||
return l:out
|
||||
endfunc
|
||||
|
||||
" use vim or neovim job api as appropriate
|
||||
function! s:job_start(cmd, start_options) abort
|
||||
if go#util#has_job()
|
||||
return job_start(a:cmd, a:start_options)
|
||||
endif
|
||||
|
||||
let opts = {'stdout_buffered': v:true, 'stderr_buffered': v:true}
|
||||
|
||||
let stdout_buf = ""
|
||||
function opts.on_stdout(job_id, data, event) closure
|
||||
let l:data = a:data
|
||||
let l:data[0] = stdout_buf . l:data[0]
|
||||
let stdout_buf = ""
|
||||
|
||||
if l:data[-1] != ""
|
||||
let stdout_buf = l:data[-1]
|
||||
endif
|
||||
|
||||
let l:data = l:data[:-2]
|
||||
if len(l:data) == 0
|
||||
return
|
||||
endif
|
||||
|
||||
call a:start_options.callback(a:job_id, join(l:data, "\n"))
|
||||
endfunction
|
||||
|
||||
let stderr_buf = ""
|
||||
function opts.on_stderr(job_id, data, event) closure
|
||||
let l:data = a:data
|
||||
let l:data[0] = stderr_buf . l:data[0]
|
||||
let stderr_buf = ""
|
||||
|
||||
if l:data[-1] != ""
|
||||
let stderr_buf = l:data[-1]
|
||||
endif
|
||||
|
||||
let l:data = l:data[:-2]
|
||||
if len(l:data) == 0
|
||||
return
|
||||
endif
|
||||
|
||||
call a:start_options.callback(a:job_id, join(l:data, "\n"))
|
||||
endfunction
|
||||
|
||||
function opts.on_exit(job_id, exit_code, event) closure
|
||||
call a:start_options.exit_cb(a:job_id, a:exit_code)
|
||||
call a:start_options.close_cb(a:job_id)
|
||||
endfunction
|
||||
|
||||
" use a shell for input redirection if needed
|
||||
let cmd = a:cmd
|
||||
if has_key(a:start_options, 'in_io') && a:start_options.in_io ==# 'file' && !empty(a:start_options.in_name)
|
||||
let cmd = ['/bin/sh', '-c', go#util#Shelljoin(a:cmd) . ' <' . a:start_options.in_name]
|
||||
endif
|
||||
|
||||
return jobstart(cmd, opts)
|
||||
endfunction
|
||||
|
||||
" async_guru runs guru in async mode with the given arguments
|
||||
function! s:async_guru(args) abort
|
||||
let result = s:guru_cmd(a:args)
|
||||
@ -172,91 +114,50 @@ function! s:async_guru(args) abort
|
||||
return
|
||||
endif
|
||||
|
||||
if !has_key(a:args, 'disable_progress')
|
||||
if a:args.needs_scope
|
||||
call go#util#EchoProgress("analysing with scope " . result.scope .
|
||||
\ " (see ':help go-guru-scope' if this doesn't work)...")
|
||||
endif
|
||||
endif
|
||||
|
||||
let state = {
|
||||
\ 'status_dir': expand('%:p:h'),
|
||||
\ 'statusline_type': printf("%s", a:args.mode),
|
||||
\ 'mode': a:args.mode,
|
||||
\ 'status': {},
|
||||
\ 'exitval': 0,
|
||||
\ 'closed': 0,
|
||||
\ 'exited': 0,
|
||||
\ 'messages': [],
|
||||
\ 'parse' : get(a:args, 'custom_parse', funcref("s:parse_guru_output"))
|
||||
\ }
|
||||
|
||||
function! s:callback(chan, msg) dict
|
||||
call add(self.messages, a:msg)
|
||||
function! s:complete(job, exit_status, messages) dict abort
|
||||
let output = join(a:messages, "\n")
|
||||
call self.parse(a:exit_status, output, self.mode)
|
||||
endfunction
|
||||
" explicitly bind complete to state so that within it, self will
|
||||
" always refer to state. See :help Partial for more information.
|
||||
let state.complete = function('s:complete', [], state)
|
||||
|
||||
function! s:exit_cb(job, exitval) dict
|
||||
let self.exited = 1
|
||||
let opts = {
|
||||
\ 'statustype': get(a:args, 'statustype', a:args.mode),
|
||||
\ 'for': '_',
|
||||
\ 'errorformat': "%f:%l.%c-%[%^:]%#:\ %m,%f:%l:%c:\ %m",
|
||||
\ 'complete': state.complete,
|
||||
\ }
|
||||
|
||||
let status = {
|
||||
\ 'desc': 'last status',
|
||||
\ 'type': self.statusline_type,
|
||||
\ 'state': "finished",
|
||||
\ }
|
||||
if has_key(a:args, 'disable_progress')
|
||||
let opts.statustype = ''
|
||||
endif
|
||||
|
||||
if a:exitval
|
||||
let self.exitval = a:exitval
|
||||
let status.state = "failed"
|
||||
endif
|
||||
|
||||
call go#statusline#Update(self.status_dir, status)
|
||||
|
||||
if self.closed
|
||||
call self.complete()
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:close_cb(ch) dict
|
||||
let self.closed = 1
|
||||
|
||||
if self.exited
|
||||
call self.complete()
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function state.complete() dict
|
||||
let out = join(self.messages, "\n")
|
||||
|
||||
call self.parse(self.exitval, out, self.mode)
|
||||
endfunction
|
||||
|
||||
" explicitly bind the callbacks to state so that self within them always
|
||||
" refers to state. See :help Partial for more information.
|
||||
let start_options = {
|
||||
\ 'callback': function('s:callback', [], state),
|
||||
\ 'exit_cb': function('s:exit_cb', [], state),
|
||||
\ 'close_cb': function('s:close_cb', [], state)
|
||||
\ }
|
||||
let opts = go#job#Options(l:opts)
|
||||
|
||||
if has_key(result, 'stdin_content')
|
||||
let l:tmpname = tempname()
|
||||
call writefile(split(result.stdin_content, "\n"), l:tmpname, "b")
|
||||
let l:start_options.in_io = "file"
|
||||
let l:start_options.in_name = l:tmpname
|
||||
let l:opts.in_io = "file"
|
||||
let l:opts.in_name = l:tmpname
|
||||
endif
|
||||
|
||||
call go#statusline#Update(state.status_dir, {
|
||||
\ 'desc': "current status",
|
||||
\ 'type': state.statusline_type,
|
||||
\ 'state': "analysing",
|
||||
\})
|
||||
call go#job#Start(result.cmd, opts)
|
||||
|
||||
return s:job_start(result.cmd, start_options)
|
||||
if a:args.needs_scope && go#config#EchoCommandInfo() && !has_key(a:args, 'disable_progress')
|
||||
call go#util#EchoProgress("analysing with scope " . result.scope .
|
||||
\ " (see ':help go-guru-scope' if this doesn't work)...")
|
||||
endif
|
||||
endfunc
|
||||
|
||||
" run_guru runs the given guru argument
|
||||
function! s:run_guru(args) abort
|
||||
if has('nvim') || go#util#has_job()
|
||||
if go#util#has_job()
|
||||
let res = s:async_guru(a:args)
|
||||
else
|
||||
let res = s:sync_guru(a:args)
|
||||
@ -320,7 +221,7 @@ function! go#guru#Describe(selected) abort
|
||||
call s:run_guru(args)
|
||||
endfunction
|
||||
|
||||
function! go#guru#DescribeInfo() abort
|
||||
function! go#guru#DescribeInfo(showstatus) abort
|
||||
" json_encode() and friends are introduced with this patch (7.4.1304)
|
||||
" vim: https://groups.google.com/d/msg/vim_dev/vLupTNhQhZ8/cDGIk0JEDgAJ
|
||||
" nvim: https://github.com/neovim/neovim/pull/4131
|
||||
@ -411,7 +312,7 @@ function! go#guru#DescribeInfo() abort
|
||||
return
|
||||
endif
|
||||
|
||||
call go#util#EchoInfo(info)
|
||||
echo "vim-go: " | echohl Function | echon info | echohl None
|
||||
endfunction
|
||||
|
||||
let args = {
|
||||
@ -504,7 +405,7 @@ function! go#guru#Referrers(selected) abort
|
||||
call s:run_guru(args)
|
||||
endfunction
|
||||
|
||||
function! go#guru#SameIds() abort
|
||||
function! go#guru#SameIds(showstatus) abort
|
||||
" we use matchaddpos() which was introduce with 7.4.330, be sure we have
|
||||
" it: http://ftp.vim.org/vim/patches/7.4/7.4.330
|
||||
if !exists("*matchaddpos")
|
||||
@ -527,6 +428,9 @@ function! go#guru#SameIds() abort
|
||||
\ 'needs_scope': 0,
|
||||
\ 'custom_parse': function('s:same_ids_highlight'),
|
||||
\ }
|
||||
if !a:showstatus
|
||||
let args.disable_progress = 1
|
||||
endif
|
||||
|
||||
call s:run_guru(args)
|
||||
endfunction
|
||||
|
@ -65,6 +65,9 @@ function! go#import#SwitchImport(enabled, localname, path, bang) abort
|
||||
let packageline = line
|
||||
let appendline = line
|
||||
|
||||
elseif linestr =~# '^import\s\+(\+)'
|
||||
let appendline = line
|
||||
let appendstr = qlocalpath
|
||||
elseif linestr =~# '^import\s\+('
|
||||
let appendstr = qlocalpath
|
||||
let indentstr = 1
|
||||
@ -161,8 +164,16 @@ function! go#import#SwitchImport(enabled, localname, path, bang) abort
|
||||
let linesdelta += 3
|
||||
let appendstr = qlocalpath
|
||||
let indentstr = 1
|
||||
call append(appendline, appendstr)
|
||||
elseif getline(appendline) =~# '^import\s\+(\+)'
|
||||
call setline(appendline, 'import (')
|
||||
call append(appendline + 0, appendstr)
|
||||
call append(appendline + 1, ')')
|
||||
let linesdelta -= 1
|
||||
let indentstr = 1
|
||||
else
|
||||
call append(appendline, appendstr)
|
||||
endif
|
||||
call append(appendline, appendstr)
|
||||
execute appendline + 1
|
||||
if indentstr
|
||||
execute 'normal! >>'
|
||||
|
22
sources_non_forked/vim-go/autoload/go/indent_test.vim
Normal file
22
sources_non_forked/vim-go/autoload/go/indent_test.vim
Normal file
@ -0,0 +1,22 @@
|
||||
func! Test_indent_raw_string() abort
|
||||
try
|
||||
let l:dir= gotest#write_file('indent/indent.go', [
|
||||
\ 'package main',
|
||||
\ '',
|
||||
\ 'import "fmt"',
|
||||
\ '',
|
||||
\ 'func main() {',
|
||||
\ "\t\x1fconst msg = `",
|
||||
\ '`',
|
||||
\ '\tfmt.Println(msg)',
|
||||
\ '}'])
|
||||
|
||||
silent execute "normal o" . "not indented\<Esc>"
|
||||
let l:indent = indent(line('.'))
|
||||
call assert_equal(0, l:indent)
|
||||
finally
|
||||
call delete(l:dir, 'rf')
|
||||
endtry
|
||||
endfunc
|
||||
|
||||
" vim: sw=2 ts=2 et
|
@ -33,7 +33,10 @@ endfunction
|
||||
" function will be passed three arguments: the job, its exit code, and the
|
||||
" list of messages received from the channel. The default is a no-op. A
|
||||
" custom value can modify the messages before they are processed by the
|
||||
" returned exit_cb and close_cb callbacks.
|
||||
" returned exit_cb and close_cb callbacks. When the function is called,
|
||||
" the current window will be the window that was hosting the buffer when
|
||||
" the job was started. After it returns, the current window will be
|
||||
" restored to what it was before the function was called.
|
||||
|
||||
" The return value is a dictionary with these keys:
|
||||
" 'callback':
|
||||
@ -87,14 +90,27 @@ function! go#job#Options(args)
|
||||
|
||||
" do nothing in state.complete by default.
|
||||
function state.complete(job, exit_status, data)
|
||||
if has_key(self, 'custom_complete')
|
||||
let l:winid = win_getid(winnr())
|
||||
" Always set the active window to the window that was active when the job
|
||||
" was started. Among other things, this makes sure that the correct
|
||||
" window's location list will be populated when the list type is
|
||||
" 'location' and the user has moved windows since starting the job.
|
||||
call win_gotoid(self.winid)
|
||||
call self.custom_complete(a:job, a:exit_status, a:data)
|
||||
call win_gotoid(l:winid)
|
||||
endif
|
||||
|
||||
call self.show_errors(a:job, a:exit_status, a:data)
|
||||
endfunction
|
||||
|
||||
function state.show_status(job, exit_status) dict
|
||||
if self.statustype == ''
|
||||
return
|
||||
endif
|
||||
|
||||
if go#config#EchoCommandInfo()
|
||||
let prefix = ""
|
||||
if self.statustype != ''
|
||||
let prefix = '[' . self.statustype . '] '
|
||||
endif
|
||||
let prefix = '[' . self.statustype . '] '
|
||||
if a:exit_status == 0
|
||||
call go#util#EchoSuccess(prefix . "SUCCESS")
|
||||
else
|
||||
@ -102,10 +118,6 @@ function! go#job#Options(args)
|
||||
endif
|
||||
endif
|
||||
|
||||
if self.statustype == ''
|
||||
return
|
||||
endif
|
||||
|
||||
let status = {
|
||||
\ 'desc': 'last status',
|
||||
\ 'type': self.statustype,
|
||||
@ -127,10 +139,15 @@ function! go#job#Options(args)
|
||||
endfunction
|
||||
|
||||
if has_key(a:args, 'complete')
|
||||
let state.complete = a:args.complete
|
||||
let state.custom_complete = a:args.complete
|
||||
endif
|
||||
|
||||
function! s:start(args) dict
|
||||
if go#config#EchoCommandInfo() && self.statustype != ""
|
||||
let prefix = '[' . self.statustype . '] '
|
||||
call go#util#EchoSuccess(prefix . "dispatched")
|
||||
endif
|
||||
|
||||
if self.statustype != ''
|
||||
let status = {
|
||||
\ 'desc': 'current status',
|
||||
@ -164,7 +181,6 @@ function! go#job#Options(args)
|
||||
|
||||
if self.closed || has('nvim')
|
||||
call self.complete(a:job, self.exit_status, self.messages)
|
||||
call self.show_errors(a:job, self.exit_status, self.messages)
|
||||
endif
|
||||
endfunction
|
||||
" explicitly bind exit_cb to state so that within it, self will always refer
|
||||
@ -177,7 +193,6 @@ function! go#job#Options(args)
|
||||
if self.exited
|
||||
let job = ch_getjob(a:ch)
|
||||
call self.complete(job, self.exit_status, self.messages)
|
||||
call self.show_errors(job, self.exit_status, self.messages)
|
||||
endif
|
||||
endfunction
|
||||
" explicitly bind close_cb to state so that within it, self will
|
||||
@ -225,7 +240,7 @@ function! go#job#Options(args)
|
||||
|
||||
if empty(errors)
|
||||
" failed to parse errors, output the original content
|
||||
call go#util#EchoError(self.messages + [self.dir])
|
||||
call go#util#EchoError([self.dir] + self.messages)
|
||||
call win_gotoid(l:winid)
|
||||
return
|
||||
endif
|
||||
@ -254,10 +269,21 @@ function! go#job#Start(cmd, options)
|
||||
let l:options = s:neooptions(l:options)
|
||||
endif
|
||||
|
||||
" Verify that the working directory for the job actually exists. Return
|
||||
" early if the directory does not exist. This helps avoid errors when
|
||||
" working with plugins that use virtual files that don't actually exist on
|
||||
" the file system.
|
||||
let filedir = expand("%:p:h")
|
||||
if has_key(l:options, 'cwd') && !isdirectory(l:options.cwd)
|
||||
return
|
||||
elseif !isdirectory(filedir)
|
||||
return
|
||||
endif
|
||||
|
||||
if !has_key(l:options, 'cwd')
|
||||
" pre start
|
||||
let dir = getcwd()
|
||||
execute l:cd fnameescape(expand("%:p:h"))
|
||||
execute l:cd fnameescape(filedir)
|
||||
endif
|
||||
|
||||
if has_key(l:options, '_start')
|
||||
@ -267,11 +293,10 @@ function! go#job#Start(cmd, options)
|
||||
unlet l:options._start
|
||||
endif
|
||||
|
||||
|
||||
if has('nvim')
|
||||
let l:input = []
|
||||
if has_key(l:options, 'in_io') && l:options.in_io ==# 'file' && !empty(l:options.in_name)
|
||||
let l:input = readfile(l:options.in_name, 1)
|
||||
if has_key(a:options, 'in_io') && a:options.in_io ==# 'file' && !empty(a:options.in_name)
|
||||
let l:input = readfile(a:options.in_name, "b")
|
||||
endif
|
||||
|
||||
let job = jobstart(a:cmd, l:options)
|
||||
@ -306,49 +331,77 @@ function! s:neooptions(options)
|
||||
continue
|
||||
endif
|
||||
|
||||
" dealing with the channel lines of Neovim sucks. The docs (:help
|
||||
" channel-lines) say:
|
||||
" stream event handlers may receive partial (incomplete) lines. For a
|
||||
" given invocation of on_stdout etc, `a:data` is not guaranteed to end
|
||||
" with a newline.
|
||||
" - `abcdefg` may arrive as `['abc']`, `['defg']`.
|
||||
" - `abc\nefg` may arrive as `['abc', '']`, `['efg']` or `['abc']`,
|
||||
" `['','efg']`, or even `['ab']`, `['c','efg']`.
|
||||
if key == 'callback'
|
||||
let l:options['callback'] = a:options['callback']
|
||||
|
||||
if !has_key(a:options, 'out_cb')
|
||||
let l:options['stdout_buffered'] = v:true
|
||||
|
||||
function! s:callback2on_stdout(ch, data, event) dict
|
||||
let l:data = a:data
|
||||
let l:data[0] = self.stdout_buf . l:data[0]
|
||||
let self.stdout_buf = ""
|
||||
" a single empty string means EOF was reached.
|
||||
if len(a:data) == 1 && a:data[0] == ''
|
||||
" when there's nothing buffered, return early so that an
|
||||
" erroneous message will not be added.
|
||||
if self.stdout_buf == ''
|
||||
return
|
||||
endif
|
||||
|
||||
if l:data[-1] != ""
|
||||
let l:data = [self.stdout_buf]
|
||||
let self.stdout_buf = ''
|
||||
else
|
||||
let l:data = copy(a:data)
|
||||
let l:data[0] = self.stdout_buf . l:data[0]
|
||||
|
||||
" The last element may be a partial line; save it for next time.
|
||||
let self.stdout_buf = l:data[-1]
|
||||
|
||||
let l:data = l:data[:-2]
|
||||
|
||||
if len(l:data) == 0
|
||||
return
|
||||
endif
|
||||
endif
|
||||
|
||||
let l:data = l:data[:-2]
|
||||
if len(l:data) == 0
|
||||
return
|
||||
endif
|
||||
|
||||
call self.callback(a:ch, join(l:data, "\n"))
|
||||
for l:msg in l:data
|
||||
call self.callback(a:ch, l:msg)
|
||||
endfor
|
||||
endfunction
|
||||
let l:options['on_stdout'] = function('s:callback2on_stdout', [], l:options)
|
||||
endif
|
||||
|
||||
if !has_key(a:options, 'err_cb')
|
||||
let l:options['stderr_buffered'] = v:true
|
||||
|
||||
function! s:callback2on_stderr(ch, data, event) dict
|
||||
let l:data = a:data
|
||||
let l:data[0] = self.stderr_buf . l:data[0]
|
||||
let self.stderr_buf = ""
|
||||
" a single empty string means EOF was reached.
|
||||
if len(a:data) == 1 && a:data[0] == ''
|
||||
" when there's nothing buffered, return early so that an
|
||||
" erroneous message will not be added.
|
||||
if self.stderr_buf == ''
|
||||
return
|
||||
endif
|
||||
let l:data = [self.stderr_buf]
|
||||
let self.stderr_buf = ''
|
||||
else
|
||||
let l:data = copy(a:data)
|
||||
let l:data[0] = self.stderr_buf . l:data[0]
|
||||
|
||||
if l:data[-1] != ""
|
||||
" The last element may be a partial line; save it for next time.
|
||||
let self.stderr_buf = l:data[-1]
|
||||
|
||||
let l:data = l:data[:-2]
|
||||
if len(l:data) == 0
|
||||
return
|
||||
endif
|
||||
endif
|
||||
|
||||
let l:data = l:data[:-2]
|
||||
if len(l:data) == 0
|
||||
return
|
||||
endif
|
||||
|
||||
call self.callback(a:ch, join(l:data, "\n"))
|
||||
for l:msg in l:data
|
||||
call self.callback(a:ch, l:msg)
|
||||
endfor
|
||||
endfunction
|
||||
let l:options['on_stderr'] = function('s:callback2on_stderr', [], l:options)
|
||||
endif
|
||||
@ -358,22 +411,32 @@ function! s:neooptions(options)
|
||||
|
||||
if key == 'out_cb'
|
||||
let l:options['out_cb'] = a:options['out_cb']
|
||||
let l:options['stdout_buffered'] = v:true
|
||||
function! s:on_stdout(ch, data, event) dict
|
||||
let l:data = a:data
|
||||
let l:data[0] = self.stdout_buf . l:data[0]
|
||||
let self.stdout_buf = ""
|
||||
" a single empty string means EOF was reached.
|
||||
if len(a:data) == 1 && a:data[0] == ''
|
||||
" when there's nothing buffered, return early so that an
|
||||
" erroneous message will not be added.
|
||||
if self.stdout_buf == ''
|
||||
return
|
||||
endif
|
||||
let l:data = [self.stdout_buf]
|
||||
let self.stdout_buf = ''
|
||||
else
|
||||
let l:data = copy(a:data)
|
||||
let l:data[0] = self.stdout_buf . l:data[0]
|
||||
|
||||
if l:data[-1] != ""
|
||||
" The last element may be a partial line; save it for next time.
|
||||
let self.stdout_buf = l:data[-1]
|
||||
|
||||
let l:data = l:data[:-2]
|
||||
if len(l:data) == 0
|
||||
return
|
||||
endif
|
||||
endif
|
||||
|
||||
let l:data = l:data[:-2]
|
||||
if len(l:data) == 0
|
||||
return
|
||||
endif
|
||||
|
||||
call self.out_cb(a:ch, join(l:data, "\n"))
|
||||
for l:msg in l:data
|
||||
call self.out_cb(a:ch, l:msg)
|
||||
endfor
|
||||
endfunction
|
||||
let l:options['on_stdout'] = function('s:on_stdout', [], l:options)
|
||||
|
||||
@ -382,22 +445,32 @@ function! s:neooptions(options)
|
||||
|
||||
if key == 'err_cb'
|
||||
let l:options['err_cb'] = a:options['err_cb']
|
||||
let l:options['stderr_buffered'] = v:true
|
||||
function! s:on_stderr(ch, data, event) dict
|
||||
let l:data = a:data
|
||||
let l:data[0] = self.stderr_buf . l:data[0]
|
||||
let self.stderr_buf = ""
|
||||
" a single empty string means EOF was reached.
|
||||
if len(a:data) == 1 && a:data[0] == ''
|
||||
" when there's nothing buffered, return early so that an
|
||||
" erroneous message will not be added.
|
||||
if self.stderr_buf == ''
|
||||
return
|
||||
endif
|
||||
let l:data = [self.stderr_buf]
|
||||
let self.stderr_buf = ''
|
||||
else
|
||||
let l:data = copy(a:data)
|
||||
let l:data[0] = self.stderr_buf . l:data[0]
|
||||
|
||||
if l:data[-1] != ""
|
||||
" The last element may be a partial line; save it for next time.
|
||||
let self.stderr_buf = l:data[-1]
|
||||
|
||||
let l:data = l:data[:-2]
|
||||
if len(l:data) == 0
|
||||
return
|
||||
endif
|
||||
endif
|
||||
|
||||
let l:data = l:data[:-2]
|
||||
if len(l:data) == 0
|
||||
return
|
||||
endif
|
||||
|
||||
call self.err_cb(a:ch, join(l:data, "\n"))
|
||||
for l:msg in l:data
|
||||
call self.err_cb(a:ch, l:msg)
|
||||
endfor
|
||||
endfunction
|
||||
let l:options['on_stderr'] = function('s:on_stderr', [], l:options)
|
||||
|
||||
@ -418,6 +491,12 @@ function! s:neooptions(options)
|
||||
continue
|
||||
endif
|
||||
|
||||
if key == 'stoponexit'
|
||||
if a:options['stoponexit'] == ''
|
||||
let l:options['detach'] = 1
|
||||
endif
|
||||
continue
|
||||
endif
|
||||
endfor
|
||||
return l:options
|
||||
endfunction
|
||||
|
@ -42,7 +42,7 @@ function! go#lint#Gometa(autosave, ...) abort
|
||||
|
||||
" Include only messages for the active buffer for autosave.
|
||||
let include = [printf('--include=^%s:.*$', fnamemodify(expand('%:p'), ":."))]
|
||||
if go#util#has_job() || has('nvim')
|
||||
if go#util#has_job()
|
||||
let include = [printf('--include=^%s:.*$', expand('%:p:t'))]
|
||||
endif
|
||||
let cmd += include
|
||||
@ -56,7 +56,7 @@ function! go#lint#Gometa(autosave, ...) abort
|
||||
|
||||
let cmd += goargs
|
||||
|
||||
if go#util#has_job() || has('nvim')
|
||||
if go#util#has_job()
|
||||
call s:lint_job({'cmd': cmd}, a:autosave)
|
||||
return
|
||||
endif
|
||||
@ -207,36 +207,10 @@ function! s:lint_job(args, autosave)
|
||||
let l:opts.for = "GoMetaLinterAutoSave"
|
||||
endif
|
||||
|
||||
let l:cbs = go#job#Options(l:opts)
|
||||
|
||||
if a:autosave
|
||||
" move to the window that was active before processing the errors, because
|
||||
" the user may have moved around within the window or even moved to a
|
||||
" different window since saving. Moving back to current window as of the
|
||||
" start of this function avoids the perception that the quickfix window
|
||||
" steals focus when linting takes a while.
|
||||
|
||||
function! s:exit_cb(next, job, exitval)
|
||||
let l:winid = win_getid(winnr())
|
||||
call call(a:next, [a:job, a:exitval])
|
||||
call win_gotoid(l:winid)
|
||||
endfunction
|
||||
" wrap l:cbs.exit_cb in s:exit_cb.
|
||||
let l:cbs.exit_cb = funcref('s:exit_cb', [l:cbs.exit_cb])
|
||||
|
||||
function! s:close_cb(next, ch)
|
||||
let l:winid = win_getid(winnr())
|
||||
call call(a:next, [a:ch])
|
||||
call win_gotoid(l:winid)
|
||||
endfunction
|
||||
" wrap l:cbs.close_cb in s:close_cb.
|
||||
let l:cbs.close_cb = funcref('s:close_cb', [l:cbs.close_cb])
|
||||
endif
|
||||
|
||||
" autowrite is not enabled for jobs
|
||||
call go#cmd#autowrite()
|
||||
|
||||
call go#job#Start(a:args.cmd, l:cbs)
|
||||
call go#job#Spawn(a:args.cmd, l:opts)
|
||||
endfunction
|
||||
|
||||
" vim: sw=2 ts=2 et
|
||||
|
@ -141,6 +141,7 @@ let s:default_list_type_commands = {
|
||||
\ "GoLint": "quickfix",
|
||||
\ "GoMetaLinter": "quickfix",
|
||||
\ "GoMetaLinterAutoSave": "locationlist",
|
||||
\ "GoModFmt": "locationlist",
|
||||
\ "GoModifyTags": "locationlist",
|
||||
\ "GoRename": "quickfix",
|
||||
\ "GoRun": "quickfix",
|
||||
|
140
sources_non_forked/vim-go/autoload/go/mod.vim
Normal file
140
sources_non_forked/vim-go/autoload/go/mod.vim
Normal file
@ -0,0 +1,140 @@
|
||||
let s:go_major_version = ""
|
||||
|
||||
function! go#mod#Format() abort
|
||||
" go mod only exists in `v1.11`
|
||||
if empty(s:go_major_version)
|
||||
let tokens = matchlist(go#util#System("go version"), '\d\+.\(\d\+\) ')
|
||||
let s:go_major_version = str2nr(tokens[1])
|
||||
endif
|
||||
|
||||
if s:go_major_version < "11"
|
||||
call go#util#EchoError("Go v1.11 is required to format go.mod file")
|
||||
return
|
||||
endif
|
||||
|
||||
let fname = fnamemodify(expand("%"), ':p:gs?\\?/?')
|
||||
|
||||
" Save cursor position and many other things.
|
||||
let l:curw = winsaveview()
|
||||
|
||||
" Write current unsaved buffer to a temp file
|
||||
let l:tmpname = tempname() . '.mod'
|
||||
call writefile(go#util#GetLines(), l:tmpname)
|
||||
if go#util#IsWin()
|
||||
let l:tmpname = tr(l:tmpname, '\', '/')
|
||||
endif
|
||||
|
||||
let current_col = col('.')
|
||||
let l:args = ['go', 'mod', 'edit', '--fmt', l:tmpname]
|
||||
let [l:out, l:err] = go#util#Exec(l:args)
|
||||
let diff_offset = len(readfile(l:tmpname)) - line('$')
|
||||
|
||||
if l:err == 0
|
||||
call go#mod#update_file(l:tmpname, fname)
|
||||
else
|
||||
let errors = s:parse_errors(fname, l:out)
|
||||
call s:show_errors(errors)
|
||||
endif
|
||||
|
||||
" We didn't use the temp file, so clean up
|
||||
call delete(l:tmpname)
|
||||
|
||||
" Restore our cursor/windows positions.
|
||||
call winrestview(l:curw)
|
||||
|
||||
" be smart and jump to the line the new statement was added/removed
|
||||
call cursor(line('.') + diff_offset, current_col)
|
||||
|
||||
" Syntax highlighting breaks less often.
|
||||
syntax sync fromstart
|
||||
endfunction
|
||||
|
||||
" update_file updates the target file with the given formatted source
|
||||
function! go#mod#update_file(source, target)
|
||||
" remove undo point caused via BufWritePre
|
||||
try | silent undojoin | catch | endtry
|
||||
|
||||
let old_fileformat = &fileformat
|
||||
if exists("*getfperm")
|
||||
" save file permissions
|
||||
let original_fperm = getfperm(a:target)
|
||||
endif
|
||||
|
||||
call rename(a:source, a:target)
|
||||
|
||||
" restore file permissions
|
||||
if exists("*setfperm") && original_fperm != ''
|
||||
call setfperm(a:target , original_fperm)
|
||||
endif
|
||||
|
||||
" reload buffer to reflect latest changes
|
||||
silent edit!
|
||||
|
||||
let &fileformat = old_fileformat
|
||||
let &syntax = &syntax
|
||||
|
||||
let l:listtype = go#list#Type("GoModFmt")
|
||||
|
||||
" the title information was introduced with 7.4-2200
|
||||
" https://github.com/vim/vim/commit/d823fa910cca43fec3c31c030ee908a14c272640
|
||||
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
|
||||
|
||||
if has_key(l:list_title, "title") && l:list_title['title'] == "Format"
|
||||
call go#list#Clean(l:listtype)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" parse_errors parses the given errors and returns a list of parsed errors
|
||||
function! s:parse_errors(filename, content) abort
|
||||
let splitted = split(a:content, '\n')
|
||||
|
||||
" list of errors to be put into location list
|
||||
let errors = []
|
||||
for line in splitted
|
||||
let tokens = matchlist(line, '^\(.\{-}\):\(\d\+\):\s*\(.*\)')
|
||||
if !empty(tokens)
|
||||
call add(errors,{
|
||||
\"filename": a:filename,
|
||||
\"lnum": tokens[2],
|
||||
\"text": tokens[3],
|
||||
\ })
|
||||
endif
|
||||
endfor
|
||||
|
||||
return errors
|
||||
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("GoModFmt")
|
||||
if !empty(a:errors)
|
||||
call go#list#Populate(l:listtype, a:errors, 'Format')
|
||||
call go#util#EchoError("GoModFmt returned error")
|
||||
endif
|
||||
|
||||
" this closes the window if there are no errors or it opens
|
||||
" it if there is any
|
||||
call go#list#Window(l:listtype, len(a:errors))
|
||||
endfunction
|
||||
|
||||
function! go#mod#ToggleModFmtAutoSave() abort
|
||||
if go#config#ModFmtAutosave()
|
||||
call go#config#SetModFmtAutosave(0)
|
||||
call go#util#EchoProgress("auto mod fmt disabled")
|
||||
return
|
||||
end
|
||||
|
||||
call go#config#SetModFmtAutosave(1)
|
||||
call go#util#EchoProgress("auto mod fmt enabled")
|
||||
endfunction
|
@ -27,8 +27,7 @@ function! go#rename#Rename(bang, ...) abort
|
||||
let offset = printf('%s:#%d', fname, pos)
|
||||
let cmd = [bin_path, "-offset", offset, "-to", to_identifier, '-tags', go#config#BuildTags()]
|
||||
|
||||
if go#util#has_job() || has('nvim')
|
||||
call go#util#EchoProgress(printf("renaming to '%s' ...", to_identifier))
|
||||
if go#util#has_job()
|
||||
call s:rename_job({
|
||||
\ 'cmd': cmd,
|
||||
\ 'bang': a:bang,
|
||||
|
@ -0,0 +1,9 @@
|
||||
package complete
|
||||
|
||||
type T struct {
|
||||
V string
|
||||
}
|
||||
|
||||
func Example(s string) {
|
||||
Example("")
|
||||
}
|
@ -26,19 +26,11 @@ function! go#test#Test(bang, compile, ...) abort
|
||||
call add(args, printf("-timeout=%s", timeout))
|
||||
endif
|
||||
|
||||
if go#config#EchoCommandInfo()
|
||||
if a:compile
|
||||
call go#util#EchoProgress("compiling tests ...")
|
||||
else
|
||||
call go#util#EchoProgress("testing...")
|
||||
endif
|
||||
endif
|
||||
|
||||
if has('nvim') && go#config#TermEnabled()
|
||||
call go#term#new(a:bang, ["go"] + args)
|
||||
endif
|
||||
|
||||
if go#util#has_job() || has('nvim')
|
||||
if go#util#has_job()
|
||||
" use vim's job functionality to call it asynchronously
|
||||
let job_options = {
|
||||
\ 'bang': a:bang,
|
||||
@ -55,6 +47,14 @@ function! go#test#Test(bang, compile, ...) abort
|
||||
return
|
||||
endif
|
||||
|
||||
if go#config#EchoCommandInfo()
|
||||
if a:compile
|
||||
call go#util#EchoProgress("compiling tests ...")
|
||||
else
|
||||
call go#util#EchoProgress("testing...")
|
||||
endif
|
||||
endif
|
||||
|
||||
call go#cmd#autowrite()
|
||||
redraw
|
||||
|
||||
@ -152,12 +152,12 @@ function! s:errorformat() abort
|
||||
" each level of test indents the test output 4 spaces. Capturing groups
|
||||
" (e.g. \(\)) cannot be used in an errorformat, but non-capturing groups can
|
||||
" (e.g. \%(\)).
|
||||
let indent = '%\\%( %\\)%#'
|
||||
let indent = '%\\%( %\\)'
|
||||
|
||||
" ignore `go test -v` output for starting tests
|
||||
let format = "%-G=== RUN %.%#"
|
||||
" ignore `go test -v` output for passing tests
|
||||
let format .= ",%-G" . indent . "--- PASS: %.%#"
|
||||
let format .= ",%-G" . indent . "%#--- PASS: %.%#"
|
||||
|
||||
" Match failure lines.
|
||||
"
|
||||
@ -167,24 +167,25 @@ function! s:errorformat() abort
|
||||
" e.g.:
|
||||
" '--- FAIL: TestSomething (0.00s)'
|
||||
if show_name
|
||||
let format .= ",%G" . indent . "--- FAIL: %m (%.%#)"
|
||||
let format .= ",%G" . indent . "%#--- FAIL: %m (%.%#)"
|
||||
else
|
||||
let format .= ",%-G" . indent . "--- FAIL: %.%#"
|
||||
let format .= ",%-G" . indent . "%#--- FAIL: %.%#"
|
||||
endif
|
||||
|
||||
" Go 1.10 test output {{{1
|
||||
" Matches test output lines.
|
||||
"
|
||||
" All test output lines start with the test indentation and a tab, followed
|
||||
" by the filename, a colon, the line number, another colon, a space, and the
|
||||
" message. e.g.:
|
||||
" '\ttime_test.go:30: Likely problem: the time zone files have not been installed.'
|
||||
let format .= ",%A" . indent . "%\\t%\\+%f:%l: %m"
|
||||
let format .= ",%A" . indent . "%#%\\t%\\+%f:%l: %m"
|
||||
" also match lines that don't have a message (i.e. the message begins with a
|
||||
" newline or is the empty string):
|
||||
" e.g.:
|
||||
" t.Errorf("\ngot %v; want %v", actual, expected)
|
||||
" t.Error("")
|
||||
let format .= ",%A" . indent . "%\\t%\\+%f:%l: "
|
||||
let format .= ",%A" . indent . "%#%\\t%\\+%f:%l: "
|
||||
|
||||
" Match the 2nd and later lines of multi-line output. These lines are
|
||||
" indented the number of spaces for the level of nesting of the test,
|
||||
@ -197,7 +198,17 @@ function! s:errorformat() abort
|
||||
" indicate that they're multiple lines of output, but in that case the lines
|
||||
" get concatenated in the quickfix list, which is not what users typically
|
||||
" want when writing a newline into their test output.
|
||||
let format .= ",%G" . indent . "%\\t%\\{2}%m"
|
||||
let format .= ",%G" . indent . "%#%\\t%\\{2}%m"
|
||||
" }}}1
|
||||
|
||||
" Go 1.11 test output {{{1
|
||||
" Match test output lines similarly to Go 1.10 test output lines, but they
|
||||
" use an indent level where the Go 1.10 test output uses tabs, so they'll
|
||||
" always have at least one level indentation...
|
||||
let format .= ",%A" . indent . "%\\+%f:%l: %m"
|
||||
let format .= ",%A" . indent . "%\\+%f:%l: "
|
||||
let format .= ",%G" . indent . "%\\{2\\,}%m"
|
||||
" }}}1
|
||||
|
||||
" set the format for panics.
|
||||
|
||||
@ -261,16 +272,16 @@ function! s:errorformat() abort
|
||||
let format .= ",%-Cexit status %[0-9]%\\+"
|
||||
"let format .= ",exit status %[0-9]%\\+"
|
||||
|
||||
" Match and ignore exit failure lines whether part of a multi-line message
|
||||
" Match and ignore failure lines whether part of a multi-line message
|
||||
" or not, because these lines sometimes come before and sometimes after
|
||||
" panic stacktraces.
|
||||
let format .= ",%-CFAIL%\\t%.%#"
|
||||
"let format .= ",FAIL%\\t%.%#"
|
||||
|
||||
" match compiler errors
|
||||
" These are very smilar to errors from test output, but lack leading tabs
|
||||
" for the first line of an error, and subsequent lines only have one tab
|
||||
" instead of two.
|
||||
" match compiler errors.
|
||||
" These are very smilar to errors from <=go1.10 test output, but lack
|
||||
" leading tabs for the first line of an error, and subsequent lines only
|
||||
" have one tab instead of two.
|
||||
let format .= ",%A%f:%l:%c: %m"
|
||||
let format .= ",%A%f:%l: %m"
|
||||
" It would be nice if this weren't necessary, but panic lines from tests are
|
||||
|
@ -74,7 +74,7 @@ endfunc
|
||||
|
||||
func! Test_GoTestVet() abort
|
||||
let expected = [
|
||||
\ {'lnum': 6, 'bufnr': 16, 'col': 0, 'valid': 1, 'vcol': 0, 'nr': -1, 'type': '', 'pattern': '', 'text': 'Errorf format %v reads arg #1, but call has only 0 args'},
|
||||
\ {'lnum': 6, 'bufnr': 16, 'col': 0, 'valid': 1, 'vcol': 0, 'nr': -1, 'type': '', 'pattern': '', 'text': 'Errorf format %v reads arg #1, but call has 0 args'},
|
||||
\ ]
|
||||
call s:test('veterror/veterror.go', expected)
|
||||
endfunc
|
||||
|
@ -76,12 +76,12 @@ function! go#tool#Imports() abort
|
||||
return imports
|
||||
endfunction
|
||||
|
||||
function! go#tool#Info() abort
|
||||
function! go#tool#Info(showstatus) abort
|
||||
let l:mode = go#config#InfoMode()
|
||||
if l:mode == 'gocode'
|
||||
call go#complete#Info()
|
||||
call go#complete#Info(a:showstatus)
|
||||
elseif l:mode == 'guru'
|
||||
call go#guru#DescribeInfo()
|
||||
call go#guru#DescribeInfo(a:showstatus)
|
||||
else
|
||||
call go#util#EchoError('go_info_mode value: '. l:mode .' is not valid. Valid values are: [gocode, guru]')
|
||||
endif
|
||||
|
@ -64,6 +64,10 @@ endfunction
|
||||
" The (optional) first parameter can be added to indicate the 'cwd' or 'env'
|
||||
" parameters will be used, which wasn't added until a later version.
|
||||
function! go#util#has_job(...) abort
|
||||
if has('nvim')
|
||||
return 1
|
||||
endif
|
||||
|
||||
" cwd and env parameters to job_start was added in this version.
|
||||
if a:0 > 0 && a:1 is 1
|
||||
return has('job') && has("patch-8.0.0902")
|
||||
|
@ -806,6 +806,11 @@ CTRL-t
|
||||
|
||||
Toggles |'g:go_fmt_autosave'|.
|
||||
|
||||
*:GoModFmtAutoSaveToggle*
|
||||
:GoModFmtAutoSaveToggle
|
||||
|
||||
Toggles |'g:go_mod_fmt_autosave'|.
|
||||
|
||||
*:GoAsmFmtAutoSaveToggle*
|
||||
:GoAsmFmtAutoSaveToggle
|
||||
|
||||
@ -880,6 +885,13 @@ CTRL-t
|
||||
}
|
||||
}
|
||||
<
|
||||
*:GoModFmt*
|
||||
:GoModFmt
|
||||
|
||||
Filter the current go.mod buffer through "go mod edit -fmt" command. It
|
||||
tries to preserve cursor position and avoids replacing the buffer with
|
||||
stderr output.
|
||||
|
||||
==============================================================================
|
||||
MAPPINGS *go-mappings*
|
||||
|
||||
@ -1097,6 +1109,10 @@ Calls `:GoImport` for the current package
|
||||
Generate if err != nil { return ... } automatically which infer the type of
|
||||
return values and the numbers.
|
||||
|
||||
*(go-mod-fmt)*
|
||||
|
||||
Calls |:GoModFmt| for the current buffer
|
||||
|
||||
==============================================================================
|
||||
TEXT OBJECTS *go-text-objects*
|
||||
|
||||
@ -1287,7 +1303,15 @@ doesn't break. However it's slows (creates/deletes a file for every save) and
|
||||
it's causing problems on some Vim versions. By default it's disabled. >
|
||||
|
||||
let g:go_fmt_experimental = 0
|
||||
|
||||
<
|
||||
*'g:go_mod_fmt_autosave'*
|
||||
|
||||
Use this option to auto |:GoModFmt| on save. By default it's enabled >
|
||||
|
||||
let g:go_mod_fmt_autosave = 1
|
||||
<
|
||||
|
||||
*'g:go_doc_keywordprg_enabled'*
|
||||
|
||||
Use this option to run `godoc` on words under the cursor with |K|; this will
|
||||
@ -1497,10 +1521,10 @@ that was called. Supported values are "", "quickfix", and "locationlist".
|
||||
Specifies the type of list to use for command outputs (such as errors from
|
||||
builds, results from static analysis commands, etc...). When an expected key
|
||||
is not present in the dictionary, |'g:go_list_type'| will be used instead.
|
||||
Supported keys are "GoBuild", "GoErrCheck", "GoFmt", "GoInstall", "GoLint",
|
||||
"GoMetaLinter", "GoMetaLinterAutoSave", "GoModifyTags" (used for both
|
||||
:GoAddTags and :GoRemoveTags), "GoRename", "GoRun", and "GoTest". Supported
|
||||
values for each command are "quickfix" and "locationlist".
|
||||
Supported keys are "GoBuild", "GoErrCheck", "GoFmt", "GoModFmt", "GoInstall",
|
||||
"GoLint", "GoMetaLinter", "GoMetaLinterAutoSave", "GoModifyTags" (used for
|
||||
both :GoAddTags and :GoRemoveTags), "GoRename", "GoRun", and "GoTest".
|
||||
Supported values for each command are "quickfix" and "locationlist".
|
||||
>
|
||||
let g:go_list_type_commands = {}
|
||||
<
|
||||
@ -1574,14 +1598,6 @@ same.
|
||||
let g:go_gorename_prefill = 'expand("<cword>") =~# "^[A-Z]"' .
|
||||
\ '? go#util#pascalcase(expand("<cword>"))' .
|
||||
\ ': go#util#camelcase(expand("<cword>"))'
|
||||
<
|
||||
*'g:go_gocode_autobuild'*
|
||||
|
||||
Specifies whether `gocode` should automatically build out-of-date packages
|
||||
when their source fields are modified, in order to obtain the freshest
|
||||
autocomplete results for them. By default it is enabled.
|
||||
>
|
||||
let g:go_gocode_autobuild = 1
|
||||
<
|
||||
*'g:go_gocode_propose_builtins'*
|
||||
|
||||
@ -1590,14 +1606,14 @@ to an autocompletion proposals. By default it is enabled.
|
||||
>
|
||||
let g:go_gocode_propose_builtins = 1
|
||||
<
|
||||
*'g:go_gocode_unimported_packages'*
|
||||
*'g:go_gocode_propose_source'*
|
||||
|
||||
Specifies whether `gocode` should include suggestions from unimported
|
||||
packages. By default it is disabled.
|
||||
Specifies whether `gocode` should use source files instead of binary packages
|
||||
for autocompletion proposals. When disabled, only identifiers from the current
|
||||
package and packages that have been installed will proposed.
|
||||
>
|
||||
let g:go_gocode_unimported_packages = 0
|
||||
let g:go_gocode_propose_source = 1
|
||||
<
|
||||
|
||||
*'g:go_gocode_socket_type'*
|
||||
|
||||
Specifies whether `gocode` should use a different socket type. By default
|
||||
@ -1882,6 +1898,13 @@ filetype.
|
||||
The `gohtmltmpl` filetype is automatically set for `*.tmpl` files; the
|
||||
`gotexttmpl` is never automatically set and needs to be set manually.
|
||||
|
||||
==============================================================================
|
||||
*gomod* *ft-gomod-syntax*
|
||||
go.mod file syntax~
|
||||
|
||||
The `gomod` 'filetype' provides syntax highlighting for Go's module file
|
||||
`go.mod`
|
||||
|
||||
|
||||
==============================================================================
|
||||
DEBUGGER *go-debug*
|
||||
@ -2245,6 +2268,18 @@ By default new terminals are opened in a vertical split. To change it
|
||||
let g:go_term_mode = "split"
|
||||
>
|
||||
|
||||
How can I customize the highlighting?~
|
||||
|
||||
All the highlight groups used by vim-go are prefixed with `go` (e.g.
|
||||
`goType`) and are defined in the files in the `syntax` directory. To change
|
||||
the highlighting for any group, add a `highlight` command for the group to
|
||||
your vimrc. To turn off the highlighting for any group, add `highlight link
|
||||
group-name NONE` (where `group-name` is the name of the group whose highlight
|
||||
you'd like to turn off) to your vimrc.
|
||||
|
||||
Some people may wish to highlight Go's builtins as keywords. To do so, one
|
||||
should simply add `highlight link goBuiltins Keyword` to the `vimrc` file.
|
||||
|
||||
==============================================================================
|
||||
DEVELOPMENT *go-development*
|
||||
|
||||
|
@ -31,4 +31,23 @@ au BufReadPost *.s call s:gofiletype_post()
|
||||
|
||||
au BufRead,BufNewFile *.tmpl set filetype=gohtmltmpl
|
||||
|
||||
" Set the filetype if the first non-comment and non-blank line starts with
|
||||
" 'module <path>'.
|
||||
au BufNewFile,BufRead go.mod call s:gomod()
|
||||
|
||||
fun! s:gomod()
|
||||
for l:i in range(1, line('$'))
|
||||
let l:l = getline(l:i)
|
||||
if l:l ==# '' || l:l[:1] ==# '//'
|
||||
continue
|
||||
endif
|
||||
|
||||
if l:l =~# '^module .\+'
|
||||
set filetype=gomod
|
||||
endif
|
||||
|
||||
break
|
||||
endfor
|
||||
endfun
|
||||
|
||||
" vim: sw=2 ts=2 et
|
||||
|
@ -14,7 +14,7 @@ command! -range=% GoFreevars call go#guru#Freevars(<count>)
|
||||
command! -range=% GoChannelPeers call go#guru#ChannelPeers(<count>)
|
||||
command! -range=% GoReferrers call go#guru#Referrers(<count>)
|
||||
|
||||
command! -range=0 GoSameIds call go#guru#SameIds()
|
||||
command! -range=0 GoSameIds call go#guru#SameIds(1)
|
||||
command! -range=0 GoSameIdsClear call go#guru#ClearSameIds()
|
||||
command! -range=0 GoSameIdsToggle call go#guru#ToggleSameIds()
|
||||
command! -range=0 GoSameIdsAutoToggle call go#guru#AutoToogleSameIds()
|
||||
@ -23,10 +23,13 @@ command! -range=0 GoSameIdsAutoToggle call go#guru#AutoToogleSameIds()
|
||||
command! -nargs=* -range GoAddTags call go#tags#Add(<line1>, <line2>, <count>, <f-args>)
|
||||
command! -nargs=* -range GoRemoveTags call go#tags#Remove(<line1>, <line2>, <count>, <f-args>)
|
||||
|
||||
" -- mod
|
||||
command! -nargs=0 -range GoModFmt call go#mod#Format()
|
||||
|
||||
" -- tool
|
||||
command! -nargs=* -complete=customlist,go#tool#ValidFiles GoFiles echo go#tool#Files(<f-args>)
|
||||
command! -nargs=0 GoDeps echo go#tool#Deps()
|
||||
command! -nargs=0 GoInfo call go#tool#Info()
|
||||
command! -nargs=0 GoInfo call go#tool#Info(1)
|
||||
command! -nargs=0 GoAutoTypeInfoToggle call go#complete#ToggleAutoTypeInfo()
|
||||
|
||||
" -- cmd
|
||||
|
@ -31,7 +31,7 @@ nnoremap <silent> <Plug>(go-coverage-browser) :<C-u>call go#coverage#Browser(!g:
|
||||
|
||||
nnoremap <silent> <Plug>(go-files) :<C-u>call go#tool#Files()<CR>
|
||||
nnoremap <silent> <Plug>(go-deps) :<C-u>call go#tool#Deps()<CR>
|
||||
nnoremap <silent> <Plug>(go-info) :<C-u>call go#tool#Info()<CR>
|
||||
nnoremap <silent> <Plug>(go-info) :<C-u>call go#tool#Info(1)<CR>
|
||||
nnoremap <silent> <Plug>(go-import) :<C-u>call go#import#SwitchImport(1, '', expand('<cword>'), '')<CR>
|
||||
nnoremap <silent> <Plug>(go-imports) :<C-u>call go#fmt#Format(1)<CR>
|
||||
|
||||
@ -43,13 +43,16 @@ nnoremap <silent> <Plug>(go-callstack) :<C-u>call go#guru#Callstack(-1)<CR>
|
||||
xnoremap <silent> <Plug>(go-freevars) :<C-u>call go#guru#Freevars(0)<CR>
|
||||
nnoremap <silent> <Plug>(go-channelpeers) :<C-u>call go#guru#ChannelPeers(-1)<CR>
|
||||
nnoremap <silent> <Plug>(go-referrers) :<C-u>call go#guru#Referrers(-1)<CR>
|
||||
nnoremap <silent> <Plug>(go-sameids) :<C-u>call go#guru#SameIds()<CR>
|
||||
nnoremap <silent> <Plug>(go-sameids) :<C-u>call go#guru#SameIds(1)<CR>
|
||||
nnoremap <silent> <Plug>(go-pointsto) :<C-u>call go#guru#PointsTo(-1)<CR>
|
||||
nnoremap <silent> <Plug>(go-whicherrs) :<C-u>call go#guru#Whicherrs(-1)<CR>
|
||||
nnoremap <silent> <Plug>(go-sameids-toggle) :<C-u>call go#guru#ToggleSameIds()<CR>
|
||||
|
||||
nnoremap <silent> <Plug>(go-rename) :<C-u>call go#rename#Rename(!g:go_jump_to_error)<CR>
|
||||
|
||||
nnoremap <silent> <Plug>(go-decls) :<C-u>call go#decls#Decls(0, '')<CR>
|
||||
nnoremap <silent> <Plug>(go-decls-dir) :<C-u>call go#decls#Decls(1, '')<CR>
|
||||
|
||||
nnoremap <silent> <Plug>(go-def) :<C-u>call go#def#Jump('')<CR>
|
||||
nnoremap <silent> <Plug>(go-def-vertical) :<C-u>call go#def#Jump("vsplit")<CR>
|
||||
nnoremap <silent> <Plug>(go-def-split) :<C-u>call go#def#Jump("split")<CR>
|
||||
|
15
sources_non_forked/vim-go/ftplugin/gomod.vim
Normal file
15
sources_non_forked/vim-go/ftplugin/gomod.vim
Normal file
@ -0,0 +1,15 @@
|
||||
" gomod.vim: Vim filetype plugin for Go assembler.
|
||||
|
||||
if exists("b:did_ftplugin")
|
||||
finish
|
||||
endif
|
||||
let b:did_ftplugin = 1
|
||||
|
||||
let b:undo_ftplugin = "setl fo< com< cms<"
|
||||
|
||||
setlocal formatoptions-=t
|
||||
|
||||
setlocal comments=s1:/*,mb:*,ex:*/,://
|
||||
setlocal commentstring=//\ %s
|
||||
|
||||
" vim: sw=2 ts=2 et
|
3
sources_non_forked/vim-go/ftplugin/gomod/commands.vim
Normal file
3
sources_non_forked/vim-go/ftplugin/gomod/commands.vim
Normal file
@ -0,0 +1,3 @@
|
||||
command! -nargs=0 -range GoModFmt call go#mod#Format()
|
||||
|
||||
command! -nargs=0 GoModFmtAutoSaveToggle call go#mod#ToggleModFmtAutoSave()
|
1
sources_non_forked/vim-go/ftplugin/gomod/mappings.vim
Normal file
1
sources_non_forked/vim-go/ftplugin/gomod/mappings.vim
Normal file
@ -0,0 +1 @@
|
||||
nnoremap <silent> <Plug>(go-mod-fmt) :<C-u>call go#mod#Format()<CR>
|
@ -363,6 +363,28 @@ func Test${1:Function}(t *testing.T) {
|
||||
}
|
||||
endsnippet
|
||||
|
||||
# test table snippet
|
||||
snippet tt
|
||||
var tests = []struct {
|
||||
name string
|
||||
expected string
|
||||
given string
|
||||
}{
|
||||
{"${1}", "${2}", "${3}",},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
tt := tt
|
||||
t.Run(tt.name, func(t *testing.T){
|
||||
actual := ${0:${VISUAL}}(tt.given)
|
||||
if actual != tt.expected {
|
||||
t.Errorf("$0(%s): expected %s, actual %s", tt.given, tt.expected, actual)
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
endsnippet
|
||||
|
||||
|
||||
snippet hf "http.HandlerFunc" !b
|
||||
func ${1:handler}(w http.ResponseWriter, r *http.Request) {
|
||||
${0:fmt.Fprintf(w, "hello world")}
|
||||
|
17
sources_non_forked/vim-go/gosnippets/minisnip/_go_tt
Normal file
17
sources_non_forked/vim-go/gosnippets/minisnip/_go_tt
Normal file
@ -0,0 +1,17 @@
|
||||
var tests = []struct {
|
||||
name string
|
||||
expected string
|
||||
given string
|
||||
}{
|
||||
{"", "", "",},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
tt := tt
|
||||
t.Run(tt.name, func(t *testing.T){
|
||||
actual := {{++}}(tt.given)
|
||||
if actual != tt.expected {
|
||||
t.Errorf("{{+~\~1+}}(%s): expected %s, actual %s", tt.given, tt.expected, actual)
|
||||
}
|
||||
|
||||
})
|
||||
}
|
@ -315,6 +315,25 @@ abbr func TestXYZ(t *testing.T) { ... }
|
||||
func Test${1:Function}(t *testing.T) {
|
||||
${0}
|
||||
}
|
||||
# test table snippet
|
||||
snippet tt
|
||||
abbr var test = {...}{...} for {t.Run(){...}}
|
||||
var tests = []struct {
|
||||
name string
|
||||
expected string
|
||||
given string
|
||||
}{
|
||||
{"${2}", "${3}", "${4}",},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
tt := tt
|
||||
t.Run(tt.name, func(t *testing.T){
|
||||
actual := ${1:Function}(tt.given)
|
||||
if actual != tt.expected {
|
||||
t.Errorf("given(%s): expected %s, actual %s", tt.given, tt.expected, actual)
|
||||
}
|
||||
})
|
||||
}
|
||||
# test server
|
||||
snippet tsrv
|
||||
abbr ts := httptest.NewServer(...)
|
||||
|
@ -24,17 +24,6 @@ if exists("*GoIndent")
|
||||
finish
|
||||
endif
|
||||
|
||||
" use shiftwidth function only if it's available
|
||||
if exists('*shiftwidth')
|
||||
func s:sw()
|
||||
return shiftwidth()
|
||||
endfunc
|
||||
else
|
||||
func s:sw()
|
||||
return &sw
|
||||
endfunc
|
||||
endif
|
||||
|
||||
function! GoIndent(lnum)
|
||||
let prevlnum = prevnonblank(a:lnum-1)
|
||||
if prevlnum == 0
|
||||
@ -49,19 +38,23 @@ function! GoIndent(lnum)
|
||||
|
||||
let ind = previ
|
||||
|
||||
if prevl =~ ' = `[^`]*$'
|
||||
" previous line started a multi-line raw string
|
||||
return 0
|
||||
endif
|
||||
if prevl =~ '[({]\s*$'
|
||||
" previous line opened a block
|
||||
let ind += s:sw()
|
||||
let ind += shiftwidth()
|
||||
endif
|
||||
if prevl =~# '^\s*\(case .*\|default\):$'
|
||||
" previous line is part of a switch statement
|
||||
let ind += s:sw()
|
||||
let ind += shiftwidth()
|
||||
endif
|
||||
" TODO: handle if the previous line is a label.
|
||||
|
||||
if thisl =~ '^\s*[)}]'
|
||||
" this line closed a block
|
||||
let ind -= s:sw()
|
||||
let ind -= shiftwidth()
|
||||
endif
|
||||
|
||||
" Colons are tricky.
|
||||
@ -69,7 +62,7 @@ function! GoIndent(lnum)
|
||||
" We ignore trying to deal with jump labels because (a) they're rare, and
|
||||
" (b) they're hard to disambiguate from a composite literal key.
|
||||
if thisl =~# '^\s*\(case .*\|default\):$'
|
||||
let ind -= s:sw()
|
||||
let ind -= shiftwidth()
|
||||
endif
|
||||
|
||||
return ind
|
||||
|
@ -29,13 +29,13 @@ if
|
||||
endif
|
||||
|
||||
" these packages are used by vim-go and can be automatically installed if
|
||||
" needed by the user with GoInstallBinaries
|
||||
" needed by the user with GoInstallBinaries.
|
||||
let s:packages = {
|
||||
\ 'asmfmt': ['github.com/klauspost/asmfmt/cmd/asmfmt'],
|
||||
\ 'dlv': ['github.com/derekparker/delve/cmd/dlv'],
|
||||
\ 'errcheck': ['github.com/kisielk/errcheck'],
|
||||
\ 'fillstruct': ['github.com/davidrjenni/reftools/cmd/fillstruct'],
|
||||
\ 'gocode': ['github.com/nsf/gocode', {'windows': ['-ldflags', '-H=windowsgui']}],
|
||||
\ 'gocode': ['github.com/mdempsky/gocode', {'windows': ['-ldflags', '-H=windowsgui']}],
|
||||
\ 'godef': ['github.com/rogpeppe/godef'],
|
||||
\ 'gogetdoc': ['github.com/zmb3/gogetdoc'],
|
||||
\ 'goimports': ['golang.org/x/tools/cmd/goimports'],
|
||||
@ -99,9 +99,9 @@ function! s:GoInstallBinaries(updateBinaries, ...)
|
||||
set noshellslash
|
||||
endif
|
||||
|
||||
let l:cmd = ['go', 'get', '-v']
|
||||
let l:dl_cmd = ['go', 'get', '-v', '-d']
|
||||
if get(g:, "go_get_update", 1) != 0
|
||||
let l:cmd += ['-u']
|
||||
let l:dl_cmd += ['-u']
|
||||
endif
|
||||
|
||||
" Filter packages from arguments (if any).
|
||||
@ -127,16 +127,21 @@ function! s:GoInstallBinaries(updateBinaries, ...)
|
||||
for [binary, pkg] in items(l:packages)
|
||||
let l:importPath = pkg[0]
|
||||
|
||||
let l:run_cmd = copy(l:cmd)
|
||||
let l:run_cmd = copy(l:dl_cmd)
|
||||
if len(l:pkg) > 1 && get(l:pkg[1], l:platform, '') isnot ''
|
||||
let l:run_cmd += get(l:pkg[1], l:platform, '')
|
||||
endif
|
||||
|
||||
let binname = "go_" . binary . "_bin"
|
||||
let bin_setting_name = "go_" . binary . "_bin"
|
||||
|
||||
let bin = binary
|
||||
if exists("g:{binname}")
|
||||
let bin = g:{binname}
|
||||
if exists("g:{bin_setting_name}")
|
||||
let bin = g:{bin_setting_name}
|
||||
else
|
||||
if go#util#IsWin()
|
||||
let bin = binary . '.exe'
|
||||
else
|
||||
let bin = binary
|
||||
endif
|
||||
endif
|
||||
|
||||
if !executable(bin) || a:updateBinaries == 1
|
||||
@ -146,7 +151,15 @@ function! s:GoInstallBinaries(updateBinaries, ...)
|
||||
echo "vim-go: ". binary ." not found. Installing ". importPath . " to folder " . go_bin_path
|
||||
endif
|
||||
|
||||
" first download the binary
|
||||
let [l:out, l:err] = go#util#Exec(l:run_cmd + [l:importPath])
|
||||
if l:err
|
||||
echom "Error downloading " . l:importPath . ": " . l:out
|
||||
endif
|
||||
|
||||
" and then build and install it
|
||||
let l:build_cmd = ['go', 'build', '-o', go_bin_path . go#util#PathSep() . bin, l:importPath]
|
||||
let [l:out, l:err] = go#util#Exec(l:build_cmd + [l:importPath])
|
||||
if l:err
|
||||
echom "Error installing " . l:importPath . ": " . l:out
|
||||
endif
|
||||
@ -158,6 +171,12 @@ function! s:GoInstallBinaries(updateBinaries, ...)
|
||||
if resetshellslash
|
||||
set shellslash
|
||||
endif
|
||||
|
||||
if a:updateBinaries == 1
|
||||
call go#util#EchoInfo('updating finished!')
|
||||
else
|
||||
call go#util#EchoInfo('installing finished!')
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" CheckBinaries checks if the necessary binaries to install the Go tool
|
||||
@ -201,14 +220,14 @@ endfunction
|
||||
function! s:auto_type_info()
|
||||
" GoInfo automatic update
|
||||
if get(g:, "go_auto_type_info", 0)
|
||||
call go#tool#Info()
|
||||
call go#tool#Info(0)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:auto_sameids()
|
||||
" GoSameId automatic update
|
||||
if get(g:, "go_auto_sameids", 0)
|
||||
call go#guru#SameIds()
|
||||
call go#guru#SameIds(0)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
@ -226,6 +245,13 @@ function! s:asmfmt_autosave()
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:modfmt_autosave()
|
||||
" go.mod code formatting on save
|
||||
if get(g:, "go_mod_fmt_autosave", 1)
|
||||
call go#mod#Format()
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:metalinter_autosave()
|
||||
" run gometalinter on save
|
||||
if get(g:, "go_metalinter_autosave", 0)
|
||||
@ -253,6 +279,7 @@ augroup vim-go
|
||||
endif
|
||||
|
||||
autocmd BufWritePre *.go call s:fmt_autosave()
|
||||
autocmd BufWritePre *.mod call s:modfmt_autosave()
|
||||
autocmd BufWritePre *.s call s:asmfmt_autosave()
|
||||
autocmd BufWritePost *.go call s:metalinter_autosave()
|
||||
autocmd BufNewFile *.go call s:template_autocreate()
|
||||
|
@ -30,7 +30,7 @@ case "$vim" in
|
||||
|
||||
"nvim")
|
||||
# Use latest stable version.
|
||||
tag="v0.2.0"
|
||||
tag="v0.3.1"
|
||||
giturl="https://github.com/neovim/neovim"
|
||||
;;
|
||||
|
||||
|
@ -47,12 +47,12 @@ hi def link goFloats Type
|
||||
hi def link goComplexes Type
|
||||
|
||||
" Predefined functions and values
|
||||
syn match goBuiltins /\<\v(append|cap|close|complex|copy|delete|imag|len)\ze\(/
|
||||
syn match goBuiltins /\<\v(make|new|panic|print|println|real|recover)\ze\(/
|
||||
syn keyword goBuiltins append cap close complex copy delete imag len
|
||||
syn keyword goBuiltins make new panic print println real recover
|
||||
syn keyword goBoolean true false
|
||||
syn keyword goPredefinedIdentifiers nil iota
|
||||
|
||||
hi def link goBuiltins Keyword
|
||||
hi def link goBuiltins Identifier
|
||||
hi def link goBoolean Boolean
|
||||
hi def link goPredefinedIdentifiers goBoolean
|
||||
|
||||
@ -148,14 +148,14 @@ endif
|
||||
" var, const
|
||||
if go#config#FoldEnable('varconst')
|
||||
syn region goVar start='var (' end='^\s*)$' transparent fold
|
||||
\ contains=ALLBUT,goParen,goBlock,goFunction,goTypeName,goReceiverType,goReceiverVar,goArgumentName,goArgumentType,goSimpleArguments
|
||||
\ contains=ALLBUT,goParen,goBlock,goFunction,goTypeName,goReceiverType,goReceiverVar,goArgumentName,goArgumentType,goSimpleArguments,goPointerOperator
|
||||
syn region goConst start='const (' end='^\s*)$' transparent fold
|
||||
\ contains=ALLBUT,goParen,goBlock,goFunction,goTypeName,goReceiverType,goReceiverVar,goArgumentName,goArgumentType,goSimpleArguments
|
||||
\ contains=ALLBUT,goParen,goBlock,goFunction,goTypeName,goReceiverType,goReceiverVar,goArgumentName,goArgumentType,goSimpleArguments,goPointerOperator
|
||||
else
|
||||
syn region goVar start='var (' end='^\s*)$' transparent
|
||||
\ contains=ALLBUT,goParen,goBlock,goFunction,goTypeName,goReceiverType,goReceiverVar,goArgumentName,goArgumentType,goSimpleArguments
|
||||
\ contains=ALLBUT,goParen,goBlock,goFunction,goTypeName,goReceiverType,goReceiverVar,goArgumentName,goArgumentType,goSimpleArguments,goPointerOperator
|
||||
syn region goConst start='const (' end='^\s*)$' transparent
|
||||
\ contains=ALLBUT,goParen,goBlock,goFunction,goTypeName,goReceiverType,goReceiverVar,goArgumentName,goArgumentType,goSimpleArguments
|
||||
\ contains=ALLBUT,goParen,goBlock,goFunction,goTypeName,goReceiverType,goReceiverVar,goArgumentName,goArgumentType,goSimpleArguments,goPointerOperator
|
||||
endif
|
||||
|
||||
" Single-line var, const, and import.
|
||||
|
46
sources_non_forked/vim-go/syntax/gomod.vim
Normal file
46
sources_non_forked/vim-go/syntax/gomod.vim
Normal file
@ -0,0 +1,46 @@
|
||||
" gomod.vim: Vim syntax file for go.mod file
|
||||
"
|
||||
" Quit when a (custom) syntax file was already loaded
|
||||
if exists("b:current_syntax")
|
||||
finish
|
||||
endif
|
||||
|
||||
syntax case match
|
||||
|
||||
" match keywords
|
||||
syntax keyword gomodModule module
|
||||
syntax keyword gomodRequire require
|
||||
syntax keyword gomodExclude exclude
|
||||
syntax keyword gomodReplace replace
|
||||
|
||||
" require, exclude and replace can be also grouped into block
|
||||
syntax region gomodRequire start='require (' end=')' transparent contains=gomodRequire,gomodVersion
|
||||
syntax region gomodExclude start='exclude (' end=')' transparent contains=gomodExclude,gomodVersion
|
||||
syntax region gomodReplace start='replace (' end=')' transparent contains=gomodReplace,gomodVersion
|
||||
|
||||
" set highlights
|
||||
highlight default link gomodModule Keyword
|
||||
highlight default link gomodRequire Keyword
|
||||
highlight default link gomodExclude Keyword
|
||||
highlight default link gomodReplace Keyword
|
||||
|
||||
" comments are always in form of // ...
|
||||
syntax region gomodComment start="//" end="$" contains=@Spell
|
||||
highlight default link gomodComment Comment
|
||||
|
||||
" make sure quoted import paths are higlighted
|
||||
syntax region gomodString start=+"+ skip=+\\\\\|\\"+ end=+"+
|
||||
highlight default link gomodString String
|
||||
|
||||
" replace operator is in the form of '=>'
|
||||
syntax match gomodReplaceOperator "\v\=\>"
|
||||
highlight default link gomodReplaceOperator Operator
|
||||
|
||||
|
||||
" highlight semver, note that this is very simple. But it works for now
|
||||
syntax match gomodVersion "v\d\+\.\d\+\.\d\+"
|
||||
syntax match gomodVersion "v\d\+\.\d\+\.\d\+-\S*"
|
||||
syntax match gomodVersion "v\d\+\.\d\+\.\d\++incompatible"
|
||||
highlight default link gomodVersion Identifier
|
||||
|
||||
let b:current_syntax = "gomod"
|
Reference in New Issue
Block a user