1
0
Fork 0
mirror of synced 2024-12-25 00:03:20 -05:00

Merge pull request #3 from amix/master

Merge to new commit.
This commit is contained in:
Tiande 2016-05-11 15:21:25 +08:00
commit 54afb04f5b
131 changed files with 2718 additions and 6450 deletions

View file

@ -98,7 +98,6 @@ I recommend reading the docs of these plugins to understand them better. Each of
* [ctrlp.vim](https://github.com/kien/ctrlp.vim): Fuzzy file, buffer, mru and tag finder. In my config it's mapped to `<Ctrl+F>`, because `<Ctrl+P>` is used by YankRing
* [mru.vim](https://github.com/vim-scripts/mru.vim): Plugin to manage Most Recently Used (MRU) files. Includes my own fork which adds syntax highlighting to MRU. This plugin can be opened with `<leader+f>`
* [open_file_under_cursor.vim](https://github.com/amix/open_file_under_cursor.vim): Open file under cursor when pressing `gf`
* [zencoding](https://github.com/mattn/emmet-vim): Expanding abbreviation like zen-coding, very useful for editing XML, HTML.
* [vim-indent-object](https://github.com/michaeljsmith/vim-indent-object): Defines a new text object representing lines of code at the same indent level. Useful for python/vim scripts
* [vim-multiple-cursors](https://github.com/terryma/vim-multiple-cursors): Sublime Text style multiple selections for Vim, CTRL+N is remapped to CTRL+S (due to YankRing)
* [vim-expand-region](https://github.com/terryma/vim-expand-region): Allows you to visually select increasingly larger regions of text using the same key combination.

View file

@ -1 +0,0 @@
/doc/tags

View file

@ -1,4 +0,0 @@
[submodule "docs"]
path = docs
url = git@github.com:mattn/zencoding-vim.git
branch = gh-pages

View file

@ -1,11 +0,0 @@
all : zencoding-vim.zip
remove-zip:
-rm doc/tags
-rm zencoding-vim.zip
zencoding-vim.zip: remove-zip
zip -r zencoding-vim.zip autoload plugin doc
release: zencoding-vim.zip
vimup update-script zencoding.vim

View file

@ -1,103 +0,0 @@
# ZenCoding-vim
[zencoding-vim](http://mattn.github.com/zencoding-vim) is vim script support for expanding abbreviation like zen-coding(emmet).
## Installation
[Download zip file](http://www.vim.org/scripts/script.php?script_id=2981):
cd ~/.vim
unzip zencoding-vim.zip
If you install pathogen.vim:
cd ~/.vim/bundle # or make directory
unzip /path/to/zencoding-vim.zip
If you get source from repository:
cd ~/.vim/bundle # or make directory
git clone http://github.com/mattn/zencoding-vim.git
or:
git clone http://github.com/mattn/zencoding-vim.git
cd zencoding-vim
cp plugin/zencoding.vim ~/.vim/plugin/
cp autoload/zencoding.vim ~/.vim/autoload/
cp -a autoload/zencoding ~/.vim/autoload/
## Quick Tutorial
Open or create New File:
vim index.html
Type ("_" is the cursor position):
html:5_
Then type "<c-y>," (Ctrl + y + ','), you should see:
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
_
</body>
</html>
[More Tutorials](https://raw.github.com/mattn/zencoding-vim/master/TUTORIAL)
## Enable in different mode
If you don't want enable zencoding in all mode,
you can use set a option in `vimrc`:
let g:user_zen_mode='n' "only enable normal mode functions.
let g:user_zen_mode='inv' "enable all functions, which is equal to
let g:user_zen_mode='a' "enable all function in all mode.
## Project Authors
[Yasuhiro Matsumoto](http://mattn.kaoriya.net/)
## Links
### zen-coding official site:
> <http://code.google.com/p/zen-coding/>
### zencoding.vim:
> <http://mattn.github.com/zencoding-vim>
### development repository:
> <https://github.com/mattn/zencoding-vim>
### my blog posts about zencoding-vim:
> <http://mattn.kaoriya.net/software/vim/20100222103327.htm>
> <http://mattn.kaoriya.net/software/vim/20100306021632.htm>
### japanese blog posts about zencoding-vim:
> <http://d.hatena.ne.jp/idesaku/20100424/1272092255>
> <http://d.hatena.ne.jp/griefworker/20110118/vim_zen_coding>
> <http://d.hatena.ne.jp/sakurako_s/20110126/1295988873>
> <http://looxu.blogspot.jp/2010/02/zencodingvimhtml.html>
### tutorial traslated in chinese:
> <http://www.zfanw.com/blog/zencoding-vim-tutorial-chinese.html>

View file

@ -1,212 +0,0 @@
Tutorial of zencoding.vim
mattn <mattn.jp@gmail.com>
1. Expand Abbreviation
Type abbreviation as 'div>p#foo$*3>a' and type '<c-y>,'.
---------------------
<div>
<p id="foo1">
<a href=""></a>
</p>
<p id="foo2">
<a href=""></a>
</p>
<p id="foo3">
<a href=""></a>
</p>
</div>
---------------------
2. Wrap with Abbreviation
Write as below.
---------------------
test1
test2
test3
---------------------
Then do visual select(line wize) and type '<c-y>,'.
If you request 'Tag:', then type 'ul>li*'.
---------------------
<ul>
<li>test1</li>
<li>test2</li>
<li>test3</li>
</ul>
---------------------
If you type tag as 'blockquote', then you'll see as following.
---------------------
<blockquote>
test1
test2
test3
</blockquote>
---------------------
3. Balance Tag Inward
type '<c-y>d' in insert mode.
4. Balance Tag Outward
type '<c-y>D' in insert mode.
5. Go to Next Edit Point
type '<c-y>n' in insert mode.
6. Go to Previous Edit Point
type '<c-y>N' in insert mode.
7. Update <img> Size
Move cursor to img tag.
---------------------
<img src="foo.png" />
---------------------
Type '<c-y>i' on img tag
---------------------
<img src="foo.png" width="32" height="48" />
---------------------
8. Merge Lines
select the lines included '<li>'
---------------------
<ul>
<li class="list1"></li>
<li class="list2"></li>
<li class="list3"></li>
</ul>
---------------------
and type '<c-y>m'
---------------------
<ul>
<li class="list1"></li><li class="list2"></li><li class="list3"></li>
</ul>
---------------------
9. Remove Tag
Move cursor in block
---------------------
<div class="foo">
<a>cursor is here</a>
</div>
---------------------
Type '<c-y>k' in insert mode.
---------------------
<div class="foo">
</div>
---------------------
And type '<c-y>k' in there again.
---------------------
---------------------
10. Split/Join Tag
Move cursor in block
---------------------
<div class="foo">
cursor is here
</div>
---------------------
Type '<c-y>j' in insert mode.
---------------------
<div class="foo"/>
---------------------
And type '<c-y>j' in there again.
---------------------
<div class="foo">
</div>
---------------------
11. Toggle Comment
Move cursor to block
---------------------
<div>
hello world
</div>
---------------------
Type '<c-y>/' in insert mode.
---------------------
<!-- <div>
hello world
</div> -->
---------------------
Type '<c-y>/' in there again.
---------------------
<div>
hello world
</div>
---------------------
12. Make anchor from URL
Move cursor to URL
---------------------
http://www.google.com/
---------------------
Type '<c-y>a'
---------------------
<a href="http://www.google.com/">Google</a>
---------------------
13. Make quoted text from URL
Move cursor to URL
---------------------
http://github.com/
---------------------
Type '<c-y>A'
---------------------
<blockquote class="quote">
<a href="http://github.com/">Secure source code hosting and collaborative development - GitHub</a><br />
<p>How does it work? Get up and running in seconds by forking a project, pushing an existing repository...</p>
<cite>http://github.com/</cite>
</blockquote>
---------------------
14. Installing zencoding.vim for language you using.
# cd ~/.vim
# unzip zencoding-vim.zip
or if you install pathogen.vim:
# cd ~/.vim/bundle # or make directory
# unzip /path/to/zencoding-vim.zip
if you get sources from repository:
# cd ~/.vim/bundle # or make directory
# git clone http://github.com/mattn/zencoding-vim.git
15. Enable zencoding.vim for language you using.
You can customize the behavior of language you using.
---------------------
# cat >> ~/.vimrc
let g:user_zen_settings = {
\ 'php' : {
\ 'extends' : 'html',
\ 'filters' : 'c',
\ },
\ 'xml' : {
\ 'extends' : 'html',
\ },
\ 'haml' : {
\ 'extends' : 'html',
\ },
\}
---------------------

File diff suppressed because it is too large Load diff

View file

@ -1,11 +0,0 @@
let s:exists = {}
function zencoding#lang#exists(type)
if len(a:type) == 0
return 0
elseif has_key(s:exists, a:type)
return s:exists[a:type]
endif
let s:exists[a:type] = len(globpath(&rtp, 'autoload/zencoding/lang/'.a:type.'.vim')) > 0
return s:exists[a:type]
endfunction

View file

@ -1,228 +0,0 @@
function! zencoding#lang#css#findTokens(str)
return substitute(a:str, '^.*[;{]\s*', '', '')
endfunction
function! zencoding#lang#css#parseIntoTree(abbr, type)
let abbr = a:abbr
let type = a:type
let prefix = 0
let value = ''
let settings = zencoding#getSettings()
let indent = zencoding#getIndentation(type)
let root = { 'name': '', 'attr': {}, 'child': [], 'snippet': '', 'multiplier': 1, 'parent': {}, 'value': '', 'pos': 0, 'important': 0 }
" emmet
let tokens = split(abbr, '+\ze[^)!]')
for n in range(len(tokens))
let token = tokens[n]
let prop = matchlist(token, '^\(-\{0,1}[a-zA-Z]\+\|[a-zA-Z0-9]\++\{0,1}\|([a-zA-Z0-9]\++\{0,1})\)\(\%([0-9.-]\+[pe]\{0,1}-\{0,1}\|-auto\)*\)$')
if len(prop)
let token = substitute(prop[1], '^(\(.*\))', '\1', '')
if token =~ '^-'
let prefix = 1
let token = token[1:]
endif
let value = ''
for v in split(prop[2], '\d\zs-')
if len(value) > 0
let value .= ' '
endif
if token =~ '^[z]'
" TODO
let value .= substitute(v, '[^0-9.]*$', '', '')
elseif v =~ 'p$'
let value .= substitute(v, 'p$', '%', '')
elseif v =~ 'e$'
let value .= substitute(v, 'e$', 'em', '')
elseif v =~ '\.'
let value .= v . 'em'
elseif v == 'auto'
let value .= v
else
let value .= v . 'px'
endif
endfor
endif
let tag_name = token
if tag_name =~ '.!$'
let tag_name = tag_name[:-2]
let important = 1
else
let important = 0
endif
" make default node
let current = { 'name': '', 'attr': {}, 'child': [], 'snippet': '', 'multiplier': 1, 'parent': {}, 'value': '', 'pos': 0, 'important': important }
let current.name = tag_name
" aliases
let aliases = zencoding#getResource(type, 'aliases', {})
if has_key(aliases, tag_name)
let current.name = aliases[tag_name]
endif
let use_pipe_for_cursor = zencoding#getResource(type, 'use_pipe_for_cursor', 1)
" snippets
let snippets = zencoding#getResource(type, 'snippets', {})
if !empty(snippets) && has_key(snippets, tag_name)
let snippet = snippets[tag_name]
if use_pipe_for_cursor
let snippet = substitute(snippet, '|', '${cursor}', 'g')
endif
let lines = split(snippet, "\n")
call map(lines, 'substitute(v:val, "\\( \\|\\t\\)", escape(indent, "\\\\"), "g")')
let current.snippet = join(lines, "\n")
let current.name = ''
let current.snippet = substitute(current.snippet, ';', value . ';', '')
if use_pipe_for_cursor && len(value) > 0 && stridx(value, '${cursor}') == -1
let current.snippet = substitute(current.snippet, '${cursor}', '', 'g') . '${cursor}'
endif
if n < len(tokens) - 1
let current.snippet .= "\n"
endif
endif
let current.pos = 0
let lg = matchlist(token, '^\%(linear-gradient\|lg\)(\s*\(\w\+\)\s*,\s*\([^,]\+\)\s*,\s*\([^)]\+\)\s*)$')
if len(lg)
let current.name = ''
let current.snippet = printf("background-image: -webkit-gradient(%s, 0 0, 0 100%, from(%s), to(%s));\n", lg[1], lg[2], lg[3])
call add(root.child, deepcopy(current))
let current.snippet = printf("background-image: -webkit-linear-gradient(%s, %s);\n", lg[2], lg[3])
call add(root.child, deepcopy(current))
let current.snippet = printf("background-image: -moz-linear-gradient(%s, %s);\n", lg[2], lg[3])
call add(root.child, deepcopy(current))
let current.snippet = printf("background-image: -o-linear-gradient(%s, %s);\n", lg[2], lg[3])
call add(root.child, deepcopy(current))
let current.snippet = printf("background-image: linear-gradient(%s, %s);\n", lg[2], lg[3])
call add(root.child, deepcopy(current))
elseif prefix
let snippet = current.snippet
let current.snippet = '-webkit-' . snippet . "\n"
call add(root.child, deepcopy(current))
let current.snippet = '-moz-' . snippet . "\n"
call add(root.child, deepcopy(current))
let current.snippet = snippet
call add(root.child, current)
else
call add(root.child, current)
endif
endfor
return root
endfunction
function! zencoding#lang#css#toString(settings, current, type, inline, filters, itemno, indent)
let current = a:current
let value = current.value[1:-2]
if zencoding#useFilter(a:filters, 'fc')
let value = substitute(value, '\([^:]\+\):\([^;]*;\)', '\1: \2', 'g')
else
let value = substitute(value, '\([^:]\+\):\([^;]*;\)', '\1:\2', 'g')
endif
if current.important
let value = substitute(value, ';', ' !important;', '')
endif
return value
endfunction
function! zencoding#lang#css#imageSize()
endfunction
function! zencoding#lang#css#encodeImage()
endfunction
function! zencoding#lang#css#parseTag(tag)
return {}
endfunction
function! zencoding#lang#css#toggleComment()
let line = getline('.')
let mx = '^\(\s*\)/\*\s*\(.*\)\s*\*/\s*$'
if line =~ '{\s*$'
let block = zencoding#util#searchRegion('/\*', '\*/\zs')
if zencoding#util#regionIsValid(block)
let content = zencoding#util#getContent(block)
let content = substitute(content, '/\*\s\(.*\)\s\*/', '\1', '')
call zencoding#util#setContent(block, content)
else
let node = expand('<cword>')
if len(node)
exe "normal ciw\<c-r>='/* '.node.' */'\<cr>"
endif
endif
else
if line =~ mx
let space = substitute(matchstr(line, mx), mx, '\1', '')
let line = substitute(matchstr(line, mx), mx, '\2', '')
let line = space . substitute(line, '^\s*\|\s*$', '\1', 'g')
else
let mx = '^\(\s*\)\(.*\)\s*$'
let line = substitute(line, mx, '\1/* \2 */', '')
endif
call setline('.', line)
endif
endfunction
function! zencoding#lang#css#balanceTag(flag) range
if a:flag == -2 || a:flag == 2
let curpos = [0, line("'<"), col("'<"), 0]
else
let curpos = getpos('.')
endif
let block = zencoding#util#getVisualBlock()
if !zencoding#util#regionIsValid(block)
if a:flag > 0
let block = zencoding#util#searchRegion('^', ';')
if zencoding#util#regionIsValid(block)
call zencoding#util#selectRegion(block)
return
endif
endif
else
if a:flag > 0
let content = zencoding#util#getContent(block)
if content !~ '^{.*}$'
let block = zencoding#util#searchRegion('{', '}')
if zencoding#util#regionIsValid(block)
call zencoding#util#selectRegion(block)
return
endif
endif
else
let pos = searchpos('.*;', 'nW')
if pos[0] != 0
call setpos('.', [0, pos[0], pos[1], 0])
let block = zencoding#util#searchRegion('^', ';')
if zencoding#util#regionIsValid(block)
call zencoding#util#selectRegion(block)
return
endif
endif
endif
endif
if a:flag == -2 || a:flag == 2
silent! exe "normal! gv"
else
call setpos('.', curpos)
endif
endfunction
function! zencoding#lang#css#moveNextPrev(flag)
let pos = search('""\|()\|\(:\s*\zs$\)', a:flag ? 'Wbp' : 'Wp')
if pos == 2
startinsert!
else
silent! normal! l
startinsert
endif
endfunction
function! zencoding#lang#css#splitJoinTag()
" nothing to do
endfunction
function! zencoding#lang#css#removeTag()
" nothing to do
endfunction

View file

@ -1,310 +0,0 @@
function! zencoding#lang#haml#findTokens(str)
return zencoding#lang#html#findTokens(a:str)
endfunction
function! zencoding#lang#haml#parseIntoTree(abbr, type)
return zencoding#lang#html#parseIntoTree(a:abbr, a:type)
endfunction
function! zencoding#lang#haml#toString(settings, current, type, inline, filters, itemno, indent)
let settings = a:settings
let current = a:current
let type = a:type
let inline = a:inline
let filters = a:filters
let itemno = a:itemno
let indent = a:indent
let dollar_expr = zencoding#getResource(type, 'dollar_expr', 1)
let str = ""
let comment_indent = ''
let comment = ''
let current_name = current.name
if dollar_expr
let current_name = substitute(current.name, '\$$', itemno+1, '')
endif
if len(current.name) > 0
let str .= '%' . current_name
let tmp = ''
for attr in current.attrs_order
if !has_key(current.attr, attr)
continue
endif
let val = current.attr[attr]
if dollar_expr
while val =~ '\$\([^#{]\|$\)'
let val = substitute(val, '\(\$\+\)\([^{]\|$\)', '\=printf("%0".len(submatch(1))."d", itemno+1).submatch(2)', 'g')
endwhile
let attr = substitute(attr, '\$$', itemno+1, '')
endif
let valtmp = substitute(val, '\${cursor}', '', '')
if attr == 'id' && len(valtmp) > 0
let str .= '#' . val
elseif attr == 'class' && len(valtmp) > 0
let str .= '.' . substitute(val, ' ', '.', 'g')
else
if len(tmp) > 0 | let tmp .= ',' | endif
let val = substitute(val, '\${cursor}', '', '')
let tmp .= ' :' . attr . ' => "' . val . '"'
endif
endfor
if len(tmp)
let str .= '{' . tmp . ' }'
endif
if stridx(','.settings.html.empty_elements.',', ','.current_name.',') != -1 && len(current.value) == 0
let str .= "/"
endif
let inner = ''
if len(current.value) > 0
let text = current.value[1:-2]
if dollar_expr
let text = substitute(text, '\%(\\\)\@\<!\(\$\+\)\([^{#]\|$\)', '\=printf("%0".len(submatch(1))."d", itemno+1).submatch(2)', 'g')
let text = substitute(text, '\${nr}', "\n", 'g')
let text = substitute(text, '\\\$', '$', 'g')
let str = substitute(str, '\$#', text, 'g')
endif
let lines = split(text, "\n")
if len(lines) == 1
let str .= " " . text
else
for line in lines
let str .= "\n" . indent . line . " |"
endfor
endif
elseif len(current.child) == 0
let str .= '${cursor}'
endif
if len(current.child) == 1 && len(current.child[0].name) == 0
let text = current.child[0].value[1:-2]
if dollar_expr
let text = substitute(text, '\%(\\\)\@\<!\(\$\+\)\([^{#]\|$\)', '\=printf("%0".len(submatch(1))."d", itemno+1).submatch(2)', 'g')
let text = substitute(text, '\${nr}', "\n", 'g')
let text = substitute(text, '\\\$', '$', 'g')
endif
let lines = split(text, "\n")
if len(lines) == 1
let str .= " " . text
else
for line in lines
let str .= "\n" . indent . line . " |"
endfor
endif
elseif len(current.child) > 0
for child in current.child
let inner .= zencoding#toString(child, type, inline, filters, itemno)
endfor
let inner = substitute(inner, "\n", "\n" . escape(indent, '\'), 'g')
let inner = substitute(inner, "\n" . escape(indent, '\') . "$", "", 'g')
let str .= "\n" . indent . inner
endif
else
let str = current.value[1:-2]
if dollar_expr
let str = substitute(str, '\%(\\\)\@\<!\(\$\+\)\([^{#]\|$\)', '\=printf("%0".len(submatch(1))."d", itemno+1).submatch(2)', 'g')
let str = substitute(str, '\${nr}', "\n", 'g')
let str = substitute(str, '\\\$', '$', 'g')
endif
endif
let str .= "\n"
return str
endfunction
function! zencoding#lang#haml#imageSize()
let line = getline('.')
let current = zencoding#lang#haml#parseTag(line)
if empty(current) || !has_key(current.attr, 'src')
return
endif
let fn = current.attr.src
if fn =~ '^\s*$'
return
elseif fn !~ '^\(/\|http\)'
let fn = simplify(expand('%:h') . '/' . fn)
endif
let [width, height] = zencoding#util#getImageSize(fn)
if width == -1 && height == -1
return
endif
let current.attr.width = width
let current.attr.height = height
let current.attrs_order += ['width', 'height']
let haml = zencoding#toString(current, 'haml', 1)
let haml = substitute(haml, '\${cursor}', '', '')
call setline('.', substitute(matchstr(line, '^\s*') . haml, "\n", "", "g"))
endfunction
function! zencoding#lang#haml#encodeImage()
endfunction
function! zencoding#lang#haml#parseTag(tag)
let current = { 'name': '', 'attr': {}, 'child': [], 'snippet': '', 'multiplier': 1, 'parent': {}, 'value': '', 'pos': 0, 'attrs_order': [] }
let mx = '%\([a-zA-Z][a-zA-Z0-9]*\)\s*\%({\(.*\)}\)'
let match = matchstr(a:tag, mx)
let current.name = substitute(match, mx, '\1', 'i')
let attrs = substitute(match, mx, '\2', 'i')
let mx = '\([a-zA-Z0-9]\+\)\s*=>\s*\%(\([^"'' \t]\+\)\|"\([^"]\{-}\)"\|''\([^'']\{-}\)''\)'
while len(attrs) > 0
let match = matchstr(attrs, mx)
if len(match) == 0
break
endif
let attr_match = matchlist(match, mx)
let name = attr_match[1]
let value = len(attr_match[2]) ? attr_match[2] : attr_match[3]
let current.attr[name] = value
let current.attrs_order += [name]
let attrs = attrs[stridx(attrs, match) + len(match):]
endwhile
return current
endfunction
function! zencoding#lang#haml#toggleComment()
let line = getline('.')
let space = matchstr(line, '^\s*')
if line =~ '^\s*-#'
call setline('.', space . matchstr(line[len(space)+2:], '^\s*\zs.*'))
elseif line =~ '^\s*%[a-z]'
call setline('.', space . '-# ' . line[len(space):])
endif
endfunction
function! zencoding#lang#haml#balanceTag(flag) range
let block = zencoding#util#getVisualBlock()
if a:flag == -2 || a:flag == 2
let curpos = [0, line("'<"), col("'<"), 0]
else
let curpos = getpos('.')
endif
let n = curpos[1]
let ml = len(matchstr(getline(n), '^\s*'))
if a:flag > 0
if a:flag == 1 || !zencoding#util#regionIsValid(block)
let n = line('.')
else
while n > 0
let l = len(matchstr(getline(n), '^\s*\ze%[a-z]'))
if l > 0 && l < ml
let ml = l
break
endif
let n -= 1
endwhile
endif
let sn = n
if n == 0
let ml = 0
endif
while n < line('$')
let l = len(matchstr(getline(n), '^\s*%[a-z]'))
if l > 0 && l <= ml
let n -= 1
break
endif
let n += 1
endwhile
call setpos('.', [0, n, 1, 0])
normal! V
call setpos('.', [0, sn, 1, 0])
else
while n > 0
let l = len(matchstr(getline(n), '^\s*\ze[a-z]'))
if l > 0 && l > ml
let ml = l
break
endif
let n += 1
endwhile
let sn = n
if n == 0
let ml = 0
endif
while n < line('$')
let l = len(matchstr(getline(n), '^\s*%[a-z]'))
if l > 0 && l <= ml
let n -= 1
break
endif
let n += 1
endwhile
call setpos('.', [0, n, 1, 0])
normal! V
call setpos('.', [0, sn, 1, 0])
endif
endfunction
function! zencoding#lang#haml#moveNextPrev(flag)
let pos = search('""', a:flag ? 'Wb' : 'W')
if pos != 0
silent! normal! l
startinsert
endif
endfunction
function! zencoding#lang#haml#splitJoinTag()
let n = line('.')
let sml = len(matchstr(getline(n), '^\s*%[a-z]'))
while n > 0
if getline(n) =~ '^\s*\ze%[a-z]'
if len(matchstr(getline(n), '^\s*%[a-z]')) < sml
break
endif
let line = getline(n)
call setline(n, substitute(line, '^\s*%\w\+\%(\s*{[^}]*}\|\s\)\zs.*', '', ''))
let sn = n
let n += 1
let ml = len(matchstr(getline(n), '^\s*%[a-z]'))
if len(matchstr(getline(n), '^\s*')) > ml
while n <= line('$')
let l = len(matchstr(getline(n), '^\s*'))
if l <= ml
break
endif
exe n "delete"
endwhile
call setpos('.', [0, sn, 1, 0])
else
let tag = matchstr(getline(sn), '^\s*%\zs\(\w\+\)')
let spaces = matchstr(getline(sn), '^\s*')
let settings = zencoding#getSettings()
if stridx(','.settings.html.inline_elements.',', ','.tag.',') == -1
call append(sn, spaces . ' ')
call setpos('.', [0, sn+1, 1, 0])
else
call setpos('.', [0, sn, 1, 0])
endif
startinsert!
endif
break
endif
let n -= 1
endwhile
endfunction
function! zencoding#lang#haml#removeTag()
let n = line('.')
let ml = 0
while n > 0
if getline(n) =~ '^\s*\ze[a-z]'
let ml = len(matchstr(getline(n), '^\s*%[a-z]'))
break
endif
let n -= 1
endwhile
let sn = n
while n < line('$')
let l = len(matchstr(getline(n), '^\s*%[a-z]'))
if l > 0 && l <= ml
let n -= 1
break
endif
let n += 1
endwhile
if sn == n
exe "delete"
else
exe sn "," (n-1) "delete"
endif
endfunction

View file

@ -1,692 +0,0 @@
let s:mx = '\([+>]\|[<^]\+\)\{-}\s*'
\ .'\((*\)\{-}\s*'
\ .'\([@#.]\{-}[a-zA-Z\!][a-zA-Z0-9:_\!\-$]*\|{\%([^$}]\+\|\$#\|\${\w\+}\|\$\+\)*}[ \t\r\n}]*\)'
\ .'\('
\ .'\%('
\ .'\%(#{[{}a-zA-Z0-9_\-\$]\+\|#[a-zA-Z0-9_\-\$]\+\)'
\ .'\|\%(\[[^\]]\+\]\)'
\ .'\|\%(\.{[{}a-zA-Z0-9_\-\$]\+\|\.[a-zA-Z0-9_\-\$]\+\)'
\ .'\)*'
\ .'\)'
\ .'\%(\({\%([^$}]\+\|\$#\|\${\w\+}\|\$\+\)*}\)\)\{0,1}'
\ .'\%(\*\([0-9]\+\)\)\{0,1}'
\ .'\(\%()\%(\*[0-9]\+\)\{0,1}\)*\)'
function! zencoding#lang#html#findTokens(str)
let str = a:str
let [pos, last_pos] = [0, 0]
while 1
let tag = matchstr(str, '<[a-zA-Z].\{-}>', pos)
if len(tag) == 0
break
endif
let pos = stridx(str, tag, pos) + len(tag)
endwhile
let last_pos = pos
while len(str) > 0
let token = matchstr(str, s:mx, pos)
if token == ''
break
endif
if token =~ '^\s'
let token = matchstr(token, '^\s*\zs.*')
let last_pos = stridx(str, token, pos)
endif
let pos = stridx(str, token, pos) + len(token)
endwhile
return a:str[last_pos :-1]
endfunction
function! zencoding#lang#html#parseIntoTree(abbr, type)
let abbr = a:abbr
let type = a:type
let settings = zencoding#getSettings()
if !has_key(settings, type)
let type = 'html'
endif
if len(type) == 0 | let type = 'html' | endif
let settings = zencoding#getSettings()
let indent = zencoding#getIndentation(type)
" try 'foo' to (foo-x)
let rabbr = zencoding#getExpandos(type, abbr)
if rabbr == abbr
" try 'foo+(' to (foo-x)
let rabbr = substitute(abbr, '\%(+\|^\)\([a-zA-Z][a-zA-Z0-9+]\+\)+\([(){}>]\|$\)', '\="(".zencoding#getExpandos(type, submatch(1)).")".submatch(2)', 'i')
endif
let abbr = rabbr
let root = { 'name': '', 'attr': {}, 'child': [], 'snippet': '', 'multiplier': 1, 'parent': {}, 'value': '', 'pos': 0, 'important': 0, 'attrs_order': ['id', 'class'] }
let parent = root
let last = root
let pos = []
while len(abbr)
" parse line
let match = matchstr(abbr, s:mx)
let str = substitute(match, s:mx, '\0', 'ig')
let operator = substitute(match, s:mx, '\1', 'ig')
let block_start = substitute(match, s:mx, '\2', 'ig')
let tag_name = substitute(match, s:mx, '\3', 'ig')
let attributes = substitute(match, s:mx, '\4', 'ig')
let value = substitute(match, s:mx, '\5', 'ig')
let multiplier = 0 + substitute(match, s:mx, '\6', 'ig')
let block_end = substitute(match, s:mx, '\7', 'ig')
let important = 0
if len(str) == 0
break
endif
if tag_name =~ '^#'
let attributes = tag_name . attributes
let tag_name = 'div'
endif
if tag_name =~ '.!$'
let tag_name = tag_name[:-2]
let important = 1
endif
if tag_name =~ '^\.'
let attributes = tag_name . attributes
let tag_name = 'div'
endif
if multiplier <= 0 | let multiplier = 1 | endif
" make default node
let current = { 'name': '', 'attr': {}, 'child': [], 'snippet': '', 'multiplier': 1, 'parent': {}, 'value': '', 'pos': 0, 'important': 0, 'attrs_order': ['id', 'class'] }
let current.name = tag_name
let current.important = important
" aliases
let aliases = zencoding#getResource(type, 'aliases', {})
if has_key(aliases, tag_name)
let current.name = aliases[tag_name]
endif
let use_pipe_for_cursor = zencoding#getResource(type, 'use_pipe_for_cursor', 1)
" snippets
let snippets = zencoding#getResource(type, 'snippets', {})
if !empty(snippets) && has_key(snippets, tag_name)
let snippet = snippets[tag_name]
if use_pipe_for_cursor
let snippet = substitute(snippet, '|', '${cursor}', 'g')
endif
let lines = split(snippet, "\n")
call map(lines, 'substitute(v:val, "\\( \\|\\t\\)", escape(indent, "\\\\"), "g")')
let current.snippet = join(lines, "\n")
let current.name = ''
endif
" default_attributes
let default_attributes = zencoding#getResource(type, 'default_attributes', {})
if !empty(default_attributes)
for pat in [current.name, tag_name]
if has_key(default_attributes, pat)
if type(default_attributes[pat]) == 4
let a = default_attributes[pat]
let current.attrs_order += keys(a)
if use_pipe_for_cursor
for k in keys(a)
let current.attr[k] = len(a[k]) ? substitute(a[k], '|', '${cursor}', 'g') : '${cursor}'
endfor
else
for k in keys(a)
let current.attr[k] = a[k]
endfor
endif
else
for a in default_attributes[pat]
let current.attrs_order += keys(a)
if use_pipe_for_cursor
for k in keys(a)
let current.attr[k] = len(a[k]) ? substitute(a[k], '|', '${cursor}', 'g') : '${cursor}'
endfor
else
for k in keys(a)
let current.attr[k] = a[k]
endfor
endif
endfor
endif
if has_key(settings.html.default_attributes, current.name)
let current.name = substitute(current.name, ':.*$', '', '')
endif
break
endif
endfor
endif
" parse attributes
if len(attributes)
let attr = attributes
while len(attr)
let item = matchstr(attr, '\(\%(\%(#[{}a-zA-Z0-9_\-\$]\+\)\|\%(\[[^\]]\+\]\)\|\%(\.[{}a-zA-Z0-9_\-\$]\+\)*\)\)')
if len(item) == 0
break
endif
if item[0] == '#'
let current.attr.id = item[1:]
endif
if item[0] == '.'
let current.attr.class = substitute(item[1:], '\.', ' ', 'g')
endif
if item[0] == '['
let atts = item[1:-2]
while len(atts)
let amat = matchstr(atts, '\(\w\+\%(="[^"]*"\|=''[^'']*''\|[^ ''"\]]*\)\{0,1}\)')
if len(amat) == 0
break
endif
let key = split(amat, '=')[0]
let val = amat[len(key)+1:]
if val =~ '^["'']'
let val = val[1:-2]
endif
let current.attr[key] = val
if index(current.attrs_order, key) == -1
let current.attrs_order += [key]
endif
let atts = atts[stridx(atts, amat) + len(amat):]
endwhile
endif
let attr = substitute(strpart(attr, len(item)), '^\s*', '', '')
endwhile
endif
" parse text
if tag_name =~ '^{.*}$'
let current.name = ''
let current.value = tag_name
else
let current.value = value
endif
let current.multiplier = multiplier
" parse step inside/outside
if !empty(last)
if operator =~ '>'
unlet! parent
let parent = last
let current.parent = last
let current.pos = last.pos + 1
else
let current.parent = parent
let current.pos = last.pos
endif
else
let current.parent = parent
let current.pos = 1
endif
if operator =~ '[<^]'
for c in range(len(operator))
let tmp = parent.parent
if empty(tmp)
break
endif
let parent = tmp
let current.parent = tmp
endfor
endif
call add(parent.child, current)
let last = current
" parse block
if block_start =~ '('
if operator =~ '>'
let last.pos += 1
endif
for n in range(len(block_start))
let pos += [last.pos]
endfor
endif
if block_end =~ ')'
for n in split(substitute(substitute(block_end, ' ', '', 'g'), ')', ',),', 'g'), ',')
if n == ')'
if len(pos) > 0 && last.pos >= pos[-1]
for c in range(last.pos - pos[-1])
let tmp = parent.parent
if !has_key(tmp, 'parent')
break
endif
let parent = tmp
endfor
if len(pos) > 0
call remove(pos, -1)
endif
let last = parent
let last.pos += 1
endif
elseif len(n)
let cl = last.child
let cls = []
for c in range(n[1:])
let cls += cl
endfor
let last.child = cls
endif
endfor
endif
let abbr = abbr[stridx(abbr, match) + len(match):]
if g:zencoding_debug > 1
echomsg "str=".str
echomsg "block_start=".block_start
echomsg "tag_name=".tag_name
echomsg "operator=".operator
echomsg "attributes=".attributes
echomsg "value=".value
echomsg "multiplier=".multiplier
echomsg "block_end=".block_end
echomsg "abbr=".abbr
echomsg "pos=".string(pos)
echomsg "---"
endif
endwhile
return root
endfunction
function! zencoding#lang#html#toString(settings, current, type, inline, filters, itemno, indent)
let settings = a:settings
let current = a:current
let type = a:type
let inline = a:inline
let filters = a:filters
let itemno = a:itemno
let indent = a:indent
let dollar_expr = zencoding#getResource(type, 'dollar_expr', 1)
if zencoding#useFilter(filters, 'haml')
return zencoding#lang#haml#toString(settings, current, type, inline, filters, itemno, indent)
endif
if zencoding#useFilter(filters, 'slim')
return zencoding#lang#slim#toString(settings, current, type, inline, filters, itemno, indent)
endif
let comment = ''
let current_name = current.name
if dollar_expr
let current_name = substitute(current_name, '\$$', itemno+1, '')
endif
let str = ''
if len(current_name) == 0
let text = current.value[1:-2]
if dollar_expr
let text = substitute(text, '\%(\\\)\@\<!\(\$\+\)\([^{#]\|$\)', '\=printf("%0".len(submatch(1))."d", itemno+1).submatch(2)', 'g')
let text = substitute(text, '\${nr}', "\n", 'g')
let text = substitute(text, '\\\$', '$', 'g')
endif
return text
endif
if len(current_name) > 0
let str .= '<' . current_name
for attr in current.attrs_order
if !has_key(current.attr, attr)
continue
endif
let val = current.attr[attr]
if dollar_expr
while val =~ '\$\([^#{]\|$\)'
let val = substitute(val, '\(\$\+\)\([^{]\|$\)', '\=printf("%0".len(submatch(1))."d", itemno+1).submatch(2)', 'g')
endwhile
let attr = substitute(attr, '\$$', itemno+1, '')
endif
let str .= ' ' . attr . '="' . val . '"'
if zencoding#useFilter(filters, 'c')
if attr == 'id' | let comment .= '#' . val | endif
if attr == 'class' | let comment .= '.' . val | endif
endif
endfor
if len(comment) > 0
let str = "<!-- " . comment . " -->\n" . str
endif
if stridx(','.settings.html.empty_elements.',', ','.current_name.',') != -1
let str .= settings.html.empty_element_suffix
else
let str .= ">"
let text = current.value[1:-2]
if dollar_expr
let text = substitute(text, '\%(\\\)\@\<!\(\$\+\)\([^{#]\|$\)', '\=printf("%0".len(submatch(1))."d", itemno+1).submatch(2)', 'g')
let text = substitute(text, '\${nr}', "\n", 'g')
let text = substitute(text, '\\\$', '$', 'g')
let str = substitute(str, '\("\zs$#\ze"\|\s\zs\$#"\|"\$#\ze\s\)', text, 'g')
endif
let str .= text
let nc = len(current.child)
let dr = 0
if nc > 0
for n in range(nc)
let child = current.child[n]
if child.multiplier > 1
let str .= "\n" . indent
let dr = 1
elseif len(current_name) > 0 && stridx(','.settings.html.inline_elements.',', ','.current_name.',') == -1
if nc > 1 || (len(child.name) > 0 && stridx(','.settings.html.inline_elements.',', ','.child.name.',') == -1)
let str .= "\n" . indent
let dr = 1
elseif current.multiplier == 1 && nc == 1 && len(child.name) == 0
let str .= "\n" . indent
let dr = 1
endif
endif
let inner = zencoding#toString(child, type, 0, filters, itemno)
let inner = substitute(inner, "^\n", "", 'g')
let inner = substitute(inner, "\n", "\n" . escape(indent, '\'), 'g')
let inner = substitute(inner, "\n" . escape(indent, '\') . '$', '', 'g')
let str .= inner
endfor
else
let str .= '${cursor}'
endif
if dr
let str .= "\n"
endif
let str .= "</" . current_name . ">"
endif
if len(comment) > 0
let str .= "\n<!-- /" . comment . " -->"
endif
if len(current_name) > 0 && current.multiplier > 0 || stridx(','.settings.html.block_elements.',', ','.current_name.',') != -1
let str .= "\n"
endif
return str
endfunction
function! zencoding#lang#html#imageSize()
let img_region = zencoding#util#searchRegion('<img\s', '>')
if !zencoding#util#regionIsValid(img_region) || !zencoding#util#cursorInRegion(img_region)
return
endif
let content = zencoding#util#getContent(img_region)
if content !~ '^<img[^><]\+>$'
return
endif
let current = zencoding#lang#html#parseTag(content)
if empty(current) || !has_key(current.attr, 'src')
return
endif
let fn = current.attr.src
if fn =~ '^\s*$'
return
elseif fn !~ '^\(/\|http\)'
let fn = simplify(expand('%:h') . '/' . fn)
endif
let [width, height] = zencoding#util#getImageSize(fn)
if width == -1 && height == -1
return
endif
let current.attr.width = width
let current.attr.height = height
let current.attrs_order += ['width', 'height']
let html = substitute(zencoding#toString(current, 'html', 1), '\n', '', '')
let html = substitute(html, '\${cursor}', '', '')
call zencoding#util#setContent(img_region, html)
endfunction
function! zencoding#lang#html#encodeImage()
let img_region = zencoding#util#searchRegion('<img\s', '>')
if !zencoding#util#regionIsValid(img_region) || !zencoding#util#cursorInRegion(img_region)
return
endif
let content = zencoding#util#getContent(img_region)
if content !~ '^<img[^><]\+>$'
return
endif
let current = zencoding#lang#html#parseTag(content)
if empty(current) || !has_key(current.attr, 'src')
return
endif
let fn = current.attr.src
if fn !~ '^\(/\|http\)'
let fn = simplify(expand('%:h') . '/' . fn)
endif
let [width, height] = zencoding#util#getImageSize(fn)
if width == -1 && height == -1
return
endif
let current.attr.width = width
let current.attr.height = height
let html = zencoding#toString(current, 'html', 1)
call zencoding#util#setContent(img_region, html)
endfunction
function! zencoding#lang#html#parseTag(tag)
let current = { 'name': '', 'attr': {}, 'child': [], 'snippet': '', 'multiplier': 1, 'parent': {}, 'value': '', 'pos': 0, 'attrs_order': [] }
let mx = '<\([a-zA-Z][a-zA-Z0-9]*\)\(\%(\s[a-zA-Z][a-zA-Z0-9]\+=\%([^"'' \t]\+\|"[^"]\{-}"\|''[^'']\{-}''\)\s*\)*\)\(/\{0,1}\)>'
let match = matchstr(a:tag, mx)
let current.name = substitute(match, mx, '\1', 'i')
let attrs = substitute(match, mx, '\2', 'i')
let mx = '\([a-zA-Z0-9]\+\)=\%(\([^"'' \t]\+\)\|"\([^"]\{-}\)"\|''\([^'']\{-}\)''\)'
while len(attrs) > 0
let match = matchstr(attrs, mx)
if len(match) == 0
break
endif
let attr_match = matchlist(match, mx)
let name = attr_match[1]
let value = len(attr_match[2]) ? attr_match[2] : attr_match[3]
let current.attr[name] = value
let current.attrs_order += [name]
let attrs = attrs[stridx(attrs, match) + len(match):]
endwhile
return current
endfunction
function! zencoding#lang#html#toggleComment()
let orgpos = getpos('.')
let curpos = getpos('.')
let mx = '<\%#[^>]*>'
while 1
let block = zencoding#util#searchRegion('<!--', '-->')
if zencoding#util#regionIsValid(block)
let block[1][1] += 2
let content = zencoding#util#getContent(block)
let content = substitute(content, '^<!--\s\(.*\)\s-->$', '\1', '')
call zencoding#util#setContent(block, content)
silent! call setpos('.', orgpos)
return
endif
let block = zencoding#util#searchRegion('<[^>]', '>')
if !zencoding#util#regionIsValid(block)
let pos1 = searchpos('<', 'bcW')
if pos1[0] == 0 && pos1[1] == 0
return
endif
let curpos = getpos('.')
continue
endif
let pos1 = block[0]
let pos2 = block[1]
let content = zencoding#util#getContent(block)
let tag_name = matchstr(content, '^<\zs/\{0,1}[^ \r\n>]\+')
if tag_name[0] == '/'
call setpos('.', [0, pos1[0], pos1[1], 0])
let pos2 = searchpairpos('<'. tag_name[1:] . '>', '', '</' . tag_name[1:] . '>', 'bnW')
let pos1 = searchpos('>', 'cneW')
let block = [pos2, pos1]
elseif tag_name =~ '/$'
if !zencoding#util#pointInRegion(orgpos[1:2], block)
" it's broken tree
call setpos('.', orgpos)
let block = zencoding#util#searchRegion('>', '<')
let content = '><!-- ' . zencoding#util#getContent(block)[1:-2] . ' --><'
call zencoding#util#setContent(block, content)
silent! call setpos('.', orgpos)
return
endif
else
call setpos('.', [0, pos2[0], pos2[1], 0])
let pos2 = searchpairpos('<'. tag_name . '>', '', '</' . tag_name . '>', 'nW')
call setpos('.', [0, pos2[0], pos2[1], 0])
let pos2 = searchpos('>', 'neW')
let block = [pos1, pos2]
endif
if !zencoding#util#regionIsValid(block)
silent! call setpos('.', orgpos)
return
endif
if zencoding#util#pointInRegion(curpos[1:2], block)
let content = '<!-- ' . zencoding#util#getContent(block) . ' -->'
call zencoding#util#setContent(block, content)
silent! call setpos('.', orgpos)
return
endif
endwhile
endfunction
function! zencoding#lang#html#balanceTag(flag) range
let vblock = zencoding#util#getVisualBlock()
if a:flag == -2 || a:flag == 2
let curpos = [0, line("'<"), col("'<"), 0]
else
let curpos = getpos('.')
endif
let settings = zencoding#getSettings()
if a:flag > 0
let mx = '<\([a-zA-Z][a-zA-Z0-9:_\-]*\)[^>]*>'
while 1
let pos1 = searchpos(mx, 'bW')
let content = matchstr(getline(pos1[0])[pos1[1]-1:], mx)
let tag_name = matchstr(content, '^<\zs[a-zA-Z0-9:_\-]*\ze')
if stridx(','.settings.html.empty_elements.',', ','.tag_name.',') != -1
let pos2 = searchpos('>', 'nW')
else
let pos2 = searchpairpos('<' . tag_name . '[^>]*>', '', '</'. tag_name . '>\zs', 'nW')
endif
let block = [pos1, pos2]
if pos1[0] == 0 && pos1[1] == 0
break
endif
if zencoding#util#pointInRegion(curpos[1:2], block) && zencoding#util#regionIsValid(block)
call zencoding#util#selectRegion(block)
return
endif
endwhile
else
let mx = '<\([a-zA-Z][a-zA-Z0-9:_\-]*\)[^>]*>'
while 1
let pos1 = searchpos(mx, 'W')
if pos1 == curpos[1:2]
let pos1 = searchpos(mx . '\zs', 'W')
let pos2 = searchpos('.\ze<', 'W')
let block = [pos1, pos2]
if zencoding#util#regionIsValid(block)
call zencoding#util#selectRegion(block)
return
endif
endif
let content = matchstr(getline(pos1[0])[pos1[1]-1:], mx)
let tag_name = matchstr(content, '^<\zs[a-zA-Z0-9:_\-]*\ze')
if stridx(','.settings.html.empty_elements.',', ','.tag_name.',') != -1
let pos2 = searchpos('>', 'nW')
else
let pos2 = searchpairpos('<' . tag_name . '[^>]*>', '', '</'. tag_name . '>\zs', 'nW')
endif
let block = [pos1, pos2]
if pos1[0] == 0 && pos1[1] == 0
break
endif
if zencoding#util#regionIsValid(block)
call zencoding#util#selectRegion(block)
return
endif
endwhile
endif
call setpos('.', curpos)
if a:flag == -2 || a:flag == 2
silent! exe "normal! gv"
endif
endfunction
function! zencoding#lang#html#moveNextPrev(flag)
let pos = search('\%(</\w\+\)\@<!\zs><\/\|\(""\)\|^\(\s*\)$', a:flag ? 'Wpb' : 'Wp')
if pos == 3
startinsert!
elseif pos != 0
silent! normal! l
startinsert
endif
endfunction
function! zencoding#lang#html#splitJoinTag()
let curpos = getpos('.')
while 1
let mx = '<\(/\{0,1}[a-zA-Z][a-zA-Z0-9:_\-]*\)[^>]*>'
let pos1 = searchpos(mx, 'bcnW')
let content = matchstr(getline(pos1[0])[pos1[1]-1:], mx)
let tag_name = substitute(content, '^<\(/\{0,1}[a-zA-Z][a-zA-Z0-9:_\-]*\).*$', '\1', '')
let block = [pos1, [pos1[0], pos1[1] + len(content) - 1]]
if content[-2:] == '/>' && zencoding#util#cursorInRegion(block)
let content = content[:-3] . "></" . tag_name . '>'
call zencoding#util#setContent(block, content)
call setpos('.', [0, block[0][0], block[0][1], 0])
return
else
if tag_name[0] == '/'
let pos1 = searchpos('<' . tag_name[1:] . '[^a-zA-Z0-9]', 'bcnW')
call setpos('.', [0, pos1[0], pos1[1], 0])
let pos2 = searchpos('</' . tag_name[1:] . '>', 'cneW')
else
let pos2 = searchpos('</' . tag_name . '>', 'cneW')
endif
let block = [pos1, pos2]
let content = zencoding#util#getContent(block)
if zencoding#util#pointInRegion(curpos[1:2], block) && content[1:] !~ '<' . tag_name . '[^a-zA-Z0-9]*[^>]*>'
let content = matchstr(content, mx)[:-2] . '/>'
call zencoding#util#setContent(block, content)
call setpos('.', [0, block[0][0], block[0][1], 0])
return
else
if block[0][0] > 0
call setpos('.', [0, block[0][0]-1, block[0][1], 0])
else
call setpos('.', curpos)
return
endif
endif
endif
endwhile
endfunction
function! zencoding#lang#html#removeTag()
let curpos = getpos('.')
while 1
let mx = '<\(/\{0,1}[a-zA-Z][a-zA-Z0-9:_\-]*\)[^>]*>'
let pos1 = searchpos(mx, 'bcnW')
let content = matchstr(getline(pos1[0])[pos1[1]-1:], mx)
let tag_name = substitute(content, '^<\(/\{0,1}[a-zA-Z0-9:_\-]*\).*$', '\1', '')
let block = [pos1, [pos1[0], pos1[1] + len(content) - 1]]
if content[-2:] == '/>' && zencoding#util#cursorInRegion(block)
call zencoding#util#setContent(block, '')
call setpos('.', [0, block[0][0], block[0][1], 0])
return
else
if tag_name[0] == '/'
let pos1 = searchpos('<' . tag_name[1:] . '[^a-zA-Z0-9]', 'bcnW')
call setpos('.', [0, pos1[0], pos1[1], 0])
let pos2 = searchpos('</' . tag_name[1:] . '>', 'cneW')
else
let pos2 = searchpos('</' . tag_name . '>', 'cneW')
endif
let block = [pos1, pos2]
let content = zencoding#util#getContent(block)
if zencoding#util#pointInRegion(curpos[1:2], block) && content[1:] !~ '<' . tag_name . '[^a-zA-Z0-9]*[^>]*>'
call zencoding#util#setContent(block, '')
call setpos('.', [0, block[0][0], block[0][1], 0])
return
else
if block[0][0] > 0
call setpos('.', [0, block[0][0]-1, block[0][1], 0])
else
call setpos('.', curpos)
return
endif
endif
endif
endwhile
endfunction

View file

@ -1,158 +0,0 @@
function! zencoding#lang#sass#findTokens(str)
return zencoding#lang#html#findTokens(a:str)
endfunction
function! zencoding#lang#sass#parseIntoTree(abbr, type)
if a:abbr =~ '>'
return zencoding#lang#html#parseIntoTree(a:abbr, a:type)
else
return zencoding#lang#css#parseIntoTree(a:abbr, a:type)
endif
endfunction
function! zencoding#lang#sass#toString(settings, current, type, inline, filters, itemno, indent)
let settings = a:settings
let current = a:current
let type = a:type
let inline = a:inline
let filters = a:filters
let itemno = a:itemno
let indent = a:indent
let str = ""
let current_name = current.name
let current_name = substitute(current.name, '\$$', itemno+1, '')
if len(current.name) > 0
let str .= current_name
let tmp = ''
for attr in keys(current.attr)
let val = current.attr[attr]
while val =~ '\$\([^#{]\|$\)'
let val = substitute(val, '\(\$\+\)\([^{]\|$\)', '\=printf("%0".len(submatch(1))."d", itemno+1).submatch(2)', 'g')
endwhile
let attr = substitute(attr, '\$$', itemno+1, '')
if attr == 'id'
let str .= '#' . val
elseif attr == 'class'
let str .= '.' . val
else
let tmp .= attr . ': ' . val
endif
endfor
if len(tmp) > 0
let str .= "\n"
for line in split(tmp, "\n")
let str .= indent . line . "\n"
endfor
else
let str .= "\n"
endif
let inner = ''
for child in current.child
let inner .= zencoding#toString(child, type, inline, filters, itemno)
endfor
let inner = substitute(inner, "\n", "\n" . indent, 'g')
let inner = substitute(inner, "\n" . indent . "$", "", 'g')
let str .= indent . inner
else
let text = zencoding#lang#css#toString(settings, current, type, inline, filters, itemno, indent)
let text = substitute(text, '\${cursor}', '', 'g')
let text = substitute(text, '\s*;$', '', '')
return text
endif
return str
endfunction
function! zencoding#lang#sass#imageSize()
endfunction
function! zencoding#lang#sass#encodeImage()
endfunction
function! zencoding#lang#sass#parseTag(tag)
endfunction
function! zencoding#lang#sass#toggleComment()
endfunction
function! zencoding#lang#sass#balanceTag(flag) range
let block = zencoding#util#getVisualBlock()
if a:flag == -2 || a:flag == 2
let curpos = [0, line("'<"), col("'<"), 0]
else
let curpos = getpos('.')
endif
let n = curpos[1]
let ml = len(matchstr(getline(n), '^\s*'))
if a:flag > 0
if a:flag == 1 || !zencoding#util#regionIsValid(block)
let n = line('.')
else
while n > 0
let l = len(matchstr(getline(n), '^\s*\ze[a-z]'))
if l > 0 && l < ml
let ml = l
break
endif
let n -= 1
endwhile
endif
let sn = n
if n == 0
let ml = 0
endif
while n < line('$')
let l = len(matchstr(getline(n), '^\s*[a-z]'))
if l > 0 && l <= ml
let n -= 1
break
endif
let n += 1
endwhile
call setpos('.', [0, n, 1, 0])
normal! V
call setpos('.', [0, sn, 1, 0])
else
while n > 0
let l = len(matchstr(getline(n), '^\s*\ze[a-z]'))
if l > 0 && l > ml
let ml = l
break
endif
let n += 1
endwhile
let sn = n
if n == 0
let ml = 0
endif
while n < line('$')
let l = len(matchstr(getline(n), '^\s*[a-z]'))
if l > 0 && l <= ml
let n -= 1
break
endif
let n += 1
endwhile
call setpos('.', [0, n, 1, 0])
normal! V
call setpos('.', [0, sn, 1, 0])
endif
endfunction
function! zencoding#lang#sass#moveNextPrev(flag)
let pos = search('""\|\(^\s*|\s*\zs\)', a:flag ? 'Wpb' : 'Wp')
if pos == 2
startinsert!
elseif pos != 0
silent! normal! l
startinsert
endif
endfunction
function! zencoding#lang#sass#splitJoinTag()
endfunction
function! zencoding#lang#sass#removeTag()
endfunction

View file

@ -1,121 +0,0 @@
function! zencoding#lang#scss#findTokens(str)
return zencoding#lang#html#findTokens(a:str)
endfunction
function! zencoding#lang#scss#parseIntoTree(abbr, type)
if a:abbr =~ '>'
return zencoding#lang#html#parseIntoTree(a:abbr, a:type)
else
return zencoding#lang#css#parseIntoTree(a:abbr, a:type)
endif
endfunction
function! zencoding#lang#scss#toString(settings, current, type, inline, filters, itemno, indent)
let settings = a:settings
let current = a:current
let type = a:type
let inline = a:inline
let filters = a:filters
let itemno = a:itemno
let indent = a:indent
let str = ""
let current_name = substitute(current.name, '\$$', itemno+1, '')
if len(current.name) > 0
let str .= current_name
let tmp = ''
for attr in keys(current.attr)
let val = current.attr[attr]
while val =~ '\$\([^#{]\|$\)'
let val = substitute(val, '\(\$\+\)\([^{]\|$\)', '\=printf("%0".len(submatch(1))."d", itemno+1).submatch(2)', 'g')
endwhile
let attr = substitute(attr, '\$$', itemno+1, '')
if attr == 'id'
let str .= '#' . val
elseif attr == 'class'
let str .= '.' . val
else
let tmp .= attr . ': ' . val . ';'
endif
endfor
if len(tmp) > 0
let str .= " {\n"
for line in split(tmp, "\n")
let str .= indent . line . "\n"
endfor
else
let str .= " {\n"
endif
let inner = ''
for child in current.child
let inner .= zencoding#toString(child, type, inline, filters, itemno)
endfor
let inner = substitute(inner, "\n", "\n" . escape(indent, '\'), 'g')
let inner = substitute(inner, "\n" . escape(indent, '\') . "$", "", 'g')
let str .= indent . inner . "\n}\n"
else
return zencoding#lang#css#toString(settings, current, type, inline, filters, itemno, indent)
endif
return str
endfunction
function! zencoding#lang#scss#imageSize()
call zencoding#lang#css#imageSize()
endfunction
function! zencoding#lang#scss#encodeImage()
return zencoding#lang#css#encodeImage()
endfunction
function! zencoding#lang#scss#parseTag(tag)
return zencoding#lang#css#parseTag(a:tag)
endfunction
function! zencoding#lang#scss#toggleComment()
call zencoding#lang#css#toggleComment()
endfunction
function! zencoding#lang#scss#balanceTag(flag) range
if a:flag == -2 || a:flag == 2
let curpos = [0, line("'<"), col("'<"), 0]
call setpos('.', curpos)
else
let curpos = getpos('.')
endif
if a:flag < 0
let ret = searchpair('}', '', '.\zs{')
else
let ret = searchpair('{', '', '}', 'bW')
endif
if ret > 0
let pos1 = getpos('.')[1:2]
if a:flag < 0
let pos2 = searchpairpos('{', '', '}')
else
let pos2 = searchpairpos('{', '', '}')
endif
let block = [pos1, pos2]
if zencoding#util#regionIsValid(block)
call zencoding#util#selectRegion(block)
return
endif
endif
if a:flag == -2 || a:flag == 2
silent! exe "normal! gv"
else
call setpos('.', curpos)
endif
endfunction
function! zencoding#lang#scss#moveNextPrev(flag)
call zencoding#lang#css#moveNextPrev(a:flag)
endfunction
function! zencoding#lang#scss#splitJoinTag()
call zencoding#lang#css#splitJoinTag()
endfunction
function! zencoding#lang#scss#removeTag()
call zencoding#lang#ss#removeTag()
endfunction

View file

@ -1,276 +0,0 @@
function! zencoding#lang#slim#findTokens(str)
return zencoding#lang#html#findTokens(a:str)
endfunction
function! zencoding#lang#slim#parseIntoTree(abbr, type)
return zencoding#lang#html#parseIntoTree(a:abbr, a:type)
endfunction
function! zencoding#lang#slim#toString(settings, current, type, inline, filters, itemno, indent)
let settings = a:settings
let current = a:current
let type = a:type
let inline = a:inline
let filters = a:filters
let itemno = a:itemno
let indent = a:indent
let dollar_expr = zencoding#getResource(type, 'dollar_expr', 1)
let str = ""
let comment_indent = ''
let comment = ''
let current_name = current.name
if dollar_expr
let current_name = substitute(current.name, '\$$', itemno+1, '')
endif
if len(current.name) > 0
let str .= current_name
for attr in current.attrs_order
if !has_key(current.attr, attr)
continue
endif
let val = current.attr[attr]
if dollar_expr
while val =~ '\$\([^#{]\|$\)'
let val = substitute(val, '\(\$\+\)\([^{]\|$\)', '\=printf("%0".len(submatch(1))."d", itemno+1).submatch(2)', 'g')
endwhile
endif
let attr = substitute(attr, '\$$', itemno+1, '')
let str .= ' ' . attr . '="' . val . '"'
endfor
let inner = ''
if len(current.value) > 0
let str .= "\n"
let text = current.value[1:-2]
if dollar_expr
let text = substitute(text, '\%(\\\)\@\<!\(\$\+\)\([^{#]\|$\)', '\=printf("%0".len(submatch(1))."d", itemno+1).submatch(2)', 'g')
let text = substitute(text, '\${nr}', "\n", 'g')
let text = substitute(text, '\\\$', '$', 'g')
let str = substitute(str, '\$#', text, 'g')
endif
for line in split(text, "\n")
let str .= indent . "| " . line . "\n"
endfor
elseif len(current.child) == 0
let str .= '${cursor}'
endif
if len(current.child) == 1 && len(current.child[0].name) == 0
let str .= "\n"
let text = current.child[0].value[1:-2]
if dollar_expr
let text = substitute(text, '\%(\\\)\@\<!\(\$\+\)\([^{#]\|$\)', '\=printf("%0".len(submatch(1))."d", itemno+1).submatch(2)', 'g')
let text = substitute(text, '\${nr}', "\n", 'g')
let text = substitute(text, '\\\$', '$', 'g')
endif
for line in split(text, "\n")
let str .= indent . "| " . line . "\n"
endfor
elseif len(current.child) > 0
for child in current.child
let inner .= zencoding#toString(child, type, inline, filters, itemno)
endfor
let inner = substitute(inner, "\n", "\n" . escape(indent, '\'), 'g')
let inner = substitute(inner, "\n" . escape(indent, '\') . "$", "", 'g')
let str .= "\n" . indent . inner
endif
else
let str = current.value[1:-2]
if dollar_expr
let str = substitute(str, '\%(\\\)\@\<!\(\$\+\)\([^{#]\|$\)', '\=printf("%0".len(submatch(1))."d", itemno+1).submatch(2)', 'g')
let str = substitute(str, '\${nr}', "\n", 'g')
let str = substitute(str, '\\\$', '$', 'g')
endif
endif
if str !~ "\n$"
let str .= "\n"
endif
return str
endfunction
function! zencoding#lang#slim#imageSize()
let line = getline('.')
let current = zencoding#lang#slim#parseTag(line)
if empty(current) || !has_key(current.attr, 'src')
return
endif
let fn = current.attr.src
if fn =~ '^\s*$'
return
elseif fn !~ '^\(/\|http\)'
let fn = simplify(expand('%:h') . '/' . fn)
endif
let [width, height] = zencoding#util#getImageSize(fn)
if width == -1 && height == -1
return
endif
let current.attr.width = width
let current.attr.height = height
let current.attrs_order += ['width', 'height']
let slim = zencoding#toString(current, 'slim', 1)
let slim = substitute(slim, '\${cursor}', '', '')
call setline('.', substitute(matchstr(line, '^\s*') . slim, "\n", "", "g"))
endfunction
function! zencoding#lang#slim#encodeImage()
endfunction
function! zencoding#lang#slim#parseTag(tag)
let current = { 'name': '', 'attr': {}, 'child': [], 'snippet': '', 'multiplier': 1, 'parent': {}, 'value': '', 'pos': 0, 'attrs_order': [] }
let mx = '\([a-zA-Z][a-zA-Z0-9]*\)\s\+\(.*\)'
let match = matchstr(a:tag, mx)
let current.name = substitute(match, mx, '\1', 'i')
let attrs = substitute(match, mx, '\2', 'i')
let mx = '\([a-zA-Z0-9]\+\)=\%(\([^"'' \t]\+\)\|"\([^"]\{-}\)"\|''\([^'']\{-}\)''\)'
while len(attrs) > 0
let match = matchstr(attrs, mx)
if len(match) == 0
break
endif
let attr_match = matchlist(match, mx)
let name = attr_match[1]
let value = len(attr_match[2]) ? attr_match[2] : attr_match[3]
let current.attr[name] = value
let current.attrs_order += [name]
let attrs = attrs[stridx(attrs, match) + len(match):]
endwhile
return current
endfunction
function! zencoding#lang#slim#toggleComment()
let line = getline('.')
let space = matchstr(line, '^\s*')
if line =~ '^\s*/'
call setline('.', space . line[len(space)+1:])
elseif line =~ '^\s*[a-z]'
call setline('.', space . '/' . line[len(space):])
endif
endfunction
function! zencoding#lang#slim#balanceTag(flag) range
let block = zencoding#util#getVisualBlock()
if a:flag == -2 || a:flag == 2
let curpos = [0, line("'<"), col("'<"), 0]
else
let curpos = getpos('.')
endif
let n = curpos[1]
let ml = len(matchstr(getline(n), '^\s*'))
if a:flag > 0
if a:flag == 1 || !zencoding#util#regionIsValid(block)
let n = line('.')
else
while n > 0
let l = len(matchstr(getline(n), '^\s*\ze[a-z]'))
if l > 0 && l < ml
let ml = l
break
endif
let n -= 1
endwhile
endif
let sn = n
if n == 0
let ml = 0
endif
while n < line('$')
let l = len(matchstr(getline(n), '^\s*[a-z]'))
if l > 0 && l <= ml
let n -= 1
break
endif
let n += 1
endwhile
call setpos('.', [0, n, 1, 0])
normal! V
call setpos('.', [0, sn, 1, 0])
else
while n > 0
let l = len(matchstr(getline(n), '^\s*\ze[a-z]'))
if l > 0 && l > ml
let ml = l
break
endif
let n += 1
endwhile
let sn = n
if n == 0
let ml = 0
endif
while n < line('$')
let l = len(matchstr(getline(n), '^\s*[a-z]'))
if l > 0 && l <= ml
let n -= 1
break
endif
let n += 1
endwhile
call setpos('.', [0, n, 1, 0])
normal! V
call setpos('.', [0, sn, 1, 0])
endif
endfunction
function! zencoding#lang#slim#moveNextPrev(flag)
let pos = search('""\|\(^\s*|\s*\zs\)', a:flag ? 'Wpb' : 'Wp')
if pos == 2
startinsert!
elseif pos != 0
silent! normal! l
startinsert
endif
endfunction
function! zencoding#lang#slim#splitJoinTag()
let n = line('.')
while n > 0
if getline(n) =~ '^\s*\ze[a-z]'
let sn = n
let n += 1
if getline(n) =~ '^\s*|'
while n <= line('$')
if getline(n) !~ '^\s*|'
break
endif
exe n "delete"
endwhile
call setpos('.', [0, sn, 1, 0])
else
let spaces = matchstr(getline(sn), '^\s*')
call append(sn, spaces . ' | ')
call setpos('.', [0, sn+1, 1, 0])
startinsert!
endif
break
endif
let n -= 1
endwhile
endfunction
function! zencoding#lang#slim#removeTag()
let n = line('.')
let ml = 0
while n > 0
if getline(n) =~ '^\s*\ze[a-z]'
let ml = len(matchstr(getline(n), '^\s*[a-z]'))
break
endif
let n -= 1
endwhile
let sn = n
while n < line('$')
let l = len(matchstr(getline(n), '^\s*[a-z]'))
if l > 0 && l <= ml
let n -= 1
break
endif
let n += 1
endwhile
if sn == n
exe "delete"
else
exe sn "," (n-1) "delete"
endif
endfunction

View file

@ -1,249 +0,0 @@
"==============================================================================
" region utils
"==============================================================================
" deleteContent : delete content in region
" if region make from between '<foo>' and '</foo>'
" --------------------
" begin:<foo>
" </foo>:end
" --------------------
" this function make the content as following
" --------------------
" begin::end
" --------------------
function! zencoding#util#deleteContent(region)
let lines = getline(a:region[0][0], a:region[1][0])
call setpos('.', [0, a:region[0][0], a:region[0][1], 0])
silent! exe "delete ".(a:region[1][0] - a:region[0][0])
call setline(line('.'), lines[0][:a:region[0][1]-2] . lines[-1][a:region[1][1]])
endfunction
" change_content : change content in region
" if region make from between '<foo>' and '</foo>'
" --------------------
" begin:<foo>
" </foo>:end
" --------------------
" and content is
" --------------------
" foo
" bar
" baz
" --------------------
" this function make the content as following
" --------------------
" begin:foo
" bar
" baz:end
" --------------------
function! zencoding#util#setContent(region, content)
let newlines = split(a:content, '\n', 1)
let oldlines = getline(a:region[0][0], a:region[1][0])
call setpos('.', [0, a:region[0][0], a:region[0][1], 0])
silent! exe "delete ".(a:region[1][0] - a:region[0][0])
if len(newlines) == 0
let tmp = ''
if a:region[0][1] > 1
let tmp = oldlines[0][:a:region[0][1]-2]
endif
if a:region[1][1] >= 1
let tmp .= oldlines[-1][a:region[1][1]:]
endif
call setline(line('.'), tmp)
elseif len(newlines) == 1
if a:region[0][1] > 1
let newlines[0] = oldlines[0][:a:region[0][1]-2] . newlines[0]
endif
if a:region[1][1] >= 1
let newlines[0] .= oldlines[-1][a:region[1][1]:]
endif
call setline(line('.'), newlines[0])
else
if a:region[0][1] > 1
let newlines[0] = oldlines[0][:a:region[0][1]-2] . newlines[0]
endif
if a:region[1][1] >= 1
let newlines[-1] .= oldlines[-1][a:region[1][1]:]
endif
call setline(line('.'), newlines[0])
call append(line('.'), newlines[1:])
endif
endfunction
" select_region : select region
" this function make a selection of region
function! zencoding#util#selectRegion(region)
call setpos('.', [0, a:region[1][0], a:region[1][1], 0])
normal! v
call setpos('.', [0, a:region[0][0], a:region[0][1], 0])
endfunction
" point_in_region : check point is in the region
" this function return 0 or 1
function! zencoding#util#pointInRegion(point, region)
if !zencoding#util#regionIsValid(a:region) | return 0 | endif
if a:region[0][0] > a:point[0] | return 0 | endif
if a:region[1][0] < a:point[0] | return 0 | endif
if a:region[0][0] == a:point[0] && a:region[0][1] > a:point[1] | return 0 | endif
if a:region[1][0] == a:point[0] && a:region[1][1] < a:point[1] | return 0 | endif
return 1
endfunction
" cursor_in_region : check cursor is in the region
" this function return 0 or 1
function! zencoding#util#cursorInRegion(region)
if !zencoding#util#regionIsValid(a:region) | return 0 | endif
let cur = getpos('.')[1:2]
return zencoding#util#pointInRegion(cur, a:region)
endfunction
" region_is_valid : check region is valid
" this function return 0 or 1
function! zencoding#util#regionIsValid(region)
if a:region[0][0] == 0 || a:region[1][0] == 0 | return 0 | endif
return 1
endfunction
" search_region : make region from pattern which is composing start/end
" this function return array of position
function! zencoding#util#searchRegion(start, end)
return [searchpairpos(a:start, '', a:end, 'bcnW'), searchpairpos(a:start, '\%#', a:end, 'nW')]
endfunction
" get_content : get content in region
" this function return string in region
function! zencoding#util#getContent(region)
if !zencoding#util#regionIsValid(a:region)
return ''
endif
let lines = getline(a:region[0][0], a:region[1][0])
if a:region[0][0] == a:region[1][0]
let lines[0] = lines[0][a:region[0][1]-1:a:region[1][1]-1]
else
let lines[0] = lines[0][a:region[0][1]-1:]
let lines[-1] = lines[-1][:a:region[1][1]-1]
endif
return join(lines, "\n")
endfunction
" region_in_region : check region is in the region
" this function return 0 or 1
function! zencoding#util#regionInRegion(outer, inner)
if !zencoding#util#regionIsValid(a:inner) || !zencoding#util#regionIsValid(a:outer)
return 0
endif
return zencoding#util#pointInRegion(a:inner[0], a:outer) && zencoding#util#pointInRegion(a:inner[1], a:outer)
endfunction
" get_visualblock : get region of visual block
" this function return region of visual block
function! zencoding#util#getVisualBlock()
return [[line("'<"), col("'<")], [line("'>"), col("'>")]]
endfunction
"==============================================================================
" html utils
"==============================================================================
function! zencoding#util#getContentFromURL(url)
let res = system(printf("%s %s", g:zencoding_curl_command, shellescape(substitute(a:url, '#.*', '', ''))))
let s1 = len(split(res, '?'))
let utf8 = iconv(res, 'utf-8', &encoding)
let s2 = len(split(utf8, '?'))
return (s2 == s1 || s2 >= s1 * 2) ? utf8 : res
endfunction
function! zencoding#util#getTextFromHTML(buf)
let threshold_len = 100
let threshold_per = 0.1
let buf = a:buf
let buf = strpart(buf, stridx(buf, '</head>'))
let buf = substitute(buf, '<style[^>]*>.\{-}</style>', '', 'g')
let buf = substitute(buf, '<script[^>]*>.\{-}</script>', '', 'g')
let res = ''
let max = 0
let mx = '\(<td[^>]\{-}>\)\|\(<\/td>\)\|\(<div[^>]\{-}>\)\|\(<\/div>\)'
let m = split(buf, mx)
for str in m
let c = split(str, '<[^>]*?>')
let str = substitute(str, '<[^>]\{-}>', ' ', 'g')
let str = substitute(str, '&gt;', '>', 'g')
let str = substitute(str, '&lt;', '<', 'g')
let str = substitute(str, '&quot;', '"', 'g')
let str = substitute(str, '&apos;', "'", 'g')
let str = substitute(str, '&nbsp;', ' ', 'g')
let str = substitute(str, '&yen;', '\&#65509;', 'g')
let str = substitute(str, '&amp;', '\&', 'g')
let str = substitute(str, '^\s*\(.*\)\s*$', '\1', '')
let str = substitute(str, '\s\+', ' ', 'g')
let l = len(str)
if l > threshold_len
let per = (l+0.0) / len(c)
if max < l && per > threshold_per
let max = l
let res = str
endif
endif
endfor
let res = substitute(res, '^\s*\(.*\)\s*$', '\1', 'g')
return res
endfunction
function! zencoding#util#getImageSize(fn)
let fn = a:fn
if zencoding#util#isImageMagickInstalled()
return zencoding#util#imageSizeWithImageMagick(fn)
endif
if filereadable(fn)
let hex = substitute(system('xxd -p "'.fn.'"'), '\n', '', 'g')
else
let hex = substitute(system(g:zencoding_curl_command.' "'.fn.'" | xxd -p'), '\n', '', 'g')
endif
let [width, height] = [-1, -1]
if hex =~ '^89504e470d0a1a0a'
let width = eval('0x'.hex[32:39])
let height = eval('0x'.hex[40:47])
endif
if hex =~ '^ffd8'
let pos = 4
while pos < len(hex)
let bs = hex[pos+0:pos+3]
let pos += 4
if bs == 'ffc0' || bs == 'ffc2'
let pos += 6
let height = eval('0x'.hex[pos+0:pos+1])*256 + eval('0x'.hex[pos+2:pos+3])
let pos += 4
let width = eval('0x'.hex[pos+0:pos+1])*256 + eval('0x'.hex[pos+2:pos+3])
break
elseif bs =~ 'ffd[9a]'
break
elseif bs =~ 'ff\(e[0-9a-e]\|fe\|db\|dd\|c4\)'
let pos += (eval('0x'.hex[pos+0:pos+1])*256 + eval('0x'.hex[pos+2:pos+3])) * 2
endif
endwhile
endif
if hex =~ '^47494638'
let width = eval('0x'.hex[14:15].hex[12:13])
let height = eval('0x'.hex[18:19].hex[16:17])
endif
return [width, height]
endfunction
function! zencoding#util#imageSizeWithImageMagick(fn)
let img_info = system('identify -format "%wx%h" "'.a:fn.'"')
let img_size = split(substitute(img_info, '\n', '', ''), 'x')
let width = img_size[0]
let height = img_size[1]
return [width, height]
endfunction
function! zencoding#util#isImageMagickInstalled()
if !get(s:, 'zencoding_use_identify', 1)
return 0
endif
return executable('identify')
endfunction

View file

@ -1,438 +0,0 @@
*zencoding.txt* ZenCoding for Vim
-------------------------------------------------------
ZenCoding: vim plugins for HTML and CSS hi-speed coding
-------------------------------------------------------
Author: Yasuhiro Matsumoto <mattn.jp@gmail.com>
WebSite: http://mattn.kaoriya.net/
Repository: http://github.com/mattn/zencoding-vim
Site: http://mattn.github.com/zencoding-vim
License: BSD style license
==============================================================================
CONTENTS *zencoding-contents*
Introduction |zencoding-introduction|
Install |zencoding-install|
Tutorial |zencoding-tutorial|
1. Expand Abbreviation |zencoding-expandabbr|
2. Wrap with Abbreviation |zencoding-wrap-wtih-abbreviation|
3. Balance Tag Inward |zencoding-balance-tag-inward|
4. Balance Tag Outward |zencoding-balance-tag-outward|
5. Go to Next Edit Point |zencoding-goto-next-point| |<C-Y>n|
6. Go to Previous Edit Point |zencoding-goto-previous-point|
7. Update <img> Size |zencoding-update-image-size|
8. Merge Lines |zencoding-merge-lines|
9. Remove Tag |zencoding-remove-tag|
10. Split/Join Tag |zencoding-split-join-tag|
11. Toggle Comment |zencoding-toggle-comment|
12. Make anchor from URL |zencoding-make-anchor-url|
13. Make quoted text from URL |zencoding-quoted-text-url|
14. Code Pretty |zencoding-code-pretty|
Customize |zencoding-customize|
1. Key Mappings |zencoding-customize-keymappings|
2. Indent Size |zencoding-indent-size|
3. Define Tag's Behavior |zencoding-define-tags-behavior|
4. Complete Tag |zencoding-complete-tag|
Links |zencoding-links|
ToDo |zencoding-todo|
==============================================================================
INTRODUCTION *zencoding-introduction* *zencoding*
|ZenCoding| is an editor plugin for high-speed HTML, XML, XSL (or any other
structured code format) coding and editing. The core of this plugin is a
powerful abbreviation engine which allows you to expand expressions?similar to
CSS selectors?into HTML code:
>
div#page>div.logo+ul#navigation>li*5>a
<
...can be expanded into:
>
<div id="page">
<div class="logo"></div>
<ul id="navigation">
<li><a href=""></a></li>
<li><a href=""></a></li>
<li><a href=""></a></li>
<li><a href=""></a></li>
<li><a href=""></a></li>
</ul>
</div>
<
Read more about current Zen Coding syntax
http://code.google.com/p/zen-coding/wiki/ZenHTMLSelectorsEn
Abbreviation engine has a modular structure which allows you to expand
abbreviations into different languages. Zen Coding currently supports CSS,
HTML, XML/XSL and HAML, Slim languages via filters.
==============================================================================
INSTALL *zencoding-install*
Install the distributed files into Vim runtime directory which is usually
~/.vim/, or $HOME/vimfiles on Windows.
If you install pathogen that provided from Tim Pope, you should extract the
file into 'bundle' directory.
==============================================================================
TUTORIAL *zencoding-tutorial*
If you are seeing this file as :help, then you can't edit this file.
You should copy this section and create new buffer, paste and write as
'zencoding-tutor.txt'. Formally, open the file to start tutorial.
1. Expand Abbreviation *zencoding-expandabbr* *<C-Y>,*
Type abbreviation as 'div>p#foo$*3>a' and type |<C-Y>,|.
>
<div>
<p id="foo1">
<a href=""></a>
</p>
<p id="foo2">
<a href=""></a>
</p>
<p id="foo3">
<a href=""></a>
</p>
</div>
<
2. Wrap with Abbreviation *zencoding-wrap-wtih-abbreviation* *v_<C-Y>,*
Write as below.
>
test1
test2
test3
<
Then do visual select(line wize) and type |<C-Y>,|.
If you request 'Tag:', then type 'ul>li*'.
>
<ul>
<li>test1</li>
<li>test2</li>
<li>test3</li>
</ul>
<
If you type tag as 'blockquote', then you'll see as following.
>
<blockquote>
test1
test2
test3
</blockquote>
<
3. Balance Tag Inward *zencoding-balance-tag-inward* *<C-Y>d*
To select inward of ul tag, type |<C-Y>d| in insert mode.
>
<ul>
* <li class="list1"></li>
<li class="list2"></li>
<li class="list3"></li>
</ul>
<
If cursor is at '*', |<C-Y>d| select from begin of <ul> to end of </ul>.
If cursor is at first of <li>, it select <li class="list1"></li>.
4. Balance Tag Outward *zencoding-balance-tag-outward* *<C-Y>D*
To select outward of ul tag, insert mode, type <C-Y>D in insert mode.
>
<ul>
* <li class="list1"></li>
<li class="list2"></li>
<li class="list3"></li>
</ul>
<
If cursor is at '*', |<C-Y>D| select from next letter of <ul> to previous
letter of </ul>.
If cursor is at first of <li>, it select <li class="list1"></li>.
5. Go to Next Edit Point *zencoding-goto-next-point* *<C-Y>n*
To jump next point that need to edit, type |<C-Y>n| in insert mode.
>
* <div id="foo" class="">foo</div>
<div id="bar" class="bar"></li>
<
If cursor is at '*', |<C-Y>n| move a cursor into attribute value of div
specified id as 'foo'. And type again |<C-Y>n| move a cursor into inner of
div specified id as 'bar'.
6. Go to Previous Edit Point *zencoding-goto-previous-point* *<C-Y>N*
To jump previous point that need to edit, type |<C-Y>N| in insert mode.
>
<div id="foo" class="">foo</div>
<div id="bar" class="bar"></li> *
<
If cursor is at '*', |<C-Y>N| move a cursor into div specified id as 'bar'.
And type again |<C-Y>N| move a cursor into attribute value of 'foo'.
7. Update <img> Size *zencoding-update-image-size* *<C-Y>i*
To expand or update size of image, type |<C-Y>i| on img tag
>
<img src="foo.png" />
<
Type '<c-y>i' on img tag
>
<img src="foo.png" width="32" height="32" />
<
If you change image, then type it again. it will be following.
>
<img src="foo-48.png" width="32" height="48" />
<
8. Merge Lines *zencoding-merge-lines*
To join multi line text like following, type |J|.
>
<ul>
<li class="list1"></li>
<li class="list2"></li>
<li class="list3"></li>
</ul>
<
If you select part of line include <li> and type |<C-Y>m|, it will be
following.
>
<ul>
<li class="list1"></li><li class="list2"></li><li class="list3"></li>
</ul>
<
9. Remove Tag *zencoding-remove-tag* *<C-Y>k*
To remove tag in the block, type |<C-Y>k|.
>
<div class="foo">
<a>cursor is here</a>
</div>
<
Type |<C-Y>k| in insert mode, then
>
<div class="foo">
</div>
<
And type |<C-Y>k| in there again, then div will be removed.
10. Split/Join Tag *zencoding-split-join-tag* *<C-Y>j*
To join block, type |<C-Y>j|.
>
<div class="foo">
cursor is here
</div>
<
Type |<C-Y>j| in insert mode. then,
>
<div class="foo"/>
<
And type |<C-Y>j| in there again.
>
<div class="foo">
</div>
<
11. Toggle Comment *zencoding-toggle-comment* *<C-Y>/*
Move cursor to block
>
<div>
hello world
</div>
<
Type '<c-y>/' in insert mode.
>
<!-- <div>
hello world
</div> -->
<
Type '<c-y>/' in there again.
>
<div>
hello world
</div>
<
12. Make anchor from URL *zencoding-make-anchor-url* *<C-Y>a*
Move cursor to URL
>
http://www.google.com/
<
Type |<C-Y>a|
>
<a href="http://www.google.com/">Google</a>
<
13. Make quoted text from URL *zencoding-quoted-text-url* *<C-Y>A*
Move cursor to URL
>
http://github.com/
<
Type |<C-Y>A|
>
<blockquote class="quote">
<a href="http://github.com/">Secure source code hosting and collaborative development - GitHub</a><br />
<p>How does it work? Get up and running in seconds by forking a project, pushing an existing repository...</p>
<cite>http://github.com/</cite>
</blockquote>
<
14. Code Pretty *zencoding-code-pretty* *<C-Y>c*
Select code block, for example select following code from "int main()".
>
<p>Writing in C language</p>
int main() {
puts("hello world");
}
<
Type |<C-Y>c|
>
<p>Writing in C language</p>
<span class="Type">int</span>&nbsp;main() {<br />
&nbsp;&nbsp;puts(<span class="Constant">&quot;hello world&quot;</span>);<br />
}<br />
<
==============================================================================
CUSTOMIZE *zencoding-customize*
1. Key Mapping *zencoding-customize-keymappings*
To specify leading key for expanding or balance tag, or for all,
Add this line in your vimrc: >
>
let g:user_zen_leader_key = '<c-y>'
<
Or if you prefer to map for each actions, then you set each variables.
'user_zen_expandabbr_key'
'user_zen_expandword_key'
'user_zen_balancetaginward_key'
'user_zen_balancetagoutward_key'
'user_zen_next_key'
'user_zen_prev_key'
'user_zen_imagesize_key'
'user_zen_togglecomment_key'
'user_zen_splitjointag_key'
'user_zen_removetag_key'
'user_zen_anchorizeurl_key'
'user_zen_anchorizesummary_key'
2. Indent Size *zencoding-indent-size*
To change indent size of html, add this code in your vimrc.
>
let g:user_zen_settings = {
\ 'html' : {
\ 'indentation' : ' '
\ },
\}
<
If you prefer to change global indent size then add this.
>
let g:user_zen_settings = {
\ 'indentation' : ' '
\}
<
3. Define Tag's Behavior *zencoding-define-tags-behavior*
zencoding.vim can change behavior of expanding abbreviation for each
filetypes as |Dictionary|. for details, see official site of zencoding.
for example, vimmer can add following.
>
let g:user_zen_settings = {
\ 'lang' : 'ja',
\ 'html' : {
\ 'filters' : 'html',
\ 'indentation' : ' '
\ },
\ 'perl' : {
\ 'indentation' : ' ',
\ 'aliases' : {
\ 'req' : "require '|'"
\ },
\ 'snippets' : {
\ 'use' : "use strict\nuse warnings\n\n",
\ 'w' : "warn \"${cursor}\";",
\ },
\ },
\ 'php' : {
\ 'extends' : 'html',
\ 'filters' : 'html,c',
\ },
\ 'css' : {
\ 'filters' : 'fc',
\ },
\ 'javascript' : {
\ 'snippets' : {
\ 'jq' : "$(function() {\n\t${cursor}${child}\n});",
\ 'jq:each' : "$.each(arr, function(index, item)\n\t${child}\n});",
\ 'fn' : "(function() {\n\t${cursor}\n})();",
\ 'tm' : "setTimeout(function() {\n\t${cursor}\n}, 100);",
\ },
\ },
\ 'java' : {
\ 'indentation' : ' ',
\ 'snippets' : {
\ 'main': "public static void main(String[] args) {\n\t|\n}",
\ 'println': "System.out.println(\"|\");",
\ 'class': "public class | {\n}\n",
\ },
\ },
\}
<
4. Complete Tag *zencoding-complete-tag*
If you want to complete tags using |omnifunc| then add this.
>
let g:use_zen_complete_tag = 1
<
5. Enable functions in different mode
If you want to use zencoding only in some modes, set an mode option:
let g:user_zen_mode='n' "only enable normal mode functions, or
let g:user_zen_mode='inv' "enable all functions, which is equal to
let g:user_zen_mode='a' "enable all function in all mode.
==============================================================================
LINKS *zencoding-links*
zen-coding official site:
http://code.google.com/p/zen-coding/
zencoding.vim:
http://mattn.github.com/zencoding-vim
development repository:
https://github.com/mattn/zencoding-vim
my blog posts about zencoding-vim:
http://mattn.kaoriya.net/software/vim/20100222103327.htm
http://mattn.kaoriya.net/software/vim/20100306021632.htm
japanese blog posts about zencoding-vim:
http://d.hatena.ne.jp/idesaku/20100424/1272092255
http://d.hatena.ne.jp/griefworker/20110118/vim_zen_coding
http://d.hatena.ne.jp/sakurako_s/20110126/1295988873
http://looxu.blogspot.jp/2010/02/zencodingvimhtml.html
tutorial traslated in chinese:
http://www.zfanw.com/blog/zencoding-vim-tutorial-chinese.html
==============================================================================
TODO *zencoding-todo*
* wrapping inline selected.
* more documents.
* more contributor.
* more time to improve zencodig.vim.
==============================================================================
vim:tw=78:ts=8:ft=help:norl:noet:fen:fdl=0:

View file

@ -1,215 +0,0 @@
"=============================================================================
" File: zencoding.vim
" Author: Yasuhiro Matsumoto <mattn.jp@gmail.com>
" Last Change: 13-Feb-2013.
" Version: 0.75
" WebPage: http://github.com/mattn/zencoding-vim
" Description: vim plugins for HTML and CSS hi-speed coding.
" SeeAlso: http://code.google.com/p/zen-coding/
" Usage:
"
" This is vim script support expanding abbreviation like zen-coding.
" ref: http://code.google.com/p/zen-coding/
"
" Type abbreviation
" +-------------------------------------
" | html:5_
" +-------------------------------------
" "_" is a cursor position. and type "<c-y>," (Ctrl+y and Comma)
" NOTE: Don't worry about key map. you can change it easily.
" +-------------------------------------
" | <!DOCTYPE HTML>
" | <html lang="en">
" | <head>
" | <title></title>
" | <meta charset="UTF-8">
" | </head>
" | <body>
" | _
" | </body>
" | </html>
" +-------------------------------------
" Type following
" +-------------------------------------
" | div#foo$*2>div.bar
" +-------------------------------------
" And type "<c-y>,"
" +-------------------------------------
" |<div id="foo1">
" | <div class="bar">_</div>
" |</div>
" |<div id="foo2">
" | <div class="bar"></div>
" |</div>
" +-------------------------------------
"
" Tips:
"
" You can customize behavior of expanding with overriding config.
" This configuration will be marged at loading plugin.
"
" let g:user_zen_settings = {
" \ 'indentation' : ' ',
" \ 'perl' : {
" \ 'aliases' : {
" \ 'req' : 'require '
" \ },
" \ 'snippets' : {
" \ 'use' : "use strict\nuse warnings\n\n",
" \ 'warn' : "warn \"|\";",
" \ }
" \ }
" \}
"
" You can set language attribute in html using 'zen_settings.lang'.
"
" GetLatestVimScripts: 2981 1 :AutoInstall: zencoding.vim
" script type: plugin
if &cp || (exists('g:loaded_zencoding_vim') && g:loaded_zencoding_vim)
finish
endif
let g:loaded_zencoding_vim = 1
let s:save_cpo = &cpo
set cpo&vim
if !exists('g:zencoding_debug')
let g:zencoding_debug = 0
endif
if !exists('g:zencoding_curl_command')
let g:zencoding_curl_command = 'curl -s -L -A Mozilla/5.0'
endif
if exists('g:use_zen_complete_tag') && g:use_zen_complete_tag
setlocal omnifunc=zencoding#CompleteTag
endif
if !exists('g:user_zen_leader_key')
let g:user_zen_leader_key = '<c-y>'
endif
function! s:install_plugin_i()
for item in [
\ {'mode': 'i', 'var': 'user_zen_expandabbr_key', 'key': ',', 'plug': 'ZenCodingExpandAbbr', 'func': '<c-g>u<esc>:call zencoding#expandAbbr(0,"")<cr>a'},
\ {'mode': 'i', 'var': 'user_zen_expandword_key', 'key': ';', 'plug': 'ZenCodingExpandWord', 'func': '<c-g>u<esc>:call zencoding#expandAbbr(1,"")<cr>a'},
\ {'mode': 'i', 'var': 'user_zen_balancetaginward_key', 'key': 'd', 'plug': 'ZenCodingBalanceTagInwardInsert', 'func': '<esc>:call zencoding#balanceTag(1)<cr>'},
\ {'mode': 'i', 'var': 'user_zen_balancetagoutward_key', 'key': 'D', 'plug': 'ZenCodingBalanceTagOutwardInsert', 'func': '<esc>:call zencoding#balanceTag(-1)<cr>'},
\ {'mode': 'i', 'var': 'user_zen_next_key', 'key': 'n', 'plug': 'ZenCodingNext', 'func': '<esc>:call zencoding#moveNextPrev(0)<cr>'},
\ {'mode': 'i', 'var': 'user_zen_prev_key', 'key': 'N', 'plug': 'ZenCodingPrev', 'func': '<esc>:call zencoding#moveNextPrev(1)<cr>'},
\ {'mode': 'i', 'var': 'user_zen_imagesize_key', 'key': 'i', 'plug': 'ZenCodingImageSize', 'func': '<esc>:call zencoding#imageSize()<cr>a'},
\ {'mode': 'i', 'var': 'user_zen_togglecomment_key', 'key': '/', 'plug': 'ZenCodingToggleComment', 'func': '<esc>:call zencoding#toggleComment()<cr>a'},
\ {'mode': 'i', 'var': 'user_zen_splitjointag_key', 'key': 'j', 'plug': 'ZenCodingSplitJoinTagInsert', 'func': '<esc>:call zencoding#splitJoinTag()<cr>'},
\ {'mode': 'i', 'var': 'user_zen_removetag_key', 'key': 'k', 'plug': 'ZenCodingRemoveTag', 'func': '<esc>:call zencoding#removeTag()<cr>a'},
\ {'mode': 'i', 'var': 'user_zen_anchorizeurl_key', 'key': 'a', 'plug': 'ZenCodingAnchorizeURL', 'func': '<esc>:call zencoding#anchorizeURL(0)<cr>a'},
\ {'mode': 'i', 'var': 'user_zen_anchorizesummary_key', 'key': 'A', 'plug': 'ZenCodingAnchorizeSummary', 'func': '<esc>:call zencoding#anchorizeURL(1)<cr>a'},
\]
if !hasmapto('<plug>'.item.plug, item.mode)
exe item.mode . 'noremap <plug>' . item.plug . ' ' . item.func
endif
if !exists('g:' . item.var)
endif
if exists('g:' . item.var)
let key = eval('g:' . item.var)
else
let key = g:user_zen_leader_key . item.key
endif
if len(maparg(key, item.mode)) == 0
exe item.mode . 'map <unique> ' . key . ' <plug>' . item.plug
endif
endfor
endfunction
function! s:install_plugin_n()
for item in [
\ {'mode': 'n', 'var': 'user_zen_expandabbr_key', 'key': ',', 'plug': 'ZenCodingExpandNormal', 'func': ':call zencoding#expandAbbr(3,"")<cr>'},
\ {'mode': 'n', 'var': 'user_zen_expandword_key', 'key': ',', 'plug': 'ZenCodingExpandWord', 'func': ':call zencoding#expandAbbr(1,"")<cr>'},
\ {'mode': 'n', 'var': 'user_zen_balancetaginward_key', 'key': 'd', 'plug': 'ZenCodingBalanceTagInwardNormal', 'func': ':call zencoding#balanceTag(1)<cr>'},
\ {'mode': 'n', 'var': 'user_zen_balancetagoutward_key', 'key': 'D', 'plug': 'ZenCodingBalanceTagOutwardNormal', 'func': ':call zencoding#balanceTag(-1)<cr>'},
\ {'mode': 'n', 'var': 'user_zen_next_key', 'key': 'n', 'plug': 'ZenCodingNext', 'func': ':call zencoding#moveNextPrev(0)<cr>'},
\ {'mode': 'n', 'var': 'user_zen_prev_key', 'key': 'N', 'plug': 'ZenCodingPrev', 'func': ':call zencoding#moveNextPrev(1)<cr>'},
\ {'mode': 'n', 'var': 'user_zen_imagesize_key', 'key': 'i', 'plug': 'ZenCodingImageSize', 'func': ':call zencoding#imageSize()<cr>'},
\ {'mode': 'n', 'var': 'user_zen_togglecomment_key', 'key': '/', 'plug': 'ZenCodingToggleComment', 'func': ':call zencoding#toggleComment()<cr>'},
\ {'mode': 'n', 'var': 'user_zen_splitjointag_key', 'key': 'j', 'plug': 'ZenCodingSplitJoinTagNormal', 'func': ':call zencoding#splitJoinTag()<cr>'},
\ {'mode': 'n', 'var': 'user_zen_removetag_key', 'key': 'k', 'plug': 'ZenCodingRemoveTag', 'func': ':call zencoding#removeTag()<cr>'},
\ {'mode': 'n', 'var': 'user_zen_anchorizeurl_key', 'key': 'a', 'plug': 'ZenCodingAnchorizeURL', 'func': ':call zencoding#anchorizeURL(0)<cr>'},
\ {'mode': 'n', 'var': 'user_zen_anchorizesummary_key', 'key': 'A', 'plug': 'ZenCodingAnchorizeSummary', 'func': ':call zencoding#anchorizeURL(1)<cr>'},
\]
if !hasmapto('<plug>'.item.plug, item.mode)
exe item.mode . 'noremap <plug>' . item.plug . ' ' . item.func
endif
if !exists('g:' . item.var)
endif
if exists('g:' . item.var)
let key = eval('g:' . item.var)
else
let key = g:user_zen_leader_key . item.key
endif
if len(maparg(key, item.mode)) == 0
exe item.mode . 'map <unique> ' . key . ' <plug>' . item.plug
endif
endfor
endfunction
function! s:install_plugin_v()
for item in [
\ {'mode': 'v', 'var': 'user_zen_expandabbr_key', 'key': ',', 'plug': 'ZenCodingExpandVisual', 'func': ':call zencoding#expandAbbr(2,"")<cr>'},
\ {'mode': 'v', 'var': 'user_zen_balancetaginward_key', 'key': 'd', 'plug': 'ZenCodingBalanceTagInwardVisual', 'func': ':call zencoding#balanceTag(2)<cr>'},
\ {'mode': 'v', 'var': 'user_zen_balancetagoutward_key', 'key': 'D', 'plug': 'ZenCodingBalanceTagOutwardVisual', 'func': ':call zencoding#balanceTag(-2)<cr>'},
\ {'mode': 'v', 'var': 'user_zen_mergelines_key', 'key': 'm', 'plug': 'ZenCodingMergeLines', 'func': ':call zencoding#mergeLines()<cr>'},
\ {'mode': 'v', 'var': 'user_zen_codepretty_key', 'key': 'c', 'plug': 'ZenCodingCodePretty', 'func': ':call zencoding#codePretty()<cr>'},
\]
if !hasmapto('<plug>'.item.plug, item.mode)
exe item.mode . 'noremap <plug>' . item.plug . ' ' . item.func
endif
if !exists('g:' . item.var)
endif
if exists('g:' . item.var)
let key = eval('g:' . item.var)
else
let key = g:user_zen_leader_key . item.key
endif
if len(maparg(key, item.mode)) == 0
exe item.mode . 'map <unique> ' . key . ' <plug>' . item.plug
endif
endfor
endfunction
if exists('g:user_zen_mode')
let imode = matchstr(g:user_zen_mode, '[ai]')
let nmode = matchstr(g:user_zen_mode, '[an]')
let vmode = matchstr(g:user_zen_mode, '[av]')
if !empty(imode)
call s:install_plugin_i()
endif
if !empty(nmode)
call s:install_plugin_n()
endif
if !empty(vmode)
call s:install_plugin_v()
endif
else
call s:install_plugin_i()
call s:install_plugin_n()
call s:install_plugin_v()
endif
delfunction s:install_plugin_i
delfunction s:install_plugin_n
delfunction s:install_plugin_v
command! -nargs=1 Zen call zencoding#expandAbbr(4, <q-args>)
let &cpo = s:save_cpo
unlet s:save_cpo
" vim:set et:

View file

@ -1,794 +0,0 @@
let s:sfile = expand('<sfile>')
function! s:reload(d)
exe "so" a:d."/plugin/zencoding.vim"
for f in split(globpath(a:d, 'autoload/**/*.vim'), "\n")
silent! exe "so" f
endfor
endfunction
function! s:show_type(type)
echohl Search | echon "[" a:type "]\n" | echohl None
echo "\r"
endfunction
function! s:show_category(category)
echohl MatchParen | echon "[" a:category "]\n" | echohl None
echo "\r"
endfunction
function! s:show_pass(pass)
echohl Title | echo "pass".a:pass."\n" | echohl None
endfunction
function! s:show_done()
echohl IncSearch | echo "done" | echohl None
endfunction
function! s:escape(str)
let str = a:str
let str = substitute(str, "\n", '\\n', 'g')
let str = substitute(str, "\t", '\\t', 'g')
return str
endfunction
function! s:show_title(no, title)
let title = s:escape(a:title)
let width = &columns - 23
echohl MoreMsg | echon "\rtesting #".printf("%03d", a:no)
echohl None | echon ": " . (len(title) < width ? (title.repeat(' ', width-len(title))) : strpart(title, 0, width)) . ' ... '
endfunction
function! s:show_skip(no, title)
let title = s:escape(a:title)
let width = &columns - 23
echohl WarningMsg | echon "\rskipped #".printf("%03d", a:no)
echohl None | echon ": " . (len(title) < width ? (title.repeat(' ', width-len(title))) : strpart(title, 0, width)) . ' ... '
echo ""
endfunction
function! s:show_ok()
echohl Title | echon "ok\n" | echohl None
echo ""
endfunction
function! s:show_ng(no, expect, got)
echohl WarningMsg | echon "ng\n" | echohl None
echohl ErrorMsg | echo "failed test #".a:no | echohl None
set more
echohl WarningMsg | echo printf("expect(%d):", len(a:expect)) | echohl None
echo join(split(a:expect, "\n", 1), "|\n")
echohl WarningMsg | echo printf("got(%d):", len(a:got)) | echohl None
echo join(split(a:got, "\n", 1), "|\n")
let cs = split(a:expect, '\zs')
for c in range(len(cs))
if c < len(a:got)
if a:expect[c] != a:got[c]
echohl WarningMsg | echo "differ at:" | echohl None
echo a:expect[c :-1]
break
endif
endif
endfor
echo ""
throw "stop"
endfunction
function! s:test(...)
let type = get(a:000, 0, '')
let name = get(a:000, 1, '')
let index = get(a:000, 2, '')
let testgroups = eval(join(filter(split(substitute(join(readfile(s:sfile), "\n"), '.*\nfinish\n', '', ''), '\n', 1), "v:val !~ '^\"'")))
for testgroup in testgroups
if len(type) > 0 && testgroup.type != type | continue | endif
call s:show_type(testgroup.type)
for category in testgroup.categories
if len(name) > 0 && substitute(category.name,' ','_','g') != name | continue | endif
call s:show_category(category.name)
let tests = category.tests
let start = reltime()
for n in range(len(tests))
if len(index) > 0 && n != index | continue | endif
let query = tests[n].query
let result = tests[n].result
if has_key(tests[n], 'skip') && tests[n].skip != 0
call s:show_skip(n+1, query)
continue
endif
if stridx(query, '$$$$') != -1
silent! 1new
silent! exe "setlocal ft=".testgroup.type
silent! let key = matchstr(query, '.*\$\$\$\$\zs.*\ze\$\$\$\$')
if len(key) > 0
exe printf('let key = "%s"', key)
else
let key = "\<c-y>,"
endif
silent! let query = substitute(query, '\$\$\$\$.*\$\$\$\$', '$$$$', '')
silent! call setline(1, split(query, "\n"))
let cmd = "normal gg0/\\$\\$\\$\\$\ri\<del>\<del>\<del>\<del>".key
if stridx(result, '$$$$') != -1
let cmd .= '$$$$'
endif
silent! exe cmd
unlet! res | let res = join(getline(1, line('$')), "\n")
silent! bw!
call s:show_title(n+1, query)
else
call s:show_title(n+1, query)
unlet! res | let res = zencoding#ExpandWord(query, testgroup.type, 0)
endif
if stridx(result, '$$$$') != -1
if res ==# result
call s:show_ok()
else
call s:show_ng(n+1, result, res)
endif
else
if res ==# result
call s:show_ok()
else
call s:show_ng(n+1, result, res)
endif
endif
endfor
call s:show_pass(reltimestr(reltime(start)))
endfor
endfor
endfunction
function! s:do_tests(...)
try
if exists('g:user_zen_settings')
let s:old_user_zen_settings = g:user_zen_settings
let g:user_zen_settings = { 'indentation': "\t" }
endif
let oldmore = &more
call s:reload(fnamemodify(s:sfile, ':h'))
let &more = 0
call call('s:test', a:000)
call s:show_done()
catch
echohl ErrorMsg | echomsg v:exception | echohl None
finally
let &more=oldmore
if exists('g:user_zen_settings')
let g:user_zen_settings = s:old_user_zen_settings
endif
endtry
endfunction
function! g:zencoding_unittest_complete(arglead, cmdline, cmdpos)
let args = split(a:cmdline, '\s\+', 1)
let testgroups = eval(join(filter(split(substitute(join(readfile(s:sfile), "\n"), '.*\nfinish\n', '', ''), '\n', 1), "v:val !~ '^\"'")))
try
if len(args) == 2
return filter(map(testgroups, 'v:val.type'), 'stridx(v:val,args[1])!=-1')
elseif len(args) == 3
return map(filter(testgroups, 'v:val.type==args[1]')[0].categories, 'substitute(v:val.name," ","_","g")')
endif
catch
endtry
return []
endfunction
command! -nargs=* -complete=customlist,g:zencoding_unittest_complete ZenCodingUnitTest call s:do_tests(<f-args>)
if s:sfile == expand('%:p')
ZenCodingUnitTest
endif
finish
[
{
'type': "html",
'categories': [
{
'name': 'expand abbreviation',
'tests': [
{
'query': "div",
'result': "<div></div>\n",
},
{
'query': "div#wrapper",
'result': "<div id=\"wrapper\"></div>\n",
},
{
'query': "div.box",
'result': "<div class=\"box\"></div>\n",
},
{
'query': "a[title=TITLE]",
'result': "<a href=\"\" title=\"TITLE\"></a>\n",
},
{
'query': "div#wrapper.box",
'result': "<div id=\"wrapper\" class=\"box\"></div>\n",
},
{
'query': "div#wrapper.box.current",
'result': "<div id=\"wrapper\" class=\"box current\"></div>\n",
},
{
'query': "div#wrapper.box.current[title=TITLE rel]",
'result': "<div id=\"wrapper\" class=\"box current\" title=\"TITLE\" rel=\"\"></div>\n",
},
{
'query': "div#main+div#sub",
'result': "<div id=\"main\"></div>\n<div id=\"sub\"></div>\n",
},
{
'query': "div#main>div#sub",
'result': "<div id=\"main\">\n\t<div id=\"sub\"></div>\n</div>\n",
},
{
'query': "html:xt>div#header>div#logo+ul#nav>li.item-$*5>a",
'result': "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\">\n<head>\n\t<meta http-equiv=\"Content-Type\" content=\"text/html;charset=UTF-8\" />\n\t<title></title>\n</head>\n<body>\n\t<div id=\"header\">\n\t\t<div id=\"logo\"></div>\n\t\t<ul id=\"nav\">\n\t\t\t<li class=\"item-1\"><a href=\"\"></a></li>\n\t\t\t<li class=\"item-2\"><a href=\"\"></a></li>\n\t\t\t<li class=\"item-3\"><a href=\"\"></a></li>\n\t\t\t<li class=\"item-4\"><a href=\"\"></a></li>\n\t\t\t<li class=\"item-5\"><a href=\"\"></a></li>\n\t\t</ul>\n\t</div>\n\t\n</body>\n</html>",
},
{
'query': "ol>li*2",
'result': "<ol>\n\t<li></li>\n\t<li></li>\n</ol>\n",
},
{
'query': "a",
'result': "<a href=\"\"></a>\n",
},
{
'query': "obj",
'result': "<object data=\"\" type=\"\"></object>\n",
},
{
'query': "cc:ie6>p+blockquote#sample$.so.many.classes*2",
'result': "<!--[if lte IE 6]>\n\t<p></p>\n\t<blockquote id=\"sample1\" class=\"so many classes\"></blockquote>\n\t<blockquote id=\"sample2\" class=\"so many classes\"></blockquote>\n\t\n<![endif]-->",
},
{
'query': "html:4t>div#wrapper>div#header+div#contents+div#footer",
'result': "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<html lang=\"en\">\n<head>\n\t<meta http-equiv=\"Content-Type\" content=\"text/html;charset=UTF-8\">\n\t<title></title>\n</head>\n<body>\n\t<div id=\"wrapper\">\n\t\t<div id=\"header\"></div>\n\t\t<div id=\"contents\"></div>\n\t\t<div id=\"footer\"></div>\n\t</div>\n\t\n</body>\n</html>",
},
{
'query': "a[href=http://www.google.com/].foo#hoge",
'result': "<a id=\"hoge\" class=\"foo\" href=\"http://www.google.com/\"></a>\n",
},
{
'query': "a[href=http://www.google.com/]{Google}",
'result': "<a href=\"http://www.google.com/\">Google</a>\n",
},
{
'query': "{ZenCoding}",
'result': "ZenCoding",
},
{
'query': "a+b",
'result': "<a href=\"\"></a>\n<b></b>\n",
},
{
'query': "a>b>i<b",
'result': "<a href=\"\"><b><i></i></b><b></b></a>\n",
},
{
'query': "a>b>i^b",
'result': "<a href=\"\"><b><i></i></b><b></b></a>\n",
},
{
'query': "a>b>i<<b",
'result': "<a href=\"\"><b><i></i></b></a>\n<b></b>\n",
},
{
'query': "a>b>i^^b",
'result': "<a href=\"\"><b><i></i></b></a>\n<b></b>\n",
},
{
'query': "blockquote>b>i<<b",
'result': "<blockquote><b><i></i></b></blockquote>\n<b></b>\n",
},
{
'query': "blockquote>b>i^^b",
'result': "<blockquote><b><i></i></b></blockquote>\n<b></b>\n",
},
{
'query': "a[href=foo][class=bar]",
'result': "<a class=\"bar\" href=\"foo\"></a>\n",
},
{
'query': "a[a=b][b=c=d][e]{foo}*2",
'result': "<a href=\"\" a=\"b\" b=\"c=d\" e=\"\">foo</a>\n<a href=\"\" a=\"b\" b=\"c=d\" e=\"\">foo</a>\n",
},
{
'query': "a[a=b][b=c=d][e]*2{foo}",
'result': "<a href=\"\" a=\"b\" b=\"c=d\" e=\"\"></a>\n<a href=\"\" a=\"b\" b=\"c=d\" e=\"\"></a>\nfoo",
},
{
'query': "a*2{foo}a",
'result': "<a href=\"\"></a>\n<a href=\"\"></a>\nfoo<a href=\"\"></a>\n",
},
{
'query': "a{foo}*2>b",
'result': "<a href=\"\">foo<b></b></a>\n<a href=\"\">foo<b></b></a>\n",
},
{
'query': "a*2{foo}>b",
'result': "<a href=\"\"></a>\n<a href=\"\"></a>\nfoo",
},
{
'query': "table>tr>td.name#foo+td*3",
'result': "<table>\n\t<tr>\n\t\t<td id=\"foo\" class=\"name\"></td>\n\t\t<td></td>\n\t\t<td></td>\n\t\t<td></td>\n\t</tr>\n</table>\n",
},
{
'query': "div#header + div#footer",
'result': "<div id=\"header\"></div>\n<div id=\"footer\"></div>\n",
},
{
'query': "#header + div#footer",
'result': "<div id=\"header\"></div>\n<div id=\"footer\"></div>\n",
},
{
'query': "#header > ul > li < p{Footer}",
'result': "<div id=\"header\">\n\t<ul>\n\t\t<li></li>\n\t</ul>\n\t<p>Footer</p>\n</div>\n",
},
{
'query': "#header > ul > li ^ p{Footer}",
'result': "<div id=\"header\">\n\t<ul>\n\t\t<li></li>\n\t</ul>\n\t<p>Footer</p>\n</div>\n",
},
{
'query': "a#foo$$$*3",
'result': "<a id=\"foo001\" href=\"\"></a>\n<a id=\"foo002\" href=\"\"></a>\n<a id=\"foo003\" href=\"\"></a>\n",
},
{
'query': "ul+",
'result': "<ul>\n\t<li></li>\n</ul>\n",
},
{
'query': "table+",
'result': "<table>\n\t<tr>\n\t\t<td></td>\n\t</tr>\n</table>\n",
},
{
'query': "#header>li<#content",
'result': "<div id=\"header\">\n\t<li></li>\n</div>\n<div id=\"content\"></div>\n",
},
{
'query': "#header>li^#content",
'result': "<div id=\"header\">\n\t<li></li>\n</div>\n<div id=\"content\"></div>\n",
},
{
'query': "(#header>li)<#content",
'result': "<div id=\"header\">\n\t<li></li>\n</div>\n<div id=\"content\"></div>\n",
},
{
'query': "(#header>li)^#content",
'result': "<div id=\"header\">\n\t<li></li>\n</div>\n<div id=\"content\"></div>\n",
},
{
'query': "a>b>i<<div",
'result': "<a href=\"\"><b><i></i></b></a>\n<div></div>\n",
},
{
'query': "a>b>i^^div",
'result': "<a href=\"\"><b><i></i></b></a>\n<div></div>\n",
},
{
'query': "(#header>h1)+#content+#footer",
'result': "<div id=\"header\">\n\t<h1></h1>\n</div>\n<div id=\"content\"></div>\n<div id=\"footer\"></div>\n",
},
{
'query': "(#header>h1)+(#content>(#main>h2+div#entry$.section*5>(h3>a)+div>p*3+ul+)+(#utilities))+(#footer>address)",
'result': "<div id=\"header\">\n\t<h1></h1>\n</div>\n<div id=\"content\">\n\t<div id=\"main\">\n\t\t<h2></h2>\n\t\t<div id=\"entry1\" class=\"section\">\n\t\t\t<h3><a href=\"\"></a></h3>\n\t\t\t<div>\n\t\t\t\t<p></p>\n\t\t\t\t<p></p>\n\t\t\t\t<p></p>\n\t\t\t\t<ul>\n\t\t\t\t\t<li></li>\n\t\t\t\t</ul>\n\t\t\t</div>\n\t\t</div>\n\t\t<div id=\"entry2\" class=\"section\">\n\t\t\t<h3><a href=\"\"></a></h3>\n\t\t\t<div>\n\t\t\t\t<p></p>\n\t\t\t\t<p></p>\n\t\t\t\t<p></p>\n\t\t\t\t<ul>\n\t\t\t\t\t<li></li>\n\t\t\t\t</ul>\n\t\t\t</div>\n\t\t</div>\n\t\t<div id=\"entry3\" class=\"section\">\n\t\t\t<h3><a href=\"\"></a></h3>\n\t\t\t<div>\n\t\t\t\t<p></p>\n\t\t\t\t<p></p>\n\t\t\t\t<p></p>\n\t\t\t\t<ul>\n\t\t\t\t\t<li></li>\n\t\t\t\t</ul>\n\t\t\t</div>\n\t\t</div>\n\t\t<div id=\"entry4\" class=\"section\">\n\t\t\t<h3><a href=\"\"></a></h3>\n\t\t\t<div>\n\t\t\t\t<p></p>\n\t\t\t\t<p></p>\n\t\t\t\t<p></p>\n\t\t\t\t<ul>\n\t\t\t\t\t<li></li>\n\t\t\t\t</ul>\n\t\t\t</div>\n\t\t</div>\n\t\t<div id=\"entry5\" class=\"section\">\n\t\t\t<h3><a href=\"\"></a></h3>\n\t\t\t<div>\n\t\t\t\t<p></p>\n\t\t\t\t<p></p>\n\t\t\t\t<p></p>\n\t\t\t\t<ul>\n\t\t\t\t\t<li></li>\n\t\t\t\t</ul>\n\t\t\t</div>\n\t\t</div>\n\t</div>\n\t<div id=\"utilities\"></div>\n</div>\n<div id=\"footer\">\n\t<address></address>\n</div>\n",
},
{
'query': "(div>(ul*2)*2)+(#utilities)",
'result': "<div>\n\t<ul></ul>\n\t<ul></ul>\n\t<ul></ul>\n\t<ul></ul>\n</div>\n<div id=\"utilities\"></div>\n",
},
{
'query': "table>(tr>td*3)*4",
'result': "<table>\n\t<tr>\n\t\t<td></td>\n\t\t<td></td>\n\t\t<td></td>\n\t</tr>\n\t<tr>\n\t\t<td></td>\n\t\t<td></td>\n\t\t<td></td>\n\t</tr>\n\t<tr>\n\t\t<td></td>\n\t\t<td></td>\n\t\t<td></td>\n\t</tr>\n\t<tr>\n\t\t<td></td>\n\t\t<td></td>\n\t\t<td></td>\n\t</tr>\n</table>\n",
},
{
'query': "(((a#foo+a#bar)*2)*3)",
'result': "<a id=\"foo\" href=\"\"></a>\n<a id=\"bar\" href=\"\"></a>\n<a id=\"foo\" href=\"\"></a>\n<a id=\"bar\" href=\"\"></a>\n<a id=\"foo\" href=\"\"></a>\n<a id=\"bar\" href=\"\"></a>\n<a id=\"foo\" href=\"\"></a>\n<a id=\"bar\" href=\"\"></a>\n<a id=\"foo\" href=\"\"></a>\n<a id=\"bar\" href=\"\"></a>\n<a id=\"foo\" href=\"\"></a>\n<a id=\"bar\" href=\"\"></a>\n",
},
{
'query': "div#box$*3>h3+p*2",
'result': "<div id=\"box1\">\n\t<h3></h3>\n\t<p></p>\n\t<p></p>\n</div>\n<div id=\"box2\">\n\t<h3></h3>\n\t<p></p>\n\t<p></p>\n</div>\n<div id=\"box3\">\n\t<h3></h3>\n\t<p></p>\n\t<p></p>\n</div>\n"
},
{
'query': "div#box.foo$$$.bar$$$*3",
'result': "<div id=\"box\" class=\"foo001 bar001\"></div>\n<div id=\"box\" class=\"foo002 bar002\"></div>\n<div id=\"box\" class=\"foo003 bar003\"></div>\n",
},
{
'query': "div#box$*3>h3+p.bar*2|e",
'result': "&lt;div id=\"box1\"&gt;\n\t&lt;h3&gt;&lt;/h3&gt;\n\t&lt;p class=\"bar\"&gt;&lt;/p&gt;\n\t&lt;p class=\"bar\"&gt;&lt;/p&gt;\n&lt;/div&gt;\n&lt;div id=\"box2\"&gt;\n\t&lt;h3&gt;&lt;/h3&gt;\n\t&lt;p class=\"bar\"&gt;&lt;/p&gt;\n\t&lt;p class=\"bar\"&gt;&lt;/p&gt;\n&lt;/div&gt;\n&lt;div id=\"box3\"&gt;\n\t&lt;h3&gt;&lt;/h3&gt;\n\t&lt;p class=\"bar\"&gt;&lt;/p&gt;\n\t&lt;p class=\"bar\"&gt;&lt;/p&gt;\n&lt;/div&gt;\n",
},
{
'query': "div>div#page>p.title+p|c",
'result': "<div>\n\t<!-- #page -->\n\t<div id=\"page\">\n\t\t<!-- .title -->\n\t\t<p class=\"title\"></p>\n\t\t<!-- /.title -->\n\t\t<p></p>\n\t</div>\n\t<!-- /#page -->\n</div>\n",
},
{
'query': "link:css",
'result': "<link rel=\"stylesheet\" type=\"text/css\" href=\"style.css\" media=\"all\" />\n",
},
{
'query': "a[title=\"Hello', world\" rel]",
'result': "<a href=\"\" title=\"Hello', world\" rel=\"\"></a>\n",
},
{
'query': "div>a#foo{bar}",
'result': "<div><a id=\"foo\" href=\"\">bar</a></div>\n",
},
{
'query': ".content{Hello!}",
'result': "<div class=\"content\">Hello!</div>\n",
},
{
'query': "div.logo+(div#navigation)+(div#links)",
'result': "<div class=\"logo\"></div>\n<div id=\"navigation\"></div>\n<div id=\"links\"></div>\n",
},
{
'query': "h1{header}+{Text}+a[href=http://link.org]{linktext}+{again some text}+a[href=http://anoterlink.org]{click me!}+{some final text}",
'result': "<h1>header</h1>\nText<a href=\"http://link.org\">linktext</a>\nagain some text<a href=\"http://anoterlink.org\">click me!</a>\nsome final text",
},
{
'query': "a{&}+div{&&}",
'result': "<a href=\"\">&</a>\n<div>&&</div>\n",
},
{
'query': "<foo/>span$$$$\\<c-y>,$$$$",
'result': "<foo/><span></span>",
},
{
'query': "foo span$$$$\\<c-y>,$$$$",
'result': "foo <span></span>",
},
{
'query': "foo span$$$$\\<c-y>,$$$$ bar",
'result': "foo <span></span> bar",
},
{
'query': "foo $$$$\\<c-o>ve\\<c-y>,p\\<cr>$$$$bar baz",
'result': "foo <p>bar</p> baz",
},
{
'query': "foo $$$$\\<c-o>vee\\<c-y>,p\\<cr>$$$$bar baz",
'result': "foo <p>bar baz</p>",
},
{
'query': "f div.boxes>article.box2>header>(hgroup>h2{aaa}+h3{bbb})+p{ccc}$$$$",
'result': "f <div class=\"boxes\">\n\t<article class=\"box2\">\n\t\t<header>\n\t\t\t<hgroup>\n\t\t\t\t<h2>aaa</h2>\n\t\t\t\t<h3>bbb</h3>\n\t\t\t</hgroup>\n\t\t\t<p>ccc</p>\n\t\t</header>\n\t</article>\n</div>",
},
{
'query': "div.boxes>(div.box2>section>h2{a}+p{b})+(div.box1>section>h2{c}+p{d}+p{e}+(bq>h2{f}+h3{g})+p{h})",
'result': "<div class=\"boxes\">\n\t<div class=\"box2\">\n\t\t<section>\n\t\t\t<h2>a</h2>\n\t\t\t<p>b</p>\n\t\t</section>\n\t</div>\n\t<div class=\"box1\">\n\t\t<section>\n\t\t\t<h2>c</h2>\n\t\t\t<p>d</p>\n\t\t\t<p>e</p>\n\t\t\t<blockquote>\n\t\t\t\t<h2>f</h2>\n\t\t\t\t<h3>g</h3>\n\t\t\t</blockquote>\n\t\t\t<p>h</p>\n\t\t</section>\n\t</div>\n</div>\n",
},
{
'query': "(div>(label+input))+div",
'result': "<div>\n\t<label for=\"\"></label>\n\t<input type=\"\" />\n</div>\n<div></div>\n",
},
{
'query': "test1\ntest2\ntest3$$$$\\<esc>ggVG\\<c-y>,ul>li>span*>a\\<cr>$$$$",
'result': "<ul>\n\t<li>\n\t\t<span><a href=\"\">test1</a></span>\n\t\t<span><a href=\"\">test2</a></span>\n\t\t<span><a href=\"\">test3</a></span>\n\t</li>\n</ul>",
},
{
'query': "test1\ntest2\ntest3$$$$\\<esc>ggVG\\<c-y>,input[type=input value=$#]*\\<cr>$$$$",
'result': "<input type=\"input\" value=\"test1\" />\n<input type=\"input\" value=\"test2\" />\n<input type=\"input\" value=\"test3\" />",
},
{
'query': "div#id-$*5>div#id2-$",
'result': "<div id=\"id-1\">\n\t<div id=\"id2-1\"></div>\n</div>\n<div id=\"id-2\">\n\t<div id=\"id2-2\"></div>\n</div>\n<div id=\"id-3\">\n\t<div id=\"id2-3\"></div>\n</div>\n<div id=\"id-4\">\n\t<div id=\"id2-4\"></div>\n</div>\n<div id=\"id-5\">\n\t<div id=\"id2-5\"></div>\n</div>\n",
},
{
'query': "{test case $ }*3",
'result': "test case 1 test case 2 test case 3 ",
},
{
'query': "{test case $${nr}}*3",
'result': "test case 1\ntest case 2\ntest case 3\n",
},
{
'query': "{test case \\$ }*3",
'result': "test case $ test case $ test case $ ",
},
{
'query': "{test case $$$ }*3",
'result': "test case 001 test case 002 test case 003 ",
},
{
'query': "a[title=$#]{foo}",
'result': "<a href=\"\" title=\"foo\">foo</a>\n",
},
],
},
{
'name': 'split join tag',
'tests': [
{
'query': "<div>\n\t<span>$$$$\\<c-y>j$$$$</span>\n</div>",
'result': "<div>\n\t<span/>\n</div>",
},
{
'query': "<div>\n\t<span$$$$\\<c-y>j$$$$/>\n</div>",
'result': "<div>\n\t<span></span>\n</div>",
},
],
},
{
'name': 'toggle comment',
'tests': [
{
'query': "<div>\n\t<span>$$$$\\<c-y>/$$$$</span>\n</div>",
'result': "<div>\n\t<!-- <span></span> -->\n</div>",
},
{
'query': "<div>\n\t<!-- <span>$$$$\\<c-y>/$$$$</span> -->\n</div>",
'result': "<div>\n\t<span></span>\n</div>",
},
],
},
{
'name': 'image size',
'tests': [
{
'query': "img[src=http://mattn.kaoriya.net/images/logo.png]$$$$\\<c-y>,\\<c-y>i$$$$",
'result': "<img src=\"http://mattn.kaoriya.net/images/logo.png\" alt=\"\" width=\"96\" height=\"96\" />",
},
{
'query': "img[src=/logo.png]$$$$\\<c-y>,\\<c-y>i$$$$",
'result': "<img src=\"/logo.png\" alt=\"\" />",
},
],
},
{
'name': 'move next prev',
'tests': [
{
'query': "foo+bar+baz[dankogai=\"\"]$$$$\\<c-y>,\\<esc>gg0\\<c-y>n\\<c-y>n\\<c-y>n\\<esc>Byw:%d _\\<cr>p$$$$",
'result': "dankogai",
},
],
},
],
},
{
'type': 'css',
'categories': [
{
'name': 'expand abbreviation',
'tests': [
{
'query': "@i",
'result': "@import url();",
},
{
'query': "fs:n",
'result': "font-style: normal;",
},
{
'query': "fl:l|fc",
'result': "float: left;",
},
{
'query': "bg+$$$$",
'result': "background: #FFF url($$$$) 0 0 no-repeat;",
},
{
'query': "bg+!$$$$",
'result': "background: #FFF url($$$$) 0 0 no-repeat !important;",
},
{
'query': "m$$$$",
'result': "margin: $$$$;",
},
{
'query': "m0.1p$$$$",
'result': "margin: 0.1%;",
},
{
'query': "m1.0$$$$",
'result': "margin: 1.0em;",
},
{
'query': "m2$$$$",
'result': "margin: 2px;",
},
{
'query': "bdrs10$$$$",
'result': "border-radius: 10px;",
},
{
'query': "-bdrs20$$$$",
'result': "-webkit-border-radius: 20px;\n-moz-border-radius: 20px;\nborder-radius: 20px;",
},
{
'query': "lg(top,#fff,#000)$$$$",
'result': "background-image: -webkit-gradient(top, 0 0, 0 100, from(#fff), to(#000));\nbackground-image: -webkit-linear-gradient(#fff, #000);\nbackground-image: -moz-linear-gradient(#fff, #000);\nbackground-image: -o-linear-gradient(#fff, #000);\nbackground-image: linear-gradient(#fff, #000);\n",
},
{
'query': "m10-5-0$$$$",
'result': "margin: 10px 5px 0px;",
},
{
'query': "m-10--5$$$$",
'result': "margin: -10px -5px;",
},
{
'query': "m10-auto$$$$",
'result': "margin: 10px auto;",
},
{
'query': "w100p$$$$",
'result': "width: 100%;",
},
{
'query': "h50e$$$$",
'result': "height: 50em;",
},
{
'query': "(bg+)+c$$$$",
'result': "background: #FFF url($$$$) 0 0 no-repeat;\ncolor: #000;",
},
],
},
],
},
{
'type': 'haml',
'categories': [
{
'name': 'expand abbreviation',
'tests': [
{
'query': "div>p+ul#foo>li.bar$[foo=bar][bar=baz]*3>{baz}",
'result': "%div\n %p\n %ul#foo\n %li.bar1{ :foo => \"bar\", :bar => \"baz\" } baz\n %li.bar2{ :foo => \"bar\", :bar => \"baz\" } baz\n %li.bar3{ :foo => \"bar\", :bar => \"baz\" } baz\n",
},
{
'query': "div>p+ul#foo>li.bar$[foo=bar][bar=baz]*3>{baz}|haml",
'result': "%div\n %p\n %ul#foo\n %li.bar1{ :foo => \"bar\", :bar => \"baz\" } baz\n %li.bar2{ :foo => \"bar\", :bar => \"baz\" } baz\n %li.bar3{ :foo => \"bar\", :bar => \"baz\" } baz\n",
},
{
'query': "a*3|haml",
'result': "%a{ :href => \"\" }\n%a{ :href => \"\" }\n%a{ :href => \"\" }\n",
},
{
'query': ".content{Hello!}|haml",
'result': "%div.content Hello!\n",
},
{
'query': "a[title=$#]{foo}",
'result': "%a{ :href => \"\", :title => \"foo\" } foo\n",
},
],
},
{
'name': 'expand abbreviation',
'tests': [
{
'query': "%a foo\n bar$$$$\\<c-y>j$$$$",
'result': "%a ",
},
{
'query': "$$$$\\<c-y>j$$$$%a ",
'result': "%a $$$$",
},
],
},
{
'name': 'toggle comment',
'tests': [
{
'query': "%a{ :href => \"http://www.google.com\"$$$$\\<c-y>/$$$$ } hello",
'result': "-# %a{ :href => \"http://www.google.com\" } hello",
},
{
'query': "-# %a{ :href => \"http://www.google.com\"$$$$\\<c-y>/$$$$ } hello",
'result': "%a{ :href => \"http://www.google.com\" } hello",
},
],
},
],
},
{
'type': 'slim',
'categories': [
{
'name': 'expand abbreviation',
'tests': [
{
'query': "div>p+ul#foo>li.bar$[foo=bar][bar=baz]*3>{baz}",
'result': "div\n p\n ul id=\"foo\"\n li class=\"bar1\" foo=\"bar\" bar=\"baz\"\n | baz\n li class=\"bar2\" foo=\"bar\" bar=\"baz\"\n | baz\n li class=\"bar3\" foo=\"bar\" bar=\"baz\"\n | baz\n",
},
{
'query': "div>p+ul#foo>li.bar$[foo=bar][bar=baz]*3>{baz}|slim",
'result': "div\n p\n ul id=\"foo\"\n li class=\"bar1\" foo=\"bar\" bar=\"baz\"\n | baz\n li class=\"bar2\" foo=\"bar\" bar=\"baz\"\n | baz\n li class=\"bar3\" foo=\"bar\" bar=\"baz\"\n | baz\n",
},
{
'query': "a*3|slim",
'result': "a href=\"\"\na href=\"\"\na href=\"\"\n",
},
{
'query': ".content{Hello!}|slim",
'result': "div class=\"content\"\n | Hello!\n",
},
{
'query': "a[title=$#]{foo}",
'result': "a href=\"\" title=\"foo\"\n | foo\n",
},
],
},
{
'name': 'split join tag',
'tests': [
{
'query': "a\n | foo$$$$\\<c-y>j$$$$",
'result': "a",
},
{
'query': "a$$$$\\<c-y>j$$$$",
'result': "a\n | $$$$",
},
],
},
{
'name': 'toggle comment',
'tests': [
{
'query': "a href=\"http://www.google.com\"$$$$\\<c-y>/$$$$\n | hello",
'result': "/a href=\"http://www.google.com\"\n | hello",
},
{
'query': "/a href=\"http://www.google.com\"$$$$\\<c-y>/$$$$\n | hello",
'result': "a href=\"http://www.google.com\"\n | hello",
},
],
},
],
},
{
'type': 'xsl',
'categories': [
{
'name': 'expand abbreviation',
'tests': [
{
'query': "vari",
'result': "<xsl:variable name=\"\"></xsl:variable>\n",
},
{
'query': "ap>wp",
'result': "<xsl:apply-templates select=\"\" mode=\"\">\n\t<xsl:with-param name=\"\" select=\"\"></xsl:with-param>\n</xsl:apply-templates>\n",
},
],
},
],
},
{
'type': 'xsd',
'categories': [
{
'name': 'expand abbreviation',
'tests': [
{
'query': "xsd:w3c",
'result': "<?xml version=\"1.0\"?>\n<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">\n\t<xsd:element name=\"\" type=\"\"/>\n</xsd:schema>",
},
],
},
],
},
{
'type': 'mustache',
'categories': [
{
'name': 'expand abbreviation',
'tests': [
{
'query': "div#{{foo}}",
'result': "<div id=\"{{foo}}\"></div>\n",
},
{
'query': "div.{{foo}}",
'result': "<div class=\"{{foo}}\"></div>\n",
},
],
},
],
},
]
" vim:set et:

View file

@ -1,265 +0,0 @@
script_name: ZenCoding.vim
script_id: '2981'
script_type: utility
script_package: zencoding-vim.zip
script_version: '0.80'
required_vim_version: '7.0'
summary: vim plugins for HTML and CSS hi-speed coding.
detailed_description: |
This is vim script support expanding abbreviation like zen-coding.
ref: http://code.google.com/p/zen-coding/
There is a movie using zencoding.vim
ref: http://mattn.github.com/zencoding-vim
Source Repository.
ref: http://github.com/mattn/zencoding-vim
Type abbreviation
+-------------------------------------
| html:5_
+-------------------------------------
"_" is a cursor position. and type "<c-y>," (Ctrl + y and Comma)
NOTE: Don't worry about key map. you can change it easily.
+-------------------------------------
| <!DOCTYPE HTML>
| <html lang="en">
| <head>
| <title></title>
| <meta charset="UTF-8">
| </head>
| <body>
| _
| </body>
| </html>
+-------------------------------------
Type following
+-------------------------------------
| div#foo$*2>div.bar
+-------------------------------------
And type "<c-y>,"
+-------------------------------------
|<div id="foo1">
| <div class="bar">_</div>
|</div>
|<div id="foo2">
| <div class="bar"></div>
|</div>
| _
+-------------------------------------
Tutorial:
http://github.com/mattn/zencoding-vim/raw/master/TUTORIAL
How work this:
http://mattn.github.com/zencoding-vim
Tips:
You can customize behavior of expanding with overriding config.
This configuration will be marged at loading plugin.
let g:user_zen_settings = {
\ 'indentation' : ' ',
\ 'perl' : {
\ 'aliases' : {
\ 'req' : 'require '
\ },
\ 'snippets' : {
\ 'use' : "use strict\nuse warnings\n\n",
\ 'warn' : "warn \"|\";",
\ }
\ }
\}
let g:user_zen_expandabbr_key = '<c-e>'
let g:use_zen_complete_tag = 1
You can set language attribute in html using zen_settings['lang'].
install_details: |
# cd ~/.vim
# unzip zencoding-vim.zip
or if you install pathogen.vim:
# cd ~/.vim/bundle # or make directory
# unzip /path/to/zencoding-vim.zip
if you get sources from repository:
# cd ~/.vim/bundle # or make directory
# git clone http://github.com/mattn/zencoding-vim.git
versions:
- '0.80': |
This is an upgrade for ZenCoding.vim: add emmet features.
- '0.74': |
This is an upgrade for ZenCoding.vim: many bug fixes.
- '0.73': |
This is an upgrade for ZenCoding.vim: many bug fixes. and support slim format (experimental).
- '0.72': |
This is an upgrade for ZenCoding.vim:
[fix] fix finding tokens.
- '0.71': |
This is an upgrade for ZenCoding.vim:
[fix] fix finding begin of tokens.
- '0.70': |
This is an upgrade for ZenCoding.vim:
[mod] Changed behavior of expanding. "div div>a|" should keep first div element.
[add] Supported slim formatter.
- '0.60': |
This is an upgrade for ZenCoding.vim:
[fix] fixed expanding {{}}.
- '0.59': |
This is an upgrade for ZenCoding.vim:
[fix] fixed toggleComment and mny bugs.
- '0.58': |
This is an upgrade for ZenCoding.vim:
[fix] fixed 'foo+' style expandos.
- '0.57': |
This is an upgrade for ZenCoding.vim:
[fix] fixed expandos that don't work 'choose' in xsl.
- '0.56': |
This is an upgrade for ZenCoding.vim:
[fix] fixed contents parser.
- '0.55': |
uploaded again: sorry, files was old.
- '0.54': |
[add] support sass, xsd.
[fix] expanding with html tag.
uploaded again: sorry, fileformat was DOS.
- '0.53': |
[fix] gif width/height was swapped.
- '0.52': |
[fix] broken wrap expanding.
- '0.51': |
This is an upgrade for ZenCoding.vim:
[fix] wrap expanding with '&'.
[fix] expand .content to class="content".
[fix] haml expanding.
[fix] bg+ snippet
- '0.50': |
This is an upgrade for ZenCoding.vim:
[fix] fixed parsing '#{{foo}}' and '.{{bar}}'.
- '0.49': |
This is an upgrade for ZenCoding.vim:
[doc] add help manual.
- '0.48': |
This is an upgrade for ZenCoding.vim:
[fix] install mappings to global.
- '0.47': |
This is an upgrade for ZenCoding.vim:
[drastic changes] enable autoload. you should whole replace older files.
package was empty. upload again.
- '0.46': |
This is an upgrade for ZenCoding.vim:
[drastic changes] enable autoload. you should whole replace older files.
- '0.45': |
This is an upgrade for ZenCoding.vim:
fixed attribute parsing like: a[href="hello', world" rel].
- '0.44': |
This is an upgrade for ZenCoding.vim:
fixed checking whether have mapping using maparg() / hasmapto().
- '0.43': |
This is an upgrade for ZenCoding.vim:
fixed behavior for nested block. like "html:5>#page>(header#globalHeader>(hgroup>h1+h2)+(nav>ul>li*3>a)+(form>p.siteSearch>input+input[type=button]))+(#contents>(#main>(section>h2+p*5)+p.pagetop>a[href=#page])+(#sub>p+(nav>ul>li>a)))+(footer#globalFoooter>(ul>li>a)+(p.copyright>small))"
- '0.42': |
This is an upgrade for ZenCoding.vim:
fixed select/option indent.
- '0.41': |
This is an upgrade for ZenCoding.vim:
fixed default filter. when using 'e' filter, output become empty.
- '0.40': |
This is an upgrade for ZenCoding.vim:
add the pure vimscript code for 'get image size'. you can use it without perl interface just now.
change key assign of ZenCodingExpandWord from ',' to ';'. it don't effect to most users.
- '0.39': |
This is an upgrade for ZenCoding.vim: fixed problem about 'selection'. see http://github.com/mattn/zencoding-vim/issues/#issue/2
- '0.38': |
This is an upgrade for ZenCoding.vim: use v7h"_s instead of v7hs for backspace.
- '0.37': |
This is an upgrade for ZenCoding.vim: fixed problem that won't working with some 'backspace' options.
- '0.36': |
This is an upgrade for ZenCoding.vim: fixed problem that filter does not work.
- '0.35': |
This is an upgrade for ZenCoding.vim: enable zencoding for other languages. (meaning php also)
- '0.34': |
This is an upgrade for ZenCoding.vim: enable zencoding for xsl. (you should add ~/.vim/ftplugin/xslt/zencoding.vim)
- '0.33': |
This is an upgrade for ZenCoding.vim: fixed problem breaking multibyte when cursor is in a part of line. enabled zencoding for javascript in html.
- '0.32': |
This is an upgrade for ZenCoding.vim: fixed indentation. supported extends so that you can enable zencoding for php/xhtml/haml other's section 14 in http://github.com/mattn/zencoding-vim/raw/master/TUTORIAL
- '0.31': |
This is an upgrade for ZenCoding.vim: fixed indentation and $$$ problem. fixed about missing support multiple classes.
- '0.30': |
This is an upgrade for ZenCoding.vim: Fixed key assign.
- '0.29': |
This is an upgrade for ZenCoding.vim: Changed leading key to '<c-y>' from '<c-z>'.
- '0.28': |
This is an upgrade for ZenCoding.vim: supported 'Balance Tag Inward/Outward', 'Go to Next/Previous Edit Point', 'Update <img> Size', 'Remove Tag', 'Split/Join Tag', 'Toggle Comment'
- '0.27': |
This is an upgrade for ZenCoding.vim: fixed problem that can't work on the part of multibyte characters. fixed inline elements behavior.
- '0.26': |
This is an upgrade for ZenCoding.vim: The count of '(((a#foo + a#bar)*2)*3)' should be 12.
- '0.25': |
This is an upgrade for ZenCoding.vim: store undo before working. good luck about 'table>(tr>td*3)*4'.
- '0.24': |
This is an upgrade for ZenCoding.vim: fixed behavior of parsing area of visual selection.
- '0.23': |
This is an upgrade for ZenCoding.vim: pre-expand '#header>li<#content' to 'div#header>li<div#content'. support () expression.
- '0.22': |
This is an upgrade for ZenCoding.vim: expand 'ul+' to 'ul>li'. fix undo ring. support visual selection. when type trigger key on visual select, it request you leader like 'ul>li'. if you give 'ul>li*' as leader, you'll get each separate 'ul>li' tags. and when you give 'blockquote' as leader, you'll get blocked text.
- '0.21': |
This is an upgrade for ZenCoding.vim: treat xhtml as html.
- '0.20': |
This is an upgrade for ZenCoding.vim: add option use_zen_complete_tag for complete abbr.
- '0.19': |
This is an upgrade for ZenCoding.vim: fixed problem that couldn't expand 'link:css' correctly.
- '0.18': |
This is an upgrade for ZenCoding.vim: ignore duplicate key map.
- '0.17': |
This is an upgrade for ZenCoding.vim: fixed key map.
- '0.16': |
This is an upgrade for ZenCoding.vim: fixed problem 'endless loop'.
- '0.15': |
This is an upgrade for ZenCoding.vim: set default filetype to 'html'.
- '0.14': |
This is an upgrade for ZenCoding.vim: fixed tag name like 'fs:n' in 'css'.
- '0.14': |
This is an upgrade for ZenCoding.vim: indentation for each languages.
- '0.13': |
This is an upgrade for ZenCoding.vim: user key map.
- '0.12': |
This is an upgrade for ZenCoding.vim: few extensive notation.
- '0.11': |
This is an upgrade for ZenCoding.vim: fixed indent.
- '0.10': |
This is an upgrade for ZenCoding.vim: fixed behavior of '+' operator
- '0.9': |
This is an upgrade for ZenCoding.vim: fixed single line behavior
- '0.8': |
This is an upgrade for ZenCoding.vim: support 'a[href=http://www.google.com]{Google}'
- '0.7': |
This is an upgrade for ZenCoding.vim: fixed behavior in 'a+b'.
- '0.6': |
This is an upgrade for ZenCoding.vim: fixed strange behavior about '<a href="">b_</a>'.
- '0.5': |
This is an upgrade for ZenCoding.vim: recover rest part in line.
- '0.4': |
This is an upgrade for ZenCoding.vim: fixed cursor position. fixed ${lang} replacement.
- '0.3': |
This is an upgrade for ZenCoding.vim: fixed line expanding.
- '0.2': |
This is an upgrade for ZenCoding.vim: fixed problem that moving cursor with expanding.
- '0.1': |
Initial upload
# __END__
# vim: filetype=yaml

View file

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

View file

@ -34,7 +34,7 @@ endfunction
function! s:set_color(group, attr, color)
let gui = a:color =~ '^#'
execute printf("hi %s %s%s=%s", a:group, gui ? 'gui' : 'cterm', a:attr, a:color)
execute printf('hi %s %s%s=%s', a:group, gui ? 'gui' : 'cterm', a:attr, a:color)
endfunction
function! s:blank(repel)
@ -161,6 +161,8 @@ function! s:maps_resize()
return mapped
endfunction
nnoremap <silent> <plug>(goyo-resize) :<c-u>call <sid>resize_pads()<cr>
function! s:goyo_on(dim)
let dim = s:parse_arg(a:dim)
if empty(dim)
@ -207,13 +209,13 @@ function! s:goyo_on(dim)
endif
" vim-airline
let t:goyo_disabled_airline = exists("#airline")
let t:goyo_disabled_airline = exists('#airline')
if t:goyo_disabled_airline
AirlineToggle
endif
" vim-powerline
let t:goyo_disabled_powerline = exists("#PowerlineMain")
let t:goyo_disabled_powerline = exists('#PowerlineMain')
if t:goyo_disabled_powerline
augroup PowerlineMain
autocmd!
@ -222,7 +224,7 @@ function! s:goyo_on(dim)
endif
" lightline.vim
let t:goyo_disabled_lightline = exists('#LightLine')
let t:goyo_disabled_lightline = exists('#lightline')
if t:goyo_disabled_lightline
silent! call lightline#disable()
endif
@ -263,6 +265,9 @@ function! s:goyo_on(dim)
autocmd ColorScheme * call s:tranquilize()
autocmd BufWinEnter * call s:hide_linenr() | call s:hide_statusline()
autocmd WinEnter,WinLeave * call s:hide_statusline()
if has('nvim')
autocmd TermClose * call feedkeys("\<plug>(goyo-resize)")
endif
augroup END
call s:hide_statusline()
@ -330,7 +335,7 @@ function! s:goyo_off()
let &winheight = wh
for [k, v] in items(goyo_revert)
execute printf("let &%s = %s", k, string(v))
execute printf('let &%s = %s', k, string(v))
endfor
execute 'colo '. get(g:, 'colors_name', 'default')
@ -344,7 +349,7 @@ function! s:goyo_off()
endif
endif
if goyo_disabled_airline && !exists("#airline")
if goyo_disabled_airline && !exists('#airline')
AirlineToggle
" For some reason, Airline requires two refreshes to avoid display
" artifacts
@ -352,7 +357,7 @@ function! s:goyo_off()
silent! AirlineRefresh
endif
if goyo_disabled_powerline && !exists("#PowerlineMain")
if goyo_disabled_powerline && !exists('#PowerlineMain')
doautocmd PowerlineStartup VimEnter
silent! PowerlineReloadColorscheme
endif

View file

@ -38,10 +38,10 @@ too:
## 2. Submitting a patch
Before you consider adding features to syntastic, _please_ spend a few
minutes (re-)reading the latest version of the [manual][1]. Syntastic
is changing rapidly at times, and it's quite possible that some features
you want to add exist already.
Before you consider adding features to syntastic, _please_ spend a few minutes
(re-)reading the latest version of the [manual][1]. Syntastic is changing
rapidly at times, and it's possible that some features you want to add exist
already.
To submit a patch:

View file

@ -105,6 +105,12 @@ Syntastic should work with any modern plugin managers for Vim, such as
[Vundle][17]. Instructions for installing syntastic with [Pathogen][1] are
included below for completeness.
Starting with Vim version 7.4.1486 you can also load syntastic using the
standard mechanism of packages, without the help of third-party plugin managers
(see `:help packages` in Vim for details). Beware however that, while support
for packages has been added in Vim 7.4.1384, the functionality needed by
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
itself. In order to get meaningful results you need to install external
checkers corresponding to the types of files you use. Please consult the
@ -184,7 +190,7 @@ let g:syntastic_check_on_wq = 0
__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
is installed. For example: by default, python requires either `flake8` or
are installed. For example: by default, python requires either `flake8` or
`pylint` to be installed and in your `$PATH`. To see which executables are
supported, look at the [wiki][3]. Note that aliases do not work; the actual
executables must be available in your `$PATH`. Symbolic links are okay though.
@ -254,11 +260,11 @@ __4.4. Q. The `perl` checker has stopped working...__
A. The `perl` checker runs `perl -c` against your file, which in turn
__executes__ any `BEGIN`, `UNITCHECK`, and `CHECK` blocks, and any `use`
statements in your file (cf. [perlrun][10]). This is probably fine if you
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 while
still producing useful results, the checker is now disabled by default. To
(re-)enable it, make sure the `g:syntastic_perl_checkers` list includes `perl`,
and set `g:syntastic_enable_perl_checker` to 1 in your `vimrc`:
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
while still producing useful results, the checker is now disabled by default.
To (re-)enable it, make sure the `g:syntastic_perl_checkers` list includes
`perl`, and set `g:syntastic_enable_perl_checker` to 1 in your `vimrc`:
```vim
let g:syntastic_enable_perl_checker = 1
```

View file

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

View file

@ -240,7 +240,12 @@ function! syntastic#util#findGlobInParent(what, where) abort " {{{2
let old = ''
while here !=# ''
let p = split(globpath(here, a:what, 1), '\n')
try
" Vim 7.4.279 and later
let p = globpath(here, a:what, 1, 1)
catch /\m^Vim\%((\a\+)\)\=:E118/
let p = split(globpath(here, a:what, 1), "\n")
endtry
if !empty(p)
return fnamemodify(p[0], ':p')
@ -329,6 +334,12 @@ function! syntastic#util#stamp() abort " {{{2
return split( split(reltimestr(reltime(g:_SYNTASTIC_START)))[0], '\.' )
endfunction " }}}2
function! syntastic#util#setChangedtick() abort " {{{2
unlockvar! b:syntastic_changedtick
let b:syntastic_changedtick = b:changedtick
lockvar! b:syntastic_changedtick
endfunction " }}}2
let s:_wid_base = 'syntastic_' . getpid() . '_' . reltimestr(g:_SYNTASTIC_START) . '_'
let s:_wid_pool = 0
@ -499,7 +510,13 @@ function! s:_rmrf(what) abort " {{{2
return
endif
for f in split(globpath(a:what, '*', 1), "\n")
try
" Vim 7.4.279 and later
let entries = globpath(a:what, '*', 1, 1)
catch /\m^Vim\%((\a\+)\)\=:E118/
let entries = split(globpath(a:what, '*', 1), "\n")
endtry
for f in entries
call s:_rmrf(f)
endfor
silent! call syntastic#util#system(s:rmdir . ' ' . syntastic#util#shescape(a:what))

View file

@ -36,7 +36,9 @@ CONTENTS *syntastic-contents*
5.2.Choosing the executable................|syntastic-config-exec|
5.3.Configuring specific checkers..........|syntastic-config-makeprg|
5.4.Sorting errors.........................|syntastic-config-sort|
5.5.Debugging..............................|syntastic-config-debug|
5.5.Filtering errors.......................|syntastic-config-filtering|
5.6.Debugging..............................|syntastic-config-debug|
5.7.Profiling..............................|syntastic-profiling|
6.Notes........................................|syntastic-notes|
6.1.Handling of composite filetypes........|syntastic-composite|
6.2.Editing files over network.............|syntastic-netrw|
@ -64,8 +66,8 @@ CONTENTS *syntastic-contents*
1. Intro *syntastic-intro*
Syntastic is a syntax checking plugin that runs files through external syntax
checkers. This can be done on demand, or automatically as files are saved and
opened. If syntax errors are detected, the user is notified and is happy
checkers. This can be done on demand, or automatically as files are saved
and opened. If syntax errors 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.
@ -91,21 +93,21 @@ Syntastic comes preconfigured with a default list of enabled checkers per
trying to use conflicting checkers.
You can see the list of checkers available for the current filetype with the
|:SyntasticInfo| command.
`:SyntasticInfo` command.
You probably want to override the configured list of checkers for the
filetypes you use, and also change the arguments passed to specific checkers
to suit your needs. See |syntastic-checker-options| below for details.
Use |:SyntasticCheck| to manually check right now. Use |:Errors| to open the
|location-list| window, and |:lclose| to close it. You can clear the error
list with |:SyntasticReset|, and you can use |:SyntasticToggleMode| to switch
Use `:SyntasticCheck` to manually check right now. Use `:Errors` to open the
|location-list| window, and `:lclose` to close it. You can clear the error
list with `:SyntasticReset`, and you can use `:SyntasticToggleMode` to switch
between active (checking on writing the buffer) and passive (manual) checking.
You don't have to switch focus to the |location-list| window to jump to the
different errors. Vim provides several built-in commands for this, for
example |:lnext| and |:lprevious|. You may want to add shortcut mappings for
these commands, or perhaps install a plugin such as Tim Pope's 'unimpaired'
example `:lnext` and `:lprevious`. You may want to add shortcut mappings for
these commands, or perhaps install a plugin such as Tim Pope's "unimpaired"
(see https://github.com/tpope/vim-unimpaired) that provides such mappings.
------------------------------------------------------------------------------
@ -128,7 +130,7 @@ needed: >
2. Functionality provided *syntastic-functionality*
Syntax checking can be done automatically or on demand (see
|'syntastic_mode_map'| and |:SyntasticToggleMode| for configuring this).
|'syntastic_mode_map'| and `:SyntasticToggleMode` for configuring this).
When syntax checking is done, the features below can be used to notify the
user of errors. See |syntastic-global-options| for how to configure and
@ -167,19 +169,19 @@ possible solutions. See also |syntastic-powerline| below if you're using the
------------------------------------------------------------------------------
2.2. Error signs *syntastic-error-signs*
Syntastic uses the |:sign| commands (provided that the |+signs| feature is
Syntastic uses the `:sign` commands (provided that the |+signs| feature is
compiled in) to mark lines with errors and warnings in the sign column. To
enable this feature, use the |'syntastic_enable_signs'| option.
Signs are colored using the Error and Todo syntax highlight groups by default
(see |group-name|). If you wish to customize the colors for the signs, you
can use the following groups:
SyntasticErrorSign - For syntax errors, links to 'error' by default
SyntasticWarningSign - For syntax warnings, links to 'todo' by default
SyntasticStyleErrorSign - For style errors, links to 'SyntasticErrorSign'
SyntasticErrorSign - For syntax errors, links to "error" by default
SyntasticWarningSign - For syntax warnings, links to "todo" by default
SyntasticStyleErrorSign - For style errors, links to "SyntasticErrorSign"
by default
SyntasticStyleWarningSign - For style warnings, links to
'SyntasticWarningSign' by default
"SyntasticWarningSign" by default
Example: >
highlight SyntasticErrorSign guifg=white guibg=red
@ -188,8 +190,8 @@ To set up highlighting for the line where a sign resides, you can use the
following highlight groups:
SyntasticErrorLine
SyntasticWarningLine
SyntasticStyleErrorLine - Links to 'SyntasticErrorLine' by default
SyntasticStyleWarningLine - Links to 'SyntasticWarningLine' by default
SyntasticStyleErrorLine - Links to "SyntasticErrorLine" by default
SyntasticStyleWarningLine - Links to "SyntasticWarningLine" by default
Example: >
highlight SyntasticErrorLine guibg=#2f0000
@ -197,15 +199,15 @@ Example: >
------------------------------------------------------------------------------
2.3. The error window *syntastic-error-window*
You can use the |:Errors| command to display the errors for the current buffer
You can use the `:Errors` command to display the errors for the current buffer
in the |location-list|.
By default syntastic doesn't fill the |location-list| with the errors found by
the checkers, in order to reduce clashes with other plugins. Consequently, if
you run |:lopen| or |:lwindow| rather than |:Errors| to open the error window
you wouldn't see syntastic's list of errors. If you insist on using |:lopen|
or |:lwindow| you should either run |:SyntasticSetLoclist| after running the
checks, or set |syntastic_always_populate_loc_list| which tells syntastic to
you run `:lopen` or `:lwindow` rather than `:Errors` to open the error window
you wouldn't see syntastic's list of errors. If you insist on using `:lopen`
or `:lwindow` you should either run `:SyntasticSetLoclist` after running the
checks, or set |'syntastic_always_populate_loc_list'| which tells syntastic to
update the |location-list| automatically.
------------------------------------------------------------------------------
@ -215,10 +217,10 @@ Some checkers provide enough information for syntastic to be able to highlight
errors. By default the SpellBad syntax highlight group is used to color errors,
and the SpellCap group is used for warnings. If you wish to customize the
colors for highlighting you can use the following groups:
SyntasticError - Links to 'SpellBad' by default
SyntasticWarning - Links to 'SpellCap' by default
SyntasticStyleError - Links to SyntasticError by default
SyntasticStyleWarning - Links to SyntasticWarning by default
SyntasticError - Links to "SpellBad" by default (see |hl-SpellBad|)
SyntasticWarning - Links to "SpellCap" by default (see |hl-SpellCap|)
SyntasticStyleError - Links to "SyntasticError" by default
SyntasticStyleWarning - Links to "SyntasticWarning" by default
Example: >
highlight SyntasticError guibg=#2f0000
@ -238,7 +240,7 @@ If |'syntastic_aggregate_errors'| is set, syntastic runs all checkers that
apply (still cf. |syntastic-filetype-checkers|), then aggregates errors found
by all checkers in a single list, and notifies you. In this mode each error
message is labeled with the name of the checker that generated it, but you can
disable generation of these labels by turning off '|syntastic_id_checkers|'.
disable generation of these labels by turning off |'syntastic_id_checkers'|.
If |'syntastic_sort_aggregated_errors'| is set (which is the default), messages
in the aggregated list are grouped by file, then sorted by line number, then
@ -264,7 +266,7 @@ See also: |'syntastic_<filetype>_<checker>_quiet_messages'| and
When errors have been detected, use this command to pop up the |location-list|
and display the error messages.
Please note that the |:Errors| command overwrites the current location list with
Please note that the `:Errors` command overwrites the current location list with
syntastic's own location list.
:SyntasticToggleMode *:SyntasticToggleMode*
@ -304,26 +306,29 @@ Resets the list of errors and turns off all error notifiers.
If |'syntastic_always_populate_loc_list'| is not set, the |location-list| is
not filled in automatically with the list of errors detected by the checkers.
This is useful if you run syntastic along with other plugins that use location
lists. The |:SyntasticSetLoclist| command allows you to stick the errors into
lists. The `:SyntasticSetLoclist` command allows you to stick the errors into
the location list explicitly.
==============================================================================
4. Global Options *syntastic-global-options*
*'syntastic_check_on_open'*
Type: boolean
Default: 0
If this variable is enabled, syntastic in active mode will run syntax checks
when buffers are first loaded, as well as on saving: >
let g:syntastic_check_on_open = 1
<
*'syntastic_check_on_wq'*
Type: boolean
Default: 1
In active mode syntax checks are normally run whenever buffers are written to
disk, even when the writes happen just before quitting Vim. If you want to
skip checks when you issue |:wq|, |:x|, and |:ZZ|, set this variable to 0: >
skip checks when you issue `:wq`, `:x`, and `:ZZ`, set this variable to 0: >
let g:syntastic_check_on_wq = 0
<
*'syntastic_aggregate_errors'*
Type: boolean
Default: 0
When enabled, syntastic runs all checkers that apply to the current filetype,
then aggregates errors found by all checkers and displays them. When disabled,
@ -332,26 +337,30 @@ time a checker finds any errors. >
let g:syntastic_aggregate_errors = 1
<
*'syntastic_id_checkers'*
Type: boolean
Default: 1
When results from multiple checkers are aggregated in a single error list
(that is either when |'syntastic_aggregate_errors'| is enabled, or when
checking a file with a composite filetype), it might not be immediately
obvious which checker has produced a given error message. This variable
instructs syntastic to label error messages with the names of the checkers
that created them. >
checking a file with a composite filetype, cf. |syntastic-composite|), it
might not be immediately obvious which checker has produced a given error
message. This variable instructs syntastic to label error messages with the
names of the checkers that created them. >
let g:syntastic_id_checkers = 0
<
*'syntastic_sort_aggregated_errors'*
Type: boolean
Default: 1
By default, when results from multiple checkers are aggregated in a single
error list (that is either when |'syntastic_aggregate_errors'| is enabled,
or when checking a file with a composite filetype), errors are grouped by
file, then sorted by line number, then grouped by type (namely errors take
precedence over warnings), then they are sorted by column number. If you want
to leave messages grouped by checker output, set this variable to 0: >
error list (that is either when |'syntastic_aggregate_errors'| is enabled, or
when checking a file with a composite filetype, cf. |syntastic-composite|),
errors are grouped by file, then sorted by line number, then grouped by type
(namely errors take precedence over warnings), then they are sorted by column
number. If you want to leave messages grouped by checker output, set this
variable to 0: >
let g:syntastic_sort_aggregated_errors = 0
<
*'syntastic_echo_current_error'*
Type: boolean
Default: 1
If enabled, syntastic will echo current error to the command window. If
multiple errors are found on the same line, |'syntastic_cursor_columns'| is
@ -359,6 +368,7 @@ used to decide which one is shown. >
let g:syntastic_echo_current_error = 1
<
*'syntastic_cursor_columns'*
Type: boolean
Default: 1
This option controls which errors are echoed to the command window if
|'syntastic_echo_current_error'| is set and multiple errors are found on the
@ -371,25 +381,28 @@ up navigation significantly: >
let g:syntastic_cursor_column = 0
<
*'syntastic_enable_signs'*
Type: boolean
Default: 1
Use this option to tell syntastic whether to use the |:sign| interface to mark
Use this option to tell syntastic whether to use the `:sign` interface to mark
syntax errors: >
let g:syntastic_enable_signs = 1
<
*'syntastic_error_symbol'* *'syntastic_style_error_symbol'*
*'syntastic_warning_symbol'* *'syntastic_style_warning_symbol'*
Use this option to control what the syntastic |:sign| text contains. Several
Type: string
Use these options to control what the syntastic `:sign` text contains. Several
error symbols can be customized:
syntastic_error_symbol - For syntax errors, defaults to '>>'
syntastic_style_error_symbol - For style errors, defaults to 'S>'
syntastic_warning_symbol - For syntax warnings, defaults to '>>'
syntastic_style_warning_symbol - For style warnings, defaults to 'S>'
syntastic_error_symbol - For syntax errors, defaults to ">>"
syntastic_style_error_symbol - For style errors, defaults to "S>"
syntastic_warning_symbol - For syntax warnings, defaults to ">>"
syntastic_style_warning_symbol - For style warnings, defaults to "S>"
Example: >
let g:syntastic_error_symbol = ""
let g:syntastic_warning_symbol = ""
let g:syntastic_error_symbol = "\u2717"
let g:syntastic_warning_symbol = "\u26A0"
<
*'syntastic_enable_balloons'*
Type: boolean
Default: 1
Use this option to tell syntastic whether to display error messages in balloons
when the mouse is hovered over erroneous lines: >
@ -398,12 +411,14 @@ when the mouse is hovered over erroneous lines: >
Note that Vim must be compiled with |+balloon_eval|.
*'syntastic_enable_highlighting'*
Type: boolean
Default: 1
Use this option to tell syntastic whether to use syntax highlighting to mark
errors (where possible). Highlighting can be turned off with the following >
let g:syntastic_enable_highlighting = 0
<
*'syntastic_always_populate_loc_list'*
Type: boolean
Default: 0
By default syntastic doesn't fill the |location-list| with the errors found
by the checkers, in order to reduce clashes with other plugins. Enable this
@ -414,9 +429,10 @@ option to tell syntastic to always stick any detected errors into the
Please note that if |'syntastic_auto_jump'| is set to a non-zero value the
location list is overwritten with Syntastic's own list when taking a jump,
regardless of the value of |'syntastic_always_populate_loc_list'|. The
location list is also overwritten when running the |:Errors| command.
location list is also overwritten when running the `:Errors` command.
*'syntastic_auto_jump'*
Type: integer
Default: 0
Enable this option if you want the cursor to jump to the first detected issue
when saving or opening a file.
@ -441,6 +457,7 @@ of the location list being overwritten with Syntastic's own location list,
regardless of the value of |'syntastic_always_populate_loc_list'|.
*'syntastic_auto_loc_list'*
Type: integer
Default: 2
Use this option to tell syntastic to automatically open and/or close the
|location-list| (see |syntastic-error-window|).
@ -462,12 +479,14 @@ detected, but not closed automatically. >
let g:syntastic_auto_loc_list = 3
<
*'syntastic_loc_list_height'*
Type: integer
Default: 10
Use this option to specify the height of the location lists that syntastic
opens. >
let g:syntastic_loc_list_height = 5
<
*'syntastic_ignore_files'*
Type: list of strings
Default: []
Use this option to specify files that syntastic should never check. It's a
list of |regular-expression| patterns. The full paths of files (see |::p|) are
@ -476,6 +495,7 @@ to specify case-insensitive patterns. Example: >
let g:syntastic_ignore_files = ['\m^/usr/include/', '\m\c\.h$']
<
*'syntastic_filetype_map'*
Type: dictionary
Default: {}
Use this option to map non-standard filetypes to standard ones. Corresponding
checkers are mapped accordingly, which allows syntastic to check files with
@ -484,11 +504,13 @@ non-standard filetypes: >
\ "plaintex": "tex",
\ "gentoo-metadata": "xml" }
<
Composite filetypes can also be mapped to simple types, which disables the
default behaviour of running both checkers against the input file: >
Composite filetypes (cf. |syntastic-composite|) can also be mapped to simple
types, which disables the default behaviour of running both checkers against
the input file: >
let g:syntastic_filetype_map = { "handlebars.html": "handlebars" }
<
*'syntastic_mode_map'*
Type: dictionary
Default: { "mode": "active",
"active_filetypes": [],
"passive_filetypes": [] }
@ -496,7 +518,6 @@ Use this option to fine tune when automatic syntax checking is done (or not
done).
The option should be set to something like: >
let g:syntastic_mode_map = {
\ "mode": "active",
\ "active_filetypes": ["ruby", "php"],
@ -505,7 +526,7 @@ The option should be set to something like: >
"mode" can be mapped to one of two values - "active" or "passive". When set
to "active", syntastic does automatic checking whenever a buffer is saved or
initially opened. When set to "passive" syntastic only checks when the user
calls |:SyntasticCheck|.
calls `:SyntasticCheck`.
The exceptions to these rules are defined with "active_filetypes" and
"passive_filetypes". In passive mode, automatic checks are still done for
@ -520,16 +541,18 @@ If local variable |'b:syntastic_mode'| is defined its value takes precedence
over all calculations involving |'syntastic_mode_map'| for the corresponding
buffer.
At runtime, the |:SyntasticToggleMode| command can be used to switch between
At runtime, the `:SyntasticToggleMode` command can be used to switch between
active and passive modes.
*'b:syntastic_mode'*
Type: string
Default: unset
Only the local form |'b:syntastic_mode'| is used. When set to either "active"
or "passive", it takes precedence over |'syntastic_mode_map'| when deciding
whether the corresponding buffer should be checked automatically.
*'syntastic_quiet_messages'*
Type: dictionary
Default: {}
Use this option to filter out some of the messages produced by checkers. The
option should be set to something like: >
@ -542,7 +565,7 @@ option should be set to something like: >
Each element turns off messages matching the patterns specified by the
corresponding value. Values are lists, but if a list consist of a single
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|).
"level" - takes one of two values, "warnings" or "errors"
@ -572,16 +595,17 @@ errors produced by the said checker). In case of conflicting values for the
same keys, the values of the checker-specific filters take precedence.
*filter-overrides*
Since filter elements with values [] or '' are ignored, you can disable global
Since filter elements with values [] or "" are ignored, you can disable global
filters for particular checkers, by setting the values of the corresponding
elements in |'syntastic_<filetype>_<checker>_quiet_messages'| to [] or ''. For
elements in |'syntastic_<filetype>_<checker>_quiet_messages'| to [] or "". For
example, the following setting will silence all warnings, except for the
ones produced by "pylint": >
let g:syntastic_quiet_messages = { "level": "warnings" }
let g:syntastic_python_pylint_quiet_messages = { "level" : [] }
<
*'syntastic_stl_format'*
Default: [Syntax: line:%F (%t)]
Type: string
Default: "[Syntax: line:%F (%t)]"
Use this option to control what the syntastic statusline text contains. Several
magic flags are available to insert information:
%e - number of errors
@ -612,7 +636,7 @@ Several additional flags are available to hide text under certain conditions:
These flags can't be nested.
Example: >
let g:syntastic_stl_format = '[%E{Err: %fe #%e}%B{, }%W{Warn: %fw #%w}]'
let g:syntastic_stl_format = "[%E{Err: %fe #%e}%B{, }%W{Warn: %fw #%w}]"
<
If this format is used and the current buffer has 5 errors and 1 warning
starting on lines 20 and 10 respectively then this would appear on the
@ -623,19 +647,22 @@ If the buffer had 2 warnings, starting on line 5 then this would appear: >
[Warn: 5 #2]
<
*'b:syntastic_skip_checks'*
Type: boolean
Default: unset
Only the local form |'b:syntastic_skip_checks'| is used. When set to a true
value, no checks are run against the corresponding buffer. Example: >
let b:syntastic_skip_checks = 1
<
*'syntastic_full_redraws'*
Type: boolean
Default: 0 in GUI Vim and MacVim, 1 otherwise
Controls whether syntastic calls |:redraw| or |:redraw!| for screen redraws.
Controls whether syntastic calls `:redraw` or `:redraw!` for screen redraws.
Changing it can in principle make screen redraws smoother, but it can also
cause screen to flicker, or cause ghost characters. Leaving it to the default
should be safe.
*'syntastic_exit_checks'*
Type: boolean
Default: 0 when running under "cmd.exe" on Windows, 1 otherwise
Syntastic attempts to catch abnormal termination conditions from checkers by
looking at their exit codes. The "cmd.exe" shell on Windows make these checks
@ -643,6 +670,7 @@ meaningless, by returning 1 to Vim when the checkers exit with non-zero codes.
The above variable can be used to disable exit code checks in syntastic.
*'syntastic_shell'*
Type: string
Default: Vim's 'shell'
This is the (full path to) the shell syntastic will use to run the checkers.
On UNIX and Mac OS-X this shell must accept Bourne-compatible syntax for
@ -656,6 +684,7 @@ by the checkers you're using. Example: >
let g:syntastic_shell = "/bin/sh"
<
*'syntastic_nested_autocommands'*
Type: boolean
Default: 0
Controls whether syntastic's autocommands |BufReadPost| and |BufWritePost|
are called from other |BufReadPost| and |BufWritePost| autocommands (see
@ -663,6 +692,7 @@ are called from other |BufReadPost| and |BufWritePost| autocommands (see
other plugins, so only enable it if you actually need that functionality.
*'syntastic_debug'*
Type: integer
Default: 0
Set this to the sum of one or more of the following flags to enable
debugging:
@ -678,15 +708,17 @@ Example: >
let g:syntastic_debug = 1
<
Syntastic will then add debugging messages to Vim's |message-history|. You can
examine these messages with |:mes|.
examine these messages with `:mes`.
*'syntastic_debug_file'*
Type: string
Default: unset
When set, debugging messages are written to the file named by its value, in
addition to being added to Vim's |message-history|: >
let g:syntastic_debug_file = '~/syntastic.log'
let g:syntastic_debug_file = "~/syntastic.log"
<
*'syntastic_extra_filetypes'*
Type: list of strings
Default: []
List of filetypes handled by checkers external to syntastic. If you have a Vim
plugin that adds a checker for syntastic, and if the said checker deals with a
@ -694,7 +726,7 @@ filetype that is unknown to syntastic, you might consider adding that filetype
to this list: >
let g:syntastic_extra_filetypes = [ "make", "gitcommit" ]
<
This will allow |:SyntasticInfo| to do proper tab completion for the new
This will allow `:SyntasticInfo` to do proper tab completion for the new
filetypes.
==============================================================================
@ -709,7 +741,7 @@ variable 'g:syntastic_<filetype>_checkers' to a list of checkers, e.g. >
let g:syntastic_php_checkers = ["php", "phpcs", "phpmd"]
<
*'b:syntastic_checkers'*
There is also a per-buffer version of this setting, 'b:syntastic_checkers'.
There is also a per-buffer version of this setting, |'b:syntastic_checkers'|.
When set, it takes precedence over |'g:syntastic_<filetype>_checkers'|. You can
use this in an autocmd to configure specific checkers for particular paths: >
autocmd FileType python if stridx(expand("%:p"), "/some/path/") == 0 |
@ -724,7 +756,7 @@ by syntastic:
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.
------------------------------------------------------------------------------
5.2 Choosing the executable *syntastic-config-exec*
@ -733,74 +765,93 @@ Use |:SyntasticInfo| to see which checkers are available for a given filetype.
The executable run by a checker is normally defined automatically, when the
checker is registered. You can however override it, by setting the variable
'g:syntastic_<filetype>_<checker>_exec': >
let g:syntastic_ruby_mri_exec = '~/bin/ruby2'
let g:syntastic_ruby_mri_exec = "~/bin/ruby2"
<
This variable has a local version, 'b:syntastic_<filetype>_<checker>_exec',
which takes precedence over the global one in the corresponding buffer.
*'b:syntastic_<checker>_exec'*
And there is also a local variable named 'b:syntastic_<checker>_exec', which
There is also a local variable named 'b:syntastic_<checker>_exec', which
takes precedence over both 'b:syntastic_<filetype>_<checker>_exec' and
'g:syntastic_<filetype>_<checker>_exec' in the buffers where it is defined.
------------------------------------------------------------------------------
5.3 Configuring specific checkers *syntastic-config-makeprg*
Most checkers use the 'makeprgBuild()' function and provide many options by
default - in fact you can customise every part of the command that gets called.
Checkers are run by constructing a command line and by passing it to a shell
(see |'shell'| and |'syntastic_shell'|). In most cases this command line is
built using an internal function named "makeprgBuild()", which provides a
number of options that allow you to customise every part of the command that
gets called.
*'syntastic_<filetype>_<checker>_<option>'*
Checkers that use 'makeprgBuild()' construct a 'makeprg' like this: >
Checkers that use "makeprgBuild()" construct the corresponding command line
like this: >
let makeprg = self.makeprgBuild({
\ "exe": self.getExec(),
\ "args": "-a -b -c",
\ "fname": shellescape(expand("%", 1)),
\ "post_args": "--more --args",
\ "tail": "2>/dev/null" })
<
The result is a 'makeprg' of the form: >
The result is a command line of the form: >
<exe> <args> <fname> <post_args> <tail>
<
All arguments above are optional, and can be overridden by setting global
All fields above are optional, and can be overridden by setting global
variables 'g:syntastic_<filetype>_<checker-name>_<option-name>' - even
parameters not specified in the call to makeprgBuild(). These variables also
have local versions 'b:syntastic_<filetype>_<checker-name>_<option-name>',
which take precedence over the global ones in the corresponding buffers.
If one of these variables has a non-empty default and you want it to be empty,
you can set it to an empty string, e.g.: >
let g:syntastic_javascript_jslint_args = ""
<
*'syntastic_<filetype>_<checker>_exe'*
The 'exe' is normally the same as the 'exec' attribute described above, in
which case it may be omitted. However, you can use it to add environment
variables, or to change the way the checker is run. For example this setup
allows you to run PC-Lint under Wine emulation on Linux: >
let g:syntastic_c_pc_lint_exec = "wine"
let g:syntastic_c_pc_lint_exe = "wine c:/path/to/lint-nt.exe"
<
To override the args and the tail: >
parameters not specified in the call to "makeprgBuild()". For example to
override the argguments and the tail: >
let g:syntastic_c_pc_lint_args = "-w5 -Iz:/usr/include/linux"
let g:syntastic_c_pc_lint_tail = "2>/dev/null"
<
The general form of the override options is: >
syntastic_<filetype>_<checker>_<option-name>
These variables also have buffer-local versions named
'b:syntastic_<filetype>_<checker-name>_<option-name>', which takes precedence
over the global ones in the corresponding buffers.
You can see the final outcome of setting these variables in the debug logs
(cf. |syntastic-config-debug|).
Special characters need to be escaped, so that they can survive shell
expansions. Vim function |shellescape()| can help you with escaping: >
let g:syntastic_c_cppcheck_args =
\ "-DBUILD_BASENAME=my-module " . shellescape("-DBUILD_STR(s)=#s")
<
For checkers that do not use the 'makeprgBuild()' function you will have to
Alternatively, you can tell syntastic to escape special characters by turning
the value into a list: >
let g:syntastic_c_cppcheck_args =
\ ["-DBUILD_BASENAME=my-module", "-DBUILD_STR(s)=#s"]
<
Each element of this list is then escaped as needed, and turned into a
separate argument for the shell.
*syntastic-config-empty*
If one of the above variables has a non-empty default and you want it to be
empty, you can set it to an empty string, e.g.: >
let g:syntastic_javascript_jslint_args = ""
<
*'syntastic_<filetype>_<checker>_exe'*
The 'exe' option is special. Normally it is the same as the 'exec' attribute
described above, but you can use it to add environment variables to the
command line, or to change the way the checker is run. For example this setup
allows you to run PC-Lint on Linux, under Wine emulation: >
let g:syntastic_c_pc_lint_exec = "wine"
let g:syntastic_c_pc_lint_exe = "wine c:/path/to/lint-nt.exe"
<
*'syntastic_<filetype>_<checker>_fname'*
The 'fname' option is also special. Normally it is automatically set by
syntastic to the name of the current file, but you can change that as needed.
For example you can tell the SML/NJ compiler to use Compilation Manager by
omitting the filename from the command line: >
let g:syntastic_sml_smlnj_fname = ""
<
*syntastic-config-no-makeprgbuild*
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
options that can be set, these are usually documented in the wiki:
options that can be set, they are normally documented in the wiki:
https://github.com/scrooloose/syntastic/wiki/Syntax-Checkers
*'syntastic_<filetype>_<checker>_quiet_messages'*
In the same vein, 'g:syntastic_<filetype>_<checker-name>_quiet_messages' can
be used to restrict message filters to messages produced by specific checkers.
Example: >
let g:syntastic_python_pylama_quiet_messages = {
\ "type": "style",
\ "regex": '\m\[C03\d\d\]' }
<
See |syntastic_quiet_messages| for the syntax.
------------------------------------------------------------------------------
5.4 Sorting errors *syntastic-config-sort*
@ -821,11 +872,25 @@ For aggregated lists (see |syntastic-aggregating-errors|) these variables are
ignored if |'syntastic_sort_aggregated_errors'| is set (which is the default).
------------------------------------------------------------------------------
5.5 Debugging *syntastic-config-debug*
5.5 Filtering errors *syntastic-config-filtering*
*'syntastic_<filetype>_<checker>_quiet_messages'*
Finally, variables 'g:syntastic_<filetype>_<checker-name>_quiet_messages' can
be used to filter out some of the messages produced by specific checkers. The
effect is identical to that of |syntastic_quiet_messages|, except only messages
from the corresponding checkers are filtered. Example: >
let g:syntastic_python_pylama_quiet_messages = {
\ "type": "style",
\ "regex": '\m\[C03\d\d\]' }
<
The syntax is of course identical to that of |syntastic_quiet_messages|.
------------------------------------------------------------------------------
5.6 Debugging *syntastic-config-debug*
Syntastic can log a trace of its working to Vim's |message-history|. To verify
the command line constructed by syntastic to run a checker, set the variable
|'syntastic_debug'| to a non-zero value, run the checker, then run |:mes| to
|'syntastic_debug'| to a non-zero value, run the checker, then run `:mes` to
display the messages, and look for "makeprg" in the output.
From a user's perspective, the useful values for |'syntastic_debug'| are 1, 3,
@ -839,6 +904,23 @@ Debug logs can be saved to a file; see |'syntastic_debug_file'| for details.
Setting |'syntastic_debug'| to 0 turns off logging.
------------------------------------------------------------------------------
5.7 Profiling *syntastic-profiling*
A very useful tool for debugging performance problems is Vim's built-in
|profiler|. In order to enable profiling for syntastic you need to add two lines
to your vimrc (not to gvimrc): >
profile start syntastic.log
profile! file */syntastic/*
<
(assuming your copy of syntastic lives in a directory creatively named
"syntastic"). These lines must be executed before syntastic is loaded, so you
need to put them before package managers such as "pathogen" or "Vundle", and
(in newer Vim versions) before any commands related to |packages|.
A log file is created in the current directory, and is updated when you quit
Vim.
==============================================================================
6. Notes *syntastic-notes*
@ -846,7 +928,7 @@ Setting |'syntastic_debug'| to 0 turns off logging.
6.1. Handling of composite filetypes *syntastic-composite*
Some Vim plugins use composite filetypes, such as "django.python" or
"handlebars.html". Normally, syntastic deals with this situation by splitting
"handlebars.html". Normally syntastic deals with this situation by splitting
the filetype in its simple components, and calling all checkers that apply.
If this behaviour is not desirable, you can disable it by mapping the
composite filetypes to simple ones using |'syntastic_filetype_map'|, e.g.: >
@ -874,11 +956,11 @@ value.
------------------------------------------------------------------------------
6.4 Saving Vim sessions *syntastic-sessions*
If you use |:mksession| to save Vim sessions you should probably make sure to
If you use `:mksession` to save Vim sessions you should probably make sure to
remove option "blank" from 'sessionoptions': >
set sessionoptions-=blank
<
This will prevent |:mksession| from saving |syntastic-error-window| as empty
This will prevent `:mksession` from saving |syntastic-error-window| as empty
quickfix windows.
==============================================================================
@ -944,7 +1026,7 @@ described in the |syntastic-statusline-flag| section above: >
The "powerline" Vim plugin (https://github.com/powerline/powerline) comes
packaged with a syntastic segment. To customize this segment create a file
~/.config/powerline/themes/vim/default.json, with a content like this: >
"~/.config/powerline/themes/vim/default.json", with a content like this: >
{
"segment_data" : {
"powerline.segments.vim.plugin.syntastic.syntastic" : {

View file

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

View file

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

View file

@ -164,7 +164,7 @@ function! g:SyntasticRegistry.CreateAndRegisterChecker(args) abort " {{{2
if has_key(a:args, 'redirect')
let [ft, name] = split(a:args['redirect'], '/')
call registry._loadCheckersFor(ft)
call registry._loadCheckersFor(ft, 1)
let clone = get(registry._checkerMap[ft], name, {})
if empty(clone)
@ -184,7 +184,7 @@ endfunction " }}}2
" not run).
function! g:SyntasticRegistry.getCheckers(ftalias, hints_list) abort " {{{2
let ft = s:_normalise_filetype(a:ftalias)
call self._loadCheckersFor(ft)
call self._loadCheckersFor(ft, 0)
let checkers_map = self._checkerMap[ft]
if empty(checkers_map)
@ -233,7 +233,7 @@ endfunction " }}}2
function! g:SyntasticRegistry.getNamesOfAvailableCheckers(ftalias) abort " {{{2
let ft = s:_normalise_filetype(a:ftalias)
call self._loadCheckersFor(ft)
call self._loadCheckersFor(ft, 0)
return keys(filter( copy(self._checkerMap[ft]), 'v:val.isAvailable()' ))
endfunction " }}}2
@ -320,8 +320,8 @@ function! g:SyntasticRegistry._filterCheckersByName(checkers_map, list) abort "
return filter( map(copy(a:list), 'get(a:checkers_map, v:val, {})'), '!empty(v:val)' )
endfunction " }}}2
function! g:SyntasticRegistry._loadCheckersFor(filetype) abort " {{{2
if has_key(self._checkerMap, a:filetype)
function! g:SyntasticRegistry._loadCheckersFor(filetype, force) abort " {{{2
if !a:force && has_key(self._checkerMap, a:filetype)
return
endif

View file

@ -21,13 +21,6 @@ let s:setup_done = 0
function! g:SyntasticSignsNotifier.New() abort " {{{2
let newObj = copy(self)
if !s:setup_done
call self._setup()
let s:setup_done = 1
lockvar s:setup_done
endif
return newObj
endfunction " }}}2
@ -37,8 +30,15 @@ endfunction " }}}2
function! g:SyntasticSignsNotifier.refresh(loclist) abort " {{{2
call syntastic#log#debug(g:_SYNTASTIC_DEBUG_NOTIFICATIONS, 'signs: refresh')
let old_signs = copy(self._bufSignIds())
if self.enabled()
if !s:setup_done
call self._setup()
let s:setup_done = 1
lockvar s:setup_done
endif
call self._signErrors(a:loclist)
endif
call self._removeSigns(old_signs)

View file

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

View file

@ -21,6 +21,7 @@ function! SyntaxCheckers_haskell_hlint_GetLocList() dict
\ '%E%f:%l:%v: Error while reading hint file\, %m,' .
\ '%E%f:%l:%v: Error: %m,' .
\ '%W%f:%l:%v: Warning: %m,' .
\ '%W%f:%l:%v: Suggestion: %m,' .
\ '%C%m'
return SyntasticMake({

View file

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

View file

@ -0,0 +1,23 @@
"============================================================================
"File: textlint.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_markdown_textlint_checker')
finish
endif
let g:loaded_syntastic_markdown_textlint_checker = 1
call g:SyntasticRegistry.CreateAndRegisterChecker({
\ 'filetype': 'markdown',
\ 'name': 'textlint',
\ 'redirect': 'text/textlint'})
" vim: set sw=4 sts=4 et fdm=marker:

View file

@ -1,6 +1,13 @@
"============================================================================
"File: pep257.vim
"Description: Docstring style checking plugin for syntastic.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_python_pep257_checker')
@ -8,52 +15,9 @@ if exists('g:loaded_syntastic_python_pep257_checker')
endif
let g:loaded_syntastic_python_pep257_checker = 1
let s:save_cpo = &cpo
set cpo&vim
function! SyntaxCheckers_python_pep257_GetLocList() dict
if !exists('s:pep257_new')
let s:pep257_new = syntastic#util#versionIsAtLeast(self.getVersion(), [0, 3])
endif
let makeprg = self.makeprgBuild({})
if s:pep257_new
let errorformat =
\ '%E%f:%l %.%#:,' .
\ '%+C %m'
else
let errorformat =
\ '%E%f:%l:%c%\%.%\%.%\d%\+:%\d%\+: %m,' .
\ '%E%f:%l:%c: %m,' .
\ '%+C %m'
endif
let env = syntastic#util#isRunningWindows() ? {} : { 'TERM': 'dumb' }
let loclist = SyntasticMake({
\ 'makeprg': makeprg,
\ 'errorformat': errorformat,
\ 'env': env,
\ 'subtype': 'Style',
\ 'preprocess': 'killEmpty',
\ 'postprocess': ['compressWhitespace'] })
if s:pep257_new == 0
" byte offsets rather than column numbers
for e in loclist
let e['col'] = get(e, 'col', 0) + 1
endfor
endif
return loclist
endfunction
call g:SyntasticRegistry.CreateAndRegisterChecker({
\ 'filetype': 'python',
\ 'name': 'pep257'})
let &cpo = s:save_cpo
unlet s:save_cpo
\ 'name': 'pep257',
\ 'redirect': 'python/pydocstyle'})
" vim: set sw=4 sts=4 et fdm=marker:

View file

@ -0,0 +1,66 @@
"============================================================================
"File: pydocstyle.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_python_pydocstyle_checker')
finish
endif
let g:loaded_syntastic_python_pydocstyle_checker = 1
let s:save_cpo = &cpo
set cpo&vim
function! SyntaxCheckers_python_pydocstyle_GetLocList() dict
if !exists('s:pydocstyle_new')
let s:pydocstyle_new = syntastic#util#versionIsAtLeast(self.getVersion(), [0, 3])
endif
let makeprg = self.makeprgBuild({})
if s:pydocstyle_new
let errorformat =
\ '%E%f:%l %.%#:,' .
\ '%+C %m'
else
let errorformat =
\ '%E%f:%l:%c%\%.%\%.%\d%\+:%\d%\+: %m,' .
\ '%E%f:%l:%c: %m,' .
\ '%+C %m'
endif
let env = syntastic#util#isRunningWindows() ? {} : { 'TERM': 'dumb' }
let loclist = SyntasticMake({
\ 'makeprg': makeprg,
\ 'errorformat': errorformat,
\ 'env': env,
\ 'subtype': 'Style',
\ 'preprocess': 'killEmpty',
\ 'postprocess': ['compressWhitespace'] })
if s:pydocstyle_new == 0
" byte offsets rather than column numbers
for e in loclist
let e['col'] = get(e, 'col', 0) + 1
endfor
endif
return loclist
endfunction
call g:SyntasticRegistry.CreateAndRegisterChecker({
\ 'filetype': 'python',
\ 'name': 'pydocstyle'})
let &cpo = s:save_cpo
unlet s:save_cpo
" vim: set sw=4 sts=4 et fdm=marker:

View file

@ -49,7 +49,7 @@ function! SyntaxCheckers_python_pylama_GetLocList() dict
" adjust for weirdness in each checker
for e in loclist
let e['type'] = e['text'] =~? '\m^[RCW]' ? 'W' : 'E'
if e['text'] =~# '\v\[%(mccabe|pep257|pylint)\]$'
if e['text'] =~# '\v\[%(isort|mccabe|pep257|pylint)\]$'
if has_key(e, 'col')
let e['col'] += 1
endif
@ -59,7 +59,7 @@ function! SyntaxCheckers_python_pylama_GetLocList() dict
let e['vcol'] = 0
endif
endif
if e['text'] =~# '\v\[%(mccabe|pep257|pep8)\]$'
if e['text'] =~# '\v\[%(isort|mccabe|pep257|pep8)\]$'
let e['subtype'] = 'Style'
endif
endfor

View file

@ -0,0 +1,42 @@
"============================================================================
"File: textlint.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_text_textlint_checker')
finish
endif
let g:loaded_syntastic_text_textlint_checker = 1
let s:save_cpo = &cpo
set cpo&vim
function! SyntaxCheckers_text_textlint_GetLocList() dict
let makeprg = self.makeprgBuild({ 'args_after': '-f compact' })
let errorformat =
\ '%f: line %l\, col %c\, %tarning - %m,' .
\ '%f: line %l\, col %c\, %trror - %m'
return SyntasticMake({
\ 'makeprg': makeprg,
\ 'errorformat': errorformat,
\ 'subtype': 'Style',
\ 'returns': [0, 1] })
endfunction
call g:SyntasticRegistry.CreateAndRegisterChecker({
\ 'filetype': 'text',
\ 'name': 'textlint'})
let &cpo = s:save_cpo
unlet s:save_cpo
" vim: set sw=4 sts=4 et fdm=marker:

View file

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

View file

@ -50,6 +50,12 @@ function! airline#themes#lucius#refresh()
\ 'red': airline#themes#get_highlight('Constant'),
\ }
" Extra tabline colors
let s:TS = airline#themes#get_highlight('TabLineSel')
let g:airline#themes#lucius#palette.tabline = {}
let g:airline#themes#lucius#palette.tabline.airline_tabsel = s:TS
let g:airline#themes#lucius#palette.tabline.airline_tabsel_right = s:TS
endfunction
call airline#themes#lucius#refresh()

View file

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

View file

@ -3,16 +3,31 @@
This is the Changelog for the vim-airline project.
## [Unreleased]
## [0.8] - 2016-03-09
- Changes
- Themes have been moved into an extra repository [vim-airline-themes](https://github.com/vim-airline/vim-airline-themes)
- Many new themes
- Airline Moved to new [repository](https://github.com/vim-airline/vim-airline)
- New features
- Integration with [taboo](https://github.com/gcmt/taboo.vim), [vim-ctrlspace](https://github.com/szw/vim-ctrlspace),
[quickfixsigns](https://github.com/tomtom/quickfixsigns_vim), [YouCompleteMe](https://github.com/Valloric/YouCompleteMe)
- Airline converted to an organization and moved to new [repository](https://github.com/vim-airline/vim-airline)
- Themes have been split into an separate repository [vim-airline-themes](https://github.com/vim-airline/vim-airline-themes)
- Improvements
- Extensions
- branch: support Git and Mercurial simultaneously, untracked files
- whitespace: new mixed-indent rule
- Windows support
- Many bug fixes
- Support for Neovim
- Added wordcount extension
- Adding Crypt and Byte Order Mark Indicator
- New features
- Many new themes
- Extensions/integration
- [taboo](https://github.com/gcmt/taboo.vim)
- [vim-ctrlspace](https://github.com/szw/vim-ctrlspace)
- [quickfixsigns](https://github.com/tomtom/quickfixsigns_vim)
- [YouCompleteMe](https://github.com/Valloric/YouCompleteMe)
- [po.vim](http://www.vim.org/scripts/script.php?script_id=695)
- [unicode.vim](https://github.com/chrisbra/unicode.vim)
- wordcount
- crypt indicator
- byte order mark indicator
- Tabline's tab mode can display splits simultaneously
## [0.7] - 2014-12-10
- New features
@ -94,7 +109,8 @@ This is the Changelog for the vim-airline project.
- integration with other plugins: netrw, unite, nerdtree, undotree, gundo, tagbar, minibufexplr, ctrlp
- support for themes: 8 included
[Unreleased]: https://github.com/vim-airline/vim-airline/compare/v0.7...HEAD
[Unreleased]: https://github.com/vim-airline/vim-airline/compare/v0.8...HEAD
[0.8]: https://github.com/vim-airline/vim-airline/compare/v0.7...v0.8
[0.7]: https://github.com/vim-airline/vim-airline/compare/v0.6...v0.7
[0.6]: https://github.com/vim-airline/vim-airline/compare/v0.5...v0.6
[0.5]: https://github.com/vim-airline/vim-airline/compare/v0.4...v0.5

View file

@ -0,0 +1,14 @@
#### environment
- vim: ????
- vim-airline: ????
- OS: ????
- terminal: ????
#### actual behavior
????
#### expected behavior
????

View file

@ -72,9 +72,10 @@ endfunction
function! airline#switch_matching_theme()
if exists('g:colors_name')
let existing = g:airline_theme
let theme = substitute(g:colors_name, '-', '_', 'g')
try
let palette = g:airline#themes#{g:colors_name}#palette
call airline#switch_theme(g:colors_name)
let palette = g:airline#themes#{theme}#palette
call airline#switch_theme(theme)
return 1
catch
for map in items(g:airline_theme_map)
@ -174,6 +175,10 @@ function! airline#check_mode(winnr)
call add(l:mode, 'crypt')
endif
if g:airline_detect_spell && &spell
call add(l:mode, 'spell')
endif
if &readonly || ! &modifiable
call add(l:mode, 'readonly')
endif

View file

@ -210,6 +210,10 @@ function! airline#extensions#load()
call airline#extensions#whitespace#init(s:ext)
endif
if get(g:, 'airline#extensions#po#enabled', 1) && executable('msgfmt')
call airline#extensions#po#init(s:ext)
endif
if get(g:, 'airline#extensions#wordcount#enabled', 1)
call airline#extensions#wordcount#init(s:ext)
endif

View file

@ -154,7 +154,7 @@ function! airline#extensions#branch#head()
if exists("g:airline#extensions#branch#displayed_head_limit")
let w:displayed_head_limit = g:airline#extensions#branch#displayed_head_limit
if len(b:airline_head) > w:displayed_head_limit - 1
let b:airline_head = b:airline_head[0:w:displayed_head_limit - 1].'…'
let b:airline_head = b:airline_head[0:(w:displayed_head_limit - 1)].(&encoding ==? 'utf-8' ? '…' : '.')
endif
endif

View file

@ -0,0 +1,36 @@
" MIT License. Copyright (c) 2013-2016 Bailey Ling.
" vim: et ts=2 sts=2 sw=2
function! airline#extensions#po#apply(...)
if &ft ==# 'po'
call airline#extensions#prepend_to_section('z', '%{airline#extensions#po#stats()}')
autocmd airline BufWritePost * unlet! b:airline_po_stats
endif
endfunction
function! airline#extensions#po#stats()
if exists('b:airline_po_stats') && !empty(b:airline_po_stats)
return b:airline_po_stats
endif
let airline_po_stats = system('msgfmt --statistics -o /dev/null -- '. expand('%:p'))
if v:shell_error
return ''
endif
try
let b:airline_po_stats = '['. split(airline_po_stats, '\n')[0]. ']'
catch
let b:airline_po_stats = ''
endtry
if exists("g:airline#extensions#po#displayed_limit")
let w:displayed_po_limit = g:airline#extensions#po#displayed_limit
if len(b:airline_po_stats) > w:displayed_po_limit - 1
let b:airline_po_stats = b:airline_po_stats[0:(w:displayed_po_limit - 1)].(&encoding==?'utf-8' ? '…' : '.')
endif
endif
return b:airline_po_stats
endfunction
function! airline#extensions#po#init(ext)
call a:ext.add_statusline_func('airline#extensions#po#apply')
endfunction

View file

@ -5,6 +5,7 @@ let s:formatter = get(g:, 'airline#extensions#tabline#formatter', 'default')
let s:show_buffers = get(g:, 'airline#extensions#tabline#show_buffers', 1)
let s:show_tabs = get(g:, 'airline#extensions#tabline#show_tabs', 1)
let s:ignore_bufadd_pat = get(g:, 'airline#extensions#tabline#ignore_bufadd_pat', '\c\vgundo|undotree|vimfiler|tagbar|nerd_tree')
let s:taboo = get(g:, 'airline#extensions#taboo#enabled', 1) && get(g:, 'loaded_taboo', 0)
if s:taboo
let g:taboo_tabline = 0
@ -41,6 +42,9 @@ function! s:toggle_on()
endfunction
function! s:update_tabline()
if get(g:, 'airline#extensions#tabline#disable_refresh', 0)
return
endif
let match = expand('<afile>')
if pumvisible()
return
@ -52,16 +56,7 @@ function! s:update_tabline()
\ || isdirectory(expand("<afile>"))
return
endif
if empty(mapcheck("<Plug>AirlineTablineRefresh", 'n'))
noremap <silent> <Plug>AirlineTablineRefresh :set mod!<cr>
endif
call feedkeys("\<Plug>AirlineTablineRefresh")
call feedkeys("\<Plug>AirlineTablineRefresh")
"call feedkeys(',,', 't')
"call feedkeys(':unmap ,,')
" force re-evaluation of tabline setting
" disable explicit redraw, may cause E315
"redraw
doautocmd User BufMRUChange
endfunction
function! airline#extensions#tabline#load_theme(palette)
@ -92,6 +87,7 @@ function! airline#extensions#tabline#load_theme(palette)
" Theme for tabs on the right
let l:tabsel_right = get(colors, 'airline_tabsel_right', a:palette.normal.airline_a)
let l:tab_right = get(colors, 'airline_tab_right', a:palette.inactive.airline_c)
let l:tabmod_right = get(colors, 'airline_tabmod_right', a:palette.insert.airline_a)
let l:tabhid_right = get(colors, 'airline_tabhid_right', a:palette.normal.airline_c)
if has_key(a:palette, 'normal_modified') && has_key(a:palette.normal_modified, 'airline_c')
@ -100,6 +96,7 @@ function! airline#extensions#tabline#load_theme(palette)
"Fall back to normal airline_c if modified airline_c isn't present
let l:tabmodu_right = get(colors, 'airline_tabmod_unsel_right', a:palette.normal.airline_c)
endif
call airline#highlighter#exec('airline_tab_right', l:tab_right)
call airline#highlighter#exec('airline_tabsel_right', l:tabsel_right)
call airline#highlighter#exec('airline_tabmod_right', l:tabmod_right)
call airline#highlighter#exec('airline_tabhid_right', l:tabhid_right)
@ -134,6 +131,10 @@ function! airline#extensions#tabline#title(n)
let title = TabooTabTitle(a:n)
endif
if empty(title) && exists('*gettabvar')
let title = gettabvar(a:n, 'title')
endif
if empty(title)
let buflist = tabpagebuflist(a:n)
let winnr = tabpagewinnr(a:n)
@ -163,3 +164,23 @@ function! airline#extensions#tabline#new_builder()
return airline#builder#new(builder_context)
endfunction
function! airline#extensions#tabline#group_of_bufnr(tab_bufs, bufnr)
let cur = bufnr('%')
if cur == a:bufnr
if g:airline_detect_modified && getbufvar(a:bufnr, '&modified')
let group = 'airline_tabmod'
else
let group = 'airline_tabsel'
endif
else
if g:airline_detect_modified && getbufvar(a:bufnr, '&modified')
let group = 'airline_tabmod_unsel'
elseif index(a:tab_bufs, a:bufnr) > -1
let group = 'airline_tab'
else
let group = 'airline_tabhid'
endif
endif
return group
endfunction

View file

@ -5,6 +5,7 @@ scriptencoding utf-8
let s:buffer_idx_mode = get(g:, 'airline#extensions#tabline#buffer_idx_mode', 0)
let s:show_tab_type = get(g:, 'airline#extensions#tabline#show_tab_type', 1)
let s:buffers_label = get(g:, 'airline#extensions#tabline#buffers_label', 'buffers')
let s:spc = g:airline_symbols.space
let s:current_bufnr = -1
@ -64,23 +65,16 @@ function! airline#extensions#tabline#buffers#get()
continue
endif
if cur == nr
if g:airline_detect_modified && getbufvar(nr, '&modified')
let group = 'airline_tabmod'
else
let group = 'airline_tabsel'
endif
let group = airline#extensions#tabline#group_of_bufnr(tab_bufs, nr)
if nr == cur
let s:current_modified = (group == 'airline_tabmod') ? 1 : 0
else
if g:airline_detect_modified && getbufvar(nr, '&modified')
let group = 'airline_tabmod_unsel'
elseif index(tab_bufs, nr) > -1
let group = 'airline_tab'
else
let group = 'airline_tabhid'
endif
endif
" Neovim feature: Have clickable buffers
if has("tablineat")
call b.add_raw('%'.nr.'@airline#extensions#tabline#buffers#switchbuf@')
endif
if s:buffer_idx_mode
if len(s:number_map) > 0
call b.add_section(group, s:spc . get(s:number_map, l:index, '') . '%(%{airline#extensions#tabline#get_buffer_name('.nr.')}%)' . s:spc)
@ -91,13 +85,16 @@ function! airline#extensions#tabline#buffers#get()
else
call b.add_section(group, s:spc.'%(%{airline#extensions#tabline#get_buffer_name('.nr.')}%)'.s:spc)
endif
if has("tablineat")
call b.add_raw('%X')
endif
endfor
call b.add_section('airline_tabfill', '')
call b.split()
call b.add_section('airline_tabfill', '')
if s:show_tab_type
call b.add_section('airline_tabtype', ' buffers ')
call b.add_section_spaced('airline_tabtype', s:buffers_label)
endif
let s:current_bufnr = cur
@ -198,3 +195,11 @@ function s:map_keys()
noremap <silent> <Plug>AirlineSelectNextTab :<C-u>call <SID>jump_to_tab(v:count1)<CR>
endif
endfunction
function airline#extensions#tabline#buffers#switchbuf(minwid, clicks, button, modifiers) abort
" Run the following code only on a single left mouse button click without modifiers pressed
" works only in recent NeoVim with has('tablineat')
if a:clicks == 1 && a:button is# 'l' && a:modifiers !~# '[^ ]'
sil execute 'buffer' a:minwid
endif
endfunction

View file

@ -7,6 +7,12 @@ let s:current_bufnr = -1
let s:current_tabnr = -1
let s:current_tabline = ''
let s:buffers_label = get(g:, 'airline#extensions#tabline#buffers_label', 'buffers')
let s:tabs_label = get(g:, 'airline#extensions#tabline#tabs_label', 'tabs')
let s:switch_buffers_and_tabs = get(g:, 'airline#extensions#tabline#switch_buffers_and_tabs', 0)
let s:show_buffers = get(g:, 'airline#extensions#tabline#show_buffers', 1)
let s:show_tabs = get(g:, 'airline#extensions#tabline#show_tabs', 1)
function! airline#extensions#tabline#ctrlspace#off()
augroup airline_tabline_ctrlspace
autocmd!
@ -25,6 +31,67 @@ function! airline#extensions#tabline#ctrlspace#invalidate()
let s:current_tabnr = -1
endfunction
function! airline#extensions#tabline#ctrlspace#add_buffer_section(builder, cur_tab, cur_buf, pos)
if a:pos == 0
let pos_extension = ''
else
let pos_extension = '_right'
endif
let s:buffer_list = ctrlspace#api#BufferList(a:cur_tab)
for buffer in s:buffer_list
if a:cur_buf == buffer.index
if buffer.modified
let group = 'airline_tabmod'.pos_extension
else
let group = 'airline_tabsel'.pos_extension
endif
else
if buffer.modified
let group = 'airline_tabmod_unsel'.pos_extension
elseif buffer.visible
let group = 'airline_tab'.pos_extension
else
let group = 'airline_tabhid'.pos_extension
endif
endif
let buf_name = '%(%{airline#extensions#tabline#get_buffer_name('.buffer.index.')}%)'
if has("tablineat")
let buf_name = '%'.buffer.index.'@airline#extensions#tabline#buffers#switchbuf@'.buf_name.'%X'
endif
call a:builder.add_section_spaced(group, buf_name)
endfor
endfunction
function! airline#extensions#tabline#ctrlspace#add_tab_section(builder, pos)
if a:pos == 0
let pos_extension = ''
else
let pos_extension = '_right'
endif
for tab in s:tab_list
if tab.current
if tab.modified
let group = 'airline_tabmod'.pos_extension
else
let group = 'airline_tabsel'.pos_extension
endif
else
if tab.modified
let group = 'airline_tabmod_unsel'.pos_extension
else
let group = 'airline_tabhid'.pos_extension
endif
endif
call a:builder.add_section_spaced(group, '%'.tab.index.'T'.tab.title.ctrlspace#api#TabBuffersNumber(tab.index).'%T')
endfor
endfunction
function! airline#extensions#tabline#ctrlspace#get()
let cur_buf = bufnr('%')
@ -39,59 +106,44 @@ function! airline#extensions#tabline#ctrlspace#get()
return s:current_tabline
endif
let b = airline#extensions#tabline#new_builder()
let builder = airline#extensions#tabline#new_builder()
call b.add_section_spaced('airline_tabtype', 'buffers')
let s:buffer_list = ctrlspace#api#BufferList(cur_tab)
for buffer in s:buffer_list
if cur_buf == buffer.index
if buffer.modified
let group = 'airline_tabmod'
" Add left tabline content
if s:show_buffers == 0
call airline#extensions#tabline#ctrlspace#add_tab_section(builder, 0)
elseif s:show_tabs == 0
call airline#extensions#tabline#ctrlspace#add_buffer_section(builder, cur_tab, cur_buf, 0)
else
let group = 'airline_tabsel'
endif
if s:switch_buffers_and_tabs == 0
call builder.add_section_spaced('airline_tabtype', s:buffers_label)
call airline#extensions#tabline#ctrlspace#add_buffer_section(builder, cur_tab, cur_buf, 0)
else
if buffer.modified
let group = 'airline_tabmod_unsel'
elseif buffer.visible
let group = 'airline_tab'
else
let group = 'airline_tabhid'
call builder.add_section_spaced('airline_tabtype', s:tabs_label)
call airline#extensions#tabline#ctrlspace#add_tab_section(builder, 0)
endif
endif
let buf_name = '%(%{airline#extensions#tabline#get_buffer_name('.buffer.index.')}%)'
call b.add_section_spaced(group, buf_name)
endfor
call builder.add_section('airline_tabfill', '')
call builder.split()
call builder.add_section('airline_tabfill', '')
call b.add_section('airline_tabfill', '')
call b.split()
call b.add_section('airline_tabfill', '')
for tab in s:tab_list
if tab.current
if tab.modified
let group = 'airline_tabmod_right'
" Add right tabline content
if s:show_buffers == 0
call builder.add_section_spaced('airline_tabtype', s:tabs_label)
elseif s:show_tabs == 0
call builder.add_section_spaced('airline_tabtype', s:buffers_label)
else
let group = 'airline_tabsel_right'
endif
if s:switch_buffers_and_tabs == 0
call airline#extensions#tabline#ctrlspace#add_tab_section(builder, 1)
call builder.add_section_spaced('airline_tabtype', s:tabs_label)
else
if tab.modified
let group = 'airline_tabmod_unsel_right'
else
let group = 'airline_tabhid_right'
call airline#extensions#tabline#ctrlspace#add_buffer_section(builder, cur_tab, cur_buf, 1)
call builder.add_section_spaced('airline_tabtype', s:buffers_label)
endif
endif
call b.add_section_spaced(group, tab.title.ctrlspace#api#TabBuffersNumber(tab.index))
endfor
call b.add_section_spaced('airline_tabtype', 'tabs')
let s:current_bufnr = cur_buf
let s:current_tabnr = cur_tab
let s:current_tabline = b.build()
let s:current_tabline = builder.build()
return s:current_tabline
endfunction

View file

@ -1,11 +1,14 @@
" MIT License. Copyright (c) 2013-2016 Bailey Ling.
" vim: et ts=2 sts=2 sw=2
let s:show_tab_nr = get(g:, 'airline#extensions#tabline#show_tab_nr', 1)
let s:tab_nr_type = get(g:, 'airline#extensions#tabline#tab_nr_type', 0)
let s:show_close_button = get(g:, 'airline#extensions#tabline#show_close_button', 1)
let s:show_tab_type = get(g:, 'airline#extensions#tabline#show_tab_type', 1)
let s:show_tab_nr = get(g:, 'airline#extensions#tabline#show_tab_nr', 1)
let s:tab_nr_type = get(g:, 'airline#extensions#tabline#tab_nr_type', 0)
let s:close_symbol = get(g:, 'airline#extensions#tabline#close_symbol', 'X')
let s:tabs_label = get(g:, 'airline#extensions#tabline#tabs_label', 'tabs')
let s:show_splits = get(g:, 'airline#extensions#tabline#show_splits', 1)
let s:spc = g:airline_symbols.space
let s:current_bufnr = -1
let s:current_tabnr = -1
@ -39,6 +42,7 @@ function! airline#extensions#tabline#tabs#get()
endif
let b = airline#extensions#tabline#new_builder()
for i in range(1, tabpagenr('$'))
if i == curtab
let group = 'airline_tabsel'
@ -66,14 +70,22 @@ function! airline#extensions#tabline#tabs#get()
call b.add_section(group, val.'%'.i.'T %{airline#extensions#tabline#title('.i.')} %)')
endfor
call b.add_raw('%T')
call b.add_section('airline_tabfill', '')
call b.split()
call b.add_section('airline_tabfill', '')
if s:show_close_button
call b.add_section('airline_tab', ' %999X'.s:close_symbol.' ')
call b.add_section('airline_tab_right', ' %999X'.s:close_symbol.' ')
endif
if s:show_tab_type
call b.add_section('airline_tabtype', ' tabs ')
if s:show_splits == 1
let buffers = tabpagebuflist(curtab)
for nr in buffers
let group = airline#extensions#tabline#group_of_bufnr(buffers, nr) . "_right"
call b.add_section_spaced(group, '%(%{airline#extensions#tabline#get_buffer_name('.nr.')}%)')
endfor
elseif s:show_tab_type == 1
call b.add_section_spaced('airline_tabtype', s:tabs_label)
endif
let s:current_bufnr = curbuf

View file

@ -18,6 +18,8 @@ let s:max_lines = get(g:, 'airline#extensions#whitespace#max_lines', 20000)
let s:enabled = get(g:, 'airline#extensions#whitespace#enabled', 1)
let s:c_like_langs = ['c', 'cpp', 'cuda', 'java', 'javascript', 'ld']
function! s:check_mixed_indent()
if s:indent_algo == 1
" [<tab>]<space><tab>
@ -35,8 +37,14 @@ function! s:check_mixed_indent()
endfunction
function! s:check_mixed_indent_file()
if index(s:c_like_langs, &ft) > -1
" for C-like languages: allow /** */ comment style with one space before the '*'
let head_spc = '\v(^ +\*@!)'
else
let head_spc = '\v(^ +)'
endif
let indent_tabs = search('\v(^\t+)', 'nw')
let indent_spc = search('\v(^ +)', 'nw')
let indent_spc = search(head_spc, 'nw')
if indent_tabs > 0 && indent_spc > 0
return printf("%d:%d", indent_tabs, indent_spc)
else

View file

@ -15,7 +15,11 @@ function! airline#extensions#windowswap#init(ext)
endfunction
function! airline#extensions#windowswap#get_status()
if WindowSwap#HasMarkedWindow() && WindowSwap#GetMarkedWindowNum() == winnr()
" use new tab-aware api if WS is up to date
let s:mark = exists('*WindowSwap#IsCurrentWindowMarked') ?
\WindowSwap#IsCurrentWindowMarked() :
\(WindowSwap#HasMarkedWindow() && WindowSwap#GetMarkedWindowNum() == winnr())
if s:mark
return g:airline#extensions#windowswap#indicator_text.s:spc
endif
return ''

View file

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

View file

@ -22,6 +22,7 @@ function! airline#init#bootstrap()
call s:check_defined('g:airline_detect_modified', 1)
call s:check_defined('g:airline_detect_paste', 1)
call s:check_defined('g:airline_detect_crypt', 1)
call s:check_defined('g:airline_detect_spell', 1)
call s:check_defined('g:airline_detect_iminsert', 0)
call s:check_defined('g:airline_inactive_collapse', 1)
call s:check_defined('g:airline_exclude_filenames', ['DebuggerWatch','DebuggerStack','DebuggerStatus'])
@ -47,18 +48,18 @@ function! airline#init#bootstrap()
call s:check_defined('g:airline_theme_map', {})
call extend(g:airline_theme_map, {
\ 'Tomorrow.*': 'tomorrow',
\ 'base16.*': 'base16',
\ 'bubblegum': 'bubblegum',
\ '\CTomorrow': 'tomorrow',
\ 'base16': 'base16',
\ 'mo[l|n]okai': 'molokai',
\ 'wombat.*': 'wombat',
\ '.*zenburn.*': 'zenburn',
\ '.*solarized.*': 'solarized',
\ 'wombat': 'wombat',
\ 'zenburn': 'zenburn',
\ 'solarized': 'solarized',
\ }, 'keep')
call s:check_defined('g:airline_symbols', {})
call extend(g:airline_symbols, {
\ 'paste': 'PASTE',
\ 'spell': 'SPELL',
\ 'readonly': get(g:, 'airline_powerline_fonts', 0) ? "\ue0a2" : 'RO',
\ 'whitespace': get(g:, 'airline_powerline_fonts', 0) ? "\u2739" : '!',
\ 'linenr': get(g:, 'airline_powerline_fonts', 0) ? "\ue0a1" : ':',
@ -76,6 +77,7 @@ function! airline#init#bootstrap()
call airline#parts#define_function('iminsert', 'airline#parts#iminsert')
call airline#parts#define_function('paste', 'airline#parts#paste')
call airline#parts#define_function('crypt', 'airline#parts#crypt')
call airline#parts#define_function('spell', 'airline#parts#spell')
call airline#parts#define_function('filetype', 'airline#parts#filetype')
call airline#parts#define('readonly', {
\ 'function': 'airline#parts#readonly',
@ -103,7 +105,7 @@ endfunction
function! airline#init#sections()
let spc = g:airline_symbols.space
if !exists('g:airline_section_a')
let g:airline_section_a = airline#section#create_left(['mode', 'crypt', 'paste', 'capslock', 'iminsert'])
let g:airline_section_a = airline#section#create_left(['mode', 'crypt', 'paste', 'spell', 'capslock', 'iminsert'])
endif
if !exists('g:airline_section_b')
let g:airline_section_b = airline#section#create(['hunks', 'branch'])

View file

@ -62,6 +62,10 @@ function! airline#parts#paste()
return g:airline_detect_paste && &paste ? g:airline_symbols.paste : ''
endfunction
function! airline#parts#spell()
return g:airline_detect_spell && &spell ? g:airline_symbols.spell : ''
endfunction
function! airline#parts#iminsert()
if g:airline_detect_iminsert && &iminsert && exists('b:keymap_name')
return toupper(b:keymap_name)
@ -70,7 +74,11 @@ function! airline#parts#iminsert()
endfunction
function! airline#parts#readonly()
if &readonly && &modifiable && !filereadable(bufname('%'))
return '[noperm]'
else
return &readonly ? g:airline_symbols.readonly : ''
endif
endfunction
function! airline#parts#filetype()

View file

@ -72,6 +72,9 @@ values):
<
* enable crypt detection >
let g:airline_detect_crypt=1
* enable spell detection >
let g:airline_detect_spell=1
<
* enable iminsert detection >
let g:airline_detect_iminsert=0
@ -191,6 +194,7 @@ its contents. >
let g:airline_symbols.paste = 'ρ'
let g:airline_symbols.paste = 'Þ'
let g:airline_symbols.paste = '∥'
let g:airline_symbols.spell = 'Ꞩ'
let g:airline_symbols.notexists = '∄'
let g:airline_symbols.whitespace = 'Ξ'
@ -223,7 +227,7 @@ section.
>
variable names default contents
----------------------------------------------------------------------------
let g:airline_section_a (mode, crypt, paste, iminsert)
let g:airline_section_a (mode, crypt, paste, spell, iminsert)
let g:airline_section_b (hunks, branch)
let g:airline_section_c (bufferline or filename)
let g:airline_section_gutter (readonly, csv)
@ -489,13 +493,22 @@ eclim <https://eclim.org>
let g:airline#extensions#whitespace#trailing_regexp = '\s$'
<
------------------------------------- *airline-tabline*
* enable/disable enhanced tabline. >
Note: If you're using the ctrlspace tabline only the option marked with (c)
are supported!
* enable/disable enhanced tabline. (c)
let g:airline#extensions#tabline#enabled = 0
<
* enable/disable displaying buffers with a single tab. >
* enable/disable displaying open splits per tab (only when tabs are opened). >
let g:airline#extensions#tabline#show_splits = 1
*
* switch position of buffers and tabs on splited tabline (c)
let g:airline#extensions#tabline#switch_buffers_and_tabs = 0
* enable/disable displaying buffers with a single tab. (c)
let g:airline#extensions#tabline#show_buffers = 1
<
* enable/disable displaying tabs, regardless of number. >
* enable/disable displaying tabs, regardless of number. (c)
let g:airline#extensions#tabline#show_tabs = 1
<
* configure filename match rules to exclude from the tabline. >
@ -515,11 +528,13 @@ eclim <https://eclim.org>
* enable/disable displaying tab type (far right) >
let g:airline#extensions#tabline#show_tab_type = 1
* enable/disable displaying index of the buffer.
* rename label for buffers (default: 'buffers') (c)
let g:airline#extensions#tabline#buffers_label = 'b'
Note: If you're using ctrlspace the tabline shows your tabs on the right and
buffer on the left. Also none of the tabline switches is currently
supported!
* rename label for tabs (default: 'tabs') (c)
let g:airline#extensions#tabline#tabs_label = 't'
* enable/disable displaying index of the buffer.
When enabled, numbers will be displayed in the tabline and mappings will be
exposed to allow you to select a buffer directly. Up to 9 mappings will be
@ -545,7 +560,7 @@ eclim <https://eclim.org>
Use |gt| for switching tabs.
In tabmode, those mappings will switch to the specified tab.
* defines the name of a formatter for how buffer names are displayed. >
* defines the name of a formatter for how buffer names are displayed. (c)
let g:airline#extensions#tabline#formatter = 'default'
" here is how you can define a 'foo' formatter:
@ -565,7 +580,7 @@ eclim <https://eclim.org>
* configure whether buffer numbers should be shown. >
let g:airline#extensions#tabline#buffer_nr_show = 0
<
* configure how buffer numbers should be formatted with |printf|. >
* configure how buffer numbers should be formatted with |printf()|. >
let g:airline#extensions#tabline#buffer_nr_format = '%s: '
<
* configure the formatting of filenames (see |filename-modifiers|). >
@ -614,9 +629,13 @@ eclim <https://eclim.org>
let airline#extensions#tabline#ignore_bufadd_pat =
\ '\c\vgundo|undotree|vimfiler|tagbar|nerd_tree'
<
Note: Enabling this extension will modify 'showtabline' and 'guioptions'.
* enable Refresh of tabline buffers on |BufAdd| autocommands
(set this to one, if you note 'AirlineTablineRefresh', however, this
won't update airline on |:badd| commands) >
let airline#extensions#tabline#disable_refresh = 0
------------------------------------- *airline-tmuxline*
tmuxline <https://github.com/edkolev/tmuxline.vim>
@ -707,6 +726,15 @@ Shows number of errors and warnings in the current file detected by YCM.
* set warning count prefix >
let g:airline#extensions#ycm#warning_symbol = 'W:'
<
------------------------------------- *airline-po*
po.vim <http://www.vim.org/scripts/script.php?script_id=2530>
* enable/disable po integration >
let g:airline#extensions#po#enabled = 1
<
* truncate width names to a fixed length >
let g:airline#extensions#po#displayed_limit = 0
<
==============================================================================
ADVANCED CUSTOMIZATION *airline-advanced-customization*
@ -747,6 +775,7 @@ Before is a list of parts that are predefined by vim-airline.
* `iminsert` displays the current insert method
* `paste` displays the paste indicator
* `crypt` displays the crypted indicator
* `spell` displays the spell indicator
* `filetype` displays the file type
* `readonly` displays the read only indicator
* `file` displays the filename and modified indicator

View file

@ -18,9 +18,10 @@ describe 'init sections'
call s:clear()
end
it 'section a should have mode, paste, iminsert'
it 'section a should have mode, paste, spell, iminsert'
Expect g:airline_section_a =~ 'mode'
Expect g:airline_section_a =~ 'paste'
Expect g:airline_section_a =~ 'spell'
Expect g:airline_section_a =~ 'iminsert'
end

View file

@ -28,11 +28,11 @@ function! s:go(type,...) abort
let [lnum1, lnum2] = [line("'["), line("']")]
endif
let [l, r] = s:surroundings()
let [l_, r_] = s:surroundings()
let uncomment = 2
for lnum in range(lnum1,lnum2)
let line = matchstr(getline(lnum),'\S.*\s\@<!')
let [l, r] = s:strip_white_space(l,r,line)
let [l, r] = s:strip_white_space(l_,r_,line)
if line != '' && (stridx(line,l) || line[strlen(line)-strlen(r) : -1] != r)
let uncomment = 0
endif

View file

@ -57,6 +57,10 @@ that are part of Git repositories).
q close status
r reload status
S |:Gvsplit|
U |:Git| checkout
U |:Git| checkout HEAD (staged files)
U |:Git| clean (untracked files)
U |:Git| rm (unmerged files)
*fugitive-:Gcommit*
:Gcommit [args] A wrapper around git-commit. If there is nothing
@ -91,10 +95,10 @@ that are part of Git repositories).
:Gfetch [args] Like |:Gpush|, but for git-fetch.
*fugitive-:Ggrep*
:Ggrep [args] |:grep| with git-grep as 'grepprg'.
:Ggrep[!] [args] |:grep|[!] with git-grep as 'grepprg'.
*fugitive-:Glgrep*
:Glgrep [args] |:lgrep| with git-grep as 'grepprg'.
:Glgrep[!] [args] |:lgrep|[!] with git-grep as 'grepprg'.
*fugitive-:Glog*
:Glog [args] Load all previous revisions of the current file into

View file

@ -123,7 +123,9 @@ let s:abstract_prototype = {}
function! fugitive#is_git_dir(path) abort
let path = s:sub(a:path, '[\/]$', '') . '/'
return isdirectory(path.'objects') && isdirectory(path.'refs') && getfsize(path.'HEAD') > 10
return getfsize(path.'HEAD') > 10 && (
\ isdirectory(path.'objects') && isdirectory(path.'refs') ||
\ getftype(path.'commondir') ==# 'file')
endfunction
function! fugitive#extract_git_dir(path) abort
@ -265,9 +267,17 @@ function! s:configured_tree(git_dir) abort
let config = readfile(config_file,'',10)
call filter(config,'v:val =~# "^\\s*worktree *="')
if len(config) == 1
let s:worktree_for_dir[a:git_dir] = matchstr(config[0], '= *\zs.*')
let s:dir_for_worktree[s:worktree_for_dir[a:git_dir]] = a:git_dir
let worktree = matchstr(config[0], '= *\zs.*')
endif
elseif filereadable(a:git_dir . '/gitdir')
let worktree = fnamemodify(readfile(a:git_dir . '/gitdir')[0], ':h')
if worktree ==# '.'
unlet! worktree
endif
endif
if exists('worktree')
let s:worktree_for_dir[a:git_dir] = worktree
let s:dir_for_worktree[s:worktree_for_dir[a:git_dir]] = a:git_dir
endif
endif
if s:worktree_for_dir[a:git_dir] =~# '^\.'
@ -299,6 +309,10 @@ function! s:repo_bare() dict abort
endfunction
function! s:repo_translate(spec) dict abort
let refs = self.dir('refs/')
if filereadable(self.dir('commondir'))
let refs = simplify(self.dir(get(readfile(self.dir('commondir'), 1), 0, ''))) . '/refs/'
endif
if a:spec ==# '.' || a:spec ==# '/.'
return self.bare() ? self.dir() : self.tree()
elseif a:spec =~# '^/\=\.git$' && self.bare()
@ -322,18 +336,18 @@ function! s:repo_translate(spec) dict abort
return 'fugitive://'.self.dir().'//0/'.a:spec[1:-1]
elseif a:spec ==# '@'
return self.dir('HEAD')
elseif a:spec =~# 'HEAD\|^refs/' && a:spec !~ ':' && filereadable(self.dir(a:spec))
return self.dir(a:spec)
elseif filereadable(self.dir('refs/'.a:spec))
return self.dir('refs/'.a:spec)
elseif filereadable(self.dir('refs/tags/'.a:spec))
return self.dir('refs/tags/'.a:spec)
elseif filereadable(self.dir('refs/heads/'.a:spec))
return self.dir('refs/heads/'.a:spec)
elseif filereadable(self.dir('refs/remotes/'.a:spec))
return self.dir('refs/remotes/'.a:spec)
elseif filereadable(self.dir('refs/remotes/'.a:spec.'/HEAD'))
return self.dir('refs/remotes/'.a:spec,'/HEAD')
elseif a:spec =~# 'HEAD\|^refs/' && a:spec !~ ':' && filereadable(refs . '../' . a:spec)
return simplify(refs . '../' . a:spec)
elseif filereadable(refs.a:spec)
return refs.a:spec
elseif filereadable(refs.'tags/'.a:spec)
return refs.'tags/'.a:spec
elseif filereadable(refs.'heads/'.a:spec)
return refs.'heads/'.a:spec
elseif filereadable(refs.'remotes/'.a:spec)
return refs.'remotes/'.a:spec
elseif filereadable(refs.'remotes/'.a:spec.'/HEAD')
return refs.'remotes/'.a:spec,'/HEAD'
else
try
let ref = self.rev_parse(matchstr(a:spec,'[^:]*'))
@ -849,7 +863,9 @@ function! s:StageUndo() abort
let hash = repo.git_chomp('hash-object', '-w', filename)
if !empty(hash)
if section ==# 'untracked'
call delete(s:repo().tree(filename))
call repo.git_chomp_in_tree('clean', '--', filename)
elseif section ==# 'unmerged'
call repo.git_chomp_in_tree('rm', '--', filename)
elseif section ==# 'unstaged'
call repo.git_chomp_in_tree('checkout', '--', filename)
else
@ -1552,6 +1568,7 @@ function! s:Write(force,...) abort
unlet! restorewinnr
let zero = s:repo().translate(':0:'.path)
silent execute 'doautocmd BufWritePost' s:fnameescape(zero)
for tab in range(1,tabpagenr('$'))
for winnr in range(1,tabpagewinnr(tab,'$'))
let bufnr = tabpagebuflist(tab)[winnr-1]
@ -2310,7 +2327,7 @@ function! s:Browse(bang,line1,count,...) abort
let url = s:gsub(url, '[ <>]', '\="%".printf("%02X",char2nr(submatch(0)))')
if a:bang
if has('clipboard')
let @* = url
let @+ = url
endif
return 'echomsg '.string(url)
elseif exists(':Browse') == 2
@ -2675,7 +2692,7 @@ function! s:BufReadObject() abort
if b:fugitive_display_format
call s:ReplaceCmd(s:repo().git_command('cat-file',b:fugitive_type,hash))
else
call s:ReplaceCmd(s:repo().git_command('show','--no-color','--pretty=format:tree %T%nparent %P%nauthor %an <%ae> %ad%ncommitter %cn <%ce> %cd%nencoding %e%n%n%s%n%n%b',hash))
call s:ReplaceCmd(s:repo().git_command('show','--no-color','--pretty=format:tree%x20%T%nparent%x20%P%nauthor%x20%an%x20<%ae>%x20%ad%ncommitter%x20%cn%x20<%ce>%x20%cd%nencoding%x20%e%n%n%s%n%n%b',hash))
keepjumps call search('^parent ')
if getline('.') ==# 'parent '
silent keepjumps delete_

View file

@ -0,0 +1,9 @@
Thanks for improving vim-go! Before you dive in please read the following:
1. Please read our
[FAQ](https://github.com/fatih/vim-go/wiki/FAQ-Troubleshooting), it might
have answers for your problem
2. If you add a new feature please don't forget to update the documentation:
[doc/vim-go.txt](doc/vim-go.txt)
3. If it's a breaking change or exceed +100 lines please open an issue first
and describe the changes you want to make.

View file

@ -0,0 +1,28 @@
### Actual behavior
Write here what's happening ...
### Expected behavior
Write here what you're expecting ...
### Steps to reproduce:
Please create a reproducible case of your problem. Re produce it
with a minimal `vimrc` with all plugins disabled and only `vim-go`
enabled:
1.
2.
3.
### Configuration
Add here your current configuration and additional information that might be
useful, such as:
* `vimrc` you used to reproduce
* vim version:
* vim-go version
* go version

View file

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

View file

@ -24,8 +24,8 @@ disabled/enabled easily.
* Automatic `GOPATH` detection based on the directory structure (i.e. `gb`
projects, `godep` vendored projects)
* Change or display `GOPATH` with `:GoPath`
* Create a coverage profile and display annotated source code in browser to see
which functions are covered with `:GoCoverage`
* Create a coverage profile and display annotated source code to see which
functions are covered with `:GoCoverage`
* Call `gometalinter` with `:GoMetaLinter`, which invokes all possible linters
(golint, vet, errcheck, deadcode, etc..) and shows the warnings/errors
* Lint your code with `:GoLint`
@ -43,12 +43,19 @@ disabled/enabled easily.
* Tagbar support to show tags of the source code in a sidebar with `gotags`
* Custom vim text objects such as `a function` or `inner function`
list.
* Jump to function or type declarations with `:GoDecls` or `:GoDeclsDir`
* A async launcher for the go command is implemented for Neovim, fully async
building and testing (beta).
* Integrated with the Neovim terminal, launch `:GoRun` and other go commands
in their own new terminal. (beta)
* Alternate between implementation and test code with `:GoAlternate`
## Donation
People have asked for this for a long time, now you can be a fully supporter by [being a patron](https://www.patreon.com/fatih)! This is fully optional and is just a way to support vim-go's ongoing development directly. Thanks!
[https://www.patreon.com/fatih](https://www.patreon.com/fatih)
## Install
Vim-go follows the standard runtime path structure, so I highly recommend to

View file

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

View file

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

View file

@ -5,26 +5,26 @@ endif
" Test alternates between the implementation of code and the test code.
function! go#alternate#Switch(bang, cmd)
let l:file = go#alternate#Filename(fnameescape(expand("%")))
if !filereadable(l:file) && !bufexists(l:file) && !a:bang
redraws! | echon "vim-go: " | echohl ErrorMsg | echon "couldn't find ".file | echohl None
let file = expand('%')
if empty(file)
call go#util#EchoError("no buffer name")
return
elseif file =~# '^\f\+_test\.go$'
let l:root = split(file, '_test.go$')[0]
let l:alt_file = l:root . ".go"
elseif file =~# '^\f\+\.go$'
let l:root = split(file, ".go$")[0]
let l:alt_file = l:root . '_test.go'
else
call go#util#EchoError("not a go file")
return
endif
if !filereadable(alt_file) && !bufexists(alt_file) && !a:bang
call go#util#EchoError("couldn't find ".alt_file)
return
elseif empty(a:cmd)
execute ":" . g:go_alternate_mode . " " . file
execute ":" . g:go_alternate_mode . " " . alt_file
else
execute ":" . a:cmd . " " . file
execute ":" . a:cmd . " " . alt_file
endif
endfunction
" Filename returns the name of the test file or implementation file
" depending on the arguments
function! go#alternate#Filename(path)
if empty(matchstr(a:path, "_test"))
let l:root = split(a:path, ".go$")[0]
let l:file = l:root . "_test.go"
else
let l:root = split(a:path, "_test.go$")[0]
let l:file = l:root . ".go"
endif
return l:file
endfunction

View file

@ -74,8 +74,12 @@ endfunction
" Run runs the current file (and their dependencies if any) in a new terminal.
function! go#cmd#RunTerm(bang, mode)
function! go#cmd#RunTerm(bang, mode, files)
if empty(a:files)
let cmd = "go run ". go#util#Shelljoin(go#tool#Files())
else
let cmd = "go run ". go#util#Shelljoin(map(copy(a:files), "expand(v:val)"), 1)
endif
call go#term#newmode(a:bang, cmd, a:mode)
endfunction
@ -85,7 +89,7 @@ endfunction
" calling long running apps will block the whole UI.
function! go#cmd#Run(bang, ...)
if has('nvim')
call go#cmd#RunTerm(a:bang, '')
call go#cmd#RunTerm(a:bang, '', a:000)
return
endif
@ -117,9 +121,9 @@ function! go#cmd#Run(bang, ...)
if g:go_dispatch_enabled && exists(':Make') == 2
silent! exe 'Make'
elseif l:listtype == "locationlist"
silent! exe 'lmake!'
exe 'lmake!'
else
silent! exe 'make!'
exe 'make!'
endif
let items = go#list#Get(l:listtype)
@ -209,11 +213,11 @@ function! go#cmd#Test(bang, compile, ...)
if has('nvim')
if get(g:, 'go_term_enabled', 0)
call go#term#new(a:bang, ["go"] + args)
let id = go#term#new(a:bang, ["go"] + args)
else
call go#jobcontrol#Spawn(a:bang, "test", args)
let id = go#jobcontrol#Spawn(a:bang, "test", args)
endif
return
return id
endif
call go#cmd#autowrite()
@ -286,36 +290,6 @@ function! go#cmd#TestFunc(bang, ...)
call call('go#cmd#Test', args)
endfunction
" Coverage creates a new cover profile with 'go test -coverprofile' and opens
" a new HTML coverage page from that profile.
function! go#cmd#Coverage(bang, ...)
let l:tmpname=tempname()
let command = "go test -coverprofile=" . l:tmpname . ' ' . go#util#Shelljoin(a:000)
let l:listtype = "quickfix"
call go#cmd#autowrite()
let out = go#tool#ExecuteInDir(command)
if v:shell_error
let errors = go#tool#ParseErrors(split(out, '\n'))
call go#list#Populate(l:listtype, errors)
call go#list#Window(l:listtype, len(errors))
if !empty(errors) && !a:bang
call go#list#JumpToFirst(l:listtype)
endif
else
" clear previous location list
call go#list#Clean(l:listtype)
call go#list#Window(l:listtype)
let openHTML = 'go tool cover -html='.l:tmpname
call go#tool#ExecuteInDir(openHTML)
endif
call delete(l:tmpname)
endfunction
" Generate runs 'go generate' in similar fashion to go#cmd#Build()
function! go#cmd#Generate(bang, ...)
let default_makeprg = &makeprg

View file

@ -87,32 +87,21 @@ fu! s:gocodeCurrentBufferOpt(filename)
return '-in=' . a:filename
endf
fu! go#complete#gocodeCursor()
if &encoding != 'utf-8'
let sep = &l:fileformat == 'dos' ? "\r\n" : "\n"
let c = col('.')
let buf = line('.') == 1 ? "" : (join(getline(1, line('.')-1), sep) . sep)
let buf .= c == 1 ? "" : getline('.')[:c-2]
return printf('%d', len(iconv(buf, &encoding, "utf-8")))
endif
return printf('%d', line2byte(line('.')) + (col('.')-2))
endf
fu! s:gocodeAutocomplete()
let filename = s:gocodeCurrentBuffer()
let result = s:gocodeCommand('autocomplete',
\ [s:gocodeCurrentBufferOpt(filename), '-f=vim'],
\ [expand('%:p'), go#complete#gocodeCursor()])
\ [expand('%:p'), go#util#OffsetCursor()])
call delete(filename)
return result
endf
function! go#complete#GetInfoFromOffset(offset)
function! go#complete#GetInfo()
let offset = go#util#OffsetCursor()+1
let filename = s:gocodeCurrentBuffer()
let result = s:gocodeCommand('autocomplete',
\ [s:gocodeCurrentBufferOpt(filename), '-f=godit'],
\ [expand('%:p'), a:offset])
\ [expand('%:p'), offset])
call delete(filename)
" first line is: Charcount,,NumberOfCandidates, i.e: 8,,1
@ -148,14 +137,12 @@ function! go#complete#GetInfoFromOffset(offset)
return ""
endfunction
function! go#complete#GetInfo()
let offset = go#complete#gocodeCursor()
return go#complete#GetInfoFromOffset(offset)
endfunction
function! go#complete#Info()
function! go#complete#Info(auto)
" auto is true if we were called by g:go_auto_type_info's autocmd
let result = go#complete#GetInfo()
if !empty(result)
" if auto, and the result is a PANIC by gocode, hide it
if a:auto && result ==# 'PANIC PANIC PANIC' | return | endif
echo "vim-go: " | echohl Function | echon result | echohl None
endif
endfunction

View file

@ -0,0 +1,251 @@
let s:toggle = 0
" Buffer creates a new cover profile with 'go test -coverprofile' and changes
" teh current buffers highlighting to show covered and uncovered sections of
" the code. If run again it clears the annotation
function! go#coverage#Buffer(bang, ...)
if s:toggle
call go#coverage#Clear()
return
endif
let s:toggle = 1
let l:tmpname=tempname()
let args = [a:bang, 0, "-coverprofile", l:tmpname]
if a:0
call extend(args, a:000)
endif
let disabled_term = 0
if get(g:, 'go_term_enabled')
let disabled_term = 1
let g:go_term_enabled = 0
endif
let id = call('go#cmd#Test', args)
if disabled_term
let g:go_term_enabled = 1
endif
if has('nvim')
call go#jobcontrol#AddHandler(function('s:coverage_handler'))
let s:coverage_handler_jobs[id] = l:tmpname
return
endif
if !v:shell_error
call go#coverage#overlay(l:tmpname)
endif
call delete(l:tmpname)
endfunction
" Clear clears and resets the buffer annotation matches
function! go#coverage#Clear()
if exists("g:syntax_on") | syntax enable | endif
if exists("s:toggle") | let s:toggle = 0 | endif
" remove the autocmd we defined
if exists("#BufWinLeave#<buffer>")
autocmd! BufWinLeave <buffer>
endif
call clearmatches()
endfunction
" Browser creates a new cover profile with 'go test -coverprofile' and opens
" a new HTML coverage page from that profile in a new browser
function! go#coverage#Browser(bang, ...)
let l:tmpname=tempname()
let args = [a:bang, 0, "-coverprofile", l:tmpname]
if a:0
call extend(args, a:000)
endif
let id = call('go#cmd#Test', args)
if has('nvim')
call go#jobcontrol#AddHandler(function('s:coverage_browser_handler'))
let s:coverage_browser_handler_jobs[id] = l:tmpname
return
endif
if !v:shell_error
let openHTML = 'go tool cover -html='.l:tmpname
call go#tool#ExecuteInDir(openHTML)
endif
call delete(l:tmpname)
endfunction
" Parses a single line from the cover file generated via go test -coverprofile
" and returns a single coverage profile block.
function! go#coverage#parsegocoverline(line)
" file:startline.col,endline.col numstmt count
let mx = '\([^:]\+\):\(\d\+\)\.\(\d\+\),\(\d\+\)\.\(\d\+\)\s\(\d\+\)\s\(\d\+\)'
let tokens = matchlist(a:line, mx)
let ret = {}
let ret.file = tokens[1]
let ret.startline = str2nr(tokens[2])
let ret.startcol = str2nr(tokens[3])
let ret.endline = str2nr(tokens[4])
let ret.endcol = str2nr(tokens[5])
let ret.numstmt = tokens[6]
let ret.cnt = tokens[7]
return ret
endfunction
" Generates matches to be added to matchaddpos for the given coverage profile
" block
function! go#coverage#genmatch(cov)
let color = 'covered'
if a:cov.cnt == 0
let color = 'uncover'
endif
let matches = []
" if start and end are the same, also specify the byte length
" example: foo.go:92.2,92.65 1 0
if a:cov.startline == a:cov.endline
call add(matches, {
\ 'group': color,
\ 'pos': [[a:cov.startline, a:cov.startcol, a:cov.endcol - a:cov.startcol]],
\ 'priority': 2,
\ })
return matches
endif
" add start columns. Because we don't know the length of the of
" the line, we assume it is at maximum 200 bytes. I know this is hacky,
" but that's only way of fixing the issue
call add(matches, {
\ 'group': color,
\ 'pos': [[a:cov.startline, a:cov.startcol, 200]],
\ 'priority': 2,
\ })
" and then the remaining lines
let start_line = a:cov.startline
while start_line < a:cov.endline
let start_line += 1
call add(matches, {
\ 'group': color,
\ 'pos': [[start_line]],
\ 'priority': 2,
\ })
endwhile
" finally end columns
call add(matches, {
\ 'group': color,
\ 'pos': [[a:cov.endline, a:cov.endcol-1]],
\ 'priority': 2,
\ })
return matches
endfunction
" Reads the given coverprofile file and annotates the current buffer
function! go#coverage#overlay(file)
if !filereadable(a:file)
return
endif
let lines = readfile(a:file)
" cover mode, by default it's 'set'. Just here for debugging purposes
let mode = lines[0]
" contains matches for matchaddpos()
let matches = []
" first mark all lines as normaltext. We use a custom group to not
" interfere with other buffers highlightings. Because the priority is
" lower than the cover and uncover matches, it'll be overriden.
let cnt = 1
while cnt <= line('$')
call add(matches, {'group': 'normaltext', 'pos': [cnt], 'priority': 1})
let cnt += 1
endwhile
let fname = expand('%:t')
" when called for a _test.go file, run the coverage for the actuall file
" file
if fname =~# '^\f\+_test\.go$'
let l:root = split(fname, '_test.go$')[0]
let fname = l:root . ".go"
if !filereadable(fname)
call go#util#EchoError("couldn't find ".fname)
return
endif
" open the alternate file to show the coverage
exe ":edit ". fnamemodify(fname, ":p")
endif
for line in lines[1:]
let cov = go#coverage#parsegocoverline(line)
" TODO(arslan): for now only include the coverage for the current
" buffer
if fname != fnamemodify(cov.file, ':t')
continue
endif
call extend(matches, go#coverage#genmatch(cov))
endfor
syntax manual
highlight normaltext term=bold ctermfg=59 guifg=#75715E
highlight covered term=bold ctermfg=118 guifg=#A6E22E
highlight uncover term=bold ctermfg=197 guifg=#F92672
" clear the matches if we leave the buffer
autocmd BufWinLeave <buffer> call go#coverage#Clear()
for m in matches
call matchaddpos(m.group, m.pos)
endfor
endfunction
" -----------------------
" | Neovim job handlers |
" -----------------------
let s:coverage_handler_jobs = {}
let s:coverage_browser_handler_jobs = {}
function! s:coverage_handler(job, exit_status, data)
if !has_key(s:coverage_handler_jobs, a:job.id)
return
endif
let l:tmpname = s:coverage_handler_jobs[a:job.id]
if a:exit_status == 0
call go#coverage#overlay(l:tmpname)
endif
call delete(l:tmpname)
unlet s:coverage_handler_jobs[a:job.id]
endfunction
function! s:coverage_browser_handler(job, exit_status, data)
if !has_key(s:coverage_browser_handler_jobs, a:job.id)
return
endif
let l:tmpname = s:coverage_browser_handler_jobs[a:job.id]
if a:exit_status == 0
let openHTML = 'go tool cover -html='.l:tmpname
call go#tool#ExecuteInDir(openHTML)
endif
call delete(l:tmpname)
unlet s:coverage_browser_handler_jobs[a:job.id]
endfunction
" vim:ts=4:sw=4:et

View file

@ -15,9 +15,7 @@ endf
" modified and improved version of vim-godef
function! go#def#Jump(...)
if !len(a:000)
" gives us the offset of the word, basicall the position of the word under
" he cursor
let arg = s:getOffset()
let arg = "-o=" . go#util#OffsetCursor()
else
let arg = a:1
endif
@ -31,19 +29,23 @@ function! go#def#Jump(...)
let $GOPATH = go#path#Detect()
let fname = fnamemodify(expand("%"), ':p:gs?\\?/?')
let command = bin_path . " -f=" . shellescape(fname) . " -i " . shellescape(arg)
let command = bin_path . " -t -f=" . shellescape(fname) . " -i " . shellescape(arg)
" get output of godef
let out = s:system(command, join(getbufline(bufnr('%'), 1, '$'), go#util#LineEnding()))
" First line is <file>:<line>:<col>
" Second line is <identifier><space><type>
let godefout=split(out, go#util#LineEnding())
" jump to it
call s:godefJump(out, "")
call s:godefJump(godefout, "")
let $GOPATH = old_gopath
endfunction
function! go#def#JumpMode(mode)
let arg = s:getOffset()
let arg = "-o=" . go#util#OffsetCursor()
let bin_path = go#path#CheckBinPath(g:go_godef_bin)
if empty(bin_path)
@ -54,29 +56,23 @@ function! go#def#JumpMode(mode)
let $GOPATH = go#path#Detect()
let fname = fnamemodify(expand("%"), ':p:gs?\\?/?')
let command = bin_path . " -f=" . shellescape(fname) . " -i " . shellescape(arg)
let command = bin_path . " -t -f=" . shellescape(fname) . " -i " . shellescape(arg)
" get output of godef
let out = s:system(command, join(getbufline(bufnr('%'), 1, '$'), go#util#LineEnding()))
call s:godefJump(out, a:mode)
" First line is <file>:<line>:<col>
" Second line is <identifier><space><type>
let godefout=split(out, go#util#LineEnding())
" jump to it
call s:godefJump(godefout, a:mode)
let $GOPATH = old_gopath
endfunction
function! s:getOffset()
let pos = getpos(".")[1:2]
if &encoding == 'utf-8'
let offs = line2byte(pos[0]) + pos[1] - 2
else
let c = pos[1]
let buf = line('.') == 1 ? "" : (join(getline(1, pos[0] - 1), go#util#LineEnding()) . go#util#LineEnding())
let buf .= c == 1 ? "" : getline(pos[0])[:c-2]
let offs = len(iconv(buf, &encoding, "utf-8"))
endif
let argOff = "-o=" . offs
return argOff
return "-o=" . go#util#OffsetCursor()
endfunction
@ -84,17 +80,26 @@ function! s:godefJump(out, mode)
let old_errorformat = &errorformat
let &errorformat = "%f:%l:%c"
if a:out =~ 'godef: '
let out = substitute(a:out, go#util#LineEnding() . '$', '', '')
echom out
else
let parts = split(a:out, ':')
" Location is the first line of godef output. Ideally in the proper format
" but it could also be an error
let location = a:out[0]
" Echo the godef error if we had one.
if location =~ 'godef: '
let gderr=substitute(location, go#util#LineEnding() . '$', '', '')
call go#util#EchoError(gderr)
return
endif
let parts = split(a:out[0], ':')
" parts[0] contains filename
let fileName = parts[0]
" put the error format into location list so we can jump automatically to
" it
lgetexpr a:out
" Don't jump if it's the same identifier we just jumped to
if len(w:go_stack) > 0 && w:go_stack[w:go_stack_level-1]['ident'] == a:out[1] && w:go_stack[w:go_stack_level-1]['file'] == fileName
return
endif
" needed for restoring back user setting this is because there are two
" modes of switchbuf which we need based on the split mode
@ -106,19 +111,150 @@ function! s:godefJump(out, mode)
if bufloaded(fileName) == 0
tab split
endif
else
if a:mode == "split"
elseif a:mode == "split"
split
elseif a:mode == "vsplit"
vsplit
else
" Don't jump in this window if it's been modified
if getbufvar(bufnr('%'), "&mod")
call go#util#EchoError("No write since last change")
return
endif
endif
let stack_entry = {'line': line("."), 'col': col("."),
\'file': expand('%:p'), 'ident': a:out[1]}
" jump to file now
call s:goToFileLocation(location)
"
" Remove anything newer than the current position, just like basic
" vim tag support
if w:go_stack_level == 0
let w:go_stack = []
else
let w:go_stack = w:go_stack[0:w:go_stack_level-1]
endif
" increment the stack counter
let w:go_stack_level += 1
" push it on to the jumpstack
call add(w:go_stack, stack_entry)
let &switchbuf = old_switchbuf
endfunction
function! go#def#StackUI()
if len(w:go_stack) == 0
call go#util#EchoError("godef stack empty")
return
endif
let stackOut = ['" <Up>,<Down>:navigate <Enter>:jump <Esc>,q:exit']
let i = 0
while i < len(w:go_stack)
let entry = w:go_stack[i]
let prefix = ""
if i == w:go_stack_level
let prefix = ">"
else
let prefix = " "
endif
call add(stackOut, printf("%s %d %s|%d col %d|%s", prefix, i+1, entry["file"], entry["line"], entry["col"], entry["ident"]))
let i += 1
endwhile
if w:go_stack_level == i
call add(stackOut, "> ")
endif
call go#ui#OpenWindow("GoDef Stack", stackOut, "godefstack")
noremap <buffer> <silent> <CR> :<C-U>call go#def#SelectStackEntry()<CR>
noremap <buffer> <silent> <Esc> :<C-U>call go#ui#CloseWindow()<CR>
noremap <buffer> <silent> q :<C-U>call go#ui#CloseWindow()<CR>
endfunction
function! go#def#StackPop(...)
if len(w:go_stack) == 0
call go#util#EchoError("godef stack empty")
return
endif
if w:go_stack_level == 0
call go#util#EchoError("at bottom of the godef stack")
return
endif
if !len(a:000)
let numPop = 1
else
let numPop = a:1
endif
let newLevel = str2nr(w:go_stack_level) - str2nr(numPop)
call go#def#StackJump(newLevel + 1)
endfunction
function! go#def#StackJump(...)
if len(w:go_stack) == 0
call go#util#EchoError("godef stack empty")
return
endif
if !len(a:000)
" Display interactive stack
call go#def#StackUI()
return
else
let jumpTarget= a:1
endif
if jumpTarget !~ '^\d\+$'
if jumpTarget !~ '^\s*$'
call go#util#EchoError("location must be a number")
endif
return
endif
let jumpTarget=str2nr(jumpTarget) - 1
if jumpTarget >= 0 && jumpTarget < len(w:go_stack)
let w:go_stack_level = jumpTarget
let target = w:go_stack[w:go_stack_level]
" jump
call s:goToFileLocation(target["file"], target["line"], target["col"])
else
call go#util#EchoError("invalid godef stack location. Try :GoDefJump to see the list of valid entries")
endif
endfunction
function! s:goToFileLocation(...)
let old_errorformat = &errorformat
let &errorformat = "%f:%l:%c"
" put the error format into location list so we can jump automatically to
" it
if a:0 == 3
lgetexpr printf("%s:%s:%s", a:1, a:2, a:3)
elseif a:0 == 1
lgetexpr a:1
else
lgetexpr ""
endif
sil ll 1
normal zz
let &switchbuf = old_switchbuf
end
let &errorformat = old_errorformat
endfunction
function! go#def#SelectStackEntry()
let target_window = go#ui#GetReturnWindow()
if empty(target_window)
let target_window = winnr()
endif
let highlighted_stack_entry = matchstr(getline("."), '^..\zs\(\d\+\)')
if !empty(highlighted_stack_entry)
execute target_window . "wincmd w"
call go#def#StackJump(str2nr(highlighted_stack_entry))
endif
call go#ui#CloseWindow()
endfunction

View file

@ -1,22 +1,6 @@
" Copyright 2011 The Go Authors. All rights reserved.
" Use of this source code is governed by a BSD-style
" license that can be found in the LICENSE file.
"
" godoc.vim: Vim command to see godoc.
"
"
" Commands:
"
" :GoDoc
"
" Open the relevant Godoc for either the word[s] passed to the command or
" the, by default, the word under the cursor.
"
" Options:
"
" g:go_godoc_commands [default=1]
"
" Flag to indicate whether to enable the commands listed above.
let s:buf_nr = -1
@ -33,10 +17,9 @@ endif
" ie: github.com/fatih/set and New
function! s:godocWord(args)
if !executable('godoc')
echohl WarningMsg
echo "godoc command not found."
echo " install with: go get golang.org/x/tools/cmd/godoc"
echohl None
let msg = "godoc command not found."
let msg .= " install with: go get golang.org/x/tools/cmd/godoc"
call go#util#echoWarning(msg)
return []
endif
@ -94,47 +77,24 @@ function! go#doc#OpenBrowser(...)
endfunction
function! go#doc#Open(newmode, mode, ...)
let pkgs = s:godocWord(a:000)
if empty(pkgs)
" check if we have 'gogetdoc' and use it automatically
let bin_path = go#path#CheckBinPath('gogetdoc')
if empty(bin_path)
return
endif
let pkg = pkgs[0]
let exported_name = pkgs[1]
let offset = go#util#OffsetCursor()
let fname = expand("%:p")
let command = g:go_doc_command . ' ' . g:go_doc_options . ' ' . pkg
let command = printf("%s -pos %s:#%s", bin_path, fname, offset)
silent! let content = system(command)
if v:shell_error || s:godocNotFound(content)
echo 'No documentation found for "' . pkg . '".'
return -1
let out = system(command)
if v:shell_error != 0
call go#util#EchoError(out)
return
endif
call s:GodocView(a:newmode, a:mode, content)
if exported_name == ''
silent! normal gg
return -1
endif
" jump to the specified name
if search('^func ' . exported_name . '(')
silent! normal zt
return -1
endif
if search('^type ' . exported_name)
silent! normal zt
return -1
endif
if search('^\%(const\|var\|type\|\s\+\) ' . pkg . '\s\+=\s')
silent! normal zt
return -1
endif
" nothing found, jump to top
silent! normal gg
call s:GodocView(a:newmode, a:mode, out)
endfunction
function! s:GodocView(newposition, position, content)
@ -150,6 +110,15 @@ function! s:GodocView(newposition, position, content)
execute bufwinnr(s:buf_nr) . 'wincmd w'
endif
" cap buffer height to 20, but resize it for smaller contents
let max_height = 20
let content_height = len(split(a:content, "\n"))
if content_height > max_height
exe 'resize ' . max_height
else
exe 'resize ' . content_height
endif
setlocal filetype=godoc
setlocal bufhidden=delete
setlocal buftype=nofile
@ -165,7 +134,10 @@ function! s:GodocView(newposition, position, content)
call append(0, split(a:content, "\n"))
sil $delete _
setlocal nomodifiable
" close easily with <esc> or enter
noremap <buffer> <silent> <CR> :<C-U>close<CR>
noremap <buffer> <silent> <Esc> :<C-U>close<CR>
endfunction
" vim:ts=4:sw=4:et
" vim:ts=2:sw=2:et

View file

@ -52,13 +52,25 @@ endif
" this and have VimL experience, please look at the function for
" improvements, patches are welcome :)
function! go#fmt#Format(withGoimport)
" save cursor position, folds and many other things
if g:go_fmt_experimental == 1
" Using winsaveview to save/restore cursor state has the problem of
" closing folds on save:
" https://github.com/fatih/vim-go/issues/502
" One fix is to use mkview instead. Unfortunately, this sometimes causes
" other bad side effects:
" https://github.com/fatih/vim-go/issues/728
" and still closes all folds if foldlevel>0:
" https://github.com/fatih/vim-go/issues/732
let l:curw = {}
try
mkview!
catch
let l:curw=winsaveview()
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()
@ -101,6 +113,27 @@ function! go#fmt#Format(withGoimport)
let command = command . g:go_fmt_options
endif
if fmt_command == "goimports"
if !exists('b:goimports_vendor_compatible')
let out = system("goimports --help")
if out !~ "-srcdir"
echohl WarningMsg
echomsg "vim-go: goimports does not support srcdir."
echomsg " update with: :GoUpdateBinaries"
echohl None
else
let b:goimports_vendor_compatible = 1
endif
endif
if exists('b:goimports_vendor_compatible') && b:goimports_vendor_compatible
let ssl_save = &shellslash
set noshellslash
let command = command . '-srcdir ' . shellescape(expand("%:p:h"))
let &shellslash = ssl_save
endif
endif
" execute our command...
let out = system(command . " " . l:tmpname)
@ -163,12 +196,17 @@ function! go#fmt#Format(withGoimport)
call delete(tmpundofile)
endif
" restore our cursor/windows positions, folds, etc..
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
endfunction

View file

@ -165,7 +165,7 @@ function! go#import#SwitchImport(enabled, localname, path, bang)
call append(appendline, appendstr)
execute appendline + 1
if indentstr
execute 'normal >>'
execute 'normal! >>'
endif
let linesdelta += 1
endif

View file

@ -2,6 +2,10 @@
" internal function s:spawn
let s:jobs = {}
" s:handlers is a global event handlers for all jobs started with Spawn() or
" with the internal function s:spawn
let s:handlers = {}
" Spawn is a wrapper around s:spawn. It can be executed by other files and
" scripts if needed. Desc defines the description for printing the status
" during the job execution (useful for statusline integration).
@ -36,6 +40,22 @@ function! go#jobcontrol#Statusline() abort
return ''
endfunction
" AddHandler adds a on_exit callback handler and returns the id.
function! go#jobcontrol#AddHandler(handler)
let i = len(s:handlers)
while has_key(s:handlers, string(i))
let i += 1
break
endwhile
let s:handlers[string(i)] = a:handler
return string(i)
endfunction
" RemoveHandler removes a callback handler by id.
function! go#jobcontrol#RemoveHandler(id)
unlet s:handlers[a:id]
endfunction
" spawn spawns a go subcommand with the name and arguments with jobstart. Once
" a job is started a reference will be stored inside s:jobs. spawn changes the
" GOPATH when g:go_autodetect_gopath is enabled. The job is started inside the
@ -95,6 +115,8 @@ endfunction
" it'll be closed.
function! s:on_exit(job_id, exit_status)
let std_combined = self.stderr + self.stdout
call s:callback_handlers_on_exit(s:jobs[a:job_id], a:exit_status, std_combined)
if a:exit_status == 0
call go#list#Clean(0)
call go#list#Window(0)
@ -134,6 +156,17 @@ function! s:on_exit(job_id, exit_status)
endif
endfunction
" callback_handlers_on_exit runs all handlers for job on exit event.
function! s:callback_handlers_on_exit(job, exit_status, data)
if empty(s:handlers)
return
endif
for s:handler in values(s:handlers)
call s:handler(a:job, a:exit_status, a:data)
endfor
endfunction
" on_stdout is the stdout handler for jobstart(). It collects the output of
" stderr and stores them to the jobs internal stdout list.
function! s:on_stdout(job_id, data)

View file

@ -62,15 +62,6 @@ func! s:loclistSecond(output)
call go#list#Window("locationlist", len(errors))
endfun
func! s:getpos(l, c)
if &encoding != 'utf-8'
let buf = a:l == 1 ? '' : (join(getline(1, a:l-1), "\n") . "\n")
let buf .= a:c == 1 ? '' : getline('.')[:a:c-2]
return len(iconv(buf, &encoding, 'utf-8'))
endif
return line2byte(a:l) + (a:c-2)
endfun
func! s:RunOracle(mode, selected, needs_package) range abort
let fname = expand('%:p')
let dname = expand('%:p:h')
@ -102,18 +93,22 @@ func! s:RunOracle(mode, selected, needs_package) range abort
endif
if a:selected != -1
let pos1 = s:getpos(line("'<"), col("'<"))
let pos2 = s:getpos(line("'>"), col("'>"))
let pos1 = go#util#Offset(line("'<"), col("'<"))
let pos2 = go#util#Offset(line("'>"), col("'>"))
let cmd = printf('%s -format plain -pos=%s:#%d,#%d -tags=%s %s',
\ bin_path,
\ shellescape(fname), pos1, pos2, tags, a:mode)
else
let pos = s:getpos(line('.'), col('.'))
let pos = go#util#OffsetCursor()
let cmd = printf('%s -format plain -pos=%s:#%d -tags=%s %s',
\ bin_path,
\ shellescape(fname), pos, tags, a:mode)
endif
" strip trailing slashes for each path in scoped. bug:
" https://github.com/golang/go/issues/14584
let scopes = go#util#StripTrailingSlash(scopes)
" now append each scope to the end as Oracle's scope parameter. It can be
" a packages or go files, dependent on the User's own choice. For more
" info check Oracle's User Manual section about scopes:

View file

@ -144,7 +144,6 @@ function! go#path#CheckBinPath(binpath)
return binpath
endif
" just get the basename
let basename = fnamemodify(binpath, ":t")

View file

@ -31,7 +31,7 @@ function! go#rename#Rename(bang, ...)
endif
let fname = expand('%:p')
let pos = s:getpos(line('.'), col('.'))
let pos = go#util#OffsetCursor()
let cmd = printf('%s -offset %s -to %s', shellescape(bin_path), shellescape(printf('%s:#%d', fname, pos)), shellescape(to))
let out = go#tool#ExecuteInDir(cmd)
@ -65,14 +65,5 @@ function! go#rename#Rename(bang, ...)
silent execute ":e"
endfunction
func! s:getpos(l, c)
if &encoding != 'utf-8'
let buf = a:l == 1 ? '' : (join(getline(1, a:l-1), "\n") . "\n")
let buf .= a:c == 1 ? '' : getline('.')[:a:c-2]
return len(iconv(buf, &encoding, 'utf-8'))
endif
return line2byte(a:l) + (a:c-2)
endfun
" vim:ts=4:sw=4:et
"

View file

@ -92,22 +92,27 @@ function! s:on_stderr(job_id, data)
call extend(job.stderr, a:data)
endfunction
function! s:on_exit(job_id, data)
function! s:on_exit(job_id, exit_status)
if !has_key(s:jobs, a:job_id)
return
endif
let job = s:jobs[a:job_id]
let l:listtype = "locationlist"
" usually there is always output so never branch into this clause
if empty(job.stdout)
call go#list#Clean(l:listtype)
call go#list#Window(l:listtype)
else
unlet s:jobs[a:job_id]
return
endif
let errors = go#tool#ParseErrors(job.stdout)
let errors = go#tool#FilterValids(errors)
if !empty(errors)
" close terminal we don't need it
" close terminal we don't need it anymore
close
call go#list#Populate(l:listtype, errors)
@ -115,12 +120,17 @@ function! s:on_exit(job_id, data)
if !self.bang
call go#list#JumpToFirst(l:listtype)
endif
else
call go#list#Clean(l:listtype)
call go#list#Window(l:listtype)
unlet s:jobs[a:job_id]
return
endif
endif
" tests are passing clean the list and close the list. But we only can
" close them from a normal view, so jump back, close the list and then
" again jump back to the terminal
wincmd p
call go#list#Clean(l:listtype)
call go#list#Window(l:listtype)
wincmd p
unlet s:jobs[a:job_id]
endfunction

View file

@ -2,14 +2,179 @@ if !exists("g:go_textobj_enabled")
let g:go_textobj_enabled = 1
endif
if !exists("g:go_textobj_include_function_doc")
let g:go_textobj_include_function_doc = 1
endif
" ( ) motions
" { } motions
" s for sentence
" p for parapgrah
" < >
" t for tag
function! go#textobj#Function(mode)
if search('^\s*func .*{$', 'Wce', line('.')) <= 0
\ && search('^\s*func .*{$', 'bWce') <= 0
let offset = go#util#OffsetCursor()
let fname = expand("%:p")
if &modified
" Write current unsaved buffer to a temp file and use the modified content
let l:tmpname = tempname()
call writefile(getline(1, '$'), l:tmpname)
let fname = l:tmpname
endif
let bin_path = go#path#CheckBinPath('motion')
if empty(bin_path)
return
endif
if a:mode == 'a'
normal! Va{V
else " a:mode == 'i'
normal! Vi{V
let command = printf("%s -format vim -file %s -offset %s", bin_path, fname, offset)
let command .= " -mode enclosing"
if g:go_textobj_include_function_doc
let command .= " -parse-comments"
endif
let out = system(command)
if v:shell_error != 0
call go#util#EchoError(out)
return
endif
" if exists, delete it as we don't need it anymore
if exists("l:tmpname")
call delete(l:tmpname)
endif
" convert our string dict representation into native Vim dictionary type
let result = eval(out)
if type(result) != 4 || !has_key(result, 'fn')
return
endif
let info = result.fn
if a:mode == 'a'
" anonymous functions doesn't have associated doc. Also check if the user
" want's to include doc comments for function declarations
if has_key(info, 'doc') && g:go_textobj_include_function_doc
call cursor(info.doc.line, info.doc.col)
else
call cursor(info.func.line, info.func.col)
endif
normal! v
call cursor(info.rbrace.line, info.rbrace.col)
return
endif
" rest is inner mode, a:mode == 'i'
" if the function is a one liner we need to select only that portion
if info.lbrace.line == info.rbrace.line
call cursor(info.lbrace.line, info.lbrace.col+1)
normal! v
call cursor(info.rbrace.line, info.rbrace.col-1)
return
endif
call cursor(info.lbrace.line+1, 1)
normal! V
call cursor(info.rbrace.line-1, 1)
endfunction
function! go#textobj#FunctionJump(mode, direction)
" get count of the motion. This should be done before all the normal
" expressions below as those reset this value(because they have zero
" count!). We abstract -1 because the index starts from 0 in motion.
let l:cnt = v:count1 - 1
" set context mark so we can jump back with '' or ``
normal! m'
" select already previously selected visual content and continue from there.
" If it's the first time starts with the visual mode. This is needed so
" after selecting something in visual mode, every consecutive motion
" continues.
if a:mode == 'v'
normal! gv
endif
let offset = go#util#OffsetCursor()
let fname = expand("%:p")
if &modified
" Write current unsaved buffer to a temp file and use the modified content
let l:tmpname = tempname()
call writefile(getline(1, '$'), l:tmpname)
let fname = l:tmpname
endif
let bin_path = go#path#CheckBinPath('motion')
if empty(bin_path)
return
endif
let command = printf("%s -format vim -file %s -offset %s", bin_path, fname, offset)
let command .= ' -shift ' . l:cnt
if a:direction == 'next'
let command .= ' -mode next'
else " 'prev'
let command .= ' -mode prev'
endif
if g:go_textobj_include_function_doc
let command .= " -parse-comments"
endif
let out = system(command)
if v:shell_error != 0
call go#util#EchoError(out)
return
endif
" if exists, delete it as we don't need it anymore
if exists("l:tmpname")
call delete(l:tmpname)
endif
" convert our string dict representation into native Vim dictionary type
let result = eval(out)
if type(result) != 4 || !has_key(result, 'fn')
return
endif
" we reached the end and there are no functions. The usual [[ or ]] jumps to
" the top or bottom, we'll do the same.
if type(result) == 4 && has_key(result, 'err') && result.err == "no functions found"
if a:direction == 'next'
keepjumps normal! G
else " 'prev'
keepjumps normal! gg
endif
return
endif
let info = result.fn
" if we select something ,select all function
if a:mode == 'v' && a:direction == 'next'
keepjumps call cursor(info.rbrace.line, 1)
return
endif
if a:mode == 'v' && a:direction == 'prev'
if has_key(info, 'doc') && g:go_textobj_include_function_doc
keepjumps call cursor(info.doc.line, 1)
else
keepjumps call cursor(info.func.line, 1)
endif
return
endif
keepjumps call cursor(info.func.line, 1)
endfunction
" vim:ts=2:sw=2:et

View file

@ -1,7 +1,12 @@
let s:buf_nr = -1
"OpenWindow opens a new scratch window and put's the content into the window
function! go#ui#OpenWindow(title, content)
function! go#ui#OpenWindow(title, content, filetype)
" Ensure there's only one return window in this session/tabpage
call go#util#Windo("unlet! w:vim_go_return_window")
" Mark the window we're leaving as such
let w:vim_go_return_window = 1
" reuse existing buffer window if it exists otherwise create a new one
if !bufexists(s:buf_nr)
execute 'botright new'
@ -14,24 +19,21 @@ function! go#ui#OpenWindow(title, content)
execute bufwinnr(s:buf_nr) . 'wincmd w'
endif
" Keep minimum height to 10, if there is more just increase it that it
" occupies all results
let buffer_height = 10
if len(a:content) < buffer_height
exe 'resize ' . buffer_height
else
" Resize window to content length
exe 'resize' . len(a:content)
endif
execute "setlocal filetype=".a:filetype
" some sane default values for a readonly buffer
setlocal filetype=vimgo
setlocal bufhidden=delete
setlocal buftype=nofile
setlocal noswapfile
setlocal nobuflisted
setlocal winfixheight
setlocal cursorline " make it easy to distinguish
setlocal nonumber
setlocal norelativenumber
setlocal showbreak=""
" we need this to purge the buffer content
setlocal modifiable
@ -47,13 +49,35 @@ function! go#ui#OpenWindow(title, content)
" set it back to non modifiable
setlocal nomodifiable
" Remove the '... [New File]' message line from the command line
echon
endfunction
function! go#ui#GetReturnWindow()
for l:wn in range(1, winnr("$"))
if !empty(getwinvar(l:wn, "vim_go_return_window"))
return l:wn
endif
endfor
endfunction
" CloseWindow closes the current window
function! go#ui#CloseWindow()
close
echo ""
" Close any window associated with the ui buffer, if it's there
if bufexists(s:buf_nr)
let ui_window_number = bufwinnr(s:buf_nr)
if ui_window_number != -1
execute ui_window_number . 'close'
endif
endif
"return to original window, if it's there
let l:rw = go#ui#GetReturnWindow()
if !empty(l:rw)
execute l:rw . 'wincmd w'
unlet! w:vim_go_return_window
endif
endfunction
" OpenDefinition parses the current line and jumps to it by openening a new

View file

@ -48,6 +48,12 @@ function! go#util#StripPathSep(path)
return a:path
endfunction
" StripTrailingSlash strips the trailing slash from the given path list.
" example: ['/foo/bar/'] -> ['/foo/bar']
function! go#util#StripTrailingSlash(paths)
return map(copy(a:paths), 'go#util#StripPathSep(v:val)')
endfunction
" Shelljoin returns a shell-safe string representation of arglist. The
" {special} argument of shellescape() may optionally be passed.
function! go#util#Shelljoin(arglist, ...)
@ -79,6 +85,34 @@ function! go#util#Shelllist(arglist, ...)
endtry
endfunction
" Returns the byte offset for line and column
function! go#util#Offset(line, col)
if &encoding != 'utf-8'
let sep = go#util#LineEnding()
let buf = a:line == 1 ? '' : (join(getline(1, a:line-1), sep) . sep)
let buf .= a:col == 1 ? '' : getline('.')[:a:col-2]
return len(iconv(buf, &encoding, 'utf-8'))
endif
return line2byte(a:line) + (a:col-2)
endfunction
"
" Returns the byte offset for the cursor
function! go#util#OffsetCursor()
return go#util#Offset(line('.'), col('.'))
endfunction
" Windo is like the built-in :windo, only it returns to the window the command
" was issued from
function! go#util#Windo(command)
let s:currentWindow = winnr()
try
execute "windo " . a:command
finally
execute s:currentWindow. "wincmd w"
unlet s:currentWindow
endtry
endfunction
" TODO(arslan): I couldn't parameterize the highlight types. Check if we can
" simplify the following functions

View file

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

View file

@ -30,13 +30,26 @@ endif
if get(g:, "go_def_mapping_enabled", 1)
nnoremap <buffer> <silent> gd :GoDef<cr>
nnoremap <buffer> <silent> <C-]> :GoDef<cr>
nnoremap <buffer> <silent> <C-t> :<C-U>call go#def#StackPop(v:count1)<cr>
endif
if get(g:, "go_textobj_enabled", 1)
onoremap <buffer> af :<c-u>call go#textobj#Function('a')<cr>
xnoremap <buffer> af :<c-u>call go#textobj#Function('a')<cr>
onoremap <buffer> if :<c-u>call go#textobj#Function('i')<cr>
xnoremap <buffer> if :<c-u>call go#textobj#Function('i')<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>
xnoremap <buffer> <silent> af :<c-u>call go#textobj#Function('a')<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
nnoremap <buffer> <silent> ]] :<c-u>call go#textobj#FunctionJump('n', 'next')<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', 'prev')<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>
endif
if get(g:, "go_auto_type_info", 0)

View file

@ -16,23 +16,28 @@ command! -nargs=? GoOracleTags call go#oracle#Tags(<f-args>)
" tool
command! -nargs=0 GoFiles echo go#tool#Files()
command! -nargs=0 GoDeps echo go#tool#Deps()
command! -nargs=* GoInfo call go#complete#Info()
command! -nargs=* GoInfo call go#complete#Info(0)
" cmd
command! -nargs=* -bang GoBuild call go#cmd#Build(<bang>0,<f-args>)
command! -nargs=* -bang GoGenerate call go#cmd#Generate(<bang>0,<f-args>)
command! -nargs=* -bang GoRun call go#cmd#Run(<bang>0,<f-args>)
command! -nargs=* -bang -complete=file GoRun call go#cmd#Run(<bang>0,<f-args>)
command! -nargs=* -bang GoInstall call go#cmd#Install(<bang>0, <f-args>)
command! -nargs=* -bang GoTest call go#cmd#Test(<bang>0, 0, <f-args>)
command! -nargs=* -bang GoTestFunc call go#cmd#TestFunc(<bang>0, <f-args>)
command! -nargs=* -bang GoTestCompile call go#cmd#Test(<bang>0, 1, <f-args>)
command! -nargs=* -bang GoCoverage call go#cmd#Coverage(<bang>0, <f-args>)
" -- cover
command! -nargs=* -bang GoCoverage call go#coverage#Buffer(<bang>0, <f-args>)
command! -nargs=* -bang GoCoverageBrowser call go#coverage#Browser(<bang>0, <f-args>)
" -- play
command! -nargs=0 -range=% GoPlay call go#play#Share(<count>, <line1>, <line2>)
" -- def
command! -nargs=* -range GoDef :call go#def#Jump(<f-args>)
command! -nargs=? GoDefPop :call go#def#StackPop(<f-args>)
command! -nargs=? GoDefJump :call go#def#StackJump(<f-args>)
" -- doc
command! -nargs=* -range -complete=customlist,go#package#Complete GoDoc call go#doc#Open('new', 'split', <f-args>)
@ -56,4 +61,10 @@ command! -nargs=* -complete=customlist,go#package#Complete GoErrCheck call go#li
" -- alternate
command! -bang GoAlternate call go#alternate#Switch(<bang>0, '')
" -- ctrlp
if globpath(&rtp, 'plugin/ctrlp.vim') != ""
command! -nargs=? -complete=file GoDecls call ctrlp#init(ctrlp#decls#cmd(0, <q-args>))
command! -nargs=? -complete=dir GoDeclsDir call ctrlp#init(ctrlp#decls#cmd(1, <q-args>))
endif
" vim:ts=4:sw=4:et

View file

@ -12,9 +12,9 @@ endif
nnoremap <silent> <Plug>(go-run) :<C-u>call go#cmd#Run(!g:go_jump_to_error)<CR>
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-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-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-tab) :<C-u>call go#cmd#RunTerm(!g:go_jump_to_error, 'tabe', [])<CR>
endif
nnoremap <silent> <Plug>(go-build) :<C-u>call go#cmd#Build(!g:go_jump_to_error)<CR>
@ -23,11 +23,13 @@ nnoremap <silent> <Plug>(go-install) :<C-u>call go#cmd#Install(!g:go_jump_to_err
nnoremap <silent> <Plug>(go-test) :<C-u>call go#cmd#Test(!g:go_jump_to_error, 0)<CR>
nnoremap <silent> <Plug>(go-test-func) :<C-u>call go#cmd#TestFunc(!g:go_jump_to_error)<CR>
nnoremap <silent> <Plug>(go-test-compile) :<C-u>call go#cmd#Test(!g:go_jump_to_error, 1)<CR>
nnoremap <silent> <Plug>(go-coverage) :<C-u>call go#cmd#Coverage(!g:go_jump_to_error)<CR>
nnoremap <silent> <Plug>(go-coverage) :<C-u>call go#coverage#Buffer(!g:go_jump_to_error)<CR>
nnoremap <silent> <Plug>(go-coverage-browser) :<C-u>call go#coverage#Browser(!g:go_jump_to_error)<CR>
nnoremap <silent> <Plug>(go-files) :<C-u>call go#tool#Files()<CR>
nnoremap <silent> <Plug>(go-deps) :<C-u>call go#tool#Deps()<CR>
nnoremap <silent> <Plug>(go-info) :<C-u>call go#complete#Info()<CR>
nnoremap <silent> <Plug>(go-info) :<C-u>call go#complete#Info(0)<CR>
nnoremap <silent> <Plug>(go-import) :<C-u>call go#import#SwitchImport(1, '', expand('<cword>'), '')<CR>
nnoremap <silent> <Plug>(go-implements) :<C-u>call go#oracle#Implements(-1)<CR>

View file

@ -18,6 +18,8 @@ let s:packages = [
\ "github.com/kisielk/errcheck",
\ "github.com/jstemmer/gotags",
\ "github.com/klauspost/asmfmt/cmd/asmfmt",
\ "github.com/fatih/motion",
\ "github.com/zmb3/gogetdoc",
\ ]
" These commands are available on any filetypes
@ -143,7 +145,7 @@ augroup vim-go
" GoInfo automatic update
if get(g:, "go_auto_type_info", 0)
autocmd CursorHold *.go nested call go#complete#Info()
autocmd CursorHold *.go nested call go#complete#Info(1)
endif
" Echo the identifier information when completion is done. Useful to see
@ -166,6 +168,10 @@ augroup vim-go
if get(g:, "go_metalinter_autosave", 0)
autocmd BufWritePost *.go call go#lint#Gometa(1)
endif
" initialize window-local godef stack
au BufReadPre,WinEnter *.go if !exists('w:go_stack') | let w:go_stack = [] | endif
au BufReadPre,WinEnter *.go if !exists('w:go_stack_level') | let w:go_stack_level = 0 | endif
augroup END

View file

@ -27,6 +27,8 @@
" Highlights trailing white space.
" - go_highlight_string_spellcheck
" Specifies that strings should be spell checked
" - go_highlight_format_strings
" Highlights printf-style operators inside string literals.
" Quit when a (custom) syntax file was already loaded
if exists("b:current_syntax")
@ -81,6 +83,14 @@ if !exists("g:go_highlight_string_spellcheck")
let g:go_highlight_string_spellcheck = 1
endif
if !exists("g:go_highlight_format_strings")
let g:go_highlight_format_strings = 1
endif
if !exists("g:go_highlight_generate_tags")
let g:go_highlight_generate_tags = 0
endif
syn case match
syn keyword goDirective package import
@ -132,11 +142,18 @@ hi def link goBoolean Boolean
syn keyword goTodo contained TODO FIXME XXX BUG
syn cluster goCommentGroup contains=goTodo
syn region goComment start="/\*" end="\*/" contains=@goCommentGroup,@Spell
syn region goComment start="//" end="$" contains=@goCommentGroup,@Spell
syn region goComment start="//" end="$" contains=goGenerate,@goCommentGroup,@Spell
hi def link goComment Comment
hi def link goTodo Todo
if g:go_highlight_generate_tags != 0
syn match goGenerateVariables contained /\(\$GOARCH\|\$GOOS\|\$GOFILE\|\$GOLINE\|\$GOPACKAGE\|\$DOLLAR\)\>/
syn region goGenerate start="^\s*//go:generate" end="$" contains=goGenerateVariables
hi def link goGenerate PreProc
hi def link goGenerateVariables Special
endif
" Go escapes
syn match goEscapeOctal display contained "\\[0-7]\{3}"
syn match goEscapeC display contained +\\[abfnrtv\\'"]+
@ -162,11 +179,14 @@ else
syn region goString start=+"+ skip=+\\\\\|\\"+ end=+"+ contains=@goStringGroup
syn region goRawString start=+`+ end=+`+
endif
if g:go_highlight_format_strings != 0
syn match goFormatSpecifier /%[-#0 +]*\%(\*\|\d\+\)\=\%(\.\%(\*\|\d\+\)\)*[vTtbcdoqxXUeEfgGsp]/ contained containedin=goString
hi def link goFormatSpecifier goSpecialString
endif
hi def link goString String
hi def link goRawString String
hi def link goFormatSpecifier goSpecialString
" Characters; their contents
syn cluster goCharacterGroup contains=goEscapeOctal,goEscapeC,goEscapeX,goEscapeU,goEscapeBigU
@ -179,30 +199,31 @@ syn region goBlock start="{" end="}" transparent fold
syn region goParen start='(' end=')' transparent
" Integers
syn match goDecimalInt "\<\d\+\([Ee]\d\+\)\?\>"
syn match goHexadecimalInt "\<0x\x\+\>"
syn match goOctalInt "\<0\o\+\>"
syn match goOctalError "\<0\o*[89]\d*\>"
syn match goDecimalInt "\<-\=\d\+\%([Ee][-+]\=\d\+\)\=\>"
syn match goHexadecimalInt "\<-\=0[xX]\x\+\>"
syn match goOctalInt "\<-\=0\o\+\>"
syn match goOctalError "\<-\=0\o*[89]\d*\>"
hi def link goDecimalInt Integer
hi def link goHexadecimalInt Integer
hi def link goOctalInt Integer
hi def link goOctalError Error
hi def link Integer Number
" Floating point
syn match goFloat "\<\d\+\.\d*\([Ee][-+]\d\+\)\?\>"
syn match goFloat "\<\.\d\+\([Ee][-+]\d\+\)\?\>"
syn match goFloat "\<\d\+[Ee][-+]\d\+\>"
syn match goFloat "\<-\=\d\+\.\d*\%([Ee][-+]\=\d\+\)\=\>"
syn match goFloat "\<-\=\.\d\+\%([Ee][-+]\=\d\+\)\=\>"
hi def link goFloat Float
" Imaginary literals
syn match goImaginary "\<\d\+i\>"
syn match goImaginary "\<\d\+\.\d*\([Ee][-+]\d\+\)\?i\>"
syn match goImaginary "\<\.\d\+\([Ee][-+]\d\+\)\?i\>"
syn match goImaginary "\<\d\+[Ee][-+]\d\+i\>"
syn match goImaginary "\<-\=\d\+i\>"
syn match goImaginary "\<-\=\d\+[Ee][-+]\=\d\+i\>"
syn match goImaginaryFloat "\<-\=\d\+\.\d*\%([Ee][-+]\=\d\+\)\=i\>"
syn match goImaginaryFloat "\<-\=\.\d\+\%([Ee][-+]\=\d\+\)\=i\>"
hi def link goImaginary Number
hi def link goImaginaryFloat Float
" Spaces after "[]"
if g:go_highlight_array_whitespace_error != 0

View file

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

View file

@ -1,47 +0,0 @@
" Copyright 2011 The Go Authors. All rights reserved.
" Use of this source code is governed by a BSD-style
" license that can be found in the LICENSE file.
if exists("b:current_syntax")
finish
endif
syn case match
syn match godocTitle "^\([A-Z][A-Z ]*\)$"
hi def link godocTitle Title
" Single Line Definitions
syn match godocMethodRec /\i\+\ze)/ contained
syn match godocMethodName /) \zs\i\+\ze(/ contained
syn match godocMethod /^func \((\i\+ [^)]*)\) \i\+(/ contains=godocMethodRec,godocMethodName
syn match godocFunction /^func \zs\i\+\ze(/
syn match godocType /^type \zs\i\+\ze.*/
syn match godocVar /^var \zs\i\+\ze.*/
syn match godocConst /^const \zs\i\+\ze.*/
hi def link godocMethodRec Type
hi def link godocType Type
hi def link godocMethodName Function
hi def link godocFunction Function
hi def link godocVar Identifier
hi def link godocConst Identifier
" Definition Blocks
syn region godocComment start="/\*" end="\*/" contained
syn region godocComment start="//" end="$" contained
syn match godocDefinition /^\s\+\i\+/ contained
syn region godocVarBlock start=/^var (/ end=/^)/ contains=godocComment,godocDefinition
syn region godocConstBlock start=/^const (/ end=/^)/ contains=godocComment,godocDefinition
syn region godocTypeBlock start=/^type \i\+ \(interface\|struct\) {/ end=/^}/ matchgroup=godocType contains=godocComment,godocType
hi def link godocComment Comment
hi def link godocDefinition Identifier
syn sync minlines=500
let b:current_syntax = "godoc"
" vim:ts=4 sts=2 sw=2:

View file

@ -66,7 +66,7 @@ syn cluster gotplLiteral contains=goString,goRawString,goCharacter,@goIn
syn keyword gotplControl contained if else end range with template
syn keyword gotplFunctions contained and html index js len not or print printf println urlquery eq ne lt le gt ge
syn match gotplVariable contained /\$[a-zA-Z0-9_]*\>/
syn match goTplIdentifier contained /\.[^\s}]*\>/
syn match goTplIdentifier contained /\.[^\s}]+\>/
hi def link gotplControl Keyword
hi def link gotplFunctions Function

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

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