mirror of
				https://github.com/amix/vimrc
				synced 2025-10-31 23:13:35 +08:00 
			
		
		
		
	Updated plugins
This commit is contained in:
		| @ -213,11 +213,11 @@ function! go#cmd#Test(bang, compile, ...) | ||||
|  | ||||
|     if has('nvim') | ||||
|         if get(g:, 'go_term_enabled', 0) | ||||
|             call go#term#new(a:bang, ["go"] + args) | ||||
|             let id = go#term#new(a:bang, ["go"] + args) | ||||
|         else | ||||
|             call go#jobcontrol#Spawn(a:bang, "test", args) | ||||
|             let id = go#jobcontrol#Spawn(a:bang, "test", args) | ||||
|         endif | ||||
|         return | ||||
|         return id | ||||
|     endif | ||||
|  | ||||
|     call go#cmd#autowrite() | ||||
| @ -290,36 +290,6 @@ function! go#cmd#TestFunc(bang, ...) | ||||
|     call call('go#cmd#Test', args) | ||||
| endfunction | ||||
|  | ||||
| " Coverage creates a new cover profile with 'go test -coverprofile' and opens | ||||
| " a new HTML coverage page from that profile. | ||||
| function! go#cmd#Coverage(bang, ...) | ||||
|     let l:tmpname=tempname() | ||||
|  | ||||
|     let command = "go test -coverprofile=" . l:tmpname . ' ' . go#util#Shelljoin(a:000) | ||||
|  | ||||
|  | ||||
|     let l:listtype = "quickfix" | ||||
|     call go#cmd#autowrite() | ||||
|     let out = go#tool#ExecuteInDir(command) | ||||
|     if v:shell_error | ||||
|         let errors = go#tool#ParseErrors(split(out, '\n')) | ||||
|         call go#list#Populate(l:listtype, errors) | ||||
|         call go#list#Window(l:listtype, len(errors)) | ||||
|         if !empty(errors) && !a:bang | ||||
|             call go#list#JumpToFirst(l:listtype) | ||||
|         endif | ||||
|     else | ||||
|         " clear previous location list  | ||||
|         call go#list#Clean(l:listtype) | ||||
|         call go#list#Window(l:listtype) | ||||
|  | ||||
|         let openHTML = 'go tool cover -html='.l:tmpname | ||||
|         call go#tool#ExecuteInDir(openHTML) | ||||
|     endif | ||||
|  | ||||
|     call delete(l:tmpname) | ||||
| endfunction | ||||
|  | ||||
| " Generate runs 'go generate' in similar fashion to go#cmd#Build() | ||||
| function! go#cmd#Generate(bang, ...) | ||||
|     let default_makeprg = &makeprg | ||||
|  | ||||
							
								
								
									
										251
									
								
								sources_non_forked/vim-go/autoload/go/coverage.vim
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										251
									
								
								sources_non_forked/vim-go/autoload/go/coverage.vim
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,251 @@ | ||||
| let s:toggle = 0 | ||||
|  | ||||
| " Buffer creates a new cover profile with 'go test -coverprofile' and changes | ||||
| " teh current buffers highlighting to show covered and uncovered sections of | ||||
| " the code. If run again it clears the annotation | ||||
| function! go#coverage#Buffer(bang, ...) | ||||
|     if s:toggle | ||||
|         call go#coverage#Clear() | ||||
|         return | ||||
|     endif | ||||
|  | ||||
|     let s:toggle = 1 | ||||
|     let l:tmpname=tempname() | ||||
|     let args = [a:bang, 0, "-coverprofile", l:tmpname] | ||||
|  | ||||
|     if a:0 | ||||
|         call extend(args, a:000) | ||||
|     endif | ||||
|  | ||||
|     let disabled_term = 0 | ||||
|     if get(g:, 'go_term_enabled') | ||||
|         let disabled_term = 1 | ||||
|         let g:go_term_enabled = 0 | ||||
|     endif | ||||
|  | ||||
|     let id = call('go#cmd#Test', args) | ||||
|  | ||||
|     if disabled_term | ||||
|         let g:go_term_enabled = 1 | ||||
|     endif | ||||
|  | ||||
|     if has('nvim') | ||||
|         call go#jobcontrol#AddHandler(function('s:coverage_handler')) | ||||
|         let s:coverage_handler_jobs[id] = l:tmpname | ||||
|         return | ||||
|     endif | ||||
|  | ||||
|     if !v:shell_error | ||||
|         call go#coverage#overlay(l:tmpname) | ||||
|     endif | ||||
|  | ||||
|     call delete(l:tmpname) | ||||
| endfunction | ||||
|  | ||||
| " Clear clears and resets the buffer annotation matches | ||||
| function! go#coverage#Clear() | ||||
|     if exists("g:syntax_on") | syntax enable | endif | ||||
|  | ||||
|     if exists("s:toggle") | let s:toggle = 0 | endif | ||||
|  | ||||
|     " remove the autocmd we defined  | ||||
|     if exists("#BufWinLeave#<buffer>")  | ||||
|         autocmd! BufWinLeave <buffer> | ||||
|     endif | ||||
|  | ||||
|     call clearmatches() | ||||
| endfunction | ||||
|  | ||||
| " Browser creates a new cover profile with 'go test -coverprofile' and opens | ||||
| " a new HTML coverage page from that profile in a new browser | ||||
| function! go#coverage#Browser(bang, ...) | ||||
|     let l:tmpname=tempname() | ||||
|     let args = [a:bang, 0, "-coverprofile", l:tmpname] | ||||
|  | ||||
|     if a:0 | ||||
|         call extend(args, a:000) | ||||
|     endif | ||||
|     let id = call('go#cmd#Test', args) | ||||
|     if has('nvim') | ||||
|         call go#jobcontrol#AddHandler(function('s:coverage_browser_handler')) | ||||
|         let s:coverage_browser_handler_jobs[id] = l:tmpname | ||||
|         return | ||||
|     endif | ||||
|     if !v:shell_error | ||||
|         let openHTML = 'go tool cover -html='.l:tmpname | ||||
|         call go#tool#ExecuteInDir(openHTML) | ||||
|     endif | ||||
|  | ||||
|     call delete(l:tmpname) | ||||
| endfunction | ||||
|  | ||||
| " Parses a single line from the cover file generated via go test -coverprofile | ||||
| " and returns a single coverage profile block. | ||||
| function! go#coverage#parsegocoverline(line) | ||||
|     " file:startline.col,endline.col numstmt count | ||||
|     let mx = '\([^:]\+\):\(\d\+\)\.\(\d\+\),\(\d\+\)\.\(\d\+\)\s\(\d\+\)\s\(\d\+\)' | ||||
|     let tokens = matchlist(a:line, mx) | ||||
|     let ret = {} | ||||
|     let ret.file = tokens[1] | ||||
|     let ret.startline  = str2nr(tokens[2]) | ||||
|     let ret.startcol = str2nr(tokens[3]) | ||||
|     let ret.endline = str2nr(tokens[4]) | ||||
|     let ret.endcol = str2nr(tokens[5]) | ||||
|     let ret.numstmt = tokens[6] | ||||
|     let ret.cnt = tokens[7] | ||||
|     return ret | ||||
| endfunction | ||||
|  | ||||
| " Generates matches to be added to matchaddpos for the given coverage profile | ||||
| " block | ||||
| function! go#coverage#genmatch(cov) | ||||
|     let color = 'covered' | ||||
|     if a:cov.cnt == 0 | ||||
|         let color = 'uncover' | ||||
|     endif | ||||
|  | ||||
|     let matches = [] | ||||
|  | ||||
|     " if start and end are the same, also specify the byte length | ||||
|     " example: foo.go:92.2,92.65 1 0 | ||||
|     if a:cov.startline == a:cov.endline | ||||
|         call add(matches, { | ||||
|                     \ 'group': color,  | ||||
|                     \ 'pos': [[a:cov.startline, a:cov.startcol, a:cov.endcol - a:cov.startcol]],  | ||||
|                     \ 'priority': 2, | ||||
|                     \ }) | ||||
|         return matches | ||||
|     endif | ||||
|  | ||||
|     " add start columns. Because we don't know the length of the of | ||||
|     " the line, we assume it is at maximum 200 bytes. I know this is hacky, | ||||
|     " but that's only way of fixing the issue | ||||
|     call add(matches, { | ||||
|                 \ 'group': color,  | ||||
|                 \ 'pos': [[a:cov.startline, a:cov.startcol, 200]],  | ||||
|                 \ 'priority': 2, | ||||
|                 \ }) | ||||
|  | ||||
|     " and then the remaining lines | ||||
|     let start_line = a:cov.startline | ||||
|     while start_line < a:cov.endline | ||||
|         let start_line += 1 | ||||
|         call add(matches, { | ||||
|                     \ 'group': color,  | ||||
|                     \ 'pos': [[start_line]],  | ||||
|                     \ 'priority': 2, | ||||
|                     \ }) | ||||
|     endwhile | ||||
|  | ||||
|     " finally end columns | ||||
|     call add(matches, { | ||||
|                 \ 'group': color,  | ||||
|                 \ 'pos': [[a:cov.endline, a:cov.endcol-1]],  | ||||
|                 \ 'priority': 2, | ||||
|                 \ }) | ||||
|  | ||||
|     return matches | ||||
| endfunction | ||||
|  | ||||
| " Reads the given coverprofile file and annotates the current buffer | ||||
| function! go#coverage#overlay(file) | ||||
|     if !filereadable(a:file) | ||||
|         return | ||||
|     endif | ||||
|     let lines = readfile(a:file) | ||||
|  | ||||
|     " cover mode, by default it's 'set'. Just here for debugging purposes | ||||
|     let mode = lines[0] | ||||
|  | ||||
|     " contains matches for matchaddpos() | ||||
|     let matches = [] | ||||
|  | ||||
|     " first mark all lines as normaltext. We use a custom group to not | ||||
|     " interfere with other buffers highlightings. Because the priority is | ||||
|     " lower than the cover and uncover matches, it'll be overriden. | ||||
|     let cnt = 1 | ||||
|     while cnt <= line('$') | ||||
|         call add(matches, {'group': 'normaltext', 'pos': [cnt], 'priority': 1}) | ||||
|         let cnt += 1 | ||||
|     endwhile | ||||
|  | ||||
|     let fname = expand('%:t') | ||||
|  | ||||
|     " when called for a _test.go file, run the coverage for the actuall file | ||||
|     " file | ||||
|     if fname =~# '^\f\+_test\.go$' | ||||
|         let l:root = split(fname, '_test.go$')[0] | ||||
|         let fname = l:root . ".go" | ||||
|  | ||||
|         if !filereadable(fname) | ||||
|             call go#util#EchoError("couldn't find ".fname) | ||||
|             return | ||||
|         endif | ||||
|  | ||||
|         " open the alternate file to show the coverage | ||||
|         exe ":edit ". fnamemodify(fname, ":p") | ||||
|     endif | ||||
|  | ||||
|     for line in lines[1:] | ||||
|         let cov = go#coverage#parsegocoverline(line) | ||||
|  | ||||
|         " TODO(arslan): for now only include the coverage for the current | ||||
|         " buffer | ||||
|         if fname != fnamemodify(cov.file, ':t') | ||||
|             continue | ||||
|         endif | ||||
|  | ||||
|         call extend(matches, go#coverage#genmatch(cov)) | ||||
|     endfor | ||||
|  | ||||
|     syntax manual | ||||
|     highlight normaltext term=bold ctermfg=59 guifg=#75715E | ||||
|     highlight covered term=bold ctermfg=118 guifg=#A6E22E | ||||
|     highlight uncover term=bold ctermfg=197 guifg=#F92672 | ||||
|  | ||||
|     " clear the matches if we leave the buffer | ||||
|     autocmd BufWinLeave <buffer> call go#coverage#Clear() | ||||
|  | ||||
|     for m in matches | ||||
|         call matchaddpos(m.group, m.pos) | ||||
|     endfor | ||||
| endfunction | ||||
|  | ||||
|  | ||||
| " ----------------------- | ||||
| " | Neovim job handlers | | ||||
| " ----------------------- | ||||
|  | ||||
| let s:coverage_handler_jobs = {} | ||||
| let s:coverage_browser_handler_jobs = {} | ||||
|  | ||||
| function! s:coverage_handler(job, exit_status, data) | ||||
|     if !has_key(s:coverage_handler_jobs, a:job.id) | ||||
|         return | ||||
|     endif | ||||
|     let l:tmpname = s:coverage_handler_jobs[a:job.id] | ||||
|     if a:exit_status == 0 | ||||
|         call go#coverage#overlay(l:tmpname) | ||||
|     endif | ||||
|  | ||||
|     call delete(l:tmpname) | ||||
|     unlet s:coverage_handler_jobs[a:job.id] | ||||
| endfunction | ||||
|  | ||||
| function! s:coverage_browser_handler(job, exit_status, data) | ||||
|     if !has_key(s:coverage_browser_handler_jobs, a:job.id) | ||||
|         return | ||||
|     endif | ||||
|  | ||||
|     let l:tmpname = s:coverage_browser_handler_jobs[a:job.id] | ||||
|     if a:exit_status == 0 | ||||
|         let openHTML = 'go tool cover -html='.l:tmpname | ||||
|         call go#tool#ExecuteInDir(openHTML) | ||||
|     endif | ||||
|  | ||||
|     call delete(l:tmpname) | ||||
|     unlet s:coverage_browser_handler_jobs[a:job.id] | ||||
| endfunction | ||||
|  | ||||
|  | ||||
| " vim:ts=4:sw=4:et | ||||
| @ -29,13 +29,17 @@ function! go#def#Jump(...) | ||||
| 	let $GOPATH = go#path#Detect() | ||||
|  | ||||
| 	let fname = fnamemodify(expand("%"), ':p:gs?\\?/?') | ||||
| 	let command = bin_path . " -f=" . shellescape(fname) . " -i " . shellescape(arg) | ||||
| 	let command = bin_path . " -t -f=" . shellescape(fname) . " -i " . shellescape(arg) | ||||
|  | ||||
| 	" get output of godef | ||||
| 	let out = s:system(command, join(getbufline(bufnr('%'), 1, '$'), go#util#LineEnding())) | ||||
|  | ||||
| 	" First line is <file>:<line>:<col> | ||||
| 	" Second line is <identifier><space><type> | ||||
| 	let godefout=split(out, go#util#LineEnding()) | ||||
|  | ||||
| 	" jump to it | ||||
| 	call s:godefJump(out, "") | ||||
| 	call s:godefJump(godefout, "") | ||||
| 	let $GOPATH = old_gopath | ||||
| endfunction | ||||
|  | ||||
| @ -52,12 +56,17 @@ function! go#def#JumpMode(mode) | ||||
| 	let $GOPATH = go#path#Detect() | ||||
|  | ||||
| 	let fname = fnamemodify(expand("%"), ':p:gs?\\?/?') | ||||
| 	let command = bin_path . " -f=" . shellescape(fname) . " -i " . shellescape(arg) | ||||
| 	let command = bin_path . " -t -f=" . shellescape(fname) . " -i " . shellescape(arg) | ||||
|  | ||||
| 	" get output of godef | ||||
| 	let out = s:system(command, join(getbufline(bufnr('%'), 1, '$'), go#util#LineEnding())) | ||||
|  | ||||
| 	call s:godefJump(out, a:mode) | ||||
| 	" First line is <file>:<line>:<col> | ||||
| 	" Second line is <identifier><space><type> | ||||
| 	let godefout=split(out, go#util#LineEnding()) | ||||
|  | ||||
| 	" jump to it | ||||
| 	call s:godefJump(godefout, a:mode) | ||||
| 	let $GOPATH = old_gopath | ||||
| endfunction | ||||
|  | ||||
| @ -71,41 +80,181 @@ function! s:godefJump(out, mode) | ||||
| 	let old_errorformat = &errorformat | ||||
| 	let &errorformat = "%f:%l:%c" | ||||
|  | ||||
| 	if a:out =~ 'godef: ' | ||||
| 		let out = substitute(a:out, go#util#LineEnding() . '$', '', '') | ||||
| 		echom out | ||||
| 	else | ||||
| 		let parts = split(a:out, ':') | ||||
| 		" parts[0] contains filename | ||||
| 		let fileName = parts[0] | ||||
| 	" Location is the first line of godef output. Ideally in the proper format | ||||
| 	" but it could also be an error | ||||
| 	let location = a:out[0] | ||||
|  | ||||
| 		" put the error format into location list so we can jump automatically to | ||||
| 		" it | ||||
| 		lgetexpr a:out | ||||
| 	" Echo the godef error if we had one. | ||||
| 	if location =~ 'godef: ' | ||||
| 		let gderr=substitute(location, go#util#LineEnding() . '$', '', '') | ||||
|         call go#util#EchoError(gderr) | ||||
|         return | ||||
|     endif | ||||
|  | ||||
| 		" needed for restoring back user setting this is because there are two | ||||
| 		" modes of switchbuf which we need based on the split mode | ||||
| 		let old_switchbuf = &switchbuf | ||||
|     let parts = split(a:out[0], ':') | ||||
|  | ||||
| 		if a:mode == "tab" | ||||
| 			let &switchbuf = "usetab" | ||||
|     " parts[0] contains filename | ||||
|     let fileName = parts[0] | ||||
|  | ||||
| 			if bufloaded(fileName) == 0 | ||||
| 				tab split | ||||
| 			endif | ||||
| 		else | ||||
| 			if a:mode  == "split" | ||||
| 				split | ||||
| 			elseif a:mode == "vsplit" | ||||
| 				vsplit | ||||
| 			endif | ||||
| 		endif | ||||
|     " Don't jump if it's the same identifier we just jumped to | ||||
|     if len(w:go_stack) > 0 && w:go_stack[w:go_stack_level-1]['ident'] == a:out[1] && w:go_stack[w:go_stack_level-1]['file'] == fileName | ||||
|         return | ||||
|     endif | ||||
|  | ||||
| 		" jump to file now | ||||
| 		sil ll 1 | ||||
| 		normal! zz | ||||
|     " needed for restoring back user setting this is because there are two | ||||
|     " modes of switchbuf which we need based on the split mode | ||||
|     let old_switchbuf = &switchbuf | ||||
|  | ||||
| 		let &switchbuf = old_switchbuf | ||||
| 	end | ||||
| 	let &errorformat = old_errorformat | ||||
|     if a:mode == "tab" | ||||
|         let &switchbuf = "usetab" | ||||
|  | ||||
|         if bufloaded(fileName) == 0 | ||||
|             tab split | ||||
|         endif | ||||
|     elseif a:mode  == "split" | ||||
|         split | ||||
|     elseif a:mode == "vsplit" | ||||
|         vsplit | ||||
|     else | ||||
|         " Don't jump in this window if it's been modified | ||||
|         if getbufvar(bufnr('%'), "&mod") | ||||
|             call go#util#EchoError("No write since last change") | ||||
|             return | ||||
|         endif | ||||
|     endif | ||||
|  | ||||
|     let stack_entry = {'line': line("."), 'col': col("."), | ||||
|                 \'file': expand('%:p'), 'ident': a:out[1]} | ||||
|  | ||||
|     " jump to file now | ||||
|     call s:goToFileLocation(location) | ||||
|     " | ||||
|     " Remove anything newer than the current position, just like basic | ||||
|     " vim tag support | ||||
|     if w:go_stack_level == 0 | ||||
|         let w:go_stack = [] | ||||
|     else | ||||
|         let w:go_stack = w:go_stack[0:w:go_stack_level-1] | ||||
|     endif | ||||
|  | ||||
|     " increment the stack counter | ||||
|     let w:go_stack_level += 1 | ||||
|  | ||||
|     " push it on to the jumpstack | ||||
|     call add(w:go_stack, stack_entry) | ||||
|  | ||||
|     let &switchbuf = old_switchbuf | ||||
| endfunction | ||||
|  | ||||
| function! go#def#StackUI() | ||||
|     if len(w:go_stack) == 0 | ||||
|         call go#util#EchoError("godef stack empty") | ||||
|         return | ||||
|     endif | ||||
|  | ||||
|     let stackOut = ['" <Up>,<Down>:navigate <Enter>:jump <Esc>,q:exit'] | ||||
|  | ||||
|     let i = 0 | ||||
|     while i < len(w:go_stack) | ||||
|         let entry = w:go_stack[i] | ||||
|         let prefix = "" | ||||
|         if i == w:go_stack_level | ||||
|             let prefix = ">" | ||||
|         else | ||||
|             let prefix = " " | ||||
|         endif | ||||
|         call add(stackOut, printf("%s %d %s|%d col %d|%s", prefix, i+1, entry["file"], entry["line"], entry["col"], entry["ident"])) | ||||
|         let i += 1 | ||||
|     endwhile | ||||
|     if w:go_stack_level == i | ||||
|         call add(stackOut, "> ") | ||||
|     endif | ||||
|  | ||||
|     call go#ui#OpenWindow("GoDef Stack", stackOut, "godefstack") | ||||
|     noremap <buffer> <silent> <CR>  :<C-U>call go#def#SelectStackEntry()<CR> | ||||
|     noremap <buffer> <silent> <Esc> :<C-U>call go#ui#CloseWindow()<CR> | ||||
|     noremap <buffer> <silent> q     :<C-U>call go#ui#CloseWindow()<CR> | ||||
| endfunction | ||||
|  | ||||
| function! go#def#StackPop(...) | ||||
|     if len(w:go_stack) == 0 | ||||
|         call go#util#EchoError("godef stack empty") | ||||
|         return | ||||
|     endif | ||||
|     if w:go_stack_level == 0 | ||||
|         call go#util#EchoError("at bottom of the godef stack") | ||||
|         return | ||||
|     endif | ||||
|     if !len(a:000) | ||||
|         let numPop = 1 | ||||
|     else | ||||
|         let numPop = a:1 | ||||
|     endif | ||||
|     let newLevel = str2nr(w:go_stack_level) - str2nr(numPop) | ||||
|     call go#def#StackJump(newLevel + 1) | ||||
| endfunction | ||||
|  | ||||
| function! go#def#StackJump(...) | ||||
|     if len(w:go_stack) == 0 | ||||
|         call go#util#EchoError("godef stack empty") | ||||
|         return | ||||
|     endif | ||||
| 	if !len(a:000) | ||||
|         " Display interactive stack | ||||
|         call go#def#StackUI() | ||||
|         return | ||||
| 	else | ||||
| 		let jumpTarget= a:1 | ||||
| 	endif | ||||
|  | ||||
|     if jumpTarget !~ '^\d\+$' | ||||
|         if jumpTarget !~ '^\s*$' | ||||
|             call go#util#EchoError("location must be a number") | ||||
|         endif | ||||
|         return | ||||
|     endif | ||||
|  | ||||
|     let jumpTarget=str2nr(jumpTarget) - 1 | ||||
|     if jumpTarget >= 0 && jumpTarget < len(w:go_stack) | ||||
|         let w:go_stack_level = jumpTarget | ||||
|         let target = w:go_stack[w:go_stack_level] | ||||
|  | ||||
|         " jump | ||||
|         call s:goToFileLocation(target["file"], target["line"], target["col"]) | ||||
|     else | ||||
|         call go#util#EchoError("invalid godef stack location. Try :GoDefJump to see the list of valid entries") | ||||
|     endif | ||||
| endfunction | ||||
|  | ||||
| function! s:goToFileLocation(...) | ||||
| 	let old_errorformat = &errorformat | ||||
| 	let &errorformat = "%f:%l:%c" | ||||
|  | ||||
|     " put the error format into location list so we can jump automatically to | ||||
|     " it | ||||
|     if a:0 == 3 | ||||
|         lgetexpr printf("%s:%s:%s", a:1, a:2, a:3) | ||||
|     elseif a:0 == 1 | ||||
|         lgetexpr a:1 | ||||
|     else | ||||
|         lgetexpr "" | ||||
|     endif | ||||
|  | ||||
|     sil ll 1 | ||||
|     normal zz | ||||
|  | ||||
|     let &errorformat = old_errorformat | ||||
| endfunction | ||||
|  | ||||
| function! go#def#SelectStackEntry() | ||||
|     let target_window = go#ui#GetReturnWindow() | ||||
|     if empty(target_window) | ||||
|         let target_window = winnr() | ||||
|     endif | ||||
|     let highlighted_stack_entry = matchstr(getline("."), '^..\zs\(\d\+\)') | ||||
|     if !empty(highlighted_stack_entry) | ||||
|         execute target_window . "wincmd w" | ||||
|         call go#def#StackJump(str2nr(highlighted_stack_entry)) | ||||
|     endif | ||||
|     call go#ui#CloseWindow() | ||||
| endfunction | ||||
|  | ||||
| @ -1,22 +1,6 @@ | ||||
| " Copyright 2011 The Go Authors. All rights reserved. | ||||
| " Use of this source code is governed by a BSD-style | ||||
| " license that can be found in the LICENSE file. | ||||
| " | ||||
| " godoc.vim: Vim command to see godoc. | ||||
| " | ||||
| " | ||||
| " Commands: | ||||
| " | ||||
| "   :GoDoc | ||||
| " | ||||
| "       Open the relevant Godoc for either the word[s] passed to the command or | ||||
| "       the, by default, the word under the cursor. | ||||
| " | ||||
| " Options: | ||||
| " | ||||
| "   g:go_godoc_commands [default=1] | ||||
| " | ||||
| "       Flag to indicate whether to enable the commands listed above. | ||||
|  | ||||
| let s:buf_nr = -1 | ||||
|  | ||||
| @ -33,10 +17,9 @@ endif | ||||
| " ie: github.com/fatih/set and New | ||||
| function! s:godocWord(args) | ||||
|     if !executable('godoc') | ||||
|         echohl WarningMsg | ||||
|         echo "godoc command not found." | ||||
|         echo "  install with: go get golang.org/x/tools/cmd/godoc" | ||||
|         echohl None | ||||
|         let msg = "godoc command not found." | ||||
|         let msg .= "  install with: go get golang.org/x/tools/cmd/godoc" | ||||
|         call go#util#echoWarning(msg) | ||||
|         return [] | ||||
|     endif | ||||
|  | ||||
| @ -94,47 +77,24 @@ function! go#doc#OpenBrowser(...) | ||||
| endfunction | ||||
|  | ||||
| function! go#doc#Open(newmode, mode, ...) | ||||
|     let pkgs = s:godocWord(a:000) | ||||
|     if empty(pkgs) | ||||
|     " check if we have 'gogetdoc' and use it automatically | ||||
|     let bin_path = go#path#CheckBinPath('gogetdoc') | ||||
|     if empty(bin_path) | ||||
|         return | ||||
|     endif | ||||
|  | ||||
|     let pkg = pkgs[0] | ||||
|     let exported_name = pkgs[1] | ||||
|     let offset = go#util#OffsetCursor() | ||||
|     let fname = expand("%:p") | ||||
|  | ||||
|     let command = g:go_doc_command . ' ' . g:go_doc_options . ' ' . pkg | ||||
|     let command = printf("%s -pos %s:#%s", bin_path, fname, offset) | ||||
|  | ||||
|     silent! let content = system(command) | ||||
|     if v:shell_error || s:godocNotFound(content) | ||||
|         echo 'No documentation found for "' . pkg . '".' | ||||
|         return -1 | ||||
|     let out = system(command) | ||||
|     if v:shell_error != 0 | ||||
|         call go#util#EchoError(out) | ||||
|         return | ||||
|     endif | ||||
|  | ||||
|     call s:GodocView(a:newmode, a:mode, content) | ||||
|  | ||||
|     if exported_name == '' | ||||
|         silent! normal! gg | ||||
|         return -1 | ||||
|     endif | ||||
|  | ||||
|     " jump to the specified name | ||||
|     if search('^func ' . exported_name . '(') | ||||
|         silent! normal! zt | ||||
|         return -1 | ||||
|     endif | ||||
|  | ||||
|     if search('^type ' . exported_name) | ||||
|         silent! normal! zt | ||||
|         return -1 | ||||
|     endif | ||||
|  | ||||
|     if search('^\%(const\|var\|type\|\s\+\) ' . pkg . '\s\+=\s') | ||||
|         silent! normal! zt | ||||
|         return -1 | ||||
|     endif | ||||
|  | ||||
|     " nothing found, jump to top | ||||
|     silent! normal! gg | ||||
|     call s:GodocView(a:newmode, a:mode, out) | ||||
| endfunction | ||||
|  | ||||
| function! s:GodocView(newposition, position, content) | ||||
| @ -150,6 +110,15 @@ function! s:GodocView(newposition, position, content) | ||||
|         execute bufwinnr(s:buf_nr) . 'wincmd w' | ||||
|     endif | ||||
|  | ||||
|     " cap buffer height to 20, but resize it for smaller contents | ||||
|     let max_height = 20 | ||||
|     let content_height = len(split(a:content, "\n")) | ||||
|     if content_height > max_height | ||||
|         exe 'resize ' . max_height | ||||
|     else | ||||
|         exe 'resize ' . content_height | ||||
|     endif | ||||
|  | ||||
|     setlocal filetype=godoc | ||||
|     setlocal bufhidden=delete | ||||
|     setlocal buftype=nofile | ||||
| @ -165,7 +134,10 @@ function! s:GodocView(newposition, position, content) | ||||
|     call append(0, split(a:content, "\n")) | ||||
|     sil $delete _ | ||||
|     setlocal nomodifiable | ||||
|  | ||||
|     " close easily with <esc> or enter | ||||
|     noremap <buffer> <silent> <CR> :<C-U>close<CR> | ||||
|     noremap <buffer> <silent> <Esc> :<C-U>close<CR> | ||||
| endfunction | ||||
|  | ||||
|  | ||||
| " vim:ts=4:sw=4:et | ||||
| " vim:ts=2:sw=2:et | ||||
|  | ||||
| @ -127,7 +127,10 @@ function! go#fmt#Format(withGoimport) | ||||
|         endif | ||||
|  | ||||
|         if exists('b:goimports_vendor_compatible') && b:goimports_vendor_compatible | ||||
|             let command  = command . '-srcdir ' . fnameescape(expand("%:p:h")) | ||||
|             let ssl_save = &shellslash | ||||
|             set noshellslash | ||||
|             let command  = command . '-srcdir ' . shellescape(expand("%:p:h")) | ||||
|             let &shellslash = ssl_save | ||||
|         endif | ||||
|     endif | ||||
|  | ||||
|  | ||||
| @ -2,6 +2,10 @@ | ||||
| " internal function s:spawn | ||||
| let s:jobs = {} | ||||
|  | ||||
| " s:handlers is a global event handlers for all jobs started with Spawn() or | ||||
| " with the internal function s:spawn | ||||
| let s:handlers = {} | ||||
|  | ||||
| " Spawn is a wrapper around s:spawn. It can be executed by other files and | ||||
| " scripts if needed. Desc defines the description for printing the status | ||||
| " during the job execution (useful for statusline integration). | ||||
| @ -36,6 +40,22 @@ function! go#jobcontrol#Statusline() abort | ||||
|   return '' | ||||
| endfunction | ||||
|  | ||||
| " AddHandler adds a on_exit callback handler and returns the id. | ||||
| function! go#jobcontrol#AddHandler(handler) | ||||
|   let i = len(s:handlers) | ||||
|   while has_key(s:handlers, string(i)) | ||||
|     let i += 1 | ||||
|     break | ||||
|   endwhile | ||||
|   let s:handlers[string(i)] = a:handler | ||||
|   return string(i) | ||||
| endfunction | ||||
|  | ||||
| " RemoveHandler removes a callback handler by id. | ||||
| function! go#jobcontrol#RemoveHandler(id) | ||||
|   unlet s:handlers[a:id] | ||||
| endfunction | ||||
|  | ||||
| " spawn spawns a go subcommand with the name and arguments with jobstart. Once | ||||
| " a job is started a reference will be stored inside s:jobs. spawn changes the | ||||
| " GOPATH when g:go_autodetect_gopath is enabled. The job is started inside the | ||||
| @ -95,6 +115,8 @@ endfunction | ||||
| " it'll be closed. | ||||
| function! s:on_exit(job_id, exit_status) | ||||
|   let std_combined = self.stderr + self.stdout | ||||
|   call s:callback_handlers_on_exit(s:jobs[a:job_id], a:exit_status, std_combined) | ||||
|  | ||||
|   if a:exit_status == 0 | ||||
|     call go#list#Clean(0) | ||||
|     call go#list#Window(0) | ||||
| @ -134,6 +156,17 @@ function! s:on_exit(job_id, exit_status) | ||||
|   endif | ||||
| endfunction | ||||
|  | ||||
| " callback_handlers_on_exit runs all handlers for job on exit event. | ||||
| function! s:callback_handlers_on_exit(job, exit_status, data) | ||||
|   if empty(s:handlers) | ||||
|     return | ||||
|   endif | ||||
|  | ||||
|   for s:handler in values(s:handlers) | ||||
|     call s:handler(a:job, a:exit_status, a:data) | ||||
|   endfor | ||||
| endfunction | ||||
|  | ||||
| " on_stdout is the stdout handler for jobstart(). It collects the output of | ||||
| " stderr and stores them to the jobs internal stdout list.  | ||||
| function! s:on_stdout(job_id, data) | ||||
|  | ||||
| @ -92,36 +92,46 @@ function! s:on_stderr(job_id, data) | ||||
|     call extend(job.stderr, a:data) | ||||
| endfunction | ||||
|  | ||||
| function! s:on_exit(job_id, data) | ||||
| function! s:on_exit(job_id, exit_status) | ||||
|     if !has_key(s:jobs, a:job_id) | ||||
|         return | ||||
|     endif | ||||
|     let job = s:jobs[a:job_id] | ||||
|  | ||||
|     let l:listtype = "locationlist" | ||||
|  | ||||
|     " usually there is always output so never branch into this clause | ||||
|     if empty(job.stdout) | ||||
|         call go#list#Clean(l:listtype) | ||||
|         call go#list#Window(l:listtype) | ||||
|     else | ||||
|         let errors = go#tool#ParseErrors(job.stdout) | ||||
|         let errors = go#tool#FilterValids(errors) | ||||
|         if !empty(errors) | ||||
|             " close terminal we don't need it | ||||
|             close  | ||||
|  | ||||
|             call go#list#Populate(l:listtype, errors) | ||||
|             call go#list#Window(l:listtype, len(errors)) | ||||
|             if !self.bang | ||||
|                 call go#list#JumpToFirst(l:listtype) | ||||
|             endif | ||||
|         else | ||||
|             call go#list#Clean(l:listtype) | ||||
|             call go#list#Window(l:listtype) | ||||
|         endif | ||||
|  | ||||
|         unlet s:jobs[a:job_id] | ||||
|         return | ||||
|     endif | ||||
|  | ||||
|     let errors = go#tool#ParseErrors(job.stdout) | ||||
|     let errors = go#tool#FilterValids(errors) | ||||
|  | ||||
|     if !empty(errors) | ||||
|         " close terminal we don't need it anymore | ||||
|         close  | ||||
|  | ||||
|         call go#list#Populate(l:listtype, errors) | ||||
|         call go#list#Window(l:listtype, len(errors)) | ||||
|         if !self.bang | ||||
|             call go#list#JumpToFirst(l:listtype) | ||||
|         endif | ||||
|         unlet s:jobs[a:job_id] | ||||
|         return | ||||
|     endif | ||||
|  | ||||
|     " tests are passing clean the list and close the list. But we only can | ||||
|     " close them from a normal view, so jump back, close the list and then | ||||
|     " again jump back to the terminal | ||||
|     wincmd p | ||||
|     call go#list#Clean(l:listtype) | ||||
|     call go#list#Window(l:listtype) | ||||
|     wincmd p | ||||
|  | ||||
|     unlet s:jobs[a:job_id] | ||||
| endfunction | ||||
|  | ||||
|  | ||||
| @ -1,7 +1,12 @@ | ||||
| let s:buf_nr = -1 | ||||
|  | ||||
| "OpenWindow opens a new scratch window and put's the content into the window | ||||
| function! go#ui#OpenWindow(title, content) | ||||
| function! go#ui#OpenWindow(title, content, filetype) | ||||
|     " Ensure there's only one return window in this session/tabpage | ||||
|     call go#util#Windo("unlet! w:vim_go_return_window") | ||||
|     " Mark the window we're leaving as such | ||||
|     let w:vim_go_return_window = 1 | ||||
|  | ||||
|     " reuse existing buffer window if it exists otherwise create a new one | ||||
|     if !bufexists(s:buf_nr) | ||||
|         execute 'botright new' | ||||
| @ -14,46 +19,65 @@ function! go#ui#OpenWindow(title, content) | ||||
|         execute bufwinnr(s:buf_nr) . 'wincmd w' | ||||
|     endif | ||||
|  | ||||
|     " Resize window to content length | ||||
|     exe 'resize' . len(a:content) | ||||
|  | ||||
|     " Keep minimum height to 10, if there is more just increase it that it | ||||
|     " occupies all results | ||||
|     let buffer_height = 10 | ||||
|     if len(a:content) < buffer_height | ||||
|         exe 'resize ' . buffer_height | ||||
|     else | ||||
|         exe 'resize ' . len(a:content) | ||||
|     endif | ||||
| 	 | ||||
| 		" some sane default values for a readonly buffer | ||||
|     setlocal filetype=vimgo | ||||
|     execute "setlocal filetype=".a:filetype | ||||
|  | ||||
|     " some sane default values for a readonly buffer | ||||
|     setlocal bufhidden=delete | ||||
|     setlocal buftype=nofile | ||||
|     setlocal noswapfile | ||||
|     setlocal nobuflisted | ||||
|     setlocal winfixheight | ||||
|     setlocal cursorline " make it easy to distinguish | ||||
|     setlocal nonumber | ||||
|     setlocal norelativenumber | ||||
|     setlocal showbreak="" | ||||
|  | ||||
|     " we need this to purge the buffer content | ||||
|     setlocal modifiable | ||||
|  | ||||
|     "delete everything first from the buffer | ||||
|     %delete _   | ||||
|     %delete _ | ||||
|  | ||||
|     " add the content | ||||
|     call append(0, a:content) | ||||
|  | ||||
|     " delete last line that comes from the append call | ||||
|     $delete _   | ||||
|     $delete _ | ||||
|  | ||||
|     " set it back to non modifiable | ||||
|     setlocal nomodifiable | ||||
|  | ||||
|     " Remove the '... [New File]' message line from the command line | ||||
|     echon | ||||
| endfunction | ||||
|  | ||||
| function! go#ui#GetReturnWindow() | ||||
|     for l:wn in range(1, winnr("$")) | ||||
|         if !empty(getwinvar(l:wn, "vim_go_return_window")) | ||||
|             return l:wn | ||||
|         endif | ||||
|     endfor | ||||
| endfunction | ||||
|  | ||||
| " CloseWindow closes the current window | ||||
| function! go#ui#CloseWindow() | ||||
|     close | ||||
|     echo "" | ||||
|     " Close any window associated with the ui buffer, if it's there | ||||
|     if bufexists(s:buf_nr) | ||||
|         let ui_window_number = bufwinnr(s:buf_nr) | ||||
|         if ui_window_number != -1 | ||||
|             execute ui_window_number . 'close' | ||||
|         endif | ||||
|     endif | ||||
|  | ||||
|     "return to original window, if it's there | ||||
|     let l:rw = go#ui#GetReturnWindow() | ||||
|     if !empty(l:rw) | ||||
|         execute l:rw . 'wincmd w' | ||||
|         unlet! w:vim_go_return_window | ||||
|     endif | ||||
| endfunction | ||||
|  | ||||
| " OpenDefinition parses the current line and jumps to it by openening a new | ||||
| @ -64,7 +88,7 @@ function! go#ui#OpenDefinition(filter) | ||||
|     " don't touch our first line or any blank line | ||||
|     if curline =~ a:filter || curline =~ "^$" | ||||
|         " supress information about calling this function | ||||
|         echo ""  | ||||
|         echo "" | ||||
|         return | ||||
|     endif | ||||
|  | ||||
| @ -83,7 +107,7 @@ function! go#ui#OpenDefinition(filter) | ||||
|     tab split | ||||
|     ll 1 | ||||
|  | ||||
|     " center the word  | ||||
|     norm! zz  | ||||
|     " center the word | ||||
|     norm! zz | ||||
| endfunction | ||||
|  | ||||
|  | ||||
| @ -101,6 +101,18 @@ function! go#util#OffsetCursor() | ||||
|     return go#util#Offset(line('.'), col('.')) | ||||
| endfunction | ||||
|  | ||||
| " Windo is like the built-in :windo, only it returns to the window the command | ||||
| " was issued from | ||||
| function! go#util#Windo(command) | ||||
|     let s:currentWindow = winnr() | ||||
|     try | ||||
|         execute "windo " . a:command | ||||
|     finally | ||||
|         execute s:currentWindow. "wincmd w" | ||||
|         unlet s:currentWindow | ||||
|     endtry | ||||
| endfunction | ||||
|  | ||||
| " TODO(arslan): I couldn't parameterize the highlight types. Check if we can | ||||
| " simplify the following functions | ||||
|  | ||||
|  | ||||
		Reference in New Issue
	
	Block a user
	 amix
					amix