1
0
Fork 0
mirror of synced 2024-11-26 18:55:34 -05:00

Updated plugins

This commit is contained in:
amix 2016-04-12 09:31:09 +01:00 committed by Siew Yi Liang
parent e712cad300
commit 818a7fb941
54 changed files with 1236 additions and 291 deletions

View file

@ -1,14 +1,15 @@
==== ack.vim quick help =============== ==== ack.vim quick help ===============
*?:* Show/quit this help *?:* a quick summary of these keys, repeat to close
*t:* Open in a new tab *o:* to open (same as Enter)
*T:* Open in a new tab silently *O:* to open and close the quickfix window
*o:* Open *go:* to preview file, open but maintain focus on ack.vim results
*O:* Open and close result window *t:* to open in new tab
*go:* Preview *T:* to open in new tab without moving to it
*h:* Horizontal open *h:* to open in horizontal split
*H:* Horizontal open silently *H:* to open in horizontal split, keeping focus on the results
*v:* Vertical open *v:* to open in vertical split
*gv:* Vertical open silently *gv:* to open in vertical split, keeping focus on the results
*q:* to close the quickfix window
======================================== ========================================

View file

@ -161,6 +161,8 @@ function! s:maps_resize()
return mapped return mapped
endfunction endfunction
nnoremap <silent> <plug>(goyo-resize) :<c-u>call <sid>resize_pads()<cr>
function! s:goyo_on(dim) function! s:goyo_on(dim)
let dim = s:parse_arg(a:dim) let dim = s:parse_arg(a:dim)
if empty(dim) if empty(dim)
@ -263,6 +265,9 @@ function! s:goyo_on(dim)
autocmd ColorScheme * call s:tranquilize() autocmd ColorScheme * call s:tranquilize()
autocmd BufWinEnter * call s:hide_linenr() | call s:hide_statusline() autocmd BufWinEnter * call s:hide_linenr() | call s:hide_statusline()
autocmd WinEnter,WinLeave * call s:hide_statusline() autocmd WinEnter,WinLeave * call s:hide_statusline()
if has('nvim')
autocmd TermClose * call feedkeys("\<plug>(goyo-resize)")
endif
augroup END augroup END
call s:hide_statusline() call s:hide_statusline()

View file

@ -190,7 +190,7 @@ let g:syntastic_check_on_wq = 0
__4.1. Q. I installed syntastic but it isn't reporting any errors...__ __4.1. Q. I installed syntastic but it isn't reporting any errors...__
A. The most likely reason is that none of the syntax checkers that it requires A. The most likely reason is that none of the syntax checkers that it requires
is installed. For example: by default, python requires either `flake8` or are installed. For example: by default, python requires either `flake8` or
`pylint` to be installed and in your `$PATH`. To see which executables are `pylint` to be installed and in your `$PATH`. To see which executables are
supported, look at the [wiki][3]. Note that aliases do not work; the actual supported, look at the [wiki][3]. Note that aliases do not work; the actual
executables must be available in your `$PATH`. Symbolic links are okay though. executables must be available in your `$PATH`. Symbolic links are okay though.

View file

@ -227,12 +227,12 @@ function! syntastic#preprocess#prospector(errors) abort " {{{2
call add(out, msg) call add(out, msg)
catch /\m^Vim\%((\a\+)\)\=:E716/ catch /\m^Vim\%((\a\+)\)\=:E716/
call syntastic#log#warn('checker python/prospector: unrecognized error format') call syntastic#log#warn('checker python/prospector: unrecognized error item ' . string(e))
let out = [] let out = []
break break
endtry endtry
else else
call syntastic#log#warn('checker python/prospector: unrecognized error format') call syntastic#log#warn('checker python/prospector: unrecognized error item ' . string(e))
let out = [] let out = []
break break
endif endif
@ -394,12 +394,12 @@ function! syntastic#preprocess#vint(errors) abort " {{{2
call add(out, msg) call add(out, msg)
catch /\m^Vim\%((\a\+)\)\=:E716/ catch /\m^Vim\%((\a\+)\)\=:E716/
call syntastic#log#warn('checker vim/vint: unrecognized error format') call syntastic#log#warn('checker vim/vint: unrecognized error item ' . string(e))
let out = [] let out = []
break break
endtry endtry
else else
call syntastic#log#warn('checker vim/vint: unrecognized error format') call syntastic#log#warn('checker vim/vint: unrecognized error item ' . string(e))
let out = [] let out = []
break break
endif endif

View file

@ -334,6 +334,12 @@ function! syntastic#util#stamp() abort " {{{2
return split( split(reltimestr(reltime(g:_SYNTASTIC_START)))[0], '\.' ) return split( split(reltimestr(reltime(g:_SYNTASTIC_START)))[0], '\.' )
endfunction " }}}2 endfunction " }}}2
function! syntastic#util#setChangedtick() abort " {{{2
unlockvar! b:syntastic_changedtick
let b:syntastic_changedtick = b:changedtick
lockvar! b:syntastic_changedtick
endfunction " }}}2
let s:_wid_base = 'syntastic_' . getpid() . '_' . reltimestr(g:_SYNTASTIC_START) . '_' let s:_wid_base = 'syntastic_' . getpid() . '_' . reltimestr(g:_SYNTASTIC_START) . '_'
let s:_wid_pool = 0 let s:_wid_pool = 0

View file

