1
0
Fork 0
mirror of synced 2024-11-22 16:55:34 -05:00

Updated plugins

This commit is contained in:
amix 2016-06-26 13:12:36 +02:00
parent 0228ad0e9e
commit 0cb4702c1e
74 changed files with 10264 additions and 3014 deletions

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

@ -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'],
@ -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,6 +908,7 @@ 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(1) noa cal s:Close(1)
noa winc p noa winc p
@ -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', '^>')
@ -2346,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

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/06/11 14:05:27. " 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
@ -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

@ -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)

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

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-144' let g:_SYNTASTIC_VERSION = '3.7.0-153'
lockvar g:_SYNTASTIC_VERSION lockvar g:_SYNTASTIC_VERSION
" Sanity checks {{{1 " Sanity checks {{{1

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

@ -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

@ -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

@ -3,12 +3,16 @@
IMPROVEMENTS: 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] * `: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: BUG FIXES:
* Escape `#` characters when opening URL's, as it's handled as alternative file in vim [gh-895] * 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 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) ## 1.7.1 (June 7, 2016)

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,259 +88,257 @@ 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"
let compile_file = "vim-go-test-compile" call extend(args, ["-c", "-o", compile_file])
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 goargs = go#util#Shelllist(goargs, 1) 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'))
else let s:test_compile_handlers[id] = compile_file
echon "vim-go: " | echohl Identifier | echon "testing ..." | echohl None
endif endif
return id
endif
if has('nvim') call go#cmd#autowrite()
if get(g:, 'go_term_enabled', 0) redraw
let id = go#term#new(a:bang, ["go"] + args)
else
let id = go#jobcontrol#Spawn(a:bang, "test", args)
endif
if a:compile let command = "go " . join(args, ' ')
call go#jobcontrol#AddHandler(function('s:test_compile_handler')) let out = go#tool#ExecuteInDir(command)
let s:test_compile_handlers[id] = compile_file
endif let l:listtype = "quickfix"
return id
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 endif
echon "vim-go: " | echohl ErrorMsg | echon "[test] FAIL" | echohl None
call go#cmd#autowrite() else
redraw call go#list#Clean(l:listtype)
call go#list#Window(l:listtype)
let command = "go " . join(args, ' ')
let out = go#tool#ExecuteInDir(command)
let l:listtype = "quickfix"
if a:compile if a:compile
call delete(compile_file) echon "vim-go: " | echohl Function | echon "[test] SUCCESS" | echohl None
endif
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 else
call go#list#Clean(l:listtype) echon "vim-go: " | echohl Function | echon "[test] PASS" | echohl None
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
@ -350,12 +348,12 @@ endfunction
let s:test_compile_handlers = {} let s:test_compile_handlers = {}
function! s:test_compile_handler(job, exit_status, data) function! s:test_compile_handler(job, exit_status, data)
if !has_key(s:test_compile_handlers, a:job.id) if !has_key(s:test_compile_handlers, a:job.id)
return return
endif endif
let l:compile_file = s:test_compile_handlers[a:job.id] let l:compile_file = s:test_compile_handlers[a:job.id]
call delete(l:compile_file) call delete(l:compile_file)
unlet s:test_compile_handlers[a:job.id] unlet s:test_compile_handlers[a:job.id]
endfunction endfunction
" vim:ts=4:sw=4:et " vim: sw=2 ts=2 et

View file

@ -1,156 +1,156 @@
function! s:gocodeCurrentBuffer() function! s:gocodeCurrentBuffer()
let buf = getline(1, '$') let buf = getline(1, '$')
if &encoding != 'utf-8' if &encoding != 'utf-8'
let buf = map(buf, 'iconv(v:val, &encoding, "utf-8")') let buf = map(buf, 'iconv(v:val, &encoding, "utf-8")')
endif endif
if &l:fileformat == 'dos' if &l:fileformat == 'dos'
" XXX: line2byte() depend on 'fileformat' option. " XXX: line2byte() depend on 'fileformat' option.
" so if fileformat is 'dos', 'buf' must include '\r'. " so if fileformat is 'dos', 'buf' must include '\r'.
let buf = map(buf, 'v:val."\r"') let buf = map(buf, 'v:val."\r"')
endif endif
let file = tempname() let file = tempname()
call writefile(buf, file) call writefile(buf, file)
return file return file
endfunction endfunction
function! s:gocodeCommand(cmd, preargs, args) function! s:gocodeCommand(cmd, preargs, args)
for i in range(0, len(a:args) - 1) for i in range(0, len(a:args) - 1)
let a:args[i] = go#util#Shellescape(a:args[i]) let a:args[i] = go#util#Shellescape(a:args[i])
endfor endfor
for i in range(0, len(a:preargs) - 1) for i in range(0, len(a:preargs) - 1)
let a:preargs[i] = go#util#Shellescape(a:preargs[i]) let a:preargs[i] = go#util#Shellescape(a:preargs[i])
endfor endfor
let bin_path = go#path#CheckBinPath("gocode") let bin_path = go#path#CheckBinPath("gocode")
if empty(bin_path) if empty(bin_path)
return return
endif endif
" we might hit cache problems, as gocode doesn't handle well different " we might hit cache problems, as gocode doesn't handle well different
" GOPATHS: https://github.com/nsf/gocode/issues/239 " GOPATHS: https://github.com/nsf/gocode/issues/239
let old_gopath = $GOPATH let old_gopath = $GOPATH
let $GOPATH = go#path#Detect() 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 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 let $GOPATH = old_gopath
if go#util#ShellError() != 0 if go#util#ShellError() != 0
return "[\"0\", []]" return "[\"0\", []]"
else else
if &encoding != 'utf-8' if &encoding != 'utf-8'
let result = iconv(result, 'utf-8', &encoding) let result = iconv(result, 'utf-8', &encoding)
endif
return result
endif endif
return result
endif
endfunction endfunction
function! s:gocodeCurrentBufferOpt(filename) function! s:gocodeCurrentBufferOpt(filename)
return '-in=' . a:filename return '-in=' . a:filename
endfunction endfunction
let s:optionsEnabled = 0 let s:optionsEnabled = 0
function! s:gocodeEnableOptions() function! s:gocodeEnableOptions()
if s:optionsEnabled if s:optionsEnabled
return return
endif endif
let bin_path = go#path#CheckBinPath("gocode") let bin_path = go#path#CheckBinPath("gocode")
if empty(bin_path) if empty(bin_path)
return return
endif endif
let s:optionsEnabled = 1 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 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)))) call go#util#System(printf('%s set autobuild %s', go#util#Shellescape(bin_path), s:toBool(get(g:, 'go_gocode_autobuild', 1))))
endfunction endfunction
function! s:toBool(val) function! s:toBool(val)
if a:val | return 'true ' | else | return 'false' | endif if a:val | return 'true ' | else | return 'false' | endif
endfunction endfunction
function! s:gocodeAutocomplete() function! s:gocodeAutocomplete()
call s:gocodeEnableOptions() call s:gocodeEnableOptions()
let filename = s:gocodeCurrentBuffer() let filename = s:gocodeCurrentBuffer()
let result = s:gocodeCommand('autocomplete', let result = s:gocodeCommand('autocomplete',
\ [s:gocodeCurrentBufferOpt(filename), '-f=vim'], \ [s:gocodeCurrentBufferOpt(filename), '-f=vim'],
\ [expand('%:p'), go#util#OffsetCursor()]) \ [expand('%:p'), go#util#OffsetCursor()])
call delete(filename) call delete(filename)
return result return result
endfunction 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
function! 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,229 +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
" check if there is any test file, if not we just return let s:toggle = 1
let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd ' : 'cd ' let l:tmpname = tempname()
let dir = getcwd() let args = [a:bang, 0, "-coverprofile", l:tmpname]
try
execute cd . fnameescape(expand("%:p:h"))
if empty(glob("*_test.go"))
call go#util#EchoError("no tests files available")
return
endif
finally
execute cd . fnameescape(dir)
endtry
let s:toggle = 1 if a:0
let l:tmpname = tempname() call extend(args, a:000)
let args = [a:bang, 0, "-coverprofile", l:tmpname] endif
if a:0 let disabled_term = 0
call extend(args, a:000) if get(g:, 'go_term_enabled')
endif let disabled_term = 1
let g:go_term_enabled = 0
endif
let disabled_term = 0 let id = call('go#cmd#Test', args)
if get(g:, 'go_term_enabled')
let disabled_term = 1
let g:go_term_enabled = 0
endif
let id = call('go#cmd#Test', args) if disabled_term
let g:go_term_enabled = 1
endif
if disabled_term if has('nvim')
let g:go_term_enabled = 1 call go#jobcontrol#AddHandler(function('s:coverage_handler'))
endif let s:coverage_handler_jobs[id] = l:tmpname
return
endif
if has('nvim') if go#util#ShellError() == 0
call go#jobcontrol#AddHandler(function('s:coverage_handler')) call go#coverage#overlay(l:tmpname)
let s:coverage_handler_jobs[id] = l:tmpname endif
return
endif
if go#util#ShellError() == 0 call delete(l:tmpname)
call go#coverage#overlay(l:tmpname)
endif
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=darkgrey guifg=#75715E endfor
highlight covered term=bold ctermfg=green guifg=#A6E22E
highlight uncover term=bold ctermfg=red 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
@ -255,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,227 +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 old_gopath = $GOPATH let old_gopath = $GOPATH
let $GOPATH = go#path#Detect() let $GOPATH = go#path#Detect()
let fname = fnamemodify(expand("%"), ':p:gs?\\?/?') let fname = fnamemodify(expand("%"), ':p:gs?\\?/?')
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
" so guru right now is slow for some people. previously we were using " so guru right now is slow for some people. previously we were using
" godef which also has it's own quirks. But this issue come up so many " godef which also has it's own quirks. But this issue come up so many
" times I've decided to support both. By default we still use guru as it " times I've decided to support both. By default we still use guru as it
" covers all edge cases, but now anyone can switch to godef if they wish " covers all edge cases, but now anyone can switch to godef if they wish
let bin_name = get(g:, 'go_def_mode', 'guru') let bin_name = get(g:, 'go_def_mode', 'guru')
if bin_name == 'godef' if bin_name == 'godef'
let bin_path = go#path#CheckBinPath("godef") let bin_path = go#path#CheckBinPath("godef")
if empty(bin_path) if empty(bin_path)
let $GOPATH = old_gopath let $GOPATH = old_gopath
return return
endif endif
let command = printf("%s -f=%s -o=%s -t", bin_path, fname, go#util#OffsetCursor()) let command = printf("%s -f=%s -o=%s -t", bin_path, fname, go#util#OffsetCursor())
let out = go#util#System(command) let out = go#util#System(command)
" append the type information to the same line so our " append the type information to the same line so our
" jump_to_declaration() function can parse it. This makes it " jump_to_declaration() function can parse it. This makes it
" compatible with guru definition as well too " compatible with guru definition as well too
let out = join(split(out, '\n'), ':') let out = join(split(out, '\n'), ':')
elseif bin_name == 'guru' elseif bin_name == 'guru'
let bin_path = go#path#CheckBinPath("guru") let bin_path = go#path#CheckBinPath("guru")
if empty(bin_path) if empty(bin_path)
let $GOPATH = old_gopath let $GOPATH = old_gopath
return return
endif
let flags = ""
if exists('g:go_guru_tags')
let tags = get(g:, 'go_guru_tags')
let flags = printf(" -tags %s", tags)
endif
let fname = shellescape(fname.':#'.go#util#OffsetCursor())
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 endif
if go#util#ShellError() != 0 let flags = ""
call go#util#EchoError(out) if exists('g:go_guru_tags')
return let tags = get(g:, 'go_guru_tags')
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
let filename = parts[0]
let line = parts[1]
let col = parts[2]
let ident = parts[3]
" Remove anything newer than the current position, just like basic
" vim tag support
if s:go_stack_level == 0
let s:go_stack = []
else
let s:go_stack = s:go_stack[0:s:go_stack_level-1]
endif
" increment the stack counter
let s:go_stack_level += 1
" push it on to the jumpstack
let stack_entry = {'line': line("."), 'col': col("."), 'file': expand('%:p'), 'ident': ident}
call add(s:go_stack, stack_entry)
" needed for restoring back user setting this is because there are two
" modes of switchbuf which we need based on the split mode
let old_switchbuf = &switchbuf
" 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
if get(g:, 'go_def_reuse_buffer', 0) && bufloaded(filename) != 0 && bufwinnr(filename) != -1
" jumpt to existing buffer if it exists
execute bufwinnr(filename) . 'wincmd w'
elseif a:mode == "tab"
let &switchbuf = "usetab"
if bufloaded(filename) == 0
tab split
endif endif
elseif a:mode == "split"
split
elseif a:mode == "vsplit"
vsplit
endif
let filename = parts[0] " open the file and jump to line and column
let line = parts[1] exec 'edit '.filename
let col = parts[2] call cursor(line, col)
let ident = parts[3]
" Remove anything newer than the current position, just like basic " also align the line to middle of the view
" vim tag support normal! zz
if s:go_stack_level == 0
let s:go_stack = []
else
let s:go_stack = s:go_stack[0:s:go_stack_level-1]
endif
" increment the stack counter let &switchbuf = old_switchbuf
let s:go_stack_level += 1
" push it on to the jumpstack
let stack_entry = {'line': line("."), 'col': col("."), 'file': expand('%:p'), 'ident': ident}
call add(s:go_stack, stack_entry)
" needed for restoring back user setting this is because there are two
" modes of switchbuf which we need based on the split mode
let old_switchbuf = &switchbuf
" 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
if get(g:, 'go_def_reuse_buffer', 0) && bufloaded(filename) != 0 && bufwinnr(filename) != -1
" jumpt to existing buffer if it exists
execute bufwinnr(filename) . 'wincmd w'
elseif a:mode == "tab"
let &switchbuf = "usetab"
if bufloaded(filename) == 0
tab split
endif
elseif a:mode == "split"
split
elseif a:mode == "vsplit"
vsplit
endif
" open the file and jump to line and column
exec 'edit '.filename
call cursor(line, col)
" also align the line to middle of the view
normal! zz
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
let stackOut = ['" <Up>,<Down>:navigate <Enter>:jump <Esc>,q:exit']
let i = 0
while i < len(s:go_stack)
let entry = s:go_stack[i]
let prefix = ""
if i == s:go_stack_level
let prefix = ">"
else
let prefix = " "
endif endif
let stackOut = ['" <Up>,<Down>:navigate <Enter>:jump <Esc>,q:exit'] call add(stackOut, printf("%s %d %s|%d col %d|%s",
\ prefix, i+1, entry["file"], entry["line"], entry["col"], entry["ident"]))
let i += 1
endwhile
let i = 0 if s:go_stack_level == i
while i < len(s:go_stack) call add(stackOut, "> ")
let entry = s:go_stack[i] endif
let prefix = ""
if i == s:go_stack_level call go#ui#OpenWindow("GoDef Stack", stackOut, "godefstack")
let prefix = ">"
else
let prefix = " "
endif
call add(stackOut, printf("%s %d %s|%d col %d|%s", noremap <buffer> <silent> <CR> :<C-U>call go#def#SelectStackEntry()<CR>
\ prefix, i+1, entry["file"], entry["line"], entry["col"], entry["ident"])) noremap <buffer> <silent> <Esc> :<C-U>call go#ui#CloseWindow()<CR>
let i += 1 noremap <buffer> <silent> q :<C-U>call go#ui#CloseWindow()<CR>
endwhile
if s:go_stack_level == i
call add(stackOut, "> ")
endif
call go#ui#OpenWindow("GoDef Stack", stackOut, "godefstack")
noremap <buffer> <silent> <CR> :<C-U>call go#def#SelectStackEntry()<CR>
noremap <buffer> <silent> <Esc> :<C-U>call go#ui#CloseWindow()<CR>
noremap <buffer> <silent> q :<C-U>call go#ui#CloseWindow()<CR>
endfunction 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
if !len(a:000)
" Display interactive stack
call go#def#StackUI()
return
else
let jumpTarget = a:1
endif
if jumpTarget !~ '^\d\+$'
if jumpTarget !~ '^\s*$'
call go#util#EchoError("location must be a number")
endif endif
return
endif
if !len(a:000) let jumpTarget = str2nr(jumpTarget) - 1
" Display interactive stack
call go#def#StackUI()
return
else
let jumpTarget = a:1
endif
if jumpTarget !~ '^\d\+$' if jumpTarget >= 0 && jumpTarget < len(s:go_stack)
if jumpTarget !~ '^\s*$' let s:go_stack_level = jumpTarget
call go#util#EchoError("location must be a number") let target = s:go_stack[s:go_stack_level]
endif
return
endif
let jumpTarget = str2nr(jumpTarget) - 1 " jump
exec 'edit '.target["file"]
if jumpTarget >= 0 && jumpTarget < len(s:go_stack) call cursor(target["line"], target["col"])
let s:go_stack_level = jumpTarget normal! zz
let target = s:go_stack[s:go_stack_level] else
call go#util#EchoError("invalid location. Try :GoDefStack to see the list of valid entries")
" jump endif
exec 'edit '.target["file"]
call cursor(target["line"], target["col"])
normal! zz
else
call go#util#EchoError("invalid location. Try :GoDefStack to see the list of valid entries")
endif
endfunction endfunction
" vim: sw=2 ts=2 et

View file

@ -5,151 +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) if len(a:000)
" check if we have 'godoc' and use it automatically " check if we have 'godoc' and use it automatically
let bin_path = go#path#CheckBinPath('godoc') let bin_path = go#path#CheckBinPath('godoc')
if empty(bin_path) if empty(bin_path)
return return
endif
let command = printf("%s %s", bin_path, join(a:000, ' '))
else
" check if we have 'gogetdoc' and use it automatically
let bin_path = go#path#CheckBinPath('gogetdoc')
if empty(bin_path)
return
endif
let offset = go#util#OffsetCursor()
let fname = expand("%:p:gs!\\!/!")
let pos = shellescape(fname.':#'.offset)
let command = printf("%s -pos %s", bin_path, pos)
endif endif
let out = go#util#System(command) let command = printf("%s %s", bin_path, join(a:000, ' '))
if go#util#ShellError() != 0 else
call go#util#EchoError(out) " check if we have 'gogetdoc' and use it automatically
return let bin_path = go#path#CheckBinPath('gogetdoc')
if empty(bin_path)
return
endif endif
call s:GodocView(a:newmode, a:mode, out) let offset = go#util#OffsetCursor()
let fname = expand("%:p:gs!\\!/!")
let pos = shellescape(fname.':#'.offset)
let command = printf("%s -pos %s", bin_path, pos)
endif
let out = go#util#System(command)
if go#util#ShellError() != 0
call go#util#EchoError(out)
return
endif
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 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,162 +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(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 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,98 +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 filename .= ':'.pos
let command .= printf(' %s %s', a:mode, shellescape(filename))
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
@ -100,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 = shellescape(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(go#path#Detect(), 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
@ -172,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,78 +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))
" reload all files to reflect the new changes. We explicitly call let out = go#tool#ExecuteInDir(cmd)
" checktime to trigger a reload of all files. See
" http://www.mail-archive.com/vim@vim.org/msg05900.html for more info
" about the autoread bug
let current_autoread = &autoread
set autoread
silent! checktime
let &autoread = current_autoread
" strip out newline on the end that gorename puts. If we don't remove, it " reload all files to reflect the new changes. We explicitly call
" will trigger the 'Hit ENTER to continue' prompt " checktime to trigger a reload of all files. See
let clean = split(out, '\n') " http://www.mail-archive.com/vim@vim.org/msg05900.html for more info
" about the autoread bug
let current_autoread = &autoread
set autoread
silent! checktime
let &autoread = current_autoread
let l:listtype = "quickfix" " strip out newline on the end that gorename puts. If we don't remove, it
if go#util#ShellError() != 0 " will trigger the 'Hit ENTER to continue' prompt
let errors = go#tool#ParseErrors(split(out, '\n')) let clean = split(out, '\n')
call go#list#Populate(l:listtype, errors)
call go#list#Window(l:listtype, len(errors)) let l:listtype = "quickfix"
if !empty(errors) && !a:bang if go#util#ShellError() != 0
call go#list#JumpToFirst(l:listtype) let errors = go#tool#ParseErrors(split(out, '\n'))
elseif empty(errors) call go#list#Populate(l:listtype, errors)
" failed to parse errors, output the original content call go#list#Window(l:listtype, len(errors))
call go#util#EchoError(out) if !empty(errors) && !a:bang
endif call go#list#JumpToFirst(l:listtype)
return elseif empty(errors)
else " failed to parse errors, output the original content
call go#list#Clean(l:listtype) call go#util#EchoError(out)
call go#list#Window(l:listtype)
redraw | echon "vim-go: " | echohl Function | echon clean[0] | echohl None
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

@ -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,129 +1,129 @@
function! go#tool#Files() function! go#tool#Files()
if go#util#IsWin() if go#util#IsWin()
let format = '{{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 format = "{{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 command = 'go list -f '.shellescape(format) let command = 'go list -f '.shellescape(format)
let out = go#tool#ExecuteInDir(command) let out = go#tool#ExecuteInDir(command)
return split(out, '\n') return split(out, '\n')
endfunction endfunction
function! go#tool#Deps() function! go#tool#Deps()
if go#util#IsWin() if go#util#IsWin()
let format = '{{range $f := .Deps}}{{$f}}{{printf \"\n\"}}{{end}}' let format = '{{range $f := .Deps}}{{$f}}{{printf \"\n\"}}{{end}}'
else else
let format = "{{range $f := .Deps}}{{$f}}\n{{end}}" let format = "{{range $f := .Deps}}{{$f}}\n{{end}}"
endif endif
let command = 'go list -f '.shellescape(format) let command = 'go list -f '.shellescape(format)
let out = go#tool#ExecuteInDir(command) let out = go#tool#ExecuteInDir(command)
return split(out, '\n') 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 format = '{{range $f := .Imports}}{{$f}}{{printf \"\n\"}}{{end}}' let format = '{{range $f := .Imports}}{{$f}}{{printf \"\n\"}}{{end}}'
else else
let format = "{{range $f := .Imports}}{{$f}}{{printf \"\\n\"}}{{end}}" let format = "{{range $f := .Imports}}{{$f}}{{printf \"\\n\"}}{{end}}"
endif endif
let command = 'go list -f '.shellescape(format) let command = 'go list -f '.shellescape(format)
let out = go#tool#ExecuteInDir(command) let out = go#tool#ExecuteInDir(command)
if go#util#ShellError() != 0 if go#util#ShellError() != 0
echo out echo out
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 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
@ -182,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 =~ "^$"
" suppress 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

@ -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>
@ -70,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

@ -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,26 +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/rogpeppe/godef", \ "github.com/rogpeppe/godef",
\ "github.com/kisielk/errcheck", \ "github.com/kisielk/errcheck",
\ "github.com/jstemmer/gotags", \ "github.com/jstemmer/gotags",
\ "github.com/klauspost/asmfmt/cmd/asmfmt", \ "github.com/klauspost/asmfmt/cmd/asmfmt",
\ "github.com/fatih/motion", \ "github.com/fatih/motion",
\ "github.com/zmb3/gogetdoc", \ "github.com/zmb3/gogetdoc",
\ "github.com/josharian/impl", \ "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)
@ -33,145 +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 -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
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

@ -68,7 +68,7 @@ if !exists("g:go_highlight_methods")
endif endif
if !exists("g:go_highlight_fields") if !exists("g:go_highlight_fields")
let g:go_highlight_fields = 0 let g:go_highlight_fields = 0
endif endif
if !exists("g:go_highlight_structs") if !exists("g:go_highlight_structs")
@ -336,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
@ -376,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

@ -110,7 +110,7 @@ function! s:build_stops(snippet, stops, lnum, col, indent) abort
for line in a:snippet for line in a:snippet
let col = s:build_loc_info(line, stops, lnum, col, []) let col = s:build_loc_info(line, stops, lnum, col, [])
if line isnot line[-1] if line isnot a:snippet[-1]
let lnum += 1 let lnum += 1
let col = a:indent let col = a:indent
endif endif

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

@ -23,7 +23,7 @@ class `!p
snip.rv = re.match(r'.*(?=\.)', fn).group() snip.rv = re.match(r'.*(?=\.)', fn).group()
` extends ObjectBehavior ` extends ObjectBehavior
{ {
function it${1}() function it_${1}()
{ {
$0 $0
} }
@ -31,7 +31,7 @@ snip.rv = re.match(r'.*(?=\.)', fn).group()
endsnippet endsnippet
snippet it "function it_does_something() { ... }" snippet it "function it_does_something() { ... }"
function it${1}() function it_${1}()
{ {
${0:${VISUAL}} ${0:${VISUAL}}
} }
@ -163,11 +163,11 @@ endsnippet
# Scalar type matchers # Scalar type matchers
snippet sbscalar "$this->XYZ()->shouldBeString|Array|Bool()" snippet sbscalar "$this->XYZ()->shouldBeString|Array|Bool()"
$this->${1:method}()->shouldBe(${2:'String|Array|Bool'}); $this->${1:method}()->shouldBe${2:String|Array|Bool}();
endsnippet endsnippet
snippet snbscalar "$this->XYZ()->shouldNotBeString|Array|Bool()" snippet snbscalar "$this->XYZ()->shouldNotBeString|Array|Bool()"
$this->${1:method}()->shouldNotBe(${2:'String|Array|Bool'}); $this->${1:method}()->shouldNotBe${2:String|Array|Bool}();
endsnippet endsnippet
# Contain matcher # Contain matcher

View file

@ -3,7 +3,7 @@ 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 getter "PHP Class Getter" b snippet gm "PHP Class Getter" b
/** /**
* Getter for $1 * Getter for $1
* *
@ -11,11 +11,11 @@ snippet getter "PHP Class Getter" b
*/ */
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
* *
@ -24,11 +24,10 @@ snippet setter "PHP Class Setter" b
*/ */
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
@ -39,22 +38,21 @@ snippet gs "PHP Class Getter Setter" b
*/ */
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

View file

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

View file

@ -47,28 +47,27 @@ snippet m
{ {
${0} ${0}
} }
# setter method snippet sm "PHP Class Setter"
snippet sm
/** /**
* Sets the value of ${1:foo} * Sets the value of ${1:foo}
* *
* @param ${2:$1} $$1 ${3:description} * @param ${2:string} $$1 ${3:description}
* *
* @return ${4:`vim_snippets#Filename()`} * @return ${4:`vim_snippets#Filename()`}
*/ */
${5:public} function set${6:$2}(${7:$2 }$$1) ${5:public} function set${6:$1}(${7:$2 }$$1)
{ {
$this->${8:$1} = $$1; $this->${8:$1} = $$1;
return $this; return $this;
} }
# getter method snippet gm "PHP Class Getter Setter"
snippet gm
/** /**
* Gets the value of ${1:foo} * Gets the value of ${1:foo}
* *
* @return ${2:$1} * @return ${2:string}
*/ */
${3:public} function get${4:$2}() ${3:public} function get${4:$1}()
{ {
return $this->${5:$1}; return $this->${5:$1};
} }
@ -391,13 +390,13 @@ snippet ve "Dumb debug helper in HTML"
snippet pc "Dumb debug helper in cli" snippet pc "Dumb debug helper in cli"
var_export($1);$0 var_export($1);$0
# Getters & Setters # Getters & Setters
snippet gs snippet gs "PHP Class Getter Setter"
/** /**
* Gets the value of ${1:foo} * Gets the value of ${1:foo}
* *
* @return ${2:$1} * @return ${2:string}
*/ */
public function get${3:$2}() public function get${3:$1}()
{ {
return $this->${4:$1}; return $this->${4:$1};
} }

View file

@ -0,0 +1,36 @@
extends css
snippet $
$${1:variable}: ${0:value}
snippet imp
@import '${0}'
snippet mix
@mixin ${1:name}(${2})
${0}
snippet inc
@include ${1:mixin}(${2})
snippet ext
@extend ${0}
snippet fun
@function ${1:name}(${2:args})
${0}
snippet if
@if ${1:condition}
${0}
snippet ife
@if ${1:condition}
${2}
@else
${0}
snippet eif
@else if ${1:condition}
${0}
snippet for
@for ${1:$i} from ${2:1} through ${3:3}
${0}
snippet each
@each ${1:$item} in ${2:items}
${0}
snippet while
@while ${1:$i} ${2:>} ${3:0}
${0}

View file

@ -16,57 +16,57 @@ snippet dmo \DeclareMathOperator
# \begin{}...\end{} # \begin{}...\end{}
snippet begin \begin{} ... \end{} block snippet begin \begin{} ... \end{} block
\begin{${1:env}} \begin{${1:env}}
${0} ${0:${VISUAL}}
\end{$1} \end{$1}
# Tabular # Tabular
snippet tab tabular (or arbitrary) environment snippet tab tabular (or arbitrary) environment
\begin{${1:tabular}}{${2:c}} \begin{${1:tabular}}{${2:c}}
${0} ${0:${VISUAL}}
\end{$1} \end{$1}
snippet thm thm (or arbitrary) environment with optional argument snippet thm thm (or arbitrary) environment with optional argument
\begin[${1:author}]{${2:thm}} \begin[${1:author}]{${2:thm}}
${0} ${0:${VISUAL}}
\end{$2} \end{$2}
snippet center center environment snippet center center environment
\begin{center} \begin{center}
${0} ${0:${VISUAL}}
\end{center} \end{center}
# Align(ed) # Align(ed)
snippet ali align(ed) environment snippet ali align(ed) environment
\begin{align${1:ed}} \begin{align${1:ed}}
\label{eq:${2}} \label{eq:${2}}
${0} ${0:${VISUAL}}
\end{align$1} \end{align$1}
# Gather(ed) # Gather(ed)
snippet gat gather(ed) environment snippet gat gather(ed) environment
\begin{gather${1:ed}} \begin{gather${1:ed}}
${0} ${0:${VISUAL}}
\end{gather$1} \end{gather$1}
# Equation # Equation
snippet eq equation environment snippet eq equation environment
\begin{equation} \begin{equation}
${0} ${0:${VISUAL}}
\end{equation} \end{equation}
# Equation # Equation
snippet eql Labeled equation environment snippet eql Labeled equation environment
\begin{equation} \begin{equation}
\label{eq:${2}} \label{eq:${2}}
${0} ${0:${VISUAL}}
\end{equation} \end{equation}
# Equation # Equation
snippet eq* unnumbered equation environment snippet eq* unnumbered equation environment
\begin{equation*} \begin{equation*}
${0} ${0:${VISUAL}}
\end{equation*} \end{equation*}
# Unnumbered Equation # Unnumbered Equation
snippet \ unnumbered equation: \[ ... \] snippet \ unnumbered equation: \[ ... \]
\[ \[
${0} ${0:${VISUAL}}
\] \]
# Equation array # Equation array
snippet eqnarray eqnarray environment snippet eqnarray eqnarray environment
\begin{eqnarray} \begin{eqnarray}
${0} ${0:${VISUAL}}
\end{eqnarray} \end{eqnarray}
# Label # Label
snippet lab \label snippet lab \label
@ -90,7 +90,7 @@ snippet itemize itemize environment
\item ${0} \item ${0}
\end{itemize} \end{itemize}
snippet item \item snippet item \item
\item ${1} \item ${1:${VISUAL}}
# Description # Description
snippet desc description environment snippet desc description environment
\begin{description} \begin{description}
@ -103,18 +103,18 @@ snippet ]i \item (recursive)
# Matrix # Matrix
snippet mat smart matrix environment snippet mat smart matrix environment
\begin{${1:p/b/v/V/B/small}matrix} \begin{${1:p/b/v/V/B/small}matrix}
${0} ${0:${VISUAL}}
\end{$1matrix} \end{$1matrix}
# Cases # Cases
snippet cas cases environment snippet cas cases environment
\begin{cases} \begin{cases}
${1:equation}, &\text{ if }${2:case}\\ ${1:equation}, &\text{ if }${2:case}\\
${0} ${0:${VISUAL}}
\end{cases} \end{cases}
# Split # Split
snippet spl split environment snippet spl split environment
\begin{split} \begin{split}
${0} ${0:${VISUAL}}
\end{split} \end{split}
# Part # Part
snippet part document \part snippet part document \part
@ -203,32 +203,32 @@ snippet fcite \footcite[]{}
\footcite[${1}]{${2}}${0} \footcite[${1}]{${2}}${0}
#Formating text: italic, bold, underline, small capital, emphase .. #Formating text: italic, bold, underline, small capital, emphase ..
snippet it italic text snippet it italic text
\textit{${0:text}} \textit{${0:${VISUAL:text}}}
snippet bf bold face text snippet bf bold face text
\textbf{${0:text}} \textbf{${0:${VISUAL:text}}}
snippet under underline text snippet under underline text
\underline{${0:text}} \underline{${0:${VISUAL:text}}}
snippet emp emphasize text snippet emp emphasize text
\emph{${0:text}} \emph{${0:${VISUAL:text}}}
snippet sc small caps text snippet sc small caps text
\textsc{${0:text}} \textsc{${0:${VISUAL:text}}}
#Choosing font #Choosing font
snippet sf sans serife text snippet sf sans serife text
\textsf{${0:text}} \textsf{${0:${VISUAL:text}}}
snippet rm roman font text snippet rm roman font text
\textrm{${0:text}} \textrm{${0:${VISUAL:text}}}
snippet tt typewriter (monospace) text snippet tt typewriter (monospace) text
\texttt{${0:text}} \texttt{${0:${VISUAL:text}}}
#Math font #Math font
snippet mf mathfrak snippet mf mathfrak
\mathfrak{${0:text}} \mathfrak{${0:${VISUAL:text}}}
snippet mc mathcal snippet mc mathcal
\mathcal{${0:text}} \mathcal{${0:${VISUAL:text}}}
snippet ms mathscr snippet ms mathscr
\mathscr{${0:text}} \mathscr{${0:${VISUAL:text}}}
#misc #misc
snippet ft \footnote snippet ft \footnote
\footnote{${0:text}} \footnote{${0:${VISUAL:text}}}
snippet fig figure environment (includegraphics) snippet fig figure environment (includegraphics)
\begin{figure} \begin{figure}
\begin{center} \begin{center}
@ -260,19 +260,19 @@ snippet lim \lim_{}
\lim_{${1:n \to \infty}} ${0} \lim_{${1:n \to \infty}} ${0}
snippet frame frame environment snippet frame frame environment
\begin{frame}[${1:t}]{${2:title}} \begin{frame}[${1:t}]{${2:title}}
${0} ${0:${VISUAL}}
\end{frame} \end{frame}
snippet block block environment snippet block block environment
\begin{block}{${1:title}} \begin{block}{${1:title}}
${0} ${0:${VISUAL}}
\end{block} \end{block}
snippet alert alertblock environment snippet alert alertblock environment
\begin{alertblock}{${1:title}} \begin{alertblock}{${1:title}}
${0} ${0:${VISUAL}}
\end{alertblock} \end{alertblock}
snippet example exampleblock environment snippet example exampleblock environment
\begin{exampleblock}{${1:title}} \begin{exampleblock}{${1:title}}
${0} ${0:${VISUAL}}
\end{exampleblock} \end{exampleblock}
snippet col2 two-column environment snippet col2 two-column environment
\begin{columns} \begin{columns}
@ -301,7 +301,7 @@ snippet lra langle rangle
# Code listings # Code listings
snippet lst snippet lst
\begin{listing}[language=${1:language}] \begin{listing}[language=${1:language}]
${0} ${0:${VISUAL}}
\end{listing} \end{listing}
snippet lsi snippet lsi
\lstinline|${1}| ${0} \lstinline|${1}| ${0}