mirror of
				https://github.com/amix/vimrc
				synced 2025-10-31 23:13:35 +08:00 
			
		
		
		
	Updated plugins
This commit is contained in:
		| @ -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") | ||||
|  | ||||
		Reference in New Issue
	
	Block a user
	 Amir Salihefendic
					Amir Salihefendic