1
0
Fork 0
mirror of synced 2024-11-13 20:58:57 -05:00

merge to origin

This commit is contained in:
Tiande 2016-06-27 02:30:37 +08:00
parent 5ba4c775d9
commit 881ead4c17
113 changed files with 11333 additions and 3543 deletions

7
.gitignore vendored
View file

@ -1,7 +1,12 @@
temp_dirs/undodir* temp_dirs/undodir/*
sources_non_forked/ack.vim/.netrwhist sources_non_forked/ack.vim/.netrwhist
temp_dirs/yankring_history_v2.txt temp_dirs/yankring_history_v2.txt
sources_forked/yankring/doc/tags sources_forked/yankring/doc/tags
sources_non_forked/tlib/doc/tags sources_non_forked/tlib/doc/tags
<<<<<<< HEAD
=======
sources_non_forked/ctrlp.vim/doc/tags*
my_configs.vim
>>>>>>> 2644909e1e6273e4317a077ef289833e7500be53
tags tags
.DS_Store .DS_Store

View file

@ -148,42 +148,33 @@ Now you have vim-rails installed ;-)
### Plugin related mappings ### Plugin related mappings
Open [bufexplorer](https://github.com/vim-scripts/bufexplorer.zip) and see and manage the current buffers: Open [bufexplorer](https://github.com/vim-scripts/bufexplorer.zip) and see and manage the current buffers (`<leader>o`):
map <leader>o :BufExplorer<cr> map <leader>o :BufExplorer<cr>
Open [MRU.vim](https://github.com/vim-scripts/mru.vim) and see the recently open files: Open [MRU.vim](https://github.com/vim-scripts/mru.vim) and see the recently open files (`<leader>f`):
map <leader>f :MRU<CR> map <leader>f :MRU<CR>
Open [ctrlp.vim](https://github.com/kien/ctrlp.vim) plugin: Open [ctrlp.vim](https://github.com/kien/ctrlp.vim) plugin (`<leader>j` or `<ctrl>f`):
let g:ctrlp_map = '<c-f>' let g:ctrlp_map = '<c-f>'
Open [PeepOpen](http://topfunky.github.io/PeepOpen/) plugin:
map <leader>j :PeepOpen<cr>
Managing the [NERD Tree](https://github.com/scrooloose/nerdtree) plugin: Managing the [NERD Tree](https://github.com/scrooloose/nerdtree) plugin:
map <leader>nn :NERDTreeToggle<cr> map <leader>nn :NERDTreeToggle<cr>
map <leader>nb :NERDTreeFromBookmark map <leader>nb :NERDTreeFromBookmark
map <leader>nf :NERDTreeFind<cr> map <leader>nf :NERDTreeFind<cr>
[goyo.vim](https://github.com/junegunn/goyo.vim) and [vim-zenroom2](https://github.com/amix/vim-zenroom2) lets you only focus on one thing at a time. It removes all the distractions and centers the content. It has a special look when editing Markdown, reStructuredText and textfiles. It only has one mapping. [goyo.vim](https://github.com/junegunn/goyo.vim) and [vim-zenroom2](https://github.com/amix/vim-zenroom2) lets you only focus on one thing at a time. It removes all the distractions and centers the content. It has a special look when editing Markdown, reStructuredText and textfiles. It only has one mapping. (`<leader>z`)
map <leader>z :Goyo<cr> map <leader>z :Goyo<cr>
### Normal mode mappings ### Normal mode mappings
Fast saving of a buffer: Fast saving of a buffer (`<leader>w`):
nmap <leader>w :w!<cr> nmap <leader>w :w!<cr>
Treat long lines as break lines (useful when moving around in them):
map j gj
map k gk
Map `<Space>` to `/` (search) and `<Ctrl>+<Space>` to `?` (backwards search): Map `<Space>` to `/` (search) and `<Ctrl>+<Space>` to `?` (backwards search):
@ -195,14 +186,14 @@ Disable highlight when `<leader><cr>` is pressed:
map <silent> <leader><cr> :noh<cr> map <silent> <leader><cr> :noh<cr>
Smart way to move between windows: Smart way to move between windows (`<ctrl>j` etc.):
map <C-j> <C-W>j map <C-j> <C-W>j
map <C-k> <C-W>k map <C-k> <C-W>k
map <C-h> <C-W>h map <C-h> <C-W>h
map <C-l> <C-W>l map <C-l> <C-W>l
Closing of current buffer(s): Closing of current buffer(s) (`<leader>bd` and (`<leader>ba`)):
" Close current buffer " Close current buffer
map <leader>bd :Bclose<cr> map <leader>bd :Bclose<cr>
@ -339,18 +330,6 @@ Vimscript mappings:
map <leader>n :cn<cr> map <leader>n :cn<cr>
map <leader>p :cp<cr> map <leader>p :cp<cr>
## Useful blog tips regarding my Vim setup
* [Vim: Annotate strings with gettext (the macro way)](http://amix.dk/blog/post/19678#Vim-Annotate-strings-with-gettext-the-macro-way)
* [vimgrep: Searching through multiple file extensions](http://amix.dk/blog/post/19672#vimgrep-Searching-through-multiple-file-extensions)
* [Filtering through vimgrep results using regular expressions](http://amix.dk/blog/post/19666#Filtering-through-vimgrep-results-using-regular-expressions)
* [PeepOpen - File auto completion for Mac editors](http://amix.dk/blog/post/19601#PeepOpen-File-auto-completion-for-Mac-editors)
* [Vim 7.3: Persistent undo and encryption!](http://amix.dk/blog/post/19548#Vim-7-3-Persistent-undo-and-encryption)
* [Vim tips: Visual Search](http://amix.dk/blog/post/19334#Vim-tips-Visual-Search)
* [Folding in Vim](http://amix.dk/blog/post/19132#Folding-in-Vim)
* [
Zen room for Vim: Focusing only on the essential](http://amix.dk/blog/post/19744#zenroom-for-Vim-Focsuing-only-on-the-essential)
## How to uninstall ## How to uninstall
Do following: Do following:
* Remove `~/.vim_runtime` * Remove `~/.vim_runtime`

View file

@ -1,3 +1,7 @@
if exists('g:autoloaded_ack') || &cp
finish
endif
if exists('g:ack_use_dispatch') if exists('g:ack_use_dispatch')
if g:ack_use_dispatch && !exists(':Dispatch') if g:ack_use_dispatch && !exists(':Dispatch')
call s:Warn('Dispatch not loaded! Falling back to g:ack_use_dispatch = 0.') call s:Warn('Dispatch not loaded! Falling back to g:ack_use_dispatch = 0.')
@ -238,4 +242,5 @@ function! s:Warn(msg) "{{{
echohl WarningMsg | echomsg 'Ack: ' . a:msg | echohl None echohl WarningMsg | echomsg 'Ack: ' . a:msg | echohl None
endf "}}} endf "}}}
let g:autoloaded_ack = 1
" vim:set et sw=2 ts=2 tw=78 fdm=marker " vim:set et sw=2 ts=2 tw=78 fdm=marker

View file

@ -4,6 +4,10 @@
Author: Antoine Imbert <antoine.imbert+ackvim@gmail.com> *ack-author* Author: Antoine Imbert <antoine.imbert+ackvim@gmail.com> *ack-author*
License: Same terms as Vim itself (see |license|) License: Same terms as Vim itself (see |license|)
This plugin is only available if 'compatible' is not set.
{Vi does not have any of this}
============================================================================== ==============================================================================
INTRODUCTION *ack* INTRODUCTION *ack*
@ -16,7 +20,7 @@ shows the results in a split window.
Search recursively in {directory} (which defaults to the current Search recursively in {directory} (which defaults to the current
directory) for the {pattern}. Behaves just like the |:grep| command, but directory) for the {pattern}. Behaves just like the |:grep| command, but
will open the |Quickfix| window for you. If [!] is not given the first will open the |Quickfix| window for you. If [!] is not given the first
occurence is jumped to. occurrence is jumped to.
:AckAdd [options] {pattern} [{directory}] *:AckAdd* :AckAdd [options] {pattern} [{directory}] *:AckAdd*
@ -90,7 +94,6 @@ Example:
> >
let g:ackprg = "ag --vimgrep" let g:ackprg = "ag --vimgrep"
< <
*g:ack_default_options* *g:ack_default_options*
g:ack_default_options g:ack_default_options
Default: " -s -H --nocolor --nogroup --column" Default: " -s -H --nocolor --nogroup --column"
@ -107,18 +110,17 @@ Example:
let g:ack_default_options = let g:ack_default_options =
\ " -s -H --nocolor --nogroup --column --smart-case --follow" \ " -s -H --nocolor --nogroup --column --smart-case --follow"
< <
*g:ack_apply_qmappings* *g:ack_apply_qmappings*
g:ack_apply_qmappings g:ack_apply_qmappings
Default: 1 Default: 1
This option enable mappings on quickview window. This option enables mappings on the |quickfix| window.
*g:ack_apply_lmappings* *g:ack_apply_lmappings*
g:ack_apply_lmappings g:ack_apply_lmappings
Default: 1 Default: 1
This option enable mappings on Location list window. This option enables mappings on |location-list| windows.
*g:ack_mappings* *g:ack_mappings*
g:ack_mappings g:ack_mappings
@ -139,7 +141,6 @@ Example, if you want to open the result in the middle of the screen:
> >
let g:ack_mappings = { "o": "<CR>zz" } let g:ack_mappings = { "o": "<CR>zz" }
< <
*g:ack_qhandler* *g:ack_qhandler*
g:ack_qhandler g:ack_qhandler
Default: "botright copen" Default: "botright copen"
@ -150,7 +151,6 @@ If you want to open a quickview window with 30 lines you can do:
> >
let g:ack_qhandler = "botright copen 30" let g:ack_qhandler = "botright copen 30"
< <
*g:ack_lhandler* *g:ack_lhandler*
g:ack_lhandler g:ack_lhandler
Default: "botright lopen" Default: "botright lopen"
@ -161,9 +161,7 @@ If you want to open a Location list window with 30 lines you can do:
> >
let g:ack_lhandler = "botright lopen 30" let g:ack_lhandler = "botright lopen 30"
< <
*g:ackhighlight* *g:ackhighlight*
g:ackhighlight g:ackhighlight
Default: 0 Default: 0
@ -173,7 +171,6 @@ Example:
> >
let g:ackhighlight = 1 let g:ackhighlight = 1
< <
*g:ack_autoclose* *g:ack_autoclose*
g:ack_autoclose g:ack_autoclose
Default: 0 Default: 0
@ -185,9 +182,7 @@ Example:
> >
let g:ack_autoclose = 1 let g:ack_autoclose = 1
< <
*g:ack_autofold_results* *g:ack_autofold_results*
g:ack_autofold_results g:ack_autofold_results
Default: 0 Default: 0
@ -200,9 +195,7 @@ Example:
> >
let g:ack_autofold_results = 1 let g:ack_autofold_results = 1
< <
*g:ackpreview* *g:ackpreview*
g:ackpreview g:ackpreview
Default: 0 Default: 0
@ -212,9 +205,7 @@ Example:
> >
let g:ackpreview = 1 let g:ackpreview = 1
< <
*g:ack_use_dispatch* *g:ack_use_dispatch*
g:ack_use_dispatch g:ack_use_dispatch
Default: 0 Default: 0
@ -229,9 +220,7 @@ Example:
> >
let g:ack_use_dispatch = 1 let g:ack_use_dispatch = 1
< <
*g:ack_use_cword_for_empty_search* *g:ack_use_cword_for_empty_search*
g:ack_use_cword_for_empty_search g:ack_use_cword_for_empty_search
Default: 1 Default: 1
@ -239,34 +228,76 @@ Use this option to enable blank searches to run against the word under the
cursor. When this option is not set, blank searches will only output an error cursor. When this option is not set, blank searches will only output an error
message. message.
Example: Example:
> >
let g:ack_use_cword_for_empty_search = 0 let g:ack_use_cword_for_empty_search = 0
< <
============================================================================== ==============================================================================
MAPPINGS *ack-mappings* MAPPINGS *ack-mappings*
The following keyboard shortcuts are available in the quickfix window: The following keyboard shortcuts are available in the |quickfix| and
|location-list| windows:
o open file (same as enter). ? display a quick summary of these mappings.
O open file and close quickfix window. o open file (same as Enter).
O open file and close the quickfix window.
go preview file (open but maintain focus on ack.vim results). go preview file (open but maintain focus on ack.vim results).
t open in a new tab. t open in a new tab.
T open in new tab silently. T open in new tab without moving to it.
h open in horizontal split. h open in horizontal split.
H open in horizontal split silently. H open in horizontal split, keeping focus on the results.
v open in vertical split. v open in vertical split.
gv open in vertical split silently. gv open in vertical split, keeping focus on the results.
q close the quickfix window. q close the quickfix window.
To adjust these, see |g:ack_mappings|.
==============================================================================
Ignoring files *ack-ignore*
If you're using this plugin with ag, The Silver Searcher, bear in mind that:
- It ignores file patterns from your .gitignore and .hgignore.
- If there are other files in your source repository you don't wish to
search, you can add their patterns to an .agignore file.
==============================================================================
ISSUES AND FAQ *ack-issues-and-faq*
I use NERDTree and opening ack.vim results in a vertical split displaces it.~
You are probably using NERDTree with its default alignment at the left
side of the window. Set these custom mappings in your vimrc to work around
this:
>
let g:ack_mappings = {
\ 'v': '<C-W><CR><C-W>L<C-W>p<C-W>J<C-W>p',
\ 'gv': '<C-W><CR><C-W>L<C-W>p<C-W>J' }
<
This solution will be improved in the future.
Results show a mix of relative and absolute paths, making them hard to read.~
This is a quirk of Vim that can happen with plain |:vimgrep| too. You can
try this in your vimrc to work around it:
>
autocmd BufAdd * exe "cd" fnameescape(getcwd())
<
but for some users this may be disruptive to their Vim workflow. For more
details, see:
http://vi.stackexchange.com/a/4816/7174
https://github.com/mileszs/ack.vim/issues/143
vim:set et sw=4 ts=4 tw=78:

View file

@ -1,4 +1,4 @@
if exists('g:loaded_ack') if exists('g:loaded_ack') || &cp
finish finish
endif endif

View file

@ -1,5 +1,7 @@
# ag.vim # # ag.vim #
## Deprecated: See [this comment](https://github.com/rking/ag.vim/issues/124#issuecomment-227038003) for more info. Maybe try [ack.vim](https://github.com/mileszs/ack.vim#can-i-use-ag-the-silver-searcher-with-this) as an alternative. ##
This plugin is a front for ag, A.K.A. This plugin is a front for ag, A.K.A.
[the_silver_searcher](https://github.com/ggreer/the_silver_searcher). Ag can [the_silver_searcher](https://github.com/ggreer/the_silver_searcher). Ag can
be used as a replacement for 153% of the uses of `ack`. This plugin will allow be used as a replacement for 153% of the uses of `ack`. This plugin will allow

View file

@ -0,0 +1,7 @@
*.markdown
*.zip
note.txt
tags
tags-cn
.hg*
tmp/*

View file

@ -93,6 +93,7 @@ let [s:pref, s:bpref, s:opts, s:new_opts, s:lc_opts] =
\ 'open_single_match': ['s:opensingle', []], \ 'open_single_match': ['s:opensingle', []],
\ 'brief_prompt': ['s:brfprt', 0], \ 'brief_prompt': ['s:brfprt', 0],
\ 'match_current_file': ['s:matchcrfile', 0], \ 'match_current_file': ['s:matchcrfile', 0],
\ 'match_natural_name': ['s:matchnatural', 0],
\ 'compare_lim': ['s:compare_lim', 3000], \ 'compare_lim': ['s:compare_lim', 3000],
\ 'bufname_mod': ['s:bufname_mod', ':t'], \ 'bufname_mod': ['s:bufname_mod', ':t'],
\ 'bufpath_mod': ['s:bufpath_mod', ':~:.:h'], \ 'bufpath_mod': ['s:bufpath_mod', ':~:.:h'],
@ -315,11 +316,11 @@ fu! s:Open()
cal s:setupblank() cal s:setupblank()
endf endf
fu! s:Close() fu! s:Close(exit)
cal s:buffunc(0) cal s:buffunc(0)
if winnr('$') == 1 if winnr('$') == 1
bw! bw!
el elsei a:exit
try | bun! try | bun!
cat | clo! | endt cat | clo! | endt
cal s:unmarksigns() cal s:unmarksigns()
@ -425,7 +426,7 @@ fu! s:UserCmd(lscmd)
let do_ign = let do_ign =
\ type(s:usrcmd) == 4 && has_key(s:usrcmd, 'ignore') && s:usrcmd['ignore'] \ type(s:usrcmd) == 4 && has_key(s:usrcmd, 'ignore') && s:usrcmd['ignore']
if do_ign && ctrlp#igncwd(s:cwd) | retu | en if do_ign && ctrlp#igncwd(s:cwd) | retu | en
if exists('+ssl') && &ssl if exists('+ssl') && &ssl && &shell !~ 'sh'
let [ssl, &ssl, path] = [&ssl, 0, tr(path, '/', '\')] let [ssl, &ssl, path] = [&ssl, 0, tr(path, '/', '\')]
en en
if (has('win32') || has('win64')) && match(&shellcmdflag, "/") != -1 if (has('win32') || has('win64')) && match(&shellcmdflag, "/") != -1
@ -653,9 +654,9 @@ fu! s:Update(str)
endf endf
fu! s:ForceUpdate() fu! s:ForceUpdate()
let wv = winsaveview() let pos = exists('*getcurpos') ? getcurpos() : getpos('.')
sil! cal s:Update(escape(s:getinput(), '\')) sil! cal s:Update(escape(s:getinput(), '\'))
cal winrestview(wv) cal setpos('.', pos)
endf endf
fu! s:BuildPrompt(upd) fu! s:BuildPrompt(upd)
@ -839,9 +840,9 @@ fu! s:PrtSelectMove(dir)
let wht = winheight(0) let wht = winheight(0)
let dirs = {'t': 'gg','b': 'G','j': 'j','k': 'k','u': wht.'k','d': wht.'j'} let dirs = {'t': 'gg','b': 'G','j': 'j','k': 'k','u': wht.'k','d': wht.'j'}
exe 'keepj norm!' dirs[a:dir] exe 'keepj norm!' dirs[a:dir]
let wv = winsaveview() let pos = exists('*getcurpos') ? getcurpos() : getpos('.')
cal s:BuildPrompt(0) cal s:BuildPrompt(0)
cal winrestview(wv) cal setpos('.', pos)
endf endf
fu! s:PrtSelectJump(char) fu! s:PrtSelectJump(char)
@ -864,9 +865,9 @@ fu! s:PrtSelectJump(char)
let [jmpln, s:jmpchr] = [npos == -1 ? pos : npos, [chr, npos]] let [jmpln, s:jmpchr] = [npos == -1 ? pos : npos, [chr, npos]]
en en
exe 'keepj norm!' ( jmpln + 1 ).'G' exe 'keepj norm!' ( jmpln + 1 ).'G'
let wv = winsaveview() let pos = exists('*getcurpos') ? getcurpos() : getpos('.')
cal s:BuildPrompt(0) cal s:BuildPrompt(0)
cal winrestview(wv) cal setpos('.', pos)
en en
endf endf
" Misc {{{2 " Misc {{{2
@ -907,8 +908,9 @@ fu! s:PrtDeleteMRU()
endf endf
fu! s:PrtExit() fu! s:PrtExit()
exe bufwinnr(s:bufnr).'winc w'
if bufnr('%') == s:bufnr && bufname('%') == 'ControlP' if bufnr('%') == s:bufnr && bufname('%') == 'ControlP'
noa cal s:Close() noa cal s:Close(1)
noa winc p noa winc p
en en
endf endf
@ -1754,7 +1756,7 @@ fu! ctrlp#syntax()
en en
sy match CtrlPNoEntries '^ == NO ENTRIES ==$' sy match CtrlPNoEntries '^ == NO ENTRIES ==$'
if hlexists('CtrlPLinePre') if hlexists('CtrlPLinePre')
sy match CtrlPLinePre '^>' exe "sy match CtrlPLinePre '^".escape(get(g:, 'ctrlp_line_prefix', '>'),'^$.*~\')."'"
en en
if s:itemtype == 1 && s:has_conceal if s:itemtype == 1 && s:has_conceal
@ -1822,7 +1824,7 @@ fu! s:highlight(pat, grp)
" occurrence of our letters. We also ensure that our matcher is case " occurrence of our letters. We also ensure that our matcher is case
" insensitive or sensitive depending. " insensitive or sensitive depending.
cal matchadd(a:grp, beginning.middle.ending) cal matchadd(a:grp, beginning.middle.ending)
endfor endfo
en en
cal matchadd('CtrlPLinePre', '^>') cal matchadd('CtrlPLinePre', '^>')
@ -1941,7 +1943,7 @@ fu! s:isabs(path)
endf endf
fu! s:bufnrfilpath(line) fu! s:bufnrfilpath(line)
if s:isabs(a:line) || a:line =~ '^\~[/\\]' if s:isabs(a:line) || a:line =~ '^\~[/\\]' || a:line =~ '^\w\+:\/\/'
let filpath = a:line let filpath = a:line
el el
let filpath = s:dyncwd.s:lash().a:line let filpath = s:dyncwd.s:lash().a:line
@ -1956,9 +1958,10 @@ fu! s:bufnrfilpath(line)
endf endf
fu! ctrlp#normcmd(cmd, ...) fu! ctrlp#normcmd(cmd, ...)
let buftypes = [ 'quickfix', 'help' ]
if a:0 < 2 && s:nosplit() | retu a:cmd | en if a:0 < 2 && s:nosplit() | retu a:cmd | en
let norwins = filter(range(1, winnr('$')), let norwins = filter(range(1, winnr('$')),
\ 'empty(getbufvar(winbufnr(v:val), "&bt")) || s:isneovimterminal(winbufnr(v:val))') \ 'index(buftypes, getbufvar(winbufnr(v:val), "&bt")) == -1 || s:isneovimterminal(winbufnr(v:val))')
for each in norwins for each in norwins
let bufnr = winbufnr(each) let bufnr = winbufnr(each)
if empty(bufname(bufnr)) && empty(getbufvar(bufnr, '&ft')) if empty(bufname(bufnr)) && empty(getbufvar(bufnr, '&ft'))
@ -2345,9 +2348,16 @@ endf
fu! s:buildpat(lst) fu! s:buildpat(lst)
let pat = a:lst[0] let pat = a:lst[0]
for item in range(1, len(a:lst) - 1) if s:matchnatural == 1
let pat .= '[^'.a:lst[item - 1].']\{-}'.a:lst[item] for item in range(1, len(a:lst) - 1)
endfo let c = a:lst[item - 1]
let pat .= (c == '/' ? '[^/]\{-}' : '[^'.c.'/]\{-}').a:lst[item]
endfo
else
for item in range(1, len(a:lst) - 1)
let pat .= '[^'.a:lst[item - 1].']\{-}'.a:lst[item]
endfo
en
retu pat retu pat
endf endf
@ -2533,7 +2543,7 @@ if has('autocmd')
aug CtrlPAug aug CtrlPAug
au! au!
au BufEnter ControlP cal s:checkbuf() au BufEnter ControlP cal s:checkbuf()
au BufLeave ControlP noa cal s:Close() au BufLeave ControlP noa cal s:Close(0)
au VimLeavePre * cal s:leavepre() au VimLeavePre * cal s:leavepre()
aug END aug END
en en

View file

@ -520,8 +520,8 @@ Oops! We forgot the cool mark for the branch component! (work with the patched f
```vim ```vim
function! LightLineFugitive() function! LightLineFugitive()
if exists("*fugitive#head") if exists("*fugitive#head")
let _ = fugitive#head() let branch = fugitive#head()
return _ !=# '' ? '⭠ '._ : '' return branch !=# '' ? '⭠ '.branch : ''
endif endif
return '' return ''
endfunction endfunction
@ -596,8 +596,8 @@ endfunction
function! LightLineFugitive() function! LightLineFugitive()
if &ft !~? 'vimfiler\|gundo' && exists("*fugitive#head") if &ft !~? 'vimfiler\|gundo' && exists("*fugitive#head")
let _ = fugitive#head() let branch = fugitive#head()
return _ !=# '' ? '⭠ '._ : '' return branch !=# '' ? '⭠ '.branch : ''
endif endif
return '' return ''
endfunction endfunction
@ -691,8 +691,8 @@ function! LightLineFugitive()
try try
if expand('%:t') !~? 'Tagbar\|Gundo\|NERD' && &ft !~? 'vimfiler' && exists('*fugitive#head') if expand('%:t') !~? 'Tagbar\|Gundo\|NERD' && &ft !~? 'vimfiler' && exists('*fugitive#head')
let mark = '' " edit here for cool mark let mark = '' " edit here for cool mark
let _ = fugitive#head() let branch = fugitive#head()
return _ !=# '' ? mark._ : '' return branch !=# '' ? mark.branch : ''
endif endif
catch catch
endtry endtry

View file

@ -2,7 +2,7 @@
" Filename: autoload/lightline.vim " Filename: autoload/lightline.vim
" Author: itchyny " Author: itchyny
" License: MIT License " License: MIT License
" Last Change: 2016/05/14 13:20:45. " Last Change: 2016/06/12 22:40:00.
" ============================================================================= " =============================================================================
let s:save_cpo = &cpo let s:save_cpo = &cpo
@ -263,7 +263,7 @@ endif
function! lightline#highlight(...) abort function! lightline#highlight(...) abort
let [c, f] = [s:lightline.palette, s:lightline.mode_fallback] let [c, f] = [s:lightline.palette, s:lightline.mode_fallback]
let [s:lightline.llen, s:lightline.rlen] = [len(c.normal.left), len(c.normal.right)] let [s:lightline.llen, s:lightline.rlen] = [len(c.normal.left), len(c.normal.right)]
let [s:lightline.tab_llen, s:lightline.tab_rlen] = [len(has_key(get(c, 'tabline', {}), 'left') ? c.tabline.left : c.normal.left), len(has_key(get(c, 'tabline', {}), 'right') ? c.tabline.right : c.normal.right)] let [s:lightline.tab_llen, s:lightline.tab_rlen] = [len(has_key(get(c, 'tabline', {}), 'left') ? c.tabline.left : c.normal.left), len(has_key(get(c, 'tabline', {}), 'right') ? c.tabline.right : c.normal.right)]
let types = map(s:uniq(sort(filter(values(s:lightline.component_type), 'v:val !=# "raw"'))), '[v:val, 1]') let types = map(s:uniq(sort(filter(values(s:lightline.component_type), 'v:val !=# "raw"'))), '[v:val, 1]')
let modes = a:0 ? [a:1] : extend(['normal', 'insert', 'replace', 'visual', 'inactive', 'command', 'select', 'tabline'], has('nvim') ? ['terminal'] : []) let modes = a:0 ? [a:1] : extend(['normal', 'insert', 'replace', 'visual', 'inactive', 'command', 'select', 'tabline'], has('nvim') ? ['terminal'] : [])
for mode in modes for mode in modes
@ -276,7 +276,7 @@ function! lightline#highlight(...) abort
let rs = has_key(get(c, d, {}), 'right') ? c[d].right : has_key(f, d) && has_key(get(c, f[d], {}), 'right') ? c[f[d]].right : c.normal.right let rs = has_key(get(c, d, {}), 'right') ? c[d].right : has_key(f, d) && has_key(get(c, f[d], {}), 'right') ? c[f[d]].right : c.normal.right
for [p, l, zs] in [['Left', len(left), ls], ['Right', len(right), rs]] for [p, l, zs] in [['Left', len(left), ls], ['Right', len(right), rs]]
for [i, t] in map(range(0, l), '[v:val, 0]') + types for [i, t] in map(range(0, l), '[v:val, 0]') + types
if i != l if i < l || i < 1
let r = t ? (has_key(get(c, d, []), i) ? c[d][i][0] : has_key(get(c, 'tabline', {}), i) ? c.tabline[i][0] : get(c.normal, i, zs)[0]) : get(zs, i, ms) let r = t ? (has_key(get(c, d, []), i) ? c[d][i][0] : has_key(get(c, 'tabline', {}), i) ? c.tabline[i][0] : get(c.normal, i, zs)[0]) : get(zs, i, ms)
exec printf('hi LightLine%s_%s_%s guifg=%s guibg=%s ctermfg=%s ctermbg=%s %s', p, mode, i, r[0], r[1], r[2], r[3], s:term(r)) exec printf('hi LightLine%s_%s_%s guifg=%s guibg=%s ctermfg=%s ctermbg=%s %s', p, mode, i, r[0], r[1], r[2], r[3], s:term(r))
endif endif
@ -293,7 +293,7 @@ function! lightline#highlight(...) abort
endfunction endfunction
function! s:subseparator(components, subseparator, expanded) abort function! s:subseparator(components, subseparator, expanded) abort
let [a, c, f, v] = [ a:components, s:lightline.component, s:lightline.component_function, s:lightline.component_visible_condition ] let [a, c, f, v] = [ a:components, s:lightline.component, s:lightline.component_function, s:lightline.component_visible_condition ]
let xs = map(range(len(a:components)), 'a:expanded[v:val] ? "1" : let xs = map(range(len(a:components)), 'a:expanded[v:val] ? "1" :
\ has_key(f, a[v:val]) ? (exists("*".f[a[v:val]]) ? "" : "exists(\"*".f[a[v:val]]."\")&&").f[a[v:val]]."()!=#\"\"" : \ has_key(f, a[v:val]) ? (exists("*".f[a[v:val]]) ? "" : "exists(\"*".f[a[v:val]]."\")&&").f[a[v:val]]."()!=#\"\"" :
\ has_key(v, a[v:val]) ? "(" . v[a[v:val]] . ")" : has_key(c, a[v:val]) ? "1" : "0"') \ has_key(v, a[v:val]) ? "(" . v[a[v:val]] . ")" : has_key(c, a[v:val]) ? "1" : "0"')

View file

@ -4,7 +4,7 @@ Version: 0.0
Author: itchyny (https://github.com/itchyny) Author: itchyny (https://github.com/itchyny)
License: MIT License License: MIT License
Repository: https://github.com/itchyny/lightline.vim Repository: https://github.com/itchyny/lightline.vim
Last Change: 2016/05/08 13:56:19. Last Change: 2016/05/26 21:57:34.
CONTENTS *lightline-contents* CONTENTS *lightline-contents*
@ -175,14 +175,18 @@ OPTIONS *lightline-option*
|g:lightline.component_expand|. The types are used to specify |g:lightline.component_expand|. The types are used to specify
the color. Specifically, the type raw is used to specify a the color. Specifically, the type raw is used to specify a
component which should not be wrapped by item group: %(...%). component which should not be wrapped by item group: %(...%).
> The default value is: >
let g:lightline.component_type = { let g:lightline.component_type = {
\ 'tabs': 'tabsel', \ 'tabs': 'tabsel',
\ 'close': 'raw' } \ 'close': 'raw' }
< <
g:lightline.tab_component *g:lightline.tab_component* g:lightline.tab_component *g:lightline.tab_component*
A dictionary for components in one tab. A dictionary for components in one tab.
The default value is: >
let g:lightline.tab_component = {}
<
g:lightline.tab_component_function *g:lightline.tab_component_function* g:lightline.tab_component_function *g:lightline.tab_component_function*
Another dictionary for components in one tab. Another dictionary for components in one tab.
A function specified as a tab component takes one argument: A function specified as a tab component takes one argument:
@ -286,8 +290,8 @@ nice.
endfunction endfunction
function! LightLineFugitive() function! LightLineFugitive()
if exists('*fugitive#head') if exists('*fugitive#head')
let _ = fugitive#head() let branch = fugitive#head()
return _ !=# '' ? ''._ : '' return branch !=# '' ? ''.branch : ''
endif endif
return '' return ''
endfunction endfunction
@ -311,8 +315,8 @@ look nice.
endfunction endfunction
function! LightLineFugitive() function! LightLineFugitive()
if exists('*fugitive#head') if exists('*fugitive#head')
let _ = fugitive#head() let branch = fugitive#head()
return _ !=# '' ? '⭠ '._ : '' return branch !=# '' ? '⭠ '.branch : ''
endif endif
return '' return ''
endfunction endfunction
@ -337,7 +341,7 @@ Exposed functions for lightline.vim.
Returns the mode of the Vim using |g:lightline.mode_map|. Returns the mode of the Vim using |g:lightline.mode_map|.
lightline#init() *lightline#init()* lightline#init() *lightline#init()*
Initializes the variable |g:lightline|. Initializes the internal state from |g:lightline|.
lightline#colorscheme() *lightline#colorscheme()* lightline#colorscheme() *lightline#colorscheme()*
Initializes the colorscheme and the highlight groups. Initializes the colorscheme and the highlight groups.
@ -741,8 +745,8 @@ A nice example for |vim-powerline| font users:
endfunction endfunction
function! LightLineFugitive() function! LightLineFugitive()
if &ft !~? 'vimfiler' && exists('*fugitive#head') if &ft !~? 'vimfiler' && exists('*fugitive#head')
let _ = fugitive#head() let branch = fugitive#head()
return _ !=# '' ? '⭠ '._ : '' return branch !=# '' ? '⭠ '.branch : ''
endif endif
return '' return ''
endfunction endfunction
@ -802,8 +806,8 @@ For users who uses lots of plugins:
try try
if expand('%:t') !~? 'Tagbar\|Gundo\|NERD' && &ft !~? 'vimfiler' && exists('*fugitive#head') if expand('%:t') !~? 'Tagbar\|Gundo\|NERD' && &ft !~? 'vimfiler' && exists('*fugitive#head')
let mark = '' " edit here for cool mark let mark = '' " edit here for cool mark
let _ = fugitive#head() let branch = fugitive#head()
return _ !=# '' ? mark._ : '' return branch !=# '' ? mark.branch : ''
endif endif
catch catch
endtry endtry

View file

@ -3,9 +3,6 @@ let s:assert = themis#helper('assert')
function! s:suite.before_each() function! s:suite.before_each()
hi clear hi clear
let g:lightline = {}
call lightline#init()
call lightline#colorscheme()
endfunction endfunction
function! s:hi(name) function! s:hi(name)
@ -22,6 +19,9 @@ function! s:pattern(xs, ...) abort
endfunction endfunction
function! s:suite.highlight() function! s:suite.highlight()
let g:lightline = {}
call lightline#init()
call lightline#colorscheme()
let palette = lightline#palette() let palette = lightline#palette()
call s:assert.match(s:hi('LightLineLeft_normal_0'), s:pattern(palette.normal.left[0])) call s:assert.match(s:hi('LightLineLeft_normal_0'), s:pattern(palette.normal.left[0]))
call s:assert.match(s:hi('LightLineLeft_normal_1'), s:pattern(palette.normal.left[1])) call s:assert.match(s:hi('LightLineLeft_normal_1'), s:pattern(palette.normal.left[1]))
@ -34,6 +34,9 @@ function! s:suite.highlight()
endfunction endfunction
function! s:suite.insert() function! s:suite.insert()
let g:lightline = {}
call lightline#init()
call lightline#colorscheme()
call lightline#highlight('insert') call lightline#highlight('insert')
let palette = lightline#palette() let palette = lightline#palette()
call s:assert.match(s:hi('LightLineLeft_insert_0'), s:pattern(palette.insert.left[0])) call s:assert.match(s:hi('LightLineLeft_insert_0'), s:pattern(palette.insert.left[0]))
@ -48,6 +51,9 @@ endfunction
function! s:suite.visual() function! s:suite.visual()
let g:lightline = {}
call lightline#init()
call lightline#colorscheme()
call lightline#highlight('visual') call lightline#highlight('visual')
let palette = lightline#palette() let palette = lightline#palette()
call s:assert.match(s:hi('LightLineLeft_visual_0'), s:pattern(palette.visual.left[0])) call s:assert.match(s:hi('LightLineLeft_visual_0'), s:pattern(palette.visual.left[0]))
@ -61,6 +67,9 @@ function! s:suite.visual()
endfunction endfunction
function! s:suite.replace() function! s:suite.replace()
let g:lightline = {}
call lightline#init()
call lightline#colorscheme()
call lightline#highlight('replace') call lightline#highlight('replace')
let palette = lightline#palette() let palette = lightline#palette()
call s:assert.match(s:hi('LightLineLeft_replace_0'), s:pattern(palette.replace.left[0])) call s:assert.match(s:hi('LightLineLeft_replace_0'), s:pattern(palette.replace.left[0]))
@ -97,6 +106,27 @@ function! s:suite.left_right()
call s:assert.match(s:hi('LightLineMiddle_normal'), s:pattern(palette.normal.middle[0])) call s:assert.match(s:hi('LightLineMiddle_normal'), s:pattern(palette.normal.middle[0]))
endfunction endfunction
function! s:suite.no_components()
let g:lightline = {
\ 'active': {
\ 'left': [],
\ 'right': []
\ },
\ 'inactive': {
\ 'left': [],
\ 'right': []
\ },
\ }
call lightline#init()
call lightline#colorscheme()
let palette = lightline#palette()
call s:assert.match(s:hi('LightLineLeft_normal_0'), s:pattern(palette.normal.left[0]))
call s:assert.match(s:hi('LightLineLeft_normal_1'), 'E411: highlight group not found\|cleared')
call s:assert.match(s:hi('LightLineRight_normal_0'), s:pattern(palette.normal.right[0]))
call s:assert.match(s:hi('LightLineRight_normal_1'), 'E411: highlight group not found\|cleared')
call s:assert.match(s:hi('LightLineMiddle_normal'), s:pattern(palette.normal.middle[0]))
endfunction
function! s:suite.subseparator() function! s:suite.subseparator()
let g:lightline = { let g:lightline = {
\ 'active': { \ 'active': {

View file

@ -187,17 +187,17 @@ endfunction
" closes the parent dir of the current node " closes the parent dir of the current node
function! s:closeCurrentDir(node) function! s:closeCurrentDir(node)
let parent = a:node.parent let parent = a:node.parent
while g:NERDTreeCascadeOpenSingleChildDir && !parent.isRoot()
let childNodes = parent.getVisibleChildren()
if len(childNodes) == 1 && childNodes[0].path.isDirectory
let parent = parent.parent
else
break
endif
endwhile
if parent ==# {} || parent.isRoot() if parent ==# {} || parent.isRoot()
call nerdtree#echo("cannot close tree root") call nerdtree#echo("cannot close tree root")
else else
while g:NERDTreeCascadeOpenSingleChildDir && !parent.parent.isRoot()
if parent.parent.getVisibleChildCount() == 1
call parent.close()
let parent = parent.parent
else
break
endif
endwhile
call parent.close() call parent.close()
call b:NERDTree.render() call b:NERDTree.render()
call parent.putCursorHere(0, 0) call parent.putCursorHere(0, 0)
@ -280,7 +280,7 @@ function! s:findAndRevealPath()
else else
call g:NERDTree.CursorToTreeWin() call g:NERDTree.CursorToTreeWin()
endif endif
call b:NERDTree.setShowHidden(g:NERDTreeShowHidden) call b:NERDTree.ui.setShowHidden(g:NERDTreeShowHidden)
call s:chRoot(g:NERDTreeDirNode.New(p.getParent(), b:NERDTree)) call s:chRoot(g:NERDTreeDirNode.New(p.getParent(), b:NERDTree))
else else
if !g:NERDTree.IsOpen() if !g:NERDTree.IsOpen()

View file

@ -11,7 +11,7 @@
## 1. Bug reports / GitHub issues ## 1. Bug reports / GitHub issues
Please note that the preferred channel for posting bug reports is the Please note that the preferred channel for posting bug reports is the
[issue tracker at GitHub][0]. Reports posted elsewhere are less likely [issue tracker at GitHub][bug_tracker]. Reports posted elsewhere are less likely
to be seen by the core team. to be seen by the core team.
When reporting a bug make sure you search the existing GitHub issues When reporting a bug make sure you search the existing GitHub issues
@ -39,14 +39,14 @@ too:
## 2. Submitting a patch ## 2. Submitting a patch
Before you consider adding features to syntastic, _please_ spend a few minutes Before you consider adding features to syntastic, _please_ spend a few minutes
(re-)reading the latest version of the [manual][1]. Syntastic is changing (re-)reading the latest version of the [manual][manual]. Syntastic is changing
rapidly at times, and it's possible that some features you want to add exist rapidly at times, and it's possible that some features you want to add exist
already. already.
To submit a patch: To submit a patch:
* fork the [repo][2] on GitHub; * fork the [repo][github] on GitHub;
* make a [topic branch][3] and start hacking; * make a [topic branch][branches] and start hacking;
* submit a pull request based off your topic branch. * submit a pull request based off your topic branch.
Small, focused patches are preferred. Small, focused patches are preferred.
@ -69,14 +69,14 @@ Follow the coding conventions/styles used in the syntastic core:
* don't use `l:` prefixes for variables unless actually required (i.e. * don't use `l:` prefixes for variables unless actually required (i.e.
almost never); almost never);
* code for maintainability; we would rather a function be a couple of * code for maintainability; we would rather a function be a couple of
lines longer and have (for example) some [explaining variables][4] to lines longer and have (for example) some [explaining variables][variables] to
aid readability. aid readability.
<a name="checkerstyle"></a> <a name="checkerstyle"></a>
## 4. Syntax checker notes ## 4. Syntax checker notes
Make sure to read the [guide][5] if you plan to add new syntax checkers. Make sure to read the [guide][guide] if you plan to add new syntax checkers.
Use the existing checkers as templates, rather than writing everything Use the existing checkers as templates, rather than writing everything
from scratch. from scratch.
@ -97,9 +97,9 @@ let errorformat =
\ '%-G%.%#' \ '%-G%.%#'
``` ```
[0]: https://github.com/scrooloose/syntastic/issues [bug_tracker]: https://github.com/scrooloose/syntastic/issues
[1]: https://github.com/scrooloose/syntastic/blob/master/doc/syntastic.txt [manual]: https://github.com/scrooloose/syntastic/blob/master/doc/syntastic.txt
[2]: https://github.com/scrooloose/syntastic [github]: https://github.com/scrooloose/syntastic
[3]: https://github.com/dchelimsky/rspec/wiki/Topic-Branches#using-topic-branches-when-contributing-patches [branches]: https://github.com/dchelimsky/rspec/wiki/Topic-Branches#using-topic-branches-when-contributing-patches
[4]: http://www.refactoring.com/catalog/extractVariable.html [variables]: http://www.refactoring.com/catalog/extractVariable.html
[5]: https://github.com/scrooloose/syntastic/wiki/Syntax-Checker-Guide [guide]: https://github.com/scrooloose/syntastic/wiki/Syntax-Checker-Guide

View file

@ -46,37 +46,38 @@
## 1\. Introduction ## 1\. Introduction
Syntastic is a syntax checking plugin for [Vim][13] that runs files through Syntastic is a syntax checking plugin for [Vim][vim] that runs files through
external syntax checkers and displays any resulting errors to the user. This external syntax checkers and displays any resulting errors to the user. This
can be done on demand, or automatically as files are saved. If syntax errors can be done on demand, or automatically as files are saved. If syntax errors
are detected, the user is notified and is happy because they didn't have to are detected, the user is notified and is happy because they didn't have to
compile their code or execute their script to find them. compile their code or execute their script to find them.
At the time of this writing, syntastic has checking plugins for ActionScript, At the time of this writing, syntastic has checking plugins for ActionScript,
Ada, Ansible configurations, API Blueprint, AppleScript, AsciiDoc, ASM, Ada, Ansible configurations, API Blueprint, AppleScript, AsciiDoc, Assembly
BEMHTML, Bro, Bourne shell, C, C++, C#, Cabal, Chef, CoffeeScript, Coco, languages, BEMHTML, Bro, Bourne shell, C, C++, C#, Cabal, Chef, CoffeeScript,
Coq, CSS, Cucumber, CUDA, D, Dart, DocBook, Dockerfile, Dust, Elixir, Coco, Coq, CSS, Cucumber, CUDA, D, Dart, DocBook, Dockerfile, Dust, Elixir,
Erlang, eRuby, Fortran, Gentoo metadata, GLSL, Go, Haml, Haskell, Haxe, Erlang, eRuby, Fortran, Gentoo metadata, GLSL, Go, Haml, Haskell, Haxe,
Handlebars, HSS, HTML, Java, JavaScript, JSON, JSX, LESS, Lex, Limbo, LISP, Handlebars, HSS, HTML, Java, JavaScript, JSON, JSX, LESS, Lex, Limbo, LISP,
LLVM intermediate language, Lua, Markdown, MATLAB, Mercury, NASM, Nix, LLVM intermediate language, Lua, Markdown, MATLAB, Mercury, NASM, Nix,
Objective-C, Objective-C++, OCaml, Perl, Perl POD, PHP, gettext Portable Objective-C, Objective-C++, OCaml, Perl, Perl POD, PHP, gettext Portable
Object, OS X and iOS property lists, Pug (formerly Jade), Puppet, Python, QML, Object, OS X and iOS property lists, Pug (formerly Jade), Puppet, Python,
R, Racket, RDF TriG, RDF Turtle, Relax NG, reStructuredText, RPM spec, Ruby, QML, R, Racket, RDF TriG, RDF Turtle, Relax NG, reStructuredText, RPM spec,
SASS/SCSS, Scala, Slim, SML, Sphinx, SQL, Stylus, Tcl, TeX, Texinfo, Twig, Ruby, SASS/SCSS, Scala, Slim, SML, Sphinx, SQL, Stylus, Tcl, TeX, Texinfo,
TypeScript, Vala, Verilog, VHDL, VimL, xHtml, XML, XSLT, XQuery, YACC, YAML, Twig, TypeScript, Vala, Verilog, VHDL, VimL, xHtml, XML, XSLT, XQuery,
YANG data models, z80, Zope page templates, and zsh. See the [wiki][3] for YACC, YAML, YANG data models, z80, Zope page templates, and Zsh. See the
details about the corresponding supported checkers. [manual][checkers] for details about the corresponding supported checkers
(`:help syntastic-checkers` in Vim).
A number of third-party Vim plugins also provide checkers for syntastic, A number of third-party Vim plugins also provide checkers for syntastic,
for example: [merlin][30], [omnisharp-vim][25], [rust.vim][12], for example: [merlin][merlin], [omnisharp-vim][omnisharp], [rust.vim][rust],
[syntastic-extras][26], [syntastic-more][27], [vim-crystal][29], [syntastic-extras][myint], [syntastic-more][roktas], [vim-crystal][crystal],
[vim-eastwood][28], and [vim-swift][24]. [vim-eastwood][eastwood], and [vim-swift][swift].
Below is a screenshot showing the methods that Syntastic uses to display syntax Below is a screenshot showing the methods that Syntastic uses to display syntax
errors. Note that, in practise, you will only have a subset of these methods errors. Note that, in practise, you will only have a subset of these methods
enabled. enabled.
![Screenshot 1][0] ![Screenshot 1][screenshot]
1. Errors are loaded into the location list for the corresponding window. 1. Errors are loaded into the location list for the corresponding window.
2. When the cursor is on a line containing an error, the error message is echoed in the command window. 2. When the cursor is on a line containing an error, the error message is echoed in the command window.
@ -94,7 +95,7 @@ enabled.
### 2.1\. Requirements ### 2.1\. Requirements
Syntastic itself has rather relaxed requirements: it doesn't have any external Syntastic itself has rather relaxed requirements: it doesn't have any external
dependencies, and it needs a version of [Vim][13] compiled with a few common dependencies, and it needs a version of [Vim][vim] compiled with a few common
features: `autocmd`, `eval`, `file_in_path`, `modify_fname`, `quickfix`, features: `autocmd`, `eval`, `file_in_path`, `modify_fname`, `quickfix`,
`reltime`, and `user_commands`. Not all possible combinations of features that `reltime`, and `user_commands`. Not all possible combinations of features that
include the ones above make equal sense on all operating systems, but Vim include the ones above make equal sense on all operating systems, but Vim
@ -102,8 +103,8 @@ version 7 or later with the "normal", "big", or "huge" feature sets should be
fine. fine.
Syntastic should work with any modern plugin managers for Vim, such as Syntastic should work with any modern plugin managers for Vim, such as
[NeoBundle][14], [Pathogen][1], [Vim-Addon-Manager][15], [Vim-Plug][16], or [NeoBundle][neobundle], [Pathogen][pathogen], [Vim-Addon-Manager][vam], [Vim-Plug][plug], or
[Vundle][17]. Instructions for installing syntastic with [Pathogen][1] are [Vundle][vundle]. Instructions for installing syntastic with [Pathogen][pathogen] are
included below for completeness. included below for completeness.
Starting with Vim version 7.4.1486 you can also load syntastic using the Starting with Vim version 7.4.1486 you can also load syntastic using the
@ -115,20 +116,21 @@ syntastic is present only in versions 7.4.1486 and later.
Last but not least: syntastic doesn't know how to do any syntax checks by Last but not least: syntastic doesn't know how to do any syntax checks by
itself. In order to get meaningful results you need to install external itself. In order to get meaningful results you need to install external
checkers corresponding to the types of files you use. Please consult the checkers corresponding to the types of files you use. Please consult the
[wiki][3] for a list of supported checkers. [manual][checkers] (`:help syntastic-checkers` in Vim) for a list of supported
checkers.
<a name="installpathogen"></a> <a name="installpathogen"></a>
### 2.2\. Installing syntastic with Pathogen ### 2.2\. Installing syntastic with Pathogen
If you already have [Pathogen][1] working then skip [Step 1](#step1) and go to If you already have [Pathogen][pathogen] working then skip [Step 1](#step1) and go to
[Step 2](#step2). [Step 2](#step2).
<a name="step1"></a> <a name="step1"></a>
#### 2.2.1\. Step 1: Install pathogen.vim #### 2.2.1\. Step 1: Install pathogen.vim
First I'll show you how to install Tim Pope's [Pathogen][1] so that it's easy to First I'll show you how to install Tim Pope's [Pathogen][pathogen] so that it's easy to
install syntastic. Do this in your terminal so that you get the `pathogen.vim` install syntastic. Do this in your terminal so that you get the `pathogen.vim`
file and the directories it needs: file and the directories it needs:
```sh ```sh
@ -155,7 +157,7 @@ Quit vim and start it back up to reload it, then type:
:Helptags :Helptags
``` ```
If you get an error when you do this, then you probably didn't install If you get an error when you do this, then you probably didn't install
[Pathogen][1] right. Go back to [Step 1](#step1) and make sure you did the [Pathogen][pathogen] right. Go back to [Step 1](#step1) and make sure you did the
following: following:
1. Created both the `~/.vim/autoload` and `~/.vim/bundle` directories. 1. Created both the `~/.vim/autoload` and `~/.vim/bundle` directories.
@ -192,10 +194,11 @@ __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
are 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`. Read the [manual][checkers]
supported, look at the [wiki][3]. Note that aliases do not work; the actual (`:help syntastic-checkers` in Vim) to find out what executables are
executables must be available in your `$PATH`. Symbolic links are okay though. supported. Note that aliases do not work; the actual executables must be
You can see syntastic's idea of available checkers by running `:SyntasticInfo`. available in your `$PATH`. Symbolic links are okay though. You can see
syntastic's idea of available checkers by running `:SyntasticInfo`.
A second probable reason is that none of the available checkers are A second probable reason is that none of the available checkers are
enabled. Syntastic comes preconfigured with a default list of enabled checkers enabled. Syntastic comes preconfigured with a default list of enabled checkers
@ -222,7 +225,7 @@ on Windows.
Finally, another reason it could fail is that either the command line options Finally, another reason it could fail is that either the command line options
or the error output for a syntax checker may have changed. In this case, make or the error output for a syntax checker may have changed. In this case, make
sure you have the latest version of the syntax checker installed. If it still sure you have the latest version of the syntax checker installed. If it still
fails then post an [issue][4] - or better yet, create a pull request. fails then post an [issue][bug_tracker] - or better yet, create a pull request.
<a name="faqpython3"></a> <a name="faqpython3"></a>
@ -238,18 +241,18 @@ let g:syntastic_python_python_exec = '/path/to/python3'
__4.3. Q. Are there any local checkers for HTML5 that I can use with syntastic?__ __4.3. Q. Are there any local checkers for HTML5 that I can use with syntastic?__
[HTML Tidy][18] has a fork named [HTML Tidy for HTML5][19]. It's a drop [HTML Tidy][tidy_old] has a fork named [HTML Tidy for HTML5][tidy]. It's a drop
in replacement, and syntastic can use it without changes. Just install it in replacement, and syntastic can use it without changes. Just install it
somewhere and point `g:syntastic_html_tidy_exec` to its executable: somewhere and point `g:syntastic_html_tidy_exec` to its executable:
```vim ```vim
let g:syntastic_html_tidy_exec = 'tidy5' let g:syntastic_html_tidy_exec = 'tidy5'
``` ```
Alternatively, you can install [vnu.jar][21] from the [validator.nu][20] Alternatively, you can install [vnu.jar][vnu_jar] from the [validator.nu][vnu]
project and run it as a [HTTP server][23]: project and run it as a [HTTP server][vnu_server]:
```sh ```sh
$ java -Xss512k -cp /path/to/vnu.jar nu.validator.servlet.Main 8888 $ java -Xss512k -cp /path/to/vnu.jar nu.validator.servlet.Main 8888
``` ```
Then you can [configure][22] syntastic to use it: Then you can configure syntastic to use it:
```vim ```vim
let g:syntastic_html_validator_api = 'http://localhost:8888/' let g:syntastic_html_validator_api = 'http://localhost:8888/'
``` ```
@ -260,7 +263,7 @@ __4.4. Q. The `perl` checker has stopped working...__
A. The `perl` checker runs `perl -c` against your file, which in turn A. The `perl` checker runs `perl -c` against your file, which in turn
__executes__ any `BEGIN`, `UNITCHECK`, and `CHECK` blocks, and any `use` __executes__ any `BEGIN`, `UNITCHECK`, and `CHECK` blocks, and any `use`
statements in your file (cf. [perlrun][10]). This is probably fine if you statements in your file (cf. [perlrun][perlrun]). This is probably fine if you
wrote the file yourself, but it's a security problem if you're checking wrote the file yourself, but it's a security problem if you're checking
third-party files. Since there is currently no way to disable this behaviour third-party files. Since there is currently no way to disable this behaviour
while still producing useful results, the checker is now disabled by default. while still producing useful results, the checker is now disabled by default.
@ -274,7 +277,7 @@ let g:syntastic_enable_perl_checker = 1
__4.5. Q. What happened to the `rustc` checker?__ __4.5. Q. What happened to the `rustc` checker?__
A. It is now part of the [rust.vim][12] plugin. If you install this plugin the A. It is now part of the [rust.vim][rust] plugin. If you install this plugin the
checker should be picked up automatically by syntastic. checker should be picked up automatically by syntastic.
<a name="faqxcrun"></a> <a name="faqxcrun"></a>
@ -282,7 +285,7 @@ checker should be picked up automatically by syntastic.
__4.6. Q. What happened to the `xcrun` checker?__ __4.6. Q. What happened to the `xcrun` checker?__
A. The `xcrun` checker used to have a security problem and it has been removed. A. The `xcrun` checker used to have a security problem and it has been removed.
A better checker for __Swift__ is part of the [vim-swift][24] plugin. If you A better checker for __Swift__ is part of the [vim-swift][swift] plugin. If you
install this plugin the checker should be picked up automatically by syntastic. install this plugin the checker should be picked up automatically by syntastic.
<a name="faqloclist"></a> <a name="faqloclist"></a>
@ -324,8 +327,8 @@ A. Stick a line like this in your `vimrc`:
let g:syntastic_<filetype>_checkers = ['<checker-name>'] let g:syntastic_<filetype>_checkers = ['<checker-name>']
``` ```
To see the list of supported checkers for your filetype look at the To see the list of supported checkers for your filetype read the
[wiki][3]. [manual][checkers] (`:help syntastic-checkers` in Vim).
e.g. Python has the following checkers, among others: `flake8`, `pyflakes`, e.g. Python has the following checkers, among others: `flake8`, `pyflakes`,
`pylint` and a native `python` checker. `pylint` and a native `python` checker.
@ -406,7 +409,7 @@ A. Vim provides several built-in commands for this. See `:help :lnext` and
`:help :lprevious`. `:help :lprevious`.
If you use these commands a lot then you may want to add shortcut mappings to If you use these commands a lot then you may want to add shortcut mappings to
your `vimrc`, or install something like [unimpaired][2], which provides such your `vimrc`, or install something like [unimpaired][unimpaired], which provides such
mappings (among other things). mappings (among other things).
<a name="faqbdelete"></a> <a name="faqbdelete"></a>
@ -427,50 +430,50 @@ cabbrev <silent> bd <C-r>=(getcmdtype()==#':' && getcmdpos()==1 ? 'lclose\|bdele
## 5\. Resources ## 5\. Resources
The preferred place for posting suggestions, reporting bugs, and general The preferred place for posting suggestions, reporting bugs, and general
discussions related to syntastic is the [issue tracker at GitHub][4]. discussions related to syntastic is the [issue tracker at GitHub][bug_tracker].
A guide for writing syntax checkers can be found in the [wiki][11]. A guide for writing syntax checkers can be found in the [wiki][guide].
There are also a dedicated [google group][5], and a There are also a dedicated [google group][google_group], and a
[syntastic tag at StackOverflow][6]. [syntastic tag at StackOverflow][stack_overflow].
Syntastic aims to provide a common interface to syntax checkers for as many Syntastic aims to provide a common interface to syntax checkers for as many
languages as possible. For particular languages, there are, of course, other languages as possible. For particular languages, there are, of course, other
plugins that provide more functionality than syntastic. You might want to take plugins that provide more functionality than syntastic. You might want to take
a look at [ghcmod-vim][31], [jedi-vim][7], [python-mode][8], [vim-go][32], or a look at [ghcmod-vim][ghcmod], [jedi-vim][jedi], [python-mode][python_mode], [vim-go][vimgo], or
[YouCompleteMe][9]. [YouCompleteMe][ycm].
[0]: https://github.com/scrooloose/syntastic/raw/master/_assets/screenshot_1.png [screenshot]: https://github.com/scrooloose/syntastic/raw/master/_assets/screenshot_1.png
[1]: https://github.com/tpope/vim-pathogen
[2]: https://github.com/tpope/vim-unimpaired [bug_tracker]: https://github.com/scrooloose/syntastic/issues
[3]: https://github.com/scrooloose/syntastic/wiki/Syntax-Checkers [checkers]: https://github.com/scrooloose/syntastic/blob/master/doc/syntastic-checkers.txt
[4]: https://github.com/scrooloose/syntastic/issues [crystal]: https://github.com/rhysd/vim-crystal
[5]: https://groups.google.com/group/vim-syntastic [eastwood]: https://github.com/venantius/vim-eastwood
[6]: http://stackoverflow.com/questions/tagged/syntastic [ghcmod]: https://github.com/eagletmt/ghcmod-vim
[7]: https://github.com/davidhalter/jedi-vim [google_group]: https://groups.google.com/group/vim-syntastic
[8]: https://github.com/klen/python-mode [guide]: https://github.com/scrooloose/syntastic/wiki/Syntax-Checker-Guide
[9]: http://valloric.github.io/YouCompleteMe/ [jedi]: https://github.com/davidhalter/jedi-vim
[10]: http://perldoc.perl.org/perlrun.html#*-c* [merlin]: https://github.com/the-lambda-church/merlin
[11]: https://github.com/scrooloose/syntastic/wiki/Syntax-Checker-Guide [myint]: https://github.com/myint/syntastic-extras
[12]: https://github.com/rust-lang/rust.vim [neobundle]: https://github.com/Shougo/neobundle.vim
[13]: http://www.vim.org/ [omnisharp]: https://github.com/OmniSharp/omnisharp-vim
[14]: https://github.com/Shougo/neobundle.vim [pathogen]: https://github.com/tpope/vim-pathogen
[15]: https://github.com/MarcWeber/vim-addon-manager [perlrun]: http://perldoc.perl.org/perlrun.html#*-c*
[16]: https://github.com/junegunn/vim-plug/ [plug]: https://github.com/junegunn/vim-plug/
[17]: https://github.com/gmarik/Vundle.vim [python_mode]: https://github.com/klen/python-mode
[18]: http://tidy.sourceforge.net/ [roktas]: https://github.com/roktas/syntastic-more
[19]: http://www.htacg.org/tidy-html5/ [rust]: https://github.com/rust-lang/rust.vim
[20]: http://about.validator.nu/ [stack_overflow]: http://stackoverflow.com/questions/tagged/syntastic
[21]: https://github.com/validator/validator/releases/latest [swift]: https://github.com/kballard/vim-swift
[22]: https://github.com/scrooloose/syntastic/wiki/HTML%3A---validator [tidy]: http://www.htacg.org/tidy-html5/
[23]: http://validator.github.io/validator/#standalone [tidy_old]: http://tidy.sourceforge.net/
[24]: https://github.com/kballard/vim-swift [unimpaired]: https://github.com/tpope/vim-unimpaired
[25]: https://github.com/OmniSharp/omnisharp-vim [vam]: https://github.com/MarcWeber/vim-addon-manager
[26]: https://github.com/myint/syntastic-extras [vim]: http://www.vim.org/
[27]: https://github.com/roktas/syntastic-more [vimgo]: https://github.com/fatih/vim-go
[28]: https://github.com/venantius/vim-eastwood [vnu]: http://about.validator.nu/
[29]: https://github.com/rhysd/vim-crystal [vnu_jar]: https://github.com/validator/validator/releases/latest
[30]: https://github.com/the-lambda-church/merlin [vnu_server]: http://validator.github.io/validator/#standalone
[31]: https://github.com/eagletmt/ghcmod-vim [vundle]: https://github.com/gmarik/Vundle.vim
[32]: https://github.com/fatih/vim-go [ycm]: http://valloric.github.io/YouCompleteMe/
<!-- <!--
vim:tw=79:sw=4: vim:tw=79:sw=4:

View file

@ -357,6 +357,54 @@ function! syntastic#preprocess#stylelint(errors) abort " {{{2
return out return out
endfunction " }}}2 endfunction " }}}2
function! syntastic#preprocess#tern_lint(errors) abort " {{{2
let errs = join(a:errors, '')
let json = s:_decode_JSON(errs)
echomsg string(json)
let out = []
if type(json) == type({}) && has_key(json, 'messages') && type(json['messages']) == type([])
for e in json['messages']
try
let line_from = byte2line(e['from'] + 1)
if line_from > 0
let line = line_from
let column = e['from'] - line2byte(line_from) + 2
let line_to = byte2line(e['from'] + 1)
let hl = line_to == line ? e['to'] - line2byte(line_to) + 1 : 0
else
let line = 0
let column = 0
let hl = 0
endif
if column < 0
let column = 0
endif
if hl < 0
let hl = 0
endif
call add(out,
\ e['file'] . ':' .
\ e['severity'][0] . ':' .
\ line . ':' .
\ column . ':' .
\ hl . ':' .
\ e['message'])
catch /\m^Vim\%((\a\+)\)\=:E716/
call syntastic#log#warn('checker javascript/tern_lint: unrecognized error item ' . string(e))
let out = []
endtry
endfor
else
call syntastic#log#warn('checker javascript/tern_lint: unrecognized error format')
endif
echomsg string(out)
return out
endfunction " }}}2
function! syntastic#preprocess#tslint(errors) abort " {{{2 function! syntastic#preprocess#tslint(errors) abort " {{{2
return map(copy(a:errors), 'substitute(v:val, ''\m^\(([^)]\+)\)\s\(.\+\)$'', ''\2 \1'', "")') return map(copy(a:errors), 'substitute(v:val, ''\m^\(([^)]\+)\)\s\(.\+\)$'', ''\2 \1'', "")')
endfunction " }}}2 endfunction " }}}2

View file

@ -37,13 +37,19 @@ function! syntastic#util#system(command) abort " {{{2
let $LC_MESSAGES = 'C' let $LC_MESSAGES = 'C'
let $LC_ALL = '' let $LC_ALL = ''
let cmd_start = reltime()
let out = system(a:command) let out = system(a:command)
let cmd_time = split(reltimestr(reltime(cmd_start)))[0]
let $LC_ALL = old_lc_all let $LC_ALL = old_lc_all
let $LC_MESSAGES = old_lc_messages let $LC_MESSAGES = old_lc_messages
let &shell = old_shell let &shell = old_shell
if exists('g:_SYNTASTIC_DEBUG_TRACE')
call syntastic#log#debug(g:_SYNTASTIC_DEBUG_TRACE, 'system: command run in ' . cmd_time . 's')
endif
return out return out
endfunction " }}}2 endfunction " }}}2

File diff suppressed because it is too large Load diff

View file

@ -76,9 +76,7 @@ syntax checker plugins are defined on a per-filetype basis where each one wraps
up an external syntax checking program. The core script delegates off to these up an external syntax checking program. The core script delegates off to these
plugins and uses their output to provide the syntastic functionality. plugins and uses their output to provide the syntastic functionality.
Take a look at the wiki for a list of supported filetypes and checkers: Take a look at the list of supported filetypes and checkers: |syntastic-checkers|.
https://github.com/scrooloose/syntastic/wiki/Syntax-Checkers
Note: This doc only deals with using syntastic. To learn how to write syntax Note: This doc only deals with using syntastic. To learn how to write syntax
checker integrations, see the guide on the GitHub wiki: checker integrations, see the guide on the GitHub wiki:
@ -563,7 +561,7 @@ option should be set to something like: >
\ "file:p": ['\m^/usr/include/', '\m\c\.h$'] } \ "file:p": ['\m^/usr/include/', '\m\c\.h$'] }
< <
Each element turns off messages matching the patterns specified by the Each element turns off messages matching the patterns specified by the
corresponding value. Values are lists, but if a list consist of a single corresponding value. Values are lists, but if a list consists of a single
element you may omit the brackets (e.g. you may write "style" instead of element you may omit the brackets (e.g. you may write "style" instead of
["style"]). Elements with values [] or "" are ignored (this is useful for ["style"]). Elements with values [] or "" are ignored (this is useful for
overriding filters, cf. |filter-overrides|). overriding filters, cf. |filter-overrides|).
@ -751,10 +749,8 @@ If neither |'g:syntastic_<filetype>_checkers'| nor |'b:syntastic_checkers'|
is set, a default list of checker is used. Beware however that this list is set, a default list of checker is used. Beware however that this list
deliberately kept minimal, for performance reasons. deliberately kept minimal, for performance reasons.
Take a look at the wiki to find out what checkers and filetypes are supported Take a look elsewhere in this manual to find out what checkers and filetypes
by syntastic: are supported by syntastic: |syntastic-checkers|.
https://github.com/scrooloose/syntastic/wiki/Syntax-Checkers
Use `:SyntasticInfo` to see which checkers are available for a given filetype. Use `:SyntasticInfo` to see which checkers are available for a given filetype.
@ -848,9 +844,8 @@ omitting the filename from the command line: >
*syntastic-config-no-makeprgbuild* *syntastic-config-no-makeprgbuild*
For checkers that do not use the "makeprgBuild()" function you will have to For checkers that do not use the "makeprgBuild()" function you will have to
look at the source code of the checker in question. If there are specific look at the source code of the checker in question. If there are specific
options that can be set, they are normally documented in the wiki: options that can be set they are normally documented in this manual (see
|syntastic-checkers|).
https://github.com/scrooloose/syntastic/wiki/Syntax-Checkers
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
5.4 Sorting errors *syntastic-config-sort* 5.4 Sorting errors *syntastic-config-sort*

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-137' let g:_SYNTASTIC_VERSION = '3.7.0-153'
lockvar g:_SYNTASTIC_VERSION lockvar g:_SYNTASTIC_VERSION
" Sanity checks {{{1 " Sanity checks {{{1
@ -522,7 +522,7 @@ function! SyntasticMake(options) abort " {{{2
let env_save = {} let env_save = {}
if has_key(a:options, 'env') && len(a:options['env']) if has_key(a:options, 'env') && len(a:options['env'])
for key in keys(a:options['env']) for key in keys(a:options['env'])
if key =~? '\m^[a-z_]\+$' if key =~? '\m^[a-z_][a-z0-9_]*$'
execute 'let env_save[' . string(key) . '] = $' . key execute 'let env_save[' . string(key) . '] = $' . key
execute 'let $' . key . ' = ' . string(a:options['env'][key]) execute 'let $' . key . ' = ' . string(a:options['env'][key])
endif endif

View file

@ -91,6 +91,7 @@ function! g:SyntasticChecker.getExecEscaped() abort " {{{2
endfunction " }}}2 endfunction " }}}2
function! g:SyntasticChecker.getLocListRaw() abort " {{{2 function! g:SyntasticChecker.getLocListRaw() abort " {{{2
let checker_start = reltime()
let name = self._filetype . '/' . self._name let name = self._filetype . '/' . self._name
if has_key(self, '_enable') if has_key(self, '_enable')
@ -128,6 +129,8 @@ function! g:SyntasticChecker.getLocListRaw() abort " {{{2
call self._populateHighlightRegexes(list) call self._populateHighlightRegexes(list)
call syntastic#log#debug(g:_SYNTASTIC_DEBUG_LOCLIST, name . ' raw:', list) call syntastic#log#debug(g:_SYNTASTIC_DEBUG_LOCLIST, name . ' raw:', list)
call self._quietMessages(list) call self._quietMessages(list)
call syntastic#log#debug(g:_SYNTASTIC_DEBUG_TRACE,
\ 'getLocList: checker ' . name . ' run in ' . split(reltimestr(reltime(checker_start)))[0] . 's')
return list return list
endfunction " }}}2 endfunction " }}}2

View file

@ -28,7 +28,9 @@ endfunction
function! SyntaxCheckers_ansible_ansible_lint_GetLocList() dict function! SyntaxCheckers_ansible_ansible_lint_GetLocList() dict
let makeprg = self.makeprgBuild({ 'args_after': '-p' }) let makeprg = self.makeprgBuild({ 'args_after': '-p' })
let errorformat = '%f:%l: [ANSIBLE%n] %m' let errorformat =
\ '%f:%l: [EANSIBLE%n] %m,' .
\ '%f:%l: [ANSIBLE%n] %m'
let env = syntastic#util#isRunningWindows() ? {} : { 'TERM': 'dumb' } let env = syntastic#util#isRunningWindows() ? {} : { 'TERM': 'dumb' }

View file

@ -17,7 +17,6 @@ let g:loaded_syntastic_cpp_clang_check_checker = 1
call g:SyntasticRegistry.CreateAndRegisterChecker({ call g:SyntasticRegistry.CreateAndRegisterChecker({
\ 'filetype': 'cpp', \ 'filetype': 'cpp',
\ 'name': 'clang_check', \ 'name': 'clang_check',
\ 'exec': 'clang-check',
\ 'redirect': 'c/clang_check'}) \ 'redirect': 'c/clang_check'})
" vim: set sw=4 sts=4 et fdm=marker: " vim: set sw=4 sts=4 et fdm=marker:

View file

@ -17,7 +17,6 @@ let g:loaded_syntastic_cpp_clang_tidy_checker = 1
call g:SyntasticRegistry.CreateAndRegisterChecker({ call g:SyntasticRegistry.CreateAndRegisterChecker({
\ 'filetype': 'cpp', \ 'filetype': 'cpp',
\ 'name': 'clang_tidy', \ 'name': 'clang_tidy',
\ 'exec': 'clang-tidy',
\ 'redirect': 'c/clang_tidy'}) \ 'redirect': 'c/clang_tidy'})
" vim: set sw=4 sts=4 et fdm=marker: " vim: set sw=4 sts=4 et fdm=marker:

View file

@ -18,7 +18,6 @@ let g:loaded_syntastic_cpp_pc_lint_checker = 1
call g:SyntasticRegistry.CreateAndRegisterChecker({ call g:SyntasticRegistry.CreateAndRegisterChecker({
\ 'filetype': 'cpp', \ 'filetype': 'cpp',
\ 'name': 'pc_lint', \ 'name': 'pc_lint',
\ 'exec': 'lint-nt',
\ 'redirect': 'c/pc_lint'}) \ 'redirect': 'c/pc_lint'})
" vim: set sw=4 sts=4 et fdm=marker: " vim: set sw=4 sts=4 et fdm=marker:

View file

@ -10,19 +10,41 @@ if exists('g:loaded_syntastic_cuda_nvcc_checker')
endif endif
let g:loaded_syntastic_cuda_nvcc_checker = 1 let g:loaded_syntastic_cuda_nvcc_checker = 1
if !exists('g:syntastic_cuda_config_file')
let g:syntastic_cuda_config_file = '.syntastic_cuda_config'
endif
let s:save_cpo = &cpo let s:save_cpo = &cpo
set cpo&vim set cpo&vim
function! SyntaxCheckers_cuda_nvcc_GetLocList() dict function! SyntaxCheckers_cuda_nvcc_GetLocList() dict
if syntastic#util#var('cuda_arch') !=# '' let arch_flag = syntastic#util#var('cuda_arch')
let arch_flag = '-arch=' . g:syntastic_cuda_arch if arch_flag !=# ''
else let arch_flag = '-arch=' . arch_flag
let arch_flag = '' call syntastic#log#oneTimeWarn('variable g:syntastic_cuda_arch is deprecated, ' .
\ 'please add ' . string(arch_flag) . ' to g:syntastic_cuda_nvcc_args instead')
endif endif
let makeprg =
\ self.getExecEscaped() . ' ' . arch_flag . let build_opts = {}
\ ' --cuda -O0 -I . -Xcompiler -fsyntax-only ' . let dummy = ''
\ syntastic#util#shexpand('%') . ' ' . syntastic#c#NullOutput() if index(['h', 'hpp', 'cuh'], expand('%:e', 1), 0, 1) >= 0
if syntastic#util#var('cuda_check_header', 0)
let dummy = expand('%:p:h', 1) . syntastic#util#Slash() . '.syntastic_dummy.cu'
let build_opts = {
\ 'exe_before': 'echo > ' . syntastic#util#shescape(dummy) . ' ;',
\ 'fname_before': '.syntastic_dummy.cu -include' }
else
return []
endif
endif
call extend(build_opts, {
\ 'args_before': arch_flag . ' --cuda -O0 -I .',
\ 'args': syntastic#c#ReadConfig(g:syntastic_cuda_config_file),
\ 'args_after': '-Xcompiler -fsyntax-only',
\ 'tail_after': syntastic#c#NullOutput() })
let makeprg = self.makeprgBuild(build_opts)
let errorformat = let errorformat =
\ '%*[^"]"%f"%*\D%l: %m,'. \ '%*[^"]"%f"%*\D%l: %m,'.
@ -40,19 +62,13 @@ function! SyntaxCheckers_cuda_nvcc_GetLocList() dict
\ '%DMaking %*\a in %f,'. \ '%DMaking %*\a in %f,'.
\ '%f|%l| %m' \ '%f|%l| %m'
if index(['h', 'hpp', 'cuh'], expand('%:e', 1), 0, 1) >= 0 let loclist = SyntasticMake({ 'makeprg': makeprg, 'errorformat': errorformat })
if syntastic#util#var('cuda_check_header', 0)
let makeprg = if dummy !=# ''
\ 'echo > .syntastic_dummy.cu ; ' . call delete(dummy)
\ self.getExecEscaped() . ' ' . arch_flag .
\ ' --cuda -O0 -I . .syntastic_dummy.cu -Xcompiler -fsyntax-only -include ' .
\ syntastic#util#shexpand('%') . ' ' . syntastic#c#NullOutput()
else
return []
endif
endif endif
return SyntasticMake({ 'makeprg': makeprg, 'errorformat': errorformat }) return loclist
endfunction endfunction
call g:SyntasticRegistry.CreateAndRegisterChecker({ call g:SyntasticRegistry.CreateAndRegisterChecker({

View file

@ -0,0 +1,23 @@
"============================================================================
"File: eslint.vim
"Description: Syntax checking plugin for syntastic
"Maintainer: LCD 47 <lcd047 at gmail dot com>
"License: This program is free software. It comes without any warranty,
" to the extent permitted by applicable law. You can redistribute
" it and/or modify it under the terms of the Do What The Fuck You
" Want To Public License, Version 2, as published by Sam Hocevar.
" See http://sam.zoy.org/wtfpl/COPYING for more details.
"
"============================================================================
if exists('g:loaded_syntastic_html_eslint_checker')
finish
endif
let g:loaded_syntastic_html_eslint_checker = 1
call g:SyntasticRegistry.CreateAndRegisterChecker({
\ 'filetype': 'html',
\ 'name': 'eslint',
\ 'redirect': 'javascript/eslint'})
" vim: set sw=4 sts=4 et fdm=marker:

View file

@ -0,0 +1,53 @@
"============================================================================
"File: tern_lint.vim
"Description: Syntax checking plugin for syntastic
"Maintainer: LCD 47 <lcd047@gmail.com>
"License: This program is free software. It comes without any warranty,
" to the extent permitted by applicable law. You can redistribute
" it and/or modify it under the terms of the Do What The Fuck You
" Want To Public License, Version 2, as published by Sam Hocevar.
" See http://sam.zoy.org/wtfpl/COPYING for more details.
"============================================================================
if exists('g:loaded_syntastic_javascript_tern_lint_checker')
finish
endif
let g:loaded_syntastic_javascript_tern_lint_checker = 1
let s:save_cpo = &cpo
set cpo&vim
function! SyntaxCheckers_javascript_tern_lint_IsAvailable() dict
return has('byte_offset') && executable(self.getExec())
endfunction
function! SyntaxCheckers_javascript_tern_lint_GetLocList() dict
let makeprg = self.makeprgBuild({})
let errorformat = '%f:%t:%l:%c:%n:%m'
let loclist = SyntasticMake({
\ 'makeprg': makeprg,
\ 'errorformat': errorformat,
\ 'preprocess': 'tern_lint',
\ 'returns': [0] })
for e in loclist
if get(e, 'col', 0) && get(e, 'nr', 0)
let e['hl'] = '\%>' . (e['col'] - 1) . 'c\%<' . (e['nr'] + 1) . 'c'
endif
let e['nr'] = 0
endfor
return loclist
endfunction
call g:SyntasticRegistry.CreateAndRegisterChecker({
\ 'filetype': 'javascript',
\ 'name': 'tern_lint',
\ 'exec': 'tern-lint' })
let &cpo = s:save_cpo
unlet s:save_cpo
" vim: set sw=4 sts=4 et fdm=marker:

View file

@ -42,7 +42,8 @@ endfunction
call g:SyntasticRegistry.CreateAndRegisterChecker({ call g:SyntasticRegistry.CreateAndRegisterChecker({
\ 'filetype': 'racket', \ 'filetype': 'racket',
\ 'name': 'racket'}) \ 'name': 'racket',
\ 'enable': 'enable_racket_racket_checker' })
let &cpo = s:save_cpo let &cpo = s:save_cpo
unlet s:save_cpo unlet s:save_cpo

View file

@ -0,0 +1,51 @@
"============================================================================
"File: sass_lint.vim
"Description: Syntax checking plugin for syntastic
"Maintainer: LCD 47 <lcd047 at gmail dot com>
"License: This program is free software. It comes without any warranty,
" to the extent permitted by applicable law. You can redistribute
" it and/or modify it under the terms of the Do What The Fuck You
" Want To Public License, Version 2, as published by Sam Hocevar.
" See http://sam.zoy.org/wtfpl/COPYING for more details.
"
"============================================================================
if exists('g:loaded_syntastic_sass_sass_lint_checker')
finish
endif
let g:loaded_syntastic_sass_sass_lint_checker = 1
let s:save_cpo = &cpo
set cpo&vim
function! SyntaxCheckers_sass_sass_lint_IsAvailable() dict
if !executable(self.getExec())
return 0
endif
return syntastic#util#versionIsAtLeast(self.getVersion(), [1, 5])
endfunction
function! SyntaxCheckers_sass_sass_lint_GetLocList() dict
let makeprg = self.makeprgBuild({
\ 'args': '-v',
\ 'args_after': '-q -f compact' })
let errorformat =
\ '%f: line %l\, col %c\, %trror - %m,' .
\ '%f: line %l\, col %c\, %tarning - %m'
return SyntasticMake({
\ 'makeprg': makeprg,
\ 'errorformat': errorformat,
\ 'returns': [0, 1] })
endfunction
call g:SyntasticRegistry.CreateAndRegisterChecker({
\ 'filetype': 'sass',
\ 'name': 'sass_lint',
\ 'exec': 'sass-lint' })
let &cpo = s:save_cpo
unlet s:save_cpo
" vim: set sw=4 sts=4 et fdm=marker:

View file

@ -0,0 +1,23 @@
"============================================================================
"File: sass_lint.vim
"Description: Syntax checking plugin for syntastic
"Maintainer: LCD 47 <lcd047 at gmail dot com>
"License: This program is free software. It comes without any warranty,
" to the extent permitted by applicable law. You can redistribute
" it and/or modify it under the terms of the Do What The Fuck You
" Want To Public License, Version 2, as published by Sam Hocevar.
" See http://sam.zoy.org/wtfpl/COPYING for more details.
"
"============================================================================
if exists('g:loaded_syntastic_scss_sass_lint_checker')
finish
endif
let g:loaded_syntastic_scss_sass_lint_checker = 1
call g:SyntasticRegistry.CreateAndRegisterChecker({
\ 'filetype': 'scss',
\ 'name': 'sass_lint',
\ 'redirect': 'sass/sass_lint'})
" vim: set sw=4 sts=4 et fdm=marker:

View file

@ -41,35 +41,37 @@ endfunction " }}}1
" Utilities {{{1 " Utilities {{{1
function! s:GetValaModules() " {{{2 function! s:GetValaModules() " {{{2
if exists('g:syntastic_vala_modules') if exists('g:syntastic_vala_modules') || exists('b:syntastic_vala_modules')
if type(g:syntastic_vala_modules) == type('') let modules = syntastic#util#var('vala_modules')
return split(g:syntastic_vala_modules, '\s\+') if type(modules) == type('')
elseif type(g:syntastic_vala_modules) == type([]) return split(modules, '\m\s\+')
return copy(g:syntastic_vala_modules) elseif type(modules) == type([])
return copy(modules)
else else
echoerr 'g:syntastic_vala_modules must be either list or string: fallback to in file modules string' echoerr 'syntastic_vala_modules must be either list or string: fallback to in file modules string'
endif endif
endif endif
let modules_line = search('^// modules: ', 'n') let modules_line = search('^// modules: ', 'n')
let modules_str = getline(modules_line) let modules_str = getline(modules_line)
return split(strpart(modules_str, 12), '\s\+') return split(strpart(modules_str, 12), '\m\s\+')
endfunction " }}}2 endfunction " }}}2
function! s:GetValaVapiDirs() " {{{2 function! s:GetValaVapiDirs() " {{{2
if exists('g:syntastic_vala_vapi_dirs') if exists('g:syntastic_vala_vapi_dirs') || exists('b:syntastic_vala_vapi_dirs')
if type(g:syntastic_vala_vapi_dirs) == type('') let vapi_dirs = syntastic#util#var('vala_vapi_dirs')
return split(g:syntastic_vala_vapi_dirs, '\s\+') if type(vapi_dirs) == type('')
elseif type(g:syntastic_vala_vapi_dirs) == type([]) return split(vapi_dirs, '\m\s\+')
return copy(g:syntastic_vala_vapi_dirs) elseif type(vapi_dirs) == type([])
return copy(vapi_dirs)
else else
echoerr 'g:syntastic_vala_vapi_dirs must be either a list, or a string: fallback to in-file modules string' echoerr 'syntastic_vala_vapi_dirs must be either a list, or a string: fallback to in-file modules string'
endif endif
endif endif
let vapi_line = search('^//\s*vapidirs:\s*','n') let vapi_line = search('^//\s*vapidirs:\s*','n')
let vapi_str = getline(vapi_line) let vapi_str = getline(vapi_line)
return split( substitute( vapi_str, '^//\s*vapidirs:\s*', '', 'g' ), '\s\+' ) return split( substitute( vapi_str, '\m^//\s*vapidirs:\s*', '', 'g' ), '\m\s\+' )
endfunction " }}}2 endfunction " }}}2
" }}}1 " }}}1

View file

@ -67,9 +67,10 @@ function! SyntaxCheckers_vim_vimlint_GetLocList() dict " {{{1
\ 'EVL204': 3, \ 'EVL204': 3,
\ 'EVL205': 3 } \ 'EVL205': 3 }
if exists('g:syntastic_vimlint_options') if exists('g:syntastic_vimlint_options') || exists('b:syntastic_vimlint_options')
if type(g:syntastic_vimlint_options) == type({}) let opts = syntastic#util#var('vimlint_options')
let options = filter(copy(g:syntastic_vimlint_options), 'v:key =~# "\\m^EVL"') if type(opts) == type({})
let options = filter(copy(opts), 'v:key =~# "\\m^EVL"')
call extend(param, options, 'force') call extend(param, options, 'force')
endif endif
endif endif

View file

@ -1116,7 +1116,7 @@ endfunction
function! s:CommitComplete(A,L,P) abort function! s:CommitComplete(A,L,P) abort
if a:A =~ '^-' || type(a:A) == type(0) " a:A is 0 on :Gcommit -<Tab> if a:A =~ '^-' || type(a:A) == type(0) " a:A is 0 on :Gcommit -<Tab>
let args = ['-C', '-F', '-a', '-c', '-e', '-i', '-m', '-n', '-o', '-q', '-s', '-t', '-u', '-v', '--all', '--allow-empty', '--amend', '--author=', '--cleanup=', '--dry-run', '--edit', '--file=', '--include', '--interactive', '--message=', '--no-verify', '--only', '--quiet', '--reedit-message=', '--reuse-message=', '--signoff', '--template=', '--untracked-files', '--verbose'] let args = ['-C', '-F', '-a', '-c', '-e', '-i', '-m', '-n', '-o', '-q', '-s', '-t', '-u', '-v', '--all', '--allow-empty', '--amend', '--author=', '--cleanup=', '--dry-run', '--edit', '--file=', '--fixup=', '--include', '--interactive', '--message=', '--no-verify', '--only', '--quiet', '--reedit-message=', '--reuse-message=', '--signoff', '--squash=', '--template=', '--untracked-files', '--verbose']
return filter(args,'v:val[0 : strlen(a:A)-1] ==# a:A') return filter(args,'v:val[0 : strlen(a:A)-1] ==# a:A')
else else
return s:repo().superglob(a:A) return s:repo().superglob(a:A)
@ -2840,7 +2840,7 @@ function! s:cfile() abort
elseif getline('.') =~# '^#\trenamed:.* -> ' elseif getline('.') =~# '^#\trenamed:.* -> '
let file = '/'.matchstr(getline('.'),' -> \zs.*') let file = '/'.matchstr(getline('.'),' -> \zs.*')
return [file] return [file]
elseif getline('.') =~# '^#\t[[:alpha:] ]\+: *.' elseif getline('.') =~# '^#\t\(\k\| \)\+: *.'
let file = '/'.matchstr(getline('.'),': *\zs.\{-\}\ze\%( ([^()[:digit:]]\+)\)\=$') let file = '/'.matchstr(getline('.'),': *\zs.\{-\}\ze\%( ([^()[:digit:]]\+)\)\=$')
return [file] return [file]
elseif getline('.') =~# '^#\t.' elseif getline('.') =~# '^#\t.'

View file

@ -1,25 +1,61 @@
## 1.7 (unreleased) ## 1.8 (unplanned)
IMPROVEMENTS:
* `:GoDoc` accepts arguments now which are passed directly to `godoc`. So usages like `:GoDoc flag` works again (it was changed in previous versions [gh-894]
* `:GoDef` works now for modified files as well [gh-910]
* Internal: fix indentations on all files to **2-spaces/no tabs**. This is now the default vim-go style across all VimL files [gh-915]
BUG FIXES:
* Escape `#` characters when opening URL's, as it's handled as alternative file in vim [gh-895]
* Fix typos in `doc/vim-go.txt` about usages of syntax highglightings [gh-897]
* Fix `:GoCoverage` not running for Neovim [gh-899]
* Fix `:GoFmt` not picking up `-srcdir` if the command was set to use `goimports` [gh-904]
* Fix `:GoTestCompile` to not leave behind artifacts if the cwd and the test files's directory do not match [gh-909]
## 1.7.1 (June 7, 2016)
BUG FIXES:
* Fixed typo in `syntax/go.vim` file from `go:go_highlight_fields` to `g:go_highlight_fields`
## 1.7 (June 7, 2016)
FEATURES: FEATURES:
* New **`:GoImpl`** command that generates method stubs for implementing an interface. Checkout the [demo](https://twitter.com/fatih/status/729991365581545472) to see how it works. [gh-846] * New **`:GoImpl`** command that generates method stubs for implementing an interface. Checkout the [demo](https://twitter.com/fatih/status/729991365581545472) to see how it works. [gh-846]
* `godef` support is added back as an optional setting. By default `:GoDef` still uses `guru`, but can be changed to `godef` by adding the option: `let g:go_def_mode = 'godef'` [gh-888]
* New `<C-w><C-]>` and `<C-w>]>` shortcuts to split current window and jumpt to the identifier under cursor. [gh-838] * New `<C-w><C-]>` and `<C-w>]>` shortcuts to split current window and jumpt to the identifier under cursor. [gh-838]
* New syntax setting" `g:go_highlight_fields` that highlights struct field references [gh-854]
IMPROVEMENTS: IMPROVEMENTS:
* Invoking `:GoRename` now reloads all files to reflect new changes automatically [gh-855]
* Calling `:GoTestCompile` does not create any temporary binary file anymore [gh-879]
* Enable passing the `-tags` flag to `:GoDef`. Now you can pass build tags to `:GoDef` via `:GoGuruTags` or `g:go_guru_tags` * Enable passing the `-tags` flag to `:GoDef`. Now you can pass build tags to `:GoDef` via `:GoGuruTags` or `g:go_guru_tags`
* Internal refactoring to use custom `system()` function that wraps both the standard `system()` call and `vimproc`. Now all system calls will take advantage and will use `vimproc` if installed. [gh-801] * Internal refactoring to use custom `system()` function that wraps both the standard `system()` call and `vimproc`. Now all system calls will take advantage and will use `vimproc` if installed. [gh-801]
* Completion enables now `gocode`'s `autobuild` and `propose-builtins` flags automatically. With these settings packages will be automatically build to get the freshest completion candidates and builtin keywords will be showed as well. By defaults these settings are enabled. Settings can be disabled/enabled via `g:go_gocode_autobuild` and `g:go_gocode_propose_builtins`. [gh-815]
* Added new `http.HandlerFunc` snippets with `hf` and `hhf` shortcuts [gh-816] * Added new `http.HandlerFunc` snippets with `hf` and `hhf` shortcuts [gh-816]
* Added new `Example` and `Benchmark` snippets with `example` and `benchmark` shortcuts [gh-836] * Added new `Example` and `Benchmark` snippets with `example` and `benchmark` shortcuts [gh-836]
* Search tool binaries first in `GOBIN` and then in `PATH` as most of vim-go users installs it to `GOBIN` mostly [gh-823] * Search tool binaries first in `GOBIN` and then in `PATH` as most of vim-go users installs it to `GOBIN` mostly [gh-823]
* Improve `guru` based commands by providing automatically detected GOPATHS, such as `gb`, `godep` to be used if possible [gh-861]
* Add `<Plug>(go-imports)` mapping to make it assignable to other keys [gh-878]
* Increase compatibility with tcsh [gh-869]
* Improve `:GoInstallBinaries` for GOPATH's which don't have packages that work well with `go get -u`. We have a new `g:go_get_update` setting to disable it. By default it's enabled. [gh-883]
BUG FIXES: BUG FIXES:
* Fix `(go-freevars)` plug mapping to work as in visual mode instead of noncompatible normal mode [gh-832] * Fix `(go-freevars)` plug mapping to work as in visual mode instead of noncompatible normal mode [gh-832]
* Commands based on guru now shows a more meaningful error message instead of just showing the exit status (-1) * Commands based on guru now shows a more meaningful error message instead of just showing the exit status (-1)
* Fix `:GoCoverage` accidently enabling syntax highlighting for users who don't use syntax (i.e syntax off) [gh-827] * Fix `:GoCoverage` accidently enabling syntax highlighting for users who don't use syntax (i.e syntax off) [gh-827]
* Fix `:GoCoverage` colors to work for xterm as well [gh-863]
* Fix commenting out block of texts for Go templates (filetype gothtmltmpl) [gh-813] * Fix commenting out block of texts for Go templates (filetype gothtmltmpl) [gh-813]
* Fix `:GoImplements` failing because of an empty scope definition. Now we default to current package to make it usable. * Fix `:GoImplements` failing because of an empty scope definition. Now we default to current package to make it usable.
* Fix `:GoPlay` posting to non HTTPS url. [gh-847] * Fix `:GoPlay` posting to non HTTPS url. [gh-847]
* Fix escaping the filenames for lint and motion commands [gh-862]
* Fix escaping the filename to `:GoDef` completely for tcsh [gh-868]
* Fix showing SUCCESS for `go test` related commands if no test files are available [gh-859]

View file

@ -52,7 +52,7 @@ disabled/enabled easily.
## Install ## Install
Master branch is supposed to be a development branch. So stuff here can break and change. Master branch is supposed to be a development branch. So stuff here can break and change.
Please try use always the [latest release](https://github.com/fatih/vim-go/releases/latest) Please try use always the [latest release](https://github.com/fatih/vim-go/releases/latest)
Vim-go follows the standard runtime path structure, so I highly recommend to Vim-go follows the standard runtime path structure, so I highly recommend to
@ -180,6 +180,7 @@ To change it:
```vim ```vim
let g:go_highlight_functions = 1 let g:go_highlight_functions = 1
let g:go_highlight_methods = 1 let g:go_highlight_methods = 1
let g:go_highlight_fields = 1
let g:go_highlight_structs = 1 let g:go_highlight_structs = 1
let g:go_highlight_interfaces = 1 let g:go_highlight_interfaces = 1
let g:go_highlight_operators = 1 let g:go_highlight_operators = 1
@ -218,6 +219,11 @@ let g:go_bin_path = expand("~/.gotools")
let g:go_bin_path = "/home/fatih/.mypath" "or give absolute path let g:go_bin_path = "/home/fatih/.mypath" "or give absolute path
``` ```
Disable updating dependencies when installing/updating binaries:
```vim
let g:go_get_update = 0
```
### Using with Neovim (beta) ### Using with Neovim (beta)
Note: Neovim currently is not a first class citizen for vim-go. You are free Note: Neovim currently is not a first class citizen for vim-go. You are free

View file

@ -1,26 +1,26 @@
let s:go_decls_var = { let s:go_decls_var = {
\ 'init': 'ctrlp#decls#init()', \ 'init': 'ctrlp#decls#init()',
\ 'exit': 'ctrlp#decls#exit()', \ 'exit': 'ctrlp#decls#exit()',
\ 'enter': 'ctrlp#decls#enter()', \ 'enter': 'ctrlp#decls#enter()',
\ 'accept': 'ctrlp#decls#accept', \ 'accept': 'ctrlp#decls#accept',
\ 'lname': 'declarations', \ 'lname': 'declarations',
\ 'sname': 'decls', \ 'sname': 'decls',
\ 'type': 'tabs', \ 'type': 'tabs',
\} \}
if exists('g:ctrlp_ext_vars') && !empty(g:ctrlp_ext_vars) if exists('g:ctrlp_ext_vars') && !empty(g:ctrlp_ext_vars)
let g:ctrlp_ext_vars = add(g:ctrlp_ext_vars, s:go_decls_var) let g:ctrlp_ext_vars = add(g:ctrlp_ext_vars, s:go_decls_var)
else else
let g:ctrlp_ext_vars = [s:go_decls_var] let g:ctrlp_ext_vars = [s:go_decls_var]
endif endif
function! ctrlp#decls#init() function! ctrlp#decls#init()
cal s:enable_syntax() cal s:enable_syntax()
return s:decls return s:decls
endfunction endfunction
function! ctrlp#decls#exit() function! ctrlp#decls#exit()
unlet! s:decls s:current_dir s:target unlet! s:decls s:current_dir s:target
endfunction endfunction
" The action to perform on the selected string " The action to perform on the selected string
@ -29,130 +29,131 @@ endfunction
" the values are 'e', 'v', 't' and 'h', respectively " the values are 'e', 'v', 't' and 'h', respectively
" a:str the selected string " a:str the selected string
function! ctrlp#decls#accept(mode, str) function! ctrlp#decls#accept(mode, str)
let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd ' : 'cd ' let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd ' : 'cd '
let dir = getcwd() let dir = getcwd()
try try
" we jump to the file directory so we can get the fullpath via fnamemodify " we jump to the file directory so we can get the fullpath via fnamemodify
" below " below
execute cd . s:current_dir execute cd . s:current_dir
let vals = matchlist(a:str, '|\(.\{-}\):\(\d\+\):\(\d\+\)\s*\(.*\)|') let vals = matchlist(a:str, '|\(.\{-}\):\(\d\+\):\(\d\+\)\s*\(.*\)|')
" i.e: main.go " i.e: main.go
let filename = vals[1] let filename = vals[1]
let line = vals[2] let line = vals[2]
let col = vals[3] let col = vals[3]
" i.e: /Users/fatih/vim-go/main.go " i.e: /Users/fatih/vim-go/main.go
let filepath = fnamemodify(filename, ":p") let filepath = fnamemodify(filename, ":p")
" acceptile is a very versatile method, " acceptile is a very versatile method,
call ctrlp#acceptfile(a:mode, filepath) call ctrlp#acceptfile(a:mode, filepath)
call cursor(line, col) call cursor(line, col)
silent! norm! zvzz silent! norm! zvzz
finally finally
"jump back to old dir "jump back to old dir
execute cd . fnameescape(dir) execute cd . fnameescape(dir)
endtry endtry
endfunction endfunction
function! ctrlp#decls#enter() function! ctrlp#decls#enter()
let s:current_dir = fnameescape(expand('%:p:h')) let s:current_dir = fnameescape(expand('%:p:h'))
let s:decls = [] let s:decls = []
let bin_path = go#path#CheckBinPath('motion') let bin_path = go#path#CheckBinPath('motion')
if empty(bin_path) if empty(bin_path)
return return
endif endif
let command = printf("%s -format vim -mode decls", bin_path) let command = printf("%s -format vim -mode decls", bin_path)
let command .= " -include ". get(g:, "go_decls_includes", "func,type") let command .= " -include ". get(g:, "go_decls_includes", "func,type")
call go#cmd#autowrite() call go#cmd#autowrite()
if s:mode == 0 if s:mode == 0
" current file mode " current file mode
let fname = expand("%:p") let fname = expand("%:p")
if exists('s:target') if exists('s:target')
let fname = s:target let fname = s:target
endif endif
let command .= printf(" -file %s", fname) let command .= printf(" -file %s", fname)
else else
" all functions mode " all functions mode
let dir = expand("%:p:h") let dir = expand("%:p:h")
if exists('s:target') if exists('s:target')
let dir = s:target let dir = s:target
endif endif
let command .= printf(" -dir %s", dir) let command .= printf(" -dir %s", dir)
endif endif
let out = go#util#System(command) let out = go#util#System(command)
if go#util#ShellError() != 0 if go#util#ShellError() != 0
call go#util#EchoError(out) call go#util#EchoError(out)
return return
endif endif
if exists("l:tmpname") if exists("l:tmpname")
call delete(l:tmpname) call delete(l:tmpname)
endif endif
let result = eval(out) let result = eval(out)
if type(result) != 4 || !has_key(result, 'decls') if type(result) != 4 || !has_key(result, 'decls')
return return
endif endif
let decls = result.decls let decls = result.decls
" find the maximum function name " find the maximum function name
let max_len = 0 let max_len = 0
for decl in decls for decl in decls
if len(decl.ident)> max_len if len(decl.ident)> max_len
let max_len = len(decl.ident) let max_len = len(decl.ident)
endif endif
endfor endfor
for decl in decls for decl in decls
" paddings " paddings
let space = " " let space = " "
for i in range(max_len - len(decl.ident)) for i in range(max_len - len(decl.ident))
let space .= " " let space .= " "
endfor endfor
call add(s:decls, printf("%s\t%s |%s:%s:%s|\t%s", call add(s:decls, printf("%s\t%s |%s:%s:%s|\t%s",
\ decl.ident . space, \ decl.ident . space,
\ decl.keyword, \ decl.keyword,
\ fnamemodify(decl.filename, ":t"), \ fnamemodify(decl.filename, ":t"),
\ decl.line, \ decl.line,
\ decl.col, \ decl.col,
\ decl.full, \ decl.full,
\)) \))
endfor endfor
endfunc endfunc
function! s:enable_syntax() function! s:enable_syntax()
if !(has('syntax') && exists('g:syntax_on')) if !(has('syntax') && exists('g:syntax_on'))
return return
endif endif
syntax match CtrlPIdent '\zs\h\+\ze\s' syntax match CtrlPIdent '\zs\h\+\ze\s'
syntax match CtrlPKeyword '\zs[^\t|]\+\ze|[^|]\+:\d\+:\d\+|' syntax match CtrlPKeyword '\zs[^\t|]\+\ze|[^|]\+:\d\+:\d\+|'
syntax match CtrlPFilename '|\zs[^|]\+:\d\+:\d\+\ze|' syntax match CtrlPFilename '|\zs[^|]\+:\d\+:\d\+\ze|'
syntax match CtrlPSignature '\zs\t.*\ze$' contains=CtrlPKeyWord,CtrlPFilename syntax match CtrlPSignature '\zs\t.*\ze$' contains=CtrlPKeyWord,CtrlPFilename
highlight link CtrlPIdent Function highlight link CtrlPIdent Function
highlight link CtrlPKeyword Keyword highlight link CtrlPKeyword Keyword
highlight link CtrlPFilename SpecialComment highlight link CtrlPFilename SpecialComment
highlight link CtrlPSignature Comment highlight link CtrlPSignature Comment
endfunction endfunction
let s:id = g:ctrlp_builtins + len(g:ctrlp_ext_vars) let s:id = g:ctrlp_builtins + len(g:ctrlp_ext_vars)
function! ctrlp#decls#cmd(mode, ...) function! ctrlp#decls#cmd(mode, ...)
let s:mode = a:mode let s:mode = a:mode
if a:0 && !empty(a:1) if a:0 && !empty(a:1)
let s:target = a:1 let s:target = a:1
endif endif
return s:id return s:id
endfunction endfunction
" vim: sw=2 ts=2 et

View file

@ -28,3 +28,5 @@ function! go#alternate#Switch(bang, cmd)
execute ":" . a:cmd . " " . alt_file execute ":" . a:cmd . " " . alt_file
endif endif
endfunction endfunction
" vim: sw=2 ts=2 et

View file

@ -50,3 +50,5 @@ function! go#asmfmt#Format()
" Restore the cursor/window positions. " Restore the cursor/window positions.
call winrestview(l:curw) call winrestview(l:curw)
endfunction endfunction
" vim: sw=2 ts=2 et

View file

@ -1,11 +1,11 @@
if !exists("g:go_dispatch_enabled") if !exists("g:go_dispatch_enabled")
let g:go_dispatch_enabled = 0 let g:go_dispatch_enabled = 0
endif endif
function! go#cmd#autowrite() function! go#cmd#autowrite()
if &autowrite == 1 if &autowrite == 1
silent wall silent wall
endif endif
endfunction endfunction
@ -14,73 +14,73 @@ endfunction
" default it tries to call simply 'go build', but it first tries to get all " default it tries to call simply 'go build', but it first tries to get all
" dependent files for the current folder and passes it to go build. " dependent files for the current folder and passes it to go build.
function! go#cmd#Build(bang, ...) function! go#cmd#Build(bang, ...)
" expand all wildcards(i.e: '%' to the current file name) " expand all wildcards(i.e: '%' to the current file name)
let goargs = map(copy(a:000), "expand(v:val)") let goargs = map(copy(a:000), "expand(v:val)")
" escape all shell arguments before we pass it to make " escape all shell arguments before we pass it to make
let goargs = go#util#Shelllist(goargs, 1) let goargs = go#util#Shelllist(goargs, 1)
" create our command arguments. go build discards any results when it " create our command arguments. go build discards any results when it
" compiles multiple packages. So we pass the `errors` package just as an " compiles multiple packages. So we pass the `errors` package just as an
" placeholder with the current folder (indicated with '.') " placeholder with the current folder (indicated with '.')
let args = ["build"] + goargs + [".", "errors"] let args = ["build"] + goargs + [".", "errors"]
" if we have nvim, call it asynchronously and return early ;) " if we have nvim, call it asynchronously and return early ;)
if has('nvim') if has('nvim')
call go#util#EchoProgress("building dispatched ...") call go#util#EchoProgress("building dispatched ...")
call go#jobcontrol#Spawn(a:bang, "build", args) call go#jobcontrol#Spawn(a:bang, "build", args)
return return
endif endif
let old_gopath = $GOPATH let old_gopath = $GOPATH
let $GOPATH = go#path#Detect() let $GOPATH = go#path#Detect()
let default_makeprg = &makeprg let default_makeprg = &makeprg
let &makeprg = "go " . join(args, ' ') let &makeprg = "go " . join(args, ' ')
let l:listtype = go#list#Type("quickfix") let l:listtype = go#list#Type("quickfix")
" execute make inside the source folder so we can parse the errors " execute make inside the source folder so we can parse the errors
" correctly " correctly
let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd ' : 'cd ' let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd ' : 'cd '
let dir = getcwd() let dir = getcwd()
try try
execute cd . fnameescape(expand("%:p:h")) execute cd . fnameescape(expand("%:p:h"))
if g:go_dispatch_enabled && exists(':Make') == 2 if g:go_dispatch_enabled && exists(':Make') == 2
call go#util#EchoProgress("building dispatched ...") call go#util#EchoProgress("building dispatched ...")
silent! exe 'Make' silent! exe 'Make'
elseif l:listtype == "locationlist" elseif l:listtype == "locationlist"
silent! exe 'lmake!' silent! exe 'lmake!'
else
silent! exe 'make!'
endif
redraw!
finally
execute cd . fnameescape(dir)
endtry
let errors = go#list#Get(l:listtype)
call go#list#Window(l:listtype, len(errors))
if !empty(errors)
if !a:bang
call go#list#JumpToFirst(l:listtype)
endif
else else
call go#util#EchoSuccess("[build] SUCCESS") silent! exe 'make!'
endif endif
redraw!
finally
execute cd . fnameescape(dir)
endtry
let &makeprg = default_makeprg let errors = go#list#Get(l:listtype)
let $GOPATH = old_gopath call go#list#Window(l:listtype, len(errors))
if !empty(errors)
if !a:bang
call go#list#JumpToFirst(l:listtype)
endif
else
call go#util#EchoSuccess("[build] SUCCESS")
endif
let &makeprg = default_makeprg
let $GOPATH = old_gopath
endfunction endfunction
" Run runs the current file (and their dependencies if any) in a new terminal. " Run runs the current file (and their dependencies if any) in a new terminal.
function! go#cmd#RunTerm(bang, mode, files) function! go#cmd#RunTerm(bang, mode, files)
if empty(a:files) if empty(a:files)
let cmd = "go run ". go#util#Shelljoin(go#tool#Files()) let cmd = "go run ". go#util#Shelljoin(go#tool#Files())
else else
let cmd = "go run ". go#util#Shelljoin(map(copy(a:files), "expand(v:val)"), 1) let cmd = "go run ". go#util#Shelljoin(map(copy(a:files), "expand(v:val)"), 1)
endif endif
call go#term#newmode(a:bang, cmd, a:mode) call go#term#newmode(a:bang, cmd, a:mode)
endfunction endfunction
" Run runs the current file (and their dependencies if any) and outputs it. " Run runs the current file (and their dependencies if any) and outputs it.
@ -88,248 +88,272 @@ endfunction
" suitable for long running apps, because vim is blocking by default and " suitable for long running apps, because vim is blocking by default and
" calling long running apps will block the whole UI. " calling long running apps will block the whole UI.
function! go#cmd#Run(bang, ...) function! go#cmd#Run(bang, ...)
if has('nvim') if has('nvim')
call go#cmd#RunTerm(a:bang, '', a:000) call go#cmd#RunTerm(a:bang, '', a:000)
return return
endif endif
let old_gopath = $GOPATH let old_gopath = $GOPATH
let $GOPATH = go#path#Detect() let $GOPATH = go#path#Detect()
if go#util#IsWin() if go#util#IsWin()
exec '!go run ' . go#util#Shelljoin(go#tool#Files()) exec '!go run ' . go#util#Shelljoin(go#tool#Files())
if v:shell_error if v:shell_error
redraws! | echon "vim-go: [run] " | echohl ErrorMsg | echon "FAILED"| echohl None redraws! | echon "vim-go: [run] " | echohl ErrorMsg | echon "FAILED"| echohl None
else
redraws! | echon "vim-go: [run] " | echohl Function | echon "SUCCESS"| echohl None
endif
let $GOPATH = old_gopath
return
endif
" :make expands '%' and '#' wildcards, so they must also be escaped
let default_makeprg = &makeprg
if a:0 == 0
let &makeprg = 'go run ' . go#util#Shelljoin(go#tool#Files(), 1)
else else
let &makeprg = "go run " . go#util#Shelljoin(map(copy(a:000), "expand(v:val)"), 1) redraws! | echon "vim-go: [run] " | echohl Function | echon "SUCCESS"| echohl None
endif
let l:listtype = go#list#Type("quickfix")
if g:go_dispatch_enabled && exists(':Make') == 2
silent! exe 'Make'
elseif l:listtype == "locationlist"
exe 'lmake!'
else
exe 'make!'
endif
let items = go#list#Get(l:listtype)
let errors = go#tool#FilterValids(items)
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 endif
let $GOPATH = old_gopath let $GOPATH = old_gopath
let &makeprg = default_makeprg return
endif
" :make expands '%' and '#' wildcards, so they must also be escaped
let default_makeprg = &makeprg
if a:0 == 0
let &makeprg = 'go run ' . go#util#Shelljoin(go#tool#Files(), 1)
else
let &makeprg = "go run " . go#util#Shelljoin(map(copy(a:000), "expand(v:val)"), 1)
endif
let l:listtype = go#list#Type("quickfix")
if g:go_dispatch_enabled && exists(':Make') == 2
silent! exe 'Make'
elseif l:listtype == "locationlist"
exe 'lmake!'
else
exe 'make!'
endif
let items = go#list#Get(l:listtype)
let errors = go#tool#FilterValids(items)
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
let $GOPATH = old_gopath
let &makeprg = default_makeprg
endfunction endfunction
" Install installs the package by simple calling 'go install'. If any argument " Install installs the package by simple calling 'go install'. If any argument
" is given(which are passed directly to 'go install') it tries to install those " is given(which are passed directly to 'go install') it tries to install those
" packages. Errors are populated in the location window. " packages. Errors are populated in the location window.
function! go#cmd#Install(bang, ...) function! go#cmd#Install(bang, ...)
let default_makeprg = &makeprg let default_makeprg = &makeprg
" :make expands '%' and '#' wildcards, so they must also be escaped " :make expands '%' and '#' wildcards, so they must also be escaped
let goargs = go#util#Shelljoin(map(copy(a:000), "expand(v:val)"), 1) let goargs = go#util#Shelljoin(map(copy(a:000), "expand(v:val)"), 1)
let &makeprg = "go install " . goargs let &makeprg = "go install " . goargs
let l:listtype = go#list#Type("quickfix") let l:listtype = go#list#Type("quickfix")
" execute make inside the source folder so we can parse the errors " execute make inside the source folder so we can parse the errors
" correctly " correctly
let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd ' : 'cd ' let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd ' : 'cd '
let dir = getcwd() let dir = getcwd()
try try
execute cd . fnameescape(expand("%:p:h")) execute cd . fnameescape(expand("%:p:h"))
if g:go_dispatch_enabled && exists(':Make') == 2 if g:go_dispatch_enabled && exists(':Make') == 2
call go#util#EchoProgress("building dispatched ...") call go#util#EchoProgress("building dispatched ...")
silent! exe 'Make' silent! exe 'Make'
elseif l:listtype == "locationlist" elseif l:listtype == "locationlist"
silent! exe 'lmake!' silent! exe 'lmake!'
else
silent! exe 'make!'
endif
redraw!
finally
execute cd . fnameescape(dir)
endtry
let errors = go#list#Get(l:listtype)
call go#list#Window(l:listtype, len(errors))
if !empty(errors)
if !a:bang
call go#list#JumpToFirst(l:listtype)
endif
else else
redraws! | echon "vim-go: " | echohl Function | echon "installed to ". $GOPATH | echohl None silent! exe 'make!'
endif endif
redraw!
finally
execute cd . fnameescape(dir)
endtry
let &makeprg = default_makeprg let errors = go#list#Get(l:listtype)
call go#list#Window(l:listtype, len(errors))
if !empty(errors)
if !a:bang
call go#list#JumpToFirst(l:listtype)
endif
else
redraws! | echon "vim-go: " | echohl Function | echon "installed to ". $GOPATH | echohl None
endif
let &makeprg = default_makeprg
endfunction endfunction
" Test runs `go test` in the current directory. If compile is true, it'll " Test runs `go test` in the current directory. If compile is true, it'll
" compile the tests instead of running them (useful to catch errors in the " compile the tests instead of running them (useful to catch errors in the
" test files). Any other argument is appendend to the final `go test` command " test files). Any other argument is appendend to the final `go test` command
function! go#cmd#Test(bang, compile, ...) function! go#cmd#Test(bang, compile, ...)
let args = ["test"] let args = ["test"]
" don't run the test, only compile it. Useful to capture and fix errors or " don't run the test, only compile it. Useful to capture and fix errors.
" to create a test binary. if a:compile
if a:compile let compile_file = "vim-go-test-compile"
call add(args, "-c") call extend(args, ["-c", "-o", compile_file])
endif
if a:0
" expand all wildcards(i.e: '%' to the current file name)
let goargs = map(copy(a:000), "expand(v:val)")
if !has('nvim')
let goargs = go#util#Shelllist(goargs, 1)
endif endif
if a:0 call extend(args, goargs, 1)
" expand all wildcards(i.e: '%' to the current file name) else
let goargs = map(copy(a:000), "expand(v:val)") " only add this if no custom flags are passed
let timeout = get(g:, 'go_test_timeout', '10s')
call add(args, printf("-timeout=%s", timeout))
endif
call extend(args, goargs, 1) if a:compile
echon "vim-go: " | echohl Identifier | echon "compiling tests ..." | echohl None
else
echon "vim-go: " | echohl Identifier | echon "testing ..." | echohl None
endif
if has('nvim')
if get(g:, 'go_term_enabled', 0)
let id = go#term#new(a:bang, ["go"] + args)
else else
" only add this if no custom flags are passed let id = go#jobcontrol#Spawn(a:bang, "test", args)
let timeout = get(g:, 'go_test_timeout', '10s')
call add(args, printf("-timeout=%s", timeout))
endif endif
if a:compile if a:compile
echon "vim-go: " | echohl Identifier | echon "compiling tests ..." | echohl None call go#jobcontrol#AddHandler(function('s:test_compile_handler'))
let s:test_compile_handlers[id] = compile_file
endif
return id
endif
call go#cmd#autowrite()
redraw
let command = "go " . join(args, ' ')
let out = go#tool#ExecuteInDir(command)
let l:listtype = "quickfix"
let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd ' : 'cd '
let dir = getcwd()
execute cd fnameescape(expand("%:p:h"))
if a:compile
call delete(compile_file)
endif
if go#util#ShellError() != 0
let errors = go#tool#ParseErrors(split(out, '\n'))
let errors = go#tool#FilterValids(errors)
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)
elseif empty(errors)
" failed to parse errors, output the original content
call go#util#EchoError(out)
endif
echon "vim-go: " | echohl ErrorMsg | echon "[test] FAIL" | echohl None
else
call go#list#Clean(l:listtype)
call go#list#Window(l:listtype)
if a:compile
echon "vim-go: " | echohl Function | echon "[test] SUCCESS" | echohl None
else else
echon "vim-go: " | echohl Identifier | echon "testing ..." | echohl None echon "vim-go: " | echohl Function | echon "[test] PASS" | echohl None
endif
if has('nvim')
if get(g:, 'go_term_enabled', 0)
let id = go#term#new(a:bang, ["go"] + args)
else
let id = go#jobcontrol#Spawn(a:bang, "test", args)
endif
return id
endif
call go#cmd#autowrite()
redraw
let command = "go " . join(args, ' ')
let out = go#tool#ExecuteInDir(command)
let l:listtype = "quickfix"
if go#util#ShellError() != 0
let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd ' : 'cd '
let dir = getcwd()
try
execute cd fnameescape(expand("%:p:h"))
let errors = go#tool#ParseErrors(split(out, '\n'))
let errors = go#tool#FilterValids(errors)
finally
execute cd . fnameescape(dir)
endtry
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)
elseif empty(errors)
" failed to parse errors, output the original content
call go#util#EchoError(out)
endif
echon "vim-go: " | echohl ErrorMsg | echon "[test] FAIL" | echohl None
else
call go#list#Clean(l:listtype)
call go#list#Window(l:listtype)
if a:compile
echon "vim-go: " | echohl Function | echon "[test] SUCCESS" | echohl None
else
echon "vim-go: " | echohl Function | echon "[test] PASS" | echohl None
endif
endif endif
endif
execute cd . fnameescape(dir)
endfunction endfunction
" Testfunc runs a single test that surrounds the current cursor position. " Testfunc runs a single test that surrounds the current cursor position.
" Arguments are passed to the `go test` command. " Arguments are passed to the `go test` command.
function! go#cmd#TestFunc(bang, ...) function! go#cmd#TestFunc(bang, ...)
" search flags legend (used only) " search flags legend (used only)
" 'b' search backward instead of forward " 'b' search backward instead of forward
" 'c' accept a match at the cursor position " 'c' accept a match at the cursor position
" 'n' do Not move the cursor " 'n' do Not move the cursor
" 'W' don't wrap around the end of the file " 'W' don't wrap around the end of the file
" "
" for the full list " for the full list
" :help search " :help search
let test = search('func \(Test\|Example\)', "bcnW") let test = search('func \(Test\|Example\)', "bcnW")
if test == 0 if test == 0
echo "vim-go: [test] no test found immediate to cursor" echo "vim-go: [test] no test found immediate to cursor"
return return
end end
let line = getline(test) let line = getline(test)
let name = split(split(line, " ")[1], "(")[0] let name = split(split(line, " ")[1], "(")[0]
let args = [a:bang, 0, "-run", name . "$"] let args = [a:bang, 0, "-run", name . "$"]
if a:0 if a:0
call extend(args, a:000) call extend(args, a:000)
endif endif
call call('go#cmd#Test', args) call call('go#cmd#Test', args)
endfunction 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
let old_gopath = $GOPATH let old_gopath = $GOPATH
let $GOPATH = go#path#Detect() let $GOPATH = go#path#Detect()
" :make expands '%' and '#' wildcards, so they must also be escaped " :make expands '%' and '#' wildcards, so they must also be escaped
let goargs = go#util#Shelljoin(map(copy(a:000), "expand(v:val)"), 1) let goargs = go#util#Shelljoin(map(copy(a:000), "expand(v:val)"), 1)
if go#util#ShellError() != 0 if go#util#ShellError() != 0
let &makeprg = "go generate " . goargs let &makeprg = "go generate " . goargs
else else
let gofiles = go#util#Shelljoin(go#tool#Files(), 1) let gofiles = go#util#Shelljoin(go#tool#Files(), 1)
let &makeprg = "go generate " . goargs . ' ' . gofiles let &makeprg = "go generate " . goargs . ' ' . gofiles
endif
let l:listtype = go#list#Type("quickfix")
echon "vim-go: " | echohl Identifier | echon "generating ..."| echohl None
if g:go_dispatch_enabled && exists(':Make') == 2
silent! exe 'Make'
elseif l:listtype == "locationlist"
silent! exe 'lmake!'
else
silent! exe 'make!'
endif
redraw!
let errors = go#list#Get(l:listtype)
call go#list#Window(l:listtype, len(errors))
if !empty(errors)
if !a:bang
call go#list#JumpToFirst(l:listtype)
endif endif
else
redraws! | echon "vim-go: " | echohl Function | echon "[generate] SUCCESS"| echohl None
endif
let l:listtype = go#list#Type("quickfix") let &makeprg = default_makeprg
let $GOPATH = old_gopath
echon "vim-go: " | echohl Identifier | echon "generating ..."| echohl None
if g:go_dispatch_enabled && exists(':Make') == 2
silent! exe 'Make'
elseif l:listtype == "locationlist"
silent! exe 'lmake!'
else
silent! exe 'make!'
endif
redraw!
let errors = go#list#Get(l:listtype)
call go#list#Window(l:listtype, len(errors))
if !empty(errors)
if !a:bang
call go#list#JumpToFirst(l:listtype)
endif
else
redraws! | echon "vim-go: " | echohl Function | echon "[generate] SUCCESS"| echohl None
endif
let &makeprg = default_makeprg
let $GOPATH = old_gopath
endfunction endfunction
" vim:ts=4:sw=4:et
" -----------------------
" | Neovim job handlers |
" -----------------------
let s:test_compile_handlers = {}
function! s:test_compile_handler(job, exit_status, data)
if !has_key(s:test_compile_handlers, a:job.id)
return
endif
let l:compile_file = s:test_compile_handlers[a:job.id]
call delete(l:compile_file)
unlet s:test_compile_handlers[a:job.id]
endfunction
" vim: sw=2 ts=2 et

View file

@ -1,138 +1,156 @@
if !exists("g:go_gocode_bin") function! s:gocodeCurrentBuffer()
let g:go_gocode_bin = "gocode" let buf = getline(1, '$')
endif if &encoding != 'utf-8'
let buf = map(buf, 'iconv(v:val, &encoding, "utf-8")')
endif
if &l:fileformat == 'dos'
" XXX: line2byte() depend on 'fileformat' option.
" so if fileformat is 'dos', 'buf' must include '\r'.
let buf = map(buf, 'v:val."\r"')
endif
let file = tempname()
call writefile(buf, file)
return file
endfunction
fu! s:gocodeCurrentBuffer() function! s:gocodeCommand(cmd, preargs, args)
let buf = getline(1, '$') for i in range(0, len(a:args) - 1)
let a:args[i] = go#util#Shellescape(a:args[i])
endfor
for i in range(0, len(a:preargs) - 1)
let a:preargs[i] = go#util#Shellescape(a:preargs[i])
endfor
let bin_path = go#path#CheckBinPath("gocode")
if empty(bin_path)
return
endif
" we might hit cache problems, as gocode doesn't handle well different
" GOPATHS: https://github.com/nsf/gocode/issues/239
let old_gopath = $GOPATH
let $GOPATH = go#path#Detect()
let result = go#util#System(printf('%s %s %s %s', go#util#Shellescape(bin_path), join(a:preargs), go#util#Shellescape(a:cmd), join(a:args)))
let $GOPATH = old_gopath
if go#util#ShellError() != 0
return "[\"0\", []]"
else
if &encoding != 'utf-8' if &encoding != 'utf-8'
let buf = map(buf, 'iconv(v:val, &encoding, "utf-8")') let result = iconv(result, 'utf-8', &encoding)
endif endif
if &l:fileformat == 'dos'
" XXX: line2byte() depend on 'fileformat' option.
" so if fileformat is 'dos', 'buf' must include '\r'.
let buf = map(buf, 'v:val."\r"')
endif
let file = tempname()
call writefile(buf, file)
return file
endf
fu! s:gocodeCommand(cmd, preargs, args)
for i in range(0, len(a:args) - 1)
let a:args[i] = go#util#Shellescape(a:args[i])
endfor
for i in range(0, len(a:preargs) - 1)
let a:preargs[i] = go#util#Shellescape(a:preargs[i])
endfor
let bin_path = go#path#CheckBinPath(g:go_gocode_bin)
if empty(bin_path)
return
endif
" we might hit cache problems, as gocode doesn't handle well different
" GOPATHS: https://github.com/nsf/gocode/issues/239
let old_gopath = $GOPATH
let $GOPATH = go#path#Detect()
let result = go#util#System(printf('%s %s %s %s', go#util#Shellescape(bin_path), join(a:preargs), go#util#Shellescape(a:cmd), join(a:args)))
let $GOPATH = old_gopath
if go#util#ShellError() != 0
return "[\"0\", []]"
else
if &encoding != 'utf-8'
let result = iconv(result, 'utf-8', &encoding)
endif
return result
endif
endf
fu! s:gocodeCurrentBufferOpt(filename)
return '-in=' . a:filename
endf
fu! s:gocodeAutocomplete()
let filename = s:gocodeCurrentBuffer()
let result = s:gocodeCommand('autocomplete',
\ [s:gocodeCurrentBufferOpt(filename), '-f=vim'],
\ [expand('%:p'), go#util#OffsetCursor()])
call delete(filename)
return result return result
endf endif
endfunction
function! s:gocodeCurrentBufferOpt(filename)
return '-in=' . a:filename
endfunction
let s:optionsEnabled = 0
function! s:gocodeEnableOptions()
if s:optionsEnabled
return
endif
let bin_path = go#path#CheckBinPath("gocode")
if empty(bin_path)
return
endif
let s:optionsEnabled = 1
call go#util#System(printf('%s set propose-builtins %s', go#util#Shellescape(bin_path), s:toBool(get(g:, 'go_gocode_propose_builtins', 1))))
call go#util#System(printf('%s set autobuild %s', go#util#Shellescape(bin_path), s:toBool(get(g:, 'go_gocode_autobuild', 1))))
endfunction
function! s:toBool(val)
if a:val | return 'true ' | else | return 'false' | endif
endfunction
function! s:gocodeAutocomplete()
call s:gocodeEnableOptions()
let filename = s:gocodeCurrentBuffer()
let result = s:gocodeCommand('autocomplete',
\ [s:gocodeCurrentBufferOpt(filename), '-f=vim'],
\ [expand('%:p'), go#util#OffsetCursor()])
call delete(filename)
return result
endfunction
function! go#complete#GetInfo() function! go#complete#GetInfo()
let offset = go#util#OffsetCursor()+1 let offset = go#util#OffsetCursor()+1
let filename = s:gocodeCurrentBuffer() let filename = s:gocodeCurrentBuffer()
let result = s:gocodeCommand('autocomplete', let result = s:gocodeCommand('autocomplete',
\ [s:gocodeCurrentBufferOpt(filename), '-f=godit'], \ [s:gocodeCurrentBufferOpt(filename), '-f=godit'],
\ [expand('%:p'), offset]) \ [expand('%:p'), offset])
call delete(filename) call delete(filename)
" first line is: Charcount,,NumberOfCandidates, i.e: 8,,1 " first line is: Charcount,,NumberOfCandidates, i.e: 8,,1
" following lines are candiates, i.e: func foo(name string),,foo( " following lines are candiates, i.e: func foo(name string),,foo(
let out = split(result, '\n') let out = split(result, '\n')
" no candidates are found
if len(out) == 1
return ""
endif
" only one candiate is found
if len(out) == 2
return split(out[1], ',,')[0]
endif
" to many candidates are available, pick one that maches the word under the
" cursor
let infos = []
for info in out[1:]
call add(infos, split(info, ',,')[0])
endfor
let wordMatch = '\<' . expand("<cword>") . '\>'
" escape single quotes in wordMatch before passing it to filter
let wordMatch = substitute(wordMatch, "'", "''", "g")
let filtered = filter(infos, "v:val =~ '".wordMatch."'")
if len(filtered) == 1
return filtered[0]
endif
" no candidates are found
if len(out) == 1
return "" return ""
endif
" only one candiate is found
if len(out) == 2
return split(out[1], ',,')[0]
endif
" to many candidates are available, pick one that maches the word under the
" cursor
let infos = []
for info in out[1:]
call add(infos, split(info, ',,')[0])
endfor
let wordMatch = '\<' . expand("<cword>") . '\>'
" escape single quotes in wordMatch before passing it to filter
let wordMatch = substitute(wordMatch, "'", "''", "g")
let filtered = filter(infos, "v:val =~ '".wordMatch."'")
if len(filtered) == 1
return filtered[0]
endif
return ""
endfunction endfunction
function! go#complete#Info(auto) function! go#complete#Info(auto)
" auto is true if we were called by g:go_auto_type_info's autocmd " auto is true if we were called by g:go_auto_type_info's autocmd
let result = go#complete#GetInfo() let result = go#complete#GetInfo()
if !empty(result) if !empty(result)
" if auto, and the result is a PANIC by gocode, hide it " if auto, and the result is a PANIC by gocode, hide it
if a:auto && result ==# 'PANIC PANIC PANIC' | return | endif if a:auto && result ==# 'PANIC PANIC PANIC' | return | endif
echo "vim-go: " | echohl Function | echon result | echohl None echo "vim-go: " | echohl Function | echon result | echohl None
endif endif
endfunction endfunction
function! s:trim_bracket(val) function! s:trim_bracket(val)
let a:val.word = substitute(a:val.word, '[(){}\[\]]\+$', '', '') let a:val.word = substitute(a:val.word, '[(){}\[\]]\+$', '', '')
return a:val return a:val
endfunction endfunction
fu! go#complete#Complete(findstart, base) function! go#complete#Complete(findstart, base)
"findstart = 1 when we need to get the text length "findstart = 1 when we need to get the text length
if a:findstart == 1 if a:findstart == 1
execute "silent let g:gocomplete_completions = " . s:gocodeAutocomplete() execute "silent let g:gocomplete_completions = " . s:gocodeAutocomplete()
return col('.') - g:gocomplete_completions[0] - 1 return col('.') - g:gocomplete_completions[0] - 1
"findstart = 0 when we need to return the list of completions "findstart = 0 when we need to return the list of completions
else else
let s = getline(".")[col('.') - 1] let s = getline(".")[col('.') - 1]
if s =~ '[(){}\{\}]' if s =~ '[(){}\{\}]'
return map(copy(g:gocomplete_completions[1]), 's:trim_bracket(v:val)') return map(copy(g:gocomplete_completions[1]), 's:trim_bracket(v:val)')
endif
return g:gocomplete_completions[1]
endif endif
return g:gocomplete_completions[1]
endif
endf endf
" vim:ts=4:sw=4:et " vim: sw=2 ts=2 et

View file

@ -4,16 +4,16 @@ let s:toggle = 0
" the current buffers highlighting to show covered and uncovered sections of " the current buffers highlighting to show covered and uncovered sections of
" the code. If run again it clears the annotation. " the code. If run again it clears the annotation.
function! go#coverage#BufferToggle(bang, ...) function! go#coverage#BufferToggle(bang, ...)
if s:toggle if s:toggle
call go#coverage#Clear() call go#coverage#Clear()
return return
endif endif
if a:0 == 0 if a:0 == 0
return call(function('go#coverage#Buffer'), [a:bang]) return call(function('go#coverage#Buffer'), [a:bang])
endif endif
return call(function('go#coverage#Buffer'), [a:bang] + a:000) return call(function('go#coverage#Buffer'), [a:bang] + a:000)
endfunction endfunction
" Buffer creates a new cover profile with 'go test -coverprofile' and changes " Buffer creates a new cover profile with 'go test -coverprofile' and changes
@ -21,216 +21,229 @@ endfunction
" the code. Calling it again reruns the tests and shows the last updated " the code. Calling it again reruns the tests and shows the last updated
" coverage. " coverage.
function! go#coverage#Buffer(bang, ...) function! go#coverage#Buffer(bang, ...)
" we use matchaddpos() which was introduce with 7.4.330, be sure we have " we use matchaddpos() which was introduce with 7.4.330, be sure we have
" it: http://ftp.vim.org/vim/patches/7.4/7.4.330 " it: http://ftp.vim.org/vim/patches/7.4/7.4.330
if !exists("*matchaddpos") if !exists("*matchaddpos")
call go#util#EchoError("GoCoverage is supported with Vim version 7.4-330 or later") call go#util#EchoError("GoCoverage is supported with Vim version 7.4-330 or later")
return -1 return -1
endif
" check if there is any test file, if not we just return
let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd ' : 'cd '
let dir = getcwd()
try
execute cd . fnameescape(expand("%:p:h"))
if empty(glob("*_test.go"))
call go#util#EchoError("no tests files available")
return
endif endif
finally
execute cd . fnameescape(dir)
endtry
let s:toggle = 1 let s:toggle = 1
let l:tmpname = tempname() let l:tmpname = tempname()
let args = [a:bang, 0, "-coverprofile", l:tmpname] let args = [a:bang, 0, "-coverprofile", l:tmpname]
if a:0 if a:0
call extend(args, a:000) call extend(args, a:000)
endif endif
let disabled_term = 0 let disabled_term = 0
if get(g:, 'go_term_enabled') if get(g:, 'go_term_enabled')
let disabled_term = 1 let disabled_term = 1
let g:go_term_enabled = 0 let g:go_term_enabled = 0
endif endif
let id = call('go#cmd#Test', args) let id = call('go#cmd#Test', args)
if disabled_term if disabled_term
let g:go_term_enabled = 1 let g:go_term_enabled = 1
endif endif
if has('nvim') if has('nvim')
call go#jobcontrol#AddHandler(function('s:coverage_handler')) call go#jobcontrol#AddHandler(function('s:coverage_handler'))
let s:coverage_handler_jobs[id] = l:tmpname let s:coverage_handler_jobs[id] = l:tmpname
return return
endif endif
if go#util#ShellError() == 0 if go#util#ShellError() == 0
call go#coverage#overlay(l:tmpname) call go#coverage#overlay(l:tmpname)
endif endif
call delete(l:tmpname) call delete(l:tmpname)
endfunction endfunction
" Clear clears and resets the buffer annotation matches " Clear clears and resets the buffer annotation matches
function! go#coverage#Clear() function! go#coverage#Clear()
" only reset the syntax if the user has syntax enabled " only reset the syntax if the user has syntax enabled
if !empty(&syntax) if !empty(&syntax)
if exists("g:syntax_on") | syntax enable | endif if exists("g:syntax_on") | syntax enable | endif
endif endif
if exists("s:toggle") | let s:toggle = 0 | endif if exists("s:toggle") | let s:toggle = 0 | endif
" remove the autocmd we defined " remove the autocmd we defined
if exists("#BufWinLeave#<buffer>") if exists("#BufWinLeave#<buffer>")
autocmd! BufWinLeave <buffer> autocmd! BufWinLeave <buffer>
endif endif
call clearmatches() call clearmatches()
endfunction endfunction
" Browser creates a new cover profile with 'go test -coverprofile' and opens " Browser creates a new cover profile with 'go test -coverprofile' and opens
" a new HTML coverage page from that profile in a new browser " a new HTML coverage page from that profile in a new browser
function! go#coverage#Browser(bang, ...) function! go#coverage#Browser(bang, ...)
let l:tmpname = tempname() let l:tmpname = tempname()
let args = [a:bang, 0, "-coverprofile", l:tmpname] let args = [a:bang, 0, "-coverprofile", l:tmpname]
if a:0 if a:0
call extend(args, a:000) call extend(args, a:000)
endif endif
let id = call('go#cmd#Test', args) let id = call('go#cmd#Test', args)
if has('nvim') if has('nvim')
call go#jobcontrol#AddHandler(function('s:coverage_browser_handler')) call go#jobcontrol#AddHandler(function('s:coverage_browser_handler'))
let s:coverage_browser_handler_jobs[id] = l:tmpname let s:coverage_browser_handler_jobs[id] = l:tmpname
return return
endif endif
if go#util#ShellError() == 0 if go#util#ShellError() == 0
let openHTML = 'go tool cover -html='.l:tmpname let openHTML = 'go tool cover -html='.l:tmpname
call go#tool#ExecuteInDir(openHTML) call go#tool#ExecuteInDir(openHTML)
endif endif
call delete(l:tmpname) call delete(l:tmpname)
endfunction endfunction
" Parses a single line from the cover file generated via go test -coverprofile " Parses a single line from the cover file generated via go test -coverprofile
" and returns a single coverage profile block. " and returns a single coverage profile block.
function! go#coverage#parsegocoverline(line) function! go#coverage#parsegocoverline(line)
" file:startline.col,endline.col numstmt count " file:startline.col,endline.col numstmt count
let mx = '\([^:]\+\):\(\d\+\)\.\(\d\+\),\(\d\+\)\.\(\d\+\)\s\(\d\+\)\s\(\d\+\)' let mx = '\([^:]\+\):\(\d\+\)\.\(\d\+\),\(\d\+\)\.\(\d\+\)\s\(\d\+\)\s\(\d\+\)'
let tokens = matchlist(a:line, mx) let tokens = matchlist(a:line, mx)
let ret = {} let ret = {}
let ret.file = tokens[1] let ret.file = tokens[1]
let ret.startline = str2nr(tokens[2]) let ret.startline = str2nr(tokens[2])
let ret.startcol = str2nr(tokens[3]) let ret.startcol = str2nr(tokens[3])
let ret.endline = str2nr(tokens[4]) let ret.endline = str2nr(tokens[4])
let ret.endcol = str2nr(tokens[5]) let ret.endcol = str2nr(tokens[5])
let ret.numstmt = tokens[6] let ret.numstmt = tokens[6]
let ret.cnt = tokens[7] let ret.cnt = tokens[7]
return ret return ret
endfunction endfunction
" Generates matches to be added to matchaddpos for the given coverage profile " Generates matches to be added to matchaddpos for the given coverage profile
" block " block
function! go#coverage#genmatch(cov) function! go#coverage#genmatch(cov)
let color = 'covered' let color = 'covered'
if a:cov.cnt == 0 if a:cov.cnt == 0
let color = 'uncover' let color = 'uncover'
endif endif
let matches = [] let matches = []
" if start and end are the same, also specify the byte length " if start and end are the same, also specify the byte length
" example: foo.go:92.2,92.65 1 0 " example: foo.go:92.2,92.65 1 0
if a:cov.startline == a:cov.endline 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, { call add(matches, {
\ 'group': color, \ 'group': color,
\ 'pos': [[a:cov.startline, a:cov.startcol, 200]], \ 'pos': [[a:cov.startline, a:cov.startcol, a:cov.endcol - a:cov.startcol]],
\ 'priority': 2, \ '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 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 endfunction
" Reads the given coverprofile file and annotates the current buffer " Reads the given coverprofile file and annotates the current buffer
function! go#coverage#overlay(file) function! go#coverage#overlay(file)
if !filereadable(a:file) if !filereadable(a:file)
return return
endif endif
let lines = readfile(a:file) let lines = readfile(a:file)
" cover mode, by default it's 'set'. Just here for debugging purposes " cover mode, by default it's 'set'. Just here for debugging purposes
let mode = lines[0] let mode = lines[0]
" contains matches for matchaddpos() " contains matches for matchaddpos()
let matches = [] let matches = []
" first mark all lines as normaltext. We use a custom group to not " first mark all lines as normaltext. We use a custom group to not
" interfere with other buffers highlightings. Because the priority is " interfere with other buffers highlightings. Because the priority is
" lower than the cover and uncover matches, it'll be overriden. " lower than the cover and uncover matches, it'll be overriden.
let cnt = 1 let cnt = 1
while cnt <= line('$') while cnt <= line('$')
call add(matches, {'group': 'normaltext', 'pos': [cnt], 'priority': 1}) call add(matches, {'group': 'normaltext', 'pos': [cnt], 'priority': 1})
let cnt += 1 let cnt += 1
endwhile endwhile
let fname = expand('%:t') let fname = expand('%:t')
" when called for a _test.go file, run the coverage for the actuall file " when called for a _test.go file, run the coverage for the actuall file
" file " file
if fname =~# '^\f\+_test\.go$' if fname =~# '^\f\+_test\.go$'
let l:root = split(fname, '_test.go$')[0] let l:root = split(fname, '_test.go$')[0]
let fname = l:root . ".go" let fname = l:root . ".go"
if !filereadable(fname) if !filereadable(fname)
call go#util#EchoError("couldn't find ".fname) call go#util#EchoError("couldn't find ".fname)
return return
endif
" open the alternate file to show the coverage
exe ":edit ". fnamemodify(fname, ":p")
endif endif
for line in lines[1:] " open the alternate file to show the coverage
let cov = go#coverage#parsegocoverline(line) exe ":edit ". fnamemodify(fname, ":p")
endif
" TODO(arslan): for now only include the coverage for the current for line in lines[1:]
" buffer let cov = go#coverage#parsegocoverline(line)
if fname != fnamemodify(cov.file, ':t')
continue
endif
call extend(matches, go#coverage#genmatch(cov)) " TODO(arslan): for now only include the coverage for the current
endfor " buffer
if fname != fnamemodify(cov.file, ':t')
continue
endif
syntax manual call extend(matches, go#coverage#genmatch(cov))
highlight normaltext term=bold ctermfg=59 guifg=#75715E endfor
highlight covered term=bold ctermfg=118 guifg=#A6E22E
highlight uncover term=bold ctermfg=197 guifg=#F92672
" clear the matches if we leave the buffer syntax manual
autocmd BufWinLeave <buffer> call go#coverage#Clear() highlight normaltext term=bold ctermfg=darkgrey guifg=#75715E
highlight covered term=bold ctermfg=green guifg=#A6E22E
highlight uncover term=bold ctermfg=red guifg=#F92672
for m in matches " clear the matches if we leave the buffer
call matchaddpos(m.group, m.pos) autocmd BufWinLeave <buffer> call go#coverage#Clear()
endfor
for m in matches
call matchaddpos(m.group, m.pos)
endfor
endfunction endfunction
@ -242,32 +255,31 @@ let s:coverage_handler_jobs = {}
let s:coverage_browser_handler_jobs = {} let s:coverage_browser_handler_jobs = {}
function! s:coverage_handler(job, exit_status, data) function! s:coverage_handler(job, exit_status, data)
if !has_key(s:coverage_handler_jobs, a:job.id) if !has_key(s:coverage_handler_jobs, a:job.id)
return return
endif endif
let l:tmpname = s:coverage_handler_jobs[a:job.id] let l:tmpname = s:coverage_handler_jobs[a:job.id]
if a:exit_status == 0 if a:exit_status == 0
call go#coverage#overlay(l:tmpname) call go#coverage#overlay(l:tmpname)
endif endif
call delete(l:tmpname) call delete(l:tmpname)
unlet s:coverage_handler_jobs[a:job.id] unlet s:coverage_handler_jobs[a:job.id]
endfunction endfunction
function! s:coverage_browser_handler(job, exit_status, data) function! s:coverage_browser_handler(job, exit_status, data)
if !has_key(s:coverage_browser_handler_jobs, a:job.id) if !has_key(s:coverage_browser_handler_jobs, a:job.id)
return return
endif endif
let l:tmpname = s:coverage_browser_handler_jobs[a:job.id] let l:tmpname = s:coverage_browser_handler_jobs[a:job.id]
if a:exit_status == 0 if a:exit_status == 0
let openHTML = 'go tool cover -html='.l:tmpname let openHTML = 'go tool cover -html='.l:tmpname
call go#tool#ExecuteInDir(openHTML) call go#tool#ExecuteInDir(openHTML)
endif endif
call delete(l:tmpname) call delete(l:tmpname)
unlet s:coverage_browser_handler_jobs[a:job.id] unlet s:coverage_browser_handler_jobs[a:job.id]
endfunction endfunction
" vim: sw=2 ts=2 et
" vim:ts=4:sw=4:et

View file

@ -2,201 +2,238 @@ let s:go_stack = []
let s:go_stack_level = 0 let s:go_stack_level = 0
function! go#def#Jump(mode) function! go#def#Jump(mode)
let bin_path = go#path#CheckBinPath("guru") let old_gopath = $GOPATH
if empty(bin_path) let $GOPATH = go#path#Detect()
return
endif
let old_gopath = $GOPATH let fname = fnamemodify(expand("%"), ':p:gs?\\?/?')
let $GOPATH = go#path#Detect() if &modified
" Write current unsaved buffer to a temp file and use the modified content
let l:tmpname = tempname()
call writefile(getline(1, '$'), l:tmpname)
let fname = l:tmpname
endif
let flags = "" " so guru right now is slow for some people. previously we were using
if exists('g:go_guru_tags') " godef which also has it's own quirks. But this issue come up so many
let tags = get(g:, 'go_guru_tags') " times I've decided to support both. By default we still use guru as it
let flags = printf(" -tags %s", tags) " covers all edge cases, but now anyone can switch to godef if they wish
endif let bin_name = get(g:, 'go_def_mode', 'guru')
if bin_name == 'godef'
let bin_path = go#path#CheckBinPath("godef")
if empty(bin_path)
let $GOPATH = old_gopath
return
endif
let command = printf("%s -f=%s -o=%s -t", bin_path, fname, go#util#OffsetCursor())
let out = go#util#System(command)
let fname = fnamemodify(expand("%"), ':p:gs?\\?/?') " append the type information to the same line so our
let command = printf("%s %s definition %s:#%s", bin_path, flags, shellescape(fname), go#util#OffsetCursor()) " jump_to_declaration() function can parse it. This makes it
" compatible with guru definition as well too
let out = join(split(out, '\n'), ':')
elseif bin_name == 'guru'
let bin_path = go#path#CheckBinPath("guru")
if empty(bin_path)
let $GOPATH = old_gopath
return
endif
let out = go#util#System(command) let flags = ""
if go#util#ShellError() != 0 if exists('g:go_guru_tags')
call go#util#EchoError(out) let tags = get(g:, 'go_guru_tags')
return let flags = printf(" -tags %s", tags)
endif endif
call s:jump_to_declaration(out, a:mode) let fname = shellescape(fname.':#'.go#util#OffsetCursor())
let $GOPATH = old_gopath let command = printf("%s %s definition %s", bin_path, flags, fname)
let out = go#util#System(command)
else
call go#util#EchoError('go_def_mode value: '. bin_name .' is not valid. Valid values are: [godef, guru]')
return
endif
if exists("l:tmpname")
call delete(l:tmpname)
endif
if go#util#ShellError() != 0
call go#util#EchoError(out)
return
endif
call s:jump_to_declaration(out, a:mode)
let $GOPATH = old_gopath
endfunction endfunction
function! s:jump_to_declaration(out, mode) function! s:jump_to_declaration(out, mode)
" strip line ending " strip line ending
let out = split(a:out, go#util#LineEnding())[0] let out = split(a:out, go#util#LineEnding())[0]
if go#util#IsWin() if go#util#IsWin()
let parts = split(out, '\(^[a-zA-Z]\)\@<!:') let parts = split(out, '\(^[a-zA-Z]\)\@<!:')
else else
let parts = split(out, ':') let parts = split(out, ':')
endif endif
let filename = parts[0] let filename = parts[0]
let line = parts[1] let line = parts[1]
let col = parts[2] let col = parts[2]
let ident = parts[3] let ident = parts[3]
" Remove anything newer than the current position, just like basic " Remove anything newer than the current position, just like basic
" vim tag support " vim tag support
if s:go_stack_level == 0 if s:go_stack_level == 0
let s:go_stack = [] let s:go_stack = []
else else
let s:go_stack = s:go_stack[0:s:go_stack_level-1] let s:go_stack = s:go_stack[0:s:go_stack_level-1]
endif endif
" increment the stack counter " increment the stack counter
let s:go_stack_level += 1 let s:go_stack_level += 1
" push it on to the jumpstack " push it on to the jumpstack
let stack_entry = {'line': line("."), 'col': col("."), 'file': expand('%:p'), 'ident': ident} let stack_entry = {'line': line("."), 'col': col("."), 'file': expand('%:p'), 'ident': ident}
call add(s:go_stack, stack_entry) call add(s:go_stack, stack_entry)
" needed for restoring back user setting this is because there are two " needed for restoring back user setting this is because there are two
" modes of switchbuf which we need based on the split mode " modes of switchbuf which we need based on the split mode
let old_switchbuf = &switchbuf let old_switchbuf = &switchbuf
" jump to existing buffer if, 1. we have enabled it, 2. the buffer is loaded " jump to existing buffer if, 1. we have enabled it, 2. the buffer is loaded
" and 3. there is buffer window number we switch to " and 3. there is buffer window number we switch to
if get(g:, 'go_def_reuse_buffer', 0) && bufloaded(filename) != 0 && bufwinnr(filename) != -1 if get(g:, 'go_def_reuse_buffer', 0) && bufloaded(filename) != 0 && bufwinnr(filename) != -1
" jumpt to existing buffer if it exists " jumpt to existing buffer if it exists
execute bufwinnr(filename) . 'wincmd w' execute bufwinnr(filename) . 'wincmd w'
elseif a:mode == "tab" elseif a:mode == "tab"
let &switchbuf = "usetab" let &switchbuf = "usetab"
if bufloaded(filename) == 0 if bufloaded(filename) == 0
tab split tab split
endif endif
elseif a:mode == "split" elseif a:mode == "split"
split split
elseif a:mode == "vsplit" elseif a:mode == "vsplit"
vsplit vsplit
endif endif
" open the file and jump to line and column " open the file and jump to line and column
exec 'edit '.filename exec 'edit '.filename
call cursor(line, col) call cursor(line, col)
" also align the line to middle of the view " also align the line to middle of the view
normal! zz normal! zz
let &switchbuf = old_switchbuf let &switchbuf = old_switchbuf
endfunction endfunction
function! go#def#SelectStackEntry() function! go#def#SelectStackEntry()
let target_window = go#ui#GetReturnWindow() let target_window = go#ui#GetReturnWindow()
if empty(target_window) if empty(target_window)
let target_window = winnr() let target_window = winnr()
endif endif
let highlighted_stack_entry = matchstr(getline("."), '^..\zs\(\d\+\)') let highlighted_stack_entry = matchstr(getline("."), '^..\zs\(\d\+\)')
if !empty(highlighted_stack_entry) if !empty(highlighted_stack_entry)
execute target_window . "wincmd w" execute target_window . "wincmd w"
call go#def#Stack(str2nr(highlighted_stack_entry)) call go#def#Stack(str2nr(highlighted_stack_entry))
endif endif
call go#ui#CloseWindow() call go#ui#CloseWindow()
endfunction endfunction
function! go#def#StackUI() function! go#def#StackUI()
if len(s:go_stack) == 0 if len(s:go_stack) == 0
call go#util#EchoError("godef stack empty") call go#util#EchoError("godef stack empty")
return return
endif endif
let stackOut = ['" <Up>,<Down>:navigate <Enter>:jump <Esc>,q:exit'] let stackOut = ['" <Up>,<Down>:navigate <Enter>:jump <Esc>,q:exit']
let i = 0 let i = 0
while i < len(s:go_stack) while i < len(s:go_stack)
let entry = s:go_stack[i] let entry = s:go_stack[i]
let prefix = "" let prefix = ""
if i == s:go_stack_level if i == s:go_stack_level
let prefix = ">" let prefix = ">"
else else
let prefix = " " let prefix = " "
endif endif
call add(stackOut, printf("%s %d %s|%d col %d|%s", call add(stackOut, printf("%s %d %s|%d col %d|%s",
\ prefix, i+1, entry["file"], entry["line"], entry["col"], entry["ident"])) \ prefix, i+1, entry["file"], entry["line"], entry["col"], entry["ident"]))
let i += 1 let i += 1
endwhile endwhile
if s:go_stack_level == i if s:go_stack_level == i
call add(stackOut, "> ") call add(stackOut, "> ")
endif endif
call go#ui#OpenWindow("GoDef Stack", stackOut, "godefstack") call go#ui#OpenWindow("GoDef Stack", stackOut, "godefstack")
noremap <buffer> <silent> <CR> :<C-U>call go#def#SelectStackEntry()<CR> 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> <Esc> :<C-U>call go#ui#CloseWindow()<CR>
noremap <buffer> <silent> q :<C-U>call go#ui#CloseWindow()<CR> noremap <buffer> <silent> q :<C-U>call go#ui#CloseWindow()<CR>
endfunction endfunction
function! go#def#StackClear(...) function! go#def#StackClear(...)
let s:go_stack = [] let s:go_stack = []
let s:go_stack_level = 0 let s:go_stack_level = 0
endfunction endfunction
function! go#def#StackPop(...) function! go#def#StackPop(...)
if len(s:go_stack) == 0 if len(s:go_stack) == 0
call go#util#EchoError("godef stack empty") call go#util#EchoError("godef stack empty")
return return
endif endif
if s:go_stack_level == 0 if s:go_stack_level == 0
call go#util#EchoError("at bottom of the godef stack") call go#util#EchoError("at bottom of the godef stack")
return return
endif endif
if !len(a:000) if !len(a:000)
let numPop = 1 let numPop = 1
else else
let numPop = a:1 let numPop = a:1
endif endif
let newLevel = str2nr(s:go_stack_level) - str2nr(numPop) let newLevel = str2nr(s:go_stack_level) - str2nr(numPop)
call go#def#Stack(newLevel + 1) call go#def#Stack(newLevel + 1)
endfunction endfunction
function! go#def#Stack(...) function! go#def#Stack(...)
if len(s:go_stack) == 0 if len(s:go_stack) == 0
call go#util#EchoError("godef stack empty") call go#util#EchoError("godef stack empty")
return return
endif endif
if !len(a:000) if !len(a:000)
" Display interactive stack " Display interactive stack
call go#def#StackUI() call go#def#StackUI()
return return
else else
let jumpTarget = a:1 let jumpTarget = a:1
endif endif
if jumpTarget !~ '^\d\+$' if jumpTarget !~ '^\d\+$'
if jumpTarget !~ '^\s*$' if jumpTarget !~ '^\s*$'
call go#util#EchoError("location must be a number") call go#util#EchoError("location must be a number")
endif endif
return return
endif endif
let jumpTarget = str2nr(jumpTarget) - 1 let jumpTarget = str2nr(jumpTarget) - 1
if jumpTarget >= 0 && jumpTarget < len(s:go_stack) if jumpTarget >= 0 && jumpTarget < len(s:go_stack)
let s:go_stack_level = jumpTarget let s:go_stack_level = jumpTarget
let target = s:go_stack[s:go_stack_level] let target = s:go_stack[s:go_stack_level]
" jump " jump
exec 'edit '.target["file"] exec 'edit '.target["file"]
call cursor(target["line"], target["col"]) call cursor(target["line"], target["col"])
normal! zz normal! zz
else else
call go#util#EchoError("invalid location. Try :GoDefStack to see the list of valid entries") call go#util#EchoError("invalid location. Try :GoDefStack to see the list of valid entries")
endif endif
endfunction endfunction
" vim: sw=2 ts=2 et

View file

@ -5,139 +5,151 @@
let s:buf_nr = -1 let s:buf_nr = -1
if !exists("g:go_doc_command") if !exists("g:go_doc_command")
let g:go_doc_command = "godoc" let g:go_doc_command = "godoc"
endif endif
if !exists("g:go_doc_options") if !exists("g:go_doc_options")
let g:go_doc_options = "" let g:go_doc_options = ""
endif endif
" returns the package and exported name. exported name might be empty. " returns the package and exported name. exported name might be empty.
" ie: fmt and Println " ie: fmt and Println
" 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')
let msg = "godoc command not found." let msg = "godoc command not found."
let msg .= " install with: go get golang.org/x/tools/cmd/godoc" let msg .= " install with: go get golang.org/x/tools/cmd/godoc"
call go#util#echoWarning(msg) call go#util#echoWarning(msg)
return [] return []
endif endif
if !len(a:args) if !len(a:args)
let oldiskeyword = &iskeyword let oldiskeyword = &iskeyword
setlocal iskeyword+=. setlocal iskeyword+=.
let word = expand('<cword>') let word = expand('<cword>')
let &iskeyword = oldiskeyword let &iskeyword = oldiskeyword
let word = substitute(word, '[^a-zA-Z0-9\\/._~-]', '', 'g') let word = substitute(word, '[^a-zA-Z0-9\\/._~-]', '', 'g')
let words = split(word, '\.\ze[^./]\+$') let words = split(word, '\.\ze[^./]\+$')
else else
let words = a:args let words = a:args
endif endif
if !len(words) if !len(words)
return [] return []
endif endif
let pkg = words[0] let pkg = words[0]
if len(words) == 1 if len(words) == 1
let exported_name = "" let exported_name = ""
else else
let exported_name = words[1] let exported_name = words[1]
endif endif
let packages = go#tool#Imports() let packages = go#tool#Imports()
if has_key(packages, pkg) if has_key(packages, pkg)
let pkg = packages[pkg] let pkg = packages[pkg]
endif endif
return [pkg, exported_name] return [pkg, exported_name]
endfunction endfunction
function! s:godocNotFound(content) function! s:godocNotFound(content)
if len(a:content) == 0 if len(a:content) == 0
return 1 return 1
endif endif
return a:content =~# '^.*: no such file or directory\n$' return a:content =~# '^.*: no such file or directory\n$'
endfunction endfunction
function! go#doc#OpenBrowser(...) function! go#doc#OpenBrowser(...)
let pkgs = s:godocWord(a:000) let pkgs = s:godocWord(a:000)
if empty(pkgs) if empty(pkgs)
return return
endif endif
let pkg = pkgs[0] let pkg = pkgs[0]
let exported_name = pkgs[1] let exported_name = pkgs[1]
" example url: https://godoc.org/github.com/fatih/set#Set " example url: https://godoc.org/github.com/fatih/set#Set
let godoc_url = "https://godoc.org/" . pkg . "#" . exported_name let godoc_url = "https://godoc.org/" . pkg . "#" . exported_name
call go#tool#OpenBrowser(godoc_url) call go#tool#OpenBrowser(godoc_url)
endfunction endfunction
function! go#doc#Open(newmode, mode, ...) function! go#doc#Open(newmode, mode, ...)
if len(a:000)
" check if we have 'godoc' and use it automatically
let bin_path = go#path#CheckBinPath('godoc')
if empty(bin_path)
return
endif
let command = printf("%s %s", bin_path, join(a:000, ' '))
else
" check if we have 'gogetdoc' and use it automatically " check if we have 'gogetdoc' and use it automatically
let bin_path = go#path#CheckBinPath('gogetdoc') let bin_path = go#path#CheckBinPath('gogetdoc')
if empty(bin_path) if empty(bin_path)
return return
endif endif
let offset = go#util#OffsetCursor() let offset = go#util#OffsetCursor()
let fname = expand("%:p") let fname = expand("%:p:gs!\\!/!")
let pos = shellescape(fname.':#'.offset)
let command = printf("%s -pos %s:#%s", bin_path, fname, offset) let command = printf("%s -pos %s", bin_path, pos)
endif
let out = go#util#System(command) let out = go#util#System(command)
if go#util#ShellError() != 0 if go#util#ShellError() != 0
call go#util#EchoError(out) call go#util#EchoError(out)
return return
endif endif
call s:GodocView(a:newmode, a:mode, out) call s:GodocView(a:newmode, a:mode, out)
endfunction endfunction
function! s:GodocView(newposition, position, content) function! s:GodocView(newposition, position, content)
" 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 a:newposition execute a:newposition
sil file `="[Godoc]"` sil file `="[Godoc]"`
let s:buf_nr = bufnr('%') let s:buf_nr = bufnr('%')
elseif bufwinnr(s:buf_nr) == -1 elseif bufwinnr(s:buf_nr) == -1
execute a:position execute a:position
execute s:buf_nr . 'buffer' execute s:buf_nr . 'buffer'
elseif bufwinnr(s:buf_nr) != bufwinnr('%') elseif bufwinnr(s:buf_nr) != bufwinnr('%')
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 " cap buffer height to 20, but resize it for smaller contents
let max_height = 20 let max_height = 20
let content_height = len(split(a:content, "\n")) let content_height = len(split(a:content, "\n"))
if content_height > max_height if content_height > max_height
exe 'resize ' . max_height exe 'resize ' . max_height
else else
exe 'resize ' . content_height exe 'resize ' . content_height
endif endif
setlocal filetype=godoc setlocal filetype=godoc
setlocal bufhidden=delete setlocal bufhidden=delete
setlocal buftype=nofile setlocal buftype=nofile
setlocal noswapfile setlocal noswapfile
setlocal nobuflisted setlocal nobuflisted
setlocal nocursorline setlocal nocursorline
setlocal nocursorcolumn setlocal nocursorcolumn
setlocal iskeyword+=: setlocal iskeyword+=:
setlocal iskeyword-=- setlocal iskeyword-=-
setlocal modifiable setlocal modifiable
%delete _ %delete _
call append(0, split(a:content, "\n")) call append(0, split(a:content, "\n"))
sil $delete _ sil $delete _
setlocal nomodifiable setlocal nomodifiable
sil normal! gg
" close easily with <esc> or enter " close easily with <esc> or enter
noremap <buffer> <silent> <CR> :<C-U>close<CR> noremap <buffer> <silent> <CR> :<C-U>close<CR>
noremap <buffer> <silent> <Esc> :<C-U>close<CR> noremap <buffer> <silent> <Esc> :<C-U>close<CR>
endfunction endfunction
" vim:ts=2:sw=2:et " vim: sw=2 ts=2 et

View file

@ -24,23 +24,23 @@
" "
if !exists("g:go_fmt_command") if !exists("g:go_fmt_command")
let g:go_fmt_command = "gofmt" let g:go_fmt_command = "gofmt"
endif endif
if !exists("g:go_goimports_bin") if !exists("g:go_goimports_bin")
let g:go_goimports_bin = "goimports" let g:go_goimports_bin = "goimports"
endif endif
if !exists('g:go_fmt_fail_silently') if !exists('g:go_fmt_fail_silently')
let g:go_fmt_fail_silently = 0 let g:go_fmt_fail_silently = 0
endif endif
if !exists('g:go_fmt_options') if !exists('g:go_fmt_options')
let g:go_fmt_options = '' let g:go_fmt_options = ''
endif endif
if !exists("g:go_fmt_experimental") if !exists("g:go_fmt_experimental")
let g:go_fmt_experimental = 0 let g:go_fmt_experimental = 0
endif endif
" we have those problems : " we have those problems :
@ -52,165 +52,159 @@ endif
" this and have VimL experience, please look at the function for " this and have VimL experience, please look at the function for
" improvements, patches are welcome :) " improvements, patches are welcome :)
function! go#fmt#Format(withGoimport) function! go#fmt#Format(withGoimport)
if g:go_fmt_experimental == 1 if g:go_fmt_experimental == 1
" Using winsaveview to save/restore cursor state has the problem of " Using winsaveview to save/restore cursor state has the problem of
" closing folds on save: " closing folds on save:
" https://github.com/fatih/vim-go/issues/502 " https://github.com/fatih/vim-go/issues/502
" One fix is to use mkview instead. Unfortunately, this sometimes causes " One fix is to use mkview instead. Unfortunately, this sometimes causes
" other bad side effects: " other bad side effects:
" https://github.com/fatih/vim-go/issues/728 " https://github.com/fatih/vim-go/issues/728
" and still closes all folds if foldlevel>0: " and still closes all folds if foldlevel>0:
" https://github.com/fatih/vim-go/issues/732 " https://github.com/fatih/vim-go/issues/732
let l:curw = {} let l:curw = {}
try try
mkview! mkview!
catch catch
let l:curw = winsaveview() let l:curw = winsaveview()
endtry endtry
else
" Save cursor position and many other things.
let l:curw = winsaveview()
endif
" Write current unsaved buffer to a temp file
let l:tmpname = tempname()
call writefile(getline(1, '$'), l:tmpname)
if g:go_fmt_experimental == 1
" save our undo file to be restored after we are done. This is needed to
" prevent an additional undo jump due to BufWritePre auto command and also
" restore 'redo' history because it's getting being destroyed every
" BufWritePre
let tmpundofile = tempname()
exe 'wundo! ' . tmpundofile
endif
" get the command first so we can test it
let bin_name = g:go_fmt_command
if a:withGoimport == 1
let bin_name = g:go_goimports_bin
endif
" check if the user has installed command binary.
" For example if it's goimports, let us check if it's installed,
" if not the user get's a warning via go#path#CheckBinPath()
let bin_path = go#path#CheckBinPath(bin_name)
if empty(bin_path)
return
endif
if bin_name != "gofmt"
" change GOPATH too, so goimports can pick up the correct library
let old_gopath = $GOPATH
let $GOPATH = go#path#Detect()
endif
" populate the final command with user based fmt options
let command = bin_path . ' -w '
if a:withGoimport != 1
let command = command . g:go_fmt_options
endif
if bin_name == "goimports"
if !exists('b:goimports_vendor_compatible')
let out = go#util#System(bin_path . " --help")
if out !~ "-srcdir"
call go#util#EchoWarning("vim-go: goimports does not support srcdir. update with: :GoUpdateBinaries")
else
let b:goimports_vendor_compatible = 1
endif
endif
if exists('b:goimports_vendor_compatible') && b:goimports_vendor_compatible
let ssl_save = &shellslash
set noshellslash
let command = command . '-srcdir ' . shellescape(expand("%:p:h"))
let &shellslash = ssl_save
endif
endif
" execute our command...
if go#util#IsWin()
let l:tmpname = tr(l:tmpname, '\', '/')
endif
let out = go#util#System(command . " " . l:tmpname)
if bin_name != "gofmt"
let $GOPATH = old_gopath
endif
let l:listtype = "locationlist"
"if there is no error on the temp file replace the output with the current
"file (if this fails, we can always check the outputs first line with:
"splitted =~ 'package \w\+')
if go#util#ShellError() == 0
" remove undo point caused via BufWritePre
try | silent undojoin | catch | endtry
" Replace current file with temp file, then reload buffer
let old_fileformat = &fileformat
call rename(l:tmpname, expand('%'))
silent edit!
let &fileformat = old_fileformat
let &syntax = &syntax
" clean up previous location list, but only if it's due to fmt
if exists('b:got_fmt_error') && b:got_fmt_error
let b:got_fmt_error = 0
call go#list#Clean(l:listtype)
call go#list#Window(l:listtype)
endif
elseif g:go_fmt_fail_silently == 0
let splitted = split(out, '\n')
"otherwise get the errors and put them to location list
let errors = []
for line in splitted
let tokens = matchlist(line, '^\(.\{-}\):\(\d\+\):\(\d\+\)\s*\(.*\)')
if !empty(tokens)
call add(errors, {"filename": @%,
\"lnum": tokens[2],
\"col": tokens[3],
\"text": tokens[4]})
endif
endfor
if empty(errors)
% | " Couldn't detect gofmt error format, output errors
endif
if !empty(errors)
call go#list#Populate(l:listtype, errors)
echohl Error | echomsg "Gofmt returned error" | echohl None
endif
let b:got_fmt_error = 1
call go#list#Window(l:listtype, len(errors))
" We didn't use the temp file, so clean up
call delete(l:tmpname)
endif
if g:go_fmt_experimental == 1
" restore our undo history
silent! exe 'rundo ' . tmpundofile
call delete(tmpundofile)
endif
if g:go_fmt_experimental == 1
" Restore our cursor/windows positions, folds, etc.
if empty(l:curw)
silent! loadview
else else
" Save cursor position and many other things. call winrestview(l:curw)
let l:curw = winsaveview()
endif
" Write current unsaved buffer to a temp file
let l:tmpname = tempname()
call writefile(getline(1, '$'), l:tmpname)
if g:go_fmt_experimental == 1
" save our undo file to be restored after we are done. This is needed to
" prevent an additional undo jump due to BufWritePre auto command and also
" restore 'redo' history because it's getting being destroyed every
" BufWritePre
let tmpundofile = tempname()
exe 'wundo! ' . tmpundofile
endif
" get the command first so we can test it
let fmt_command = g:go_fmt_command
if a:withGoimport == 1
let fmt_command = g:go_goimports_bin
endif
" check if the user has installed command binary.
" For example if it's goimports, let us check if it's installed,
" if not the user get's a warning via go#path#CheckBinPath()
let bin_path = go#path#CheckBinPath(fmt_command)
if empty(bin_path)
return
endif
if fmt_command != "gofmt"
" change GOPATH too, so goimports can pick up the correct library
let old_gopath = $GOPATH
let $GOPATH = go#path#Detect()
let fmt_command = bin_path
endif
" populate the final command with user based fmt options
let command = fmt_command . ' -w '
if a:withGoimport != 1
let command = command . g:go_fmt_options
endif
if fmt_command == "goimports"
if !exists('b:goimports_vendor_compatible')
let out = go#util#System("goimports --help")
if out !~ "-srcdir"
echohl WarningMsg
echomsg "vim-go: goimports does not support srcdir."
echomsg " update with: :GoUpdateBinaries"
echohl None
else
let b:goimports_vendor_compatible = 1
endif
endif
if exists('b:goimports_vendor_compatible') && b:goimports_vendor_compatible
let ssl_save = &shellslash
set noshellslash
let command = command . '-srcdir ' . shellescape(expand("%:p:h"))
let &shellslash = ssl_save
endif
endif
" execute our command...
if go#util#IsWin()
let l:tmpname = tr(l:tmpname, '\', '/')
endif
let out = go#util#System(command . " " . l:tmpname)
if fmt_command != "gofmt"
let $GOPATH = old_gopath
endif
let l:listtype = "locationlist"
"if there is no error on the temp file replace the output with the current
"file (if this fails, we can always check the outputs first line with:
"splitted =~ 'package \w\+')
if go#util#ShellError() == 0
" remove undo point caused via BufWritePre
try | silent undojoin | catch | endtry
" Replace current file with temp file, then reload buffer
let old_fileformat = &fileformat
call rename(l:tmpname, expand('%'))
silent edit!
let &fileformat = old_fileformat
let &syntax = &syntax
" clean up previous location list, but only if it's due to fmt
if exists('b:got_fmt_error') && b:got_fmt_error
let b:got_fmt_error = 0
call go#list#Clean(l:listtype)
call go#list#Window(l:listtype)
endif
elseif g:go_fmt_fail_silently == 0
let splitted = split(out, '\n')
"otherwise get the errors and put them to location list
let errors = []
for line in splitted
let tokens = matchlist(line, '^\(.\{-}\):\(\d\+\):\(\d\+\)\s*\(.*\)')
if !empty(tokens)
call add(errors, {"filename": @%,
\"lnum": tokens[2],
\"col": tokens[3],
\"text": tokens[4]})
endif
endfor
if empty(errors)
% | " Couldn't detect gofmt error format, output errors
endif
if !empty(errors)
call go#list#Populate(l:listtype, errors)
echohl Error | echomsg "Gofmt returned error" | echohl None
endif
let b:got_fmt_error = 1
call go#list#Window(l:listtype, len(errors))
" We didn't use the temp file, so clean up
call delete(l:tmpname)
endif
if g:go_fmt_experimental == 1
" restore our undo history
silent! exe 'rundo ' . tmpundofile
call delete(tmpundofile)
endif
if g:go_fmt_experimental == 1
" Restore our cursor/windows positions, folds, etc.
if empty(l:curw)
silent! loadview
else
call winrestview(l:curw)
endif
else
" Restore our cursor/windows positions.
call winrestview(l:curw)
endif endif
else
" Restore our cursor/windows positions.
call winrestview(l:curw)
endif
endfunction endfunction
" vim: sw=2 ts=2 et
" vim:ts=4:sw=4:et

View file

@ -1,97 +1,98 @@
" guru.vim -- Vim integration for the Go guru. " guru.vim -- Vim integration for the Go guru.
func! s:RunGuru(mode, format, selected, needs_scope) range abort func! s:RunGuru(mode, format, selected, needs_scope) range abort
"return with a warning if the binary doesn't exist "return with a warning if the binary doesn't exist
let bin_path = go#path#CheckBinPath("guru") let bin_path = go#path#CheckBinPath("guru")
if empty(bin_path) if empty(bin_path)
return {'err': "bin path not found"} return {'err': "bin path not found"}
endif
let filename = expand('%:p')
let dirname = expand('%:p:h')
let pkg = go#package#ImportPath(dirname)
" this is important, check it!
if pkg == -1 && a:needs_scope
return {'err': "current directory is not inside of a valid GOPATH"}
endif
" start constructing the 'command' variable
let command = bin_path
" enable outputting in json format
if a:format == "json"
let command .= " -json"
endif
" check for any tags
if exists('g:go_guru_tags')
let tags = get(g:, 'go_guru_tags')
let command .= printf(" -tags %s", tags)
endif
" some modes require scope to be defined (such as callers). For these we
" choose a sensible setting, which is using the current file's package
let scopes = []
if a:needs_scope
let scopes = [pkg]
endif
" check for any user defined scope setting. users can define the scope,
" in package pattern form. examples:
" golang.org/x/tools/cmd/guru # a single package
" golang.org/x/tools/... # all packages beneath dir
" ... # the entire workspace.
if exists('g:go_guru_scope')
" check that the setting is of type list
if type(get(g:, 'go_guru_scope')) != type([])
return {'err' : "go_guru_scope should of type list"}
endif endif
let filename = expand('%:p') let scopes = get(g:, 'go_guru_scope')
let dirname = expand('%:p:h') endif
let pkg = go#package#ImportPath(dirname)
" this is important, check it! " now add the scope to our command if there is any
if pkg == -1 && a:needs_scope if !empty(scopes)
return {'err': "current directory is not inside of a valid GOPATH"} " strip trailing slashes for each path in scoped. bug:
endif " https://github.com/golang/go/issues/14584
let scopes = go#util#StripTrailingSlash(scopes)
" start constructing the 'command' variable " create shell-safe entries of the list
let command = bin_path let scopes = go#util#Shelllist(scopes)
" enable outputting in json format " guru expect a comma-separated list of patterns, construct it
if a:format == "json" let scope = join(scopes, ",")
let command .= " -json" let command .= printf(" -scope %s", scope)
endif endif
" check for any tags let pos = printf("#%s", go#util#OffsetCursor())
if exists('g:go_guru_tags') if a:selected != -1
let tags = get(g:, 'go_guru_tags') " means we have a range, get it
let command .= printf(" -tags %s", tags) let pos1 = go#util#Offset(line("'<"), col("'<"))
endif let pos2 = go#util#Offset(line("'>"), col("'>"))
let pos = printf("#%s,#%s", pos1, pos2)
endif
" some modes require scope to be defined (such as callers). For these we " this is our final command
" choose a sensible setting, which is using the current file's package let filename .= ':'.pos
let scopes = [] let command .= printf(' %s %s', a:mode, shellescape(filename))
if a:needs_scope
let scopes = [pkg]
endif
" check for any user defined scope setting. users can define the scope, let old_gopath = $GOPATH
" in package pattern form. examples: let $GOPATH = go#path#Detect()
" golang.org/x/tools/cmd/guru # a single package
" golang.org/x/tools/... # all packages beneath dir
" ... # the entire workspace.
if exists('g:go_guru_scope')
" check that the setting is of type list
if type(get(g:, 'go_guru_scope')) != type([])
return {'err' : "go_guru_scope should of type list"}
endif
let scopes = get(g:, 'go_guru_scope') " the query might take time, let us give some feedback
endif call go#util#EchoProgress("analysing ...")
" now add the scope to our command if there is any " run, forrest run!!!
if !empty(scopes) let out = go#util#System(command)
" strip trailing slashes for each path in scoped. bug:
" https://github.com/golang/go/issues/14584
let scopes = go#util#StripTrailingSlash(scopes)
" create shell-safe entries of the list let $GOPATH = old_gopath
let scopes = go#util#Shelllist(scopes) if go#util#ShellError() != 0
" the output contains the error message
return {'err' : out}
endif
" guru expect a comma-separated list of patterns, construct it return {'out': out}
let scope = join(scopes, ",")
let command .= printf(" -scope %s", scope)
endif
let pos = printf("#%s", go#util#OffsetCursor())
if a:selected != -1
" means we have a range, get it
let pos1 = go#util#Offset(line("'<"), col("'<"))
let pos2 = go#util#Offset(line("'>"), col("'>"))
let pos = printf("#%s,#%s", pos1, pos2)
endif
" this is our final command
let command .= printf(' %s %s:%s', a:mode, shellescape(filename), pos)
let old_gopath = $GOPATH
let $GOPATH = go#path#Detect()
" the query might take time, let us give some feedback
call go#util#EchoProgress("analysing ...")
" run, forrest run!!!
let out = go#util#System(command)
let $GOPATH = old_gopath
if go#util#ShellError() != 0
" the output contains the error message
return {'err' : out}
endif
return {'out': out}
endfunc endfunc
" This uses Vim's errorformat to parse the output from Guru's 'plain output " This uses Vim's errorformat to parse the output from Guru's 'plain output
@ -99,205 +100,205 @@ endfunc
" easier to use. If we need more power we can always switch back to parse it " easier to use. If we need more power we can always switch back to parse it
" via regex. " via regex.
func! s:loclistSecond(output) func! s:loclistSecond(output)
" backup users errorformat, will be restored once we are finished " backup users errorformat, will be restored once we are finished
let old_errorformat = &errorformat let old_errorformat = &errorformat
" match two possible styles of errorformats: " match two possible styles of errorformats:
" "
" 'file:line.col-line2.col2: message' " 'file:line.col-line2.col2: message'
" 'file:line:col: message' " 'file:line:col: message'
" "
" We discard line2 and col2 for the first errorformat, because it's not " We discard line2 and col2 for the first errorformat, because it's not
" useful and location only has the ability to show one line and column " useful and location only has the ability to show one line and column
" number " number
let errformat = "%f:%l.%c-%[%^:]%#:\ %m,%f:%l:%c:\ %m" let errformat = "%f:%l.%c-%[%^:]%#:\ %m,%f:%l:%c:\ %m"
call go#list#ParseFormat("locationlist", errformat, split(a:output, "\n")) call go#list#ParseFormat("locationlist", errformat, split(a:output, "\n"))
let errors = go#list#Get("locationlist") let errors = go#list#Get("locationlist")
call go#list#Window("locationlist", len(errors)) call go#list#Window("locationlist", len(errors))
endfun endfun
function! go#guru#Scope(...) function! go#guru#Scope(...)
if a:0 if a:0
if a:0 == 1 && a:1 == '""' if a:0 == 1 && a:1 == '""'
unlet g:go_guru_scope unlet g:go_guru_scope
call go#util#EchoSuccess("guru scope is cleared") call go#util#EchoSuccess("guru scope is cleared")
else
let g:go_guru_scope = a:000
call go#util#EchoSuccess("guru scope changed to: ". join(a:000, ","))
endif
return
endif
if !exists('g:go_guru_scope')
call go#util#EchoError("guru scope is not set")
else else
call go#util#EchoSuccess("current guru scope: ". join(g:go_guru_scope, ",")) let g:go_guru_scope = a:000
call go#util#EchoSuccess("guru scope changed to: ". join(a:000, ","))
endif endif
return
endif
if !exists('g:go_guru_scope')
call go#util#EchoError("guru scope is not set")
else
call go#util#EchoSuccess("current guru scope: ". join(g:go_guru_scope, ","))
endif
endfunction endfunction
function! go#guru#Tags(...) function! go#guru#Tags(...)
if a:0 if a:0
if a:0 == 1 && a:1 == '""' if a:0 == 1 && a:1 == '""'
unlet g:go_guru_tags unlet g:go_guru_tags
call go#util#EchoSuccess("guru tags is cleared") call go#util#EchoSuccess("guru tags is cleared")
else
let g:go_guru_tags = a:1
call go#util#EchoSuccess("guru tags changed to: ". a:1)
endif
return
endif
if !exists('g:go_guru_tags')
call go#util#EchoSuccess("guru tags is not set")
else else
call go#util#EchoSuccess("current guru tags: ". a:1) let g:go_guru_tags = a:1
call go#util#EchoSuccess("guru tags changed to: ". a:1)
endif endif
return
endif
if !exists('g:go_guru_tags')
call go#util#EchoSuccess("guru tags is not set")
else
call go#util#EchoSuccess("current guru tags: ". a:1)
endif
endfunction endfunction
" Show 'implements' relation for selected package " Show 'implements' relation for selected package
function! go#guru#Implements(selected) function! go#guru#Implements(selected)
let out = s:RunGuru('implements', 'plain', a:selected, 1) let out = s:RunGuru('implements', 'plain', a:selected, 1)
if has_key(out, 'err') if has_key(out, 'err')
call go#util#EchoError(out.err) call go#util#EchoError(out.err)
return return
endif endif
call s:loclistSecond(out.out) call s:loclistSecond(out.out)
endfunction endfunction
" Describe selected syntax: definition, methods, etc " Describe selected syntax: definition, methods, etc
function! go#guru#Describe(selected) function! go#guru#Describe(selected)
let out = s:RunGuru('describe', 'plain', a:selected, 0) let out = s:RunGuru('describe', 'plain', a:selected, 0)
if has_key(out, 'err') if has_key(out, 'err')
call go#util#EchoError(out.err) call go#util#EchoError(out.err)
return return
endif endif
call s:loclistSecond(out.out) call s:loclistSecond(out.out)
endfunction endfunction
" Show possible targets of selected function call " Show possible targets of selected function call
function! go#guru#Callees(selected) function! go#guru#Callees(selected)
let out = s:RunGuru('callees', 'plain', a:selected, 1) let out = s:RunGuru('callees', 'plain', a:selected, 1)
if has_key(out, 'err') if has_key(out, 'err')
call go#util#EchoError(out.err) call go#util#EchoError(out.err)
return return
endif endif
call s:loclistSecond(out.out) call s:loclistSecond(out.out)
endfunction endfunction
" Show possible callers of selected function " Show possible callers of selected function
function! go#guru#Callers(selected) function! go#guru#Callers(selected)
let out = s:RunGuru('callers', 'plain', a:selected, 1) let out = s:RunGuru('callers', 'plain', a:selected, 1)
if has_key(out, 'err') if has_key(out, 'err')
call go#util#EchoError(out.err) call go#util#EchoError(out.err)
return return
endif endif
call s:loclistSecond(out.out) call s:loclistSecond(out.out)
endfunction endfunction
" Show path from callgraph root to selected function " Show path from callgraph root to selected function
function! go#guru#Callstack(selected) function! go#guru#Callstack(selected)
let out = s:RunGuru('callstack', 'plain', a:selected, 1) let out = s:RunGuru('callstack', 'plain', a:selected, 1)
if has_key(out, 'err') if has_key(out, 'err')
call go#util#EchoError(out.err) call go#util#EchoError(out.err)
return return
endif endif
call s:loclistSecond(out.out) call s:loclistSecond(out.out)
endfunction endfunction
" Show free variables of selection " Show free variables of selection
function! go#guru#Freevars(selected) function! go#guru#Freevars(selected)
" Freevars requires a selection " Freevars requires a selection
if a:selected == -1 if a:selected == -1
call go#util#EchoError("GoFreevars requires a selection (range) of code") call go#util#EchoError("GoFreevars requires a selection (range) of code")
return return
endif endif
let out = s:RunGuru('freevars', 'plain', a:selected, 0) let out = s:RunGuru('freevars', 'plain', a:selected, 0)
if has_key(out, 'err') if has_key(out, 'err')
call go#util#EchoError(out.err) call go#util#EchoError(out.err)
return return
endif endif
call s:loclistSecond(out.out) call s:loclistSecond(out.out)
endfunction endfunction
" Show send/receive corresponding to selected channel op " Show send/receive corresponding to selected channel op
function! go#guru#ChannelPeers(selected) function! go#guru#ChannelPeers(selected)
let out = s:RunGuru('peers', 'plain', a:selected, 1) let out = s:RunGuru('peers', 'plain', a:selected, 1)
if has_key(out, 'err') if has_key(out, 'err')
call go#util#EchoError(out.err) call go#util#EchoError(out.err)
return return
endif endif
call s:loclistSecond(out.out) call s:loclistSecond(out.out)
endfunction endfunction
" Show all refs to entity denoted by selected identifier " Show all refs to entity denoted by selected identifier
function! go#guru#Referrers(selected) function! go#guru#Referrers(selected)
let out = s:RunGuru('referrers', 'plain', a:selected, 0) let out = s:RunGuru('referrers', 'plain', a:selected, 0)
if has_key(out, 'err') if has_key(out, 'err')
call go#util#EchoError(out.err) call go#util#EchoError(out.err)
return return
endif endif
call s:loclistSecond(out.out) call s:loclistSecond(out.out)
endfunction endfunction
function! go#guru#What(selected) function! go#guru#What(selected)
" nvim doesn't have JSON support, though they work on it: " nvim doesn't have JSON support, though they work on it:
" https://github.com/neovim/neovim/pull/4131 " https://github.com/neovim/neovim/pull/4131
if has('nvim') if has('nvim')
return {'err': "GoWhat is not supported in Neovim"} return {'err': "GoWhat is not supported in Neovim"}
endif endif
" json_encode() and friends are introduced with this patch " json_encode() and friends are introduced with this patch
" https://groups.google.com/d/msg/vim_dev/vLupTNhQhZ8/cDGIk0JEDgAJ " https://groups.google.com/d/msg/vim_dev/vLupTNhQhZ8/cDGIk0JEDgAJ
if !has('patch-7.4.1304') if !has('patch-7.4.1304')
return {'err': "GoWhat is supported with Vim version 7.4-1304 or later"} return {'err': "GoWhat is supported with Vim version 7.4-1304 or later"}
endif endif
let out = s:RunGuru('what', 'json', a:selected, 0) let out = s:RunGuru('what', 'json', a:selected, 0)
if has_key(out, 'err') if has_key(out, 'err')
return out.err return out.err
endif endif
call s:loclistSecond(out.out) call s:loclistSecond(out.out)
let result = json_decode(out.out) let result = json_decode(out.out)
if type(result) != type({}) if type(result) != type({})
return {'err': "malformed output from guru"} return {'err': "malformed output from guru"}
endif endif
if !has_key(result, 'what') if !has_key(result, 'what')
return {'err': "no what query found for the given identifier"} return {'err': "no what query found for the given identifier"}
endif endif
return {'out': result.what} return {'out': result.what}
endfunction endfunction
function! go#guru#SameIds(selected) function! go#guru#SameIds(selected)
let result = go#guru#What(a:selected) let result = go#guru#What(a:selected)
if has_key(out, 'err') if has_key(out, 'err')
call go#util#EchoError(out.err) call go#util#EchoError(out.err)
return return
endif endif
if !has_key(result.out, 'sameids') if !has_key(result.out, 'sameids')
call go#util#EchoError("no same_ids founds for the given identifier") call go#util#EchoError("no same_ids founds for the given identifier")
return -1 return -1
endif endif
let same_ids = result.what.sameids let same_ids = result.what.sameids
echo same_ids echo same_ids
endfunction endfunction
" vim:ts=4:sw=4:et " vim: sw=2 ts=2 et

View file

@ -1,124 +1,126 @@
function! go#impl#Impl(...) function! go#impl#Impl(...)
let binpath = go#path#CheckBinPath('impl') let binpath = go#path#CheckBinPath('impl')
if empty(binpath) if empty(binpath)
return return
endif
let recv = ""
let iface = ""
if a:0 == 0
" user didn't passed anything, just called ':GoImpl'
let receiveType = expand("<cword>")
let recv = printf("%s *%s", tolower(receiveType)[0], receiveType)
let iface = input("vim-go: generating method stubs for interface: ")
redraw!
if empty(iface)
call go#util#EchoError('usage: interface type is not provided')
return
endif endif
elseif a:0 == 1
" we assume the user only passed the interface type,
" i.e: ':GoImpl io.Writer'
let receiveType = expand("<cword>")
let recv = printf("%s *%s", tolower(receiveType)[0], receiveType)
let iface = a:1
elseif a:0 > 2
" user passed receiver and interface type both,
" i.e: 'GoImpl f *Foo io.Writer'
let recv = join(a:000[:-2], ' ')
let iface = a:000[-1]
else
call go#util#EchoError('usage: GoImpl {receiver} {interface}')
return
endif
let recv = "" let result = go#util#System(printf("%s '%s' '%s'", binpath, recv, iface))
let iface = "" if go#util#ShellError() != 0
call go#util#EchoError(result)
return
endif
if a:0 == 0 if result ==# ''
" user didn't passed anything, just called ':GoImpl' return
let receiveType = expand("<cword>") end
let recv = printf("%s *%s", tolower(receiveType)[0], receiveType)
let iface = input("vim-go: generating method stubs for interface: ")
redraw!
if empty(iface)
call go#util#EchoError('usage: interface type is not provided')
return
endif
elseif a:0 == 1
" we assume the user only passed the interface type,
" i.e: ':GoImpl io.Writer'
let receiveType = expand("<cword>")
let recv = printf("%s *%s", tolower(receiveType)[0], receiveType)
let iface = a:1
elseif a:0 > 2
" user passed receiver and interface type both,
" i.e: 'GoImpl f *Foo io.Writer'
let recv = join(a:000[:-2], ' ')
let iface = a:000[-1]
else
call go#util#EchoError('usage: GoImpl {receiver} {interface}')
return
endif
let result = go#util#System(printf("%s '%s' '%s'", binpath, recv, iface)) let pos = getpos('.')
if go#util#ShellError() != 0 put =''
call go#util#EchoError(result) put =result
return call setpos('.', pos)
endif
if result ==# ''
return
end
let pos = getpos('.')
put =''
put =result
call setpos('.', pos)
endfunction endfunction
if exists('*uniq') if exists('*uniq')
function! s:uniq(list) function! s:uniq(list)
return uniq(a:list) return uniq(a:list)
endfunction endfunction
else else
" Note: Believe that the list is sorted " Note: Believe that the list is sorted
function! s:uniq(list) function! s:uniq(list)
let i = len(a:list) - 1 let i = len(a:list) - 1
while 0 < i while 0 < i
if a:list[i-1] ==# a:list[i] if a:list[i-1] ==# a:list[i]
call remove(a:list, i) call remove(a:list, i)
let i -= 2 let i -= 2
else else
let i -= 1 let i -= 1
endif endif
endwhile endwhile
return a:list return a:list
endfunction endfunction
endif endif
function! s:root_dirs() function! s:root_dirs()
let dirs = [] let dirs = []
let root = go#util#GOROOT() let root = go#util#GOROOT()
if root !=# '' && isdirectory(root) if root !=# '' && isdirectory(root)
call add(dirs, root) call add(dirs, root)
endif endif
let paths = map(split(go#util#GOPATH(), go#util#PathListSep()), "substitute(v:val, '\\\\', '/', 'g')") let paths = map(split(go#util#GOPATH(), go#util#PathListSep()), "substitute(v:val, '\\\\', '/', 'g')")
if go#util#ShellError() if go#util#ShellError()
return [] return []
endif endif
if !empty(filter(paths, 'isdirectory(v:val)')) if !empty(filter(paths, 'isdirectory(v:val)'))
call extend(dirs, paths) call extend(dirs, paths)
endif endif
return dirs return dirs
endfunction endfunction
function! s:go_packages(dirs) function! s:go_packages(dirs)
let pkgs = [] let pkgs = []
for d in a:dirs for d in a:dirs
let pkg_root = expand(d . '/pkg/' . go#util#OSARCH()) let pkg_root = expand(d . '/pkg/' . go#util#OSARCH())
call extend(pkgs, split(globpath(pkg_root, '**/*.a', 1), "\n")) call extend(pkgs, split(globpath(pkg_root, '**/*.a', 1), "\n"))
endfor endfor
return map(pkgs, "fnamemodify(v:val, ':t:r')") return map(pkgs, "fnamemodify(v:val, ':t:r')")
endfunction endfunction
function! s:interface_list(pkg) function! s:interface_list(pkg)
let contents = split(go#util#System('go doc ' . a:pkg), "\n") let contents = split(go#util#System('go doc ' . a:pkg), "\n")
if go#util#ShellError() if go#util#ShellError()
return [] return []
endif endif
call filter(contents, 'v:val =~# ''^type\s\+\h\w*\s\+interface''') call filter(contents, 'v:val =~# ''^type\s\+\h\w*\s\+interface''')
return map(contents, 'a:pkg . "." . matchstr(v:val, ''^type\s\+\zs\h\w*\ze\s\+interface'')') return map(contents, 'a:pkg . "." . matchstr(v:val, ''^type\s\+\zs\h\w*\ze\s\+interface'')')
endfunction endfunction
" Complete package and interface for {interface} " Complete package and interface for {interface}
function! go#impl#Complete(arglead, cmdline, cursorpos) function! go#impl#Complete(arglead, cmdline, cursorpos)
let words = split(a:cmdline, '\s\+', 1) let words = split(a:cmdline, '\s\+', 1)
if words[-1] ==# '' if words[-1] ==# ''
return s:uniq(sort(s:go_packages(s:root_dirs()))) return s:uniq(sort(s:go_packages(s:root_dirs())))
elseif words[-1] =~# '^\h\w*$' elseif words[-1] =~# '^\h\w*$'
return s:uniq(sort(filter(s:go_packages(s:root_dirs()), 'stridx(v:val, words[-1]) == 0'))) return s:uniq(sort(filter(s:go_packages(s:root_dirs()), 'stridx(v:val, words[-1]) == 0')))
elseif words[-1] =~# '^\h\w*\.\%(\h\w*\)\=$' elseif words[-1] =~# '^\h\w*\.\%(\h\w*\)\=$'
let [pkg, interface] = split(words[-1], '\.', 1) let [pkg, interface] = split(words[-1], '\.', 1)
echomsg pkg echomsg pkg
return s:uniq(sort(filter(s:interface_list(pkg), 'v:val =~? words[-1]'))) return s:uniq(sort(filter(s:interface_list(pkg), 'v:val =~? words[-1]')))
else else
return [] return []
endif endif
endfunction endfunction
" vim: sw=2 ts=2 et

View file

@ -5,209 +5,209 @@
" Check out the docs for more information at /doc/vim-go.txt " Check out the docs for more information at /doc/vim-go.txt
" "
function! go#import#SwitchImport(enabled, localname, path, bang) function! go#import#SwitchImport(enabled, localname, path, bang)
let view = winsaveview() let view = winsaveview()
let path = substitute(a:path, '^\s*\(.\{-}\)\s*$', '\1', '') let path = substitute(a:path, '^\s*\(.\{-}\)\s*$', '\1', '')
" Quotes are not necessary, so remove them if provided. " Quotes are not necessary, so remove them if provided.
if path[0] == '"' if path[0] == '"'
let path = strpart(path, 1) let path = strpart(path, 1)
endif endif
if path[len(path)-1] == '"' if path[len(path)-1] == '"'
let path = strpart(path, 0, len(path) - 1) let path = strpart(path, 0, len(path) - 1)
endif
" if given a trailing slash, eg. `github.com/user/pkg/`, remove it
if path[len(path)-1] == '/'
let path = strpart(path, 0, len(path) - 1)
endif
if path == ''
call s:Error('Import path not provided')
return
endif
if a:bang == "!"
let out = go#util#System("go get -u -v ".shellescape(path))
if go#util#ShellError() != 0
call s:Error("Can't find import: " . path . ":" . out)
endif endif
endif
let exists = go#tool#Exists(path)
if exists == -1
call s:Error("Can't find import: " . path)
return
endif
" if given a trailing slash, eg. `github.com/user/pkg/`, remove it " Extract any site prefix (e.g. github.com/).
if path[len(path)-1] == '/' " If other imports with the same prefix are grouped separately,
let path = strpart(path, 0, len(path) - 1) " we will add this new import with them.
endif " Only up to and including the first slash is used.
let siteprefix = matchstr(path, "^[^/]*/")
if path == '' let qpath = '"' . path . '"'
call s:Error('Import path not provided') if a:localname != ''
return let qlocalpath = a:localname . ' ' . qpath
endif else
let qlocalpath = qpath
endif
let indentstr = 0
let packageline = -1 " Position of package name statement
let appendline = -1 " Position to introduce new import
let deleteline = -1 " Position of line with existing import
let linesdelta = 0 " Lines added/removed
if a:bang == "!" " Find proper place to add/remove import.
let out = go#util#System("go get -u -v ".shellescape(path)) let line = 0
if go#util#ShellError() != 0 while line <= line('$')
call s:Error("Can't find import: " . path . ":" . out) let linestr = getline(line)
endif
endif
let exists = go#tool#Exists(path)
if exists == -1
call s:Error("Can't find import: " . path)
return
endif
" Extract any site prefix (e.g. github.com/). if linestr =~# '^package\s'
" If other imports with the same prefix are grouped separately, let packageline = line
" we will add this new import with them. let appendline = line
" Only up to and including the first slash is used.
let siteprefix = matchstr(path, "^[^/]*/")
let qpath = '"' . path . '"' elseif linestr =~# '^import\s\+('
if a:localname != '' let appendstr = qlocalpath
let qlocalpath = a:localname . ' ' . qpath let indentstr = 1
else let appendline = line
let qlocalpath = qpath let firstblank = -1
endif let lastprefix = ""
let indentstr = 0 while line <= line("$")
let packageline = -1 " Position of package name statement
let appendline = -1 " Position to introduce new import
let deleteline = -1 " Position of line with existing import
let linesdelta = 0 " Lines added/removed
" Find proper place to add/remove import.
let line = 0
while line <= line('$')
let linestr = getline(line)
if linestr =~# '^package\s'
let packageline = line
let appendline = line
elseif linestr =~# '^import\s\+('
let appendstr = qlocalpath
let indentstr = 1
let appendline = line
let firstblank = -1
let lastprefix = ""
while line <= line("$")
let line = line + 1
let linestr = getline(line)
let m = matchlist(getline(line), '^\()\|\(\s\+\)\(\S*\s*\)"\(.\+\)"\)')
if empty(m)
if siteprefix == "" && a:enabled
" must be in the first group
break
endif
" record this position, but keep looking
if firstblank < 0
let firstblank = line
endif
continue
endif
if m[1] == ')'
" if there's no match, add it to the first group
if appendline < 0 && firstblank >= 0
let appendline = firstblank
endif
break
endif
let lastprefix = matchstr(m[4], "^[^/]*/")
if a:localname != '' && m[3] != ''
let qlocalpath = printf('%-' . (len(m[3])-1) . 's %s', a:localname, qpath)
endif
let appendstr = m[2] . qlocalpath
let indentstr = 0
if m[4] == path
let appendline = -1
let deleteline = line
break
elseif m[4] < path
" don't set candidate position if we have a site prefix,
" we've passed a blank line, and this doesn't share the same
" site prefix.
if siteprefix == "" || firstblank < 0 || match(m[4], "^" . siteprefix) >= 0
let appendline = line
endif
elseif siteprefix != "" && match(m[4], "^" . siteprefix) >= 0
" first entry of site group
let appendline = line - 1
break
endif
endwhile
break
elseif linestr =~# '^import '
if appendline == packageline
let appendstr = 'import ' . qlocalpath
let appendline = line - 1
endif
let m = matchlist(linestr, '^import\(\s\+\)\(\S*\s*\)"\(.\+\)"')
if !empty(m)
if m[3] == path
let appendline = -1
let deleteline = line
break
endif
if m[3] < path
let appendline = line
endif
if a:localname != '' && m[2] != ''
let qlocalpath = printf("%s %" . len(m[2])-1 . "s", a:localname, qpath)
endif
let appendstr = 'import' . m[1] . qlocalpath
endif
elseif linestr =~# '^\(var\|const\|type\|func\)\>'
break
endif
let line = line + 1 let line = line + 1
endwhile let linestr = getline(line)
let m = matchlist(getline(line), '^\()\|\(\s\+\)\(\S*\s*\)"\(.\+\)"\)')
" Append or remove the package import, as requested. if empty(m)
if a:enabled if siteprefix == "" && a:enabled
if deleteline != -1 " must be in the first group
call s:Error(qpath . ' already being imported') break
elseif appendline == -1 endif
call s:Error('No package line found') " record this position, but keep looking
else if firstblank < 0
if appendline == packageline let firstblank = line
call append(appendline + 0, '') endif
call append(appendline + 1, 'import (') continue
call append(appendline + 2, ')')
let appendline += 2
let linesdelta += 3
let appendstr = qlocalpath
let indentstr = 1
endif
call append(appendline, appendstr)
execute appendline + 1
if indentstr
execute 'normal! >>'
endif
let linesdelta += 1
endif endif
if m[1] == ')'
" if there's no match, add it to the first group
if appendline < 0 && firstblank >= 0
let appendline = firstblank
endif
break
endif
let lastprefix = matchstr(m[4], "^[^/]*/")
if a:localname != '' && m[3] != ''
let qlocalpath = printf('%-' . (len(m[3])-1) . 's %s', a:localname, qpath)
endif
let appendstr = m[2] . qlocalpath
let indentstr = 0
if m[4] == path
let appendline = -1
let deleteline = line
break
elseif m[4] < path
" don't set candidate position if we have a site prefix,
" we've passed a blank line, and this doesn't share the same
" site prefix.
if siteprefix == "" || firstblank < 0 || match(m[4], "^" . siteprefix) >= 0
let appendline = line
endif
elseif siteprefix != "" && match(m[4], "^" . siteprefix) >= 0
" first entry of site group
let appendline = line - 1
break
endif
endwhile
break
elseif linestr =~# '^import '
if appendline == packageline
let appendstr = 'import ' . qlocalpath
let appendline = line - 1
endif
let m = matchlist(linestr, '^import\(\s\+\)\(\S*\s*\)"\(.\+\)"')
if !empty(m)
if m[3] == path
let appendline = -1
let deleteline = line
break
endif
if m[3] < path
let appendline = line
endif
if a:localname != '' && m[2] != ''
let qlocalpath = printf("%s %" . len(m[2])-1 . "s", a:localname, qpath)
endif
let appendstr = 'import' . m[1] . qlocalpath
endif
elseif linestr =~# '^\(var\|const\|type\|func\)\>'
break
endif
let line = line + 1
endwhile
" Append or remove the package import, as requested.
if a:enabled
if deleteline != -1
call s:Error(qpath . ' already being imported')
elseif appendline == -1
call s:Error('No package line found')
else else
if deleteline == -1 if appendline == packageline
call s:Error(qpath . ' not being imported') call append(appendline + 0, '')
else call append(appendline + 1, 'import (')
execute deleteline . 'd' call append(appendline + 2, ')')
let linesdelta -= 1 let appendline += 2
let linesdelta += 3
if getline(deleteline-1) =~# '^import\s\+(' && getline(deleteline) =~# '^)' let appendstr = qlocalpath
" Delete empty import block let indentstr = 1
let deleteline -= 1 endif
execute deleteline . "d" call append(appendline, appendstr)
execute deleteline . "d" execute appendline + 1
let linesdelta -= 2 if indentstr
endif execute 'normal! >>'
endif
if getline(deleteline) == '' && getline(deleteline - 1) == '' let linesdelta += 1
" Delete spacing for removed line too.
execute deleteline . "d"
let linesdelta -= 1
endif
endif
endif endif
else
if deleteline == -1
call s:Error(qpath . ' not being imported')
else
execute deleteline . 'd'
let linesdelta -= 1
" Adjust view for any changes. if getline(deleteline-1) =~# '^import\s\+(' && getline(deleteline) =~# '^)'
let view.lnum += linesdelta " Delete empty import block
let view.topline += linesdelta let deleteline -= 1
if view.topline < 0 execute deleteline . "d"
let view.topline = 0 execute deleteline . "d"
let linesdelta -= 2
endif
if getline(deleteline) == '' && getline(deleteline - 1) == ''
" Delete spacing for removed line too.
execute deleteline . "d"
let linesdelta -= 1
endif
endif endif
endif
" Put buffer back where it was. " Adjust view for any changes.
call winrestview(view) let view.lnum += linesdelta
let view.topline += linesdelta
if view.topline < 0
let view.topline = 0
endif
" Put buffer back where it was.
call winrestview(view)
endfunction endfunction
function! s:Error(s) function! s:Error(s)
echohl Error | echo a:s | echohl None echohl Error | echo a:s | echohl None
endfunction endfunction
" vim:ts=4:sw=4:et " vim: sw=2 ts=2 et

View file

@ -115,6 +115,11 @@ 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
let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd ' : 'cd '
let dir = getcwd()
execute cd self.dir
call s:callback_handlers_on_exit(s:jobs[a:job_id], a:exit_status, std_combined) 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
@ -123,21 +128,18 @@ function! s:on_exit(job_id, exit_status)
let self.state = "SUCCESS" let self.state = "SUCCESS"
call go#util#EchoSuccess("SUCCESS") call go#util#EchoSuccess("SUCCESS")
execute cd . fnameescape(dir)
return return
endif endif
let self.state = "FAILED" let self.state = "FAILED"
call go#util#EchoError("FAILED") call go#util#EchoError("FAILED")
let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd ' : 'cd ' let errors = go#tool#ParseErrors(std_combined)
let dir = getcwd() let errors = go#tool#FilterValids(errors)
try
execute cd self.dir execute cd . fnameescape(dir)
let errors = go#tool#ParseErrors(std_combined)
let errors = go#tool#FilterValids(errors)
finally
execute cd . fnameescape(dir)
endtry
if !len(errors) if !len(errors)
" failed to parse errors, output the original content " failed to parse errors, output the original content
@ -209,4 +211,4 @@ function! s:abort(path)
endfor endfor
endfunction endfunction
" vim:ts=2:sw=2:et " vim: sw=2 ts=2 et

View file

@ -1,199 +1,199 @@
if !exists("g:go_metalinter_command") if !exists("g:go_metalinter_command")
let g:go_metalinter_command = "" let g:go_metalinter_command = ""
endif endif
if !exists("g:go_metalinter_autosave_enabled") if !exists("g:go_metalinter_autosave_enabled")
let g:go_metalinter_autosave_enabled = ['vet', 'golint'] let g:go_metalinter_autosave_enabled = ['vet', 'golint']
endif endif
if !exists("g:go_metalinter_enabled") if !exists("g:go_metalinter_enabled")
let g:go_metalinter_enabled = ['vet', 'golint', 'errcheck'] let g:go_metalinter_enabled = ['vet', 'golint', 'errcheck']
endif endif
if !exists("g:go_metalinter_deadline") if !exists("g:go_metalinter_deadline")
let g:go_metalinter_deadline = "5s" let g:go_metalinter_deadline = "5s"
endif endif
if !exists("g:go_golint_bin") if !exists("g:go_golint_bin")
let g:go_golint_bin = "golint" let g:go_golint_bin = "golint"
endif endif
if !exists("g:go_errcheck_bin") if !exists("g:go_errcheck_bin")
let g:go_errcheck_bin = "errcheck" let g:go_errcheck_bin = "errcheck"
endif endif
function! go#lint#Gometa(autosave, ...) abort function! go#lint#Gometa(autosave, ...) abort
if a:0 == 0 if a:0 == 0
let goargs = expand('%:p:h') let goargs = shellescape(expand('%:p:h'))
else else
let goargs = go#util#Shelljoin(a:000) let goargs = go#util#Shelljoin(a:000)
endif
let meta_command = "gometalinter --disable-all"
if a:autosave || empty(g:go_metalinter_command)
let bin_path = go#path#CheckBinPath("gometalinter")
if empty(bin_path)
return
endif endif
let meta_command = "gometalinter --disable-all" if a:autosave
if a:autosave || empty(g:go_metalinter_command) " include only messages for the active buffer
let bin_path = go#path#CheckBinPath("gometalinter") let meta_command .= " --include='^" . expand('%:p') . ".*$'"
if empty(bin_path)
return
endif
if a:autosave
" include only messages for the active buffer
let meta_command .= " --include='^" . expand('%:p') . ".*$'"
endif
" linters
let linters = a:autosave ? g:go_metalinter_autosave_enabled : g:go_metalinter_enabled
for linter in linters
let meta_command .= " --enable=".linter
endfor
" deadline
let meta_command .= " --deadline=" . g:go_metalinter_deadline
" path
let meta_command .= " " . goargs
else
" the user wants something else, let us use it.
let meta_command = g:go_metalinter_command
endif endif
" comment out the following two lines for debugging " linters
" echo meta_command let linters = a:autosave ? g:go_metalinter_autosave_enabled : g:go_metalinter_enabled
" return for linter in linters
let meta_command .= " --enable=".linter
endfor
let out = go#tool#ExecuteInDir(meta_command) " deadline
let meta_command .= " --deadline=" . g:go_metalinter_deadline
let l:listtype = "quickfix" " path
if go#util#ShellError() == 0 let meta_command .= " " . goargs
redraw | echo else
call go#list#Clean(l:listtype) " the user wants something else, let us use it.
call go#list#Window(l:listtype) let meta_command = g:go_metalinter_command
echon "vim-go: " | echohl Function | echon "[metalinter] PASS" | echohl None endif
else
" GoMetaLinter can output one of the two, so we look for both:
" <file>:<line>:[<column>]: <message> (<linter>)
" <file>:<line>:: <message> (<linter>)
" This can be defined by the following errorformat:
let errformat = "%f:%l:%c:%t%*[^:]:\ %m,%f:%l::%t%*[^:]:\ %m"
" Parse and populate our location list " comment out the following two lines for debugging
call go#list#ParseFormat(l:listtype, errformat, split(out, "\n")) " echo meta_command
" return
let errors = go#list#Get(l:listtype) let out = go#tool#ExecuteInDir(meta_command)
call go#list#Window(l:listtype, len(errors))
if !a:autosave let l:listtype = "quickfix"
call go#list#JumpToFirst(l:listtype) if go#util#ShellError() == 0
endif redraw | echo
call go#list#Clean(l:listtype)
call go#list#Window(l:listtype)
echon "vim-go: " | echohl Function | echon "[metalinter] PASS" | echohl None
else
" GoMetaLinter can output one of the two, so we look for both:
" <file>:<line>:[<column>]: <message> (<linter>)
" <file>:<line>:: <message> (<linter>)
" This can be defined by the following errorformat:
let errformat = "%f:%l:%c:%t%*[^:]:\ %m,%f:%l::%t%*[^:]:\ %m"
" Parse and populate our location list
call go#list#ParseFormat(l:listtype, errformat, split(out, "\n"))
let errors = go#list#Get(l:listtype)
call go#list#Window(l:listtype, len(errors))
if !a:autosave
call go#list#JumpToFirst(l:listtype)
endif endif
endif
endfunction endfunction
" Golint calls 'golint' on the current directory. Any warnings are populated in " Golint calls 'golint' on the current directory. Any warnings are populated in
" the location list " the location list
function! go#lint#Golint(...) abort function! go#lint#Golint(...) abort
let bin_path = go#path#CheckBinPath(g:go_golint_bin) let bin_path = go#path#CheckBinPath(g:go_golint_bin)
if empty(bin_path) if empty(bin_path)
return return
endif endif
if a:0 == 0 if a:0 == 0
let goargs = shellescape(expand('%')) let goargs = shellescape(expand('%'))
else else
let goargs = go#util#Shelljoin(a:000) let goargs = go#util#Shelljoin(a:000)
endif endif
let out = go#util#System(bin_path . " " . goargs) let out = go#util#System(bin_path . " " . goargs)
if empty(out) if empty(out)
echon "vim-go: " | echohl Function | echon "[lint] PASS" | echohl None echon "vim-go: " | echohl Function | echon "[lint] PASS" | echohl None
return return
endif endif
let l:listtype = "quickfix" let l:listtype = "quickfix"
call go#list#Parse(l:listtype, out) call go#list#Parse(l:listtype, out)
let errors = go#list#Get(l:listtype) let errors = go#list#Get(l:listtype)
call go#list#Window(l:listtype, len(errors)) call go#list#Window(l:listtype, len(errors))
call go#list#JumpToFirst(l:listtype) call go#list#JumpToFirst(l:listtype)
endfunction endfunction
" Vet calls 'go vet' on the current directory. Any warnings are populated in " Vet calls 'go vet' on the current directory. Any warnings are populated in
" the location list " the location list
function! go#lint#Vet(bang, ...) function! go#lint#Vet(bang, ...)
call go#cmd#autowrite() call go#cmd#autowrite()
echon "vim-go: " | echohl Identifier | echon "calling vet..." | echohl None echon "vim-go: " | echohl Identifier | echon "calling vet..." | echohl None
if a:0 == 0 if a:0 == 0
let out = go#tool#ExecuteInDir('go vet') let out = go#tool#ExecuteInDir('go vet')
else else
let out = go#tool#ExecuteInDir('go tool vet ' . go#util#Shelljoin(a:000)) let out = go#tool#ExecuteInDir('go tool vet ' . go#util#Shelljoin(a:000))
endif endif
let l:listtype = "quickfix" let l:listtype = "quickfix"
if go#util#ShellError() != 0 if go#util#ShellError() != 0
let errors = go#tool#ParseErrors(split(out, '\n')) let errors = go#tool#ParseErrors(split(out, '\n'))
call go#list#Populate(l:listtype, errors) call go#list#Populate(l:listtype, errors)
call go#list#Window(l:listtype, len(errors)) call go#list#Window(l:listtype, len(errors))
if !empty(errors) && !a:bang if !empty(errors) && !a:bang
call go#list#JumpToFirst(l:listtype) call go#list#JumpToFirst(l:listtype)
endif
echon "vim-go: " | echohl ErrorMsg | echon "[vet] FAIL" | echohl None
else
call go#list#Clean(l:listtype)
call go#list#Window(l:listtype)
redraw | echon "vim-go: " | echohl Function | echon "[vet] PASS" | echohl None
endif endif
echon "vim-go: " | echohl ErrorMsg | echon "[vet] FAIL" | echohl None
else
call go#list#Clean(l:listtype)
call go#list#Window(l:listtype)
redraw | echon "vim-go: " | echohl Function | echon "[vet] PASS" | echohl None
endif
endfunction endfunction
" ErrCheck calls 'errcheck' for the given packages. Any warnings are populated in " ErrCheck calls 'errcheck' for the given packages. Any warnings are populated in
" the location list " the location list
function! go#lint#Errcheck(...) abort function! go#lint#Errcheck(...) abort
if a:0 == 0 if a:0 == 0
let goargs = go#package#ImportPath(expand('%:p:h')) let goargs = go#package#ImportPath(expand('%:p:h'))
if goargs == -1 if goargs == -1
echohl Error | echomsg "vim-go: package is not inside GOPATH src" | echohl None echohl Error | echomsg "vim-go: package is not inside GOPATH src" | echohl None
return return
endif endif
else else
let goargs = go#util#Shelljoin(a:000) let goargs = go#util#Shelljoin(a:000)
endif
let bin_path = go#path#CheckBinPath(g:go_errcheck_bin)
if empty(bin_path)
return
endif
echon "vim-go: " | echohl Identifier | echon "errcheck analysing ..." | echohl None
redraw
let command = bin_path . ' -abspath ' . goargs
let out = go#tool#ExecuteInDir(command)
let l:listtype = "quickfix"
if go#util#ShellError() != 0
let errformat = "%f:%l:%c:\ %m, %f:%l:%c\ %#%m"
" Parse and populate our location list
call go#list#ParseFormat(l:listtype, errformat, split(out, "\n"))
let errors = go#list#Get(l:listtype)
if empty(errors)
echohl Error | echomsg "GoErrCheck returned error" | echohl None
echo out
return
endif endif
let bin_path = go#path#CheckBinPath(g:go_errcheck_bin) if !empty(errors)
if empty(bin_path) call go#list#Populate(l:listtype, errors)
return call go#list#Window(l:listtype, len(errors))
endif if !empty(errors)
call go#list#JumpToFirst(l:listtype)
echon "vim-go: " | echohl Identifier | echon "errcheck analysing ..." | echohl None endif
redraw
let command = bin_path . ' -abspath ' . goargs
let out = go#tool#ExecuteInDir(command)
let l:listtype = "quickfix"
if go#util#ShellError() != 0
let errformat = "%f:%l:%c:\ %m, %f:%l:%c\ %#%m"
" Parse and populate our location list
call go#list#ParseFormat(l:listtype, errformat, split(out, "\n"))
let errors = go#list#Get(l:listtype)
if empty(errors)
echohl Error | echomsg "GoErrCheck returned error" | echohl None
echo out
return
endif
if !empty(errors)
call go#list#Populate(l:listtype, errors)
call go#list#Window(l:listtype, len(errors))
if !empty(errors)
call go#list#JumpToFirst(l:listtype)
endif
endif
else
call go#list#Clean(l:listtype)
call go#list#Window(l:listtype)
echon "vim-go: " | echohl Function | echon "[errcheck] PASS" | echohl None
endif endif
else
call go#list#Clean(l:listtype)
call go#list#Window(l:listtype)
echon "vim-go: " | echohl Function | echon "[errcheck] PASS" | echohl None
endif
endfunction endfunction
" vim:ts=4:sw=4:et " vim: sw=2 ts=2 et

View file

@ -1,126 +1,126 @@
if !exists("g:go_list_type") if !exists("g:go_list_type")
let g:go_list_type = "" let g:go_list_type = ""
endif endif
" Window opens the list with the given height up to 10 lines maximum. " Window opens the list with the given height up to 10 lines maximum.
" Otherwise g:go_loclist_height is used. If no or zero height is given it " Otherwise g:go_loclist_height is used. If no or zero height is given it
" closes the window " closes the window
function! go#list#Window(listtype, ...) function! go#list#Window(listtype, ...)
let l:listtype = go#list#Type(a:listtype) let l:listtype = go#list#Type(a:listtype)
" we don't use lwindow to close the location list as we need also the " we don't use lwindow to close the location list as we need also the
" ability to resize the window. So, we are going to use lopen and lclose " ability to resize the window. So, we are going to use lopen and lclose
" for a better user experience. If the number of errors in a current " for a better user experience. If the number of errors in a current
" location list increases/decreases, cwindow will not resize when a new " location list increases/decreases, cwindow will not resize when a new
" updated height is passed. lopen in the other hand resizes the screen. " updated height is passed. lopen in the other hand resizes the screen.
if !a:0 || a:1 == 0 if !a:0 || a:1 == 0
if l:listtype == "locationlist"
lclose
else
cclose
endif
return
endif
let height = get(g:, "go_list_height", 0)
if height == 0
" prevent creating a large location height for a large set of numbers
if a:1 > 10
let height = 10
else
let height = a:1
endif
endif
if l:listtype == "locationlist" if l:listtype == "locationlist"
exe 'lopen ' . height lclose
else else
exe 'copen ' . height cclose
endif endif
return
endif
let height = get(g:, "go_list_height", 0)
if height == 0
" prevent creating a large location height for a large set of numbers
if a:1 > 10
let height = 10
else
let height = a:1
endif
endif
if l:listtype == "locationlist"
exe 'lopen ' . height
else
exe 'copen ' . height
endif
endfunction endfunction
" Get returns the current list of items from the location list " Get returns the current list of items from the location list
function! go#list#Get(listtype) function! go#list#Get(listtype)
let l:listtype = go#list#Type(a:listtype) let l:listtype = go#list#Type(a:listtype)
if l:listtype == "locationlist" if l:listtype == "locationlist"
return getloclist(0) return getloclist(0)
else else
return getqflist() return getqflist()
endif endif
endfunction endfunction
" Populate populate the location list with the given items " Populate populate the location list with the given items
function! go#list#Populate(listtype, items) function! go#list#Populate(listtype, items)
let l:listtype = go#list#Type(a:listtype) let l:listtype = go#list#Type(a:listtype)
if l:listtype == "locationlist" if l:listtype == "locationlist"
call setloclist(0, a:items, 'r') call setloclist(0, a:items, 'r')
else else
call setqflist(a:items, 'r') call setqflist(a:items, 'r')
endif endif
endfunction endfunction
function! go#list#PopulateWin(winnr, items) function! go#list#PopulateWin(winnr, items)
call setloclist(a:winnr, a:items, 'r') call setloclist(a:winnr, a:items, 'r')
endfunction endfunction
" Parse parses the given items based on the specified errorformat nad " Parse parses the given items based on the specified errorformat nad
" populates the location list. " populates the location list.
function! go#list#ParseFormat(listtype, errformat, items) function! go#list#ParseFormat(listtype, errformat, items)
let l:listtype = go#list#Type(a:listtype) let l:listtype = go#list#Type(a:listtype)
" backup users errorformat, will be restored once we are finished " backup users errorformat, will be restored once we are finished
let old_errorformat = &errorformat let old_errorformat = &errorformat
" parse and populate the location list " parse and populate the location list
let &errorformat = a:errformat let &errorformat = a:errformat
if l:listtype == "locationlist" if l:listtype == "locationlist"
lgetexpr a:items lgetexpr a:items
else else
cgetexpr a:items cgetexpr a:items
endif endif
"restore back "restore back
let &errorformat = old_errorformat let &errorformat = old_errorformat
endfunction endfunction
" Parse parses the given items based on the global errorformat and " Parse parses the given items based on the global errorformat and
" populates the location list. " populates the location list.
function! go#list#Parse(listtype, items) function! go#list#Parse(listtype, items)
let l:listtype = go#list#Type(a:listtype) let l:listtype = go#list#Type(a:listtype)
if l:listtype == "locationlist" if l:listtype == "locationlist"
lgetexpr a:items lgetexpr a:items
else else
cgetexpr a:items cgetexpr a:items
endif endif
endfunction endfunction
" JumpToFirst jumps to the first item in the location list " JumpToFirst jumps to the first item in the location list
function! go#list#JumpToFirst(listtype) function! go#list#JumpToFirst(listtype)
let l:listtype = go#list#Type(a:listtype) let l:listtype = go#list#Type(a:listtype)
if l:listtype == "locationlist" if l:listtype == "locationlist"
ll 1 ll 1
else else
cc 1 cc 1
endif endif
endfunction endfunction
" Clean cleans the location list " Clean cleans the location list
function! go#list#Clean(listtype) function! go#list#Clean(listtype)
let l:listtype = go#list#Type(a:listtype) let l:listtype = go#list#Type(a:listtype)
if l:listtype == "locationlist" if l:listtype == "locationlist"
lex [] lex []
else else
cex [] cex []
endif endif
endfunction endfunction
function! go#list#Type(listtype) function! go#list#Type(listtype)
if g:go_list_type == "locationlist" if g:go_list_type == "locationlist"
return "locationlist" return "locationlist"
elseif g:go_list_type == "quickfix" elseif g:go_list_type == "quickfix"
return "quickfix" return "quickfix"
else else
return a:listtype return a:listtype
endif endif
endfunction endfunction
" vim:ts=4:sw=4:et " vim: sw=2 ts=2 et

View file

@ -9,120 +9,120 @@ let s:goos = $GOOS
let s:goarch = $GOARCH let s:goarch = $GOARCH
if len(s:goos) == 0 if len(s:goos) == 0
if exists('g:golang_goos') if exists('g:golang_goos')
let s:goos = g:golang_goos let s:goos = g:golang_goos
elseif has('win32') || has('win64') elseif has('win32') || has('win64')
let s:goos = 'windows' let s:goos = 'windows'
elseif has('macunix') elseif has('macunix')
let s:goos = 'darwin' let s:goos = 'darwin'
else else
let s:goos = '*' let s:goos = '*'
endif endif
endif endif
if len(s:goarch) == 0 if len(s:goarch) == 0
if exists('g:golang_goarch') if exists('g:golang_goarch')
let s:goarch = g:golang_goarch let s:goarch = g:golang_goarch
else else
let s:goarch = '*' let s:goarch = '*'
endif endif
endif endif
function! go#package#Paths() function! go#package#Paths()
let dirs = [] let dirs = []
if !exists("s:goroot") if !exists("s:goroot")
if executable('go') if executable('go')
let s:goroot = substitute(go#util#System('go env GOROOT'), '\n', '', 'g') let s:goroot = substitute(go#util#System('go env GOROOT'), '\n', '', 'g')
if go#util#ShellError() != 0 if go#util#ShellError() != 0
echomsg '''go env GOROOT'' failed' echomsg '''go env GOROOT'' failed'
endif endif
else else
let s:goroot = $GOROOT let s:goroot = $GOROOT
endif
endif endif
endif
if len(s:goroot) != 0 && isdirectory(s:goroot) if len(s:goroot) != 0 && isdirectory(s:goroot)
let dirs += [s:goroot] let dirs += [s:goroot]
endif endif
let workspaces = split($GOPATH, go#util#PathListSep()) let workspaces = split(go#path#Detect(), go#util#PathListSep())
if workspaces != [] if workspaces != []
let dirs += workspaces let dirs += workspaces
endif endif
return dirs return dirs
endfunction endfunction
function! go#package#ImportPath(arg) function! go#package#ImportPath(arg)
let path = fnamemodify(resolve(a:arg), ':p') let path = fnamemodify(resolve(a:arg), ':p')
let dirs = go#package#Paths() let dirs = go#package#Paths()
for dir in dirs for dir in dirs
if len(dir) && match(path, dir) == 0 if len(dir) && match(path, dir) == 0
let workspace = dir let workspace = dir
endif
endfor
if !exists('workspace')
return -1
endif endif
endfor
let srcdir = substitute(workspace . '/src/', '//', '/', '') if !exists('workspace')
return substitute(path, srcdir, '', '') return -1
endif
let srcdir = substitute(workspace . '/src/', '//', '/', '')
return substitute(path, srcdir, '', '')
endfunction endfunction
function! go#package#FromPath(arg) function! go#package#FromPath(arg)
let path = fnamemodify(resolve(a:arg), ':p') let path = fnamemodify(resolve(a:arg), ':p')
let dirs = go#package#Paths() let dirs = go#package#Paths()
for dir in dirs for dir in dirs
if len(dir) && match(path, dir) == 0 if len(dir) && match(path, dir) == 0
let workspace = dir let workspace = dir
endif
endfor
if !exists('workspace')
return -1
endif endif
endfor
if isdirectory(path) if !exists('workspace')
return substitute(path, workspace . 'src/', '', '') return -1
else endif
return substitute(substitute(path, workspace . 'src/', '', ''),
\ '/' . fnamemodify(path, ':t'), '', '') if isdirectory(path)
endif return substitute(path, workspace . 'src/', '', '')
else
return substitute(substitute(path, workspace . 'src/', '', ''),
\ '/' . fnamemodify(path, ':t'), '', '')
endif
endfunction endfunction
function! go#package#CompleteMembers(package, member) function! go#package#CompleteMembers(package, member)
silent! let content = go#util#System('godoc ' . a:package) silent! let content = go#util#System('godoc ' . a:package)
if go#util#ShellError() || !len(content) if go#util#ShellError() || !len(content)
return [] return []
endif endif
let lines = filter(split(content, "\n"),"v:val !~ '^\\s\\+$'") let lines = filter(split(content, "\n"),"v:val !~ '^\\s\\+$'")
try try
let mx1 = '^\s\+\(\S+\)\s\+=\s\+.*' let mx1 = '^\s\+\(\S+\)\s\+=\s\+.*'
let mx2 = '^\%(const\|var\|type\|func\) \([A-Z][^ (]\+\).*' let mx2 = '^\%(const\|var\|type\|func\) \([A-Z][^ (]\+\).*'
let candidates = map(filter(copy(lines), 'v:val =~ mx1'), let candidates = map(filter(copy(lines), 'v:val =~ mx1'),
\ 'substitute(v:val, mx1, "\\1", "")') \ 'substitute(v:val, mx1, "\\1", "")')
\ + map(filter(copy(lines), 'v:val =~ mx2'), \ + map(filter(copy(lines), 'v:val =~ mx2'),
\ 'substitute(v:val, mx2, "\\1", "")') \ 'substitute(v:val, mx2, "\\1", "")')
return filter(candidates, '!stridx(v:val, a:member)') return filter(candidates, '!stridx(v:val, a:member)')
catch catch
return [] return []
endtry endtry
endfunction endfunction
function! go#package#Complete(ArgLead, CmdLine, CursorPos) function! go#package#Complete(ArgLead, CmdLine, CursorPos)
let words = split(a:CmdLine, '\s\+', 1) let words = split(a:CmdLine, '\s\+', 1)
" do not complete package members for these commands " do not complete package members for these commands
let neglect_commands = ["GoImportAs", "GoGuruScope"] let neglect_commands = ["GoImportAs", "GoGuruScope"]
if len(words) > 2 && index(neglect_commands, words[0]) == -1 if len(words) > 2 && index(neglect_commands, words[0]) == -1
" Complete package members " Complete package members
return go#package#CompleteMembers(words[1], words[2]) return go#package#CompleteMembers(words[1], words[2])
endif endif
let dirs = go#package#Paths() let dirs = go#package#Paths()
@ -157,4 +157,4 @@ function! go#package#Complete(ArgLead, CmdLine, CursorPos)
return sort(keys(ret)) return sort(keys(ret))
endfunction endfunction
" vim:sw=4:et " vim: sw=2 ts=2 et

View file

@ -9,60 +9,60 @@ let s:initial_go_path = ""
" GOPATH with it. If two double quotes are passed (the empty string in go), " GOPATH with it. If two double quotes are passed (the empty string in go),
" it'll clear the GOPATH and will restore to the initial GOPATH. " it'll clear the GOPATH and will restore to the initial GOPATH.
function! go#path#GoPath(...) function! go#path#GoPath(...)
" we have an argument, replace GOPATH " we have an argument, replace GOPATH
if len(a:000) if len(a:000)
" clears the current manually set GOPATH and restores it to the " clears the current manually set GOPATH and restores it to the
" initial GOPATH, which was set when Vim was started. " initial GOPATH, which was set when Vim was started.
if len(a:000) == 1 && a:1 == '""' if len(a:000) == 1 && a:1 == '""'
if !empty(s:initial_go_path) if !empty(s:initial_go_path)
let $GOPATH = s:initial_go_path let $GOPATH = s:initial_go_path
let s:initial_go_path = "" let s:initial_go_path = ""
endif endif
echon "vim-go: " | echohl Function | echon "GOPATH restored to ". $GOPATH | echohl None echon "vim-go: " | echohl Function | echon "GOPATH restored to ". $GOPATH | echohl None
return return
endif
echon "vim-go: " | echohl Function | echon "GOPATH changed to ". a:1 | echohl None
let s:initial_go_path = $GOPATH
let $GOPATH = a:1
return
endif endif
echo go#path#Detect() echon "vim-go: " | echohl Function | echon "GOPATH changed to ". a:1 | echohl None
let s:initial_go_path = $GOPATH
let $GOPATH = a:1
return
endif
echo go#path#Detect()
endfunction endfunction
" Default returns the default GOPATH. If there is a single GOPATH it returns " Default returns the default GOPATH. If there is a single GOPATH it returns
" it. For multiple GOPATHS separated with a the OS specific separator, only " it. For multiple GOPATHS separated with a the OS specific separator, only
" the first one is returned " the first one is returned
function! go#path#Default() function! go#path#Default()
let go_paths = split($GOPATH, go#util#PathListSep()) let go_paths = split($GOPATH, go#util#PathListSep())
if len(go_paths) == 1 if len(go_paths) == 1
return $GOPATH return $GOPATH
endif endif
return go_paths[0] return go_paths[0]
endfunction endfunction
" HasPath checks whether the given path exists in GOPATH environment variable " HasPath checks whether the given path exists in GOPATH environment variable
" or not " or not
function! go#path#HasPath(path) function! go#path#HasPath(path)
let go_paths = split($GOPATH, go#util#PathListSep()) let go_paths = split($GOPATH, go#util#PathListSep())
let last_char = strlen(a:path) - 1 let last_char = strlen(a:path) - 1
" check cases of '/foo/bar/' and '/foo/bar' " check cases of '/foo/bar/' and '/foo/bar'
if a:path[last_char] == go#util#PathSep() if a:path[last_char] == go#util#PathSep()
let withSep = a:path let withSep = a:path
let noSep = strpart(a:path, 0, last_char) let noSep = strpart(a:path, 0, last_char)
else else
let withSep = a:path . go#util#PathSep() let withSep = a:path . go#util#PathSep()
let noSep = a:path let noSep = a:path
endif endif
let hasA = index(go_paths, withSep) != -1 let hasA = index(go_paths, withSep) != -1
let hasB = index(go_paths, noSep) != -1 let hasB = index(go_paths, noSep) != -1
return hasA || hasB return hasA || hasB
endfunction endfunction
" Detect returns the current GOPATH. If a package manager is used, such as " Detect returns the current GOPATH. If a package manager is used, such as
@ -70,60 +70,60 @@ endfunction
" over the current GOPATH. It also detects diretories whose are outside " over the current GOPATH. It also detects diretories whose are outside
" GOPATH. " GOPATH.
function! go#path#Detect() function! go#path#Detect()
let gopath = $GOPATH let gopath = $GOPATH
" don't lookup for godeps if autodetect is disabled.
if !get(g:, "go_autodetect_gopath", 1)
return gopath
endif
let current_dir = fnameescape(expand('%:p:h'))
" TODO(arslan): this should be changed so folders or files should be
" fetched from a customizable list. The user should define any new package
" management tool by it's own.
" src folder outside $GOPATH
let src_root = finddir("src", current_dir .";")
if !empty(src_root)
let src_path = fnamemodify(src_root, ':p:h:h') . go#util#PathSep()
" gb vendor plugin
" (https://github.com/constabulary/gb/tree/master/cmd/gb-vendor)
let gb_vendor_root = src_path . "vendor" . go#util#PathSep()
if isdirectory(gb_vendor_root) && !go#path#HasPath(gb_vendor_root)
let gopath = gb_vendor_root . go#util#PathListSep() . gopath
endif
if !go#path#HasPath(src_path)
let gopath = src_path . go#util#PathListSep() . gopath
endif
endif
" Godeps
let godeps_root = finddir("Godeps", current_dir .";")
if !empty(godeps_root)
let godeps_path = join([fnamemodify(godeps_root, ':p:h:h'), "Godeps", "_workspace" ], go#util#PathSep())
if !go#path#HasPath(godeps_path)
let gopath = godeps_path . go#util#PathListSep() . gopath
endif
endif
" don't lookup for godeps if autodetect is disabled.
if !get(g:, "go_autodetect_gopath", 1)
return gopath return gopath
endif
let current_dir = fnameescape(expand('%:p:h'))
" TODO(arslan): this should be changed so folders or files should be
" fetched from a customizable list. The user should define any new package
" management tool by it's own.
" src folder outside $GOPATH
let src_root = finddir("src", current_dir .";")
if !empty(src_root)
let src_path = fnamemodify(src_root, ':p:h:h') . go#util#PathSep()
" gb vendor plugin
" (https://github.com/constabulary/gb/tree/master/cmd/gb-vendor)
let gb_vendor_root = src_path . "vendor" . go#util#PathSep()
if isdirectory(gb_vendor_root) && !go#path#HasPath(gb_vendor_root)
let gopath = gb_vendor_root . go#util#PathListSep() . gopath
endif
if !go#path#HasPath(src_path)
let gopath = src_path . go#util#PathListSep() . gopath
endif
endif
" Godeps
let godeps_root = finddir("Godeps", current_dir .";")
if !empty(godeps_root)
let godeps_path = join([fnamemodify(godeps_root, ':p:h:h'), "Godeps", "_workspace" ], go#util#PathSep())
if !go#path#HasPath(godeps_path)
let gopath = godeps_path . go#util#PathListSep() . gopath
endif
endif
return gopath
endfunction endfunction
" BinPath returns the binary path of installed go tools. " BinPath returns the binary path of installed go tools.
function! go#path#BinPath() function! go#path#BinPath()
let bin_path = "" let bin_path = ""
" check if our global custom path is set, if not check if $GOBIN is set so " check if our global custom path is set, if not check if $GOBIN is set so
" we can use it, otherwise use $GOPATH + '/bin' " we can use it, otherwise use $GOPATH + '/bin'
if exists("g:go_bin_path") if exists("g:go_bin_path")
let bin_path = g:go_bin_path let bin_path = g:go_bin_path
elseif $GOBIN != "" elseif $GOBIN != ""
let bin_path = $GOBIN let bin_path = $GOBIN
elseif $GOPATH != "" elseif $GOPATH != ""
let bin_path = expand(go#path#Default() . "/bin/") let bin_path = expand(go#path#Default() . "/bin/")
else else
@ -151,6 +151,9 @@ function! go#path#CheckBinPath(binpath)
" if it's in PATH just return it " if it's in PATH just return it
if executable(binpath) if executable(binpath)
if v:version == 704 && has('patch235')
let binpath = exepath(binpath)
endif
let $PATH = old_path let $PATH = old_path
return binpath return binpath
endif endif
@ -169,4 +172,4 @@ function! go#path#CheckBinPath(binpath)
return go_bin_path . go#util#PathSep() . basename return go_bin_path . go#util#PathSep() . basename
endfunction endfunction
" vim:ts=4:sw=4:et " vim: sw=2 ts=2 et

View file

@ -1,54 +1,54 @@
if !exists("g:go_play_open_browser") if !exists("g:go_play_open_browser")
let g:go_play_open_browser = 1 let g:go_play_open_browser = 1
endif endif
function! go#play#Share(count, line1, line2) function! go#play#Share(count, line1, line2)
if !executable('curl') if !executable('curl')
echohl ErrorMsg | echomsg "vim-go: require 'curl' command" | echohl None echohl ErrorMsg | echomsg "vim-go: require 'curl' command" | echohl None
return return
endif endif
let content = join(getline(a:line1, a:line2), "\n") let content = join(getline(a:line1, a:line2), "\n")
let share_file = tempname() let share_file = tempname()
call writefile(split(content, "\n"), share_file, "b") call writefile(split(content, "\n"), share_file, "b")
let command = "curl -s -X POST https://play.golang.org/share --data-binary '@".share_file."'" let command = "curl -s -X POST https://play.golang.org/share --data-binary '@".share_file."'"
let snippet_id = go#util#System(command) let snippet_id = go#util#System(command)
" we can remove the temp file because it's now posted. " we can remove the temp file because it's now posted.
call delete(share_file) call delete(share_file)
if go#util#ShellError() != 0 if go#util#ShellError() != 0
echo 'A error has occured. Run this command to see what the problem is:' echo 'A error has occured. Run this command to see what the problem is:'
echo command echo command
return return
endif endif
let url = "http://play.golang.org/p/".snippet_id let url = "http://play.golang.org/p/".snippet_id
" copy to clipboard " copy to clipboard
if has('unix') && !has('xterm_clipboard') && !has('clipboard') if has('unix') && !has('xterm_clipboard') && !has('clipboard')
let @" = url let @" = url
else else
let @+ = url let @+ = url
endif endif
if g:go_play_open_browser != 0 if g:go_play_open_browser != 0
call go#tool#OpenBrowser(url) call go#tool#OpenBrowser(url)
endif endif
echo "vim-go: snippet uploaded: ".url echo "vim-go: snippet uploaded: ".url
endfunction endfunction
function! s:get_visual_content() function! s:get_visual_content()
let save_regcont = @" let save_regcont = @"
let save_regtype = getregtype('"') let save_regtype = getregtype('"')
silent! normal! gvy silent! normal! gvy
let content = @" let content = @"
call setreg('"', save_regcont, save_regtype) call setreg('"', save_regcont, save_regtype)
return content return content
endfunction endfunction
" modified version of " modified version of
@ -56,39 +56,38 @@ endfunction
" another function that returns the content of visual selection, it's not used " another function that returns the content of visual selection, it's not used
" but might be useful in the future " but might be useful in the future
function! s:get_visual_selection() function! s:get_visual_selection()
let [lnum1, col1] = getpos("'<")[1:2] let [lnum1, col1] = getpos("'<")[1:2]
let [lnum2, col2] = getpos("'>")[1:2] let [lnum2, col2] = getpos("'>")[1:2]
" check if the the visual mode is used before " check if the the visual mode is used before
if lnum1 == 0 || lnum2 == 0 || col1 == 0 || col2 == 0 if lnum1 == 0 || lnum2 == 0 || col1 == 0 || col2 == 0
return return
endif endif
let lines = getline(lnum1, lnum2) let lines = getline(lnum1, lnum2)
let lines[-1] = lines[-1][: col2 - (&selection == 'inclusive' ? 1 : 2)] let lines[-1] = lines[-1][: col2 - (&selection == 'inclusive' ? 1 : 2)]
let lines[0] = lines[0][col1 - 1:] let lines[0] = lines[0][col1 - 1:]
return join(lines, "\n") return join(lines, "\n")
endfunction endfunction
" following two functions are from: https://github.com/mattn/gist-vim " following two functions are from: https://github.com/mattn/gist-vim
" thanks @mattn " thanks @mattn
function! s:get_browser_command() function! s:get_browser_command()
let go_play_browser_command = get(g:, 'go_play_browser_command', '') let go_play_browser_command = get(g:, 'go_play_browser_command', '')
if go_play_browser_command == '' if go_play_browser_command == ''
if has('win32') || has('win64') if has('win32') || has('win64')
let go_play_browser_command = '!start rundll32 url.dll,FileProtocolHandler %URL%' let go_play_browser_command = '!start rundll32 url.dll,FileProtocolHandler %URL%'
elseif has('mac') || has('macunix') || has('gui_macvim') || go#util#System('uname') =~? '^darwin' elseif has('mac') || has('macunix') || has('gui_macvim') || go#util#System('uname') =~? '^darwin'
let go_play_browser_command = 'open %URL%' let go_play_browser_command = 'open %URL%'
elseif executable('xdg-open') elseif executable('xdg-open')
let go_play_browser_command = 'xdg-open %URL%' let go_play_browser_command = 'xdg-open %URL%'
elseif executable('firefox') elseif executable('firefox')
let go_play_browser_command = 'firefox %URL% &' let go_play_browser_command = 'firefox %URL% &'
else else
let go_play_browser_command = '' let go_play_browser_command = ''
endif
endif endif
return go_play_browser_command endif
return go_play_browser_command
endfunction endfunction
" vim: sw=2 ts=2 et
" vim:ts=4:sw=4:et

View file

@ -1,69 +1,77 @@
if !exists("g:go_gorename_bin") if !exists("g:go_gorename_bin")
let g:go_gorename_bin = "gorename" let g:go_gorename_bin = "gorename"
endif endif
if !exists("g:go_gorename_prefill") if !exists("g:go_gorename_prefill")
let g:go_gorename_prefill = 1 let g:go_gorename_prefill = 1
endif endif
function! go#rename#Rename(bang, ...) function! go#rename#Rename(bang, ...)
let to = "" let to = ""
if a:0 == 0 if a:0 == 0
let from = expand("<cword>") let from = expand("<cword>")
let ask = printf("vim-go: rename '%s' to: ", from) let ask = printf("vim-go: rename '%s' to: ", from)
if g:go_gorename_prefill if g:go_gorename_prefill
let to = input(ask, from) let to = input(ask, from)
else
let to = input(ask)
endif
redraw!
if empty(to)
return
endif
else else
let to = a:1 let to = input(ask)
endif endif
redraw!
"return with a warning if the bin doesn't exist if empty(to)
let bin_path = go#path#CheckBinPath(g:go_gorename_bin) return
if empty(bin_path)
return
endif endif
else
let to = a:1
endif
let fname = expand('%:p') "return with a warning if the bin doesn't exist
let pos = go#util#OffsetCursor() let bin_path = go#path#CheckBinPath(g:go_gorename_bin)
let cmd = printf('%s -offset %s -to %s', shellescape(bin_path), shellescape(printf('%s:#%d', fname, pos)), shellescape(to)) if empty(bin_path)
return
endif
let out = go#tool#ExecuteInDir(cmd) let fname = expand('%:p')
let pos = go#util#OffsetCursor()
let cmd = printf('%s -offset %s -to %s', shellescape(bin_path), shellescape(printf('%s:#%d', fname, pos)), shellescape(to))
" strip out newline on the end that gorename puts. If we don't remove, it let out = go#tool#ExecuteInDir(cmd)
" will trigger the 'Hit ENTER to continue' prompt
let clean = split(out, '\n')
let l:listtype = "quickfix" " reload all files to reflect the new changes. We explicitly call
if go#util#ShellError() != 0 " checktime to trigger a reload of all files. See
let errors = go#tool#ParseErrors(split(out, '\n')) " http://www.mail-archive.com/vim@vim.org/msg05900.html for more info
call go#list#Populate(l:listtype, errors) " about the autoread bug
call go#list#Window(l:listtype, len(errors)) let current_autoread = &autoread
if !empty(errors) && !a:bang set autoread
call go#list#JumpToFirst(l:listtype) silent! checktime
elseif empty(errors) let &autoread = current_autoread
" failed to parse errors, output the original content
call go#util#EchoError(out) " strip out newline on the end that gorename puts. If we don't remove, it
endif " will trigger the 'Hit ENTER to continue' prompt
return let clean = split(out, '\n')
else
call go#list#Clean(l:listtype) let l:listtype = "quickfix"
call go#list#Window(l:listtype) if go#util#ShellError() != 0
redraw | echon "vim-go: " | echohl Function | echon clean[0] | echohl None 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)
elseif empty(errors)
" failed to parse errors, output the original content
call go#util#EchoError(out)
endif endif
return
else
call go#list#Clean(l:listtype)
call go#list#Window(l:listtype)
redraw | echon "vim-go: " | echohl Function | echon clean[0] | echohl None
endif
" refresh the buffer so we can see the new content " refresh the buffer so we can see the new content
" TODO(arslan): also find all other buffers and refresh them too. For this " TODO(arslan): also find all other buffers and refresh them too. For this
" we need a way to get the list of changes from gorename upon an success " we need a way to get the list of changes from gorename upon an success
" change. " change.
silent execute ":e" silent execute ":e"
endfunction endfunction
" vim:ts=4:sw=4:et " vim: sw=2 ts=2 et
"

View file

@ -1,5 +1,5 @@
if has('nvim') && !exists("g:go_term_mode") if has('nvim') && !exists("g:go_term_mode")
let g:go_term_mode = 'vsplit' let g:go_term_mode = 'vsplit'
endif endif
" s:jobs is a global reference to all jobs started with new() " s:jobs is a global reference to all jobs started with new()
@ -8,121 +8,121 @@ let s:jobs = {}
" new creates a new terminal with the given command. Mode is set based on the " new creates a new terminal with the given command. Mode is set based on the
" global variable g:go_term_mode, which is by default set to :vsplit " global variable g:go_term_mode, which is by default set to :vsplit
function! go#term#new(bang, cmd) function! go#term#new(bang, cmd)
return go#term#newmode(a:bang, a:cmd, g:go_term_mode) return go#term#newmode(a:bang, a:cmd, g:go_term_mode)
endfunction endfunction
" new creates a new terminal with the given command and window mode. " new creates a new terminal with the given command and window mode.
function! go#term#newmode(bang, cmd, mode) function! go#term#newmode(bang, cmd, mode)
let mode = a:mode let mode = a:mode
if empty(mode) if empty(mode)
let mode = g:go_term_mode let mode = g:go_term_mode
endif endif
" modify GOPATH if needed " modify GOPATH if needed
let old_gopath = $GOPATH let old_gopath = $GOPATH
let $GOPATH = go#path#Detect() let $GOPATH = go#path#Detect()
" execute go build in the files directory " execute go build in the files directory
let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd ' : 'cd ' let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd ' : 'cd '
let dir = getcwd() let dir = getcwd()
execute cd . fnameescape(expand("%:p:h")) execute cd . fnameescape(expand("%:p:h"))
execute mode.' __go_term__' execute mode.' __go_term__'
setlocal filetype=goterm setlocal filetype=goterm
setlocal bufhidden=delete setlocal bufhidden=delete
setlocal winfixheight setlocal winfixheight
setlocal noswapfile setlocal noswapfile
setlocal nobuflisted setlocal nobuflisted
let job = { let job = {
\ 'stderr' : [], \ 'stderr' : [],
\ 'stdout' : [], \ 'stdout' : [],
\ 'bang' : a:bang, \ 'bang' : a:bang,
\ 'on_stdout': function('s:on_stdout'), \ 'on_stdout': function('s:on_stdout'),
\ 'on_stderr': function('s:on_stderr'), \ 'on_stderr': function('s:on_stderr'),
\ 'on_exit' : function('s:on_exit'), \ 'on_exit' : function('s:on_exit'),
\ } \ }
let id = termopen(a:cmd, job) let id = termopen(a:cmd, job)
execute cd . fnameescape(dir) execute cd . fnameescape(dir)
" restore back GOPATH " restore back GOPATH
let $GOPATH = old_gopath let $GOPATH = old_gopath
let job.id = id let job.id = id
startinsert startinsert
" resize new term if needed. " resize new term if needed.
let height = get(g:, 'go_term_height', winheight(0)) let height = get(g:, 'go_term_height', winheight(0))
let width = get(g:, 'go_term_width', winwidth(0)) let width = get(g:, 'go_term_width', winwidth(0))
" we are careful how to resize. for example it's vertical we don't change " we are careful how to resize. for example it's vertical we don't change
" the height. The below command resizes the buffer " the height. The below command resizes the buffer
if a:mode == "split" if a:mode == "split"
exe 'resize ' . height exe 'resize ' . height
elseif a:mode == "vertical" elseif a:mode == "vertical"
exe 'vertical resize ' . width exe 'vertical resize ' . width
endif endif
" we also need to resize the pty, so there you go... " we also need to resize the pty, so there you go...
call jobresize(id, width, height) call jobresize(id, width, height)
let s:jobs[id] = job let s:jobs[id] = job
return id return id
endfunction endfunction
function! s:on_stdout(job_id, data) function! s:on_stdout(job_id, data)
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]
call extend(job.stdout, a:data) call extend(job.stdout, a:data)
endfunction endfunction
function! s:on_stderr(job_id, data) function! s:on_stderr(job_id, data)
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]
call extend(job.stderr, a:data) call extend(job.stderr, a:data)
endfunction endfunction
function! s:on_exit(job_id, exit_status) 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)
unlet s:jobs[a:job_id] unlet s:jobs[a:job_id]
return return
endif endif
let errors = go#tool#ParseErrors(job.stdout) let errors = go#tool#ParseErrors(job.stdout)
let errors = go#tool#FilterValids(errors) let errors = go#tool#FilterValids(errors)
if !empty(errors) if !empty(errors)
" close terminal we don't need it anymore " close terminal we don't need it anymore
close close
call go#list#Populate(l:listtype, errors) call go#list#Populate(l:listtype, errors)
call go#list#Window(l:listtype, len(errors)) call go#list#Window(l:listtype, len(errors))
if !self.bang if !self.bang
call go#list#JumpToFirst(l:listtype) call go#list#JumpToFirst(l:listtype)
endif
unlet s:jobs[a:job_id]
return
endif endif
unlet s:jobs[a:job_id]
return
endif
" tests are passing clean the list and close the list. But we only can " 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 " close them from a normal view, so jump back, close the list and then
@ -135,4 +135,4 @@ function! s:on_exit(job_id, exit_status)
unlet s:jobs[a:job_id] unlet s:jobs[a:job_id]
endfunction endfunction
" vim:ts=4:sw=4:et " vim: sw=2 ts=2 et

View file

@ -16,7 +16,7 @@ endif
function! go#textobj#Function(mode) function! go#textobj#Function(mode)
let offset = go#util#OffsetCursor() let offset = go#util#OffsetCursor()
let fname = expand("%:p") let fname = shellescape(expand("%:p"))
if &modified if &modified
" Write current unsaved buffer to a temp file and use the modified content " Write current unsaved buffer to a temp file and use the modified content
let l:tmpname = tempname() let l:tmpname = tempname()
@ -103,7 +103,7 @@ function! go#textobj#FunctionJump(mode, direction)
let offset = go#util#OffsetCursor() let offset = go#util#OffsetCursor()
let fname = expand("%:p") let fname = shellescape(expand("%:p"))
if &modified if &modified
" Write current unsaved buffer to a temp file and use the modified content " Write current unsaved buffer to a temp file and use the modified content
let l:tmpname = tempname() let l:tmpname = tempname()
@ -177,4 +177,4 @@ function! go#textobj#FunctionJump(mode, direction)
keepjumps call cursor(info.func.line, 1) keepjumps call cursor(info.func.line, 1)
endfunction endfunction
" vim:ts=2:sw=2:et " vim: sw=2 ts=2 et

View file

@ -1,126 +1,129 @@
function! go#tool#Files() function! go#tool#Files()
if go#util#IsWin() if go#util#IsWin()
let command = 'go list -f "{{range $f := .GoFiles}}{{$.Dir}}\{{$f}}{{printf \"\n\"}}{{end}}{{range $f := .CgoFiles}}{{$.Dir}}\{{$f}}{{printf \"\n\"}}{{end}}"' let format = '{{range $f := .GoFiles}}{{$.Dir}}\{{$f}}{{printf \"\n\"}}{{end}}{{range $f := .CgoFiles}}{{$.Dir}}\{{$f}}{{printf \"\n\"}}{{end}}'
else else
let command = "go list -f '{{range $f := .GoFiles}}{{$.Dir}}/{{$f}}{{printf \"\\n\"}}{{end}}{{range $f := .CgoFiles}}{{$.Dir}}/{{$f}}{{printf \"\\n\"}}{{end}}'" let format = "{{range $f := .GoFiles}}{{$.Dir}}/{{$f}}{{printf \"\\n\"}}{{end}}{{range $f := .CgoFiles}}{{$.Dir}}/{{$f}}{{printf \"\\n\"}}{{end}}"
endif endif
let out = go#tool#ExecuteInDir(command) let command = 'go list -f '.shellescape(format)
return split(out, '\n') let out = go#tool#ExecuteInDir(command)
return split(out, '\n')
endfunction endfunction
function! go#tool#Deps() function! go#tool#Deps()
if go#util#IsWin() if go#util#IsWin()
let command = 'go list -f "{{range $f := .Deps}}{{$f}}{{printf \"\n\"}}{{end}}"' let format = '{{range $f := .Deps}}{{$f}}{{printf \"\n\"}}{{end}}'
else else
let command = "go list -f $'{{range $f := .Deps}}{{$f}}\n{{end}}'" let format = "{{range $f := .Deps}}{{$f}}\n{{end}}"
endif endif
let out = go#tool#ExecuteInDir(command) let command = 'go list -f '.shellescape(format)
return split(out, '\n') let out = go#tool#ExecuteInDir(command)
return split(out, '\n')
endfunction endfunction
function! go#tool#Imports() function! go#tool#Imports()
let imports = {} let imports = {}
if go#util#IsWin() if go#util#IsWin()
let command = 'go list -f "{{range $f := .Imports}}{{$f}}{{printf \"\n\"}}{{end}}"' let format = '{{range $f := .Imports}}{{$f}}{{printf \"\n\"}}{{end}}'
else else
let command = "go list -f $'{{range $f := .Imports}}{{$f}}\n{{end}}'" let format = "{{range $f := .Imports}}{{$f}}{{printf \"\\n\"}}{{end}}"
endif endif
let out = go#tool#ExecuteInDir(command) let command = 'go list -f '.shellescape(format)
if go#util#ShellError() != 0 let out = go#tool#ExecuteInDir(command)
echo out if go#util#ShellError() != 0
return imports echo out
endif
for package_path in split(out, '\n')
let cmd = "go list -f {{.Name}} " . package_path
let package_name = substitute(go#tool#ExecuteInDir(cmd), '\n$', '', '')
let imports[package_name] = package_path
endfor
return imports return imports
endif
for package_path in split(out, '\n')
let cmd = "go list -f '{{.Name}}' " . shellescape(package_path)
let package_name = substitute(go#tool#ExecuteInDir(cmd), '\n$', '', '')
let imports[package_name] = package_path
endfor
return imports
endfunction endfunction
function! go#tool#ParseErrors(lines) function! go#tool#ParseErrors(lines)
let errors = [] let errors = []
for line in a:lines for line in a:lines
let fatalerrors = matchlist(line, '^\(fatal error:.*\)$') let fatalerrors = matchlist(line, '^\(fatal error:.*\)$')
let tokens = matchlist(line, '^\s*\(.\{-}\):\(\d\+\):\s*\(.*\)') let tokens = matchlist(line, '^\s*\(.\{-}\):\(\d\+\):\s*\(.*\)')
if !empty(fatalerrors) if !empty(fatalerrors)
call add(errors, {"text": fatalerrors[1]}) call add(errors, {"text": fatalerrors[1]})
elseif !empty(tokens) elseif !empty(tokens)
" strip endlines of form ^M " strip endlines of form ^M
let out = substitute(tokens[3], '\r$', '', '') let out = substitute(tokens[3], '\r$', '', '')
call add(errors, { call add(errors, {
\ "filename" : fnamemodify(tokens[1], ':p'), \ "filename" : fnamemodify(tokens[1], ':p'),
\ "lnum" : tokens[2], \ "lnum" : tokens[2],
\ "text" : out, \ "text" : out,
\ }) \ })
elseif !empty(errors) elseif !empty(errors)
" Preserve indented lines. " Preserve indented lines.
" This comes up especially with multi-line test output. " This comes up especially with multi-line test output.
if match(line, '^\s') >= 0 if match(line, '^\s') >= 0
call add(errors, {"text": line}) call add(errors, {"text": line})
endif endif
endif endif
endfor endfor
return errors return errors
endfunction endfunction
"FilterValids filters the given items with only items that have a valid "FilterValids filters the given items with only items that have a valid
"filename. Any non valid filename is filtered out. "filename. Any non valid filename is filtered out.
function! go#tool#FilterValids(items) function! go#tool#FilterValids(items)
" Remove any nonvalid filename from the location list to avoid opening an " Remove any nonvalid filename from the location list to avoid opening an
" empty buffer. See https://github.com/fatih/vim-go/issues/287 for " empty buffer. See https://github.com/fatih/vim-go/issues/287 for
" details. " details.
let filtered = [] let filtered = []
let is_readable = {} let is_readable = {}
for item in a:items for item in a:items
if has_key(item, 'bufnr') if has_key(item, 'bufnr')
let filename = bufname(item.bufnr) let filename = bufname(item.bufnr)
elseif has_key(item, 'filename') elseif has_key(item, 'filename')
let filename = item.filename let filename = item.filename
else else
" nothing to do, add item back to the list " nothing to do, add item back to the list
call add(filtered, item) call add(filtered, item)
continue continue
endif endif
if !has_key(is_readable, filename) if !has_key(is_readable, filename)
let is_readable[filename] = filereadable(filename) let is_readable[filename] = filereadable(filename)
endif endif
if is_readable[filename] if is_readable[filename]
call add(filtered, item) call add(filtered, item)
endif endif
endfor endfor
for k in keys(filter(is_readable, '!v:val')) for k in keys(filter(is_readable, '!v:val'))
echo "vim-go: " | echohl Identifier | echon "[run] Dropped " | echohl Constant | echon '"' . k . '"' echo "vim-go: " | echohl Identifier | echon "[run] Dropped " | echohl Constant | echon '"' . k . '"'
echohl Identifier | echon " from location list (nonvalid filename)" | echohl None echohl Identifier | echon " from location list (nonvalid filename)" | echohl None
endfor endfor
return filtered return filtered
endfunction endfunction
function! go#tool#ExecuteInDir(cmd) abort function! go#tool#ExecuteInDir(cmd) abort
let old_gopath = $GOPATH let old_gopath = $GOPATH
let $GOPATH = go#path#Detect() let $GOPATH = go#path#Detect()
let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd ' : 'cd ' let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd ' : 'cd '
let dir = getcwd() let dir = getcwd()
try try
execute cd . fnameescape(expand("%:p:h")) execute cd . fnameescape(expand("%:p:h"))
let out = go#util#System(a:cmd) let out = go#util#System(a:cmd)
finally finally
execute cd . fnameescape(dir) execute cd . fnameescape(dir)
endtry endtry
let $GOPATH = old_gopath let $GOPATH = old_gopath
return out return out
endfunction endfunction
" Exists checks whether the given importpath exists or not. It returns 0 if " Exists checks whether the given importpath exists or not. It returns 0 if
@ -168,10 +171,10 @@ function! go#tool#OpenBrowser(url)
return return
endif endif
if cmd =~ '^!' if cmd =~ '^!'
let cmd = substitute(cmd, '%URL%', '\=shellescape(a:url)', 'g') let cmd = substitute(cmd, '%URL%', '\=escape(shellescape(a:url),"#")', 'g')
silent! exec cmd silent! exec cmd
elseif cmd =~ '^:[A-Z]' elseif cmd =~ '^:[A-Z]'
let cmd = substitute(cmd, '%URL%', '\=a:url', 'g') let cmd = substitute(cmd, '%URL%', '\=escape(a:url,"#")', 'g')
exec cmd exec cmd
else else
let cmd = substitute(cmd, '%URL%', '\=shellescape(a:url)', 'g') let cmd = substitute(cmd, '%URL%', '\=shellescape(a:url)', 'g')
@ -179,4 +182,4 @@ function! go#tool#OpenBrowser(url)
endif endif
endfunction endfunction
" vim:ts=4:sw=4:et " vim: sw=2 ts=2 et

View file

@ -2,112 +2,113 @@ 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, filetype) function! go#ui#OpenWindow(title, content, filetype)
" Ensure there's only one return window in this session/tabpage " Ensure there's only one return window in this session/tabpage
call go#util#Windo("unlet! w:vim_go_return_window") call go#util#Windo("unlet! w:vim_go_return_window")
" Mark the window we're leaving as such " Mark the window we're leaving as such
let w:vim_go_return_window = 1 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'
file `="[" . a:title . "]"` file `="[" . a:title . "]"`
let s:buf_nr = bufnr('%') let s:buf_nr = bufnr('%')
elseif bufwinnr(s:buf_nr) == -1 elseif bufwinnr(s:buf_nr) == -1
execute 'botright new' execute 'botright new'
execute s:buf_nr . 'buffer' execute s:buf_nr . 'buffer'
elseif bufwinnr(s:buf_nr) != bufwinnr('%') elseif bufwinnr(s:buf_nr) != bufwinnr('%')
execute bufwinnr(s:buf_nr) . 'wincmd w' execute bufwinnr(s:buf_nr) . 'wincmd w'
endif endif
" Resize window to content length " Resize window to content length
exe 'resize' . len(a:content) exe 'resize' . len(a:content)
execute "setlocal filetype=".a:filetype execute "setlocal filetype=".a:filetype
" some sane default values for a readonly buffer " some sane default values for a readonly buffer
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 nonumber
setlocal norelativenumber setlocal norelativenumber
setlocal showbreak="" setlocal showbreak=""
" we need this to purge the buffer content " we need this to purge the buffer content
setlocal modifiable setlocal modifiable
"delete everything first from the buffer "delete everything first from the buffer
%delete _ %delete _
" add the content " add the content
call append(0, a:content) call append(0, a:content)
" delete last line that comes from the append call " delete last line that comes from the append call
$delete _ $delete _
" 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 " Remove the '... [New File]' message line from the command line
echon echon
endfunction endfunction
function! go#ui#GetReturnWindow() function! go#ui#GetReturnWindow()
for l:wn in range(1, winnr("$")) for l:wn in range(1, winnr("$"))
if !empty(getwinvar(l:wn, "vim_go_return_window")) if !empty(getwinvar(l:wn, "vim_go_return_window"))
return l:wn return l:wn
endif endif
endfor endfor
endfunction endfunction
" CloseWindow closes the current window " CloseWindow closes the current window
function! go#ui#CloseWindow() function! go#ui#CloseWindow()
" Close any window associated with the ui buffer, if it's there " Close any window associated with the ui buffer, if it's there
if bufexists(s:buf_nr) if bufexists(s:buf_nr)
let ui_window_number = bufwinnr(s:buf_nr) let ui_window_number = bufwinnr(s:buf_nr)
if ui_window_number != -1 if ui_window_number != -1
execute ui_window_number . 'close' execute ui_window_number . 'close'
endif
endif endif
endif
"return to original window, if it's there "return to original window, if it's there
let l:rw = go#ui#GetReturnWindow() let l:rw = go#ui#GetReturnWindow()
if !empty(l:rw) if !empty(l:rw)
execute l:rw . 'wincmd w' execute l:rw . 'wincmd w'
unlet! w:vim_go_return_window unlet! w:vim_go_return_window
endif 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
" tab " tab
function! go#ui#OpenDefinition(filter) function! go#ui#OpenDefinition(filter)
let curline = getline('.') let curline = getline('.')
" don't touch our first line or any blank line " don't touch our first line or any blank line
if curline =~ a:filter || curline =~ "^$" if curline =~ a:filter || curline =~ "^$"
" supress information about calling this function " suppress information about calling this function
echo "" echo ""
return return
endif endif
" format: 'interface file:lnum:coln' " format: 'interface file:lnum:coln'
let mx = '^\(^\S*\)\s*\(.\{-}\):\(\d\+\):\(\d\+\)' let mx = '^\(^\S*\)\s*\(.\{-}\):\(\d\+\):\(\d\+\)'
" parse it now into the list " parse it now into the list
let tokens = matchlist(curline, mx) let tokens = matchlist(curline, mx)
" convert to: 'file:lnum:coln' " convert to: 'file:lnum:coln'
let expr = tokens[2] . ":" . tokens[3] . ":" . tokens[4] let expr = tokens[2] . ":" . tokens[3] . ":" . tokens[4]
" jump to it in a new tab, we use explicit lgetexpr so we can later change " jump to it in a new tab, we use explicit lgetexpr so we can later change
" the behaviour via settings (like opening in vsplit instead of tab) " the behaviour via settings (like opening in vsplit instead of tab)
lgetexpr expr lgetexpr expr
tab split tab split
ll 1 ll 1
" center the word " center the word
norm! zz norm! zz
endfunction endfunction
" vim: sw=2 ts=2 et

View file

@ -1,112 +1,112 @@
" PathSep returns the appropriate OS specific path separator. " PathSep returns the appropriate OS specific path separator.
function! go#util#PathSep() function! go#util#PathSep()
if go#util#IsWin() if go#util#IsWin()
return '\' return '\'
endif endif
return '/' return '/'
endfunction endfunction
" PathListSep returns the appropriate OS specific path list separator. " PathListSep returns the appropriate OS specific path list separator.
function! go#util#PathListSep() function! go#util#PathListSep()
if go#util#IsWin() if go#util#IsWin()
return ";" return ";"
endif endif
return ":" return ":"
endfunction endfunction
" LineEnding returns the correct line ending, based on the current fileformat " LineEnding returns the correct line ending, based on the current fileformat
function! go#util#LineEnding() function! go#util#LineEnding()
if &fileformat == 'dos' if &fileformat == 'dos'
return "\r\n" return "\r\n"
elseif &fileformat == 'mac' elseif &fileformat == 'mac'
return "\r" return "\r"
endif endif
return "\n" return "\n"
endfunction endfunction
" IsWin returns 1 if current OS is Windows or 0 otherwise " IsWin returns 1 if current OS is Windows or 0 otherwise
function! go#util#IsWin() function! go#util#IsWin()
let win = ['win16', 'win32', 'win64', 'win95'] let win = ['win16', 'win32', 'win64', 'win95']
for w in win for w in win
if (has(w)) if (has(w))
return 1 return 1
endif endif
endfor endfor
return 0 return 0
endfunction endfunction
function! go#util#GOARCH() function! go#util#GOARCH()
return substitute(go#util#System('go env GOARCH'), '\n', '', 'g') return substitute(go#util#System('go env GOARCH'), '\n', '', 'g')
endfunction endfunction
function! go#util#GOOS() function! go#util#GOOS()
return substitute(go#util#System('go env GOOS'), '\n', '', 'g') return substitute(go#util#System('go env GOOS'), '\n', '', 'g')
endfunction endfunction
function! go#util#GOROOT() function! go#util#GOROOT()
return substitute(go#util#System('go env GOROOT'), '\n', '', 'g') return substitute(go#util#System('go env GOROOT'), '\n', '', 'g')
endfunction endfunction
function! go#util#GOPATH() function! go#util#GOPATH()
return substitute(go#util#System('go env GOPATH'), '\n', '', 'g') return substitute(go#util#System('go env GOPATH'), '\n', '', 'g')
endfunction endfunction
function! go#util#OSARCH() function! go#util#OSARCH()
return go#util#GOOS() . '_' . go#util#GOARCH() return go#util#GOOS() . '_' . go#util#GOARCH()
endfunction endfunction
"Check if has vimproc "Check if has vimproc
function! s:has_vimproc() function! s:has_vimproc()
if !exists('g:go#use_vimproc') if !exists('g:go#use_vimproc')
if go#util#IsWin() if go#util#IsWin()
try try
call vimproc#version() call vimproc#version()
let exists_vimproc = 1 let exists_vimproc = 1
catch catch
let exists_vimproc = 0 let exists_vimproc = 0
endtry endtry
else else
let exists_vimproc = 0 let exists_vimproc = 0
endif
let g:go#use_vimproc = exists_vimproc
endif endif
return g:go#use_vimproc let g:go#use_vimproc = exists_vimproc
endif
return g:go#use_vimproc
endfunction endfunction
if s:has_vimproc() if s:has_vimproc()
let s:vim_system = get(g:, 'gocomplete#system_function', 'vimproc#system2') let s:vim_system = get(g:, 'gocomplete#system_function', 'vimproc#system2')
let s:vim_shell_error = get(g:, 'gocomplete#shell_error_function', 'vimproc#get_last_status') let s:vim_shell_error = get(g:, 'gocomplete#shell_error_function', 'vimproc#get_last_status')
else else
let s:vim_system = get(g:, 'gocomplete#system_function', 'system') let s:vim_system = get(g:, 'gocomplete#system_function', 'system')
let s:vim_shell_error = '' let s:vim_shell_error = ''
endif endif
function! go#util#System(str, ...) function! go#util#System(str, ...)
return call(s:vim_system, [a:str] + a:000) return call(s:vim_system, [a:str] + a:000)
endfunction endfunction
function! go#util#ShellError() function! go#util#ShellError()
if empty(s:vim_shell_error) if empty(s:vim_shell_error)
return v:shell_error return v:shell_error
endif endif
return call(s:vim_shell_error, []) return call(s:vim_shell_error, [])
endfunction endfunction
" StripPath strips the path's last character if it's a path separator. " StripPath strips the path's last character if it's a path separator.
" example: '/foo/bar/' -> '/foo/bar' " example: '/foo/bar/' -> '/foo/bar'
function! go#util#StripPathSep(path) function! go#util#StripPathSep(path)
let last_char = strlen(a:path) - 1 let last_char = strlen(a:path) - 1
if a:path[last_char] == go#util#PathSep() if a:path[last_char] == go#util#PathSep()
return strpart(a:path, 0, last_char) return strpart(a:path, 0, last_char)
endif endif
return a:path return a:path
endfunction endfunction
" StripTrailingSlash strips the trailing slash from the given path list. " StripTrailingSlash strips the trailing slash from the given path list.
@ -118,12 +118,12 @@ endfunction
" Shelljoin returns a shell-safe string representation of arglist. The " Shelljoin returns a shell-safe string representation of arglist. The
" {special} argument of shellescape() may optionally be passed. " {special} argument of shellescape() may optionally be passed.
function! go#util#Shelljoin(arglist, ...) function! go#util#Shelljoin(arglist, ...)
try try
let ssl_save = &shellslash let ssl_save = &shellslash
set noshellslash set noshellslash
if a:0 if a:0
return join(map(copy(a:arglist), 'shellescape(v:val, ' . a:1 . ')'), ' ') return join(map(copy(a:arglist), 'shellescape(v:val, ' . a:1 . ')'), ' ')
endif endif
return join(map(copy(a:arglist), 'shellescape(v:val)'), ' ') return join(map(copy(a:arglist), 'shellescape(v:val)'), ' ')
finally finally
@ -206,4 +206,4 @@ function! go#util#EchoProgress(msg)
redraws! | echon "vim-go: " | echohl Identifier | echon a:msg | echohl None redraws! | echon "vim-go: " | echohl Identifier | echon a:msg | echohl None
endfunction endfunction
" vim:ts=4:sw=4:et " vim: sw=2 ts=2 et

View file

@ -16,9 +16,9 @@ endif
let s:save_cpo = &cpo let s:save_cpo = &cpo
set cpo-=C set cpo-=C
if filereadable("makefile") || filereadable("Makefile") if filereadable("makefile") || filereadable("Makefile")
CompilerSet makeprg=make CompilerSet makeprg=make
else else
CompilerSet makeprg=go\ build CompilerSet makeprg=go\ build
endif endif
" Define the patterns that will be recognized by QuickFix when parsing the " Define the patterns that will be recognized by QuickFix when parsing the
@ -38,4 +38,4 @@ CompilerSet errorformat+=%-G%.%# " All lines not matching a
let &cpo = s:save_cpo let &cpo = s:save_cpo
unlet s:save_cpo unlet s:save_cpo
" vim:ts=4:sw=4:et " vim: sw=2 ts=2 et

View file

@ -439,7 +439,8 @@ CTRL-t
:GoInstallBinaries :GoInstallBinaries
Download and Install all necessary Go tool binaries such as `godef`, Download and Install all necessary Go tool binaries such as `godef`,
`goimports`, `gocode`, etc.. under `g:go_bin_path` `goimports`, `gocode`, etc.. under `g:go_bin_path`. Set |g:go_get_update|
to disable updating dependencies.
*:GoUpdateBinaries* *:GoUpdateBinaries*
:GoUpdateBinaries :GoUpdateBinaries
@ -630,6 +631,7 @@ CTRL-t
:GoImpl f *Foo io.Writer :GoImpl f *Foo io.Writer
:GoImpl T io.ReadWriteCloser :GoImpl T io.ReadWriteCloser
< <
=============================================================================== ===============================================================================
MAPPINGS *go-mappings* MAPPINGS *go-mappings*
@ -672,17 +674,14 @@ Calls `go build` for the current package
Calls `go generate` for the current package Calls `go generate` for the current package
*(go-info)* *(go-info)*
Shows type information for the word under the cursor Shows type information for the word under the cursor
*(go-install)* *(go-install)*
Calls `go install` for the current package Calls `go install` for the current package
*(go-test)* *(go-test)*
Calls `go test` for the current package Calls `go test` for the current package
@ -710,6 +709,10 @@ Calls `go test -coverprofile-temp.out` for the current package and shows the
coverage annotation. If run agains it acts as a toggle and clears the coverage annotation. If run agains it acts as a toggle and clears the
annotation. annotation.
*(go-imports)*
Calls `goimports` for the current package
*(go-vet)* *(go-vet)*
Calls `go vet` for the current package Calls `go vet` for the current package
@ -834,6 +837,11 @@ Alternates between the implementation and test code in a new horizontal split
Alternates between the implementation and test code in a new vertical split Alternates between the implementation and test code in a new vertical split
*(go-import)*
Calls `:GoImport` for the current package
=============================================================================== ===============================================================================
TEXT OBJECTS *go-text-objects* TEXT OBJECTS *go-text-objects*
@ -973,6 +981,14 @@ K , keywordprg shortcut. Usually this shortcut is set to use the program `man`.
In Go, using `godoc` is more idiomatic. Default is enabled. > In Go, using `godoc` is more idiomatic. Default is enabled. >
let g:go_doc_keywordprg_enabled = 1 let g:go_doc_keywordprg_enabled = 1
<
*'g:go_def_mode'*
Use this option to define the command to be used for |:GoDef|. By default
`guru` is being used as it covers all edge cases. But one might also use
`godef` as it's more faster. Current valid options are: `[guru, godef]` >
let g:go_def_mode = 'guru'
< <
*'g:go_def_mapping_enabled'* *'g:go_def_mapping_enabled'*
@ -1028,6 +1044,14 @@ is used. Use "neosnippet" for neosnippet.vim: >
let g:go_snippet_engine = "ultisnips" let g:go_snippet_engine = "ultisnips"
< <
*'g:go_get_update'*
Use this option to disable updating dependencies with |GoInstallBinaries|. By
default this is enabled.
>
let g:go_get_update = 1
<
*'g:go_guru_scope'* *'g:go_guru_scope'*
Use this option to define the scope of the analysis to be passed for guru Use this option to define the scope of the analysis to be passed for guru
@ -1098,7 +1122,13 @@ Highlights method names. By default it's disabled. >
Highlights struct names. By default it's disabled. > Highlights struct names. By default it's disabled. >
let g:go_highlight_structs = 0 let g:go_highlight_structs = 0
<
*'g:go_highlight_fields'*
Highlights field names. By default it's disabled. >
let g:go_highlight_fields = 0
< <
*'g:go_highlight_interfaces'* *'g:go_highlight_interfaces'*
@ -1243,10 +1273,24 @@ By default it is set to edit.
*g:go_gorename_prefill* *g:go_gorename_prefill*
Specifies whether |:GoRename| prefills the new identifier name with the Specifies whether |:GoRename| prefills the new identifier name with the
word under the cursor. By default is is enabled. word under the cursor. By default it is enabled.
> >
let g:go_gorename_prefill = 1 let g:go_gorename_prefill = 1
< <
*g:go_gocode_autobuild*
Specifies whether `gocode` should automatically build out-of-date packages
when their source fiels are modified, in order to obtahin the freshes
autocomplete results for them. By default it is enabled.
>
let g:go_gocode_autobuild = 1
<
*g:go_gocode_propose_builtins*
Specifies whether `gocode` should add built-in types, functions and constants
to an autocompletion proposals. By default it is enabled.
>
let g:go_gocode_propose_builtins = 1
=============================================================================== ===============================================================================

View file

@ -6,16 +6,16 @@ let s:current_fileencodings = ''
" define fileencodings to open as utf-8 encoding even if it's ascii. " define fileencodings to open as utf-8 encoding even if it's ascii.
function! s:gofiletype_pre(type) function! s:gofiletype_pre(type)
let s:current_fileformats = &g:fileformats let s:current_fileformats = &g:fileformats
let s:current_fileencodings = &g:fileencodings let s:current_fileencodings = &g:fileencodings
set fileencodings=utf-8 fileformats=unix set fileencodings=utf-8 fileformats=unix
let &l:filetype = a:type let &l:filetype = a:type
endfunction endfunction
" restore fileencodings as others " restore fileencodings as others
function! s:gofiletype_post() function! s:gofiletype_post()
let &g:fileformats = s:current_fileformats let &g:fileformats = s:current_fileformats
let &g:fileencodings = s:current_fileencodings let &g:fileencodings = s:current_fileencodings
endfunction endfunction
au BufNewFile *.go setfiletype go | setlocal fileencoding=utf-8 fileformat=unix au BufNewFile *.go setfiletype go | setlocal fileencoding=utf-8 fileformat=unix
@ -28,4 +28,4 @@ au BufReadPost *.s call s:gofiletype_post()
au BufRead,BufNewFile *.tmpl set filetype=gohtmltmpl au BufRead,BufNewFile *.tmpl set filetype=gohtmltmpl
" vim:ts=4:sw=4:et " vim: sw=2 ts=2 et

View file

@ -1,7 +1,7 @@
" asm.vim: Vim filetype plugin for Go assembler. " asm.vim: Vim filetype plugin for Go assembler.
if exists("b:did_ftplugin") if exists("b:did_ftplugin")
finish finish
endif endif
let b:did_ftplugin = 1 let b:did_ftplugin = 1
@ -15,3 +15,5 @@ setlocal commentstring=//\ %s
setlocal noexpandtab setlocal noexpandtab
command! -nargs=0 AsmFmt call go#asmfmt#Format() command! -nargs=0 AsmFmt call go#asmfmt#Format()
" vim: sw=2 ts=2 et

View file

@ -5,7 +5,7 @@
" go.vim: Vim filetype plugin for Go. " go.vim: Vim filetype plugin for Go.
if exists("b:did_ftplugin") if exists("b:did_ftplugin")
finish finish
endif endif
let b:did_ftplugin = 1 let b:did_ftplugin = 1
@ -24,40 +24,40 @@ compiler go
setlocal omnifunc=go#complete#Complete setlocal omnifunc=go#complete#Complete
if get(g:, "go_doc_keywordprg_enabled", 1) if get(g:, "go_doc_keywordprg_enabled", 1)
" keywordprg doesn't allow to use vim commands, override it " keywordprg doesn't allow to use vim commands, override it
nnoremap <buffer> <silent> K :GoDoc<cr> nnoremap <buffer> <silent> K :GoDoc<cr>
endif endif
if get(g:, "go_def_mapping_enabled", 1) if get(g:, "go_def_mapping_enabled", 1)
" these are default Vim mappings, we're overriding them to make them " these are default Vim mappings, we're overriding them to make them
" useful again for Go source code " useful again for Go source code
nnoremap <buffer> <silent> gd :GoDef<cr> nnoremap <buffer> <silent> gd :GoDef<cr>
nnoremap <buffer> <silent> <C-]> :GoDef<cr> nnoremap <buffer> <silent> <C-]> :GoDef<cr>
nnoremap <buffer> <silent> <C-w><C-]> :<C-u>call go#def#Jump("split")<CR> nnoremap <buffer> <silent> <C-w><C-]> :<C-u>call go#def#Jump("split")<CR>
nnoremap <buffer> <silent> <C-w>] :<C-u>call go#def#Jump("split")<CR> nnoremap <buffer> <silent> <C-w>] :<C-u>call go#def#Jump("split")<CR>
nnoremap <buffer> <silent> <C-t> :<C-U>call go#def#StackPop(v:count1)<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)
onoremap <buffer> <silent> af :<c-u>call go#textobj#Function('a')<cr> onoremap <buffer> <silent> af :<c-u>call go#textobj#Function('a')<cr>
onoremap <buffer> <silent> if :<c-u>call go#textobj#Function('i')<cr> onoremap <buffer> <silent> if :<c-u>call go#textobj#Function('i')<cr>
xnoremap <buffer> <silent> af :<c-u>call go#textobj#Function('a')<cr> xnoremap <buffer> <silent> af :<c-u>call go#textobj#Function('a')<cr>
xnoremap <buffer> <silent> if :<c-u>call go#textobj#Function('i')<cr> xnoremap <buffer> <silent> if :<c-u>call go#textobj#Function('i')<cr>
" Remap ]] and [[ to jump betweeen functions as they are useless in Go " Remap ]] and [[ to jump betweeen functions as they are useless in Go
nnoremap <buffer> <silent> ]] :<c-u>call go#textobj#FunctionJump('n', 'next')<cr> nnoremap <buffer> <silent> ]] :<c-u>call go#textobj#FunctionJump('n', 'next')<cr>
nnoremap <buffer> <silent> [[ :<c-u>call go#textobj#FunctionJump('n', 'prev')<cr> nnoremap <buffer> <silent> [[ :<c-u>call go#textobj#FunctionJump('n', 'prev')<cr>
onoremap <buffer> <silent> ]] :<c-u>call go#textobj#FunctionJump('o', 'next')<cr> onoremap <buffer> <silent> ]] :<c-u>call go#textobj#FunctionJump('o', 'next')<cr>
onoremap <buffer> <silent> [[ :<c-u>call go#textobj#FunctionJump('o', 'prev')<cr> onoremap <buffer> <silent> [[ :<c-u>call go#textobj#FunctionJump('o', 'prev')<cr>
xnoremap <buffer> <silent> ]] :<c-u>call go#textobj#FunctionJump('v', 'next')<cr> xnoremap <buffer> <silent> ]] :<c-u>call go#textobj#FunctionJump('v', 'next')<cr>
xnoremap <buffer> <silent> [[ :<c-u>call go#textobj#FunctionJump('v', 'prev')<cr> xnoremap <buffer> <silent> [[ :<c-u>call go#textobj#FunctionJump('v', 'prev')<cr>
endif endif
if get(g:, "go_auto_type_info", 0) if get(g:, "go_auto_type_info", 0)
setlocal updatetime=800 setlocal updatetime=800
endif endif
" vim:ts=4:sw=4:et " vim: sw=2 ts=2 et

View file

@ -76,4 +76,4 @@ endif
" -- impl " -- impl
command! -nargs=* -buffer -complete=customlist,go#impl#Complete GoImpl call go#impl#Impl(<f-args>) command! -nargs=* -buffer -complete=customlist,go#impl#Complete GoImpl call go#impl#Impl(<f-args>)
" vim:ts=4:sw=4:et " vim: sw=2 ts=2 et

View file

@ -5,16 +5,16 @@
" which by default is enabled. For commands the user has the ability to pass " which by default is enabled. For commands the user has the ability to pass
" the '!', such as :GoBuild or :GoBuild! " the '!', such as :GoBuild or :GoBuild!
if !exists("g:go_jump_to_error") if !exists("g:go_jump_to_error")
let g:go_jump_to_error = 1 let g:go_jump_to_error = 1
endif endif
" Some handy plug mappings " Some handy plug mappings
nnoremap <silent> <Plug>(go-run) :<C-u>call go#cmd#Run(!g:go_jump_to_error)<CR> nnoremap <silent> <Plug>(go-run) :<C-u>call go#cmd#Run(!g:go_jump_to_error)<CR>
if has("nvim") if has("nvim")
nnoremap <silent> <Plug>(go-run-vertical) :<C-u>call go#cmd#RunTerm(!g:go_jump_to_error, 'vsplit', [])<CR> nnoremap <silent> <Plug>(go-run-vertical) :<C-u>call go#cmd#RunTerm(!g:go_jump_to_error, 'vsplit', [])<CR>
nnoremap <silent> <Plug>(go-run-split) :<C-u>call go#cmd#RunTerm(!g:go_jump_to_error, 'split', [])<CR> nnoremap <silent> <Plug>(go-run-split) :<C-u>call go#cmd#RunTerm(!g:go_jump_to_error, 'split', [])<CR>
nnoremap <silent> <Plug>(go-run-tab) :<C-u>call go#cmd#RunTerm(!g:go_jump_to_error, 'tabe', [])<CR> nnoremap <silent> <Plug>(go-run-tab) :<C-u>call go#cmd#RunTerm(!g:go_jump_to_error, 'tabe', [])<CR>
endif endif
nnoremap <silent> <Plug>(go-build) :<C-u>call go#cmd#Build(!g:go_jump_to_error)<CR> nnoremap <silent> <Plug>(go-build) :<C-u>call go#cmd#Build(!g:go_jump_to_error)<CR>
@ -33,6 +33,7 @@ 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>
nnoremap <silent> <Plug>(go-info) :<C-u>call go#complete#Info(0)<CR> nnoremap <silent> <Plug>(go-info) :<C-u>call go#complete#Info(0)<CR>
nnoremap <silent> <Plug>(go-import) :<C-u>call go#import#SwitchImport(1, '', expand('<cword>'), '')<CR> nnoremap <silent> <Plug>(go-import) :<C-u>call go#import#SwitchImport(1, '', expand('<cword>'), '')<CR>
nnoremap <silent> <Plug>(go-imports) :<C-u>call go#fmt#Format(1)<CR>
nnoremap <silent> <Plug>(go-implements) :<C-u>call go#guru#Implements(-1)<CR> nnoremap <silent> <Plug>(go-implements) :<C-u>call go#guru#Implements(-1)<CR>
nnoremap <silent> <Plug>(go-callees) :<C-u>call go#guru#Callees(-1)<CR> nnoremap <silent> <Plug>(go-callees) :<C-u>call go#guru#Callees(-1)<CR>
@ -69,3 +70,5 @@ nnoremap <silent> <Plug>(go-vet) :<C-u>call go#lint#Vet(!g:go_jump_to_error)<CR>
nnoremap <silent> <Plug>(go-alternate-edit) :<C-u>call go#alternate#Switch(0, "edit")<CR> nnoremap <silent> <Plug>(go-alternate-edit) :<C-u>call go#alternate#Switch(0, "edit")<CR>
nnoremap <silent> <Plug>(go-alternate-vertical) :<C-u>call go#alternate#Switch(0, "vsplit")<CR> nnoremap <silent> <Plug>(go-alternate-vertical) :<C-u>call go#alternate#Switch(0, "vsplit")<CR>
nnoremap <silent> <Plug>(go-alternate-split) :<C-u>call go#alternate#Switch(0, "split")<CR> nnoremap <silent> <Plug>(go-alternate-split) :<C-u>call go#alternate#Switch(0, "split")<CR>
" vim: sw=2 ts=2 et

View file

@ -5,42 +5,44 @@ let g:go_loaded_gosnippets = 1
" by default UltiSnips " by default UltiSnips
if !exists("g:go_snippet_engine") if !exists("g:go_snippet_engine")
let g:go_snippet_engine = "ultisnips" let g:go_snippet_engine = "ultisnips"
endif endif
function! s:GoUltiSnips() function! s:GoUltiSnips()
if globpath(&rtp, 'plugin/UltiSnips.vim') == "" if globpath(&rtp, 'plugin/UltiSnips.vim') == ""
return return
endif endif
if !exists("g:UltiSnipsSnippetDirectories") if !exists("g:UltiSnipsSnippetDirectories")
let g:UltiSnipsSnippetDirectories = ["gosnippets/UltiSnips"] let g:UltiSnipsSnippetDirectories = ["gosnippets/UltiSnips"]
else else
let g:UltiSnipsSnippetDirectories += ["gosnippets/UltiSnips"] let g:UltiSnipsSnippetDirectories += ["gosnippets/UltiSnips"]
endif endif
endfunction endfunction
function! s:GoNeosnippet() function! s:GoNeosnippet()
if globpath(&rtp, 'plugin/neosnippet.vim') == "" if globpath(&rtp, 'plugin/neosnippet.vim') == ""
return return
endif endif
let g:neosnippet#enable_snipmate_compatibility = 1 let g:neosnippet#enable_snipmate_compatibility = 1
let gosnippets_dir = globpath(&rtp, 'gosnippets/snippets') let gosnippets_dir = globpath(&rtp, 'gosnippets/snippets')
if type(g:neosnippet#snippets_directory) == type([]) if type(g:neosnippet#snippets_directory) == type([])
let g:neosnippet#snippets_directory += [gosnippets_dir] let g:neosnippet#snippets_directory += [gosnippets_dir]
elseif type(g:neosnippet#snippets_directory) == type("") elseif type(g:neosnippet#snippets_directory) == type("")
if strlen(g:neosnippet#snippets_directory) > 0 if strlen(g:neosnippet#snippets_directory) > 0
let g:neosnippet#snippets_directory = g:neosnippet#snippets_directory . "," . gosnippets_dir let g:neosnippet#snippets_directory = g:neosnippet#snippets_directory . "," . gosnippets_dir
else else
let g:neosnippet#snippets_directory = gosnippets_dir let g:neosnippet#snippets_directory = gosnippets_dir
endif endif
endif endif
endfunction endfunction
if g:go_snippet_engine == "ultisnips" if g:go_snippet_engine == "ultisnips"
call s:GoUltiSnips() call s:GoUltiSnips()
elseif g:go_snippet_engine == "neosnippet" elseif g:go_snippet_engine == "neosnippet"
call s:GoNeosnippet() call s:GoNeosnippet()
endif endif
" vim: sw=2 ts=2 et

View file

@ -4,52 +4,54 @@
" Also make sure the ctags command exists " Also make sure the ctags command exists
" "
if !executable('ctags') if !executable('ctags')
finish finish
elseif globpath(&rtp, 'plugin/tagbar.vim') == "" elseif globpath(&rtp, 'plugin/tagbar.vim') == ""
finish finish
endif endif
if !exists("g:go_gotags_bin") if !exists("g:go_gotags_bin")
let g:go_gotags_bin = "gotags" let g:go_gotags_bin = "gotags"
endif endif
function! s:SetTagbar() function! s:SetTagbar()
let bin_path = go#path#CheckBinPath(g:go_gotags_bin) let bin_path = go#path#CheckBinPath(g:go_gotags_bin)
if empty(bin_path) if empty(bin_path)
return return
endif endif
if !exists("g:tagbar_type_go") if !exists("g:tagbar_type_go")
let g:tagbar_type_go = { let g:tagbar_type_go = {
\ 'ctagstype' : 'go', \ 'ctagstype' : 'go',
\ 'kinds' : [ \ 'kinds' : [
\ 'p:package', \ 'p:package',
\ 'i:imports', \ 'i:imports',
\ 'c:constants', \ 'c:constants',
\ 'v:variables', \ 'v:variables',
\ 't:types', \ 't:types',
\ 'n:interfaces', \ 'n:interfaces',
\ 'w:fields', \ 'w:fields',
\ 'e:embedded', \ 'e:embedded',
\ 'm:methods', \ 'm:methods',
\ 'r:constructor', \ 'r:constructor',
\ 'f:functions' \ 'f:functions'
\ ], \ ],
\ 'sro' : '.', \ 'sro' : '.',
\ 'kind2scope' : { \ 'kind2scope' : {
\ 't' : 'ctype', \ 't' : 'ctype',
\ 'n' : 'ntype' \ 'n' : 'ntype'
\ }, \ },
\ 'scope2kind' : { \ 'scope2kind' : {
\ 'ctype' : 't', \ 'ctype' : 't',
\ 'ntype' : 'n' \ 'ntype' : 'n'
\ }, \ },
\ 'ctagsbin' : expand(bin_path), \ 'ctagsbin' : expand(bin_path),
\ 'ctagsargs' : '-sort -silent' \ 'ctagsargs' : '-sort -silent'
\ } \ }
endif endif
endfunction endfunction
call s:SetTagbar() call s:SetTagbar()
" vim: sw=2 ts=2 et

View file

@ -1,6 +1,8 @@
if exists("b:did_ftplugin") if exists("b:did_ftplugin")
finish finish
endif endif
let b:did_ftplugin = 1 let b:did_ftplugin = 1
setlocal commentstring=<!--\ %s\ --> setlocal commentstring=<!--\ %s\ -->
" vim: sw=2 ts=2 et

View file

@ -307,19 +307,17 @@ abbr if err != nil { t.Fatalf(...) }
} }
# test example # test example
snippet example snippet example
func Example${1:Method}() { func Example${1:Method}() {
${0} ${0}
// Output: // Output:
} }
endsnippet
# test benchmark # test benchmark
snippet benchmark snippet benchmark
func Benchmark${1:Method}(b *testing.B) { func Benchmark${1:Method}(b *testing.B) {
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
${0} ${0}
}
} }
}
endsnippet
# variable declaration # variable declaration
snippet var snippet var
abbr var x Type [= ...] abbr var x Type [= ...]

View file

@ -9,7 +9,7 @@
" - general line splits (line ends in an operator) " - general line splits (line ends in an operator)
if exists("b:did_indent") if exists("b:did_indent")
finish finish
endif endif
let b:did_indent = 1 let b:did_indent = 1
@ -21,58 +21,58 @@ setlocal indentexpr=GoIndent(v:lnum)
setlocal indentkeys+=<:>,0=},0=) setlocal indentkeys+=<:>,0=},0=)
if exists("*GoIndent") if exists("*GoIndent")
finish finish
endif endif
" use shiftwidth function only if it's available " use shiftwidth function only if it's available
if exists('*shiftwidth') if exists('*shiftwidth')
func s:sw() func s:sw()
return shiftwidth() return shiftwidth()
endfunc endfunc
else else
func s:sw() func s:sw()
return &sw return &sw
endfunc endfunc
endif endif
function! GoIndent(lnum) function! GoIndent(lnum)
let prevlnum = prevnonblank(a:lnum-1) let prevlnum = prevnonblank(a:lnum-1)
if prevlnum == 0 if prevlnum == 0
" top of file " top of file
return 0 return 0
endif endif
" grab the previous and current line, stripping comments. " grab the previous and current line, stripping comments.
let prevl = substitute(getline(prevlnum), '//.*$', '', '') let prevl = substitute(getline(prevlnum), '//.*$', '', '')
let thisl = substitute(getline(a:lnum), '//.*$', '', '') let thisl = substitute(getline(a:lnum), '//.*$', '', '')
let previ = indent(prevlnum) let previ = indent(prevlnum)
let ind = previ let ind = previ
if prevl =~ '[({]\s*$' if prevl =~ '[({]\s*$'
" previous line opened a block " previous line opened a block
let ind += s:sw() let ind += s:sw()
endif endif
if prevl =~# '^\s*\(case .*\|default\):$' if prevl =~# '^\s*\(case .*\|default\):$'
" previous line is part of a switch statement " previous line is part of a switch statement
let ind += s:sw() let ind += s:sw()
endif endif
" TODO: handle if the previous line is a label. " TODO: handle if the previous line is a label.
if thisl =~ '^\s*[)}]' if thisl =~ '^\s*[)}]'
" this line closed a block " this line closed a block
let ind -= s:sw() let ind -= s:sw()
endif endif
" Colons are tricky. " Colons are tricky.
" We want to outdent if it's part of a switch ("case foo:" or "default:"). " We want to outdent if it's part of a switch ("case foo:" or "default:").
" We ignore trying to deal with jump labels because (a) they're rare, and " We ignore trying to deal with jump labels because (a) they're rare, and
" (b) they're hard to disambiguate from a composite literal key. " (b) they're hard to disambiguate from a composite literal key.
if thisl =~# '^\s*\(case .*\|default\):$' if thisl =~# '^\s*\(case .*\|default\):$'
let ind -= s:sw() let ind -= s:sw()
endif endif
return ind return ind
endfunction endfunction
" vim:ts=4:sw=4:et " vim: sw=2 ts=2 et

View file

@ -42,3 +42,5 @@ function! GetGoHTMLTmplIndent(lnum)
return ind return ind
endfunction endfunction
" vim: sw=2 ts=2 et

View file

@ -1,25 +1,26 @@
" install necessary Go tools " install necessary Go tools
if exists("g:go_loaded_install") if exists("g:go_loaded_install")
finish finish
endif endif
let g:go_loaded_install = 1 let g:go_loaded_install = 1
" these packages are used by vim-go and can be automatically installed if " these packages are used by vim-go and can be automatically installed if
" needed by the user with GoInstallBinaries " needed by the user with GoInstallBinaries
let s:packages = [ let s:packages = [
\ "github.com/nsf/gocode", \ "github.com/nsf/gocode",
\ "github.com/alecthomas/gometalinter", \ "github.com/alecthomas/gometalinter",
\ "golang.org/x/tools/cmd/goimports", \ "golang.org/x/tools/cmd/goimports",
\ "golang.org/x/tools/cmd/guru", \ "golang.org/x/tools/cmd/guru",
\ "golang.org/x/tools/cmd/gorename", \ "golang.org/x/tools/cmd/gorename",
\ "github.com/golang/lint/golint", \ "github.com/golang/lint/golint",
\ "github.com/kisielk/errcheck", \ "github.com/rogpeppe/godef",
\ "github.com/jstemmer/gotags", \ "github.com/kisielk/errcheck",
\ "github.com/klauspost/asmfmt/cmd/asmfmt", \ "github.com/jstemmer/gotags",
\ "github.com/fatih/motion", \ "github.com/klauspost/asmfmt/cmd/asmfmt",
\ "github.com/zmb3/gogetdoc", \ "github.com/fatih/motion",
\ "github.com/josharian/impl", \ "github.com/zmb3/gogetdoc",
\ ] \ "github.com/josharian/impl",
\ ]
" These commands are available on any filetypes " These commands are available on any filetypes
command! GoInstallBinaries call s:GoInstallBinaries(-1) command! GoInstallBinaries call s:GoInstallBinaries(-1)
@ -32,142 +33,144 @@ command! -nargs=? -complete=dir GoPath call go#path#GoPath(<f-args>)
" target install directory. GoInstallBinaries doesn't install binaries if they " target install directory. GoInstallBinaries doesn't install binaries if they
" exist, to update current binaries pass 1 to the argument. " exist, to update current binaries pass 1 to the argument.
function! s:GoInstallBinaries(updateBinaries) function! s:GoInstallBinaries(updateBinaries)
if $GOPATH == "" if $GOPATH == ""
echohl Error echohl Error
echomsg "vim.go: $GOPATH is not set" echomsg "vim.go: $GOPATH is not set"
echohl None echohl None
return return
endif
let err = s:CheckBinaries()
if err != 0
return
endif
let go_bin_path = go#path#BinPath()
" change $GOBIN so go get can automatically install to it
let $GOBIN = go_bin_path
" old_path is used to restore users own path
let old_path = $PATH
" vim's executable path is looking in PATH so add our go_bin path to it
let $PATH = go_bin_path . go#util#PathListSep() . $PATH
" when shellslash is set on MS-* systems, shellescape puts single quotes
" around the output string. cmd on Windows does not handle single quotes
" correctly. Unsetting shellslash forces shellescape to use double quotes
" instead.
let resetshellslash = 0
if has('win32') && &shellslash
let resetshellslash = 1
set noshellslash
endif
let cmd = "go get -v "
if get(g:, "go_get_update", 1) != 0
let cmd .= "-u "
endif
let s:go_version = matchstr(go#util#System("go version"), '\d.\d.\d')
" https://github.com/golang/go/issues/10791
if s:go_version > "1.4.0" && s:go_version < "1.5.0"
let cmd .= "-f "
endif
for pkg in s:packages
let basename = fnamemodify(pkg, ":t")
let binname = "go_" . basename . "_bin"
let bin = basename
if exists("g:{binname}")
let bin = g:{binname}
endif endif
let err = s:CheckBinaries() if !executable(bin) || a:updateBinaries == 1
if err != 0 if a:updateBinaries == 1
return echo "vim-go: Updating ". basename .". Reinstalling ". pkg . " to folder " . go_bin_path
else
echo "vim-go: ". basename ." not found. Installing ". pkg . " to folder " . go_bin_path
endif
let out = go#util#System(cmd . shellescape(pkg))
if go#util#ShellError() != 0
echo "Error installing ". pkg . ": " . out
endif
endif endif
endfor
let go_bin_path = go#path#BinPath() " restore back!
let $PATH = old_path
" change $GOBIN so go get can automatically install to it if resetshellslash
let $GOBIN = go_bin_path set shellslash
endif
" old_path is used to restore users own path
let old_path = $PATH
" vim's executable path is looking in PATH so add our go_bin path to it
let $PATH = go_bin_path . go#util#PathListSep() . $PATH
" when shellslash is set on MS-* systems, shellescape puts single quotes
" around the output string. cmd on Windows does not handle single quotes
" correctly. Unsetting shellslash forces shellescape to use double quotes
" instead.
let resetshellslash = 0
if has('win32') && &shellslash
let resetshellslash = 1
set noshellslash
endif
let cmd = "go get -u -v "
let s:go_version = matchstr(go#util#System("go version"), '\d.\d.\d')
" https://github.com/golang/go/issues/10791
if s:go_version > "1.4.0" && s:go_version < "1.5.0"
let cmd .= "-f "
endif
for pkg in s:packages
let basename = fnamemodify(pkg, ":t")
let binname = "go_" . basename . "_bin"
let bin = basename
if exists("g:{binname}")
let bin = g:{binname}
endif
if !executable(bin) || a:updateBinaries == 1
if a:updateBinaries == 1
echo "vim-go: Updating ". basename .". Reinstalling ". pkg . " to folder " . go_bin_path
else
echo "vim-go: ". basename ." not found. Installing ". pkg . " to folder " . go_bin_path
endif
let out = go#util#System(cmd . shellescape(pkg))
if go#util#ShellError() != 0
echo "Error installing ". pkg . ": " . out
endif
endif
endfor
" restore back!
let $PATH = old_path
if resetshellslash
set shellslash
endif
endfunction endfunction
" CheckBinaries checks if the necessary binaries to install the Go tool " CheckBinaries checks if the necessary binaries to install the Go tool
" commands are available. " commands are available.
function! s:CheckBinaries() function! s:CheckBinaries()
if !executable('go') if !executable('go')
echohl Error | echomsg "vim-go: go executable not found." | echohl None echohl Error | echomsg "vim-go: go executable not found." | echohl None
return -1 return -1
endif endif
if !executable('git') if !executable('git')
echohl Error | echomsg "vim-go: git executable not found." | echohl None echohl Error | echomsg "vim-go: git executable not found." | echohl None
return -1 return -1
endif endif
endfunction endfunction
" Autocommands " Autocommands
" ============================================================================ " ============================================================================
" "
function! s:echo_go_info() function! s:echo_go_info()
if !exists('v:completed_item') || empty(v:completed_item) if !exists('v:completed_item') || empty(v:completed_item)
return return
endif endif
let item = v:completed_item let item = v:completed_item
if !has_key(item, "info") if !has_key(item, "info")
return return
endif endif
if empty(item.info) if empty(item.info)
return return
endif endif
redraws! | echo "vim-go: " | echohl Function | echon item.info | echohl None redraws! | echo "vim-go: " | echohl Function | echon item.info | echohl None
endfunction endfunction
augroup vim-go augroup vim-go
autocmd! autocmd!
" GoInfo automatic update " GoInfo automatic update
if get(g:, "go_auto_type_info", 0) if get(g:, "go_auto_type_info", 0)
autocmd CursorHold *.go nested call go#complete#Info(1) autocmd CursorHold *.go nested call go#complete#Info(1)
endif endif
" Echo the identifier information when completion is done. Useful to see " Echo the identifier information when completion is done. Useful to see
" the signature of a function, etc... " the signature of a function, etc...
if exists('##CompleteDone') if exists('##CompleteDone')
autocmd CompleteDone *.go nested call s:echo_go_info() autocmd CompleteDone *.go nested call s:echo_go_info()
endif endif
" Go code formatting on save " Go code formatting on save
if get(g:, "go_fmt_autosave", 1) if get(g:, "go_fmt_autosave", 1)
autocmd BufWritePre *.go call go#fmt#Format(-1) autocmd BufWritePre *.go call go#fmt#Format(-1)
endif endif
" Go asm formatting on save " Go asm formatting on save
if get(g:, "go_asmfmt_autosave", 1) if get(g:, "go_asmfmt_autosave", 1)
autocmd BufWritePre *.s call go#asmfmt#Format() autocmd BufWritePre *.s call go#asmfmt#Format()
endif endif
" run gometalinter on save " run gometalinter on save
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
augroup END augroup END
" vim: sw=2 ts=2 et
" vim:ts=4:sw=4:et

View file

@ -67,6 +67,10 @@ if !exists("g:go_highlight_methods")
let g:go_highlight_methods = 0 let g:go_highlight_methods = 0
endif endif
if !exists("g:go_highlight_fields")
let g:go_highlight_fields = 0
endif
if !exists("g:go_highlight_structs") if !exists("g:go_highlight_structs")
let g:go_highlight_structs = 0 let g:go_highlight_structs = 0
endif endif
@ -308,6 +312,12 @@ if g:go_highlight_methods != 0
endif endif
hi def link goMethod Type hi def link goMethod Type
" Fields;
if g:go_highlight_fields != 0
syn match goField /\(\.\)\@<=\a\+\([\ \n\r\:\)]\)\@=/
endif
hi def link goField Type
" Structs; " Structs;
if g:go_highlight_structs != 0 if g:go_highlight_structs != 0
syn match goStruct /\(.\)\@<=\w\+\({\)\@=/ syn match goStruct /\(.\)\@<=\w\+\({\)\@=/
@ -326,35 +336,35 @@ hi def link goInterfaceDef Function
" Build Constraints " Build Constraints
if g:go_highlight_build_constraints != 0 if g:go_highlight_build_constraints != 0
syn match goBuildKeyword display contained "+build" syn match goBuildKeyword display contained "+build"
" Highlight the known values of GOOS, GOARCH, and other +build options. " Highlight the known values of GOOS, GOARCH, and other +build options.
syn keyword goBuildDirectives contained syn keyword goBuildDirectives contained
\ android darwin dragonfly freebsd linux nacl netbsd openbsd plan9 \ android darwin dragonfly freebsd linux nacl netbsd openbsd plan9
\ solaris windows 386 amd64 amd64p32 arm armbe arm64 arm64be ppc64 \ solaris windows 386 amd64 amd64p32 arm armbe arm64 arm64be ppc64
\ ppc64le mips mipsle mips64 mips64le mips64p32 mips64p32le ppc \ ppc64le mips mipsle mips64 mips64le mips64p32 mips64p32le ppc
\ s390 s390x sparc sparc64 cgo ignore race \ s390 s390x sparc sparc64 cgo ignore race
" Other words in the build directive are build tags not listed above, so " Other words in the build directive are build tags not listed above, so
" avoid highlighting them as comments by using a matchgroup just for the " avoid highlighting them as comments by using a matchgroup just for the
" start of the comment. " start of the comment.
" The rs=s+2 option lets the \s*+build portion be part of the inner region " The rs=s+2 option lets the \s*+build portion be part of the inner region
" instead of the matchgroup so it will be highlighted as a goBuildKeyword. " instead of the matchgroup so it will be highlighted as a goBuildKeyword.
syn region goBuildComment matchgroup=goBuildCommentStart syn region goBuildComment matchgroup=goBuildCommentStart
\ start="//\s*+build\s"rs=s+2 end="$" \ start="//\s*+build\s"rs=s+2 end="$"
\ contains=goBuildKeyword,goBuildDirectives \ contains=goBuildKeyword,goBuildDirectives
hi def link goBuildCommentStart Comment hi def link goBuildCommentStart Comment
hi def link goBuildDirectives Type hi def link goBuildDirectives Type
hi def link goBuildKeyword PreProc hi def link goBuildKeyword PreProc
" One or more line comments that are followed immediately by a "package" " One or more line comments that are followed immediately by a "package"
" declaration are treated like package documentation, so these must be " declaration are treated like package documentation, so these must be
" matched as comments to avoid looking like working build constraints. " matched as comments to avoid looking like working build constraints.
" The he, me, and re options let the "package" itself be highlighted by " The he, me, and re options let the "package" itself be highlighted by
" the usual rules. " the usual rules.
syn region goPackageComment start=/\v(\/\/.*\n)+\s*package/ syn region goPackageComment start=/\v(\/\/.*\n)+\s*package/
\ end=/\v\n\s*package/he=e-7,me=e-7,re=e-7 \ end=/\v\n\s*package/he=e-7,me=e-7,re=e-7
\ contains=@goCommentGroup,@Spell \ contains=@goCommentGroup,@Spell
hi def link goPackageComment Comment hi def link goPackageComment Comment
endif endif
@ -366,3 +376,5 @@ endif
syn sync minlines=500 syn sync minlines=500
let b:current_syntax = "go" let b:current_syntax = "go"
" vim: sw=2 ts=2 et

View file

@ -1,5 +1,5 @@
if exists("b:current_syntax") if exists("b:current_syntax")
finish finish
endif endif
syn match godefStackComment '^".*' syn match godefStackComment '^".*'
@ -16,3 +16,5 @@ hi def link godefStackComment Comment
hi def link godefStackCurrentPosition Special hi def link godefStackCurrentPosition Special
hi def link godefStackFilename Directory hi def link godefStackFilename Directory
hi def link godefStackEntryLocationNumber LineNr hi def link godefStackEntryLocationNumber LineNr
" vim: sw=2 ts=2 et

View file

@ -1,9 +1,9 @@
if exists("b:current_syntax") if exists("b:current_syntax")
finish finish
endif endif
if !exists("main_syntax") if !exists("main_syntax")
let main_syntax = 'html' let main_syntax = 'html'
endif endif
runtime! syntax/gotexttmpl.vim runtime! syntax/gotexttmpl.vim
@ -12,4 +12,4 @@ unlet b:current_syntax
let b:current_syntax = "gohtmltmpl" let b:current_syntax = "gohtmltmpl"
" vim:ts=4:sw=4:et " vim: sw=2 ts=2 et

View file

@ -6,7 +6,7 @@
" 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")
finish finish
endif endif
syn case match syn case match
@ -82,4 +82,4 @@ hi def link goTplComment Comment
let b:current_syntax = "gotexttmpl" let b:current_syntax = "gotexttmpl"
" vim:ts=4:sw=4:et " vim: sw=2 ts=2 et

View file

@ -1,5 +1,5 @@
if exists("b:current_syntax") if exists("b:current_syntax")
finish finish
endif endif
let b:current_syntax = "vimgo" let b:current_syntax = "vimgo"
@ -9,3 +9,5 @@ syn region goTitle start="\%1l" end=":"
hi def link goInterface Type hi def link goInterface Type
hi def link goTitle Label hi def link goTitle Label
" vim: sw=2 ts=2 et

View file

@ -199,10 +199,21 @@ highlight link multiple_cursors_visual Visual
## FAQ ## FAQ
**Q** <kbd>CTRL</kbd>+<kbd>n</kbd> doesn't seem to work in gVIM? #### **Q** <kbd>CTRL</kbd>+<kbd>n</kbd> doesn't seem to work in gVIM?
**A** Try setting `set selection=inclusive` in your `~/.gvimrc` **A** Try setting `set selection=inclusive` in your `~/.gvimrc`
#### **Q** How can I select `n` keywords with several keystrokes? I have tried `200<C-n>` which does not work.
**A** You can use :MultipleCursorsFind keyword. I have this binding in my vimrc:
```VimL
nnoremap <silent> <M-j> :MultipleCursorsFind <C-R>/<CR>
vnoremap <silent> <M-j> :MultipleCursorsFind <C-R>/<CR>
```
This allows one to a) search for the keyword using `*` b) turn search results into cursors with `Alt-j`.
## Known Issues ## Known Issues
- Select mode is not implemented - Select mode is not implemented

View file

@ -14,6 +14,7 @@ additional contributions from:
* [asymmetric](https://github.com/asymmetric) * [asymmetric](https://github.com/asymmetric)
* [bpugh](https://github.com/bpugh) * [bpugh](https://github.com/bpugh)
* [bruno-](https://github.com/bruno-) * [bruno-](https://github.com/bruno-)
* [CharlesGueunet](https://github.com/CharlesGueunet)
* [darkwise](https://github.com/darkwise) * [darkwise](https://github.com/darkwise)
* [dreviejo](https://github.com/dreviejo) * [dreviejo](https://github.com/dreviejo)
* [fish-face](https://github.com/fish-face) * [fish-face](https://github.com/fish-face)
@ -40,6 +41,7 @@ additional contributions from:
* [redpill](https://github.com/redpill) * [redpill](https://github.com/redpill)
* [rglassett](http://github.com/rglassett) * [rglassett](http://github.com/rglassett)
* [robhudson](https://github.com/robhudson) * [robhudson](https://github.com/robhudson)
* [shinymayhem](https://github.com/shinymayhem)
* [Shraymonks](https://github.com/shraymonks) * [Shraymonks](https://github.com/shraymonks)
* [sickill](https://github.com/sickill) * [sickill](https://github.com/sickill)
* [statik](https://github.com/statik) * [statik](https://github.com/statik)

View file

@ -87,7 +87,7 @@ languages. For this we provide two options: scope aliases and the
`:SnipMateLoadScope` command. Scope aliases simply say "whenever this scope is `:SnipMateLoadScope` command. Scope aliases simply say "whenever this scope is
loaded, also load this other scope: loaded, also load this other scope:
let g:snipMate = {} let g:snipMate = get(g:, 'snipMate', {}) " Allow for vimrc re-sourcing
let g:snipMate.scope_aliases = {} let g:snipMate.scope_aliases = {}
let g:snipMate.scope_aliases['ruby'] = 'ruby,rails' let g:snipMate.scope_aliases['ruby'] = 'ruby,rails'
@ -98,6 +98,16 @@ does `:SnipMateLoadScope rails` when editing a Rails project for example.
## Release Notes ## ## Release Notes ##
### 0.89 - 2016-05-29 ###
* Various regex updates to legacy parser
* Addition of double bang syntax to completely remove a snippet from lookup
* Group various SnipMate autocommands
* Support setting 'shiftwidth' to 0
* Parser now operates linewise, adding some flexibility
* Mirror substitutions are more literal
* Mirror length is calculated correctly when substitutions occur
### 0.88 - 2015-04-04 ### ### 0.88 - 2015-04-04 ###
* Implement simple caching * Implement simple caching

View file

@ -28,7 +28,8 @@ function! snipMate#expandSnip(snip, version, col) abort
let [snippet, b:snip_state.stops] = snipmate#parse#snippet(a:snip) let [snippet, b:snip_state.stops] = snipmate#parse#snippet(a:snip)
" Build stop/mirror info " Build stop/mirror info
let b:snip_state.stop_count = s:build_stops(snippet, b:snip_state.stops, lnum, col, indent) let b:snip_state.stop_count = s:build_stops(snippet, b:snip_state.stops, lnum, col, indent)
let snipLines = snipMate#sniplist_str(snippet, b:snip_state.stops) let snipLines = map(copy(snippet),
\ 'snipMate#sniplist_str(v:val, b:snip_state.stops)')
else else
let snippet = snipmate#legacy#process_snippet(a:snip) let snippet = snipmate#legacy#process_snippet(a:snip)
let [b:snip_state.stops, b:snip_state.stop_count] = snipmate#legacy#build_stops(snippet, lnum, col - indent, indent) let [b:snip_state.stops, b:snip_state.stop_count] = snipmate#legacy#build_stops(snippet, lnum, col - indent, indent)
@ -77,11 +78,11 @@ function! snipMate#expandSnip(snip, version, col) abort
endfunction endfunction
function! snipMate#placeholder_str(num, stops) abort function! snipMate#placeholder_str(num, stops) abort
return snipMate#sniplist_str(a:stops[a:num].placeholder, a:stops)[0] return snipMate#sniplist_str(a:stops[a:num].placeholder, a:stops)
endfunction endfunction
function! snipMate#sniplist_str(snippet, stops) abort function! snipMate#sniplist_str(snippet, stops) abort
let lines = [''] let str = ''
let pos = 0 let pos = 0
let add_to = 1 let add_to = 1
let seen_stops = [] let seen_stops = []
@ -90,110 +91,82 @@ function! snipMate#sniplist_str(snippet, stops) abort
let item = a:snippet[pos] let item = a:snippet[pos]
if type(item) == type('') if type(item) == type('')
if add_to let str .= item
let lines[-1] .= item
else
call add(lines, item)
endif
let add_to = 0
elseif type(item) == type([]) elseif type(item) == type([])
let lines[-1] .= snipMate#placeholder_str(item[0], a:stops) let str .= snipMate#placeholder_str(item[0], a:stops)
let add_to = 1
endif endif
let pos += 1 let pos += 1
unlet item " avoid E706 unlet item " avoid E706
endwhile endwhile
return lines return str
endfunction endfunction
function! s:build_stops(snippet, stops, lnum, col, indent) abort function! s:build_stops(snippet, stops, lnum, col, indent) abort
let stops = a:stops let stops = a:stops
let line = a:lnum let lnum = a:lnum
let col = a:col let col = a:col
for [id, dict] in items(stops) for line in a:snippet
for i in dict.instances let col = s:build_loc_info(line, stops, lnum, col, [])
if len(i) > 1 && type(i[1]) != type({}) if line isnot a:snippet[-1]
if !has_key(dict, 'placeholder') let lnum += 1
let dict.placeholder = i[1:] let col = a:indent
else
unlet i[1:]
endif
endif
endfor
if !has_key(dict, 'placeholder')
let dict.placeholder = []
let j = 0
while len(dict.instances[j]) > 1
let j += 1
endwhile
call add(dict.instances[j], '')
endif endif
unlet dict.instances
endfor endfor
let [line, col] = s:build_loc_info(a:snippet, stops, line, col, a:indent)
" add zero tabstop if it doesn't exist and then link it to the highest stop " add zero tabstop if it doesn't exist and then link it to the highest stop
" number " number
let stops[0] = get(stops, 0, let stops[0] = get(stops, 0,
\ { 'placeholder' : [], 'line' : line, 'col' : col }) \ { 'placeholder' : [], 'line' : lnum, 'col' : col })
let stop_count = max(keys(stops)) + 2 let stop_count = max(keys(stops)) + 2
let stops[stop_count - 1] = stops[0] let stops[stop_count - 1] = stops[0]
return stop_count return stop_count
endfunction endfunction
function! s:build_loc_info(snippet, stops, line, col, indent) abort function! s:build_loc_info(snippet, stops, lnum, col, seen_items) abort
let stops = a:stops let stops = a:stops
let line = a:line let lnum = a:lnum
let col = a:col let col = a:col
let pos = 0 let pos = 0
let in_text = 0 let in_text = 0
let seen_items = a:seen_items
while pos < len(a:snippet) for item in a:snippet
let item = a:snippet[pos]
if type(item) == type('') if type(item) == type('')
if in_text
let line += 1
let col = a:indent
endif
let col += len(item) let col += len(item)
let in_text = 1
elseif type(item) == type([]) elseif type(item) == type([])
let id = item[0] let id = item[0]
if len(item) > 1 && type(item[1]) != type({}) let stub = item[-1]
let stops[id].line = line let stub.line = lnum
let stops[id].col = col let stub.col = col
let [line, col] = s:build_loc_info(item[1:], stops, line, col, a:indent) call s:add_update_objects(stub, seen_items)
if len(item) > 2 && type(item[1]) != type({})
let col = s:build_loc_info(item[1:-2], stops, lnum, col, seen_items)
else else
call s:add_mirror(stops, id, line, col, item)
let col += len(snipMate#placeholder_str(id, stops)) let col += len(snipMate#placeholder_str(id, stops))
endif endif
let in_text = 0 let in_text = 0
endif endif
let pos += 1
unlet item " avoid E706 unlet item " avoid E706
endwhile endfor
return [line, col] return col
endfunction endfunction
function! s:add_mirror(stops, id, line, col, item) abort function! s:add_update_objects(object, targets) abort
let stops = a:stops let targets = a:targets
let item = a:item
let stops[a:id].mirrors = get(stops[a:id], 'mirrors', []) for item in targets
let mirror = get(a:item, 1, {}) let item.update_objects = get(item, 'update_objects', [])
let mirror.line = a:line call add(item.update_objects, a:object)
let mirror.col = a:col endfor
call add(stops[a:id].mirrors, mirror)
if len(item) == 1 call add(targets, a:object)
call add(item, mirror)
endif
endfunction endfunction
" reads a .snippets file " reads a .snippets file

View file

@ -113,7 +113,7 @@ function! s:state_update_changes() dict abort
return self.remove() return self.remove()
endif endif
call self.update(self.cur_stop, change_len) call self.update(self.cur_stop, change_len, change_len)
if !empty(self.mirrors) if !empty(self.mirrors)
call self.update_mirrors(change_len) call self.update_mirrors(change_len)
endif endif
@ -141,14 +141,37 @@ function! s:state_update_mirrors(change) dict abort
endif endif
endfor endfor
call self.update(mirror, changeLen) if has_key(mirror, 'oldSize')
" recover the old size deduce the endline
let oldSize = mirror.oldSize
else
" first time, we use the intitial size
let oldSize = strlen(newWord)
endif
" Split the line into three parts: the mirror, what's before it, and " Split the line into three parts: the mirror, what's before it, and
" what's after it. Then combine them using the new mirror string. " what's after it. Then combine them using the new mirror string.
" Subtract one to go from column index to byte index " Subtract one to go from column index to byte index
let theline = getline(mirror.line) let theline = getline(mirror.line)
let update = strpart(theline, 0, mirror.col - 1)
let update .= substitute(newWord, get(mirror, 'pat', ''), get(mirror, 'sub', ''), get(mirror, 'flags', '')) " part before the current mirror
let update .= strpart(theline, mirror.col + self.end_col - self.start_col - a:change - 1) let beginline = strpart(theline, 0, mirror.col - 1)
" current mirror transformation, and save size
let wordMirror= substitute(newWord, get(mirror, 'pat', ''), get(mirror, 'sub', ''), get(mirror, 'flags', ''))
let mirror.oldSize = strlen(wordMirror)
" end of the line, use the oldSize because with the transformation,
" the size of the mirror can be different from those of the snippet
let endline = strpart(theline, mirror.col + oldSize -1)
" Update other object on the line
call self.update(mirror, changeLen, mirror.oldSize - oldSize)
" reconstruct the line
let update = beginline.wordMirror.endline
call setline(mirror.line, update) call setline(mirror.line, update)
endfor endfor
@ -179,17 +202,17 @@ function! s:state_find_update_objects(item) dict abort
return item.update_objects return item.update_objects
endfunction endfunction
function! s:state_update(item, change_len) dict abort function! s:state_update(item, change_len, mirror_change) dict abort
let item = a:item let item = a:item
if exists('item.update_objects') if !exists('item.update_objects')
let to_update = item.update_objects let item.update_objects = self.find_update_objects(a:item)
else
let to_update = self.find_update_objects(a:item)
let item.update_objects = to_update
endif endif
let to_update = item.update_objects
for obj in to_update for obj in to_update
let obj.col += a:change_len " object does not necessarly have the same decalage
" than mirrors if mirrors use regexp
let obj.col += a:mirror_change
if obj is self.cur_stop if obj is self.cur_stop
let self.start_col += a:change_len let self.start_col += a:change_len
let self.end_col += a:change_len let self.end_col += a:change_len

View file

@ -12,8 +12,7 @@ function! snipmate#legacy#process_snippet(snip) abort
else else
let visual = '' let visual = ''
endif endif
let snippet = substitute(snippet, '\n\(\t\+\).\{-\}\zs{VISUAL}', let snippet = s:substitute_visual(snippet, visual)
\ substitute(escape(visual, '%\'), "\n", "\n\\\\1", 'g'), 'g')
" Evaluate eval (`...`) expressions. " Evaluate eval (`...`) expressions.
" Backquotes prefixed with a backslash "\" are ignored. " Backquotes prefixed with a backslash "\" are ignored.
@ -118,6 +117,16 @@ function! snipmate#legacy#build_stops(snip, lnum, col, indent) abort
return [stops, i + 1] return [stops, i + 1]
endfunction endfunction
function! s:substitute_visual(snippet, visual) abort
let lines = []
for line in split(a:snippet, "\n")
let indent = matchstr(line, '^\t\+')
call add(lines, substitute(line, '{VISUAL}',
\ substitute(escape(a:visual, '%\'), "\n", "\n" . indent, 'g'), 'g'))
endfor
return join(lines, "\n")
endfunction
" Counts occurences of haystack in needle " Counts occurences of haystack in needle
function! s:count(haystack, needle) abort function! s:count(haystack, needle) abort
let counter = 0 let counter = 0

View file

@ -5,6 +5,7 @@ function! s:sfile() abort
endfunction endfunction
let s:parser_proto = {} let s:parser_proto = {}
let s:special_chars = "$`\n"
function! s:new_parser(text) abort function! s:new_parser(text) abort
let ret = copy(s:parser_proto) let ret = copy(s:parser_proto)
@ -14,6 +15,7 @@ function! s:new_parser(text) abort
let ret.indent = 0 let ret.indent = 0
let ret.value = [] let ret.value = []
let ret.vars = {} let ret.vars = {}
let ret.stored_lines = []
call ret.advance() call ret.advance()
return ret return ret
endfunction endfunction
@ -82,35 +84,56 @@ function! s:parser_varend() dict abort
endfunction endfunction
function! s:parser_placeholder() dict abort function! s:parser_placeholder() dict abort
return self.parse('}') let ret = self.text('}')
return empty(ret) ? [''] : ret
endfunction endfunction
function! s:parser_subst() dict abort function! s:parser_subst() dict abort
let ret = {} let ret = {}
let ret.pat = join(self.text('/', 1)) let ret.pat = self.pat()
if self.same('/') if self.same('/')
let ret.sub = join(self.text('/}')) let ret.sub = self.pat(1)
endif endif
if self.same('/') if self.same('/')
let ret.flags = join(self.text('}', 1)) let ret.flags = self.pat(1)
endif endif
return ret return ret
endfunction endfunction
function! s:parser_pat(...) dict abort
let val = ''
while self.pos < self.len
if self.same('\')
if self.next == '/'
let val .= '/'
call self.advance()
elseif a:0 && self.next == '}'
let val .= '}'
call self.advance()
else
let val .= '\'
endif
elseif self.next == '/' || a:0 && self.next == '}'
break
else
let val .= self.next
call self.advance()
endif
endwhile
return val
endfunction
function! s:parser_expr() dict abort function! s:parser_expr() dict abort
let str = join(self.text('`', 1)) let str = self.string('`')
call self.same('`') call self.same('`')
return snipmate#util#eval(str) return snipmate#util#eval(str)
endfunction endfunction
function! s:parser_text(...) dict abort function! s:parser_string(till, ...) dict abort
let res = []
let val = '' let val = ''
if a:0 == 2 && a:2 let till = '\V\[' . escape(a:till, '\') . ']'
let till = '\V' . escape(a:1, '\')
else
let till = '[`$' . (a:0 ? a:1 : '') . ']'
endif
while self.pos < self.len while self.pos < self.len
if self.same('\') if self.same('\')
@ -120,11 +143,6 @@ function! s:parser_text(...) dict abort
call self.advance() call self.advance()
elseif self.next =~# till elseif self.next =~# till
break break
elseif self.next == "\n"
call add(res, val)
let val = ''
let self.indent = 0
call self.advance()
elseif self.next == "\t" elseif self.next == "\t"
let self.indent += 1 let self.indent += 1
let val .= s:indent(1) let val .= s:indent(1)
@ -135,55 +153,77 @@ function! s:parser_text(...) dict abort
endif endif
endwhile endwhile
call add(res, val) return val
return res
endfunction endfunction
function! s:parser_parse(...) dict abort function! s:join_consecutive_strings(list) abort
let ret = a:0 ? [] : self.value let list = a:list
let pos = 0
while pos + 1 < len(list)
if type(list[pos]) == type('') && type(list[pos+1]) == type('')
let list[pos] .= list[pos+1]
call remove(list, pos + 1)
else
let pos += 1
endif
endwhile
endfunction
function! s:parser_text(till) dict abort
let ret = []
while self.pos < self.len while self.pos < self.len
let lines = []
if self.same('$') if self.same('$')
let var = self.var() let var = self.var()
if !empty(var) if !empty(var)
if var[0] is# 'VISUAL' if var[0] is# 'VISUAL'
let add_to = s:visual_placeholder(var, self.indent) let lines = s:visual_placeholder(var, self.indent)
if !empty(ret) && type(ret[-1]) == type('')
let ret[-1] .= add_to[0]
else
call add(ret, add_to[0])
endif
call extend(ret, add_to[1:-1])
elseif var[0] >= 0 elseif var[0] >= 0
call add(ret, var) call add(ret, var)
call self.add_var(var) call self.add_var(var)
endif endif
endif endif
elseif self.same('`') elseif self.same('`')
let add_to = self.expr() let lines = split(self.expr(), "\n", 1)
if !empty(ret) && type(ret[-1]) == type('')
let ret[-1] .= add_to
else
call add(ret, add_to)
endif
else else
let text = a:0 ? self.text(a:1) : self.text() let lines = [self.string(a:till . s:special_chars)]
if exists('add_to')
let ret[-1] .= text[0]
call remove(text, 0)
unlet add_to
endif
call extend(ret, text)
endif endif
if a:0 && self.next == a:1
if !empty(lines)
call add(ret, lines[0])
call extend(self.stored_lines, lines[1:])
endif
" Empty lines are ignored if this is tested at the start of an iteration
if self.next ==# a:till
break break
endif endif
endwhile endwhile
call s:join_consecutive_strings(ret)
return ret return ret
endfunction endfunction
call extend(s:parser_proto, snipmate#util#add_methods(s:sfile(), 'parser', function! s:parser_line() dict abort
\ [ 'advance', 'same', 'id', 'add_var', 'var', 'varend', let ret = []
\ 'placeholder', 'subst', 'expr', 'text', 'parse' ]), 'error') if !empty(self.stored_lines)
call add(ret, remove(self.stored_lines, 0))
else
call extend(ret, self.text("\n"))
call self.same("\n")
endif
let self.indent = 0
return ret
endfunction
function! s:parser_parse() dict abort
while self.pos < self.len || !empty(self.stored_lines)
let line = self.line()
call add(self.value, line)
endwhile
endfunction
function! s:indent(count) abort function! s:indent(count) abort
if &expandtab if &expandtab
@ -211,9 +251,59 @@ function! s:visual_placeholder(var, indent) abort
return content return content
endfunction endfunction
function! snipmate#parse#snippet(text) abort function! s:parser_create_stubs() dict abort
for [id, dict] in items(self.vars)
for i in dict.instances
if len(i) > 1 && type(i[1]) != type({})
if !has_key(dict, 'placeholder')
let dict.placeholder = i[1:]
call add(i, dict)
else
unlet i[1:]
call s:create_mirror_stub(i, dict)
endif
else
call s:create_mirror_stub(i, dict)
endif
endfor
if !has_key(dict, 'placeholder')
let dict.placeholder = []
let j = 0
while len(dict.instances[j]) > 2
let j += 1
endwhile
let oldstub = remove(dict.instances[j], 1, -1)[-1]
call add(dict.instances[j], '')
call add(dict.instances[j], dict)
call filter(dict.mirrors, 'v:val isnot oldstub')
endif
unlet dict.instances
endfor
endfunction
function! s:create_mirror_stub(mirror, dict)
let mirror = a:mirror
let dict = a:dict
let stub = get(mirror, 1, {})
call add(mirror, stub)
let dict.mirrors = get(dict, 'mirrors', [])
call add(dict.mirrors, stub)
endfunction
function! snipmate#parse#snippet(text, ...) abort
let parser = s:new_parser(a:text) let parser = s:new_parser(a:text)
call parser.parse() call parser.parse()
if !(a:0 && a:1)
call parser.create_stubs()
endif
unlet! b:snipmate_visual unlet! b:snipmate_visual
return [parser.value, parser.vars] return [parser.value, parser.vars]
endfunction endfunction
call extend(s:parser_proto, snipmate#util#add_methods(s:sfile(), 'parser',
\ [ 'advance', 'same', 'id', 'add_var', 'var', 'varend',
\ 'line', 'string', 'create_stubs', 'pat',
\ 'placeholder', 'subst', 'expr', 'text', 'parse',
\ ]), 'error')

View file

@ -1,7 +1,6 @@
*SnipMate.txt* Plugin for using TextMate-style snippets in Vim. *SnipMate.txt* Plugin for using TextMate-style snippets in Vim.
SnipMate *snippet* *snippets* *SnipMate* SnipMate *snippet* *snippets* *SnipMate*
Last Change: December 27, 2009
1. Description |SnipMate-description| 1. Description |SnipMate-description|
2. Usage |SnipMate-usage| 2. Usage |SnipMate-usage|
@ -504,6 +503,15 @@ Perhaps some of these features will be added in a later release.
============================================================================== ==============================================================================
CHANGELOG *SnipMate-changelog* CHANGELOG *SnipMate-changelog*
0.89 - 2016-05-29
-----------------
* Various regex updates to legacy parser Addition of double bang syntax to
* completely remove a snippet from lookup Group various SnipMate autocommands
* Support setting 'shiftwidth' to 0 Parser now operates linewise, adding some
* flexibility Mirror substitutions are more literal Mirror length is
* calculated correctly when substitutions occur
0.88 - 2015-04-04 0.88 - 2015-04-04
----------------- -----------------

View file

@ -2,27 +2,27 @@ describe 'snippet parser'
before before
function! Parse(snippet, ...) function! Parse(snippet, ...)
let [snip, stops] = snipmate#parse#snippet(a:snippet) let [snip, stops] = snipmate#parse#snippet(a:snippet, (a:0 ? a:1 : 1))
return a:0 ? [snip, stops] : snip return (a:0 > 1 && a:2) ? [snip, stops] : snip
endfunction endfunction
let b:snipmate_visual = 'testvisual' let b:snipmate_visual = 'testvisual'
end end
it 'parses numeric $id and ${id} vars as [id] lists' it 'parses numeric $id and ${id} vars as [id] lists'
let expect = [[1234567890]] let expect = [[[1234567890]]]
Expect Parse('$1234567890') == expect Expect Parse('$1234567890') == expect
Expect Parse('${1234567890}') == expect Expect Parse('${1234567890}') == expect
end end
it 'disregards $ or ${ followed by a non-id' it 'disregards $ or ${ followed by a non-id'
Expect Parse('$x1') == ['x1'] Expect Parse('$x1') == [['x1']]
Expect Parse('${x}1') == ['x}1'] Expect Parse('${x}1') == [['x}1']]
Expect Parse('$VISUA1') == ['VISUA1'] Expect Parse('$VISUA1') == [['VISUA1']]
Expect Parse('${VISUA}1') == ['VISUA}1'] Expect Parse('${VISUA}1') == [['VISUA}1']]
end end
it 'gathers references to each instance of each stop id' it 'gathers references to each instance of each stop id'
let [snip, b:stops] = Parse('x$1x${2:x$1x}x$1x${1/a/b}x$VISUALx', 1) let [snip, b:stops] = Parse('x$1x${2:x$1x}x$1x${1/a/b}x$VISUALx', 1, 1)
function! InstanceFound(list) function! InstanceFound(list)
return !empty(filter(copy(b:stops[a:list[0]].instances), return !empty(filter(copy(b:stops[a:list[0]].instances),
\ 'v:val is a:list')) \ 'v:val is a:list'))
@ -36,87 +36,107 @@ describe 'snippet parser'
unlet item " E732 unlet item " E732
endfor endfor
endfunction endfunction
call CheckList(snip) call CheckList(snip[0])
end end
it 'parses mirror substitutions ${n/pat/sub} as [n, {...}]' it 'parses mirror substitutions ${n/pat/sub} as [n, {...}]'
let expect = [[1, { 'pat' : 'abc', 'sub' : 'def' }]] let expect = [[[1, { 'pat' : 'abc', 'sub' : 'def' }]]]
Expect Parse('${1/abc/def}') == expect Expect Parse('${1/abc/def}') == expect
let expect[0][1].flags = '' let expect[0][0][1].flags = ''
Expect Parse('${1/abc/def/}') == expect Expect Parse('${1/abc/def/}') == expect
let expect[0][1].flags = 'g' let expect[0][0][1].flags = 'g'
Expect Parse('${1/abc/def/g}') == expect Expect Parse('${1/abc/def/g}') == expect
end end
it 'reads patterns literally except for "\/"'
Expect Parse('${1/\a\/b/\c\/d\}}') == [[[1, { 'pat' : '\a/b', 'sub' : '\c/d}' }]]]
end
it 'parses vars with placeholders as [id, placeholder] lists' it 'parses vars with placeholders as [id, placeholder] lists'
Expect Parse('${1:abc}') == [[1, 'abc']] Expect Parse('${1:abc}') == [[[1, 'abc']]]
end end
it 'evaluates backtick expressions' it 'evaluates backtick expressions'
Expect Parse('`fnamemodify("x.y", ":r")`') == ['x'] Expect Parse('`fnamemodify("x.y", ":r")`') == [['x']]
end end
it 'parses placeholders for vars and other specials' it 'parses placeholders for vars and other specials'
let text = 'a `fnamemodify("x.y", ":r")` ${2:(${3/a/b})}' let text = 'a `fnamemodify("x.y", ":r")` ${2:(${3/a/b})}'
let expect = ['a x ', [2, '(', [3, { 'pat' : 'a', 'sub' : 'b' }], ')']] let expect = ['a x ', [2, '(', [3, { 'pat' : 'a', 'sub' : 'b' }], ')']]
Expect Parse(text) == expect Expect Parse(text) == [expect]
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, &ts' 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"]]
" &et -> &sts or &sw " &et -> &sts or &sw
setl et sts=2 sw=3 setl et sts=2 sw=3
Expect Parse("abc\tdef\n\t\tghi") == ["abc def", " ghi"] Expect Parse("abc\tdef\n\t\tghi") == [["abc def"], [" ghi"]]
setl et sts=0 sw=3 setl et sts=0 sw=3
Expect Parse("abc\tdef\n\t\tghi") == ["abc def", " ghi"] Expect Parse("abc\tdef\n\t\tghi") == [["abc def"], [" ghi"]]
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 " See #227
if exists('*shiftwidth') if exists('*shiftwidth')
setl et sts=0 sw=0 ts=3 setl et sts=0 sw=0 ts=3
Expect Parse("abc\tdef\n\t\tghi") == ["abc def", " ghi"] Expect Parse("abc\tdef\n\t\tghi") == [["abc def"], [" ghi"]]
endif 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'
Expect Parse('x\x') == ['xx'] Expect Parse('x\x') == [['xx']]
Expect Parse('x\\x') == ['x\x'] Expect Parse('x\\x') == [['x\x']]
Expect Parse("x\\\nx") == ['xx'] Expect Parse("x\\\nx") == [['xx']]
Expect Parse('x\$1') == ['x$1'] Expect Parse('x\$1') == [['x$1']]
Expect Parse('${1:\}}') == [[1, '}']] Expect Parse('${1:\}}') == [[[1, '}']]]
Expect Parse('${1/\//\}}') == [[1, { 'pat' : '/', 'sub' : '}' }]] Expect Parse('`fnamemodify("\`.x", ":r")`') == [['`']]
Expect Parse('`fnamemodify("\`.x", ":r")`') == ['`'] Expect Parse('\`x\`') == [['`x`']]
Expect Parse('\`x\`') == ['`x`']
end end
it 'splits text at newlines' it 'splits text at newlines'
Expect Parse("x\nx") == ['x', 'x'] Expect Parse("x\nx") == [['x'], ['x']]
end end
it 'joins evaluated expressions to surrounding text on the same line' it 'joins evaluated expressions to surrounding text on the same line'
let g:foo = 'bar' let g:foo = 'bar'
Expect Parse("x`g:foo`x") == ['xbarx'] Expect Parse("x`g:foo`x") == [['xbarx']]
Expect Parse("x`g:foo`\nx") == ['xbar', 'x'] Expect Parse("x`g:foo`\nx") == [['xbar'], ['x']]
Expect Parse("x\n`g:foo`x") == ['x', 'barx'] Expect Parse("x\n`g:foo`x") == [['x'], ['barx']]
end
it 'adds empty strings before/after vars if at the start/end of a line'
Expect Parse("x$1\nx") == ['x', [1], '', 'x']
Expect Parse("x\n$1x") == ['x', '', [1], 'x']
end end
it 'expands $VISUAL placeholders with any indents' it 'expands $VISUAL placeholders with any indents'
Expect Parse("x$VISUALx") == ['xtestvisualx'] Expect Parse("x$VISUALx") == [['xtestvisualx']]
let b:snipmate_visual = " foo\nbar\n baz" let b:snipmate_visual = " foo\nbar\n baz"
setl noet setl noet
Expect Parse("\tx\n\t$VISUAL\nx") == ["\tx", "\t foo", "\tbar", "\t baz", "x"] Expect Parse("\tx\n\t$VISUAL\nx") == [["\tx"], ["\t foo"], ["\tbar"],
\ ["\t baz"], ["x"]]
end
it 'determines which var with an id is the stop'
let [snip, stops] = Parse("$1$1$1", 0, 1)
Expect snip == [[[1, "", stops[1]], [1, {}], [1, {}]]]
let [snip, stops] = Parse("$1${1}$1", 0, 1)
Expect snip == [[[1, "", stops[1]], [1, {}], [1, {}]]]
let [snip, stops] = Parse("$1${1:}$1", 0, 1)
Expect snip == [[[1, {}], [1, "", stops[1]], [1, {}]]]
end
it 'picks the first of many possible stops'
let [snip, stops] = Parse("$1${1:foo}${1:bar}", 0, 1)
Expect snip == [[[1, {}], [1, "foo", stops[1]], [1, {}]]]
end
it 'represents empty lines as an empty string'
Expect Parse("foo\n\nbar") == [['foo'], [''], ['bar']]
end end
end end

View file

@ -186,7 +186,7 @@ snippet iblock "" bi
{% block ${1:blockname} %}${VISUAL}{% endblock $1 %} {% block ${1:blockname} %}${VISUAL}{% endblock $1 %}
endsnippet endsnippet
snippet csfr "" bi snippet csrf "" bi
{% csrf_token %} {% csrf_token %}
endsnippet endsnippet

View file

@ -21,7 +21,7 @@ def nl(snip):
snip.rv += " " snip.rv += " "
def getArgs(group): def getArgs(group):
import re import re
word = re.compile('[a-zA-Z><.]+ \w+') word = re.compile('[a-zA-Z0-9><.]+ \w+')
return [i.split(" ") for i in word.findall(group) ] return [i.split(" ") for i in word.findall(group) ]
def camel(word): def camel(word):
@ -109,7 +109,7 @@ for i in args:
snip.rv += "\n\tprivate " + i[0] + " " + i[1]+ ";" snip.rv += "\n\tprivate " + i[0] + " " + i[1]+ ";"
if len(args) > 0: if len(args) > 0:
snip.rv += "\n"` snip.rv += "\n"`
public `!p snip.rv = snip.basename or "unknown"`($1) { `!p public `!p snip.rv = snip.basename or "unknown"`($1) {`!p
args = getArgs(t[1]) args = getArgs(t[1])
for i in args: for i in args:
snip.rv += "\n\t\tthis." + i[1] + " = " + i[1] + ";" snip.rv += "\n\t\tthis." + i[1] + " = " + i[1] + ";"
@ -123,8 +123,8 @@ for i in args:
snip.rv += "\n\tpublic void set" + camel(i[1]) + "(" + i[0] + " " + i[1] + ") {\n" + "\ snip.rv += "\n\tpublic void set" + camel(i[1]) + "(" + i[0] + " " + i[1] + ") {\n" + "\
\tthis." + i[1] + " = " + i[1] + ";\n\t}\n" \tthis." + i[1] + " = " + i[1] + ";\n\t}\n"
snip.rv += "\n\tpublic " + i[0] + " get" + camel(i[1]) + "() {\ snip.rv += "\n\tpublic " + i[0] + " get" + camel(i[1]) + "() {\n\
\n\t\treturn " + i[1] + ";\n\t}\n" \treturn " + i[1] + ";\n\t}\n"
` `
} }
endsnippet endsnippet
@ -138,7 +138,7 @@ for i in args:
snip.rv += "\n\tprivate " + i[0] + " " + i[1]+ ";" snip.rv += "\n\tprivate " + i[0] + " " + i[1]+ ";"
if len(args) > 0: if len(args) > 0:
snip.rv += "\n"` snip.rv += "\n"`
public `!p snip.rv = snip.basename or "unknown"`($1) { `!p public `!p snip.rv = snip.basename or "unknown"`($1) {`!p
args = getArgs(t[1]) args = getArgs(t[1])
for i in args: for i in args:
snip.rv += "\n\t\tthis.%s = %s;" % (i[1], i[1]) snip.rv += "\n\t\tthis.%s = %s;" % (i[1], i[1])
@ -266,7 +266,7 @@ for i in args:
snip.rv += "\n\tprivate " + i[0] + " " + i[1]+ ";" snip.rv += "\n\tprivate " + i[0] + " " + i[1]+ ";"
if len(args) > 0: if len(args) > 0:
snip.rv += "\n"` snip.rv += "\n"`
public `!p snip.rv = snip.basename or "unknown"`($1) { `!p public `!p snip.rv = snip.basename or "unknown"`($1) {`!p
args = getArgs(t[1]) args = getArgs(t[1])
for i in args: for i in args:
snip.rv += "\n\t\tthis.%s = %s;" % (i[1], i[1]) snip.rv += "\n\t\tthis.%s = %s;" % (i[1], i[1])
@ -326,11 +326,11 @@ snippet md "Method With javadoc" b
* ${7:Short Description}`!p * ${7:Short Description}`!p
for i in getArgs(t[4]): for i in getArgs(t[4]):
snip.rv += "\n\t * @param " + i[1] + " usage..."` snip.rv += "\n\t * @param " + i[1] + " usage..."`
* `!p *`!p
if "throws" in t[5]: if "throws" in t[5]:
snip.rv = "\n\t * @throws " + t[6] snip.rv = "\n\t * @throws " + t[6]
else: else:
snip.rv = ""` `!p snip.rv = ""``!p
if not "void" in t[2]: if not "void" in t[2]:
snip.rv = "\n\t * @return object" snip.rv = "\n\t * @return object"
else: else:
@ -356,8 +356,7 @@ endsnippet
snippet /se?tge?t|ge?tse?t|gs/ "setter and getter" br snippet /se?tge?t|ge?tse?t|gs/ "setter and getter" br
public void set${1:Name}(${2:String} `!p snip.rv = mixedCase(t[1])`) { public void set${1:Name}(${2:String} `!p snip.rv = mixedCase(t[1])`) {
this.`!p snip.rv = mixedCase(t[1])` = `!p snip.rv = mixedCase(t[1])`; this.`!p snip.rv = mixedCase(t[1])` = `!p snip.rv = mixedCase(t[1])`;
} }`!p snip.rv += "\n"`
public $2 get$1() { public $2 get$1() {
return `!p snip.rv = mixedCase(t[1])`; return `!p snip.rv = mixedCase(t[1])`;
} }

View file

@ -4,7 +4,7 @@ snippet s "String" b
"${1:key}": "${0:value}", "${1:key}": "${0:value}",
endsnippet endsnippet
snippet n "number" b snippet n "Number" b
"${1:key}": ${0:value}, "${1:key}": ${0:value},
endsnippet endsnippet
@ -13,8 +13,39 @@ snippet a "Array" b
${VISUAL}$0 ${VISUAL}$0
], ],
endsnippet endsnippet
snippet na "Named array" b
"${1:key}": [
${VISUAL}$0
],
endsnippet
snippet o "Object" b snippet o "Object" b
{ {
${VISUAL}$0 ${VISUAL}$0
}, },
endsnippet endsnippet
snippet no "Named object" b
"${1:key}": {
${VISUAL}$0
},
endsnippet
snippet null "Null" b
"${0:key}": null,
endsnippet
global !p
def compB(t, opts):
if t:
opts = [m[len(t):] for m in opts if m.startswith(t)]
if len(opts) == 1:
return opts[0]
return "(" + '|'.join(opts) + ')'
endglobal
snippet b "Bool" b
"${1:key}": $2`!p snip.rv=compB(t[2], ['true', 'false'])`,
endsnippet

View file

@ -1,8 +1,9 @@
# Snippets for phpspec # Snippets for phpspec, to use add the following to your .vimrc
# `autocmd BufRead,BufNewFile,BufEnter *Spec.php UltiSnipsAddFiletypes php-phpspec`
priority -50 priority -50
snippet spec "phpspec class" b snippet spec "class XYZSpec extends ObjectBehaviour"
<?php <?php
namespace `!p namespace `!p
@ -22,17 +23,200 @@ class `!p
snip.rv = re.match(r'.*(?=\.)', fn).group() snip.rv = re.match(r'.*(?=\.)', fn).group()
` extends ObjectBehavior ` extends ObjectBehavior
{ {
public function it${1:_does_something}() function it_${1}()
{ {
$0 $0
} }
} }
endsnippet endsnippet
snippet it "phpspec function it..." b snippet it "function it_does_something() { ... }"
public function it${1:_does_something}() function it_${1}()
{ {
$0 ${0:${VISUAL}}
} }
endsnippet endsnippet
snippet let "function let() { ... }"
function let()
{
${0:${VISUAL}}
}
endsnippet
snippet letgo "function letgo() { ... }"
function letgo()
{
${0:${VISUAL}}
}
endsnippet
# Object construction
snippet cw "$this->beConstructedWith($arg)"
$this->beConstructedWith(${1});
endsnippet
snippet ct "$this->beConstructedThrough($methodName, [$arg])"
$this->beConstructedThrough(${1:'methodName'}, [${2:'$arg'}]);
endsnippet
# Identity and comparison matchers
snippet sreturn "$this->XYZ()->shouldReturn('value')"
$this->${1:method}()->shouldReturn(${2:'value'});
endsnippet
snippet snreturn "$this->XYZ()->shouldNotReturn('value')"
$this->${1:method}()->shouldNotReturn(${2:'value'});
endsnippet
snippet sbe "$this->XYZ()->shouldBe('value')"
$this->${1:method}()->shouldBe(${2:'value'});
endsnippet
snippet snbe "$this->XYZ()->shouldNotBe('value')"
$this->${1:method}()->shouldNotBe(${2:'value'});
endsnippet
snippet sequal "$this->XYZ()->shouldEqual('value')"
$this->${1:method}()->shouldEqual(${2:'value'});
endsnippet
snippet snequal "$this->XYZ()->shouldNotEqual('value')"
$this->${1:method}()->shouldNotEqual(${2:'value'});
endsnippet
snippet sbequalto "$this->XYZ()->shouldBeEqualTo('value')"
$this->${1:method}()->shouldBeEqualTo(${2:'value'});
endsnippet
snippet snbequalto "$this->XYZ()->shouldNotBeEqualTo('value')"
$this->${1:method}()->shouldNotBeEqualTo(${2:'value'});
endsnippet
snippet sblike "$this->XYZ()->shouldBeLike('value')"
$this->${1:method}()->shouldBeLike(${2:'value'});
endsnippet
snippet snblike "$this->XYZ()->shouldNotBeLike('value')"
$this->${1:method}()->shouldNotBeLike(${2:'value'});
endsnippet
# Throw matcher
snippet sthrowm "$this->shouldThrow('\Exception')->duringXYZ($arg)"
$this->shouldThrow(${1:'\Exception'})->during${2:Method}(${3:'$arg'});
endsnippet
snippet sthrowi "$this->shouldThrow('\Exception')->duringInstantiation()"
$this->shouldThrow(${1:'\Exception'})->duringInstantiation();
endsnippet
# Type matchers
snippet stype "$this->shouldHaveType('Type')"
$this->shouldHaveType(${1});
endsnippet
snippet sntype "$this->shouldNotHaveType('Type')"
$this->shouldNotHaveType(${1});
endsnippet
snippet srinstance "$this->shouldReturnAnInstanceOf('Type')"
$this->shouldReturnAnInstanceOf(${1});
endsnippet
snippet snrinstance "$this->shouldNotReturnAnInstanceOf('Type')"
$this->shouldNotReturnAnInstanceOf(${1});
endsnippet
snippet sbinstance "$this->shouldBeAnInstanceOf('Type')"
$this->shouldBeAnInstanceOf(${1});
endsnippet
snippet snbinstance "$this->shouldNotBeAnInstanceOf('Type')"
$this->shouldNotBeAnInstanceOf(${1});
endsnippet
snippet simplement "$this->shouldImplement('Type')"
$this->shouldImplement(${1});
endsnippet
snippet snimplement "$this->shouldNotImplement('Type')"
$this->shouldNotImplement(${1});
endsnippet
# Object state matchers
snippet sbstate "$this->shouldBeXYZ()"
$this->shouldBe${1}();
endsnippet
snippet snbstate "$this->shouldNotBeXYZ()"
$this->shouldNotBe${1}();
endsnippet
# Count matchers
snippet scount "$this->XYZ()->shouldHaveCount(7)"
$this->${1:method}()->shouldHaveCount(${2:7});
endsnippet
snippet sncount "$this->XYZ()->shouldNotHaveCount(7)"
$this->${1:method}()->shouldNotHaveCount(${2:7});
endsnippet
# Scalar type matchers
snippet sbscalar "$this->XYZ()->shouldBeString|Array|Bool()"
$this->${1:method}()->shouldBe${2:String|Array|Bool}();
endsnippet
snippet snbscalar "$this->XYZ()->shouldNotBeString|Array|Bool()"
$this->${1:method}()->shouldNotBe${2:String|Array|Bool}();
endsnippet
# Contain matcher
snippet scontain "$this->XYZ()->shouldContain('value')"
$this->${1:method}()->shouldContain(${2:'value'});
endsnippet
snippet sncontain "$this->XYZ()->shouldNotContain('value')"
$this->${1:method}()->shouldNotContain(${2:'value'});
endsnippet
# Array matchers
snippet skey "$this->XYZ()->shouldHaveKey('key')"
$this->${1:method}()->shouldHaveKey(${2:'key'});
endsnippet
snippet snkey "$this->XYZ()->shouldNotHaveKey('key')"
$this->${1:method}()->shouldNotHaveKey(${2:'key'});
endsnippet
snippet skeyvalue "$this->XYZ()->shouldHaveKeyWithValue('key', 'value')"
$this->${1:method}()->shouldHaveKeyWithValue(${2:'key'}, ${3:'value'});
endsnippet
snippet snkeyvalue "$this->XYZ()->shouldNotHaveKeyWithValue('key', 'value')"
$this->${1:method}()->shouldNotHaveKeyWithValue(${2:'key'}, ${3:'value'});
endsnippet
# String matchers
snippet sstart "$this->XYZ()->shouldStartWith('string')"
$this->${1:method}()->shouldStartWith(${2:'string'});
endsnippet
snippet snstart "$this->XYZ()->shouldNotStartWith('string')"
$this->${1:method}()->shouldNotStartWith(${2:'string'});
endsnippet
snippet send "$this->XYZ()->shouldEndWith('string')"
$this->${1:method}()->shouldEndWith(${2:'string'});
endsnippet
snippet snend "$this->XYZ()->shouldNotEndWith('string')"
$this->${1:method}()->shouldNotEndWith(${2:'string'});
endsnippet
snippet smatch "$this->XYZ()->shouldMatch('/wizard/i')"
$this->${1:method}()->shouldMatch(${2:'/wizard/i'});
endsnippet
snippet snmatch "$this->XYZ()->shouldNotMatch('/wizard/i')"
$this->${1:method}()->shouldNotMatch(${2:'/wizard/i'});
endsnippet

View file

@ -1,40 +0,0 @@
# suggestion? report bugs?
# please go to https://github.com/chrisyue/vim-snippets/issues
priority -50
snippet test "phpunit test class" b
<?php
namespace `!p
relpath = os.path.relpath(path)
m = re.search(r'[A-Z].+(?=/)', relpath)
if m:
snip.rv = m.group().replace('/', '\\')
`;
/**
* @author `!v g:snips_author`
*/
class `!p
snip.rv = re.match(r'.*(?=\.)', fn).group()
` extends \PHPUnit_Framework_TestCase
{
public function test${1}()
{
${2}
}
}
endsnippet
snippet exp "phpunit expects" i
expects($this->${1:once}())
->method('${2}')
->with($this->equalTo(${3})${4})
->will($this->returnValue(${5}));
endsnippet
snippet testcmt "phpunit comment with group" b
/**
* @group ${1}
*/
endsnippet

View file

@ -3,166 +3,56 @@ priority -50
## Snippets from SnipMate, taken from ## Snippets from SnipMate, taken from
## https://github.com/scrooloose/snipmate-snippets.git ## https://github.com/scrooloose/snipmate-snippets.git
snippet array "array" snippet gm "PHP Class Getter" b
$${1:arrayName} = array('${2}' => ${3});${4}
endsnippet
snippet def "def"
define('${1:VARIABLE_NAME}', ${2:'definition'});${3}
endsnippet
snippet wh "while"
while (${1}) {
${0:${VISUAL}}
}
endsnippet
snippet do "do"
do {
${2:// code... }
} while (${1:/* condition */});
endsnippet
snippet doc_f "doc_f"
/**
* $2
* @return ${4:void}
* @author ${5:`!v g:snips_author`}
**/
${1:public }function ${2:someFunc}(${3})
{${6}
}
endsnippet
snippet doc_i "doc_i"
/**
* $1
* @package ${2:default}
* @author ${3:`!v g:snips_author`}
**/
interface ${1:someClass}
{${4}
} // END interface $1"
endsnippet
snippet el "else"
else {
${0:${VISUAL}}
}
endsnippet
snippet for "for"
for ($${2:i} = 0; $$2 < ${1:count}; $$2${3:++}) {
${4:// code...}
}
endsnippet
snippet foreachk "foreachk"
foreach ($${1:variable} as $${2:key} => $${3:value}) {
${4:// code...}
}
endsnippet
snippet get "get"
$_GET['${1}']${2}
endsnippet
snippet if "if"
if (${1}) {
${0:${VISUAL}}
}
endsnippet
snippet eif "elseif"
elseif (${1}) {
${0:${VISUAL}}
}
endsnippet
snippet inc "inc"
include '${1:file}';${2}
endsnippet
snippet log "log"
error_log(var_export(${1}, true));${2}
endsnippet
snippet post "post"
$_POST['${1}']${2}
endsnippet
snippet req "req1"
require_once '${1:file}';${2}
endsnippet
snippet req1 "req1"
require_once '${1:file}';${2}
endsnippet
snippet session "session"
$_SESSION['${1}']${2}
endsnippet
snippet t "t"
$${1:retVal} = (${2:condition}) ? ${3:a} : ${4:b};${5}
endsnippet
snippet var "var"
var_export(${1});${2}
endsnippet
snippet getter "PHP Class Getter" b
/** /**
* Getter for $1 * Getter for $1
* *
* ${2:return string} * @return ${2:string}
*/ */
public function get${1/\w+\s*/\u$0/}() public function get${1/\w+\s*/\u$0/}()
{ {
return $this->$1;$3 return $this->$1;
} }
endsnippet endsnippet
snippet setter "PHP Class Setter" b snippet sm "PHP Class Setter" b
/** /**
* Setter for $1 * Setter for $1
* *
* @param ${2:string} $$1 * @param ${2:string} $$1
* @return ${3:`!p snip.rv=snip.basename`} * @return ${3:`!p snip.rv=snip.basename`}
*/ */
public function set${1/\w+\s*/\u$0/}(${4:${2/(void|string|int|integer|double|float|object|boolear|null|mixed|number|resource)|(.*)/(?1::$2 )/}}$$1) public function set${1/\w+\s*/\u$0/}(${4:${2/(void|string|int|integer|double|float|object|boolear|null|mixed|number|resource)|(.*)/(?1::$2 )/}}$$1)
{ {
$this->$1 = $$1;$5 $this->$1 = $$1;
${6:return $this;} ${5:return $this;}
} }
$0
endsnippet endsnippet
snippet gs "PHP Class Getter Setter" b snippet gs "PHP Class Getter Setter" b
/** /**
* Getter for $1 * Getter for $1
* *
* return ${2:string} * @return ${2:string}
*/ */
public function get${1/\w+\s*/\u$0/}() public function get${1/\w+\s*/\u$0/}()
{ {
return $this->$1;$3 return $this->$1;
} }
/** /**
* Setter for $1 * Setter for $1
* *
* @param $2 $$1 * @param $2 $$1
* @return ${4:`!p snip.rv=snip.basename`} * @return ${3:`!p snip.rv=snip.basename`}
*/ */
public function set${1/\w+\s*/\u$0/}(${5:${2/(void|string|int|integer|double|float|object|boolear|null|mixed|number|resource)|(.*)/(?1::$2 )/}}$$1) public function set${1/\w+\s*/\u$0/}(${4:${2/(void|string|int|integer|double|float|object|boolear|null|mixed|number|resource)|(.*)/(?1::$2 )/}}$$1)
{ {
$this->$1 = $$1;$6 $this->$1 = $$1;
${7:return $this;} ${5:return $this;}
} }
$0
endsnippet endsnippet
snippet pub "Public function" b snippet pub "Public function" b
@ -251,27 +141,11 @@ function ${1:name}(${2:$param})
$0 $0
endsnippet endsnippet
snippet fore "Foreach loop"
foreach ($${1:variable} as $${3:value}) {
${VISUAL}${4}
}
$0
endsnippet
snippet new "New class instance" b snippet new "New class instance" b
$${1:variableName} = new ${2:${1/\w+\s*/\u$0/}}($3); $${1:variableName} = new ${2:${1/\w+\s*/\u$0/}}($3);
$0 $0
endsnippet endsnippet
snippet ife "if else"
if (${1:/* condition */}) {
${2:// code...}
} else {
${3:// code...}
}
$0
endsnippet
snippet ns "namespace declaration" b snippet ns "namespace declaration" b
namespace ${1:`!p namespace ${1:`!p
relpath = os.path.relpath(path) relpath = os.path.relpath(path)
@ -316,7 +190,7 @@ if m:
*/ */
interface $1 interface $1
{ {
public function ${3:someFunction}();$4 public function ${3:someFunction}();$4
} }
endsnippet endsnippet
@ -349,18 +223,29 @@ public function __construct(${1:$dependencies})
$0 $0
endsnippet endsnippet
snippet ve "Dumb debug helper in HTML" # PHPUnit snippets
echo '<pre>' . var_export($1, 1) . '</pre>';$0 snippet testcase "class XYZTest extends \PHPUnit_Framework_TestCase { ... }"
endsnippet <?php
snippet pc "Dumb debug helper in cli" namespace `!p
var_export($1);$0 relpath = os.path.relpath(path)
endsnippet m = re.search(r'[A-Z].+(?=/)', relpath)
if m:
snip.rv = m.group().replace('/', '\\')
`;
snippet inheritdoc "@inheritdoc docblock"
/** /**
* {@inheritdoc} * @author `!v g:snips_author`
*/ */
class `!p
snip.rv = re.match(r'.*(?=\.)', fn).group()
` extends \PHPUnit_Framework_TestCase
{
public function test${1}()
{
${0:${VISUAL}}
}
}
endsnippet endsnippet
# :vim:ft=snippets: # :vim:ft=snippets:

View file

@ -1,53 +0,0 @@
priority -50
snippet bl "twig block" b
{% block ${1} %}
${2}
{% endblock $1 %}
endsnippet
snippet js "twig javascripts" b
{% javascripts '${1}' %}
<script src="{{ asset_url }}"></script>
{% endjavascripts %}
endsnippet
snippet css "twig stylesheets" b
{% stylesheets '${1}' %}
<link rel="stylesheet" href="{{ asset_url }}">
{% endstylesheets %}
endsnippet
snippet if "twig if" b
{% if ${1} %}
${0:${VISUAL}}
{% endif %}
endsnippet
snippet ife "twig if ... else" b
{% if ${1} %}
${2}
{% else %}
${0}
{% endif %}
endsnippet
snippet el "twig else"
{% else %}
${0:${VISUAL}}
endsnippet
snippet eif "twig elseif"
{% elseif ${1} %}
${0:${VISUAL}}
endsnippet
snippet for "twig for" b
{% for ${1} in ${2} %}
${3}
{% endfor %}
endsnippet
snippet ext "twig extends" b
{% extends ${1} %}
endsnippet

View file

@ -7,6 +7,8 @@ snippet date
`strftime("%Y-%m-%d")` `strftime("%Y-%m-%d")`
snippet ddate snippet ddate
`strftime("%B %d, %Y")` `strftime("%B %d, %Y")`
snippet diso
`strftime("%Y-%m-%dT%H:%M:%S")`
snippet time snippet time
`strftime("%H:%M")` `strftime("%H:%M")`
snippet datetime snippet datetime

View file

@ -146,9 +146,9 @@ snippet itera
## Lambdas ## Lambdas
# lamda (one line) # lamda (one line)
snippet ld snippet ld
[${1}](${2}){${3}} [${1}](${2}){${3}};
# lambda (multi-line) # lambda (multi-line)
snippet lld snippet lld
[${1}](${2}){ [${1}](${2}){
${3} ${3}
} };

View file

@ -1,3 +1,5 @@
extends html
snippet % snippet %
<% ${0} %> <% ${0} %>
snippet = snippet =

View file

@ -114,7 +114,7 @@ snippet testa
end end
snippet exunit snippet exunit
defmodule ${1:`substitute(vim_snippets#Filename(), '\(_\|^\)\(.\)', '\u\2', 'g')`} do defmodule ${1:`substitute(vim_snippets#Filename(), '\(_\|^\)\(.\)', '\u\2', 'g')`} do
use ExUnit.Case use ExUnit.Case, async: true
${0} ${0}
end end
@ -131,3 +131,6 @@ snippet qu
quote do quote do
${1} ${1}
end end
snippet beh
@behaviour ${1:Mix.Task}
${0}

View file

@ -0,0 +1,50 @@
snippet mod
module `substitute(substitute(expand('%:r'), '[/\\]','.','g'),'^\%(\l*\.\)\?','','')` exposing (${1})
${0}
snippet imp
import ${0:List}
snippet impe
import ${1:List} exposing (${0:map})
snippet fn
${1:fn} : ${2:a} -> ${3:a}
$1 ${4} =
${0}
snippet fn1
${1:fn} : ${2:a} -> ${3:a}
$1 ${4} =
${0}
snippet fn2
${1:fn} : ${2:a} -> ${3:a} -> ${4:a}
$1 ${5} =
${0}
snippet fn3
${1:fn} : ${2:a} -> ${3:a} -> ${4:a} -> ${5:a}
$1 ${6} =
${0}
snippet fn0
${1:fn} : ${2:a}
$1 =
${0}
snippet case
case ${1} of
${2} ->
${0}
snippet -
${1} ->
${0}
snippet let
let
${1} = ${2}
in
${0}
snippet if
if ${1} then
${2}
else
${0}
snippet ty
type ${1:Msg}
= ${0}
snippet tya
type alias ${1:Model} =
${0}

Some files were not shown because too many files have changed in this diff Show more