@ -19,7 +19,7 @@ if has('reltime')
lockvar! g:_SYNTASTIC_START lockvar! g:_SYNTASTIC_START
endif endif
let g:_SYNTASTIC_VERSION = '3.7.0-106' let g:_SYNTASTIC_VERSION = '3.7.0-112'
lockvar g:_SYNTASTIC_VERSION lockvar g:_SYNTASTIC_VERSION
" Sanity checks {{{1 " Sanity checks {{{1
@ -94,7 +94,7 @@ let g:_SYNTASTIC_DEFAULTS = {
\ 'loc_list_height': 10, \ 'loc_list_height': 10,
\ 'nested_autocommands': 0, \ 'nested_autocommands': 0,
\ 'quiet_messages': {}, \ 'quiet_messages': {},
\ 'reuse_loc_lists': 0, \ 'reuse_loc_lists': 1,
\ 'shell': &shell, \ 'shell': &shell,
\ 'sort_aggregated_errors': 1, \ 'sort_aggregated_errors': 1,
\ 'stl_format': '[Syntax: line:%F (%t)]', \ 'stl_format': '[Syntax: line:%F (%t)]',
@ -292,7 +292,7 @@ function! s:BufEnterHook() abort " {{{2
let loclist = filter(copy(getloclist(0)), 'v:val["valid"] == 1') let loclist = filter(copy(getloclist(0)), 'v:val["valid"] == 1')
let owner = str2nr(getbufvar(bufnr(''), 'syntastic_owner_buffer')) let owner = str2nr(getbufvar(bufnr(''), 'syntastic_owner_buffer'))
let buffers = syntastic#util#unique(map(loclist, 'v:val["bufnr"]') + (owner ? [owner] : [])) let buffers = syntastic#util#unique(map(loclist, 'v:val["bufnr"]') + (owner ? [owner] : []))
if get(w:, 'syntastic_loclist_set', 0) && !empty(loclist) && empty(filter( buffers, 'syntastic#util#bufIsActive(v:val)' )) if !empty(get(w:, 'syntastic_loclist_set', [])) && !empty(loclist) && empty(filter( buffers, 'syntastic#util#bufIsActive(v:val)' ))
call SyntasticLoclistHide() call SyntasticLoclistHide()
endif endif
endif endif
@ -307,7 +307,7 @@ function! s:QuitPreHook(fname) abort " {{{2
call add(s:_quit_pre, buf . '_' . getbufvar(buf, 'changetick') . '_' . w:syntastic_wid) call add(s:_quit_pre, buf . '_' . getbufvar(buf, 'changetick') . '_' . w:syntastic_wid)
endif endif
if get(w:, 'syntastic_loclist_set', 0) if !empty(get(w:, 'syntastic_loclist_set', []))
call SyntasticLoclistHide() call SyntasticLoclistHide()
endif endif
endfunction " }}}2 endfunction " }}}2
@ -333,9 +333,7 @@ function! s:UpdateErrors(auto_invoked, checker_names) abort " {{{2
let run_checks = !a:auto_invoked || s:modemap.doAutoChecking() let run_checks = !a:auto_invoked || s:modemap.doAutoChecking()
if run_checks if run_checks
call s:CacheErrors(a:checker_names) call s:CacheErrors(a:checker_names)
unlockvar! b:syntastic_changedtick call syntastic#util#setChangedtick()
let b:syntastic_changedtick = b:changedtick
lockvar! b:syntastic_changedtick
else else
if a:auto_invoked if a:auto_invoked
return return
@ -358,11 +356,14 @@ function! s:UpdateErrors(auto_invoked, checker_names) abort " {{{2
let do_jump = 0 let do_jump = 0
endif endif
let w:syntastic_loclist_set = 0 let w:syntastic_loclist_set = []
if syntastic#util#var('always_populate_loc_list') || do_jump if syntastic#util#var('always_populate_loc_list') || do_jump
call syntastic#log#debug(g:_SYNTASTIC_DEBUG_NOTIFICATIONS, 'loclist: setloclist (new)') call syntastic#log#debug(g:_SYNTASTIC_DEBUG_NOTIFICATIONS, 'loclist: setloclist (new)')
call setloclist(0, loclist.getRaw()) call setloclist(0, loclist.getRaw())
let w:syntastic_loclist_set = 1 if !exists('b:syntastic_changedtick')
call syntastic#util#setChangedtick()
endif
let w:syntastic_loclist_set = [bufnr(''), b:syntastic_changedtick]
if run_checks && do_jump && !loclist.isEmpty() if run_checks && do_jump && !loclist.isEmpty()
call syntastic#log#debug(g:_SYNTASTIC_DEBUG_NOTIFICATIONS, 'loclist: jump') call syntastic#log#debug(g:_SYNTASTIC_DEBUG_NOTIFICATIONS, 'loclist: jump')
execute 'silent! lrewind ' . do_jump execute 'silent! lrewind ' . do_jump

View file

@ -291,12 +291,15 @@ endfunction " }}}2
function! g:SyntasticLoclist.setloclist() abort " {{{2 function! g:SyntasticLoclist.setloclist() abort " {{{2
if !exists('w:syntastic_loclist_set') if !exists('w:syntastic_loclist_set')
let w:syntastic_loclist_set = 0 let w:syntastic_loclist_set = []
endif
if empty(w:syntastic_loclist_set) || w:syntastic_loclist_set != [bufnr(''), b:changedtick]
let replace = g:syntastic_reuse_loc_lists && !empty(w:syntastic_loclist_set)
call syntastic#log#debug(g:_SYNTASTIC_DEBUG_NOTIFICATIONS, 'loclist: setloclist ' . (replace ? '(replace)' : '(new)'))
call setloclist(0, self.getRaw(), replace ? 'r' : ' ')
call syntastic#util#setChangedtick()
let w:syntastic_loclist_set = [bufnr(''), b:syntastic_changedtick]
endif endif
let replace = g:syntastic_reuse_loc_lists && w:syntastic_loclist_set
call syntastic#log#debug(g:_SYNTASTIC_DEBUG_NOTIFICATIONS, 'loclist: setloclist ' . (replace ? '(replace)' : '(new)'))
call setloclist(0, self.getRaw(), replace ? 'r' : ' ')
let w:syntastic_loclist_set = 1
endfunction " }}}2 endfunction " }}}2
"display the cached errors for this buf in the location list "display the cached errors for this buf in the location list

View file

@ -24,22 +24,28 @@ if !exists('g:syntastic_d_compiler_options')
let g:syntastic_d_compiler_options = '' let g:syntastic_d_compiler_options = ''
endif endif
if !exists('g:syntastic_d_use_dub')
let g:syntastic_d_use_dub = 1
endif
if !exists('g:syntastic_d_dub_exec')
let g:syntastic_d_dub_exec = 'dub'
endif
let s:save_cpo = &cpo let s:save_cpo = &cpo
set cpo&vim set cpo&vim
function! SyntaxCheckers_d_dmd_IsAvailable() dict function! SyntaxCheckers_d_dmd_IsAvailable() dict " {{{1
if !exists('g:syntastic_d_compiler') if !exists('g:syntastic_d_compiler')
let g:syntastic_d_compiler = self.getExec() let g:syntastic_d_compiler = self.getExec()
endif endif
call self.log('g:syntastic_d_compiler =', g:syntastic_d_compiler) call self.log('g:syntastic_d_compiler =', g:syntastic_d_compiler)
return executable(expand(g:syntastic_d_compiler, 1)) return executable(expand(g:syntastic_d_compiler, 1))
endfunction endfunction " }}}1
function! SyntaxCheckers_d_dmd_GetLocList() dict function! SyntaxCheckers_d_dmd_GetLocList() dict " {{{1
if !exists('g:syntastic_d_include_dirs') if !exists('g:syntastic_d_include_dirs')
let g:syntastic_d_include_dirs = filter(glob($HOME . '/.dub/packages/*', 1, 1), 'isdirectory(v:val)') let g:syntastic_d_include_dirs = s:GetIncludes(self, expand('%:p:h'))
call map(g:syntastic_d_include_dirs, 'isdirectory(v:val . "/source") ? v:val . "/source" : v:val')
call add(g:syntastic_d_include_dirs, './source')
endif endif
return syntastic#c#GetLocList('d', 'dmd', { return syntastic#c#GetLocList('d', 'dmd', {
@ -48,7 +54,73 @@ function! SyntaxCheckers_d_dmd_GetLocList() dict
\ '%f:%l: %m', \ '%f:%l: %m',
\ 'main_flags': '-c -of' . syntastic#util#DevNull(), \ 'main_flags': '-c -of' . syntastic#util#DevNull(),
\ 'header_names': '\m\.di$' }) \ 'header_names': '\m\.di$' })
endfunction endfunction " }}}1
" Utilities {{{1
function! s:GetIncludes(checker, base) " {{{2
let includes = []
if g:syntastic_d_use_dub && !exists('s:dub_ok')
let s:dub_ok = s:ValidateDub(a:checker)
endif
if g:syntastic_d_use_dub && s:dub_ok
let where = escape(a:base, ' ') . ';'
let old_suffixesadd = &suffixesadd
let dirs = syntastic#util#unique(map(filter(
\ findfile('dub.json', where, -1) +
\ findfile('dub.sdl', where, -1) +
\ findfile('package.json', where, -1),
\ 'filereadable(v:val)'), 'fnamemodify(v:val, ":h")'))
let &suffixesadd = old_suffixesadd
call a:checker.log('using dub: looking for includes in', dirs)
for dir in dirs
try
execute 'silent lcd ' . fnameescape(dir)
let paths = split(syntastic#util#system(syntastic#util#shescape(g:syntastic_d_dub_exec) . ' describe --import-paths'), "\n")
silent lcd -
if v:shell_error == 0
call extend(includes, paths)
call a:checker.log('using dub: found includes', paths)
endif
catch /\m^Vim\%((\a\+)\)\=:E472/
" evil directory is evil
endtry
endfor
endif
if empty(includes)
let includes = filter(glob($HOME . '/.dub/packages/*', 1, 1), 'isdirectory(v:val)')
call map(includes, 'isdirectory(v:val . "/source") ? v:val . "/source" : v:val')
call add(includes, './source')
endif
return syntastic#util#unique(includes)
endfunction " }}}2
function! s:ValidateDub(checker) " {{{2
let ok = 0
if executable(g:syntastic_d_dub_exec)
let command = syntastic#util#shescape(g:syntastic_d_dub_exec) . ' --version'
let version_output = syntastic#util#system(command)
call a:checker.log('getVersion: ' . string(command) . ': ' .
\ string(split(version_output, "\n", 1)) .
\ (v:shell_error ? ' (exit code ' . v:shell_error . ')' : '') )
let parsed_ver = syntastic#util#parseVersion(version_output)
call a:checker.log(g:syntastic_d_dub_exec . ' version =', parsed_ver)
if len(parsed_ver)
let ok = syntastic#util#versionIsAtLeast(parsed_ver, [0, 9, 24])
endif
endif
return ok
endfunction " }}}2
" }}}1
call g:SyntasticRegistry.CreateAndRegisterChecker({ call g:SyntasticRegistry.CreateAndRegisterChecker({
\ 'filetype': 'd', \ 'filetype': 'd',

View file

@ -16,25 +16,25 @@ let s:gui0D = "#0d61ac"
let s:gui0E = "#c594c5" let s:gui0E = "#c594c5"
let s:gui0F = "#ab7967" let s:gui0F = "#ab7967"
let s:cterm00 = "234" let s:cterm00 = "233"
let s:cterm01 = "235" let s:cterm01 = "235"
let s:cterm02 = "239" let s:cterm02 = "59"
let s:cterm03 = "59" let s:cterm03 = "66"
let s:cterm04 = "145" let s:cterm04 = "145"
let s:cterm05 = "152" let s:cterm05 = "152"
let s:cterm06 = "188" let s:cterm06 = "188"
let s:cterm07 = "15" let s:cterm07 = "189"
let s:cterm08 = "88" let s:cterm08 = "88"
let s:cterm09 = "209" let s:cterm09 = "209"
let s:cterm0A = "221" let s:cterm0A = "221"
let s:cterm0B = "28" let s:cterm0B = "64"
let s:cterm0C = "73" let s:cterm0C = "73"
let s:cterm0D = "04" let s:cterm0D = "25"
let s:cterm0E = "176" let s:cterm0E = "176"
let s:cterm0F = "137" let s:cterm0F = "137"
let s:guiWhite = "#ffffff" let s:guiWhite = "#ffffff"
let s:ctermWhite = "15" let s:ctermWhite = "231"
let g:airline#themes#jellybeans#palette = {} let g:airline#themes#jellybeans#palette = {}

View file

@ -4,26 +4,26 @@
" Normal mode " Normal mode
" [ guifg, guibg, ctermfg, ctermbg, opts ] " [ guifg, guibg, ctermfg, ctermbg, opts ]
let s:N1 = [ '#141413' , '#CAE682' , 232 , 192 ] " mode let s:N1 = [ '#141413' , '#CAE682' , 232 , 192 ] " mode
let s:N2 = [ '#CAE682' , '#32322F' , 192 , 236 ] " info let s:N2 = [ '#CAE682' , '#32322F' , 192 , 238 ] " info
let s:N3 = [ '#CAE682' , '#242424' , 192 , 234 ] " statusline let s:N3 = [ '#CAE682' , '#242424' , 192 , 235 ] " statusline
let s:N4 = [ '#86CD74' , 113 ] " mode modified let s:N4 = [ '#86CD74' , 113 ] " mode modified
" Insert mode " Insert mode
let s:I1 = [ '#141413' , '#FDE76E' , 232 , 227 ] let s:I1 = [ '#141413' , '#FDE76E' , 232 , 227 ]
let s:I2 = [ '#FDE76E' , '#32322F' , 227 , 236 ] let s:I2 = [ '#FDE76E' , '#32322F' , 227 , 238 ]
let s:I3 = [ '#FDE76E' , '#242424' , 227 , 234 ] let s:I3 = [ '#FDE76E' , '#242424' , 227 , 235 ]
let s:I4 = [ '#FADE3E' , 221 ] let s:I4 = [ '#FADE3E' , 221 ]
" Visual mode " Visual mode
let s:V1 = [ '#141413' , '#B5D3F3' , 232 , 153 ] let s:V1 = [ '#141413' , '#B5D3F3' , 232 , 153 ]
let s:V2 = [ '#B5D3F3' , '#32322F' , 153 , 236 ] let s:V2 = [ '#B5D3F3' , '#32322F' , 153 , 238 ]
let s:V3 = [ '#B5D3F3' , '#242424' , 153 , 234 ] let s:V3 = [ '#B5D3F3' , '#242424' , 153 , 235 ]
let s:V4 = [ '#7CB0E6' , 111 ] let s:V4 = [ '#7CB0E6' , 111 ]
" Replace mode " Replace mode
let s:R1 = [ '#141413' , '#E5786D' , 232 , 173 ] let s:R1 = [ '#141413' , '#E5786D' , 232 , 173 ]
let s:R2 = [ '#E5786D' , '#32322F' , 173 , 236 ] let s:R2 = [ '#E5786D' , '#32322F' , 173 , 238 ]
let s:R3 = [ '#E5786D' , '#242424' , 173 , 234 ] let s:R3 = [ '#E5786D' , '#242424' , 173 , 235 ]
let s:R4 = [ '#E55345' , 203 ] let s:R4 = [ '#E55345' , 203 ]
" Paste mode " Paste mode

View file

@ -45,17 +45,17 @@ function! airline#extensions#tabline#tabs#get()
for i in range(1, tabpagenr('$')) for i in range(1, tabpagenr('$'))
if i == curtab if i == curtab
let group = 'airline_tabsel_right' let group = 'airline_tabsel'
if g:airline_detect_modified if g:airline_detect_modified
for bi in tabpagebuflist(i) for bi in tabpagebuflist(i)
if getbufvar(bi, '&modified') if getbufvar(bi, '&modified')
let group = 'airline_tabmod_right' let group = 'airline_tabmod'
endif endif
endfor endfor
endif endif
let s:current_modified = (group == 'airline_tabmod_right') ? 1 : 0 let s:current_modified = (group == 'airline_tabmod') ? 1 : 0
else else
let group = 'airline_tab_right' let group = 'airline_tab'
endif endif
let val = '%(' let val = '%('
if s:show_tab_nr if s:show_tab_nr
@ -81,7 +81,7 @@ function! airline#extensions#tabline#tabs#get()
if s:show_splits == 1 if s:show_splits == 1
let buffers = tabpagebuflist(curtab) let buffers = tabpagebuflist(curtab)
for nr in buffers for nr in buffers
let group = airline#extensions#tabline#group_of_bufnr(buffers, nr) let group = airline#extensions#tabline#group_of_bufnr(buffers, nr) . "_right"
call b.add_section_spaced(group, '%(%{airline#extensions#tabline#get_buffer_name('.nr.')}%)') call b.add_section_spaced(group, '%(%{airline#extensions#tabline#get_buffer_name('.nr.')}%)')
endfor endfor
elseif s:show_tab_type == 1 elseif s:show_tab_type == 1

View file

@ -18,7 +18,7 @@ let s:max_lines = get(g:, 'airline#extensions#whitespace#max_lines', 20000)
let s:enabled = get(g:, 'airline#extensions#whitespace#enabled', 1) let s:enabled = get(g:, 'airline#extensions#whitespace#enabled', 1)
let s:c_like_langs = ['c', 'cpp', 'javascript', 'ld'] let s:c_like_langs = ['c', 'cpp', 'cuda', 'java', 'javascript', 'ld']
function! s:check_mixed_indent() function! s:check_mixed_indent()
if s:indent_algo == 1 if s:indent_algo == 1

View file

@ -1,7 +1,7 @@
" MIT License. Copyright (c) 2013-2016 Bailey Ling. " MIT License. Copyright (c) 2013-2016 Bailey Ling.
" vim: et ts=2 sts=2 sw=2 " vim: et ts=2 sts=2 sw=2
let s:filetypes = get(g:, 'airline#extensions#wordcount#filetypes', '\vhelp|markdown|rst|org|text') let s:filetypes = get(g:, 'airline#extensions#wordcount#filetypes', '\vhelp|markdown|rst|org|text|asciidoc')
let s:format = get(g:, 'airline#extensions#wordcount#format', '%d words') let s:format = get(g:, 'airline#extensions#wordcount#format', '%d words')
let s:formatter = get(g:, 'airline#extensions#wordcount#formatter', 'default') let s:formatter = get(g:, 'airline#extensions#wordcount#formatter', 'default')

View file

@ -2327,7 +2327,7 @@ function! s:Browse(bang,line1,count,...) abort
let url = s:gsub(url, '[ <>]', '\="%".printf("%02X",char2nr(submatch(0)))') let url = s:gsub(url, '[ <>]', '\="%".printf("%02X",char2nr(submatch(0)))')
if a:bang if a:bang
if has('clipboard') if has('clipboard')
let @* = url let @+ = url
endif endif
return 'echomsg '.string(url) return 'echomsg '.string(url)
elseif exists(':Browse') == 2 elseif exists(':Browse') == 2

View file

@ -0,0 +1,27 @@
## 1.6 (unreleased)
FEATURES:
* New `CHANGELOG.md` file (which you're reading now). This will make it easier
for me to track changes and release versions
* **`:GoCoverage`**: is now highlighting the current source file for
covered/uncovered lines. If called again it clears the highlighting. This is
a pretty good addition to vim-go and I suggest to check out the gif that shows
it in action: https://twitter.com/fatih/status/716722650383564800 [gh-786]
* **`:GoCoverageBrowser`**: opens a new annotated HTML page. This is the old
`:GoCoverage` behavior [gh-786]
* **`GoDoc`**: uses now `[gogetdoc](https://github.com/zmb3/gogetdoc)` to
lookup and display the comment documentation for the identifier under the
cursor. This is more superior as it support looking up dot imports, named
imports and imports where package name and file name are different [gh-782]
IMPROVEMENTS:
* **`:GoCoverage`** is now executed async when used within Neovim [gh-686]
BUG FIXES:
* Fix not showing documentation for dot, named and package/file name being different imports [gh-332]
* Term mode: fix closing location list if result is successful after a failed attempt [gh-768]
* Syntax: fix gotexttmpl identifier highlighting [gh-778]

View file

@ -9,8 +9,6 @@ disabled/enabled easily.
![vim-go](https://dl.dropboxusercontent.com/u/174404/vim-go-2.png) ![vim-go](https://dl.dropboxusercontent.com/u/174404/vim-go-2.png)
## Features ## Features
* Improved Syntax highlighting with items such as Functions, Operators, Methods. * Improved Syntax highlighting with items such as Functions, Operators, Methods.
@ -26,8 +24,8 @@ disabled/enabled easily.
* Automatic `GOPATH` detection based on the directory structure (i.e. `gb` * Automatic `GOPATH` detection based on the directory structure (i.e. `gb`
projects, `godep` vendored projects) projects, `godep` vendored projects)
* Change or display `GOPATH` with `:GoPath` * Change or display `GOPATH` with `:GoPath`
* Create a coverage profile and display annotated source code in browser to see * Create a coverage profile and display annotated source code to see which
which functions are covered with `:GoCoverage` functions are covered with `:GoCoverage`
* Call `gometalinter` with `:GoMetaLinter`, which invokes all possible linters * Call `gometalinter` with `:GoMetaLinter`, which invokes all possible linters
(golint, vet, errcheck, deadcode, etc..) and shows the warnings/errors (golint, vet, errcheck, deadcode, etc..) and shows the warnings/errors
* Lint your code with `:GoLint` * Lint your code with `:GoLint`
@ -45,6 +43,7 @@ disabled/enabled easily.
* Tagbar support to show tags of the source code in a sidebar with `gotags` * Tagbar support to show tags of the source code in a sidebar with `gotags`
* Custom vim text objects such as `a function` or `inner function` * Custom vim text objects such as `a function` or `inner function`
list. list.
* Jump to function or type declarations with `:GoDecls` or `:GoDeclsDir`
* A async launcher for the go command is implemented for Neovim, fully async * A async launcher for the go command is implemented for Neovim, fully async
building and testing (beta). building and testing (beta).
* Integrated with the Neovim terminal, launch `:GoRun` and other go commands * Integrated with the Neovim terminal, launch `:GoRun` and other go commands

View file

@ -0,0 +1,13 @@
#!/usr/bin/env rake
task :ci => [:dump, :test]
task :dump do
sh 'vim --version'
end
# Firstly, `bundle install; bundle install --deployment`
# Then, `rake test`
task :test do
sh 'bundle exec vim-flavor test'
end

View file

@ -213,11 +213,11 @@ function! go#cmd#Test(bang, compile, ...)
if has('nvim') if has('nvim')
if get(g:, 'go_term_enabled', 0) 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 else
call go#jobcontrol#Spawn(a:bang, "test", args) let id = go#jobcontrol#Spawn(a:bang, "test", args)
endif endif
return return id
endif endif
call go#cmd#autowrite() call go#cmd#autowrite()
@ -290,36 +290,6 @@ function! go#cmd#TestFunc(bang, ...)
call call('go#cmd#Test', args) call call('go#cmd#Test', args)
endfunction 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() " Generate runs 'go generate' in similar fashion to go#cmd#Build()
function! go#cmd#Generate(bang, ...) function! go#cmd#Generate(bang, ...)
let default_makeprg = &makeprg let default_makeprg = &makeprg

View 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

View file

@ -29,13 +29,17 @@ function! go#def#Jump(...)
let $GOPATH = go#path#Detect() let $GOPATH = go#path#Detect()
let fname = fnamemodify(expand("%"), ':p:gs?\\?/?') 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 " get output of godef
let out = s:system(command, join(getbufline(bufnr('%'), 1, '$'), go#util#LineEnding())) 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 " jump to it
call s:godefJump(out, "") call s:godefJump(godefout, "")
let $GOPATH = old_gopath let $GOPATH = old_gopath
endfunction endfunction
@ -52,12 +56,17 @@ function! go#def#JumpMode(mode)
let $GOPATH = go#path#Detect() let $GOPATH = go#path#Detect()
let fname = fnamemodify(expand("%"), ':p:gs?\\?/?') 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 " get output of godef
let out = s:system(command, join(getbufline(bufnr('%'), 1, '$'), go#util#LineEnding())) 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 let $GOPATH = old_gopath
endfunction endfunction
@ -71,41 +80,181 @@ function! s:godefJump(out, mode)
let old_errorformat = &errorformat let old_errorformat = &errorformat
let &errorformat = "%f:%l:%c" let &errorformat = "%f:%l:%c"
if a:out =~ 'godef: ' " Location is the first line of godef output. Ideally in the proper format
let out = substitute(a:out, go#util#LineEnding() . '$', '', '') " but it could also be an error
echom out let location = a:out[0]
else
let parts = split(a:out, ':')
" parts[0] contains filename
let fileName = parts[0]
" put the error format into location list so we can jump automatically to " Echo the godef error if we had one.
" it if location =~ 'godef: '
lgetexpr a:out 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 let parts = split(a:out[0], ':')
" modes of switchbuf which we need based on the split mode
let old_switchbuf = &switchbuf
if a:mode == "tab" " parts[0] contains filename
let &switchbuf = "usetab" let fileName = parts[0]
if bufloaded(fileName) == 0 " Don't jump if it's the same identifier we just jumped to
tab split 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
endif return
else endif
if a:mode == "split"
split
elseif a:mode == "vsplit"
vsplit
endif
endif
" jump to file now " needed for restoring back user setting this is because there are two
sil ll 1 " modes of switchbuf which we need based on the split mode
normal! zz let old_switchbuf = &switchbuf
let &switchbuf = old_switchbuf if a:mode == "tab"
end let &switchbuf = "usetab"
let &errorformat = old_errorformat
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 endfunction

View file

@ -1,22 +1,6 @@
" Copyright 2011 The Go Authors. All rights reserved. " Copyright 2011 The Go Authors. All rights reserved.
" Use of this source code is governed by a BSD-style " Use of this source code is governed by a BSD-style
" license that can be found in the LICENSE file. " 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 let s:buf_nr = -1
@ -33,10 +17,9 @@ endif
" ie: github.com/fatih/set and New " ie: github.com/fatih/set and New
function! s:godocWord(args) function! s:godocWord(args)
if !executable('godoc') if !executable('godoc')
echohl WarningMsg let msg = "godoc command not found."
echo "godoc command not found." let msg .= " install with: go get golang.org/x/tools/cmd/godoc"
echo " install with: go get golang.org/x/tools/cmd/godoc" call go#util#echoWarning(msg)
echohl None
return [] return []
endif endif
@ -94,47 +77,24 @@ function! go#doc#OpenBrowser(...)
endfunction endfunction
function! go#doc#Open(newmode, mode, ...) function! go#doc#Open(newmode, mode, ...)
let pkgs = s:godocWord(a:000) " check if we have 'gogetdoc' and use it automatically
if empty(pkgs) let bin_path = go#path#CheckBinPath('gogetdoc')
if empty(bin_path)
return return
endif endif
let pkg = pkgs[0] let offset = go#util#OffsetCursor()
let exported_name = pkgs[1] 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) let out = system(command)
if v:shell_error || s:godocNotFound(content) if v:shell_error != 0
echo 'No documentation found for "' . pkg . '".' call go#util#EchoError(out)
return -1 return
endif endif
call s:GodocView(a:newmode, a:mode, content) call s:GodocView(a:newmode, a:mode, out)
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
endfunction endfunction
function! s:GodocView(newposition, position, content) function! s:GodocView(newposition, position, content)
@ -150,6 +110,15 @@ function! s:GodocView(newposition, position, content)
execute bufwinnr(s:buf_nr) . 'wincmd w' execute bufwinnr(s:buf_nr) . 'wincmd w'
endif 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 filetype=godoc
setlocal bufhidden=delete setlocal bufhidden=delete
setlocal buftype=nofile setlocal buftype=nofile
@ -165,7 +134,10 @@ function! s:GodocView(newposition, position, content)
call append(0, split(a:content, "\n")) call append(0, split(a:content, "\n"))
sil $delete _ sil $delete _
setlocal nomodifiable 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 endfunction
" vim:ts=2:sw=2:et
" vim:ts=4:sw=4:et

View file

@ -127,7 +127,10 @@ function! go#fmt#Format(withGoimport)
endif endif
if exists('b:goimports_vendor_compatible') && b:goimports_vendor_compatible 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
endif endif

View file

@ -2,6 +2,10 @@
" internal function s:spawn " internal function s:spawn
let s:jobs = {} 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 " 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 " scripts if needed. Desc defines the description for printing the status
" during the job execution (useful for statusline integration). " during the job execution (useful for statusline integration).
@ -36,6 +40,22 @@ function! go#jobcontrol#Statusline() abort
return '' return ''
endfunction 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 " 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 " 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 " GOPATH when g:go_autodetect_gopath is enabled. The job is started inside the
@ -95,6 +115,8 @@ endfunction
" it'll be closed. " it'll be closed.
function! s:on_exit(job_id, exit_status) function! s:on_exit(job_id, exit_status)
let std_combined = self.stderr + self.stdout 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 if a:exit_status == 0
call go#list#Clean(0) call go#list#Clean(0)
call go#list#Window(0) call go#list#Window(0)
@ -134,6 +156,17 @@ function! s:on_exit(job_id, exit_status)
endif endif
endfunction 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 " on_stdout is the stdout handler for jobstart(). It collects the output of
" stderr and stores them to the jobs internal stdout list. " stderr and stores them to the jobs internal stdout list.
function! s:on_stdout(job_id, data) function! s:on_stdout(job_id, data)

View file

@ -92,36 +92,46 @@ function! s:on_stderr(job_id, data)
call extend(job.stderr, a:data) call extend(job.stderr, a:data)
endfunction endfunction
function! s:on_exit(job_id, data) function! s:on_exit(job_id, exit_status)
if !has_key(s:jobs, a:job_id) if !has_key(s:jobs, a:job_id)
return return
endif endif
let job = s:jobs[a:job_id] let job = s:jobs[a:job_id]
let l:listtype = "locationlist" let l:listtype = "locationlist"
" usually there is always output so never branch into this clause " usually there is always output so never branch into this clause
if empty(job.stdout) if empty(job.stdout)
call go#list#Clean(l:listtype) call go#list#Clean(l:listtype)
call go#list#Window(l:listtype) call go#list#Window(l:listtype)
else unlet s:jobs[a:job_id]
let errors = go#tool#ParseErrors(job.stdout) return
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
endif 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] unlet s:jobs[a:job_id]
endfunction endfunction

View file

@ -1,7 +1,12 @@
let s:buf_nr = -1 let s:buf_nr = -1
"OpenWindow opens a new scratch window and put's the content into the window "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 " reuse existing buffer window if it exists otherwise create a new one
if !bufexists(s:buf_nr) if !bufexists(s:buf_nr)
execute 'botright new' execute 'botright new'
@ -14,24 +19,21 @@ function! go#ui#OpenWindow(title, content)
execute bufwinnr(s:buf_nr) . 'wincmd w' execute bufwinnr(s:buf_nr) . 'wincmd w'
endif 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 execute "setlocal filetype=".a:filetype
" 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 " some sane default values for a readonly buffer
setlocal filetype=vimgo
setlocal bufhidden=delete setlocal bufhidden=delete
setlocal buftype=nofile setlocal buftype=nofile
setlocal noswapfile setlocal noswapfile
setlocal nobuflisted setlocal nobuflisted
setlocal winfixheight setlocal winfixheight
setlocal cursorline " make it easy to distinguish setlocal cursorline " make it easy to distinguish
setlocal nonumber
setlocal norelativenumber
setlocal showbreak=""
" we need this to purge the buffer content " we need this to purge the buffer content
setlocal modifiable setlocal modifiable
@ -47,13 +49,35 @@ function! go#ui#OpenWindow(title, content)
" set it back to non modifiable " set it back to non modifiable
setlocal nomodifiable setlocal nomodifiable
" Remove the '... [New File]' message line from the command line
echon
endfunction 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 " CloseWindow closes the current window
function! go#ui#CloseWindow() function! go#ui#CloseWindow()
close " Close any window associated with the ui buffer, if it's there
echo "" 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 endfunction
" OpenDefinition parses the current line and jumps to it by openening a new " OpenDefinition parses the current line and jumps to it by openening a new

View file

@ -101,6 +101,18 @@ function! go#util#OffsetCursor()
return go#util#Offset(line('.'), col('.')) return go#util#Offset(line('.'), col('.'))
endfunction 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 " TODO(arslan): I couldn't parameterize the highlight types. Check if we can
" simplify the following functions " simplify the following functions

View file

@ -47,7 +47,7 @@ easily.
* Automatic `GOPATH` detection based on the directory structure (i.e. `gb` * Automatic `GOPATH` detection based on the directory structure (i.e. `gb`
projects, `godep` vendored projects) projects, `godep` vendored projects)
* Change or display `GOPATH` with `:GoPath` * Change or display `GOPATH` with `:GoPath`
* Create a coverage profile and display annotated source code in browser to see * Create a coverage profile and display annotated source code in to see
which functions are covered with `:GoCoverage` which functions are covered with `:GoCoverage`
* Call `gometalinter` with `:GoMetaLinter`, which invokes all possible linters * Call `gometalinter` with `:GoMetaLinter`, which invokes all possible linters
(golint, vet, errcheck, deadcode, etc..) and shows the warnings/errors (golint, vet, errcheck, deadcode, etc..) and shows the warnings/errors
@ -211,11 +211,62 @@ COMMANDS *go-commands*
*:GoDef* *:GoDef*
:GoDef [identifier] :GoDef [identifier]
gd
CTRL-]
Goto declaration/definition for the given [identifier]. If no argument is Goto declaration/definition for the given [identifier]. If no argument is
given, it will jump to the declaration under the cursor. By default the given, it will jump to the declaration under the cursor. By default the
mapping `gd` is enabled to invoke GoDef for the identifier under the cursor. CTRL-] key and the mapping `gd` are enabled to invoke :GoDef for the
See |g:go_def_mapping_enabled| to disable it. identifier under the cursor. See |g:go_def_mapping_enabled| to disable them.
vim-go also keeps a per-window location stack, roughly analagous to how
vim's internal |tags| functionality works. This is pushed to every time a
jump is made using the GoDef functionality. In essence, this is a LIFO list
of file locations you have visited with :GoDef that is retained to help you
navigate software. For more information on displaying the stack, see
|:GoDefJump|
*:GoDefJump*
:GoDefJump [number]
This command Jumps to a given location in the jumpstack, retaining all other
entries. Jumps to non-existent entries will print an informative message,
but are otherwise a noop.
If no argument is given, it will print out an interactive list of all items
in the stack. Its output looks like this:
1 /path/to/first/file.go|1187 col 16|AddThing func(t *Thing)
> 2 /path/to/thing/thing.go|624 col 19|String() string
3 /path/to/thing/thing.go|744 col 6|func Sprintln(a ...interface{}) string
This list shows the identifiers that you jumped to and the file and cursor
position before that jump. The older jumps are at the top, the newer at the
bottom.
The '>' points to the active entry. This entry and any newer entries below
it will be replaced if |:GoDef| is done from this location. The CTRL-t and
|:GoDefPop| command will jump to the position above the active entry.
Jumps to non-existent entries will print an informative message, but are
otherwise a noop.
*:GoDefPop*
:GoDefPop [count]
CTRL-t
Navigate to the [count] earlier entry in the jump stack, retaining the newer
entries. If no argument is given, it will jump to the next most recent entry
(`:GoDefPop 1`). If [count] is greater than the number of prior entries,
an error will be printed and no jump will be performed.
If you have used :GoDefPop to jump to an earlier location, and you issue
another :GoDef command, the current entry will be replaced, and all newer
entries will be removed, effectively resuming the stack at that location.
By default [count]CTRL-t is enabled to invoke :GoDefPop. Similarly, hitting
CTRL-t without a prior count is equivalent to `:GoDefPop 1`. See
|g:go_def_mapping_enabled| to disable this.
*:GoRun* *:GoRun*
:GoRun[!] [expand] :GoRun[!] [expand]
@ -323,13 +374,22 @@ COMMANDS *go-commands*
If [!] is not given the first error is jumped to. If [!] is not given the first error is jumped to.
If using neovim `:GoTestCompile` will run in a new terminal or run asynchronously If using neovim `:GoTestCompile` will run in a new terminal or run
in the background according to |g:go_term_enabled|. You can set the mode of asynchronously in the background according to |g:go_term_enabled|. You can
the new terminal with |g:go_term_mode|. set the mode of the new terminal with |g:go_term_mode|.
*:GoCoverage* *:GoCoverage*
:GoCoverage[!] [options] :GoCoverage[!] [options]
Create a coverage profile and annotates the current file's source code. If
called again clears the annotation (works as a toggle)
If [!] is not given the first error is jumped to.
*:GoCoverageBrowser*
:GoCoverageBrowser[!] [options]
Create a coverage profile and open a browser to display the annotated Create a coverage profile and open a browser to display the annotated
source code of the current package. source code of the current package.
@ -846,8 +906,9 @@ In Go, using `godoc` is more idiomatic. Default is enabled. >
< <
*'g:go_def_mapping_enabled'* *'g:go_def_mapping_enabled'*
Use this option to enable/disable the default mapping of (`gd`) for GoDef. Use this option to enable/disable the default mapping of CTRL-] and (`gd`) for
Disabling it allows you to map something else to `gd`. Default is enabled. > GoDef and CTRL-t for :GoDefPop. Disabling it allows you to map something else to
these keys or mappings. Default is enabled. >
let g:go_def_mapping_enabled = 1 let g:go_def_mapping_enabled = 1
< <
@ -980,7 +1041,13 @@ also enabled. By default it's enabled. >
let g:go_highlight_string_spellcheck = 1 let g:go_highlight_string_spellcheck = 1
< <
*'g:go_highlight_format_strings*
Use this option to highlight printf-style operators inside string literals.
By default it's enabled. >
let g:go_highlight_format_strings = 1
<
*'g:go_autodetect_gopath'* *'g:go_autodetect_gopath'*
Automatically modifies GOPATH for certain directory structures, such as for Automatically modifies GOPATH for certain directory structures, such as for

View file

@ -29,7 +29,9 @@ if get(g:, "go_doc_keywordprg_enabled", 1)
endif endif
if get(g:, "go_def_mapping_enabled", 1) if get(g:, "go_def_mapping_enabled", 1)
nnoremap <buffer> <silent> gd :GoDef<cr> nnoremap <buffer> <silent> gd :GoDef<cr>
nnoremap <buffer> <silent> <C-]> :GoDef<cr>
nnoremap <buffer> <silent> <C-t> :<C-U>call go#def#StackPop(v:count1)<cr>
endif endif
if get(g:, "go_textobj_enabled", 1) if get(g:, "go_textobj_enabled", 1)

View file

@ -26,13 +26,18 @@ command! -nargs=* -bang GoInstall call go#cmd#Install(<bang>0, <f-args>)
command! -nargs=* -bang GoTest call go#cmd#Test(<bang>0, 0, <f-args>) command! -nargs=* -bang GoTest call go#cmd#Test(<bang>0, 0, <f-args>)
command! -nargs=* -bang GoTestFunc call go#cmd#TestFunc(<bang>0, <f-args>) command! -nargs=* -bang GoTestFunc call go#cmd#TestFunc(<bang>0, <f-args>)
command! -nargs=* -bang GoTestCompile call go#cmd#Test(<bang>0, 1, <f-args>) command! -nargs=* -bang GoTestCompile call go#cmd#Test(<bang>0, 1, <f-args>)
command! -nargs=* -bang GoCoverage call go#cmd#Coverage(<bang>0, <f-args>)
" -- cover
command! -nargs=* -bang GoCoverage call go#coverage#Buffer(<bang>0, <f-args>)
command! -nargs=* -bang GoCoverageBrowser call go#coverage#Browser(<bang>0, <f-args>)
" -- play " -- play
command! -nargs=0 -range=% GoPlay call go#play#Share(<count>, <line1>, <line2>) command! -nargs=0 -range=% GoPlay call go#play#Share(<count>, <line1>, <line2>)
" -- def " -- def
command! -nargs=* -range GoDef :call go#def#Jump(<f-args>) command! -nargs=* -range GoDef :call go#def#Jump(<f-args>)
command! -nargs=? GoDefPop :call go#def#StackPop(<f-args>)
command! -nargs=? GoDefJump :call go#def#StackJump(<f-args>)
" -- doc " -- doc
command! -nargs=* -range -complete=customlist,go#package#Complete GoDoc call go#doc#Open('new', 'split', <f-args>) command! -nargs=* -range -complete=customlist,go#package#Complete GoDoc call go#doc#Open('new', 'split', <f-args>)

View file

@ -23,7 +23,9 @@ nnoremap <silent> <Plug>(go-install) :<C-u>call go#cmd#Install(!g:go_jump_to_err
nnoremap <silent> <Plug>(go-test) :<C-u>call go#cmd#Test(!g:go_jump_to_error, 0)<CR> nnoremap <silent> <Plug>(go-test) :<C-u>call go#cmd#Test(!g:go_jump_to_error, 0)<CR>
nnoremap <silent> <Plug>(go-test-func) :<C-u>call go#cmd#TestFunc(!g:go_jump_to_error)<CR> nnoremap <silent> <Plug>(go-test-func) :<C-u>call go#cmd#TestFunc(!g:go_jump_to_error)<CR>
nnoremap <silent> <Plug>(go-test-compile) :<C-u>call go#cmd#Test(!g:go_jump_to_error, 1)<CR> nnoremap <silent> <Plug>(go-test-compile) :<C-u>call go#cmd#Test(!g:go_jump_to_error, 1)<CR>
nnoremap <silent> <Plug>(go-coverage) :<C-u>call go#cmd#Coverage(!g:go_jump_to_error)<CR>
nnoremap <silent> <Plug>(go-coverage) :<C-u>call go#coverage#Buffer(!g:go_jump_to_error)<CR>
nnoremap <silent> <Plug>(go-coverage-browser) :<C-u>call go#coverage#Browser(!g:go_jump_to_error)<CR>
nnoremap <silent> <Plug>(go-files) :<C-u>call go#tool#Files()<CR> nnoremap <silent> <Plug>(go-files) :<C-u>call go#tool#Files()<CR>
nnoremap <silent> <Plug>(go-deps) :<C-u>call go#tool#Deps()<CR> nnoremap <silent> <Plug>(go-deps) :<C-u>call go#tool#Deps()<CR>

View file

@ -19,6 +19,7 @@ let s:packages = [
\ "github.com/jstemmer/gotags", \ "github.com/jstemmer/gotags",
\ "github.com/klauspost/asmfmt/cmd/asmfmt", \ "github.com/klauspost/asmfmt/cmd/asmfmt",
\ "github.com/fatih/motion", \ "github.com/fatih/motion",
\ "github.com/zmb3/gogetdoc",
\ ] \ ]
" These commands are available on any filetypes " These commands are available on any filetypes
@ -167,6 +168,10 @@ augroup vim-go
if get(g:, "go_metalinter_autosave", 0) if get(g:, "go_metalinter_autosave", 0)
autocmd BufWritePost *.go call go#lint#Gometa(1) autocmd BufWritePost *.go call go#lint#Gometa(1)
endif endif
" initialize window-local godef stack
au BufReadPre,WinEnter *.go if !exists('w:go_stack') | let w:go_stack = [] | endif
au BufReadPre,WinEnter *.go if !exists('w:go_stack_level') | let w:go_stack_level = 0 | endif
augroup END augroup END

View file

@ -27,6 +27,8 @@
" Highlights trailing white space. " Highlights trailing white space.
" - go_highlight_string_spellcheck " - go_highlight_string_spellcheck
" Specifies that strings should be spell checked " Specifies that strings should be spell checked
" - go_highlight_format_strings
" Highlights printf-style operators inside string literals.
" Quit when a (custom) syntax file was already loaded " Quit when a (custom) syntax file was already loaded
if exists("b:current_syntax") if exists("b:current_syntax")
@ -81,6 +83,10 @@ if !exists("g:go_highlight_string_spellcheck")
let g:go_highlight_string_spellcheck = 1 let g:go_highlight_string_spellcheck = 1
endif endif
if !exists("g:go_highlight_format_strings")
let g:go_highlight_format_strings = 1
endif
if !exists("g:go_highlight_generate_tags") if !exists("g:go_highlight_generate_tags")
let g:go_highlight_generate_tags = 0 let g:go_highlight_generate_tags = 0
endif endif
@ -173,11 +179,14 @@ else
syn region goString start=+"+ skip=+\\\\\|\\"+ end=+"+ contains=@goStringGroup syn region goString start=+"+ skip=+\\\\\|\\"+ end=+"+ contains=@goStringGroup
syn region goRawString start=+`+ end=+`+ syn region goRawString start=+`+ end=+`+
endif endif
syn match goFormatSpecifier /%[-#0 +]*\%(\*\|\d\+\)\=\%(\.\%(\*\|\d\+\)\)*[vTtbcdoqxXUeEfgGsp]/ contained containedin=goString
if g:go_highlight_format_strings != 0
syn match goFormatSpecifier /%[-#0 +]*\%(\*\|\d\+\)\=\%(\.\%(\*\|\d\+\)\)*[vTtbcdoqxXUeEfgGsp]/ contained containedin=goString
hi def link goFormatSpecifier goSpecialString
endif
hi def link goString String hi def link goString String
hi def link goRawString String hi def link goRawString String
hi def link goFormatSpecifier goSpecialString
" Characters; their contents " Characters; their contents
syn cluster goCharacterGroup contains=goEscapeOctal,goEscapeC,goEscapeX,goEscapeU,goEscapeBigU syn cluster goCharacterGroup contains=goEscapeOctal,goEscapeC,goEscapeX,goEscapeU,goEscapeBigU

View file

@ -0,0 +1,18 @@
if exists("b:current_syntax")
finish
endif
syn match godefStackComment '^".*'
syn match godefLinePrefix '^[>\s]\s' nextgroup=godefStackEntryNumber contains=godefStackCurrentPosition
syn match godefStackEntryNumber '\d\+' nextgroup=godefStackFilename skipwhite
syn match godefStackCurrentPosition '>' contained
syn match godefStackFilename '[^|]\+' contained nextgroup=godefStackEntryLocation
syn region godefStackEntryLocation oneline start='|' end='|' contained contains=godefStackEntryLocationNumber
syn match godefStackEntryLocationNumber '\d\+' contained display
let b:current_syntax = "godefstack"
hi def link godefStackComment Comment
hi def link godefStackCurrentPosition Special
hi def link godefStackFilename Directory
hi def link godefStackEntryLocationNumber LineNr

View file

@ -1,47 +0,0 @@
" 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.
if exists("b:current_syntax")
finish
endif
syn case match
syn match godocTitle "^\([A-Z][A-Z ]*\)$"
hi def link godocTitle Title
" Single Line Definitions
syn match godocMethodRec /\i\+\ze)/ contained
syn match godocMethodName /) \zs\i\+\ze(/ contained
syn match godocMethod /^func \((\i\+ [^)]*)\) \i\+(/ contains=godocMethodRec,godocMethodName
syn match godocFunction /^func \zs\i\+\ze(/
syn match godocType /^type \zs\i\+\ze.*/
syn match godocVar /^var \zs\i\+\ze.*/
syn match godocConst /^const \zs\i\+\ze.*/
hi def link godocMethodRec Type
hi def link godocType Type
hi def link godocMethodName Function
hi def link godocFunction Function
hi def link godocVar Identifier
hi def link godocConst Identifier
" Definition Blocks
syn region godocComment start="/\*" end="\*/" contained
syn region godocComment start="//" end="$" contained
syn match godocDefinition /^\s\+\i\+/ contained
syn region godocVarBlock start=/^var (/ end=/^)/ contains=godocComment,godocDefinition
syn region godocConstBlock start=/^const (/ end=/^)/ contains=godocComment,godocDefinition
syn region godocTypeBlock start=/^type \i\+ \(interface\|struct\) {/ end=/^}/ matchgroup=godocType contains=godocComment,godocType
hi def link godocComment Comment
hi def link godocDefinition Identifier
syn sync minlines=500
let b:current_syntax = "godoc"
" vim:ts=4 sts=2 sw=2:

View file

@ -0,0 +1,191 @@
" to execute, `rake test` on parent dir
describe 'go#coverage#Buffer'
before
new
let g:curdir = expand('<sfile>:p:h') . '/'
let g:srcpath = 't/fixtures/src/'
let g:sample = 'pkg1/sample.go'
let g:sampleabs = g:curdir . g:srcpath . 'pkg1/sample.go'
let g:samplecover = g:curdir . g:srcpath . 'pkg1/sample.out'
let g:go_gopath = g:curdir . 't/fixtures'
execute "badd " . g:srcpath . g:sample
execute "buffer " . bufnr("$")
end
after
execute "bprev"
execute "bdelete " . g:srcpath . g:sample
close!
end
it 'puts match to the list'
call go#coverage#Buffer(0)
Expect len(go#coverlay#matches()) == 5
call go#coverlay#Clearlay()
Expect len(go#coverlay#matches()) == 0
call go#coverage#Buffer(0)
Expect len(go#coverlay#matches()) == 5
call go#coverlay#Clearlay()
Expect len(go#coverlay#matches()) == 0
call go#coverage#Buffer(0)
Expect len(go#coverlay#matches()) == 5
call go#coverage#Buffer(0)
Expect len(go#coverlay#matches()) == 5
call go#coverlay#Clearlay()
Expect len(go#coverlay#matches()) == 0
end
end
describe 'go#coverage#Buffer fail'
before
new
let g:curdir = expand('<sfile>:p:h') . '/'
let g:srcpath = 't/fixtures/src/'
let g:sample = 'failtest/sample.go'
let g:sampletest = 'failtest/sample_test.go'
let g:sampleabs = g:curdir . g:srcpath . 'failtest/sample.go'
let g:go_gopath = g:curdir . 't/fixtures'
execute "badd " . g:srcpath . g:sample
execute "buffer " . bufnr("$")
end
after
execute "bprev"
execute "bdelete " . g:srcpath . g:sampletest
execute "bdelete " . g:srcpath . g:sample
end
it 'does nothing if test fail'
call go#coverage#Buffer(0)
Expect len(go#coverlay#matches()) == 0
Expect len(getqflist()) == 1
end
end
describe 'go#coverage#Buffer build fail'
before
new
let g:curdir = expand('<sfile>:p:h') . '/'
let g:srcpath = 't/fixtures/src/'
let g:sample = 'buildfail/sample.go'
let g:sampleabs = g:curdir . g:srcpath . 'buildfail/sample.go'
let g:go_gopath = g:curdir . 't/fixtures'
execute "badd " . g:srcpath . g:sample
execute "buffer " . bufnr("$")
end
after
execute "bprev"
execute "bdelete " . g:srcpath . g:sample
end
it 'does nothing if test fail'
call go#coverage#Buffer(0)
Expect len(go#coverlay#matches()) == 0
end
end
describe 'go#coverage#Buffer build test fail'
before
new
let g:curdir = expand('<sfile>:p:h') . '/'
let g:srcpath = 't/fixtures/src/'
let g:sample = 'buildtestfail/sample.go'
let g:sampleabs = g:curdir . g:srcpath . 'buildtestfail/sample.go'
let g:go_gopath = g:curdir . 't/fixtures'
execute "badd " . g:srcpath . g:sample
execute "buffer " . bufnr("$")
end
after
execute "bprev"
execute "bdelete " . g:srcpath . g:sample
end
it 'does nothing if test fail'
call go#coverage#Buffer(0)
Expect len(go#coverlay#matches()) == 0
end
end
describe 'go#coverlay#findbufnr'
before
new
let g:curdir = expand('<sfile>:p:h') . '/'
let g:srcpath = 't/fixtures/src/'
let g:sample = 'pkg1/sample.go'
let g:sample2 = 'pkg2/sample.go'
let g:sampleabs = g:curdir . g:srcpath . 'pkg1/sample.go'
let g:sampleabs2 = g:curdir . g:srcpath . 'pkg2/sample.go'
let g:go_gopath = g:curdir . 't/fixtures'
execute "badd " . g:srcpath . g:sample
execute "badd " . g:srcpath . g:sample2
end
after
execute "bdelete " . g:srcpath . g:sample2
execute "bdelete " . g:srcpath . g:sample
close!
end
it 'returns BUFNR if FILE is opened at BUFNR'
Expect go#coverlay#findbufnr('_' . g:sampleabs) == bufnr(g:sampleabs)
Expect go#coverlay#findbufnr(g:sample) == bufnr(g:sampleabs)
Expect go#coverlay#findbufnr('_' . g:sampleabs2) == bufnr(g:sampleabs2)
Expect go#coverlay#findbufnr(g:sample2) == bufnr(g:sampleabs2)
end
it 'returns -1 if FILE is not exists'
Expect go#coverlay#findbufnr('pkg1/NOTEXISTS.go') == -1
Expect go#coverlay#findbufnr('_' . g:curdir . g:srcpath . 'pkg1/NOTEXISTS.go') == -1
end
end
describe 'go#coverlay#isopenedon'
before
new
let g:curdir = expand('<sfile>:p:h') . '/'
let g:srcpath = 't/fixtures/src/'
let g:sample = 'pkg1/sample.go'
let g:sampleabs = g:curdir . g:srcpath . 'pkg1/sample.go'
let g:go_gopath = g:curdir . 't/fixtures'
execute "badd " . g:srcpath . g:sample
end
after
execute "bdelete " . g:srcpath . g:sample
close!
end
it 'returns 1 if FILE is opened at BUFNR'
Expect go#coverlay#isopenedon('_' . g:sampleabs, bufnr(g:sampleabs)) == 1
Expect go#coverlay#isopenedon(g:sample, bufnr(g:sampleabs)) == 1
end
it 'returns 0 if FILE is not opened at BUFNR'
Expect go#coverlay#isopenedon('_' . g:sampleabs, 42) == 0
Expect go#coverlay#isopenedon(g:sample, 42) == 0
end
it 'returns 0 if FILE is not exists'
Expect go#coverlay#isopenedon('_' . g:curdir . g:srcpath . 'pkg1/NOTEXISTS', bufnr(g:sampleabs)) == 0
Expect go#coverlay#isopenedon('pkg1/NOTEXISTS.go', bufnr(g:sampleabs)) == 0
end
end
describe 'go#coverlay#parsegocoverline'
it 'parses a go cover output line and returns as dict'
let d = {'file': 'f',"startline": "1", "startcol": "2", "endline": "3", "endcol": "4", "numstmt": "5", "cnt": "6"}
" file:startline.col,endline.col numstmt count
Expect go#coverlay#parsegocoverline("f:1.2,3.4 5 6") == d
end
end
describe 'go#coverlay#genmatch'
it 'generate mark pattern from cover data'
let d = {'file': 'f',"startline": "1", "startcol": "2", "endline": "3", "endcol": "4", "numstmt": "5", "cnt": "6"}
Expect go#coverlay#genmatch(d) == {'group': 'covered', "pattern": '\%>1l\_^\s\+\%<3l\|\%1l\_^\s\+\|\%3l\_^\s\+\(\}$\)\@!', "priority": 6}
let d = {'file': 'f',"startline": "1", "startcol": "2", "endline": "3", "endcol": "4", "numstmt": "5", "cnt": "0"}
Expect go#coverlay#genmatch(d) == {'group': 'uncover', "pattern": '\%>1l\_^\s\+\%<3l\|\%1l\_^\s\+\|\%3l\_^\s\+\(\}$\)\@!', "priority": 5}
end
end

View file

@ -0,0 +1,13 @@
// set gopath before
//go:generate go test --coverprofile=sample.out
// go1.5.3 example output:
// GOPATH=`pwd`/fixtures go test --coverprofile=log.out buildfail
// # buildfail
// /tmp/go-build264733986/buildfail/_test/_obj_test/sample.go:7: undefined: IT_SHOULD_BE_BUILD_FAILED
// /tmp/go-build264733986/buildfail/_test/_obj_test/sample.go:8: missing return at end of function
// FAIL buildfail [build failed]
package pkg
func Sample() int {
IT_SHOULD_BE_BUILD_FAILED
}

View file

@ -0,0 +1,7 @@
package pkg
import "testing"
func TestSample(t *testing.T) {
Sample()
}

View file

@ -0,0 +1,7 @@
// set gopath before
//go:generate go test --coverprofile=sample.out
package pkg
func Sample() int {
return 1
}

View file

@ -0,0 +1,15 @@
// go1.5.3 example output:
// GOPATH=`pwd`/fixtures go test --coverprofile=log.out buildtestfail
// # buildtestfail
// fixtures/src/buildtestfail/sample_test.go:14: undefined: IT_SHOULD_BE_BUILD_FAILED
// FAIL buildtestfail [build failed]
// echo $?
// 2
package pkg
import "testing"
func TestSample(t *testing.T) {
IT_SHOULD_BE_BUILD_FAILED
}

View file

@ -0,0 +1,12 @@
// set gopath before
//go:generate go test --coverprofile=sample.out
package pkg
func Sample() int {
if false {
return 0
} else if false {
return 0
}
return 1
}

View file

@ -0,0 +1,8 @@
package pkg
import "testing"
func TestSample(t *testing.T) {
Sample()
t.Fatal("itwillfail")
}

View file

@ -0,0 +1,14 @@
// set gopath before
//go:generate go test --coverprofile=sample.out
// go1.5.3 example output:
// GOPATH=`pwd`/fixtures go test --coverprofile=log.out parsefail
// # cover parsefail
// 2016/01/17 23:59:08 cover: /home/sey/vimfiles/_vim/bundle/vim-go-coverlay/t/fixtures/src/parsefail/sample.go: /home/sey/vimfiles/_vim/bundle/vim-go-coverlay/t/fixtures/src/parsefail/sample.go:10:1: expected declaration, found 'IDENT' PARSEFAIL
// FAIL parsefail [build failed]
// echo $?
// 2
package pkg
PARSEFAIL Sample() int {
return 0
}

View file

@ -0,0 +1,7 @@
package pkg
import "testing"
func TestSample(t *testing.T) {
Sample()
}

View file

@ -0,0 +1,12 @@
// set gopath before
//go:generate go test --coverprofile=sample.out
package pkg1
func Sample() int {
if false {
return 0
} else if false {
return 0
}
return 1
}

View file

@ -0,0 +1,6 @@
mode: set
pkg1/sample.go:5.19,6.11 1 1
pkg1/sample.go:11.2,11.10 1 1
pkg1/sample.go:6.11,8.3 1 0
pkg1/sample.go:8.3,8.18 1 1
pkg1/sample.go:8.18,10.3 1 0

View file

@ -0,0 +1,7 @@
package pkg1
import "testing"
func TestSample(t *testing.T) {
Sample()
}

View file

@ -886,7 +886,8 @@ function! s:process_user_input()
" Grr this is frustrating. In Insert mode, between the feedkey call and here, " Grr this is frustrating. In Insert mode, between the feedkey call and here,
" the current position could actually CHANGE for some odd reason. Forcing a " the current position could actually CHANGE for some odd reason. Forcing a
" position reset here " position reset here
call cursor(s:cm.get_current().position) let cursor_position = s:cm.get_current()
call cursor(cursor_position.position)
" Before applying the user input, we need to revert back to the mode the user " Before applying the user input, we need to revert back to the mode the user
" was in when the input was entered " was in when the input was entered
@ -894,13 +895,14 @@ function! s:process_user_input()
" Update the line length BEFORE applying any actions. TODO(terryma): Is there " Update the line length BEFORE applying any actions. TODO(terryma): Is there
" a better place to do this? " a better place to do this?
call s:cm.get_current().update_line_length() " let cursor_position = s:cm.get_current()
call cursor_position.update_line_length()
let s:saved_linecount = line('$') let s:saved_linecount = line('$')
" Restore unnamed register only in Normal mode. This should happen before user " Restore unnamed register only in Normal mode. This should happen before user
" input is processed. " input is processed.
if s:from_mode ==# 'n' || s:from_mode ==# 'v' || s:from_mode ==# 'V' if s:from_mode ==# 'n' || s:from_mode ==# 'v' || s:from_mode ==# 'V'
call s:cm.get_current().restore_unnamed_register() call cursor_position.restore_unnamed_register()
endif endif
" Apply the user input. Note that the above could potentially change mode, we " Apply the user input. Note that the above could potentially change mode, we

View file

@ -38,6 +38,7 @@ additional contributions from:
* [r00k](https://github.com/r00k) * [r00k](https://github.com/r00k)
* [radicalbit](https://github.com/radicalbit) * [radicalbit](https://github.com/radicalbit)
* [redpill](https://github.com/redpill) * [redpill](https://github.com/redpill)
* [rglassett](http://github.com/rglassett)
* [robhudson](https://github.com/robhudson) * [robhudson](https://github.com/robhudson)
* [Shraymonks](https://github.com/shraymonks) * [Shraymonks](https://github.com/shraymonks)
* [sickill](https://github.com/sickill) * [sickill](https://github.com/sickill)

View file

@ -61,7 +61,7 @@ function! snipmate#legacy#process_snippet(snip) abort
endw endw
if &et " Expand tabs to spaces if 'expandtab' is set. if &et " Expand tabs to spaces if 'expandtab' is set.
return substitute(snippet, '\t', repeat(' ', (&sts > 0) ? &sts : &sw), 'g') return substitute(snippet, '\t', repeat(' ', snipmate#util#tabwidth()), 'g')
endif endif
return snippet return snippet
endfunction endfunction

View file

@ -187,7 +187,7 @@ call extend(s:parser_proto, snipmate#util#add_methods(s:sfile(), 'parser',
function! s:indent(count) abort function! s:indent(count) abort
if &expandtab if &expandtab
let shift = repeat(' ', (&sts > 0) ? &sts : &sw) let shift = repeat(' ', snipmate#util#tabwidth())
else else
let shift = "\t" let shift = "\t"
endif endif

View file

@ -20,3 +20,11 @@ function! snipmate#util#eval(arg)
endtry endtry
return type(ret) == type('') ? ret : string(ret) return type(ret) == type('') ? ret : string(ret)
endfunction endfunction
function! snipmate#util#tabwidth()
if &sts > 0
return &sts
else
return exists('*shiftwidth') ? shiftwidth() : &sw
endif
endfunction

View file

@ -63,7 +63,7 @@ describe 'snippet parser'
Expect Parse(printf('${1:%s}', text)) == [[1] + expect] Expect Parse(printf('${1:%s}', text)) == [[1] + expect]
end end
it 'converts tabs according to &et, &sts, &sw' it 'converts tabs according to &et, &sts, &sw, &ts'
" &noet -> leave tabs alone " &noet -> leave tabs alone
setl noet setl noet
Expect Parse("abc\tdef\n\t\tghi") == ["abc\tdef", "\t\tghi"] Expect Parse("abc\tdef\n\t\tghi") == ["abc\tdef", "\t\tghi"]
@ -77,6 +77,12 @@ describe 'snippet parser'
setl et sts=-1 sw=3 setl et sts=-1 sw=3
Expect Parse("abc\tdef\n\t\tghi") == ["abc def", " ghi"] Expect Parse("abc\tdef\n\t\tghi") == ["abc def", " ghi"]
" See #227
if exists('*shiftwidth')
setl et sts=0 sw=0 ts=3
Expect Parse("abc\tdef\n\t\tghi") == ["abc def", " ghi"]
endif
end end
it 'parses backslashes as escaping the next character or joining lines' it 'parses backslashes as escaping the next character or joining lines'

View file

@ -54,4 +54,20 @@ snippet tp "template <typename ..> (template)"
template <typename ${1:_InputIter}> template <typename ${1:_InputIter}>
endsnippet endsnippet
snippet cla "An entire .h generator" b
#ifndef ${2:`!v substitute(vim_snippets#Filename('$1_H','ClassName'),'.*','\U&\E','')`}
#define $2
class ${1:`!v substitute(substitute(vim_snippets#Filename('$1','ClassName'),'^.','\u&',''), '_\(\w\)', '\u\1', 'g')`}
{
private:
${3}
public:
$1();
virtual ~$1();
};
#endif /* $2 */
endsnippet
# vim:ft=snippets: # vim:ft=snippets:

View file

@ -59,6 +59,7 @@ snippet eif "Else-If statement"
else if (${1}) { else if (${1}) {
${0} ${0}
} }
endsnippet
snippet el "Else statement" snippet el "Else statement"
else { else {