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

Updated all plugins that are non-forked. Added some new plugins.

Added update_plugins.py which can fetch new plugins from GitHub.

New plugins added: zencoding, vim-indent-object, taglist, nginx.vim
This commit is contained in:
amix 2013-04-13 14:45:21 -03:00
parent 5731b3a420
commit 3f1cdba799
1057 changed files with 33631 additions and 10806 deletions

4
.gitignore vendored Normal file
View file

@ -0,0 +1,4 @@
temp_dirs/undodir*
sources_non_forked/ack.vim/.netrwhist
temp_dirs/yankring_history_v2.txt
my_configs.vim

View file

@ -257,6 +257,10 @@ Bash like keys for the command line:
cnoremap <C-P> <Up>
cnoremap <C-N> <Down>
Write the file as sudo (only on Unix). [Vim tip](http://vim.wikia.com/wiki/Su-write):
:W
### Spell checking
Pressing `<leader>ss` will toggle and untoggle spell checking

View file

@ -0,0 +1,40 @@
YRClear yankring.txt /*YRClear*
YRClear-example yankring.txt /*YRClear-example*
YRDeleteRange yankring.txt /*YRDeleteRange*
YRGetElem yankring.txt /*YRGetElem*
YRGetMultiple yankring.txt /*YRGetMultiple*
YRGetMultiple-example yankring.txt /*YRGetMultiple-example*
YRMapsCreate yankring.txt /*YRMapsCreate*
YRMapsDelete yankring.txt /*YRMapsDelete*
YRPaste yankring.txt /*YRPaste*
YRPop yankring.txt /*YRPop*
YRPop-example yankring.txt /*YRPop-example*
YRPush yankring.txt /*YRPush*
YRPush-example yankring.txt /*YRPush-example*
YRReplace yankring.txt /*YRReplace*
YRReplace-example yankring.txt /*YRReplace-example*
YRSearch yankring.txt /*YRSearch*
YRSearch-example yankring.txt /*YRSearch-example*
YRShow yankring.txt /*YRShow*
YRShow-example yankring.txt /*YRShow-example*
YRToggle yankring.txt /*YRToggle*
YRYankCount yankring.txt /*YRYankCount*
YRYankRange yankring.txt /*YRYankRange*
YRYankRange-example yankring.txt /*YRYankRange-example*
any-item-example yankring.txt /*any-item-example*
global-example yankring.txt /*global-example*
multiple-items-example yankring.txt /*multiple-items-example*
yankring yankring.txt /*yankring*
yankring-commands yankring.txt /*yankring-commands*
yankring-configure yankring.txt /*yankring-configure*
yankring-contents yankring.txt /*yankring-contents*
yankring-custom-maps yankring.txt /*yankring-custom-maps*
yankring-description yankring.txt /*yankring-description*
yankring-globals yankring.txt /*yankring-globals*
yankring-history yankring.txt /*yankring-history*
yankring-mappings yankring.txt /*yankring-mappings*
yankring-tutorial yankring.txt /*yankring-tutorial*
yankring-visual-example yankring.txt /*yankring-visual-example*
yankring-window yankring.txt /*yankring-window*
yankring-window-example yankring.txt /*yankring-window-example*
yankring.txt yankring.txt /*yankring.txt*

1
sources_forked/zencoding/.gitignore vendored Executable file
View file

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

4
sources_forked/zencoding/.gitmodules vendored Executable file
View file

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

View file

@ -0,0 +1,11 @@
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

@ -0,0 +1,103 @@
# 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>

0
sources_forked/zencoding/TODO Executable file
View file

212
sources_forked/zencoding/TUTORIAL Executable file
View file

@ -0,0 +1,212 @@
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

@ -0,0 +1,11 @@
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

@ -0,0 +1,228 @@
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

@ -0,0 +1,310 @@
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

@ -0,0 +1,692 @@
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

@ -0,0 +1,158 @@
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

@ -0,0 +1,121 @@
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

@ -0,0 +1,276 @@
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

@ -0,0 +1,249 @@
"==============================================================================
" 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

@ -0,0 +1,438 @@
*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

@ -0,0 +1,215 @@
"=============================================================================
" 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

@ -0,0 +1,794 @@
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

@ -0,0 +1,265 @@
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

@ -18,9 +18,13 @@ Install on Debian / Ubuntu with:
sudo apt-get install ack-grep
For Debian / Ubuntu you can add this line into your .vimrc:
Install on Fedora with:
let g:ackprg="ack-grep -H --nocolor --nogroup --column"
su -l -c 'yum install ack'
Install on openSUSE with:
sudo zypper install ack
Install on Gentoo with:
@ -34,10 +38,18 @@ Install with MacPorts:
sudo port install p5-app-ack
Install with Gentoo Prefix
Install with Gentoo Prefix:
emerge ack
Install on FreeBSD with:
cd /usr/ports/textproc/p5-ack/ && make install clean
You can specify a custom ack name and path in your .vimrc like so:
let g:ackprg="<custom-ack-path-goes-here> -H --nocolor --nogroup --column"
Otherwise, you are on your own.
### The Plugin
@ -75,6 +87,10 @@ Just like where you use :grep, :grepadd, :lgrep, and :lgrepadd, you can use `:Ac
See ack --help=types for a list of valid types.
### Gotchas ###
Some characters have special meaning, and need to be escaped your search pattern. For instance, '#'. You have to escape it like this `:Ack '\\\#define foo'` to search for `#define foo`. (From [blueyed in issue #5](https://github.com/mileszs/ack.vim/issues/5).)
### Keyboard Shortcuts ###
In the quickfix window, you can use:
@ -83,6 +99,8 @@ In the quickfix window, you can use:
go to preview file (open but maintain focus on ack.vim results)
t to open in new tab
T to open in new tab silently
h to open in horizontal split
H to open in horizontal split silently
v to open in vertical split
gv to open in vertical split silently
q to close the quickfix window

View file

@ -43,6 +43,16 @@ shows the results in a split window.
directory) for filenames matching the {pattern}. Behaves just like the
|:grep| command, but will open the |Quickfix| window for you.
:AckHelp[!] [options] {pattern} *:AckHelp*
Search vim documentation files for the {pattern}. Behaves just like the
|:Ack| command, but searches only vim documentation .txt files
:LAckHelp [options] {pattern} *:LAckHelp*
Just like |:AckHelp| but instead of the |quickfix| list, matches are placed
in the current |location-list|.
Files containing the search term will be listed in the split window, along
with the line number of the occurrence, once for each occurrence. <Enter> on
a line in this window will open the file, and place the cursor on the matching
@ -63,6 +73,10 @@ t open in a new tab.
T open in new tab silently.
h open in horizontal split.
H open in horizontal split silently.
v open in vertical split.
gv open in vertical split silently.

View file

@ -2,74 +2,112 @@
" in your path.
" On Debian / Ubuntu:
" sudo apt-get install ack-grep
" On your vimrc:
" let g:ackprg="ack-grep -H --nocolor --nogroup --column"
"
" With MacPorts:
" sudo port install p5-app-ack
" With Homebrew:
" brew install ack
" Location of the ack utility
if !exists("g:ackprg")
let g:ackprg="ack -H --nocolor --nogroup --column"
let s:ackcommand = executable('ack-grep') ? 'ack-grep' : 'ack'
let g:ackprg=s:ackcommand." -H --nocolor --nogroup --column"
endif
if !exists("g:ack_apply_qmappings")
let g:ack_apply_qmappings = !exists("g:ack_qhandler")
endif
if !exists("g:ack_apply_lmappings")
let g:ack_apply_lmappings = !exists("g:ack_lhandler")
endif
if !exists("g:ack_qhandler")
let g:ack_qhandler="botright copen"
endif
if !exists("g:ack_lhandler")
let g:ack_lhandler="botright lopen"
endif
function! s:Ack(cmd, args)
redraw
echo "Searching ..."
redraw
echo "Searching ..."
" If no pattern is provided, search for the word under the cursor
if empty(a:args)
let l:grepargs = expand("<cword>")
else
let l:grepargs = a:args
end
" If no pattern is provided, search for the word under the cursor
if empty(a:args)
let l:grepargs = expand("<cword>")
else
let l:grepargs = a:args . join(a:000, ' ')
end
" Format, used to manage column jump
if a:cmd =~# '-g$'
let g:ackformat="%f"
else
let g:ackformat="%f:%l:%c:%m"
end
" Format, used to manage column jump
if a:cmd =~# '-g$'
let g:ackformat="%f"
else
let g:ackformat="%f:%l:%c:%m"
end
let grepprg_bak=&grepprg
let grepformat_bak=&grepformat
try
let &grepprg=g:ackprg
let &grepformat=g:ackformat
silent execute a:cmd . " " . l:grepargs
finally
let &grepprg=grepprg_bak
let &grepformat=grepformat_bak
endtry
let grepprg_bak=&grepprg
let grepformat_bak=&grepformat
try
let &grepprg=g:ackprg
let &grepformat=g:ackformat
silent execute a:cmd . " " . escape(l:grepargs, '|')
finally
let &grepprg=grepprg_bak
let &grepformat=grepformat_bak
endtry
if a:cmd =~# '^l'
botright lopen
else
botright copen
endif
if a:cmd =~# '^l'
exe g:ack_lhandler
let l:apply_mappings = g:ack_apply_lmappings
else
exe g:ack_qhandler
let l:apply_mappings = g:ack_apply_qmappings
endif
if l:apply_mappings
exec "nnoremap <silent> <buffer> q :ccl<CR>"
exec "nnoremap <silent> <buffer> t <C-W><CR><C-W>T"
exec "nnoremap <silent> <buffer> T <C-W><CR><C-W>TgT<C-W><C-W>"
exec "nnoremap <silent> <buffer> o <CR>"
exec "nnoremap <silent> <buffer> go <CR><C-W><C-W>"
exec "nnoremap <silent> <buffer> v <C-W><C-W><C-W>v<C-L><C-W><C-J><CR>"
exec "nnoremap <silent> <buffer> gv <C-W><C-W><C-W>v<C-L><C-W><C-J><CR><C-W><C-J>"
exec "nnoremap <silent> <buffer> h <C-W><CR><C-W>K"
exec "nnoremap <silent> <buffer> H <C-W><CR><C-W>K<C-W>b"
exec "nnoremap <silent> <buffer> v <C-W><CR><C-W>H<C-W>b<C-W>J<C-W>t"
exec "nnoremap <silent> <buffer> gv <C-W><CR><C-W>H<C-W>b<C-W>J"
endif
" If highlighting is on, highlight the search keyword.
if exists("g:ackhighlight")
let @/=a:args
set hlsearch
end
" If highlighting is on, highlight the search keyword.
if exists("g:ackhighlight")
let @/=a:args
set hlsearch
end
redraw!
redraw!
endfunction
function! s:AckFromSearch(cmd, args)
let search = getreg('/')
" translate vim regular expression to perl regular expression.
let search = substitute(search,'\(\\<\|\\>\)','\\b','g')
call s:Ack(a:cmd, '"' . search .'" '. a:args)
let search = getreg('/')
" translate vim regular expression to perl regular expression.
let search = substitute(search,'\(\\<\|\\>\)','\\b','g')
call s:Ack(a:cmd, '"' . search .'" '. a:args)
endfunction
function! s:GetDocLocations()
let dp = ''
for p in split(&rtp,',')
let p = p.'/doc/'
if isdirectory(p)
let dp = p.'*.txt '.dp
endif
endfor
return dp
endfunction
function! s:AckHelp(cmd,args)
let args = a:args.' '.s:GetDocLocations()
call s:Ack(a:cmd,args)
endfunction
command! -bang -nargs=* -complete=file Ack call s:Ack('grep<bang>',<q-args>)
@ -78,3 +116,5 @@ command! -bang -nargs=* -complete=file AckFromSearch call s:AckFromSearch('grep<
command! -bang -nargs=* -complete=file LAck call s:Ack('lgrep<bang>', <q-args>)
command! -bang -nargs=* -complete=file LAckAdd call s:Ack('lgrepadd<bang>', <q-args>)
command! -bang -nargs=* -complete=file AckFile call s:Ack('grep<bang> -g', <q-args>)
command! -bang -nargs=* -complete=help AckHelp call s:AckHelp('grep<bang>',<q-args>)
command! -bang -nargs=* -complete=help LAckHelp call s:AckHelp('lgrep<bang>',<q-args>)

View file

@ -1,20 +0,0 @@
This is a mirror of http://www.vim.org/scripts/script.php?script_id=42
With bufexplorer, you can quickly and easily switch between buffers by using the one of the default public interfaces:
'\be' (normal open) or
'\bs' (force horizontal split open) or
'\bv' (force vertical split open)
Once the bufexplorer window is open you can use the normal movement keys (hjkl) to move around and then use <Enter> or <Left-Mouse-Click> to select the buffer you would like to open. If you would like to have the selected buffer opened in a new tab, simply press either <Shift-Enter> or 't'. Please note that when opening a buffer in a tab, that if the buffer is already in another tab, bufexplorer can switch to that tab automatically for you if you would like. More about that in the supplied VIM help.
Bufexplorer also offers various options including:
- Display the list of buffers in various sort orders including:
- Most Recently Used (MRU) which is the default
- Buffer number
- File name
- File extension
- Full file path name
- Delete buffer from list
For more about options, sort orders, configuration options, etc. please see the supplied VIM help.

View file

@ -0,0 +1,39 @@
created by
---------
[jeff lanzarotta](http://www.vim.org/account/profile.php?user_id=97)
script type
----------
utility
description
-----------
With bufexplorer, you can quickly and easily switch between buffers by using the one of the default public interfaces:
'\be' (normal open) or
'\bs' (force horizontal split open) or
'\bv' (force vertical split open)
Once the bufexplorer window is open you can use the normal movement keys (hjkl) to move around and then use <Enter> or <Left-Mouse-Click> to select the buffer you would like to open. If you would like to have the selected buffer opened in a new tab, simply press either <Shift-Enter> or 't'. Please note that when opening a buffer in a tab, that if the buffer is already in another tab, bufexplorer can switch to that tab automatically for you if you would like. More about that in the supplied VIM help.
Bufexplorer also offers various options including:
* Display the list of buffers in various sort orders including:
* Most Recently Used (MRU) which is the default
* Buffer number
* File name
* File extension
* Full file path name
* Delete buffer from list
For more about options, sort orders, configuration options, etc. please see the supplied VIM help.
install details
---------------
Simply unzip bufexplorer.zip into a directory in your 'runtimepath', usually ~/.vim or c:\vimfiles, and restart Vim. This zip file contains plugin\bufexplorer.vim, and doc\bufexplorer.txt. See ':help add-local-help' on how to add bufexplorer.txt to vim's help system.
NOTE
----
Version 7.0.12 and above will ONLY work with 7.0 and above of Vim.
**IMPORTANT**: If you have a version prior to 7.1.2 that contains an autoload\bufexplorer.vim file, please REMOVE the autoload\bufexlorer.vim AND the plugin\bufexplorer.vim files before installing a new version.

View file

@ -1,4 +1,4 @@
*bufexplorer.txt* Buffer Explorer Last Change: 16 Feb 2010
*bufexplorer.txt* Buffer Explorer Last Change: 22 Oct 2010
Buffer Explorer *buffer-explorer* *bufexplorer*
Version 7.2.8

View file

@ -0,0 +1,24 @@
bufexplorer bufexplorer.txt /*bufexplorer*
bufexplorer-changelog bufexplorer.txt /*bufexplorer-changelog*
bufexplorer-credits bufexplorer.txt /*bufexplorer-credits*
bufexplorer-customization bufexplorer.txt /*bufexplorer-customization*
bufexplorer-installation bufexplorer.txt /*bufexplorer-installation*
bufexplorer-todo bufexplorer.txt /*bufexplorer-todo*
bufexplorer-usage bufexplorer.txt /*bufexplorer-usage*
bufexplorer-windowlayout bufexplorer.txt /*bufexplorer-windowlayout*
bufexplorer.txt bufexplorer.txt /*bufexplorer.txt*
buffer-explorer bufexplorer.txt /*buffer-explorer*
g:bufExplorerChgWin bufexplorer.txt /*g:bufExplorerChgWin*
g:bufExplorerDefaultHelp bufexplorer.txt /*g:bufExplorerDefaultHelp*
g:bufExplorerDetailedHelp bufexplorer.txt /*g:bufExplorerDetailedHelp*
g:bufExplorerFindActive bufexplorer.txt /*g:bufExplorerFindActive*
g:bufExplorerFuncRef bufexplorer.txt /*g:bufExplorerFuncRef*
g:bufExplorerReverseSort bufexplorer.txt /*g:bufExplorerReverseSort*
g:bufExplorerShowDirectories bufexplorer.txt /*g:bufExplorerShowDirectories*
g:bufExplorerShowRelativePath bufexplorer.txt /*g:bufExplorerShowRelativePath*
g:bufExplorerShowTabBuffer bufexplorer.txt /*g:bufExplorerShowTabBuffer*
g:bufExplorerShowUnlisted bufexplorer.txt /*g:bufExplorerShowUnlisted*
g:bufExplorerSortBy bufexplorer.txt /*g:bufExplorerSortBy*
g:bufExplorerSplitBelow bufexplorer.txt /*g:bufExplorerSplitBelow*
g:bufExplorerSplitOutPathName bufexplorer.txt /*g:bufExplorerSplitOutPathName*
g:bufExplorerSplitRight bufexplorer.txt /*g:bufExplorerSplitRight*

View file

@ -10,7 +10,7 @@
" Name Of File: bufexplorer.vim
" Description: Buffer Explorer Vim Plugin
" Maintainer: Jeff Lanzarotta (delux256-vim at yahoo dot com)
" Last Changed: Tuesday, 16 Feb 2010
" Last Changed: Friday, 22 October 2010
" Version: See g:bufexplorer_version for version number.
" Usage: This file should reside in the plugin directory and be
" automatically sourced.

File diff suppressed because it is too large Load diff

View file

@ -149,13 +149,16 @@ fu! s:esctagscmd(bin, args, ...)
if exists('+ssl')
let [ssl, &ssl] = [&ssl, 0]
en
let fname = a:0 == 1 ? shellescape(a:1) : ''
let fname = a:0 ? shellescape(a:1) : ''
let cmd = shellescape(a:bin).' '.a:args.' '.fname
if &sh =~ 'cmd\.exe'
let cmd = substitute(cmd, '[&()@^<>|]', '^\0', 'g')
en
if exists('+ssl')
let &ssl = ssl
en
if has('iconv')
let last = s:enc != &enc ? s:enc : !empty($LANG) ? $LANG : &enc
let last = s:enc != &enc ? s:enc : !empty( $LANG ) ? $LANG : &enc
let cmd = iconv(cmd, &enc, last)
en
retu cmd
@ -170,12 +173,14 @@ fu! s:process(fname, ftype)
el
let data = s:exectagsonfile(a:fname, a:ftype)
let [raw, lines] = [split(data, '\n\+'), []]
for line in raw | if len(split(line, ';"')) == 2
let parsed_line = s:parseline(line)
if parsed_line != ''
cal add(lines, parsed_line)
for line in raw
if line !~# '^!_TAG_' && len(split(line, ';"')) == 2
let parsed_line = s:parseline(line)
if parsed_line != ''
cal add(lines, parsed_line)
en
en
en | endfo
endfo
let cache = { a:fname : { 'time': ftime, 'lines': lines } }
cal extend(g:ctrlp_buftags, cache)
en
@ -183,8 +188,8 @@ fu! s:process(fname, ftype)
endf
fu! s:parseline(line)
let eval = '\v^([^\t]+)\t(.+)\t\/\^(.+)\$\/\;\"\t(.+)\tline(no)?\:(\d+)'
let vals = matchlist(a:line, eval)
let vals = matchlist(a:line,
\ '\v^([^\t]+)\t(.+)\t[?/]\^?(.{-1,})\$?[?/]\;\"\t(.+)\tline(no)?\:(\d+)')
if vals == [] | retu '' | en
let [bufnr, bufname] = [bufnr('^'.vals[2].'$'), fnamemodify(vals[2], ':p:t')]
retu vals[1].' '.vals[4].'|'.bufnr.':'.bufname.'|'.vals[6].'| '.vals[3]
@ -200,6 +205,19 @@ fu! s:syntax()
sy match CtrlPTabExtra '\zs\t.*\ze$' contains=CtrlPBufName,CtrlPTagKind
en
endf
fu! s:chknearby(pat)
if match(getline('.'), a:pat) < 0
let [int, forw, maxl] = [1, 1, line('$')]
wh !search(a:pat, 'W'.( forw ? '' : 'b' ))
if !forw
if int > maxl | brea | en
let int += int
en
let forw = !forw
endw
en
endf
" Public {{{1
fu! ctrlp#buffertag#init(fname)
let bufs = exists('s:btmode') && s:btmode
@ -208,7 +226,7 @@ fu! ctrlp#buffertag#init(fname)
let lines = []
for each in bufs
let bname = fnamemodify(each, ':p')
let tftype = get(split(getbufvar(bname, '&ft'), '\.'), 0, '')
let tftype = get(split(getbufvar('^'.bname.'$', '&ft'), '\.'), 0, '')
cal extend(lines, s:process(bname, tftype))
endfo
cal s:syntax()
@ -216,10 +234,14 @@ fu! ctrlp#buffertag#init(fname)
endf
fu! ctrlp#buffertag#accept(mode, str)
let vals = matchlist(a:str, '\v^[^\t]+\t+[^\t|]+\|(\d+)\:[^\t|]+\|(\d+)\|')
let vals = matchlist(a:str,
\ '\v^[^\t]+\t+[^\t|]+\|(\d+)\:[^\t|]+\|(\d+)\|\s(.+)$')
let bufnr = str2nr(get(vals, 1))
if bufnr
cal ctrlp#acceptfile(a:mode, bufname(bufnr), get(vals, 2))
cal ctrlp#acceptfile(a:mode, bufnr)
exe 'norm!' str2nr(get(vals, 2, line('.'))).'G'
cal s:chknearby('\V\C'.get(vals, 3, ''))
sil! norm! zvzz
en
endf

View file

@ -59,7 +59,8 @@ fu! ctrlp#changes#init(original_bufnr, bufnr)
let [swb, &swb] = [&swb, '']
let lines = []
for each in bufs
let fnamet = fnamemodify(bufname(each), ':t')
let bname = bufname(each)
let fnamet = fnamemodify(bname == '' ? '[No Name]' : bname, ':t')
cal extend(lines, s:process(s:changelist(each), each, fnamet))
endfo
sil! exe 'noa hid b' a:original_bufnr
@ -73,7 +74,7 @@ fu! ctrlp#changes#accept(mode, str)
let info = matchlist(a:str, '\t|\(\d\+\):[^|]\+|\(\d\+\):\(\d\+\)|$')
let bufnr = str2nr(get(info, 1))
if bufnr
cal ctrlp#acceptfile(a:mode, bufname(bufnr))
cal ctrlp#acceptfile(a:mode, bufnr)
cal cursor(get(info, 2), get(info, 3))
sil! norm! zvzz
en

View file

@ -32,12 +32,13 @@ fu! s:globdirs(dirs, depth)
let nr = len(g:ctrlp_alldirs)
if !empty(dirs) && !s:max(nr, s:maxfiles) && depth <= s:maxdepth
sil! cal ctrlp#progress(nr)
cal map(dirs, 'ctrlp#utils#fnesc(v:val, "g", ",")')
cal s:globdirs(join(dirs, ','), depth)
en
endf
fu! s:max(len, max)
retu a:max && a:len > a:max ? 1 : 0
retu a:max && a:len > a:max
endf
fu! s:nocache()
@ -53,7 +54,9 @@ fu! ctrlp#dir#init(...)
let cafile = cadir.ctrlp#utils#lash().ctrlp#utils#cachefile('dir')
if g:ctrlp_newdir || s:nocache() || !filereadable(cafile)
let [s:initcwd, g:ctrlp_alldirs] = [s:cwd, []]
cal s:globdirs(s:cwd, 0)
if !ctrlp#igncwd(s:cwd)
cal s:globdirs(ctrlp#utils#fnesc(s:cwd, 'g', ','), 0)
en
cal ctrlp#rmbasedir(g:ctrlp_alldirs)
if len(g:ctrlp_alldirs) <= s:compare_lim
cal sort(g:ctrlp_alldirs, 'ctrlp#complen')

View file

@ -33,9 +33,12 @@ fu! ctrlp#line#init()
let [bufs, lines] = [ctrlp#buffers('id'), []]
for bufnr in bufs
let [lfb, bufn] = [getbufline(bufnr, 1, '$'), bufname(bufnr)]
let lfb = lfb == [] ? ctrlp#utils#readfile(fnamemodify(bufn, ':p')) : lfb
if lfb == [] && bufn != ''
let lfb = ctrlp#utils#readfile(fnamemodify(bufn, ':p'))
en
cal map(lfb, 'tr(v:val, '' '', '' '')')
let [linenr, len_lfb, buft] = [1, len(lfb), fnamemodify(bufn, ':t')]
let [linenr, len_lfb] = [1, len(lfb)]
let buft = bufn == '' ? '[No Name]' : fnamemodify(bufn, ':t')
wh linenr <= len_lfb
let lfb[linenr - 1] .= ' |'.buft.'|'.bufnr.':'.linenr.'|'
let linenr += 1
@ -50,7 +53,7 @@ fu! ctrlp#line#accept(mode, str)
let info = matchlist(a:str, '\t|[^|]\+|\(\d\+\):\(\d\+\)|$')
let bufnr = str2nr(get(info, 1))
if bufnr
cal ctrlp#acceptfile(a:mode, bufname(bufnr), get(info, 2))
cal ctrlp#acceptfile(a:mode, bufnr, get(info, 2))
en
endf

View file

@ -41,7 +41,11 @@ fu! s:getnewmix(cwd, clim)
if exists('+ssl') && &ssl
cal map(mrufs, 'tr(v:val, "\\", "/")')
en
let bufs = map(ctrlp#buffers('id'), 'fnamemodify(bufname(v:val), ":p")')
let allbufs = map(ctrlp#buffers(), 'fnamemodify(v:val, ":p")')
let [bufs, ubufs] = [[], []]
for each in allbufs
cal add(filereadable(each) ? bufs : ubufs, each)
endfo
let mrufs = bufs + filter(mrufs, 'index(bufs, v:val) < 0')
if len(mrufs) > len(g:ctrlp_lines)
cal filter(mrufs, 'stridx(v:val, a:cwd)')
@ -53,6 +57,7 @@ fu! s:getnewmix(cwd, clim)
if id >= 0 | cal remove(g:ctrlp_lines, id) | en
endfo
en
let mrufs += ubufs
cal map(mrufs, 'fnamemodify(v:val, ":.")')
let g:ctrlp_lines = len(mrufs) > len(g:ctrlp_lines)
\ ? g:ctrlp_lines + mrufs : mrufs + g:ctrlp_lines

View file

@ -14,6 +14,7 @@ fu! ctrlp#mrufiles#opts()
\ 'exclude': ['s:ex', ''],
\ 'case_sensitive': ['s:cseno', 1],
\ 'relative': ['s:re', 0],
\ 'save_on_update': ['s:soup', 1],
\ }]
for [ke, va] in items(opts)
let [{va[0]}, {pref.ke}] = [pref.ke, exists(pref.ke) ? {pref.ke} : va[1]]
@ -37,29 +38,47 @@ fu! s:chop(mrufs)
retu a:mrufs
endf
fu! s:reformat(mrufs)
fu! s:reformat(mrufs, ...)
let cwd = getcwd()
let cwd .= cwd !~ '[\/]$' ? ctrlp#utils#lash() : ''
if {s:re}
let cwd = exists('+ssl') ? tr(getcwd(), '/', '\') : getcwd()
let cwd = exists('+ssl') ? tr(cwd, '/', '\') : cwd
cal filter(a:mrufs, '!stridx(v:val, cwd)')
en
retu map(a:mrufs, 'fnamemodify(v:val, ":.")')
if a:0 && a:1 == 'raw' | retu a:mrufs | en
let idx = strlen(cwd)
if exists('+ssl') && &ssl
let cwd = tr(cwd, '\', '/')
cal map(a:mrufs, 'tr(v:val, "\\", "/")')
en
retu map(a:mrufs, '!stridx(v:val, cwd) ? strpart(v:val, idx) : v:val')
endf
fu! s:record(bufnr)
if s:locked | retu | en
let bufnr = a:bufnr + 0
if bufnr <= 0 | retu | en
let bufname = bufname(bufnr)
if empty(bufname) | retu | en
let fn = fnamemodify(bufname, ':p')
let fn = exists('+ssl') ? tr(fn, '/', '\') : fn
cal filter(s:mrbs, 'v:val != bufnr')
cal insert(s:mrbs, bufnr)
if ( !empty({s:in}) && fn !~# {s:in} ) || ( !empty({s:ex}) && fn =~# {s:ex} )
\ || !empty(&bt) || !filereadable(fn) | retu
if bufnr > 0 && !empty(bufname)
cal filter(s:mrbs, 'v:val != bufnr')
cal insert(s:mrbs, bufnr)
cal s:addtomrufs(bufname)
en
endf
fu! s:addtomrufs(fname)
let fn = fnamemodify(a:fname, ':p')
let fn = exists('+ssl') ? tr(fn, '/', '\') : fn
if ( !empty({s:in}) && fn !~# {s:in} ) || ( !empty({s:ex}) && fn =~# {s:ex} )
\ || !empty(getbufvar('^'.fn.'$', '&bt')) || !filereadable(fn) | retu
en
let idx = index(s:mrufs, fn, 0, !{s:cseno})
if idx
cal filter(s:mrufs, 'v:val !='.( {s:cseno} ? '#' : '?' ).' fn')
cal insert(s:mrufs, fn)
if {s:soup} && idx < 0
cal s:savetofile(s:mergelists())
en
en
cal filter(s:mrufs, 'v:val !='.( {s:cseno} ? '#' : '?' ).' fn')
cal insert(s:mrufs, fn)
endf
fu! s:savetofile(mrufs)
@ -67,28 +86,40 @@ fu! s:savetofile(mrufs)
endf
" Public {{{1
fu! ctrlp#mrufiles#refresh(...)
let s:mrufs = s:mergelists()
cal filter(s:mrufs, '!empty(ctrlp#utils#glob(v:val, 1)) && !s:excl(v:val)')
let mrufs = s:mergelists()
cal filter(mrufs, '!empty(ctrlp#utils#glob(v:val, 1)) && !s:excl(v:val)')
if exists('+ssl')
cal map(mrufs, 'tr(v:val, "/", "\\")')
cal map(s:mrufs, 'tr(v:val, "/", "\\")')
cal filter(s:mrufs, 'count(s:mrufs, v:val) == 1')
let cond = 'count(mrufs, v:val, !{s:cseno}) == 1'
cal filter(mrufs, cond)
cal filter(s:mrufs, cond)
en
cal s:savetofile(s:mrufs)
retu a:0 && a:1 == 'raw' ? [] : s:reformat(copy(s:mrufs))
cal s:savetofile(mrufs)
retu a:0 && a:1 == 'raw' ? [] : s:reformat(mrufs)
endf
fu! ctrlp#mrufiles#remove(files)
let s:mrufs = []
let mrufs = []
if a:files != []
let s:mrufs = s:mergelists()
cal filter(s:mrufs, 'index(a:files, v:val, 0, '.(!{s:cseno}).') < 0')
let mrufs = s:mergelists()
let cond = 'index(a:files, v:val, 0, !{s:cseno}) < 0'
cal filter(mrufs, cond)
cal filter(s:mrufs, cond)
en
cal s:savetofile(mrufs)
retu s:reformat(mrufs)
endf
fu! ctrlp#mrufiles#add(fn)
if !empty(a:fn)
cal s:addtomrufs(a:fn)
en
cal s:savetofile(s:mrufs)
retu s:reformat(copy(s:mrufs))
endf
fu! ctrlp#mrufiles#list(...)
retu a:0 ? a:1 == 'raw' ? s:mergelists() : 0 : s:reformat(s:mergelists())
retu a:0 ? a:1 == 'raw' ? s:reformat(s:mergelists(), a:1) : 0
\ : s:reformat(s:mergelists())
endf
fu! ctrlp#mrufiles#bufs()
@ -108,7 +139,7 @@ fu! ctrlp#mrufiles#init()
let s:locked = 0
aug CtrlPMRUF
au!
au BufAdd,BufEnter,BufLeave,BufUnload * cal s:record(expand('<abuf>', 1))
au BufAdd,BufEnter,BufLeave,BufWritePost * cal s:record(expand('<abuf>', 1))
au QuickFixCmdPre *vimgrep* let s:locked = 1
au QuickFixCmdPost *vimgrep* let s:locked = 0
au VimLeavePre * cal s:savetofile(s:mergelists())

View file

@ -40,18 +40,15 @@ fu! ctrlp#quickfix#init()
endf
fu! ctrlp#quickfix#accept(mode, str)
let items = matchlist(a:str, '^\([^|]\+\ze\)|\(\d\+\):\(\d\+\)|')
if items == [] | retu | en
let [md, filpath] = [a:mode, fnamemodify(items[1], ':p')]
if empty(filpath) | retu | en
cal ctrlp#exit()
let cmd = md == 't' ? 'tabe' : md == 'h' ? 'new' : md == 'v' ? 'vne'
\ : ctrlp#normcmd('e')
let cmd = cmd == 'e' && &modified ? 'hid e' : cmd
exe cmd ctrlp#fnesc(filpath)
cal cursor(items[2], items[3])
let vals = matchlist(a:str, '^\([^|]\+\ze\)|\(\d\+\):\(\d\+\)|')
if vals == [] || vals[1] == '' | retu | en
cal ctrlp#acceptfile(a:mode, vals[1])
let cur_pos = getpos('.')[1:2]
if cur_pos != [1, 1] && cur_pos != map(vals[2:3], 'str2nr(v:val)')
mark '
en
cal cursor(vals[2], vals[3])
sil! norm! zvzz
cal ctrlp#setlcdir()
endf
fu! ctrlp#quickfix#id()

View file

@ -24,23 +24,26 @@ let s:id = g:ctrlp_builtins + len(g:ctrlp_ext_vars)
let s:filecounts = {}
" Utilities {{{1
fu! s:nocache()
retu !s:caching || ( s:caching > 1 && get(s:filecounts, s:cwd) < s:caching )
retu g:ctrlp_newrts ||
\ !s:caching || ( s:caching > 1 && get(s:filecounts, s:cwd) < s:caching )
endf
" Public {{{1
fu! ctrlp#rtscript#init(caching)
let [s:caching, s:cwd] = [a:caching, getcwd()]
if g:ctrlp_newrts || s:nocache()
\ || !( exists('g:ctrlp_rtscache') && g:ctrlp_rtscache[0] == &rtp )
if s:nocache() ||
\ !( exists('g:ctrlp_rtscache') && g:ctrlp_rtscache[0] == &rtp )
sil! cal ctrlp#progress('Indexing...')
let entries = split(globpath(&rtp, '**/*.*'), "\n")
let entries = split(globpath(ctrlp#utils#fnesc(&rtp, 'g'), '**/*.*'), "\n")
cal filter(entries, 'count(entries, v:val) == 1')
let [entries, echoed] = [ctrlp#dirnfile(entries)[1], 1]
el
let [entries, results] = g:ctrlp_rtscache[2:3]
en
if g:ctrlp_newrts || s:nocache()
\ || !( exists('g:ctrlp_rtscache') && g:ctrlp_rtscache[:1] == [&rtp, s:cwd] )
if !exists('echoed') | sil! cal ctrlp#progress('Processing...') | en
if s:nocache() ||
\ !( exists('g:ctrlp_rtscache') && g:ctrlp_rtscache[:1] == [&rtp, s:cwd] )
if !exists('echoed')
sil! cal ctrlp#progress('Processing...')
en
let results = map(copy(entries), 'fnamemodify(v:val, '':.'')')
en
let [g:ctrlp_rtscache, g:ctrlp_newrts] = [[&rtp, s:cwd, entries, results], 0]

View file

@ -54,11 +54,11 @@ fu! s:filter(tags)
let nr = 0
wh 0 < 1
if a:tags == [] | brea | en
if a:tags[nr] =~ '^!' && a:tags[nr] !~ '^!_TAG_'
if a:tags[nr] =~ '^!' && a:tags[nr] !~# '^!_TAG_'
let nr += 1
con
en
if a:tags[nr] =~ '^!_TAG_' && len(a:tags) > nr
if a:tags[nr] =~# '^!_TAG_' && len(a:tags) > nr
cal remove(a:tags, nr)
el
brea
@ -97,15 +97,19 @@ fu! ctrlp#tag#accept(mode, str)
\ 'e': ['', 'tj'],
\ }
let cmd = fnd[0] == 1 ? cmds[a:mode][0] : cmds[a:mode][1]
let cmd = cmd == 'tj' && &mod ? 'hid '.cmd : cmd
let cmd = a:mode == 'e' && ctrlp#modfilecond(!&aw)
\ ? ( cmd == 'tj' ? 'stj' : 'sp' ) : cmd
let cmd = a:mode == 't' ? ctrlp#tabcount().cmd : cmd
if fnd[0] == 1
if cmd != ''
exe cmd
en
exe fnd[1].'ta' tg
let save_cst = &cst
set cst&
cal feedkeys(":".fnd[1]."ta ".tg."\r", 'nt')
let &cst = save_cst
el
exe cmd tg
cal feedkeys(":".cmd." ".tg."\r", 'nt')
en
cal ctrlp#setlcdir()
endf

View file

@ -8,25 +8,28 @@
fu! ctrlp#utils#lash()
retu &ssl || !exists('+ssl') ? '/' : '\'
endf
let s:lash = ctrlp#utils#lash()
fu! s:lash(...)
retu ( a:0 ? a:1 : getcwd() ) !~ '[\/]$' ? s:lash : ''
endf
fu! ctrlp#utils#opts()
let usrhome = $HOME.s:lash($HOME)
let s:lash = ctrlp#utils#lash()
let usrhome = $HOME . s:lash( $HOME )
let cahome = exists('$XDG_CACHE_HOME') ? $XDG_CACHE_HOME : usrhome.'.cache'
let s:cache_dir = isdirectory(usrhome.'.ctrlp_cache')
let cadir = isdirectory(usrhome.'.ctrlp_cache')
\ ? usrhome.'.ctrlp_cache' : cahome.s:lash(cahome).'ctrlp'
if exists('g:ctrlp_cache_dir')
let s:cache_dir = expand(g:ctrlp_cache_dir, 1)
if isdirectory(s:cache_dir.s:lash(s:cache_dir).'.ctrlp_cache')
let s:cache_dir = s:cache_dir.s:lash(s:cache_dir).'.ctrlp_cache'
let cadir = expand(g:ctrlp_cache_dir, 1)
if isdirectory(cadir.s:lash(cadir).'.ctrlp_cache')
let cadir = cadir.s:lash(cadir).'.ctrlp_cache'
en
en
let s:cache_dir = cadir
endf
cal ctrlp#utils#opts()
let s:wig_cond = v:version > 702 || ( v:version == 702 && has('patch051') )
" Files and Directories {{{1
fu! ctrlp#utils#cachedir()
retu s:cache_dir
@ -64,8 +67,43 @@ fu! ctrlp#utils#writecache(lines, ...)
endf
fu! ctrlp#utils#glob(...)
let cond = v:version > 702 || ( v:version == 702 && has('patch051') )
retu call('glob', cond ? a:000 : [a:1])
let path = ctrlp#utils#fnesc(a:1, 'g')
retu s:wig_cond ? glob(path, a:2) : glob(path)
endf
fu! ctrlp#utils#globpath(...)
retu call('globpath', s:wig_cond ? a:000 : a:000[:1])
endf
fu! ctrlp#utils#fnesc(path, type, ...)
if exists('*fnameescape')
if exists('+ssl')
if a:type == 'c'
let path = escape(a:path, '%#')
elsei a:type == 'f'
let path = fnameescape(a:path)
elsei a:type == 'g'
let path = escape(a:path, '?*')
en
let path = substitute(path, '[', '[[]', 'g')
el
let path = fnameescape(a:path)
en
el
if exists('+ssl')
if a:type == 'c'
let path = escape(a:path, '%#')
elsei a:type == 'f'
let path = escape(a:path, " \t\n%#*?|<\"")
elsei a:type == 'g'
let path = escape(a:path, '?*')
en
let path = substitute(path, '[', '[[]', 'g')
el
let path = escape(a:path, " \t\n*?[{`$\\%#'\"|!<")
en
en
retu a:0 ? escape(path, a:1) : path
endf
"}}}

View file

@ -1,4 +1,4 @@
*ctrlp.txt* Fuzzy file, buffer, mru, tag, ... finder. v1.78
*ctrlp.txt* Fuzzy file, buffer, mru, tag, ... finder. v1.79
*CtrlP* *ControlP* *'ctrlp'* *'ctrl-p'*
===============================================================================
# #
@ -35,50 +35,53 @@ OPTIONS *ctrlp-options*
Overview:~
|loaded_ctrlp| Disable the plugin.
|ctrlp_map| Default mapping.
|ctrlp_cmd| Default command used for the default mapping.
|ctrlp_by_filename| Default to filename mode or not.
|ctrlp_regexp| Default to regexp mode or not.
|ctrlp_match_window_bottom| Where to show the match window.
|ctrlp_match_window_reversed| Sort order in the match window.
|ctrlp_max_height| Max height of the match window.
|ctrlp_switch_buffer| Jump to an open buffer if already opened.
|ctrlp_reuse_window| Reuse special windows (help, quickfix, etc).
|ctrlp_tabpage_position| Where to put the new tab page.
|ctrlp_working_path_mode| How to set CtrlP's local working directory.
|ctrlp_root_markers| Additional, high priority root markers.
|ctrlp_use_caching| Use per-session caching or not.
|ctrlp_clear_cache_on_exit| Keep cache after exiting Vim or not.
|ctrlp_cache_dir| Location of the cache directory.
|ctrlp_dotfiles| Ignore dotfiles and dotdirs or not.
|ctrlp_custom_ignore| Hide stuff when using |globpath()|.
|ctrlp_max_files| Number of files to scan initially.
|ctrlp_max_depth| Directory depth to recurse into when scanning.
|ctrlp_user_command| Use an external scanner.
|ctrlp_max_history| Number of entries saved in the prompt history.
|ctrlp_open_new_file| How to open a file created by <c-y>.
|ctrlp_open_multiple_files| How to open files selected by <c-z>.
|ctrlp_arg_map| Intercept <c-y> and <c-o> or not.
|ctrlp_follow_symlinks| Follow symbolic links or not.
|ctrlp_lazy_update| Only update when typing has stopped.
|ctrlp_default_input| Seed the prompt with an initial string.
|ctrlp_use_migemo| Use Migemo patterns for Japanese filenames.
|ctrlp_prompt_mappings| Change the mappings in the prompt.
|loaded_ctrlp|................Disable the plugin.
|ctrlp_map|...................Default mapping.
|ctrlp_cmd|...................Default command used for the default mapping.
|ctrlp_by_filename|...........Default to filename mode or not.
|ctrlp_regexp|................Default to regexp mode or not.
|ctrlp_match_window_bottom|...Where to show the match window.
|ctrlp_match_window_reversed|.Sort order in the match window.
|ctrlp_max_height|............Max height of the match window.
|ctrlp_switch_buffer|.........Jump to an open buffer if already opened.
|ctrlp_reuse_window|..........Reuse special windows (help, quickfix, etc).
|ctrlp_tabpage_position|......Where to put the new tab page.
|ctrlp_working_path_mode|.....How to set CtrlP's local working directory.
|ctrlp_root_markers|..........Additional, high priority root markers.
|ctrlp_use_caching|...........Use per-session caching or not.
|ctrlp_clear_cache_on_exit|...Keep cache after exiting Vim or not.
|ctrlp_cache_dir|.............Location of the cache directory.
|ctrlp_show_hidden|...........Ignore dotfiles and dotdirs or not.
|ctrlp_custom_ignore|.........Hide stuff when using |globpath()|.
|ctrlp_max_files|.............Number of files to scan initially.
|ctrlp_max_depth|.............Directory depth to recurse into when scanning.
|ctrlp_user_command|..........Use an external scanner.
|ctrlp_max_history|...........Number of entries saved in the prompt history.
|ctrlp_open_new_file|.........How to open a file created by <c-y>.
|ctrlp_open_multiple_files|...How to open files selected by <c-z>.
|ctrlp_arg_map|...............Intercept <c-y> and <c-o> or not.
|ctrlp_follow_symlinks|.......Follow symbolic links or not.
|ctrlp_lazy_update|...........Only update when typing has stopped.
|ctrlp_default_input|.........Seed the prompt with an initial string.
|ctrlp_abbrev|................Input abbreviations.
|ctrlp_key_loop|..............Use input looping for multi-byte input.
|ctrlp_use_migemo|............Use Migemo patterns for Japanese filenames.
|ctrlp_prompt_mappings|.......Change the mappings inside the prompt.
MRU mode:
|ctrlp_mruf_max| Max MRU entries to remember.
|ctrlp_mruf_exclude| Files that shouldn't be remembered.
|ctrlp_mruf_include| Files to be remembered.
|ctrlp_mruf_relative| Show only MRU files in the working directory.
|ctrlp_mruf_default_order| Disable sorting.
|ctrlp_mruf_case_sensitive| MRU files are case sensitive or not.
|ctrlp_mruf_max|..............Max MRU entries to remember.
|ctrlp_mruf_exclude|..........Files that shouldn't be remembered.
|ctrlp_mruf_include|..........Files to be remembered.
|ctrlp_mruf_relative|.........Show only MRU files in the working directory.
|ctrlp_mruf_default_order|....Disable sorting.
|ctrlp_mruf_case_sensitive|...MRU files are case sensitive or not.
|ctrlp_mruf_save_on_update|...Save to disk whenever a new entry is added.
Advanced options:
|ctrlp_open_func| Use custom file opening functions.
|ctrlp_status_func| Change CtrlP's two statuslines.
|ctrlp_buffer_func| Call custom functions in the CtrlP buffer.
|ctrlp_match_func| Replace the built-in matching algorithm.
|ctrlp_open_func|.............Use custom file opening functions.
|ctrlp_status_func|...........Change CtrlP's two statuslines.
|ctrlp_buffer_func|...........Call custom functions in the CtrlP buffer.
|ctrlp_match_func|............Replace the built-in matching algorithm.
-------------------------------------------------------------------------------
Detailed descriptions and default values:~
@ -128,13 +131,16 @@ Set the maximum height of the match window: >
<
*'g:ctrlp_switch_buffer'*
When opening a file with <cr> or <c-t>, if the file's already opened somewhere
CtrlP will try to jump to it instead of opening a new instance: >
let g:ctrlp_switch_buffer = 2
When opening a file, if it's already open in a window somewhere, CtrlP will try
to jump to it instead of opening a new instance: >
let g:ctrlp_switch_buffer = 'Et'
<
1 - only jump to the buffer if it's opened in the current tab.
2 - jump tab as well if the buffer's opened in another tab.
0 - disable this feature.
e - jump when <cr> is pressed, but only to windows in the current tab.
t - jump when <c-t> is pressed, but only to windows in another tab.
v - like "e", but jump when <c-v> is pressed.
h - like "e", but jump when <c-x> is pressed.
E, T, V, H - like "e", "t", "v", and "h", but jump to windows anywhere.
0 or <empty> - disable this feature.
*'g:ctrlp_reuse_window'*
When opening a file with <cr>, CtrlP avoids opening it in windows created by
@ -160,24 +166,29 @@ Where to put the new tab page when opening one: >
*'g:ctrlp_working_path_mode'*
When starting up, CtrlP sets its local working directory according to this
variable: >
let g:ctrlp_working_path_mode = 'rc'
let g:ctrlp_working_path_mode = 'ra'
<
c - the directory of the current file.
a - like "c", but only applies when the current working directory outside of
CtrlP isn't a direct ancestor of the directory of the current file.
r - the nearest ancestor that contains one of these directories or files:
.git .hg .svn .bzr _darcs
{empty-string} - don't manage working directory.
w - begin finding a root from the current working directory outside of CtrlP
instead of from the directory of the current file (default). Only applies
when "r" is also present.
0 or <empty> - disable this feature.
Note #1: you can use b:ctrlp_working_path_mode (a |b:var|) to set this option
on a per buffer basis.
Note #1: if "a" or "c" is included with "r", use the behavior of "a" or "c" (as
a fallback) when a root can't be found.
Note #2: with both 'r' and 'c' in the option, when a root isn't found, use the
directory of the current file.
Note #2: you can use a |b:var| to set this option on a per buffer basis.
*'g:ctrlp_root_markers'*
Use this to set your own root markers in addition to the default ones (.git,
.hg, .svn, .bzr, and _darcs). Your markers will take precedence: >
let g:ctrlp_root_markers = ['']
<
Note: you can use a |b:var| to set this option on a per buffer basis.
*'g:ctrlp_use_caching'*
Enable/Disable per-session caching: >
@ -187,6 +198,7 @@ Enable/Disable per-session caching: >
1 - Enable caching.
n - When bigger than 1, disable caching and use the number as the limit to
enable caching again.
Note: you can quickly purge the cache by pressing <F5> while inside CtrlP.
*'g:ctrlp_clear_cache_on_exit'*
@ -200,18 +212,20 @@ Set the directory to store the cache files: >
let g:ctrlp_cache_dir = $HOME.'/.cache/ctrlp'
<
*'g:ctrlp_dotfiles'*
Set this to 0 if you don't want CtrlP to scan for dotfiles and dotdirs: >
let g:ctrlp_dotfiles = 1
*'g:ctrlp_show_hidden'*
Set this to 1 if you want CtrlP to scan for dotfiles and dotdirs: >
let g:ctrlp_show_hidden = 0
<
Note: does not apply when a command defined with |g:ctrlp_user_command| is
being used.
*'ctrlp-wildignore'*
You can use Vim's |'wildignore'| to exclude files and directories from the
results.
Examples: >
" Excluding version control directories
set wildignore+=*/.git/*,*/.hg/*,*/.svn/* " Linux/MacOSX
set wildignore+=.git\*,.hg\*,.svn\* " Windows
set wildignore+=*/.git/*,*/.hg/*,*/.svn/* " Linux/MacOSX
set wildignore+=*\\.git\\*,*\\.hg\\*,*\\.svn\\* " Windows ('noshellslash')
<
Note #1: the `*/` in front of each directory glob is required.
@ -226,25 +240,36 @@ CtrlP to not show. Use regexp to specify the patterns: >
let g:ctrlp_custom_ignore = ''
<
Examples: >
let g:ctrlp_custom_ignore = '\.git$\|\.hg$\|\.svn$'
let g:ctrlp_custom_ignore = '\v[\/]\.(git|hg|svn)$'
let g:ctrlp_custom_ignore = {
\ 'dir': '\.git$\|\.hg$\|\.svn$',
\ 'file': '\.exe$\|\.so$\|\.dll$',
\ 'dir': '\v[\/]\.(git|hg|svn)$',
\ 'file': '\v\.(exe|so|dll)$',
\ 'link': 'SOME_BAD_SYMBOLIC_LINKS',
\ }
let g:ctrlp_custom_ignore = {
\ 'file': '\v(\.cpp|\.h|\.hh|\.cxx)@<!$'
\ }
<
Note: ignoring only applies when |globpath()| is used to scan for files.
Note #1: by default, |wildignore| and |g:ctrlp_custom_ignore| only apply when
|globpath()| is used to scan for files, thus these options do not apply when a
command defined with |g:ctrlp_user_command| is being used.
Note #2: when changing the option's variable type, remember to |:unlet| it
first or restart Vim to avoid the "E706: Variable type mismatch" error.
*'g:ctrlp_max_files'*
The maximum number of files to scan, set to 0 for no limit: >
let g:ctrlp_max_files = 10000
<
Note: does not apply when a command defined with |g:ctrlp_user_command| is
being used.
*'g:ctrlp_max_depth'*
The maximum depth of a directory tree to recurse into: >
let g:ctrlp_max_depth = 40
<
Note: the larger these values, the more memory Vim uses.
Note: does not apply when a command defined with |g:ctrlp_user_command| is
being used.
*'g:ctrlp_user_command'*
Specify an external tool to use for listing files instead of using Vim's
@ -257,8 +282,10 @@ Examples: >
<
You can also use 'grep', 'findstr' or something else to filter the results.
Examples: >
let g:ctrlp_user_command = 'find %s -type f | grep (?!tmp/.*)'
let g:ctrlp_user_command = 'dir %s /-n /b /s /a-d | findstr .*\.py$'
let g:ctrlp_user_command =
\ 'find %s -type f | grep -v -P "\.jpg$|/tmp/"' " MacOSX/Linux
let g:ctrlp_user_command =
\ 'dir %s /-n /b /s /a-d | findstr /v /l ".jpg \\tmp\\"' " Windows
<
Use a version control listing command when inside a repository, this is faster
when scanning large projects: >
@ -268,12 +295,16 @@ when scanning large projects: >
\ 1: [root_marker_1, listing_command_1],
\ n: [root_marker_n, listing_command_n],
\ },
\ 'fallback': fallback_command
\ 'fallback': fallback_command,
\ 'ignore': 0 or 1
\ }
<
Examples: >
Some examples: >
" Single VCS, listing command does not list untracked files:
let g:ctrlp_user_command = ['.git', 'cd %s && git ls-files']
let g:ctrlp_user_command = ['.hg', 'hg --cwd %s locate -I .']
" Multiple VCS's:
let g:ctrlp_user_command = {
\ 'types': {
\ 1: ['.git', 'cd %s && git ls-files'],
@ -281,9 +312,29 @@ Examples: >
\ },
\ 'fallback': 'find %s -type f'
\ }
" Single VCS, listing command lists untracked files (slower):
let g:ctrlp_user_command =
\ ['.git', 'cd %s && git ls-files . -co --exclude-standard']
let g:ctrlp_user_command =
\ ['.hg', 'hg --cwd %s status -numac -I . $(hg root)'] " MacOSX/Linux
let g:ctrlp_user_command = ['.hg', 'for /f "tokens=1" %%a in (''hg root'') '
\ . 'do hg --cwd %s status -numac -I . %%a'] " Windows
<
If the fallback_command is empty or not defined, |globpath()| will then be used
when searching outside a repo.
Note #1: if the fallback_command is empty or the 'fallback' key is not defined,
|globpath()| will then be used when scanning outside of a repository.
Note #2: unless the |Dictionary| format is used and 'ignore' is defined and set
to 1, the |wildignore| and |g:ctrlp_custom_ignore| options do not apply when
these custom commands are being used. When not present, 'ignore' is set to 0 by
default to retain the performance advantage of using external commands.
Note #3: when changing the option's variable type, remember to |:unlet| it
first or restart Vim to avoid the "E706: Variable type mismatch" error.
Note #4: you can use a |b:var| to set this option on a per buffer basis.
*'g:ctrlp_max_history'*
The maximum number of input strings you want CtrlP to remember. The default
@ -294,14 +345,13 @@ Set to 0 to disable prompt's history. Browse the history with <c-n> and <c-p>.
*'g:ctrlp_open_new_file'*
Use this option to specify how the newly created file is to be opened when
pressing <c-y>:
t - in a new tab
h - in a new horizontal split
v - in a new vertical split
r - in the current window
>
pressing <c-y>: >
let g:ctrlp_open_new_file = 'v'
<
t - in a new tab.
h - in a new horizontal split.
v - in a new vertical split.
r - in the current window.
*'g:ctrlp_open_multiple_files'*
If non-zero, this will enable opening multiple files with <c-z> and <c-o>: >
@ -322,7 +372,8 @@ For the letters:
i - all files as hidden buffers.
j - after opening, jump to the first opened tab or window.
r - open the first file in the current window, then the remaining files in
new splits or new tabs depending on which of h, v and t is also present.
new splits or new tabs depending on which of "h", "v" and "t" is also
present.
*'g:ctrlp_arg_map'*
When this is set to 1, the <c-o> and <c-y> mappings will accept one extra key
@ -348,6 +399,9 @@ If non-zero, CtrlP will follow symbolic links when listing files: >
1 - follow but ignore looped internal symlinks to avoid duplicates.
2 - follow all symlinks indiscriminately.
Note: does not apply when a command defined with |g:ctrlp_user_command| is
being used.
*'g:ctrlp_lazy_update'*
Set this to 1 to enable the lazy-update feature: only update the match window
after typing's been stopped for a certain amount of time: >
@ -366,6 +420,68 @@ as the default input: >
let g:ctrlp_default_input = 'anystring'
<
*'g:ctrlp_abbrev'*
Define input abbreviations that can be expanded (either internally or visibly)
in the prompt: >
let g:ctrlp_abbrev = {}
<
Examples: >
let g:ctrlp_abbrev = {
\ 'gmode': 'i',
\ 'abbrevs': [
\ {
\ 'pattern': '^cd b',
\ 'expanded': '@cd ~/.vim/bundle',
\ 'mode': 'pfrz',
\ },
\ {
\ 'pattern': '\(^@.\+\|\\\@<!:.\+\)\@<! ',
\ 'expanded': '.\{-}',
\ 'mode': 'pfr',
\ },
\ {
\ 'pattern': '\\\@<!:.\+\zs\\\@<! ',
\ 'expanded': '\ ',
\ 'mode': 'pfz',
\ },
\ ]
\ }
<
The 'pattern' string is regexp matched against the entered input. The expansion
is as if the 'expanded' string was typed into the prompt.
For 'gmode' (optional):
i - expand internally (default).
t - insert the expanded results into the prompt as you type.
k - insert the expanded results when a non-keyword character is typed. Only
applies when "t" is also present.
For 'mode' (of each entry; optional):
f - only in filename mode.
p - only in full path mode.
r - only in regexp mode.
z - only in fuzzy mode.
n - only when creating a new file with <c-y> (use the expanded string in the
new filename).
c - only when auto-completing directory names with <tab> (expand the pattern
immediately before doing the auto-completion).
<empty> or not defined - always enable.
Note: the abbrev entries are evaluated in sequence, so a later entry can be
evaluated against the expanded result of a previous entry; this includes itself
when 'gmode' is "t".
*'g:ctrlp_key_loop'*
An experimental feature. Set this to 1 to enable input looping for the typing
of multi-byte characters: >
let g:ctrlp_key_loop = 0
<
Note #1: when set, this option resets the |g:ctrlp_lazy_update| option.
Note #2: you can toggle this feature inside the prompt with a custom mapping: >
let g:ctrlp_prompt_mappings = { 'ToggleKeyLoop()': ['<F3>'] }
<
*'g:ctrlp_use_migemo'*
Set this to 1 to use Migemo Pattern for Japanese filenames. Migemo Search only
works in regexp mode. To split the pattern, separate words with space: >
@ -412,9 +528,8 @@ only need to keep the lines that you've changed the values (inside []): >
\ 'PrtExit()': ['<esc>', '<c-c>', '<c-g>'],
\ }
<
Note: In some terminals, it's not possible to remap <c-h> without also changing
<bs> (|keycodes|). So if pressing <bs> moves the cursor to the left instead of
deleting a char for you, add this to your |.vimrc| to disable the plugin's
Note: if pressing <bs> moves the cursor one character to the left instead of
deleting a character for you, add this to your |.vimrc| to disable the plugin's
default <c-h> mapping: >
let g:ctrlp_prompt_mappings = { 'PrtCurLeft()': ['<left>', '<c-^>'] }
<
@ -460,6 +575,12 @@ MRU entries: >
let g:ctrlp_mruf_case_sensitive = 1
<
*'g:ctrlp_mruf_save_on_update'*
Set this to 0 to disable saving of the MRU list to hard drive whenever a new
entry is added, saving will then only occur when exiting Vim: >
let g:ctrlp_mruf_save_on_update = 1
<
----------------------------------------
Advanced options:~
@ -634,12 +755,13 @@ COMMANDS *ctrlp-commands*
Open CtrlP in find Most-Recently-Used file mode.
*:CtrlPLastMode*
:CtrlPLastMode
Open CtrlP in the last mode used.
:CtrlPLastMode [--dir]
Open CtrlP in the last mode used. When having the "--dir" argument, also
reuse the last working directory.
*:CtrlPRoot*
:CtrlPRoot
This acts like |:CtrlP| with |g:ctrlp_working_path_mode| = 'rc' and ignores
This acts like |:CtrlP| with |g:ctrlp_working_path_mode| = 'r' and ignores
the variable's current value.
*:CtrlPClearCache*
@ -768,7 +890,22 @@ Opening multiple files:~
- Mark/unmark a file to create a new file in its directory using <c-y>.
<c-o>
Open files marked by <c-z>.
- Open files marked by <c-z>.
- When no file has been marked by <c-z>, open a console dialog with the
following options:
Open the selected file:
t - in a tab page.
v - in a vertical split.
h - in a horizontal split.
r - in the current window.
i - as a hidden buffer.
x - (optional) with the function defined in |g:ctrlp_open_func|.
Other options (not shown):
a - mark all files in the match window.
d - change CtrlP's local working directory to the selected file's
directory and switch to find file mode.
Function keys:~
@ -891,7 +1028,7 @@ Available extensions:~
*:CtrlPTag*
* Tag mode:~
- Name: 'tag'
- Command: ':CtrlPTag'
- Command: ":CtrlPTag"
- Search for a tag within a generated central tags file, and jump to the
definition. Use the Vim's option |'tags'| to specify the names and the
locations of the tags file(s).
@ -901,21 +1038,21 @@ Available extensions:~
*:CtrlPBufTagAll*
* Buffer Tag mode:~
- Name: 'buffertag'
- Commands: ':CtrlPBufTag [buffer]',
':CtrlPBufTagAll'.
- Commands: ":CtrlPBufTag [buffer]",
":CtrlPBufTagAll".
- Search for a tag within the current buffer or all listed buffers and jump
to the definition. Requires |exuberant_ctags| or compatible programs.
*:CtrlPQuickfix*
* Quickfix mode:~
- Name: 'quickfix'
- Command: ':CtrlPQuickfix'
- Command: ":CtrlPQuickfix"
- Search for an entry in the current quickfix errors and jump to it.
*:CtrlPDir*
* Directory mode:~
- Name: 'dir'
- Command: ':CtrlPDir [starting-directory]'
- Command: ":CtrlPDir [starting-directory]"
- Search for a directory and change the working directory to it.
- Mappings:
+ <cr> change the local working directory for CtrlP and keep it open.
@ -927,42 +1064,42 @@ Available extensions:~
*:CtrlPRTS*
* Runtime script mode:~
- Name: 'rtscript'
- Command: ':CtrlPRTS'
- Command: ":CtrlPRTS"
- Search for files (vimscripts, docs, snippets...) in runtimepath.
*:CtrlPUndo*
* Undo mode:~
- Name: 'undo'
- Command: ':CtrlPUndo'
- Command: ":CtrlPUndo"
- Browse undo history.
*:CtrlPLine*
* Line mode:~
- Name: 'line'
- Command: ':CtrlPLine'
- Command: ":CtrlPLine"
- Search for a line in all listed buffers.
*:CtrlPChange*
*:CtrlPChangeAll*
* Change list mode:~
- Name: 'changes'
- Commands: ':CtrlPChange [buffer]',
':CtrlPChangeAll'.
- Commands: ":CtrlPChange [buffer]",
":CtrlPChangeAll".
- Search for and jump to a recent change in the current buffer or in all
listed buffers.
*:CtrlPMixed*
* Mixed mode:~
- Name: 'mixed'
- Command: ':CtrlPMixed'
- Command: ":CtrlPMixed"
- Search in files, buffers and MRU files at the same time.
*:CtrlPBookmarkDir*
*:CtrlPBookmarkDirAdd*
* BookmarkDir mode:~
- Name: 'bookmarkdir'
- Commands: ':CtrlPBookmarkDir',
':CtrlPBookmarkDirAdd [directory]'.
- Commands: ":CtrlPBookmarkDir",
":CtrlPBookmarkDirAdd [directory]".
- Search for a bookmarked directory and change the working directory to it.
- Mappings:
+ <cr> change the local working directory for CtrlP, keep it open and
@ -1027,8 +1164,8 @@ Highlighting:~
Statuslines:~
* Highlight groups:
CtrlPMode1 : 'prt' or 'win', also for 'regex' (Character)
CtrlPMode2 : 'file' or 'path', also for the local working dir (|hl-LineNr|)
CtrlPMode1 : 'file' or 'path', and the current mode (Character)
CtrlPMode2 : 'prt' or 'win', 'regex', the working directory (|hl-LineNr|)
CtrlPStats : the scanning status (Function)
For rebuilding the statuslines, see |g:ctrlp_status_func|.
@ -1083,7 +1220,7 @@ MISCELLANEOUS CONFIGS *ctrlp-miscellaneous-configs*
===============================================================================
CREDITS *ctrlp-credits*
Developed by Kien Nguyen <github.com/kien>.
Developed by Kien Nguyen <github.com/kien>. Distributed under Vim's |license|.
Project's homepage: http://kien.github.com/ctrlp.vim
Git repository: https://github.com/kien/ctrlp.vim
@ -1109,12 +1246,25 @@ Special thanks:~
* Luca Pette <github.com/lucapette>
* Seth Fowler <github.com/sfowler>
* Lowe Thiderman <github.com/thiderman>
* Christopher Fredén <github.com/icetan>
* Zahary Karadjov <github.com/zah>
* Jo De Boeck <github.com/grimpy>
===============================================================================
CHANGELOG *ctrlp-changelog*
+ New options: |g:ctrlp_open_func|.
|g:ctrlp_tabpage_position|.
Before 2012/11/30~
+ New options: |g:ctrlp_abbrev|,
|g:ctrlp_key_loop|,
|g:ctrlp_open_func|,
|g:ctrlp_tabpage_position|,
|g:ctrlp_mruf_save_on_update|
+ Rename:
*g:ctrlp_dotfiles* -> |g:ctrlp_show_hidden|.
+ Change |g:ctrlp_switch_buffer|'s and |g:ctrlp_working_path_mode|'s type
(old values still work).
+ New key for |g:ctrlp_user_command| when it's a Dictionary: 'ignore'.
Before 2012/06/15~

View file

@ -21,19 +21,17 @@ com! -n=? -com=dir CtrlP cal ctrlp#init(0, { 'dir': <q-args> })
com! -n=? -com=dir CtrlPMRUFiles cal ctrlp#init(2, { 'dir': <q-args> })
com! -bar CtrlPBuffer cal ctrlp#init(1)
com! -bar CtrlPLastMode cal ctrlp#init(-1)
com! -n=? CtrlPLastMode cal ctrlp#init(-1, { 'args': <q-args> })
com! -bar CtrlPClearCache cal ctrlp#clr()
com! -bar CtrlPClearAllCaches cal ctrlp#clra()
com! -bar CtrlPReload cal ctrlp#reset()
com! -bar ClearCtrlPCache cal ctrlp#clr()
com! -bar ClearAllCtrlPCaches cal ctrlp#clra()
com! -bar ResetCtrlP cal ctrlp#reset()
com! -bar CtrlPCurWD cal ctrlp#init(0, { 'mode': '' })
com! -bar CtrlPCurFile cal ctrlp#init(0, { 'mode': 'c' })
com! -bar CtrlPRoot cal ctrlp#init(0, { 'mode': 'rc' })
com! -bar CtrlPRoot cal ctrlp#init(0, { 'mode': 'r' })
if g:ctrlp_map != '' && !hasmapto(':<c-u>'.g:ctrlp_cmd.'<cr>', 'n')
exe 'nn <silent>' g:ctrlp_map ':<c-u>'.g:ctrlp_cmd.'<cr>'
@ -64,3 +62,5 @@ com! -bar CtrlPBookmarkDir cal ctrlp#init(ctrlp#bookmarkdir#id())
com! -n=? -com=dir CtrlPBookmarkDirAdd
\ cal ctrlp#call('ctrlp#bookmarkdir#add', <q-args>)
" vim:ts=2:sw=2:sts=2

View file

@ -23,6 +23,8 @@ Check `:help ctrlp-commands` and `:help ctrlp-extensions` for other commands.
* Press `<c-f>` and `<c-b>` to cycle between modes.
* Press `<c-d>` to switch to filename only search instead of full path.
* Press `<c-r>` to switch to regexp mode.
* Use `<c-j>`, `<c-k>` or the arrow keys to navigate the result list.
* Use `<c-t>` or `<c-v>`, `<c-x>` to open the selected entry in a new tab or in a new split.
* Use `<c-n>`, `<c-p>` to select the next/previous string in the prompt's history.
* Use `<c-y>` to create a new file and its parent directories.
* Use `<c-z>` to mark/unmark multiple files and `<c-o>` to open them.
@ -32,8 +34,7 @@ Run `:help ctrlp-mappings` or submit `?` in CtrlP for more mapping help.
* Submit two or more dots `..` to go up the directory tree by one or multiple levels.
* End the input string with a colon `:` followed by a command to execute it on the opening file(s):
Use `:25` to jump to line 25.
Use `:/any\:\ string` to jump to the first instance of `any: string`.
Use `:difft` when opening multiple files to run `:difft` on the first 4 files.
Use `:diffthis` when opening multiple files to run `:diffthis` on the first 4 files.
## Basic Options
* Change the default mapping and the default command to invoke CtrlP:
@ -46,26 +47,26 @@ Use `:difft` when opening multiple files to run `:difft` on the first 4 files.
* When invoked, unless a starting directory is specified, CtrlP will set its local working directory according to this variable:
```vim
let g:ctrlp_working_path_mode = 'rc'
let g:ctrlp_working_path_mode = 'ra'
```
`{empty-string}` - don't manage working directory.
`c` - the directory of the current file.
`r` - the nearest ancestor that contains one of these directories or files:
`.git` `.hg` `.svn` `.bzr` `_darcs`
`'c'` - the directory of the current file.
`'r'` - the nearest ancestor that contains one of these directories or files: `.git` `.hg` `.svn` `.bzr` `_darcs`
`'a'` - like c, but only if the current working directory outside of CtrlP is not a direct ancestor of the directory of the current file.
`0` or `''` (empty string) - disable this feature.
Define additional root markers with the `g:ctrlp_root_markers` option.
* Exclude files and directories using Vim's `wildignore` and CtrlP's own `g:ctrlp_custom_ignore`:
```vim
set wildignore+=*/tmp/*,*.so,*.swp,*.zip " MacOSX/Linux
set wildignore+=tmp\*,*.swp,*.zip,*.exe " Windows
set wildignore+=*/tmp/*,*.so,*.swp,*.zip " MacOSX/Linux
set wildignore+=*\\tmp\\*,*.swp,*.zip,*.exe " Windows
let g:ctrlp_custom_ignore = '\.git$\|\.hg$\|\.svn$'
let g:ctrlp_custom_ignore = '\v[\/]\.(git|hg|svn)$'
let g:ctrlp_custom_ignore = {
\ 'dir': '\.git$\|\.hg$\|\.svn$',
\ 'file': '\.exe$\|\.so$\|\.dll$',
\ 'dir': '\v[\/]\.(git|hg|svn)$',
\ 'file': '\v\.(exe|so|dll)$',
\ 'link': 'some_bad_symbolic_links',
\ }
```

View file

@ -82,6 +82,10 @@ __Q. How can I open a NERDTree automatically when vim starts up if no files were
A. Stick this in your vimrc `autocmd vimenter * if !argc() | NERDTree | endif`
__Q. How can I map a specific key or shortcut to open NERDTree?__
A. Stick this in your vimrc to open NERDTree with `Ctrl+n` (you can set whatever key you want): `map <C-n> :NERDTreeToggle<CR>`
__Q. How can I close vim if the only window left open is a NERDTree?__
A. Stick this in your vimrc:

File diff suppressed because it is too large Load diff

View file

@ -137,6 +137,10 @@ The following features and functionality are provided by the NERD tree:
In any case, the current file is revealed and the cursor is placed on it.
:NERDTreeCWD *:NERDTreeCWD*
Change tree root to current directory. If no NERD tree exists for this
tab, a new tree will be opened.
------------------------------------------------------------------------------
2.2. Bookmarks *NERDTreeBookmarks*
@ -247,6 +251,7 @@ r.......Recursively refresh the current directory................|NERDTree-r|
R.......Recursively refresh the current root.....................|NERDTree-R|
m.......Display the NERD tree menu...............................|NERDTree-m|
cd......Change the CWD to the dir of the selected node...........|NERDTree-cd|
CD......Change tree root to the CWD..............................|NERDTree-CD|
I.......Toggle whether hidden files displayed....................|NERDTree-I|
f.......Toggle whether the file filters are used.................|NERDTree-f|
@ -514,6 +519,14 @@ Applies to: files and directories.
Change vims current working directory to that of the selected node.
------------------------------------------------------------------------------
*NERDTree-CD*
Default key: CD
Map option: NERDTreeMapCWD
Applies to: no restrictions.
Change tree root to vims current working directory.
------------------------------------------------------------------------------
*NERDTree-I*
Default key: I
@ -658,6 +671,10 @@ NERD tree. These options should be set in your vimrc.
Casade open while selected directory has only
one child that also is a directory.
|'NERDTreeAutoDeleteBuffer'| Tells the NERD tree to automatically remove
a buffer when a file is being deleted or renamed
via a context menu command.
------------------------------------------------------------------------------
3.2. Customisation details *NERDTreeOptionDetails*
@ -982,6 +999,20 @@ for Java projects. Use one of the follow lines to set this option: >
let NERDTreeCasadeOpenSingleChildDir=1
<
------------------------------------------------------------------------------
*'NERDTreeAutoDeleteBuffer'*
Values: 0 or 1
Default: 0.
When using a context menu to delete or rename a file you may also want to delete
the buffer which is no more valid. If the option is not set you will see a
confirmation if you really want to delete an old buffer. If you always press 'y'
then it worths to set this option to 1. Use one of the follow lines to set this
option: >
let NERDTreeAutoDeleteBuffer=0
let NERDTreeAutoDeleteBuffer=1
<
==============================================================================
4. The NERD tree API *NERDTreeAPI*

View file

@ -15,6 +15,11 @@ if exists("g:loaded_nerdtree_fs_menu")
endif
let g:loaded_nerdtree_fs_menu = 1
"Automatically delete the buffer after deleting or renaming a file
if !exists("g:NERDTreeAutoDeleteBuffer")
let g:NERDTreeAutoDeleteBuffer = 0
endif
call NERDTreeAddMenuItem({'text': '(a)dd a childnode', 'shortcut': 'a', 'callback': 'NERDTreeAddNode'})
call NERDTreeAddMenuItem({'text': '(m)ove the current node', 'shortcut': 'm', 'callback': 'NERDTreeMoveNode'})
call NERDTreeAddMenuItem({'text': '(d)elete the current node', 'shortcut': 'd', 'callback': 'NERDTreeDeleteNode'})
@ -26,7 +31,7 @@ if has("gui_mac") || has("gui_macvim")
endif
if g:NERDTreePath.CopyingSupported()
call NERDTreeAddMenuItem({'text': '(c)copy the current node', 'shortcut': 'c', 'callback': 'NERDTreeCopyNode'})
call NERDTreeAddMenuItem({'text': '(c)opy the current node', 'shortcut': 'c', 'callback': 'NERDTreeCopyNode'})
endif
"FUNCTION: s:echo(msg){{{1
@ -52,11 +57,44 @@ endfunction
" del the buffer
function! s:promptToDelBuffer(bufnum, msg)
echo a:msg
if nr2char(getchar()) ==# 'y'
exec "silent bdelete! " . a:bufnum
if g:NERDTreeAutoDeleteBuffer || nr2char(getchar()) ==# 'y'
" 1. ensure that all windows which display the just deleted filename
" now display an empty buffer (so a layout is preserved).
" Is not it better to close single tabs with this file only ?
let s:originalTabNumber = tabpagenr()
let s:originalWindowNumber = winnr()
exec "tabdo windo if winbufnr(0) == " . a:bufnum . " | exec ':enew! ' | endif"
exec "tabnext " . s:originalTabNumber
exec s:originalWindowNumber . "wincmd w"
" 3. We don't need a previous buffer anymore
exec "bwipeout! " . a:bufnum
endif
endfunction
"FUNCTION: s:promptToRenameBuffer(bufnum, msg){{{1
"prints out the given msg and, if the user responds by pushing 'y' then the
"buffer with the given bufnum is replaced with a new one
"
"Args:
"bufnum: the buffer that may be deleted
"msg: a message that will be echoed to the user asking them if they wish to
" del the buffer
function! s:promptToRenameBuffer(bufnum, msg, newFileName)
echo a:msg
if g:NERDTreeAutoDeleteBuffer || nr2char(getchar()) ==# 'y'
" 1. ensure that a new buffer is loaded
exec "badd " . a:newFileName
" 2. ensure that all windows which display the just deleted filename
" display a buffer for a new filename.
let s:originalTabNumber = tabpagenr()
let s:originalWindowNumber = winnr()
exec "tabdo windo if winbufnr(0) == " . a:bufnum . " | exec ':e! " . a:newFileName . "' | endif"
exec "tabnext " . s:originalTabNumber
exec s:originalWindowNumber . "wincmd w"
" 3. We don't need a previous buffer anymore
exec "bwipeout! " . a:bufnum
endif
endfunction
"FUNCTION: NERDTreeAddNode(){{{1
function! NERDTreeAddNode()
let curDirNode = g:NERDTreeDirNode.GetSelected()
@ -108,8 +146,8 @@ function! NERDTreeMoveNode()
"if the node is open in a buffer, ask the user if they want to
"close that buffer
if bufnum != -1
let prompt = "\nNode renamed.\n\nThe old file is open in buffer ". bufnum . (bufwinnr(bufnum) ==# -1 ? " (hidden)" : "") .". Delete this buffer? (yN)"
call s:promptToDelBuffer(bufnum, prompt)
let prompt = "\nNode renamed.\n\nThe old file is open in buffer ". bufnum . (bufwinnr(bufnum) ==# -1 ? " (hidden)" : "") .". Replace this buffer with a new file? (yN)"
call s:promptToRenameBuffer(bufnum, prompt, newNodePath)
endif
call curNode.putCursorHere(1, 0)

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,315 @@
"CLASS: Bookmark
"============================================================
let s:Bookmark = {}
let g:NERDTreeBookmark = s:Bookmark
" FUNCTION: Bookmark.activate() {{{1
function! s:Bookmark.activate(...)
call self.open(a:0 ? a:1 : {})
endfunction
" FUNCTION: Bookmark.AddBookmark(name, path) {{{1
" Class method to add a new bookmark to the list, if a previous bookmark exists
" with the same name, just update the path for that bookmark
function! s:Bookmark.AddBookmark(name, path)
for i in s:Bookmark.Bookmarks()
if i.name ==# a:name
let i.path = a:path
return
endif
endfor
call add(s:Bookmark.Bookmarks(), s:Bookmark.New(a:name, a:path))
call s:Bookmark.Sort()
endfunction
" FUNCTION: Bookmark.Bookmarks() {{{1
" Class method to get all bookmarks. Lazily initializes the bookmarks global
" variable
function! s:Bookmark.Bookmarks()
if !exists("g:NERDTreeBookmarks")
let g:NERDTreeBookmarks = []
endif
return g:NERDTreeBookmarks
endfunction
" FUNCTION: Bookmark.BookmarkExistsFor(name) {{{1
" class method that returns 1 if a bookmark with the given name is found, 0
" otherwise
function! s:Bookmark.BookmarkExistsFor(name)
try
call s:Bookmark.BookmarkFor(a:name)
return 1
catch /^NERDTree.BookmarkNotFoundError/
return 0
endtry
endfunction
" FUNCTION: Bookmark.BookmarkFor(name) {{{1
" Class method to get the bookmark that has the given name. {} is return if no
" bookmark is found
function! s:Bookmark.BookmarkFor(name)
for i in s:Bookmark.Bookmarks()
if i.name ==# a:name
return i
endif
endfor
throw "NERDTree.BookmarkNotFoundError: no bookmark found for name: \"". a:name .'"'
endfunction
" FUNCTION: Bookmark.BookmarkNames() {{{1
" Class method to return an array of all bookmark names
function! s:Bookmark.BookmarkNames()
let names = []
for i in s:Bookmark.Bookmarks()
call add(names, i.name)
endfor
return names
endfunction
" FUNCTION: Bookmark.CacheBookmarks(silent) {{{1
" Class method to read all bookmarks from the bookmarks file intialize
" bookmark objects for each one.
"
" Args:
" silent - dont echo an error msg if invalid bookmarks are found
function! s:Bookmark.CacheBookmarks(silent)
if filereadable(g:NERDTreeBookmarksFile)
let g:NERDTreeBookmarks = []
let g:NERDTreeInvalidBookmarks = []
let bookmarkStrings = readfile(g:NERDTreeBookmarksFile)
let invalidBookmarksFound = 0
for i in bookmarkStrings
"ignore blank lines
if i != ''
let name = substitute(i, '^\(.\{-}\) .*$', '\1', '')
let path = substitute(i, '^.\{-} \(.*\)$', '\1', '')
try
let bookmark = s:Bookmark.New(name, g:NERDTreePath.New(path))
call add(g:NERDTreeBookmarks, bookmark)
catch /^NERDTree.InvalidArgumentsError/
call add(g:NERDTreeInvalidBookmarks, i)
let invalidBookmarksFound += 1
endtry
endif
endfor
if invalidBookmarksFound
call s:Bookmark.Write()
if !a:silent
call nerdtree#echo(invalidBookmarksFound . " invalid bookmarks were read. See :help NERDTreeInvalidBookmarks for info.")
endif
endif
call s:Bookmark.Sort()
endif
endfunction
" FUNCTION: Bookmark.compareTo(otherbookmark) {{{1
" Compare these two bookmarks for sorting purposes
function! s:Bookmark.compareTo(otherbookmark)
return a:otherbookmark.name < self.name
endfunction
" FUNCTION: Bookmark.ClearAll() {{{1
" Class method to delete all bookmarks.
function! s:Bookmark.ClearAll()
for i in s:Bookmark.Bookmarks()
call i.delete()
endfor
call s:Bookmark.Write()
endfunction
" FUNCTION: Bookmark.delete() {{{1
" Delete this bookmark. If the node for this bookmark is under the current
" root, then recache bookmarks for its Path object
function! s:Bookmark.delete()
let node = {}
try
let node = self.getNode(1)
catch /^NERDTree.BookmarkedNodeNotFoundError/
endtry
call remove(s:Bookmark.Bookmarks(), index(s:Bookmark.Bookmarks(), self))
if !empty(node)
call node.path.cacheDisplayString()
endif
call s:Bookmark.Write()
endfunction
" FUNCTION: Bookmark.getNode(searchFromAbsoluteRoot) {{{1
" Gets the treenode for this bookmark
"
" Args:
" searchFromAbsoluteRoot: specifies whether we should search from the current
" tree root, or the highest cached node
function! s:Bookmark.getNode(searchFromAbsoluteRoot)
let searchRoot = a:searchFromAbsoluteRoot ? g:NERDTreeDirNode.AbsoluteTreeRoot() : b:NERDTreeRoot
let targetNode = searchRoot.findNode(self.path)
if empty(targetNode)
throw "NERDTree.BookmarkedNodeNotFoundError: no node was found for bookmark: " . self.name
endif
return targetNode
endfunction
" FUNCTION: Bookmark.GetNodeForName(name, searchFromAbsoluteRoot) {{{1
" Class method that finds the bookmark with the given name and returns the
" treenode for it.
function! s:Bookmark.GetNodeForName(name, searchFromAbsoluteRoot)
let bookmark = s:Bookmark.BookmarkFor(a:name)
return bookmark.getNode(a:searchFromAbsoluteRoot)
endfunction
" FUNCTION: Bookmark.GetSelected() {{{1
" returns the Bookmark the cursor is over, or {}
function! s:Bookmark.GetSelected()
let line = getline(".")
let name = substitute(line, '^>\(.\{-}\) .\+$', '\1', '')
if name != line
try
return s:Bookmark.BookmarkFor(name)
catch /^NERDTree.BookmarkNotFoundError/
return {}
endtry
endif
return {}
endfunction
" FUNCTION: Bookmark.InvalidBookmarks() {{{1
" Class method to get all invalid bookmark strings read from the bookmarks
" file
function! s:Bookmark.InvalidBookmarks()
if !exists("g:NERDTreeInvalidBookmarks")
let g:NERDTreeInvalidBookmarks = []
endif
return g:NERDTreeInvalidBookmarks
endfunction
" FUNCTION: Bookmark.mustExist() {{{1
function! s:Bookmark.mustExist()
if !self.path.exists()
call s:Bookmark.CacheBookmarks(1)
throw "NERDTree.BookmarkPointsToInvalidLocationError: the bookmark \"".
\ self.name ."\" points to a non existing location: \"". self.path.str()
endif
endfunction
" FUNCTION: Bookmark.New(name, path) {{{1
" Create a new bookmark object with the given name and path object
function! s:Bookmark.New(name, path)
if a:name =~# ' '
throw "NERDTree.IllegalBookmarkNameError: illegal name:" . a:name
endif
let newBookmark = copy(self)
let newBookmark.name = a:name
let newBookmark.path = a:path
return newBookmark
endfunction
" FUNCTION: Bookmark.open([options]) {{{1
"Args:
"A dictionary containing the following keys (all optional):
" 'where': Specifies whether the node should be opened in new split/tab or in
" the previous window. Can be either 'v' (vertical split), 'h'
" (horizontal split), 't' (new tab) or 'p' (previous window).
" 'reuse': if a window is displaying the file then jump the cursor there
" 'keepopen': dont close the tree window
" 'stay': open the file, but keep the cursor in the tree win
"
function! s:Bookmark.open(...)
let opts = a:0 ? a:1 : {}
if self.path.isDirectory && !has_key(opts, 'where')
call self.toRoot()
else
let opener = g:NERDTreeOpener.New(self.path, opts)
call opener.open(self)
endif
endfunction
" FUNCTION: Bookmark.openInNewTab(options) {{{1
" Create a new bookmark object with the given name and path object
function! s:Bookmark.openInNewTab(options)
call nerdtree#deprecated('Bookmark.openInNewTab', 'is deprecated, use open() instead')
call self.open(a:options)
endfunction
" FUNCTION: Bookmark.setPath(path) {{{1
" makes this bookmark point to the given path
function! s:Bookmark.setPath(path)
let self.path = a:path
endfunction
" FUNCTION: Bookmark.Sort() {{{1
" Class method that sorts all bookmarks
function! s:Bookmark.Sort()
let CompareFunc = function("nerdtree#compareBookmarks")
call sort(s:Bookmark.Bookmarks(), CompareFunc)
endfunction
" FUNCTION: Bookmark.str() {{{1
" Get the string that should be rendered in the view for this bookmark
function! s:Bookmark.str()
let pathStrMaxLen = winwidth(nerdtree#getTreeWinNum()) - 4 - len(self.name)
if &nu
let pathStrMaxLen = pathStrMaxLen - &numberwidth
endif
let pathStr = self.path.str({'format': 'UI'})
if len(pathStr) > pathStrMaxLen
let pathStr = '<' . strpart(pathStr, len(pathStr) - pathStrMaxLen)
endif
return '>' . self.name . ' ' . pathStr
endfunction
" FUNCTION: Bookmark.toRoot() {{{1
" Make the node for this bookmark the new tree root
function! s:Bookmark.toRoot()
if self.validate()
try
let targetNode = self.getNode(1)
catch /^NERDTree.BookmarkedNodeNotFoundError/
let targetNode = g:NERDTreeFileNode.New(s:Bookmark.BookmarkFor(self.name).path)
endtry
call targetNode.makeRoot()
call nerdtree#renderView()
call targetNode.putCursorHere(0, 0)
endif
endfunction
" FUNCTION: Bookmark.ToRoot(name) {{{1
" Make the node for this bookmark the new tree root
function! s:Bookmark.ToRoot(name)
let bookmark = s:Bookmark.BookmarkFor(a:name)
call bookmark.toRoot()
endfunction
" FUNCTION: Bookmark.validate() {{{1
function! s:Bookmark.validate()
if self.path.exists()
return 1
else
call s:Bookmark.CacheBookmarks(1)
call nerdtree#renderView()
call nerdtree#echo(self.name . "now points to an invalid location. See :help NERDTreeInvalidBookmarks for info.")
return 0
endif
endfunction
" FUNCTION: Bookmark.Write() {{{1
" Class method to write all bookmarks to the bookmarks file
function! s:Bookmark.Write()
let bookmarkStrings = []
for i in s:Bookmark.Bookmarks()
call add(bookmarkStrings, i.name . ' ' . i.path.str())
endfor
"add a blank line before the invalid ones
call add(bookmarkStrings, "")
for j in s:Bookmark.InvalidBookmarks()
call add(bookmarkStrings, j)
endfor
call writefile(bookmarkStrings, g:NERDTreeBookmarksFile)
endfunction
" vim: set sw=4 sts=4 et fdm=marker:

View file

@ -0,0 +1,322 @@
"CLASS: Creator
"Creates primary/secondary/mirror nerdtree windows. Sets up all the window and
"buffer options and key mappings etc.
"============================================================
let s:Creator = {}
let g:NERDTreeCreator = s:Creator
"FUNCTION: s:Creator._bindMappings() {{{1
function! s:Creator._bindMappings()
"make <cr> do the same as the default 'o' mapping
exec "nnoremap <silent> <buffer> <cr> :call nerdtree#invokeKeyMap('". g:NERDTreeMapActivateNode ."')<cr>"
call g:NERDTreeKeyMap.BindAll()
command! -buffer -nargs=? Bookmark :call nerdtree#bookmarkNode('<args>')
command! -buffer -complete=customlist,nerdtree#completeBookmarks -nargs=1 RevealBookmark :call nerdtree#revealBookmark('<args>')
command! -buffer -complete=customlist,nerdtree#completeBookmarks -nargs=1 OpenBookmark :call nerdtree#openBookmark('<args>')
command! -buffer -complete=customlist,nerdtree#completeBookmarks -nargs=* ClearBookmarks call nerdtree#clearBookmarks('<args>')
command! -buffer -complete=customlist,nerdtree#completeBookmarks -nargs=+ BookmarkToRoot call g:NERDTreeBookmark.ToRoot('<args>')
command! -buffer -nargs=0 ClearAllBookmarks call g:NERDTreeBookmark.ClearAll() <bar> call nerdtree#renderView()
command! -buffer -nargs=0 ReadBookmarks call g:NERDTreeBookmark.CacheBookmarks(0) <bar> call nerdtree#renderView()
command! -buffer -nargs=0 WriteBookmarks call g:NERDTreeBookmark.Write()
endfunction
"FUNCTION: s:Creator._broadcastInitEvent() {{{1
function! s:Creator._broadcastInitEvent()
silent doautocmd User NERDTreeInit
endfunction
" FUNCTION: s:Creator.BufNamePrefix() {{{2
function! s:Creator.BufNamePrefix()
return 'NERD_tree_'
endfunction
"FUNCTION: s:Creator.CreatePrimary(a:name) {{{1
function! s:Creator.CreatePrimary(name)
let creator = s:Creator.New()
call creator.createPrimary(a:name)
endfunction
"FUNCTION: s:Creator.createPrimary(a:name) {{{1
"name: the name of a bookmark or a directory
function! s:Creator.createPrimary(name)
let path = self._pathForString(a:name)
"if instructed to, then change the vim CWD to the dir the NERDTree is
"inited in
if g:NERDTreeChDirMode != 0
call path.changeToDir()
endif
if nerdtree#treeExistsForTab()
if nerdtree#isTreeOpen()
call nerdtree#closeTree()
endif
unlet t:NERDTreeBufName
endif
let newRoot = g:NERDTreeDirNode.New(path)
call newRoot.open()
call self._createTreeWin()
let b:treeShowHelp = 0
let b:NERDTreeIgnoreEnabled = 1
let b:NERDTreeShowFiles = g:NERDTreeShowFiles
let b:NERDTreeShowHidden = g:NERDTreeShowHidden
let b:NERDTreeShowBookmarks = g:NERDTreeShowBookmarks
let b:NERDTreeRoot = newRoot
let b:NERDTreeType = "primary"
call nerdtree#renderView()
call b:NERDTreeRoot.putCursorHere(0, 0)
call self._broadcastInitEvent()
endfunction
"FUNCTION: s:Creator.CreateSecondary(dir) {{{1
function! s:Creator.CreateSecondary(dir)
let creator = s:Creator.New()
call creator.createSecondary(a:dir)
endfunction
"FUNCTION: s:Creator.createSecondary(dir) {{{1
function! s:Creator.createSecondary(dir)
try
let path = g:NERDTreePath.New(a:dir)
catch /^NERDTree.InvalidArgumentsError/
call nerdtree#echo("Invalid directory name:" . a:name)
return
endtry
"we want the directory buffer to disappear when we do the :edit below
setlocal bufhidden=wipe
let previousBuf = expand("#")
"we need a unique name for each secondary tree buffer to ensure they are
"all independent
exec "silent edit " . self._nextBufferName()
let b:NERDTreePreviousBuf = bufnr(previousBuf)
let b:NERDTreeRoot = g:NERDTreeDirNode.New(path)
call b:NERDTreeRoot.open()
call self._setCommonBufOptions()
let b:NERDTreeType = "secondary"
call nerdtree#renderView()
call self._broadcastInitEvent()
endfunction
" FUNCTION: s:Creator.CreateMirror() {{{1
function! s:Creator.CreateMirror()
let creator = s:Creator.New()
call creator.createMirror()
endfunction
" FUNCTION: s:Creator.createMirror() {{{1
function! s:Creator.createMirror()
"get the names off all the nerd tree buffers
let treeBufNames = []
for i in range(1, tabpagenr("$"))
let nextName = nerdtree#tabpagevar(i, 'NERDTreeBufName')
if nextName != -1 && (!exists("t:NERDTreeBufName") || nextName != t:NERDTreeBufName)
call add(treeBufNames, nextName)
endif
endfor
let treeBufNames = nerdtree#unique(treeBufNames)
"map the option names (that the user will be prompted with) to the nerd
"tree buffer names
let options = {}
let i = 0
while i < len(treeBufNames)
let bufName = treeBufNames[i]
let treeRoot = getbufvar(bufName, "NERDTreeRoot")
let options[i+1 . '. ' . treeRoot.path.str() . ' (buf name: ' . bufName . ')'] = bufName
let i = i + 1
endwhile
"work out which tree to mirror, if there is more than 1 then ask the user
let bufferName = ''
if len(keys(options)) > 1
let choices = ["Choose a tree to mirror"]
let choices = extend(choices, sort(keys(options)))
let choice = inputlist(choices)
if choice < 1 || choice > len(options) || choice ==# ''
return
endif
let bufferName = options[sort(keys(options))[choice-1]]
elseif len(keys(options)) ==# 1
let bufferName = values(options)[0]
else
call nerdtree#echo("No trees to mirror")
return
endif
if nerdtree#treeExistsForTab() && nerdtree#isTreeOpen()
call nerdtree#closeTree()
endif
let t:NERDTreeBufName = bufferName
call self._createTreeWin()
exec 'buffer ' . bufferName
if !&hidden
call nerdtree#renderView()
endif
endfunction
"FUNCTION: s:Creator._createTreeWin() {{{1
"Inits the NERD tree window. ie. opens it, sizes it, sets all the local
"options etc
function! s:Creator._createTreeWin()
"create the nerd tree window
let splitLocation = g:NERDTreeWinPos ==# "left" ? "topleft " : "botright "
let splitSize = g:NERDTreeWinSize
if !exists('t:NERDTreeBufName')
let t:NERDTreeBufName = self._nextBufferName()
silent! exec splitLocation . 'vertical ' . splitSize . ' new'
silent! exec "edit " . t:NERDTreeBufName
else
silent! exec splitLocation . 'vertical ' . splitSize . ' split'
silent! exec "buffer " . t:NERDTreeBufName
endif
setlocal winfixwidth
call self._setCommonBufOptions()
endfunction
"FUNCTION: s:Creator.New() {{{1
function! s:Creator.New()
let newCreator = copy(self)
return newCreator
endfunction
" FUNCTION: s:Creator._nextBufferName() {{{2
" returns the buffer name for the next nerd tree
function! s:Creator._nextBufferName()
let name = s:Creator.BufNamePrefix() . self._nextBufferNumber()
return name
endfunction
" FUNCTION: s:Creator._nextBufferNumber() {{{2
" the number to add to the nerd tree buffer name to make the buf name unique
function! s:Creator._nextBufferNumber()
if !exists("s:Creator._NextBufNum")
let s:Creator._NextBufNum = 1
else
let s:Creator._NextBufNum += 1
endif
return s:Creator._NextBufNum
endfunction
"FUNCTION: s:Creator._pathForString(str) {{{1
"find a bookmark or adirectory for the given string
function! s:Creator._pathForString(str)
let path = {}
if g:NERDTreeBookmark.BookmarkExistsFor(a:str)
let path = g:NERDTreeBookmark.BookmarkFor(a:str).path
else
let dir = a:str ==# '' ? getcwd() : a:str
"hack to get an absolute path if a relative path is given
if dir =~# '^\.'
let dir = getcwd() . g:NERDTreePath.Slash() . dir
endif
let dir = g:NERDTreePath.Resolve(dir)
try
let path = g:NERDTreePath.New(dir)
catch /^NERDTree.InvalidArgumentsError/
call nerdtree#echo("No bookmark or directory found for: " . a:str)
return
endtry
endif
if !path.isDirectory
let path = path.getParent()
endif
return path
endfunction
"FUNCTION: s:Creator._setCommonBufOptions() {{{1
function! s:Creator._setCommonBufOptions()
"throwaway buffer options
setlocal noswapfile
setlocal buftype=nofile
setlocal bufhidden=hide
setlocal nowrap
setlocal foldcolumn=0
setlocal foldmethod=manual
setlocal nofoldenable
setlocal nobuflisted
setlocal nospell
if g:NERDTreeShowLineNumbers
setlocal nu
else
setlocal nonu
if v:version >= 703
setlocal nornu
endif
endif
iabc <buffer>
if g:NERDTreeHighlightCursorline
setlocal cursorline
endif
call self._setupStatusline()
let b:treeShowHelp = 0
let b:NERDTreeIgnoreEnabled = 1
let b:NERDTreeShowFiles = g:NERDTreeShowFiles
let b:NERDTreeShowHidden = g:NERDTreeShowHidden
let b:NERDTreeShowBookmarks = g:NERDTreeShowBookmarks
setfiletype nerdtree
call self._bindMappings()
endfunction
"FUNCTION: s:Creator._setupStatusline() {{{1
function! s:Creator._setupStatusline()
if g:NERDTreeStatusline != -1
let &l:statusline = g:NERDTreeStatusline
endif
endfunction
"FUNCTION: s:Creator.TogglePrimary(dir) {{{1
function! s:Creator.TogglePrimary(dir)
let creator = s:Creator.New()
call creator.togglePrimary(a:dir)
endfunction
"FUNCTION: s:Creator.togglePrimary(dir) {{{1
"Toggles the NERD tree. I.e the NERD tree is open, it is closed, if it is
"closed it is restored or initialized (if it doesnt exist)
"
"Args:
"dir: the full path for the root node (is only used if the NERD tree is being
"initialized.
function! s:Creator.togglePrimary(dir)
if nerdtree#treeExistsForTab()
if !nerdtree#isTreeOpen()
call self._createTreeWin()
if !&hidden
call nerdtree#renderView()
endif
call nerdtree#restoreScreenState()
else
call nerdtree#closeTree()
endif
else
call self.createPrimary(a:dir)
endif
endfunction
" vim: set sw=4 sts=4 et fdm=marker:

View file

@ -0,0 +1,143 @@
"CLASS: KeyMap
"============================================================
let s:KeyMap = {}
let g:NERDTreeKeyMap = s:KeyMap
"FUNCTION: KeyMap.All() {{{1
function! s:KeyMap.All()
if !exists("s:keyMaps")
let s:keyMaps = []
endif
return s:keyMaps
endfunction
"FUNCTION: KeyMap.FindFor(key, scope) {{{1
function! s:KeyMap.FindFor(key, scope)
for i in s:KeyMap.All()
if i.key ==# a:key && i.scope ==# a:scope
return i
endif
endfor
return {}
endfunction
"FUNCTION: KeyMap.BindAll() {{{1
function! s:KeyMap.BindAll()
for i in s:KeyMap.All()
call i.bind()
endfor
endfunction
"FUNCTION: KeyMap.bind() {{{1
function! s:KeyMap.bind()
" If the key sequence we're trying to map contains any '<>' notation, we
" must replace each of the '<' characters with '<lt>' to ensure the string
" is not translated into its corresponding keycode during the later part
" of the map command below
" :he <>
let specialNotationRegex = '\m<\([[:alnum:]_-]\+>\)'
if self.key =~# specialNotationRegex
let keymapInvokeString = substitute(self.key, specialNotationRegex, '<lt>\1', 'g')
else
let keymapInvokeString = self.key
endif
let premap = self.key == "<LeftRelease>" ? " <LeftRelease>" : " "
exec 'nnoremap <buffer> <silent> '. self.key . premap . ':call nerdtree#invokeKeyMap("'. keymapInvokeString .'")<cr>'
endfunction
"FUNCTION: KeyMap.Remove(key, scope) {{{1
function! s:KeyMap.Remove(key, scope)
let maps = s:KeyMap.All()
for i in range(len(maps))
if maps[i].key ==# a:key && maps[i].scope ==# a:scope
return remove(maps, i)
endif
endfor
endfunction
"FUNCTION: KeyMap.invoke() {{{1
"Call the KeyMaps callback function
function! s:KeyMap.invoke(...)
let Callback = function(self.callback)
if a:0
call Callback(a:1)
else
call Callback()
endif
endfunction
"FUNCTION: KeyMap.Invoke() {{{1
"Find a keymapping for a:key and the current scope invoke it.
"
"Scope is determined as follows:
" * if the cursor is on a dir node then "DirNode"
" * if the cursor is on a file node then "FileNode"
" * if the cursor is on a bookmark then "Bookmark"
"
"If a keymap has the scope of "all" then it will be called if no other keymap
"is found for a:key and the scope.
function! s:KeyMap.Invoke(key)
let node = g:NERDTreeFileNode.GetSelected()
if !empty(node)
"try file node
if !node.path.isDirectory
let km = s:KeyMap.FindFor(a:key, "FileNode")
if !empty(km)
return km.invoke(node)
endif
endif
"try dir node
if node.path.isDirectory
let km = s:KeyMap.FindFor(a:key, "DirNode")
if !empty(km)
return km.invoke(node)
endif
endif
"try generic node
let km = s:KeyMap.FindFor(a:key, "Node")
if !empty(km)
return km.invoke(node)
endif
endif
"try bookmark
let bm = g:NERDTreeBookmark.GetSelected()
if !empty(bm)
let km = s:KeyMap.FindFor(a:key, "Bookmark")
if !empty(km)
return km.invoke(bm)
endif
endif
"try all
let km = s:KeyMap.FindFor(a:key, "all")
if !empty(km)
return km.invoke()
endif
endfunction
"FUNCTION: KeyMap.Create(options) {{{1
function! s:KeyMap.Create(options)
let newKeyMap = copy(self)
let opts = extend({'scope': 'all', 'quickhelpText': ''}, copy(a:options))
let newKeyMap.key = opts['key']
let newKeyMap.quickhelpText = opts['quickhelpText']
let newKeyMap.callback = opts['callback']
let newKeyMap.scope = opts['scope']
call s:KeyMap.Add(newKeyMap)
endfunction
"FUNCTION: KeyMap.Add(keymap) {{{1
function! s:KeyMap.Add(keymap)
call s:KeyMap.Remove(a:keymap.key, a:keymap.scope)
call add(s:KeyMap.All(), a:keymap)
endfunction
" vim: set sw=4 sts=4 et fdm=marker:

View file

@ -0,0 +1,180 @@
"CLASS: MenuController
"============================================================
let s:MenuController = {}
let g:NERDTreeMenuController = s:MenuController
"FUNCTION: MenuController.New(menuItems) {{{1
"create a new menu controller that operates on the given menu items
function! s:MenuController.New(menuItems)
let newMenuController = copy(self)
if a:menuItems[0].isSeparator()
let newMenuController.menuItems = a:menuItems[1:-1]
else
let newMenuController.menuItems = a:menuItems
endif
return newMenuController
endfunction
"FUNCTION: MenuController.showMenu() {{{1
"start the main loop of the menu and get the user to choose/execute a menu
"item
function! s:MenuController.showMenu()
call self._saveOptions()
try
let self.selection = 0
let done = 0
while !done
redraw!
call self._echoPrompt()
let key = nr2char(getchar())
let done = self._handleKeypress(key)
endwhile
finally
call self._restoreOptions()
endtry
if self.selection != -1
let m = self._current()
call m.execute()
endif
endfunction
"FUNCTION: MenuController._echoPrompt() {{{1
function! s:MenuController._echoPrompt()
echo "NERDTree Menu. Use j/k/enter and the shortcuts indicated"
echo "=========================================================="
for i in range(0, len(self.menuItems)-1)
if self.selection == i
echo "> " . self.menuItems[i].text
else
echo " " . self.menuItems[i].text
endif
endfor
endfunction
"FUNCTION: MenuController._current(key) {{{1
"get the MenuItem that is currently selected
function! s:MenuController._current()
return self.menuItems[self.selection]
endfunction
"FUNCTION: MenuController._handleKeypress(key) {{{1
"change the selection (if appropriate) and return 1 if the user has made
"their choice, 0 otherwise
function! s:MenuController._handleKeypress(key)
if a:key == 'j'
call self._cursorDown()
elseif a:key == 'k'
call self._cursorUp()
elseif a:key == nr2char(27) "escape
let self.selection = -1
return 1
elseif a:key == "\r" || a:key == "\n" "enter and ctrl-j
return 1
else
let index = self._nextIndexFor(a:key)
if index != -1
let self.selection = index
if len(self._allIndexesFor(a:key)) == 1
return 1
endif
endif
endif
return 0
endfunction
"FUNCTION: MenuController._allIndexesFor(shortcut) {{{1
"get indexes to all menu items with the given shortcut
function! s:MenuController._allIndexesFor(shortcut)
let toReturn = []
for i in range(0, len(self.menuItems)-1)
if self.menuItems[i].shortcut == a:shortcut
call add(toReturn, i)
endif
endfor
return toReturn
endfunction
"FUNCTION: MenuController._nextIndexFor(shortcut) {{{1
"get the index to the next menu item with the given shortcut, starts from the
"current cursor location and wraps around to the top again if need be
function! s:MenuController._nextIndexFor(shortcut)
for i in range(self.selection+1, len(self.menuItems)-1)
if self.menuItems[i].shortcut == a:shortcut
return i
endif
endfor
for i in range(0, self.selection)
if self.menuItems[i].shortcut == a:shortcut
return i
endif
endfor
return -1
endfunction
"FUNCTION: MenuController._setCmdheight() {{{1
"sets &cmdheight to whatever is needed to display the menu
function! s:MenuController._setCmdheight()
let &cmdheight = len(self.menuItems) + 3
endfunction
"FUNCTION: MenuController._saveOptions() {{{1
"set any vim options that are required to make the menu work (saving their old
"values)
function! s:MenuController._saveOptions()
let self._oldLazyredraw = &lazyredraw
let self._oldCmdheight = &cmdheight
set nolazyredraw
call self._setCmdheight()
endfunction
"FUNCTION: MenuController._restoreOptions() {{{1
"restore the options we saved in _saveOptions()
function! s:MenuController._restoreOptions()
let &cmdheight = self._oldCmdheight
let &lazyredraw = self._oldLazyredraw
endfunction
"FUNCTION: MenuController._cursorDown() {{{1
"move the cursor to the next menu item, skipping separators
function! s:MenuController._cursorDown()
let done = 0
while !done
if self.selection < len(self.menuItems)-1
let self.selection += 1
else
let self.selection = 0
endif
if !self._current().isSeparator()
let done = 1
endif
endwhile
endfunction
"FUNCTION: MenuController._cursorUp() {{{1
"move the cursor to the previous menu item, skipping separators
function! s:MenuController._cursorUp()
let done = 0
while !done
if self.selection > 0
let self.selection -= 1
else
let self.selection = len(self.menuItems)-1
endif
if !self._current().isSeparator()
let done = 1
endif
endwhile
endfunction
" vim: set sw=4 sts=4 et fdm=marker:

View file

@ -0,0 +1,114 @@
"CLASS: MenuItem
"============================================================
let s:MenuItem = {}
let g:NERDTreeMenuItem = s:MenuItem
"FUNCTION: MenuItem.All() {{{1
"get all top level menu items
function! s:MenuItem.All()
if !exists("s:menuItems")
let s:menuItems = []
endif
return s:menuItems
endfunction
"FUNCTION: MenuItem.AllEnabled() {{{1
"get all top level menu items that are currently enabled
function! s:MenuItem.AllEnabled()
let toReturn = []
for i in s:MenuItem.All()
if i.enabled()
call add(toReturn, i)
endif
endfor
return toReturn
endfunction
"FUNCTION: MenuItem.Create(options) {{{1
"make a new menu item and add it to the global list
function! s:MenuItem.Create(options)
let newMenuItem = copy(self)
let newMenuItem.text = a:options['text']
let newMenuItem.shortcut = a:options['shortcut']
let newMenuItem.children = []
let newMenuItem.isActiveCallback = -1
if has_key(a:options, 'isActiveCallback')
let newMenuItem.isActiveCallback = a:options['isActiveCallback']
endif
let newMenuItem.callback = -1
if has_key(a:options, 'callback')
let newMenuItem.callback = a:options['callback']
endif
if has_key(a:options, 'parent')
call add(a:options['parent'].children, newMenuItem)
else
call add(s:MenuItem.All(), newMenuItem)
endif
return newMenuItem
endfunction
"FUNCTION: MenuItem.CreateSeparator(options) {{{1
"make a new separator menu item and add it to the global list
function! s:MenuItem.CreateSeparator(options)
let standard_options = { 'text': '--------------------',
\ 'shortcut': -1,
\ 'callback': -1 }
let options = extend(a:options, standard_options, "force")
return s:MenuItem.Create(options)
endfunction
"FUNCTION: MenuItem.CreateSubmenu(options) {{{1
"make a new submenu and add it to global list
function! s:MenuItem.CreateSubmenu(options)
let standard_options = { 'callback': -1 }
let options = extend(a:options, standard_options, "force")
return s:MenuItem.Create(options)
endfunction
"FUNCTION: MenuItem.enabled() {{{1
"return 1 if this menu item should be displayed
"
"delegates off to the isActiveCallback, and defaults to 1 if no callback was
"specified
function! s:MenuItem.enabled()
if self.isActiveCallback != -1
return {self.isActiveCallback}()
endif
return 1
endfunction
"FUNCTION: MenuItem.execute() {{{1
"perform the action behind this menu item, if this menuitem has children then
"display a new menu for them, otherwise deletegate off to the menuitem's
"callback
function! s:MenuItem.execute()
if len(self.children)
let mc = s:MenuController.New(self.children)
call mc.showMenu()
else
if self.callback != -1
call {self.callback}()
endif
endif
endfunction
"FUNCTION: MenuItem.isSeparator() {{{1
"return 1 if this menuitem is a separator
function! s:MenuItem.isSeparator()
return self.callback == -1 && self.children == []
endfunction
"FUNCTION: MenuItem.isSubmenu() {{{1
"return 1 if this menuitem is a submenu
function! s:MenuItem.isSubmenu()
return self.callback == -1 && !empty(self.children)
endfunction
" vim: set sw=4 sts=4 et fdm=marker:

View file

@ -0,0 +1,264 @@
"CLASS: Opener
"============================================================
let s:Opener = {}
let g:NERDTreeOpener = s:Opener
"FUNCTION: Opener._checkToCloseTree(newtab) {{{1
"Check the class options and global options (i.e. NERDTreeQuitOnOpen) to see
"if the tree should be closed now.
"
"Args:
"a:newtab - boolean. If set, only close the tree now if we are opening the
"target in a new tab. This is needed because we have to close tree before we
"leave the tab
function! s:Opener._checkToCloseTree(newtab)
if self._keepopen
return
endif
if (a:newtab && self._where == 't') || !a:newtab
call nerdtree#closeTreeIfQuitOnOpen()
endif
endfunction
"FUNCTION: Opener._gotoTargetWin() {{{1
function! s:Opener._gotoTargetWin()
if b:NERDTreeType ==# "secondary"
if self._where == 'v'
vsplit
elseif self._where == 'h'
split
elseif self._where == 't'
tabnew
endif
else
call self._checkToCloseTree(1)
if self._where == 'v'
call self._newVSplit()
elseif self._where == 'h'
call self._newSplit()
elseif self._where == 't'
tabnew
elseif self._where == 'p'
call self._previousWindow()
endif
call self._checkToCloseTree(0)
endif
endfunction
"FUNCTION: Opener.New(path, opts) {{{1
"Args:
"
"a:path: The path object that is to be opened.
"
"a:opts:
"
"A dictionary containing the following keys (all optional):
" 'where': Specifies whether the node should be opened in new split/tab or in
" the previous window. Can be either 'v' or 'h' or 't' (for open in
" new tab)
" 'reuse': if a window is displaying the file then jump the cursor there
" 'keepopen': dont close the tree window
" 'stay': open the file, but keep the cursor in the tree win
function! s:Opener.New(path, opts)
let newObj = copy(self)
let newObj._path = a:path
let newObj._stay = nerdtree#has_opt(a:opts, 'stay')
let newObj._reuse = nerdtree#has_opt(a:opts, 'reuse')
let newObj._keepopen = nerdtree#has_opt(a:opts, 'keepopen')
let newObj._where = has_key(a:opts, 'where') ? a:opts['where'] : ''
let newObj._treetype = b:NERDTreeType
call newObj._saveCursorPos()
return newObj
endfunction
"FUNCTION: Opener._newSplit() {{{1
function! s:Opener._newSplit()
" Save the user's settings for splitbelow and splitright
let savesplitbelow=&splitbelow
let savesplitright=&splitright
" 'there' will be set to a command to move from the split window
" back to the explorer window
"
" 'back' will be set to a command to move from the explorer window
" back to the newly split window
"
" 'right' and 'below' will be set to the settings needed for
" splitbelow and splitright IF the explorer is the only window.
"
let there= g:NERDTreeWinPos ==# "left" ? "wincmd h" : "wincmd l"
let back = g:NERDTreeWinPos ==# "left" ? "wincmd l" : "wincmd h"
let right= g:NERDTreeWinPos ==# "left"
let below=0
" Attempt to go to adjacent window
call nerdtree#exec(back)
let onlyOneWin = (winnr("$") ==# 1)
" If no adjacent window, set splitright and splitbelow appropriately
if onlyOneWin
let &splitright=right
let &splitbelow=below
else
" found adjacent window - invert split direction
let &splitright=!right
let &splitbelow=!below
endif
let splitMode = onlyOneWin ? "vertical" : ""
" Open the new window
try
exec(splitMode." sp ")
catch /^Vim\%((\a\+)\)\=:E37/
call nerdtree#putCursorInTreeWin()
throw "NERDTree.FileAlreadyOpenAndModifiedError: ". self._path.str() ." is already open and modified."
catch /^Vim\%((\a\+)\)\=:/
"do nothing
endtry
"resize the tree window if no other window was open before
if onlyOneWin
let size = exists("b:NERDTreeOldWindowSize") ? b:NERDTreeOldWindowSize : g:NERDTreeWinSize
call nerdtree#exec(there)
exec("silent ". splitMode ." resize ". size)
call nerdtree#exec('wincmd p')
endif
" Restore splitmode settings
let &splitbelow=savesplitbelow
let &splitright=savesplitright
endfunction
"FUNCTION: Opener._newVSplit() {{{1
function! s:Opener._newVSplit()
let winwidth = winwidth(".")
if winnr("$")==#1
let winwidth = g:NERDTreeWinSize
endif
call nerdtree#exec("wincmd p")
vnew
"resize the nerd tree back to the original size
call nerdtree#putCursorInTreeWin()
exec("silent vertical resize ". winwidth)
call nerdtree#exec('wincmd p')
endfunction
"FUNCTION: Opener.open(target) {{{1
function! s:Opener.open(target)
if self._path.isDirectory
call self._openDirectory(a:target)
else
call self._openFile()
endif
endfunction
"FUNCTION: Opener._openFile() {{{1
function! s:Opener._openFile()
if self._reuse && self._reuseWindow()
return
endif
call self._gotoTargetWin()
if self._treetype ==# "secondary"
call self._path.edit()
else
call self._path.edit()
if self._stay
call self._restoreCursorPos()
endif
endif
endfunction
"FUNCTION: Opener._openDirectory(node) {{{1
function! s:Opener._openDirectory(node)
if self._treetype ==# "secondary"
call self._gotoTargetWin()
call g:NERDTreeCreator.CreateSecondary(a:node.path.str())
else
call self._gotoTargetWin()
if empty(self._where)
call a:node.makeRoot()
call nerdtree#renderView()
call a:node.putCursorHere(0, 0)
elseif self._where == 't'
call g:NERDTreeCreator.CreatePrimary(a:node.path.str())
else
call g:NERDTreeCreator.CreateSecondary(a:node.path.str())
endif
endif
if self._stay
call self._restoreCursorPos()
endif
endfunction
"FUNCTION: Opener._previousWindow() {{{1
function! s:Opener._previousWindow()
if !nerdtree#isWindowUsable(winnr("#")) && nerdtree#firstUsableWindow() ==# -1
call self._newSplit()
else
try
if !nerdtree#isWindowUsable(winnr("#"))
call nerdtree#exec(nerdtree#firstUsableWindow() . "wincmd w")
else
call nerdtree#exec('wincmd p')
endif
catch /^Vim\%((\a\+)\)\=:E37/
call nerdtree#putCursorInTreeWin()
throw "NERDTree.FileAlreadyOpenAndModifiedError: ". self._path.str() ." is already open and modified."
catch /^Vim\%((\a\+)\)\=:/
echo v:exception
endtry
endif
endfunction
"FUNCTION: Opener._restoreCursorPos(){{{1
function! s:Opener._restoreCursorPos()
call nerdtree#exec('normal ' . self._tabnr . 'gt')
call nerdtree#exec(bufwinnr(self._bufnr) . 'wincmd w')
endfunction
"FUNCTION: Opener._reuseWindow(){{{1
"put the cursor in the first window we find for this file
"
"return 1 if we were successful
function! s:Opener._reuseWindow()
"check the current tab for the window
let winnr = bufwinnr('^' . self._path.str() . '$')
if winnr != -1
call nerdtree#exec(winnr . "wincmd w")
call self._checkToCloseTree(0)
return 1
else
"check other tabs
let tabnr = self._path.tabnr()
if tabnr
call self._checkToCloseTree(1)
call nerdtree#exec('normal! ' . tabnr . 'gt')
let winnr = bufwinnr('^' . self._path.str() . '$')
call nerdtree#exec(winnr . "wincmd w")
return 1
endif
endif
return 0
endfunction
"FUNCTION: Opener._saveCursorPos(){{{1
function! s:Opener._saveCursorPos()
let self._bufnr = bufnr("")
let self._tabnr = tabpagenr()
endfunction
" vim: set sw=4 sts=4 et fdm=marker:

View file

@ -0,0 +1,724 @@
"we need to use this number many times for sorting... so we calculate it only
"once here
let s:NERDTreeSortStarIndex = index(g:NERDTreeSortOrder, '*')
"CLASS: Path
"============================================================
let s:Path = {}
let g:NERDTreePath = s:Path
"FUNCTION: Path.AbsolutePathFor(str) {{{1
function! s:Path.AbsolutePathFor(str)
let prependCWD = 0
if nerdtree#runningWindows()
let prependCWD = a:str !~# '^.:\(\\\|\/\)' && a:str !~# '^\(\\\\\|\/\/\)'
else
let prependCWD = a:str !~# '^/'
endif
let toReturn = a:str
if prependCWD
let toReturn = getcwd() . s:Path.Slash() . a:str
endif
return toReturn
endfunction
"FUNCTION: Path.bookmarkNames() {{{1
function! s:Path.bookmarkNames()
if !exists("self._bookmarkNames")
call self.cacheDisplayString()
endif
return self._bookmarkNames
endfunction
"FUNCTION: Path.cacheDisplayString() {{{1
function! s:Path.cacheDisplayString()
let self.cachedDisplayString = self.getLastPathComponent(1)
if self.isExecutable
let self.cachedDisplayString = self.cachedDisplayString . '*'
endif
let self._bookmarkNames = []
for i in g:NERDTreeBookmark.Bookmarks()
if i.path.equals(self)
call add(self._bookmarkNames, i.name)
endif
endfor
if !empty(self._bookmarkNames)
let self.cachedDisplayString .= ' {' . join(self._bookmarkNames) . '}'
endif
if self.isSymLink
let self.cachedDisplayString .= ' -> ' . self.symLinkDest
endif
if self.isReadOnly
let self.cachedDisplayString .= ' [RO]'
endif
endfunction
"FUNCTION: Path.changeToDir() {{{1
function! s:Path.changeToDir()
let dir = self.str({'format': 'Cd'})
if self.isDirectory ==# 0
let dir = self.getParent().str({'format': 'Cd'})
endif
try
execute "cd " . dir
call nerdtree#echo("CWD is now: " . getcwd())
catch
throw "NERDTree.PathChangeError: cannot change CWD to " . dir
endtry
endfunction
"FUNCTION: Path.compareTo() {{{1
"
"Compares this Path to the given path and returns 0 if they are equal, -1 if
"this Path is "less than" the given path, or 1 if it is "greater".
"
"Args:
"path: the path object to compare this to
"
"Return:
"1, -1 or 0
function! s:Path.compareTo(path)
let thisPath = self.getLastPathComponent(1)
let thatPath = a:path.getLastPathComponent(1)
"if the paths are the same then clearly we return 0
if thisPath ==# thatPath
return 0
endif
let thisSS = self.getSortOrderIndex()
let thatSS = a:path.getSortOrderIndex()
"compare the sort sequences, if they are different then the return
"value is easy
if thisSS < thatSS
return -1
elseif thisSS > thatSS
return 1
else
"if the sort sequences are the same then compare the paths
"alphabetically
let pathCompare = g:NERDTreeCaseSensitiveSort ? thisPath <# thatPath : thisPath <? thatPath
if pathCompare
return -1
else
return 1
endif
endif
endfunction
"FUNCTION: Path.Create(fullpath) {{{1
"
"Factory method.
"
"Creates a path object with the given path. The path is also created on the
"filesystem. If the path already exists, a NERDTree.Path.Exists exception is
"thrown. If any other errors occur, a NERDTree.Path exception is thrown.
"
"Args:
"fullpath: the full filesystem path to the file/dir to create
function! s:Path.Create(fullpath)
"bail if the a:fullpath already exists
if isdirectory(a:fullpath) || filereadable(a:fullpath)
throw "NERDTree.CreatePathError: Directory Exists: '" . a:fullpath . "'"
endif
try
"if it ends with a slash, assume its a dir create it
if a:fullpath =~# '\(\\\|\/\)$'
"whack the trailing slash off the end if it exists
let fullpath = substitute(a:fullpath, '\(\\\|\/\)$', '', '')
call mkdir(fullpath, 'p')
"assume its a file and create
else
call writefile([], a:fullpath)
endif
catch
throw "NERDTree.CreatePathError: Could not create path: '" . a:fullpath . "'"
endtry
return s:Path.New(a:fullpath)
endfunction
"FUNCTION: Path.copy(dest) {{{1
"
"Copies the file/dir represented by this Path to the given location
"
"Args:
"dest: the location to copy this dir/file to
function! s:Path.copy(dest)
if !s:Path.CopyingSupported()
throw "NERDTree.CopyingNotSupportedError: Copying is not supported on this OS"
endif
let dest = s:Path.WinToUnixPath(a:dest)
let cmd = g:NERDTreeCopyCmd . " " . escape(self.str(), nerdtree#escChars()) . " " . escape(dest, nerdtree#escChars())
let success = system(cmd)
if success != 0
throw "NERDTree.CopyError: Could not copy ''". self.str() ."'' to: '" . a:dest . "'"
endif
endfunction
"FUNCTION: Path.CopyingSupported() {{{1
"
"returns 1 if copying is supported for this OS
function! s:Path.CopyingSupported()
return exists('g:NERDTreeCopyCmd')
endfunction
"FUNCTION: Path.copyingWillOverwrite(dest) {{{1
"
"returns 1 if copy this path to the given location will cause files to
"overwritten
"
"Args:
"dest: the location this path will be copied to
function! s:Path.copyingWillOverwrite(dest)
if filereadable(a:dest)
return 1
endif
if isdirectory(a:dest)
let path = s:Path.JoinPathStrings(a:dest, self.getLastPathComponent(0))
if filereadable(path)
return 1
endif
endif
endfunction
"FUNCTION: Path.delete() {{{1
"
"Deletes the file represented by this path.
"Deletion of directories is not supported
"
"Throws NERDTree.Path.Deletion exceptions
function! s:Path.delete()
if self.isDirectory
let cmd = g:NERDTreeRemoveDirCmd . self.str({'escape': 1})
let success = system(cmd)
if v:shell_error != 0
throw "NERDTree.PathDeletionError: Could not delete directory: '" . self.str() . "'"
endif
else
let success = delete(self.str())
if success != 0
throw "NERDTree.PathDeletionError: Could not delete file: '" . self.str() . "'"
endif
endif
"delete all bookmarks for this path
for i in self.bookmarkNames()
let bookmark = g:NERDTreeBookmark.BookmarkFor(i)
call bookmark.delete()
endfor
endfunction
"FUNCTION: Path.displayString() {{{1
"
"Returns a string that specifies how the path should be represented as a
"string
function! s:Path.displayString()
if self.cachedDisplayString ==# ""
call self.cacheDisplayString()
endif
return self.cachedDisplayString
endfunction
"FUNCTION: Path.edit() {{{1
function! s:Path.edit()
exec "edit " . self.str({'format': 'Edit'})
endfunction
"FUNCTION: Path.extractDriveLetter(fullpath) {{{1
"
"If running windows, cache the drive letter for this path
function! s:Path.extractDriveLetter(fullpath)
if nerdtree#runningWindows()
if a:fullpath =~ '^\(\\\\\|\/\/\)'
"For network shares, the 'drive' consists of the first two parts of the path, i.e. \\boxname\share
let self.drive = substitute(a:fullpath, '^\(\(\\\\\|\/\/\)[^\\\/]*\(\\\|\/\)[^\\\/]*\).*', '\1', '')
let self.drive = substitute(self.drive, '/', '\', "g")
else
let self.drive = substitute(a:fullpath, '\(^[a-zA-Z]:\).*', '\1', '')
endif
else
let self.drive = ''
endif
endfunction
"FUNCTION: Path.exists() {{{1
"return 1 if this path points to a location that is readable or is a directory
function! s:Path.exists()
let p = self.str()
return filereadable(p) || isdirectory(p)
endfunction
"FUNCTION: Path.getDir() {{{1
"
"Returns this path if it is a directory, else this paths parent.
"
"Return:
"a Path object
function! s:Path.getDir()
if self.isDirectory
return self
else
return self.getParent()
endif
endfunction
"FUNCTION: Path.getParent() {{{1
"
"Returns a new path object for this paths parent
"
"Return:
"a new Path object
function! s:Path.getParent()
if nerdtree#runningWindows()
let path = self.drive . '\' . join(self.pathSegments[0:-2], '\')
else
let path = '/'. join(self.pathSegments[0:-2], '/')
endif
return s:Path.New(path)
endfunction
"FUNCTION: Path.getLastPathComponent(dirSlash) {{{1
"
"Gets the last part of this path.
"
"Args:
"dirSlash: if 1 then a trailing slash will be added to the returned value for
"directory nodes.
function! s:Path.getLastPathComponent(dirSlash)
if empty(self.pathSegments)
return ''
endif
let toReturn = self.pathSegments[-1]
if a:dirSlash && self.isDirectory
let toReturn = toReturn . '/'
endif
return toReturn
endfunction
"FUNCTION: Path.getSortOrderIndex() {{{1
"returns the index of the pattern in g:NERDTreeSortOrder that this path matches
function! s:Path.getSortOrderIndex()
let i = 0
while i < len(g:NERDTreeSortOrder)
if self.getLastPathComponent(1) =~# g:NERDTreeSortOrder[i]
return i
endif
let i = i + 1
endwhile
return s:NERDTreeSortStarIndex
endfunction
"FUNCTION: Path.isUnixHiddenFile() {{{1
"check for unix hidden files
function! s:Path.isUnixHiddenFile()
return self.getLastPathComponent(0) =~# '^\.'
endfunction
"FUNCTION: Path.isUnixHiddenPath() {{{1
"check for unix path with hidden components
function! s:Path.isUnixHiddenPath()
if self.getLastPathComponent(0) =~# '^\.'
return 1
else
for segment in self.pathSegments
if segment =~# '^\.'
return 1
endif
endfor
return 0
endif
endfunction
"FUNCTION: Path.ignore() {{{1
"returns true if this path should be ignored
function! s:Path.ignore()
"filter out the user specified paths to ignore
if b:NERDTreeIgnoreEnabled
for i in g:NERDTreeIgnore
if self._ignorePatternMatches(i)
return 1
endif
endfor
endif
"dont show hidden files unless instructed to
if b:NERDTreeShowHidden ==# 0 && self.isUnixHiddenFile()
return 1
endif
if b:NERDTreeShowFiles ==# 0 && self.isDirectory ==# 0
return 1
endif
if exists("*NERDTreeCustomIgnoreFilter") && NERDTreeCustomIgnoreFilter(self)
return 1
endif
return 0
endfunction
"FUNCTION: Path._ignorePatternMatches(pattern) {{{1
"returns true if this path matches the given ignore pattern
function! s:Path._ignorePatternMatches(pattern)
let pat = a:pattern
if strpart(pat,len(pat)-7) == '[[dir]]'
if !self.isDirectory
return 0
endif
let pat = strpart(pat,0, len(pat)-7)
elseif strpart(pat,len(pat)-8) == '[[file]]'
if self.isDirectory
return 0
endif
let pat = strpart(pat,0, len(pat)-8)
endif
return self.getLastPathComponent(0) =~# pat
endfunction
"FUNCTION: Path.isUnder(path) {{{1
"return 1 if this path is somewhere under the given path in the filesystem.
"
"a:path should be a dir
function! s:Path.isUnder(path)
if a:path.isDirectory == 0
return 0
endif
let this = self.str()
let that = a:path.str()
return stridx(this, that . s:Path.Slash()) == 0
endfunction
"FUNCTION: Path.JoinPathStrings(...) {{{1
function! s:Path.JoinPathStrings(...)
let components = []
for i in a:000
let components = extend(components, split(i, '/'))
endfor
return '/' . join(components, '/')
endfunction
"FUNCTION: Path.equals() {{{1
"
"Determines whether 2 path objects are "equal".
"They are equal if the paths they represent are the same
"
"Args:
"path: the other path obj to compare this with
function! s:Path.equals(path)
return self.str() ==# a:path.str()
endfunction
"FUNCTION: Path.New() {{{1
"The Constructor for the Path object
function! s:Path.New(path)
let newPath = copy(self)
call newPath.readInfoFromDisk(s:Path.AbsolutePathFor(a:path))
let newPath.cachedDisplayString = ""
return newPath
endfunction
"FUNCTION: Path.Slash() {{{1
"return the slash to use for the current OS
function! s:Path.Slash()
return nerdtree#runningWindows() ? '\' : '/'
endfunction
"FUNCTION: Path.Resolve() {{{1
"Invoke the vim resolve() function and return the result
"This is necessary because in some versions of vim resolve() removes trailing
"slashes while in other versions it doesn't. This always removes the trailing
"slash
function! s:Path.Resolve(path)
let tmp = resolve(a:path)
return tmp =~# '.\+/$' ? substitute(tmp, '/$', '', '') : tmp
endfunction
"FUNCTION: Path.readInfoFromDisk(fullpath) {{{1
"
"
"Throws NERDTree.Path.InvalidArguments exception.
function! s:Path.readInfoFromDisk(fullpath)
call self.extractDriveLetter(a:fullpath)
let fullpath = s:Path.WinToUnixPath(a:fullpath)
if getftype(fullpath) ==# "fifo"
throw "NERDTree.InvalidFiletypeError: Cant handle FIFO files: " . a:fullpath
endif
let self.pathSegments = split(fullpath, '/')
let self.isReadOnly = 0
if isdirectory(a:fullpath)
let self.isDirectory = 1
elseif filereadable(a:fullpath)
let self.isDirectory = 0
let self.isReadOnly = filewritable(a:fullpath) ==# 0
else
throw "NERDTree.InvalidArgumentsError: Invalid path = " . a:fullpath
endif
let self.isExecutable = 0
if !self.isDirectory
let self.isExecutable = getfperm(a:fullpath) =~# 'x'
endif
"grab the last part of the path (minus the trailing slash)
let lastPathComponent = self.getLastPathComponent(0)
"get the path to the new node with the parent dir fully resolved
let hardPath = s:Path.Resolve(self.strTrunk()) . '/' . lastPathComponent
"if the last part of the path is a symlink then flag it as such
let self.isSymLink = (s:Path.Resolve(hardPath) != hardPath)
if self.isSymLink
let self.symLinkDest = s:Path.Resolve(fullpath)
"if the link is a dir then slap a / on the end of its dest
if isdirectory(self.symLinkDest)
"we always wanna treat MS windows shortcuts as files for
"simplicity
if hardPath !~# '\.lnk$'
let self.symLinkDest = self.symLinkDest . '/'
endif
endif
endif
endfunction
"FUNCTION: Path.refresh() {{{1
function! s:Path.refresh()
call self.readInfoFromDisk(self.str())
call self.cacheDisplayString()
endfunction
"FUNCTION: Path.rename() {{{1
"
"Renames this node on the filesystem
function! s:Path.rename(newPath)
if a:newPath ==# ''
throw "NERDTree.InvalidArgumentsError: Invalid newPath for renaming = ". a:newPath
endif
let success = rename(self.str(), a:newPath)
if success != 0
throw "NERDTree.PathRenameError: Could not rename: '" . self.str() . "'" . 'to:' . a:newPath
endif
call self.readInfoFromDisk(a:newPath)
for i in self.bookmarkNames()
let b = g:NERDTreeBookmark.BookmarkFor(i)
call b.setPath(copy(self))
endfor
call g:NERDTreeBookmark.Write()
endfunction
"FUNCTION: Path.str() {{{1
"
"Returns a string representation of this Path
"
"Takes an optional dictionary param to specify how the output should be
"formatted.
"
"The dict may have the following keys:
" 'format'
" 'escape'
" 'truncateTo'
"
"The 'format' key may have a value of:
" 'Cd' - a string to be used with the :cd command
" 'Edit' - a string to be used with :e :sp :new :tabedit etc
" 'UI' - a string used in the NERD tree UI
"
"The 'escape' key, if specified will cause the output to be escaped with
"shellescape()
"
"The 'truncateTo' key causes the resulting string to be truncated to the value
"'truncateTo' maps to. A '<' char will be prepended.
function! s:Path.str(...)
let options = a:0 ? a:1 : {}
let toReturn = ""
if has_key(options, 'format')
let format = options['format']
if has_key(self, '_strFor' . format)
exec 'let toReturn = self._strFor' . format . '()'
else
raise 'NERDTree.UnknownFormatError: unknown format "'. format .'"'
endif
else
let toReturn = self._str()
endif
if nerdtree#has_opt(options, 'escape')
let toReturn = shellescape(toReturn)
endif
if has_key(options, 'truncateTo')
let limit = options['truncateTo']
if len(toReturn) > limit
let toReturn = "<" . strpart(toReturn, len(toReturn) - limit + 1)
endif
endif
return toReturn
endfunction
"FUNCTION: Path._strForUI() {{{1
function! s:Path._strForUI()
let toReturn = '/' . join(self.pathSegments, '/')
if self.isDirectory && toReturn != '/'
let toReturn = toReturn . '/'
endif
return toReturn
endfunction
"FUNCTION: Path._strForCd() {{{1
"
" returns a string that can be used with :cd
function! s:Path._strForCd()
return escape(self.str(), nerdtree#escChars())
endfunction
"FUNCTION: Path._strForEdit() {{{1
"
"Return: the string for this path that is suitable to be used with the :edit
"command
function! s:Path._strForEdit()
let p = escape(self.str({'format': 'UI'}), nerdtree#escChars())
let cwd = getcwd() . s:Path.Slash()
"return a relative path if we can
let isRelative = 0
if nerdtree#runningWindows()
let isRelative = stridx(tolower(p), tolower(cwd)) == 0
else
let isRelative = stridx(p, cwd) == 0
endif
if isRelative
let p = strpart(p, strlen(cwd))
"handle the edge case where the file begins with a + (vim interprets
"the +foo in `:e +foo` as an option to :edit)
if p[0] == "+"
let p = '\' . p
endif
endif
if p ==# ''
let p = '.'
endif
return p
endfunction
"FUNCTION: Path._strForGlob() {{{1
function! s:Path._strForGlob()
let lead = s:Path.Slash()
"if we are running windows then slap a drive letter on the front
if nerdtree#runningWindows()
let lead = self.drive . '\'
endif
let toReturn = lead . join(self.pathSegments, s:Path.Slash())
if !nerdtree#runningWindows()
let toReturn = escape(toReturn, nerdtree#escChars())
endif
return toReturn
endfunction
"FUNCTION: Path._str() {{{1
"
"Gets the string path for this path object that is appropriate for the OS.
"EG, in windows c:\foo\bar
" in *nix /foo/bar
function! s:Path._str()
let lead = s:Path.Slash()
"if we are running windows then slap a drive letter on the front
if nerdtree#runningWindows()
let lead = self.drive . '\'
endif
return lead . join(self.pathSegments, s:Path.Slash())
endfunction
"FUNCTION: Path.strTrunk() {{{1
"Gets the path without the last segment on the end.
function! s:Path.strTrunk()
return self.drive . '/' . join(self.pathSegments[0:-2], '/')
endfunction
" FUNCTION: Path.tabnr() {{{1
" return the number of the first tab that is displaying this file
"
" return 0 if no tab was found
function! s:Path.tabnr()
let str = self.str()
for t in range(tabpagenr('$'))
for b in tabpagebuflist(t+1)
if str == expand('#' . b . ':p')
return t+1
endif
endfor
endfor
return 0
endfunction
"FUNCTION: Path.WinToUnixPath(pathstr){{{1
"Takes in a windows path and returns the unix equiv
"
"A class level method
"
"Args:
"pathstr: the windows path to convert
function! s:Path.WinToUnixPath(pathstr)
if !nerdtree#runningWindows()
return a:pathstr
endif
let toReturn = a:pathstr
"remove the x:\ of the front
let toReturn = substitute(toReturn, '^.*:\(\\\|/\)\?', '/', "")
"remove the \\ network share from the front
let toReturn = substitute(toReturn, '^\(\\\\\|\/\/\)[^\\\/]*\(\\\|\/\)[^\\\/]*\(\\\|\/\)\?', '/', "")
"convert all \ chars to /
let toReturn = substitute(toReturn, '\', '/', "g")
return toReturn
endfunction
" vim: set sw=4 sts=4 et fdm=marker:

View file

@ -0,0 +1,528 @@
"CLASS: TreeDirNode
"A subclass of NERDTreeFileNode.
"
"The 'composite' part of the file/dir composite.
"============================================================
let s:TreeDirNode = copy(g:NERDTreeFileNode)
let g:NERDTreeDirNode = s:TreeDirNode
"FUNCTION: TreeDirNode.AbsoluteTreeRoot(){{{1
"class method that returns the highest cached ancestor of the current root
function! s:TreeDirNode.AbsoluteTreeRoot()
let currentNode = b:NERDTreeRoot
while currentNode.parent != {}
let currentNode = currentNode.parent
endwhile
return currentNode
endfunction
"FUNCTION: TreeDirNode.activate([options]) {{{1
unlet s:TreeDirNode.activate
function! s:TreeDirNode.activate(...)
let opts = a:0 ? a:1 : {}
call self.toggleOpen(opts)
call nerdtree#renderView()
call self.putCursorHere(0, 0)
endfunction
"FUNCTION: TreeDirNode.addChild(treenode, inOrder) {{{1
"Adds the given treenode to the list of children for this node
"
"Args:
"-treenode: the node to add
"-inOrder: 1 if the new node should be inserted in sorted order
function! s:TreeDirNode.addChild(treenode, inOrder)
call add(self.children, a:treenode)
let a:treenode.parent = self
if a:inOrder
call self.sortChildren()
endif
endfunction
"FUNCTION: TreeDirNode.close() {{{1
"Closes this directory
function! s:TreeDirNode.close()
let self.isOpen = 0
endfunction
"FUNCTION: TreeDirNode.closeChildren() {{{1
"Closes all the child dir nodes of this node
function! s:TreeDirNode.closeChildren()
for i in self.children
if i.path.isDirectory
call i.close()
call i.closeChildren()
endif
endfor
endfunction
"FUNCTION: TreeDirNode.createChild(path, inOrder) {{{1
"Instantiates a new child node for this node with the given path. The new
"nodes parent is set to this node.
"
"Args:
"path: a Path object that this node will represent/contain
"inOrder: 1 if the new node should be inserted in sorted order
"
"Returns:
"the newly created node
function! s:TreeDirNode.createChild(path, inOrder)
let newTreeNode = g:NERDTreeFileNode.New(a:path)
call self.addChild(newTreeNode, a:inOrder)
return newTreeNode
endfunction
"FUNCTION: TreeDirNode.findNode(path) {{{1
"Will find one of the children (recursively) that has the given path
"
"Args:
"path: a path object
unlet s:TreeDirNode.findNode
function! s:TreeDirNode.findNode(path)
if a:path.equals(self.path)
return self
endif
if stridx(a:path.str(), self.path.str(), 0) ==# -1
return {}
endif
if self.path.isDirectory
for i in self.children
let retVal = i.findNode(a:path)
if retVal != {}
return retVal
endif
endfor
endif
return {}
endfunction
"FUNCTION: TreeDirNode.getChildCount() {{{1
"Returns the number of children this node has
function! s:TreeDirNode.getChildCount()
return len(self.children)
endfunction
"FUNCTION: TreeDirNode.getChild(path) {{{1
"Returns child node of this node that has the given path or {} if no such node
"exists.
"
"This function doesnt not recurse into child dir nodes
"
"Args:
"path: a path object
function! s:TreeDirNode.getChild(path)
if stridx(a:path.str(), self.path.str(), 0) ==# -1
return {}
endif
let index = self.getChildIndex(a:path)
if index ==# -1
return {}
else
return self.children[index]
endif
endfunction
"FUNCTION: TreeDirNode.getChildByIndex(indx, visible) {{{1
"returns the child at the given index
"Args:
"indx: the index to get the child from
"visible: 1 if only the visible children array should be used, 0 if all the
"children should be searched.
function! s:TreeDirNode.getChildByIndex(indx, visible)
let array_to_search = a:visible? self.getVisibleChildren() : self.children
if a:indx > len(array_to_search)
throw "NERDTree.InvalidArgumentsError: Index is out of bounds."
endif
return array_to_search[a:indx]
endfunction
"FUNCTION: TreeDirNode.getChildIndex(path) {{{1
"Returns the index of the child node of this node that has the given path or
"-1 if no such node exists.
"
"This function doesnt not recurse into child dir nodes
"
"Args:
"path: a path object
function! s:TreeDirNode.getChildIndex(path)
if stridx(a:path.str(), self.path.str(), 0) ==# -1
return -1
endif
"do a binary search for the child
let a = 0
let z = self.getChildCount()
while a < z
let mid = (a+z)/2
let diff = a:path.compareTo(self.children[mid].path)
if diff ==# -1
let z = mid
elseif diff ==# 1
let a = mid+1
else
return mid
endif
endwhile
return -1
endfunction
"FUNCTION: TreeDirNode.GetSelected() {{{1
"Returns the current node if it is a dir node, or else returns the current
"nodes parent
unlet s:TreeDirNode.GetSelected
function! s:TreeDirNode.GetSelected()
let currentDir = g:NERDTreeFileNode.GetSelected()
if currentDir != {} && !currentDir.isRoot()
if currentDir.path.isDirectory ==# 0
let currentDir = currentDir.parent
endif
endif
return currentDir
endfunction
"FUNCTION: TreeDirNode.getVisibleChildCount() {{{1
"Returns the number of visible children this node has
function! s:TreeDirNode.getVisibleChildCount()
return len(self.getVisibleChildren())
endfunction
"FUNCTION: TreeDirNode.getVisibleChildren() {{{1
"Returns a list of children to display for this node, in the correct order
"
"Return:
"an array of treenodes
function! s:TreeDirNode.getVisibleChildren()
let toReturn = []
for i in self.children
if i.path.ignore() ==# 0
call add(toReturn, i)
endif
endfor
return toReturn
endfunction
"FUNCTION: TreeDirNode.hasVisibleChildren() {{{1
"returns 1 if this node has any childre, 0 otherwise..
function! s:TreeDirNode.hasVisibleChildren()
return self.getVisibleChildCount() != 0
endfunction
"FUNCTION: TreeDirNode._initChildren() {{{1
"Removes all childen from this node and re-reads them
"
"Args:
"silent: 1 if the function should not echo any "please wait" messages for
"large directories
"
"Return: the number of child nodes read
function! s:TreeDirNode._initChildren(silent)
"remove all the current child nodes
let self.children = []
"get an array of all the files in the nodes dir
let dir = self.path
let globDir = dir.str({'format': 'Glob'})
if version >= 703
let filesStr = globpath(globDir, '*', 1) . "\n" . globpath(globDir, '.*', 1)
else
let filesStr = globpath(globDir, '*') . "\n" . globpath(globDir, '.*')
endif
let files = split(filesStr, "\n")
if !a:silent && len(files) > g:NERDTreeNotificationThreshold
call nerdtree#echo("Please wait, caching a large dir ...")
endif
let invalidFilesFound = 0
for i in files
"filter out the .. and . directories
"Note: we must match .. AND ../ cos sometimes the globpath returns
"../ for path with strange chars (eg $)
if i !~# '\/\.\.\/\?$' && i !~# '\/\.\/\?$'
"put the next file in a new node and attach it
try
let path = g:NERDTreePath.New(i)
call self.createChild(path, 0)
catch /^NERDTree.\(InvalidArguments\|InvalidFiletype\)Error/
let invalidFilesFound += 1
endtry
endif
endfor
call self.sortChildren()
if !a:silent && len(files) > g:NERDTreeNotificationThreshold
call nerdtree#echo("Please wait, caching a large dir ... DONE (". self.getChildCount() ." nodes cached).")
endif
if invalidFilesFound
call nerdtree#echoWarning(invalidFilesFound . " file(s) could not be loaded into the NERD tree")
endif
return self.getChildCount()
endfunction
"FUNCTION: TreeDirNode.New(path) {{{1
"Returns a new TreeNode object with the given path and parent
"
"Args:
"path: a path object representing the full filesystem path to the file/dir that the node represents
unlet s:TreeDirNode.New
function! s:TreeDirNode.New(path)
if a:path.isDirectory != 1
throw "NERDTree.InvalidArgumentsError: A TreeDirNode object must be instantiated with a directory Path object."
endif
let newTreeNode = copy(self)
let newTreeNode.path = a:path
let newTreeNode.isOpen = 0
let newTreeNode.children = []
let newTreeNode.parent = {}
return newTreeNode
endfunction
"FUNCTION: TreeDirNode.open([opts]) {{{1
"Open the dir in the current tree or in a new tree elsewhere.
"
"If opening in the current tree, return the number of cached nodes.
unlet s:TreeDirNode.open
function! s:TreeDirNode.open(...)
let opts = a:0 ? a:1 : {}
if has_key(opts, 'where') && !empty(opts['where'])
let opener = g:NERDTreeOpener.New(self.path, opts)
call opener.open(self)
else
let self.isOpen = 1
if self.children ==# []
return self._initChildren(0)
else
return 0
endif
endif
endfunction
"FUNCTION: TreeDirNode.openAlong([opts]) {{{1
"recursive open the dir if it has only one directory child.
"
"return the level of opened directories.
function! s:TreeDirNode.openAlong(...)
let opts = a:0 ? a:1 : {}
let level = 0
let node = self
while node.path.isDirectory
call node.open(opts)
let level += 1
if node.getVisibleChildCount() == 1
let node = node.getChildByIndex(0, 1)
else
break
endif
endwhile
return level
endfunction
" FUNCTION: TreeDirNode.openExplorer() {{{1
" opens an explorer window for this node in the previous window (could be a
" nerd tree or a netrw)
function! s:TreeDirNode.openExplorer()
call self.open({'where': 'p'})
endfunction
"FUNCTION: TreeDirNode.openInNewTab(options) {{{1
unlet s:TreeDirNode.openInNewTab
function! s:TreeDirNode.openInNewTab(options)
call nerdtree#deprecated('TreeDirNode.openInNewTab', 'is deprecated, use open() instead')
call self.open({'where': 't'})
endfunction
"FUNCTION: TreeDirNode._openInNewTab() {{{1
function! s:TreeDirNode._openInNewTab()
tabnew
call g:NERDTreeCreator.CreatePrimary(self.path.str())
endfunction
"FUNCTION: TreeDirNode.openRecursively() {{{1
"Opens this treenode and all of its children whose paths arent 'ignored'
"because of the file filters.
"
"This method is actually a wrapper for the OpenRecursively2 method which does
"the work.
function! s:TreeDirNode.openRecursively()
call self._openRecursively2(1)
endfunction
"FUNCTION: TreeDirNode._openRecursively2() {{{1
"Opens this all children of this treenode recursively if either:
" *they arent filtered by file filters
" *a:forceOpen is 1
"
"Args:
"forceOpen: 1 if this node should be opened regardless of file filters
function! s:TreeDirNode._openRecursively2(forceOpen)
if self.path.ignore() ==# 0 || a:forceOpen
let self.isOpen = 1
if self.children ==# []
call self._initChildren(1)
endif
for i in self.children
if i.path.isDirectory ==# 1
call i._openRecursively2(0)
endif
endfor
endif
endfunction
"FUNCTION: TreeDirNode.refresh() {{{1
unlet s:TreeDirNode.refresh
function! s:TreeDirNode.refresh()
call self.path.refresh()
"if this node was ever opened, refresh its children
if self.isOpen || !empty(self.children)
"go thru all the files/dirs under this node
let newChildNodes = []
let invalidFilesFound = 0
let dir = self.path
let globDir = dir.str({'format': 'Glob'})
let filesStr = globpath(globDir, '*') . "\n" . globpath(globDir, '.*')
let files = split(filesStr, "\n")
for i in files
"filter out the .. and . directories
"Note: we must match .. AND ../ cos sometimes the globpath returns
"../ for path with strange chars (eg $)
if i !~# '\/\.\.\/\?$' && i !~# '\/\.\/\?$'
try
"create a new path and see if it exists in this nodes children
let path = g:NERDTreePath.New(i)
let newNode = self.getChild(path)
if newNode != {}
call newNode.refresh()
call add(newChildNodes, newNode)
"the node doesnt exist so create it
else
let newNode = g:NERDTreeFileNode.New(path)
let newNode.parent = self
call add(newChildNodes, newNode)
endif
catch /^NERDTree.\(InvalidArguments\|InvalidFiletype\)Error/
let invalidFilesFound = 1
endtry
endif
endfor
"swap this nodes children out for the children we just read/refreshed
let self.children = newChildNodes
call self.sortChildren()
if invalidFilesFound
call nerdtree#echoWarning("some files could not be loaded into the NERD tree")
endif
endif
endfunction
"FUNCTION: TreeDirNode.reveal(path) {{{1
"reveal the given path, i.e. cache and open all treenodes needed to display it
"in the UI
function! s:TreeDirNode.reveal(path)
if !a:path.isUnder(self.path)
throw "NERDTree.InvalidArgumentsError: " . a:path.str() . " should be under " . self.path.str()
endif
call self.open()
if self.path.equals(a:path.getParent())
let n = self.findNode(a:path)
call nerdtree#renderView()
call n.putCursorHere(1,0)
return
endif
let p = a:path
while !p.getParent().equals(self.path)
let p = p.getParent()
endwhile
let n = self.findNode(p)
call n.reveal(a:path)
endfunction
"FUNCTION: TreeDirNode.removeChild(treenode) {{{1
"
"Removes the given treenode from this nodes set of children
"
"Args:
"treenode: the node to remove
"
"Throws a NERDTree.ChildNotFoundError if the given treenode is not found
function! s:TreeDirNode.removeChild(treenode)
for i in range(0, self.getChildCount()-1)
if self.children[i].equals(a:treenode)
call remove(self.children, i)
return
endif
endfor
throw "NERDTree.ChildNotFoundError: child node was not found"
endfunction
"FUNCTION: TreeDirNode.sortChildren() {{{1
"
"Sorts the children of this node according to alphabetical order and the
"directory priority.
"
function! s:TreeDirNode.sortChildren()
let CompareFunc = function("nerdtree#compareNodes")
call sort(self.children, CompareFunc)
endfunction
"FUNCTION: TreeDirNode.toggleOpen([options]) {{{1
"Opens this directory if it is closed and vice versa
function! s:TreeDirNode.toggleOpen(...)
let opts = a:0 ? a:1 : {}
if self.isOpen ==# 1
call self.close()
else
if g:NERDTreeCasadeOpenSingleChildDir == 0
call self.open(opts)
else
call self.openAlong(opts)
endif
endif
endfunction
"FUNCTION: TreeDirNode.transplantChild(newNode) {{{1
"Replaces the child of this with the given node (where the child node's full
"path matches a:newNode's fullpath). The search for the matching node is
"non-recursive
"
"Arg:
"newNode: the node to graft into the tree
function! s:TreeDirNode.transplantChild(newNode)
for i in range(0, self.getChildCount()-1)
if self.children[i].equals(a:newNode)
let self.children[i] = a:newNode
let a:newNode.parent = self
break
endif
endfor
endfunction
" vim: set sw=4 sts=4 et fdm=marker:

View file

@ -0,0 +1,485 @@
"CLASS: TreeFileNode
"This class is the parent of the TreeDirNode class and is the
"'Component' part of the composite design pattern between the treenode
"classes.
"============================================================
let s:TreeFileNode = {}
let g:NERDTreeFileNode = s:TreeFileNode
"FUNCTION: TreeFileNode.activate(...) {{{1
function! s:TreeFileNode.activate(...)
call self.open(a:0 ? a:1 : {})
endfunction
"FUNCTION: TreeFileNode.bookmark(name) {{{1
"bookmark this node with a:name
function! s:TreeFileNode.bookmark(name)
"if a bookmark exists with the same name and the node is cached then save
"it so we can update its display string
let oldMarkedNode = {}
try
let oldMarkedNode = g:NERDTreeBookmark.GetNodeForName(a:name, 1)
catch /^NERDTree.BookmarkNotFoundError/
catch /^NERDTree.BookmarkedNodeNotFoundError/
endtry
call g:NERDTreeBookmark.AddBookmark(a:name, self.path)
call self.path.cacheDisplayString()
call g:NERDTreeBookmark.Write()
if !empty(oldMarkedNode)
call oldMarkedNode.path.cacheDisplayString()
endif
endfunction
"FUNCTION: TreeFileNode.cacheParent() {{{1
"initializes self.parent if it isnt already
function! s:TreeFileNode.cacheParent()
if empty(self.parent)
let parentPath = self.path.getParent()
if parentPath.equals(self.path)
throw "NERDTree.CannotCacheParentError: already at root"
endif
let self.parent = s:TreeFileNode.New(parentPath)
endif
endfunction
"FUNCTION: TreeFileNode.clearBookmarks() {{{1
function! s:TreeFileNode.clearBookmarks()
for i in g:NERDTreeBookmark.Bookmarks()
if i.path.equals(self.path)
call i.delete()
end
endfor
call self.path.cacheDisplayString()
endfunction
"FUNCTION: TreeFileNode.copy(dest) {{{1
function! s:TreeFileNode.copy(dest)
call self.path.copy(a:dest)
let newPath = g:NERDTreePath.New(a:dest)
let parent = b:NERDTreeRoot.findNode(newPath.getParent())
if !empty(parent)
call parent.refresh()
return parent.findNode(newPath)
else
return {}
endif
endfunction
"FUNCTION: TreeFileNode.delete {{{1
"Removes this node from the tree and calls the Delete method for its path obj
function! s:TreeFileNode.delete()
call self.path.delete()
call self.parent.removeChild(self)
endfunction
"FUNCTION: TreeFileNode.displayString() {{{1
"
"Returns a string that specifies how the node should be represented as a
"string
"
"Return:
"a string that can be used in the view to represent this node
function! s:TreeFileNode.displayString()
return self.path.displayString()
endfunction
"FUNCTION: TreeFileNode.equals(treenode) {{{1
"
"Compares this treenode to the input treenode and returns 1 if they are the
"same node.
"
"Use this method instead of == because sometimes when the treenodes contain
"many children, vim seg faults when doing ==
"
"Args:
"treenode: the other treenode to compare to
function! s:TreeFileNode.equals(treenode)
return self.path.str() ==# a:treenode.path.str()
endfunction
"FUNCTION: TreeFileNode.findNode(path) {{{1
"Returns self if this node.path.Equals the given path.
"Returns {} if not equal.
"
"Args:
"path: the path object to compare against
function! s:TreeFileNode.findNode(path)
if a:path.equals(self.path)
return self
endif
return {}
endfunction
"FUNCTION: TreeFileNode.findOpenDirSiblingWithVisibleChildren(direction) {{{1
"
"Finds the next sibling for this node in the indicated direction. This sibling
"must be a directory and may/may not have children as specified.
"
"Args:
"direction: 0 if you want to find the previous sibling, 1 for the next sibling
"
"Return:
"a treenode object or {} if no appropriate sibling could be found
function! s:TreeFileNode.findOpenDirSiblingWithVisibleChildren(direction)
"if we have no parent then we can have no siblings
if self.parent != {}
let nextSibling = self.findSibling(a:direction)
while nextSibling != {}
if nextSibling.path.isDirectory && nextSibling.hasVisibleChildren() && nextSibling.isOpen
return nextSibling
endif
let nextSibling = nextSibling.findSibling(a:direction)
endwhile
endif
return {}
endfunction
"FUNCTION: TreeFileNode.findSibling(direction) {{{1
"
"Finds the next sibling for this node in the indicated direction
"
"Args:
"direction: 0 if you want to find the previous sibling, 1 for the next sibling
"
"Return:
"a treenode object or {} if no sibling could be found
function! s:TreeFileNode.findSibling(direction)
"if we have no parent then we can have no siblings
if self.parent != {}
"get the index of this node in its parents children
let siblingIndx = self.parent.getChildIndex(self.path)
if siblingIndx != -1
"move a long to the next potential sibling node
let siblingIndx = a:direction ==# 1 ? siblingIndx+1 : siblingIndx-1
"keep moving along to the next sibling till we find one that is valid
let numSiblings = self.parent.getChildCount()
while siblingIndx >= 0 && siblingIndx < numSiblings
"if the next node is not an ignored node (i.e. wont show up in the
"view) then return it
if self.parent.children[siblingIndx].path.ignore() ==# 0
return self.parent.children[siblingIndx]
endif
"go to next node
let siblingIndx = a:direction ==# 1 ? siblingIndx+1 : siblingIndx-1
endwhile
endif
endif
return {}
endfunction
"FUNCTION: TreeFileNode.getLineNum(){{{1
"returns the line number this node is rendered on, or -1 if it isnt rendered
function! s:TreeFileNode.getLineNum()
"if the node is the root then return the root line no.
if self.isRoot()
return s:TreeFileNode.GetRootLineNum()
endif
let totalLines = line("$")
"the path components we have matched so far
let pathcomponents = [substitute(b:NERDTreeRoot.path.str({'format': 'UI'}), '/ *$', '', '')]
"the index of the component we are searching for
let curPathComponent = 1
let fullpath = self.path.str({'format': 'UI'})
let lnum = s:TreeFileNode.GetRootLineNum()
while lnum > 0
let lnum = lnum + 1
"have we reached the bottom of the tree?
if lnum ==# totalLines+1
return -1
endif
let curLine = getline(lnum)
let indent = nerdtree#indentLevelFor(curLine)
if indent ==# curPathComponent
let curLine = nerdtree#stripMarkupFromLine(curLine, 1)
let curPath = join(pathcomponents, '/') . '/' . curLine
if stridx(fullpath, curPath, 0) ==# 0
if fullpath ==# curPath || strpart(fullpath, len(curPath)-1,1) ==# '/'
let curLine = substitute(curLine, '/ *$', '', '')
call add(pathcomponents, curLine)
let curPathComponent = curPathComponent + 1
if fullpath ==# curPath
return lnum
endif
endif
endif
endif
endwhile
return -1
endfunction
"FUNCTION: TreeFileNode.GetRootForTab(){{{1
"get the root node for this tab
function! s:TreeFileNode.GetRootForTab()
if nerdtree#treeExistsForTab()
return getbufvar(t:NERDTreeBufName, 'NERDTreeRoot')
end
return {}
endfunction
"FUNCTION: TreeFileNode.GetRootLineNum(){{{1
"gets the line number of the root node
function! s:TreeFileNode.GetRootLineNum()
let rootLine = 1
while getline(rootLine) !~# '^\(/\|<\)'
let rootLine = rootLine + 1
endwhile
return rootLine
endfunction
"FUNCTION: TreeFileNode.GetSelected() {{{1
"gets the treenode that the cursor is currently over
function! s:TreeFileNode.GetSelected()
try
let path = nerdtree#getPath(line("."))
if path ==# {}
return {}
endif
return b:NERDTreeRoot.findNode(path)
catch /^NERDTree/
return {}
endtry
endfunction
"FUNCTION: TreeFileNode.isVisible() {{{1
"returns 1 if this node should be visible according to the tree filters and
"hidden file filters (and their on/off status)
function! s:TreeFileNode.isVisible()
return !self.path.ignore()
endfunction
"FUNCTION: TreeFileNode.isRoot() {{{1
"returns 1 if this node is b:NERDTreeRoot
function! s:TreeFileNode.isRoot()
if !nerdtree#treeExistsForBuf()
throw "NERDTree.NoTreeError: No tree exists for the current buffer"
endif
return self.equals(b:NERDTreeRoot)
endfunction
"FUNCTION: TreeFileNode.makeRoot() {{{1
"Make this node the root of the tree
function! s:TreeFileNode.makeRoot()
if self.path.isDirectory
let b:NERDTreeRoot = self
else
call self.cacheParent()
let b:NERDTreeRoot = self.parent
endif
call b:NERDTreeRoot.open()
"change dir to the dir of the new root if instructed to
if g:NERDTreeChDirMode ==# 2
exec "cd " . b:NERDTreeRoot.path.str({'format': 'Edit'})
endif
silent doautocmd User NERDTreeNewRoot
endfunction
"FUNCTION: TreeFileNode.New(path) {{{1
"Returns a new TreeNode object with the given path and parent
"
"Args:
"path: a path object representing the full filesystem path to the file/dir that the node represents
function! s:TreeFileNode.New(path)
if a:path.isDirectory
return g:NERDTreeDirNode.New(a:path)
else
let newTreeNode = copy(self)
let newTreeNode.path = a:path
let newTreeNode.parent = {}
return newTreeNode
endif
endfunction
"FUNCTION: TreeFileNode.open() {{{1
function! s:TreeFileNode.open(...)
let opts = a:0 ? a:1 : {}
let opener = g:NERDTreeOpener.New(self.path, opts)
call opener.open(self)
endfunction
"FUNCTION: TreeFileNode.openSplit() {{{1
"Open this node in a new window
function! s:TreeFileNode.openSplit()
call nerdtree#deprecated('TreeFileNode.openSplit', 'is deprecated, use .open() instead.')
call self.open({'where': 'h'})
endfunction
"FUNCTION: TreeFileNode.openVSplit() {{{1
"Open this node in a new vertical window
function! s:TreeFileNode.openVSplit()
call nerdtree#deprecated('TreeFileNode.openVSplit', 'is deprecated, use .open() instead.')
call self.open({'where': 'v'})
endfunction
"FUNCTION: TreeFileNode.openInNewTab(options) {{{1
function! s:TreeFileNode.openInNewTab(options)
echomsg 'TreeFileNode.openInNewTab is deprecated'
call self.open(extend({'where': 't'}, a:options))
endfunction
"FUNCTION: TreeFileNode.putCursorHere(isJump, recurseUpward){{{1
"Places the cursor on the line number this node is rendered on
"
"Args:
"isJump: 1 if this cursor movement should be counted as a jump by vim
"recurseUpward: try to put the cursor on the parent if the this node isnt
"visible
function! s:TreeFileNode.putCursorHere(isJump, recurseUpward)
let ln = self.getLineNum()
if ln != -1
if a:isJump
mark '
endif
call cursor(ln, col("."))
else
if a:recurseUpward
let node = self
while node != {} && node.getLineNum() ==# -1
let node = node.parent
call node.open()
endwhile
call nerdtree#renderView()
call node.putCursorHere(a:isJump, 0)
endif
endif
endfunction
"FUNCTION: TreeFileNode.refresh() {{{1
function! s:TreeFileNode.refresh()
call self.path.refresh()
endfunction
"FUNCTION: TreeFileNode.rename() {{{1
"Calls the rename method for this nodes path obj
function! s:TreeFileNode.rename(newName)
let newName = substitute(a:newName, '\(\\\|\/\)$', '', '')
call self.path.rename(newName)
call self.parent.removeChild(self)
let parentPath = self.path.getParent()
let newParent = b:NERDTreeRoot.findNode(parentPath)
if newParent != {}
call newParent.createChild(self.path, 1)
call newParent.refresh()
endif
endfunction
"FUNCTION: TreeFileNode.renderToString {{{1
"returns a string representation for this tree to be rendered in the view
function! s:TreeFileNode.renderToString()
return self._renderToString(0, 0, [], self.getChildCount() ==# 1)
endfunction
"Args:
"depth: the current depth in the tree for this call
"drawText: 1 if we should actually draw the line for this node (if 0 then the
"child nodes are rendered only)
"vertMap: a binary array that indicates whether a vertical bar should be draw
"for each depth in the tree
"isLastChild:true if this curNode is the last child of its parent
function! s:TreeFileNode._renderToString(depth, drawText, vertMap, isLastChild)
let output = ""
if a:drawText ==# 1
let treeParts = ''
"get all the leading spaces and vertical tree parts for this line
if a:depth > 1
for j in a:vertMap[0:-2]
if g:NERDTreeDirArrows
let treeParts = treeParts . ' '
else
if j ==# 1
let treeParts = treeParts . '| '
else
let treeParts = treeParts . ' '
endif
endif
endfor
endif
"get the last vertical tree part for this line which will be different
"if this node is the last child of its parent
if !g:NERDTreeDirArrows
if a:isLastChild
let treeParts = treeParts . '`'
else
let treeParts = treeParts . '|'
endif
endif
"smack the appropriate dir/file symbol on the line before the file/dir
"name itself
if self.path.isDirectory
if self.isOpen
if g:NERDTreeDirArrows
let treeParts = treeParts . '▾ '
else
let treeParts = treeParts . '~'
endif
else
if g:NERDTreeDirArrows
let treeParts = treeParts . '▸ '
else
let treeParts = treeParts . '+'
endif
endif
else
if g:NERDTreeDirArrows
let treeParts = treeParts . ' '
else
let treeParts = treeParts . '-'
endif
endif
let line = treeParts . self.displayString()
let output = output . line . "\n"
endif
"if the node is an open dir, draw its children
if self.path.isDirectory ==# 1 && self.isOpen ==# 1
let childNodesToDraw = self.getVisibleChildren()
if len(childNodesToDraw) > 0
"draw all the nodes children except the last
let lastIndx = len(childNodesToDraw)-1
if lastIndx > 0
for i in childNodesToDraw[0:lastIndx-1]
let output = output . i._renderToString(a:depth + 1, 1, add(copy(a:vertMap), 1), 0)
endfor
endif
"draw the last child, indicating that it IS the last
let output = output . childNodesToDraw[lastIndx]._renderToString(a:depth + 1, 1, add(copy(a:vertMap), 0), 1)
endif
endif
return output
endfunction
" vim: set sw=4 sts=4 et fdm=marker:

View file

@ -0,0 +1,7 @@
# nginx syntax files for Vim.
Copied into a directory to play well with pathogen.
* Original: http://www.vim.org/scripts/script.php?script_id=1886

View file

@ -0,0 +1,2 @@
au BufRead,BufNewFile /etc/nginx/* set ft=nginx
au BufRead,BufNewFile /usr/local/nginx/conf/* set ft=nginx

View file

@ -0,0 +1,9 @@
if exists("b:did_indent")
finish
endif
let b:did_indent = 1
" cindent actually works for nginx' simple file structure
setlocal cindent
" Just make sure that the comments are not reset as defs would be.
setlocal cinkeys-=0#

View file

@ -0,0 +1,664 @@
" Vim syntax file
" Language: nginx.conf
if exists("b:current_syntax")
finish
end
setlocal iskeyword+=.
setlocal iskeyword+=/
setlocal iskeyword+=:
syn match ngxVariable '\$\w\w*'
syn match ngxVariableBlock '\$\w\w*' contained
syn match ngxVariableString '\$\w\w*' contained
syn region ngxBlock start=+^+ end=+{+ contains=ngxComment,ngxDirectiveBlock,ngxVariableBlock,ngxString oneline
syn region ngxString start=+"+ end=+"+ skip=+\\\\\|\\"+ contains=ngxVariableString oneline
syn region ngxString start=+'+ end=+'+ skip=+\\\\\|\\'+ contains=ngxVariableString oneline
syn match ngxComment ' *#.*$'
syn keyword ngxBoolean on
syn keyword ngxBoolean off
syn keyword ngxDirectiveBlock http contained
syn keyword ngxDirectiveBlock mail contained
syn keyword ngxDirectiveBlock events contained
syn keyword ngxDirectiveBlock server contained
syn keyword ngxDirectiveBlock types contained
syn keyword ngxDirectiveBlock location contained
syn keyword ngxDirectiveBlock upstream contained
syn keyword ngxDirectiveBlock charset_map contained
syn keyword ngxDirectiveBlock limit_except contained
syn keyword ngxDirectiveBlock if contained
syn keyword ngxDirectiveBlock geo contained
syn keyword ngxDirectiveBlock map contained
syn keyword ngxDirectiveImportant include
syn keyword ngxDirectiveImportant root
syn keyword ngxDirectiveImportant server
syn keyword ngxDirectiveImportant server_name
syn keyword ngxDirectiveImportant listen
syn keyword ngxDirectiveImportant internal
syn keyword ngxDirectiveImportant proxy_pass
syn keyword ngxDirectiveImportant memcached_pass
syn keyword ngxDirectiveImportant fastcgi_pass
syn keyword ngxDirectiveImportant try_files
syn keyword ngxDirectiveControl break
syn keyword ngxDirectiveControl return
syn keyword ngxDirectiveControl rewrite
syn keyword ngxDirectiveControl set
syn keyword ngxDirectiveError error_page
syn keyword ngxDirectiveError post_action
syn keyword ngxDirectiveDeprecated connections
syn keyword ngxDirectiveDeprecated imap
syn keyword ngxDirectiveDeprecated open_file_cache_retest
syn keyword ngxDirectiveDeprecated optimize_server_names
syn keyword ngxDirectiveDeprecated satisfy_any
syn keyword ngxDirective accept_mutex
syn keyword ngxDirective accept_mutex_delay
syn keyword ngxDirective access_log
syn keyword ngxDirective add_after_body
syn keyword ngxDirective add_before_body
syn keyword ngxDirective add_header
syn keyword ngxDirective addition_types
syn keyword ngxDirective aio
syn keyword ngxDirective alias
syn keyword ngxDirective allow
syn keyword ngxDirective ancient_browser
syn keyword ngxDirective ancient_browser_value
syn keyword ngxDirective auth_basic
syn keyword ngxDirective auth_basic_user_file
syn keyword ngxDirective auth_http
syn keyword ngxDirective auth_http_header
syn keyword ngxDirective auth_http_timeout
syn keyword ngxDirective autoindex
syn keyword ngxDirective autoindex_exact_size
syn keyword ngxDirective autoindex_localtime
syn keyword ngxDirective charset
syn keyword ngxDirective charset_types
syn keyword ngxDirective client_body_buffer_size
syn keyword ngxDirective client_body_in_file_only
syn keyword ngxDirective client_body_in_single_buffer
syn keyword ngxDirective client_body_temp_path
syn keyword ngxDirective client_body_timeout
syn keyword ngxDirective client_header_buffer_size
syn keyword ngxDirective client_header_timeout
syn keyword ngxDirective client_max_body_size
syn keyword ngxDirective connection_pool_size
syn keyword ngxDirective create_full_put_path
syn keyword ngxDirective daemon
syn keyword ngxDirective dav_access
syn keyword ngxDirective dav_methods
syn keyword ngxDirective debug_connection
syn keyword ngxDirective debug_points
syn keyword ngxDirective default_type
syn keyword ngxDirective degradation
syn keyword ngxDirective degrade
syn keyword ngxDirective deny
syn keyword ngxDirective devpoll_changes
syn keyword ngxDirective devpoll_events
syn keyword ngxDirective directio
syn keyword ngxDirective directio_alignment
syn keyword ngxDirective empty_gif
syn keyword ngxDirective env
syn keyword ngxDirective epoll_events
syn keyword ngxDirective error_log
syn keyword ngxDirective eventport_events
syn keyword ngxDirective expires
syn keyword ngxDirective fastcgi_bind
syn keyword ngxDirective fastcgi_buffer_size
syn keyword ngxDirective fastcgi_buffers
syn keyword ngxDirective fastcgi_busy_buffers_size
syn keyword ngxDirective fastcgi_cache
syn keyword ngxDirective fastcgi_cache_key
syn keyword ngxDirective fastcgi_cache_methods
syn keyword ngxDirective fastcgi_cache_min_uses
syn keyword ngxDirective fastcgi_cache_path
syn keyword ngxDirective fastcgi_cache_use_stale
syn keyword ngxDirective fastcgi_cache_valid
syn keyword ngxDirective fastcgi_catch_stderr
syn keyword ngxDirective fastcgi_connect_timeout
syn keyword ngxDirective fastcgi_hide_header
syn keyword ngxDirective fastcgi_ignore_client_abort
syn keyword ngxDirective fastcgi_ignore_headers
syn keyword ngxDirective fastcgi_index
syn keyword ngxDirective fastcgi_intercept_errors
syn keyword ngxDirective fastcgi_max_temp_file_size
syn keyword ngxDirective fastcgi_next_upstream
syn keyword ngxDirective fastcgi_param
syn keyword ngxDirective fastcgi_pass_header
syn keyword ngxDirective fastcgi_pass_request_body
syn keyword ngxDirective fastcgi_pass_request_headers
syn keyword ngxDirective fastcgi_read_timeout
syn keyword ngxDirective fastcgi_send_lowat
syn keyword ngxDirective fastcgi_send_timeout
syn keyword ngxDirective fastcgi_split_path_info
syn keyword ngxDirective fastcgi_store
syn keyword ngxDirective fastcgi_store_access
syn keyword ngxDirective fastcgi_temp_file_write_size
syn keyword ngxDirective fastcgi_temp_path
syn keyword ngxDirective fastcgi_upstream_fail_timeout
syn keyword ngxDirective fastcgi_upstream_max_fails
syn keyword ngxDirective flv
syn keyword ngxDirective geoip_city
syn keyword ngxDirective geoip_country
syn keyword ngxDirective google_perftools_profiles
syn keyword ngxDirective gzip
syn keyword ngxDirective gzip_buffers
syn keyword ngxDirective gzip_comp_level
syn keyword ngxDirective gzip_disable
syn keyword ngxDirective gzip_hash
syn keyword ngxDirective gzip_http_version
syn keyword ngxDirective gzip_min_length
syn keyword ngxDirective gzip_no_buffer
syn keyword ngxDirective gzip_proxied
syn keyword ngxDirective gzip_static
syn keyword ngxDirective gzip_types
syn keyword ngxDirective gzip_vary
syn keyword ngxDirective gzip_window
syn keyword ngxDirective if_modified_since
syn keyword ngxDirective ignore_invalid_headers
syn keyword ngxDirective image_filter
syn keyword ngxDirective image_filter_buffer
syn keyword ngxDirective image_filter_jpeg_quality
syn keyword ngxDirective image_filter_transparency
syn keyword ngxDirective imap_auth
syn keyword ngxDirective imap_capabilities
syn keyword ngxDirective imap_client_buffer
syn keyword ngxDirective index
syn keyword ngxDirective ip_hash
syn keyword ngxDirective keepalive_requests
syn keyword ngxDirective keepalive_timeout
syn keyword ngxDirective kqueue_changes
syn keyword ngxDirective kqueue_events
syn keyword ngxDirective large_client_header_buffers
syn keyword ngxDirective limit_conn
syn keyword ngxDirective limit_conn_log_level
syn keyword ngxDirective limit_rate
syn keyword ngxDirective limit_rate_after
syn keyword ngxDirective limit_req
syn keyword ngxDirective limit_req_log_level
syn keyword ngxDirective limit_req_zone
syn keyword ngxDirective limit_zone
syn keyword ngxDirective lingering_time
syn keyword ngxDirective lingering_timeout
syn keyword ngxDirective lock_file
syn keyword ngxDirective log_format
syn keyword ngxDirective log_not_found
syn keyword ngxDirective log_subrequest
syn keyword ngxDirective map_hash_bucket_size
syn keyword ngxDirective map_hash_max_size
syn keyword ngxDirective master_process
syn keyword ngxDirective memcached_bind
syn keyword ngxDirective memcached_buffer_size
syn keyword ngxDirective memcached_connect_timeout
syn keyword ngxDirective memcached_next_upstream
syn keyword ngxDirective memcached_read_timeout
syn keyword ngxDirective memcached_send_timeout
syn keyword ngxDirective memcached_upstream_fail_timeout
syn keyword ngxDirective memcached_upstream_max_fails
syn keyword ngxDirective merge_slashes
syn keyword ngxDirective min_delete_depth
syn keyword ngxDirective modern_browser
syn keyword ngxDirective modern_browser_value
syn keyword ngxDirective msie_padding
syn keyword ngxDirective msie_refresh
syn keyword ngxDirective multi_accept
syn keyword ngxDirective open_file_cache
syn keyword ngxDirective open_file_cache_errors
syn keyword ngxDirective open_file_cache_events
syn keyword ngxDirective open_file_cache_min_uses
syn keyword ngxDirective open_file_cache_valid
syn keyword ngxDirective open_log_file_cache
syn keyword ngxDirective output_buffers
syn keyword ngxDirective override_charset
syn keyword ngxDirective perl
syn keyword ngxDirective perl_modules
syn keyword ngxDirective perl_require
syn keyword ngxDirective perl_set
syn keyword ngxDirective pid
syn keyword ngxDirective pop3_auth
syn keyword ngxDirective pop3_capabilities
syn keyword ngxDirective port_in_redirect
syn keyword ngxDirective postpone_gzipping
syn keyword ngxDirective postpone_output
syn keyword ngxDirective protocol
syn keyword ngxDirective proxy
syn keyword ngxDirective proxy_bind
syn keyword ngxDirective proxy_buffer
syn keyword ngxDirective proxy_buffer_size
syn keyword ngxDirective proxy_buffering
syn keyword ngxDirective proxy_buffers
syn keyword ngxDirective proxy_busy_buffers_size
syn keyword ngxDirective proxy_cache
syn keyword ngxDirective proxy_cache_key
syn keyword ngxDirective proxy_cache_methods
syn keyword ngxDirective proxy_cache_min_uses
syn keyword ngxDirective proxy_cache_path
syn keyword ngxDirective proxy_cache_use_stale
syn keyword ngxDirective proxy_cache_valid
syn keyword ngxDirective proxy_connect_timeout
syn keyword ngxDirective proxy_headers_hash_bucket_size
syn keyword ngxDirective proxy_headers_hash_max_size
syn keyword ngxDirective proxy_hide_header
syn keyword ngxDirective proxy_ignore_client_abort
syn keyword ngxDirective proxy_ignore_headers
syn keyword ngxDirective proxy_intercept_errors
syn keyword ngxDirective proxy_max_temp_file_size
syn keyword ngxDirective proxy_method
syn keyword ngxDirective proxy_next_upstream
syn keyword ngxDirective proxy_pass_error_message
syn keyword ngxDirective proxy_pass_header
syn keyword ngxDirective proxy_pass_request_body
syn keyword ngxDirective proxy_pass_request_headers
syn keyword ngxDirective proxy_read_timeout
syn keyword ngxDirective proxy_redirect
syn keyword ngxDirective proxy_send_lowat
syn keyword ngxDirective proxy_send_timeout
syn keyword ngxDirective proxy_set_body
syn keyword ngxDirective proxy_set_header
syn keyword ngxDirective proxy_ssl_session_reuse
syn keyword ngxDirective proxy_store
syn keyword ngxDirective proxy_store_access
syn keyword ngxDirective proxy_temp_file_write_size
syn keyword ngxDirective proxy_temp_path
syn keyword ngxDirective proxy_timeout
syn keyword ngxDirective proxy_upstream_fail_timeout
syn keyword ngxDirective proxy_upstream_max_fails
syn keyword ngxDirective random_index
syn keyword ngxDirective read_ahead
syn keyword ngxDirective real_ip_header
syn keyword ngxDirective recursive_error_pages
syn keyword ngxDirective request_pool_size
syn keyword ngxDirective reset_timedout_connection
syn keyword ngxDirective resolver
syn keyword ngxDirective resolver_timeout
syn keyword ngxDirective rewrite_log
syn keyword ngxDirective rtsig_overflow_events
syn keyword ngxDirective rtsig_overflow_test
syn keyword ngxDirective rtsig_overflow_threshold
syn keyword ngxDirective rtsig_signo
syn keyword ngxDirective satisfy
syn keyword ngxDirective secure_link_secret
syn keyword ngxDirective send_lowat
syn keyword ngxDirective send_timeout
syn keyword ngxDirective sendfile
syn keyword ngxDirective sendfile_max_chunk
syn keyword ngxDirective server_name_in_redirect
syn keyword ngxDirective server_names_hash_bucket_size
syn keyword ngxDirective server_names_hash_max_size
syn keyword ngxDirective server_tokens
syn keyword ngxDirective set_real_ip_from
syn keyword ngxDirective smtp_auth
syn keyword ngxDirective smtp_capabilities
syn keyword ngxDirective smtp_client_buffer
syn keyword ngxDirective smtp_greeting_delay
syn keyword ngxDirective so_keepalive
syn keyword ngxDirective source_charset
syn keyword ngxDirective ssi
syn keyword ngxDirective ssi_ignore_recycled_buffers
syn keyword ngxDirective ssi_min_file_chunk
syn keyword ngxDirective ssi_silent_errors
syn keyword ngxDirective ssi_types
syn keyword ngxDirective ssi_value_length
syn keyword ngxDirective ssl
syn keyword ngxDirective ssl_certificate
syn keyword ngxDirective ssl_certificate_key
syn keyword ngxDirective ssl_ciphers
syn keyword ngxDirective ssl_client_certificate
syn keyword ngxDirective ssl_crl
syn keyword ngxDirective ssl_dhparam
syn keyword ngxDirective ssl_engine
syn keyword ngxDirective ssl_prefer_server_ciphers
syn keyword ngxDirective ssl_protocols
syn keyword ngxDirective ssl_session_cache
syn keyword ngxDirective ssl_session_timeout
syn keyword ngxDirective ssl_verify_client
syn keyword ngxDirective ssl_verify_depth
syn keyword ngxDirective starttls
syn keyword ngxDirective stub_status
syn keyword ngxDirective sub_filter
syn keyword ngxDirective sub_filter_once
syn keyword ngxDirective sub_filter_types
syn keyword ngxDirective tcp_nodelay
syn keyword ngxDirective tcp_nopush
syn keyword ngxDirective thread_stack_size
syn keyword ngxDirective timeout
syn keyword ngxDirective timer_resolution
syn keyword ngxDirective types_hash_bucket_size
syn keyword ngxDirective types_hash_max_size
syn keyword ngxDirective underscores_in_headers
syn keyword ngxDirective uninitialized_variable_warn
syn keyword ngxDirective use
syn keyword ngxDirective user
syn keyword ngxDirective userid
syn keyword ngxDirective userid_domain
syn keyword ngxDirective userid_expires
syn keyword ngxDirective userid_mark
syn keyword ngxDirective userid_name
syn keyword ngxDirective userid_p3p
syn keyword ngxDirective userid_path
syn keyword ngxDirective userid_service
syn keyword ngxDirective valid_referers
syn keyword ngxDirective variables_hash_bucket_size
syn keyword ngxDirective variables_hash_max_size
syn keyword ngxDirective worker_connections
syn keyword ngxDirective worker_cpu_affinity
syn keyword ngxDirective worker_priority
syn keyword ngxDirective worker_processes
syn keyword ngxDirective worker_rlimit_core
syn keyword ngxDirective worker_rlimit_nofile
syn keyword ngxDirective worker_rlimit_sigpending
syn keyword ngxDirective worker_threads
syn keyword ngxDirective working_directory
syn keyword ngxDirective xclient
syn keyword ngxDirective xml_entities
syn keyword ngxDirective xslt_stylesheet
syn keyword ngxDirective xslt_types
" 3rd party module list:
" http://wiki.nginx.org/Nginx3rdPartyModules
" Accept Language Module <http://wiki.nginx.org/NginxAcceptLanguageModule>
" Parses the Accept-Language header and gives the most suitable locale from a list of supported locales.
syn keyword ngxDirectiveThirdParty set_from_accept_language
" Access Key Module <http://wiki.nginx.org/NginxHttpAccessKeyModule>
" Denies access unless the request URL contains an access key.
syn keyword ngxDirectiveThirdParty accesskey
syn keyword ngxDirectiveThirdParty accesskey_arg
syn keyword ngxDirectiveThirdParty accesskey_hashmethod
syn keyword ngxDirectiveThirdParty accesskey_signature
" Auth PAM Module <http://web.iti.upv.es/~sto/nginx/>
" HTTP Basic Authentication using PAM.
syn keyword ngxDirectiveThirdParty auth_pam
syn keyword ngxDirectiveThirdParty auth_pam_service_name
" Cache Purge Module <http://labs.frickle.com/nginx_ngx_cache_purge/>
" Module adding ability to purge content from FastCGI and proxy caches.
syn keyword ngxDirectiveThirdParty fastcgi_cache_purge
syn keyword ngxDirectiveThirdParty proxy_cache_purge
" Chunkin Module <http://wiki.nginx.org/NginxHttpChunkinModule>
" HTTP 1.1 chunked-encoding request body support for Nginx.
syn keyword ngxDirectiveThirdParty chunkin
syn keyword ngxDirectiveThirdParty chunkin_keepalive
syn keyword ngxDirectiveThirdParty chunkin_max_chunks_per_buf
syn keyword ngxDirectiveThirdParty chunkin_resume
" Circle GIF Module <http://wiki.nginx.org/NginxHttpCircleGifModule>
" Generates simple circle images with the colors and size specified in the URL.
syn keyword ngxDirectiveThirdParty circle_gif
syn keyword ngxDirectiveThirdParty circle_gif_max_radius
syn keyword ngxDirectiveThirdParty circle_gif_min_radius
syn keyword ngxDirectiveThirdParty circle_gif_step_radius
" Drizzle Module <http://github.com/chaoslawful/drizzle-nginx-module>
" Make nginx talk directly to mysql, drizzle, and sqlite3 by libdrizzle.
syn keyword ngxDirectiveThirdParty drizzle_connect_timeout
syn keyword ngxDirectiveThirdParty drizzle_dbname
syn keyword ngxDirectiveThirdParty drizzle_keepalive
syn keyword ngxDirectiveThirdParty drizzle_module_header
syn keyword ngxDirectiveThirdParty drizzle_pass
syn keyword ngxDirectiveThirdParty drizzle_query
syn keyword ngxDirectiveThirdParty drizzle_recv_cols_timeout
syn keyword ngxDirectiveThirdParty drizzle_recv_rows_timeout
syn keyword ngxDirectiveThirdParty drizzle_send_query_timeout
syn keyword ngxDirectiveThirdParty drizzle_server
" Echo Module <http://wiki.nginx.org/NginxHttpEchoModule>
" Brings 'echo', 'sleep', 'time', 'exec' and more shell-style goodies to Nginx config file.
syn keyword ngxDirectiveThirdParty echo
syn keyword ngxDirectiveThirdParty echo_after_body
syn keyword ngxDirectiveThirdParty echo_before_body
syn keyword ngxDirectiveThirdParty echo_blocking_sleep
syn keyword ngxDirectiveThirdParty echo_duplicate
syn keyword ngxDirectiveThirdParty echo_end
syn keyword ngxDirectiveThirdParty echo_exec
syn keyword ngxDirectiveThirdParty echo_flush
syn keyword ngxDirectiveThirdParty echo_foreach_split
syn keyword ngxDirectiveThirdParty echo_location
syn keyword ngxDirectiveThirdParty echo_location_async
syn keyword ngxDirectiveThirdParty echo_read_request_body
syn keyword ngxDirectiveThirdParty echo_request_body
syn keyword ngxDirectiveThirdParty echo_reset_timer
syn keyword ngxDirectiveThirdParty echo_sleep
syn keyword ngxDirectiveThirdParty echo_subrequest
syn keyword ngxDirectiveThirdParty echo_subrequest_async
" Events Module <http://docs.dutov.org/nginx_modules_events_en.html>
" Privides options for start/stop events.
syn keyword ngxDirectiveThirdParty on_start
syn keyword ngxDirectiveThirdParty on_stop
" EY Balancer Module <http://github.com/ry/nginx-ey-balancer>
" Adds a request queue to Nginx that allows the limiting of concurrent requests passed to the upstream.
syn keyword ngxDirectiveThirdParty max_connections
syn keyword ngxDirectiveThirdParty max_connections_max_queue_length
syn keyword ngxDirectiveThirdParty max_connections_queue_timeout
" Fancy Indexes Module <https://connectical.com/projects/ngx-fancyindex/wiki>
" Like the built-in autoindex module, but fancier.
syn keyword ngxDirectiveThirdParty fancyindex
syn keyword ngxDirectiveThirdParty fancyindex_exact_size
syn keyword ngxDirectiveThirdParty fancyindex_footer
syn keyword ngxDirectiveThirdParty fancyindex_header
syn keyword ngxDirectiveThirdParty fancyindex_localtime
syn keyword ngxDirectiveThirdParty fancyindex_readme
syn keyword ngxDirectiveThirdParty fancyindex_readme_mode
" GeoIP Module (DEPRECATED) <http://wiki.nginx.org/NginxHttp3rdPartyGeoIPModule>
" Country code lookups via the MaxMind GeoIP API.
syn keyword ngxDirectiveThirdParty geoip_country_file
" Headers More Module <http://wiki.nginx.org/NginxHttpHeadersMoreModule>
" Set and clear input and output headers...more than "add"!
syn keyword ngxDirectiveThirdParty more_clear_headers
syn keyword ngxDirectiveThirdParty more_clear_input_headers
syn keyword ngxDirectiveThirdParty more_set_headers
syn keyword ngxDirectiveThirdParty more_set_input_headers
" HTTP Push Module <http://pushmodule.slact.net/>
" Turn Nginx into an adept long-polling HTTP Push (Comet) server.
syn keyword ngxDirectiveThirdParty push_buffer_size
syn keyword ngxDirectiveThirdParty push_listener
syn keyword ngxDirectiveThirdParty push_message_timeout
syn keyword ngxDirectiveThirdParty push_queue_messages
syn keyword ngxDirectiveThirdParty push_sender
" HTTP Redis Module <http://people.FreeBSD.ORG/~osa/ngx_http_redis-0.3.1.tar.gz>>
" Redis <http://code.google.com/p/redis/> support.>
syn keyword ngxDirectiveThirdParty redis_bind
syn keyword ngxDirectiveThirdParty redis_buffer_size
syn keyword ngxDirectiveThirdParty redis_connect_timeout
syn keyword ngxDirectiveThirdParty redis_next_upstream
syn keyword ngxDirectiveThirdParty redis_pass
syn keyword ngxDirectiveThirdParty redis_read_timeout
syn keyword ngxDirectiveThirdParty redis_send_timeout
" HTTP JavaScript Module <http://wiki.github.com/kung-fu-tzu/ngx_http_js_module>
" Embedding SpiderMonkey. Nearly full port on Perl module.
syn keyword ngxDirectiveThirdParty js
syn keyword ngxDirectiveThirdParty js_filter
syn keyword ngxDirectiveThirdParty js_filter_types
syn keyword ngxDirectiveThirdParty js_load
syn keyword ngxDirectiveThirdParty js_maxmem
syn keyword ngxDirectiveThirdParty js_require
syn keyword ngxDirectiveThirdParty js_set
syn keyword ngxDirectiveThirdParty js_utf8
" Log Request Speed <http://wiki.nginx.org/NginxHttpLogRequestSpeed>
" Log the time it took to process each request.
syn keyword ngxDirectiveThirdParty log_request_speed_filter
syn keyword ngxDirectiveThirdParty log_request_speed_filter_timeout
" Memc Module <http://wiki.nginx.org/NginxHttpMemcModule>
" An extended version of the standard memcached module that supports set, add, delete, and many more memcached commands.
syn keyword ngxDirectiveThirdParty memc_buffer_size
syn keyword ngxDirectiveThirdParty memc_cmds_allowed
syn keyword ngxDirectiveThirdParty memc_connect_timeout
syn keyword ngxDirectiveThirdParty memc_flags_to_last_modified
syn keyword ngxDirectiveThirdParty memc_next_upstream
syn keyword ngxDirectiveThirdParty memc_pass
syn keyword ngxDirectiveThirdParty memc_read_timeout
syn keyword ngxDirectiveThirdParty memc_send_timeout
syn keyword ngxDirectiveThirdParty memc_upstream_fail_timeout
syn keyword ngxDirectiveThirdParty memc_upstream_max_fails
" Mogilefs Module <http://www.grid.net.ru/nginx/mogilefs.en.html>
" Implements a MogileFS client, provides a replace to the Perlbal reverse proxy of the original MogileFS.
syn keyword ngxDirectiveThirdParty mogilefs_connect_timeout
syn keyword ngxDirectiveThirdParty mogilefs_domain
syn keyword ngxDirectiveThirdParty mogilefs_methods
syn keyword ngxDirectiveThirdParty mogilefs_noverify
syn keyword ngxDirectiveThirdParty mogilefs_pass
syn keyword ngxDirectiveThirdParty mogilefs_read_timeout
syn keyword ngxDirectiveThirdParty mogilefs_send_timeout
syn keyword ngxDirectiveThirdParty mogilefs_tracker
" MP4 Streaming Lite Module <http://wiki.nginx.org/NginxMP4StreamingLite>
" Will seek to a certain time within H.264/MP4 files when provided with a 'start' parameter in the URL.
syn keyword ngxDirectiveThirdParty mp4
" Nginx Notice Module <http://xph.us/software/nginx-notice/>
" Serve static file to POST requests.
syn keyword ngxDirectiveThirdParty notice
syn keyword ngxDirectiveThirdParty notice_type
" Phusion Passenger <http://www.modrails.com/documentation.html>
" Easy and robust deployment of Ruby on Rails application on Apache and Nginx webservers.
syn keyword ngxDirectiveThirdParty passenger_base_uri
syn keyword ngxDirectiveThirdParty passenger_default_user
syn keyword ngxDirectiveThirdParty passenger_enabled
syn keyword ngxDirectiveThirdParty passenger_log_level
syn keyword ngxDirectiveThirdParty passenger_max_instances_per_app
syn keyword ngxDirectiveThirdParty passenger_max_pool_size
syn keyword ngxDirectiveThirdParty passenger_pool_idle_time
syn keyword ngxDirectiveThirdParty passenger_root
syn keyword ngxDirectiveThirdParty passenger_ruby
syn keyword ngxDirectiveThirdParty passenger_use_global_queue
syn keyword ngxDirectiveThirdParty passenger_user_switching
syn keyword ngxDirectiveThirdParty rack_env
syn keyword ngxDirectiveThirdParty rails_app_spawner_idle_time
syn keyword ngxDirectiveThirdParty rails_env
syn keyword ngxDirectiveThirdParty rails_framework_spawner_idle_time
syn keyword ngxDirectiveThirdParty rails_spawn_method
" RDS JSON Module <http://github.com/agentzh/rds-json-nginx-module>
" Help ngx_drizzle and other DBD modules emit JSON data.
syn keyword ngxDirectiveThirdParty rds_json
syn keyword ngxDirectiveThirdParty rds_json_content_type
syn keyword ngxDirectiveThirdParty rds_json_format
syn keyword ngxDirectiveThirdParty rds_json_ret
" RRD Graph Module <http://wiki.nginx.org/NginxNgx_rrd_graph>
" This module provides an HTTP interface to RRDtool's graphing facilities.
syn keyword ngxDirectiveThirdParty rrd_graph
syn keyword ngxDirectiveThirdParty rrd_graph_root
" Secure Download <http://wiki.nginx.org/NginxHttpSecureDownload>
" Create expiring links.
syn keyword ngxDirectiveThirdParty secure_download
syn keyword ngxDirectiveThirdParty secure_download_fail_location
syn keyword ngxDirectiveThirdParty secure_download_path_mode
syn keyword ngxDirectiveThirdParty secure_download_secret
" SlowFS Cache Module <http://labs.frickle.com/nginx_ngx_slowfs_cache/>
" Module adding ability to cache static files.
syn keyword ngxDirectiveThirdParty slowfs_big_file_size
syn keyword ngxDirectiveThirdParty slowfs_cache
syn keyword ngxDirectiveThirdParty slowfs_cache_key
syn keyword ngxDirectiveThirdParty slowfs_cache_min_uses
syn keyword ngxDirectiveThirdParty slowfs_cache_path
syn keyword ngxDirectiveThirdParty slowfs_cache_purge
syn keyword ngxDirectiveThirdParty slowfs_cache_valid
syn keyword ngxDirectiveThirdParty slowfs_temp_path
" Strip Module <http://wiki.nginx.org/NginxHttpStripModule>
" Whitespace remover.
syn keyword ngxDirectiveThirdParty strip
" Substitutions Module <http://wiki.nginx.org/NginxHttpSubsModule>
" A filter module which can do both regular expression and fixed string substitutions on response bodies.
syn keyword ngxDirectiveThirdParty subs_filter
syn keyword ngxDirectiveThirdParty subs_filter_types
" Supervisord Module <http://labs.frickle.com/nginx_ngx_supervisord/>
" Module providing nginx with API to communicate with supervisord and manage (start/stop) backends on-demand.
syn keyword ngxDirectiveThirdParty supervisord
syn keyword ngxDirectiveThirdParty supervisord_inherit_backend_status
syn keyword ngxDirectiveThirdParty supervisord_name
syn keyword ngxDirectiveThirdParty supervisord_start
syn keyword ngxDirectiveThirdParty supervisord_stop
" Upload Module <http://www.grid.net.ru/nginx/upload.en.html>
" Parses multipart/form-data allowing arbitrary handling of uploaded files.
syn keyword ngxDirectiveThirdParty upload_aggregate_form_field
syn keyword ngxDirectiveThirdParty upload_buffer_size
syn keyword ngxDirectiveThirdParty upload_cleanup
syn keyword ngxDirectiveThirdParty upload_limit_rate
syn keyword ngxDirectiveThirdParty upload_max_file_size
syn keyword ngxDirectiveThirdParty upload_max_output_body_len
syn keyword ngxDirectiveThirdParty upload_max_part_header_len
syn keyword ngxDirectiveThirdParty upload_pass
syn keyword ngxDirectiveThirdParty upload_pass_args
syn keyword ngxDirectiveThirdParty upload_pass_form_field
syn keyword ngxDirectiveThirdParty upload_set_form_field
syn keyword ngxDirectiveThirdParty upload_store
syn keyword ngxDirectiveThirdParty upload_store_access
" Upload Progress Module <http://wiki.nginx.org/NginxHttpUploadProgressModule>
" Tracks and reports upload progress.
syn keyword ngxDirectiveThirdParty report_uploads
syn keyword ngxDirectiveThirdParty track_uploads
syn keyword ngxDirectiveThirdParty upload_progress
syn keyword ngxDirectiveThirdParty upload_progress_content_type
syn keyword ngxDirectiveThirdParty upload_progress_header
syn keyword ngxDirectiveThirdParty upload_progress_json_output
syn keyword ngxDirectiveThirdParty upload_progress_template
" Upstream Fair Balancer <http://wiki.nginx.org/NginxHttpUpstreamFairModule>
" Sends an incoming request to the least-busy backend server, rather than distributing requests round-robin.
syn keyword ngxDirectiveThirdParty fair
syn keyword ngxDirectiveThirdParty upstream_fair_shm_size
" Upstream Consistent Hash <http://wiki.nginx.org/NginxHttpUpstreamConsistentHash>
" Select backend based on Consistent hash ring.
syn keyword ngxDirectiveThirdParty consistent_hash
" Upstream Hash Module <http://wiki.nginx.org/NginxHttpUpstreamRequestHashModule>
" Provides simple upstream load distribution by hashing a configurable variable.
syn keyword ngxDirectiveThirdParty hash
syn keyword ngxDirectiveThirdParty hash_again
" XSS Module <http://github.com/agentzh/xss-nginx-module>
" Native support for cross-site scripting (XSS) in an nginx.
syn keyword ngxDirectiveThirdParty xss_callback_arg
syn keyword ngxDirectiveThirdParty xss_get
syn keyword ngxDirectiveThirdParty xss_input_types
syn keyword ngxDirectiveThirdParty xss_output_type
" highlight
hi link ngxComment Comment
hi link ngxVariable Identifier
hi link ngxVariableBlock Identifier
hi link ngxVariableString PreProc
hi link ngxBlock Normal
hi link ngxString String
hi link ngxBoolean Boolean
hi link ngxDirectiveBlock Statement
hi link ngxDirectiveImportant Type
hi link ngxDirectiveControl Keyword
hi link ngxDirectiveError Constant
hi link ngxDirectiveDeprecated Error
hi link ngxDirective Identifier
hi link ngxDirectiveThirdParty Special
let b:current_syntax = "nginx"

View file

@ -0,0 +1,3 @@
This is a mirror of http://www.vim.org/scripts/script.php?script_id=1886
nginx.vim highlights configuration files for nginx, the high-performance web server (see http://nginx.net).

View file

@ -0,0 +1,664 @@
" Vim syntax file
" Language: nginx.conf
if exists("b:current_syntax")
finish
end
setlocal iskeyword+=.
setlocal iskeyword+=/
setlocal iskeyword+=:
syn match ngxVariable '\$\w\w*'
syn match ngxVariableBlock '\$\w\w*' contained
syn match ngxVariableString '\$\w\w*' contained
syn region ngxBlock start=+^+ end=+{+ contains=ngxComment,ngxDirectiveBlock,ngxVariableBlock,ngxString oneline
syn region ngxString start=+"+ end=+"+ skip=+\\\\\|\\"+ contains=ngxVariableString oneline
syn region ngxString start=+'+ end=+'+ skip=+\\\\\|\\'+ contains=ngxVariableString oneline
syn match ngxComment ' *#.*$'
syn keyword ngxBoolean on
syn keyword ngxBoolean off
syn keyword ngxDirectiveBlock http contained
syn keyword ngxDirectiveBlock mail contained
syn keyword ngxDirectiveBlock events contained
syn keyword ngxDirectiveBlock server contained
syn keyword ngxDirectiveBlock types contained
syn keyword ngxDirectiveBlock location contained
syn keyword ngxDirectiveBlock upstream contained
syn keyword ngxDirectiveBlock charset_map contained
syn keyword ngxDirectiveBlock limit_except contained
syn keyword ngxDirectiveBlock if contained
syn keyword ngxDirectiveBlock geo contained
syn keyword ngxDirectiveBlock map contained
syn keyword ngxDirectiveImportant include
syn keyword ngxDirectiveImportant root
syn keyword ngxDirectiveImportant server
syn keyword ngxDirectiveImportant server_name
syn keyword ngxDirectiveImportant listen
syn keyword ngxDirectiveImportant internal
syn keyword ngxDirectiveImportant proxy_pass
syn keyword ngxDirectiveImportant memcached_pass
syn keyword ngxDirectiveImportant fastcgi_pass
syn keyword ngxDirectiveImportant try_files
syn keyword ngxDirectiveControl break
syn keyword ngxDirectiveControl return
syn keyword ngxDirectiveControl rewrite
syn keyword ngxDirectiveControl set
syn keyword ngxDirectiveError error_page
syn keyword ngxDirectiveError post_action
syn keyword ngxDirectiveDeprecated connections
syn keyword ngxDirectiveDeprecated imap
syn keyword ngxDirectiveDeprecated open_file_cache_retest
syn keyword ngxDirectiveDeprecated optimize_server_names
syn keyword ngxDirectiveDeprecated satisfy_any
syn keyword ngxDirective accept_mutex
syn keyword ngxDirective accept_mutex_delay
syn keyword ngxDirective access_log
syn keyword ngxDirective add_after_body
syn keyword ngxDirective add_before_body
syn keyword ngxDirective add_header
syn keyword ngxDirective addition_types
syn keyword ngxDirective aio
syn keyword ngxDirective alias
syn keyword ngxDirective allow
syn keyword ngxDirective ancient_browser
syn keyword ngxDirective ancient_browser_value
syn keyword ngxDirective auth_basic
syn keyword ngxDirective auth_basic_user_file
syn keyword ngxDirective auth_http
syn keyword ngxDirective auth_http_header
syn keyword ngxDirective auth_http_timeout
syn keyword ngxDirective autoindex
syn keyword ngxDirective autoindex_exact_size
syn keyword ngxDirective autoindex_localtime
syn keyword ngxDirective charset
syn keyword ngxDirective charset_types
syn keyword ngxDirective client_body_buffer_size
syn keyword ngxDirective client_body_in_file_only
syn keyword ngxDirective client_body_in_single_buffer
syn keyword ngxDirective client_body_temp_path
syn keyword ngxDirective client_body_timeout
syn keyword ngxDirective client_header_buffer_size
syn keyword ngxDirective client_header_timeout
syn keyword ngxDirective client_max_body_size
syn keyword ngxDirective connection_pool_size
syn keyword ngxDirective create_full_put_path
syn keyword ngxDirective daemon
syn keyword ngxDirective dav_access
syn keyword ngxDirective dav_methods
syn keyword ngxDirective debug_connection
syn keyword ngxDirective debug_points
syn keyword ngxDirective default_type
syn keyword ngxDirective degradation
syn keyword ngxDirective degrade
syn keyword ngxDirective deny
syn keyword ngxDirective devpoll_changes
syn keyword ngxDirective devpoll_events
syn keyword ngxDirective directio
syn keyword ngxDirective directio_alignment
syn keyword ngxDirective empty_gif
syn keyword ngxDirective env
syn keyword ngxDirective epoll_events
syn keyword ngxDirective error_log
syn keyword ngxDirective eventport_events
syn keyword ngxDirective expires
syn keyword ngxDirective fastcgi_bind
syn keyword ngxDirective fastcgi_buffer_size
syn keyword ngxDirective fastcgi_buffers
syn keyword ngxDirective fastcgi_busy_buffers_size
syn keyword ngxDirective fastcgi_cache
syn keyword ngxDirective fastcgi_cache_key
syn keyword ngxDirective fastcgi_cache_methods
syn keyword ngxDirective fastcgi_cache_min_uses
syn keyword ngxDirective fastcgi_cache_path
syn keyword ngxDirective fastcgi_cache_use_stale
syn keyword ngxDirective fastcgi_cache_valid
syn keyword ngxDirective fastcgi_catch_stderr
syn keyword ngxDirective fastcgi_connect_timeout
syn keyword ngxDirective fastcgi_hide_header
syn keyword ngxDirective fastcgi_ignore_client_abort
syn keyword ngxDirective fastcgi_ignore_headers
syn keyword ngxDirective fastcgi_index
syn keyword ngxDirective fastcgi_intercept_errors
syn keyword ngxDirective fastcgi_max_temp_file_size
syn keyword ngxDirective fastcgi_next_upstream
syn keyword ngxDirective fastcgi_param
syn keyword ngxDirective fastcgi_pass_header
syn keyword ngxDirective fastcgi_pass_request_body
syn keyword ngxDirective fastcgi_pass_request_headers
syn keyword ngxDirective fastcgi_read_timeout
syn keyword ngxDirective fastcgi_send_lowat
syn keyword ngxDirective fastcgi_send_timeout
syn keyword ngxDirective fastcgi_split_path_info
syn keyword ngxDirective fastcgi_store
syn keyword ngxDirective fastcgi_store_access
syn keyword ngxDirective fastcgi_temp_file_write_size
syn keyword ngxDirective fastcgi_temp_path
syn keyword ngxDirective fastcgi_upstream_fail_timeout
syn keyword ngxDirective fastcgi_upstream_max_fails
syn keyword ngxDirective flv
syn keyword ngxDirective geoip_city
syn keyword ngxDirective geoip_country
syn keyword ngxDirective google_perftools_profiles
syn keyword ngxDirective gzip
syn keyword ngxDirective gzip_buffers
syn keyword ngxDirective gzip_comp_level
syn keyword ngxDirective gzip_disable
syn keyword ngxDirective gzip_hash
syn keyword ngxDirective gzip_http_version
syn keyword ngxDirective gzip_min_length
syn keyword ngxDirective gzip_no_buffer
syn keyword ngxDirective gzip_proxied
syn keyword ngxDirective gzip_static
syn keyword ngxDirective gzip_types
syn keyword ngxDirective gzip_vary
syn keyword ngxDirective gzip_window
syn keyword ngxDirective if_modified_since
syn keyword ngxDirective ignore_invalid_headers
syn keyword ngxDirective image_filter
syn keyword ngxDirective image_filter_buffer
syn keyword ngxDirective image_filter_jpeg_quality
syn keyword ngxDirective image_filter_transparency
syn keyword ngxDirective imap_auth
syn keyword ngxDirective imap_capabilities
syn keyword ngxDirective imap_client_buffer
syn keyword ngxDirective index
syn keyword ngxDirective ip_hash
syn keyword ngxDirective keepalive_requests
syn keyword ngxDirective keepalive_timeout
syn keyword ngxDirective kqueue_changes
syn keyword ngxDirective kqueue_events
syn keyword ngxDirective large_client_header_buffers
syn keyword ngxDirective limit_conn
syn keyword ngxDirective limit_conn_log_level
syn keyword ngxDirective limit_rate
syn keyword ngxDirective limit_rate_after
syn keyword ngxDirective limit_req
syn keyword ngxDirective limit_req_log_level
syn keyword ngxDirective limit_req_zone
syn keyword ngxDirective limit_zone
syn keyword ngxDirective lingering_time
syn keyword ngxDirective lingering_timeout
syn keyword ngxDirective lock_file
syn keyword ngxDirective log_format
syn keyword ngxDirective log_not_found
syn keyword ngxDirective log_subrequest
syn keyword ngxDirective map_hash_bucket_size
syn keyword ngxDirective map_hash_max_size
syn keyword ngxDirective master_process
syn keyword ngxDirective memcached_bind
syn keyword ngxDirective memcached_buffer_size
syn keyword ngxDirective memcached_connect_timeout
syn keyword ngxDirective memcached_next_upstream
syn keyword ngxDirective memcached_read_timeout
syn keyword ngxDirective memcached_send_timeout
syn keyword ngxDirective memcached_upstream_fail_timeout
syn keyword ngxDirective memcached_upstream_max_fails
syn keyword ngxDirective merge_slashes
syn keyword ngxDirective min_delete_depth
syn keyword ngxDirective modern_browser
syn keyword ngxDirective modern_browser_value
syn keyword ngxDirective msie_padding
syn keyword ngxDirective msie_refresh
syn keyword ngxDirective multi_accept
syn keyword ngxDirective open_file_cache
syn keyword ngxDirective open_file_cache_errors
syn keyword ngxDirective open_file_cache_events
syn keyword ngxDirective open_file_cache_min_uses
syn keyword ngxDirective open_file_cache_valid
syn keyword ngxDirective open_log_file_cache
syn keyword ngxDirective output_buffers
syn keyword ngxDirective override_charset
syn keyword ngxDirective perl
syn keyword ngxDirective perl_modules
syn keyword ngxDirective perl_require
syn keyword ngxDirective perl_set
syn keyword ngxDirective pid
syn keyword ngxDirective pop3_auth
syn keyword ngxDirective pop3_capabilities
syn keyword ngxDirective port_in_redirect
syn keyword ngxDirective postpone_gzipping
syn keyword ngxDirective postpone_output
syn keyword ngxDirective protocol
syn keyword ngxDirective proxy
syn keyword ngxDirective proxy_bind
syn keyword ngxDirective proxy_buffer
syn keyword ngxDirective proxy_buffer_size
syn keyword ngxDirective proxy_buffering
syn keyword ngxDirective proxy_buffers
syn keyword ngxDirective proxy_busy_buffers_size
syn keyword ngxDirective proxy_cache
syn keyword ngxDirective proxy_cache_key
syn keyword ngxDirective proxy_cache_methods
syn keyword ngxDirective proxy_cache_min_uses
syn keyword ngxDirective proxy_cache_path
syn keyword ngxDirective proxy_cache_use_stale
syn keyword ngxDirective proxy_cache_valid
syn keyword ngxDirective proxy_connect_timeout
syn keyword ngxDirective proxy_headers_hash_bucket_size
syn keyword ngxDirective proxy_headers_hash_max_size
syn keyword ngxDirective proxy_hide_header
syn keyword ngxDirective proxy_ignore_client_abort
syn keyword ngxDirective proxy_ignore_headers
syn keyword ngxDirective proxy_intercept_errors
syn keyword ngxDirective proxy_max_temp_file_size
syn keyword ngxDirective proxy_method
syn keyword ngxDirective proxy_next_upstream
syn keyword ngxDirective proxy_pass_error_message
syn keyword ngxDirective proxy_pass_header
syn keyword ngxDirective proxy_pass_request_body
syn keyword ngxDirective proxy_pass_request_headers
syn keyword ngxDirective proxy_read_timeout
syn keyword ngxDirective proxy_redirect
syn keyword ngxDirective proxy_send_lowat
syn keyword ngxDirective proxy_send_timeout
syn keyword ngxDirective proxy_set_body
syn keyword ngxDirective proxy_set_header
syn keyword ngxDirective proxy_ssl_session_reuse
syn keyword ngxDirective proxy_store
syn keyword ngxDirective proxy_store_access
syn keyword ngxDirective proxy_temp_file_write_size
syn keyword ngxDirective proxy_temp_path
syn keyword ngxDirective proxy_timeout
syn keyword ngxDirective proxy_upstream_fail_timeout
syn keyword ngxDirective proxy_upstream_max_fails
syn keyword ngxDirective random_index
syn keyword ngxDirective read_ahead
syn keyword ngxDirective real_ip_header
syn keyword ngxDirective recursive_error_pages
syn keyword ngxDirective request_pool_size
syn keyword ngxDirective reset_timedout_connection
syn keyword ngxDirective resolver
syn keyword ngxDirective resolver_timeout
syn keyword ngxDirective rewrite_log
syn keyword ngxDirective rtsig_overflow_events
syn keyword ngxDirective rtsig_overflow_test
syn keyword ngxDirective rtsig_overflow_threshold
syn keyword ngxDirective rtsig_signo
syn keyword ngxDirective satisfy
syn keyword ngxDirective secure_link_secret
syn keyword ngxDirective send_lowat
syn keyword ngxDirective send_timeout
syn keyword ngxDirective sendfile
syn keyword ngxDirective sendfile_max_chunk
syn keyword ngxDirective server_name_in_redirect
syn keyword ngxDirective server_names_hash_bucket_size
syn keyword ngxDirective server_names_hash_max_size
syn keyword ngxDirective server_tokens
syn keyword ngxDirective set_real_ip_from
syn keyword ngxDirective smtp_auth
syn keyword ngxDirective smtp_capabilities
syn keyword ngxDirective smtp_client_buffer
syn keyword ngxDirective smtp_greeting_delay
syn keyword ngxDirective so_keepalive
syn keyword ngxDirective source_charset
syn keyword ngxDirective ssi
syn keyword ngxDirective ssi_ignore_recycled_buffers
syn keyword ngxDirective ssi_min_file_chunk
syn keyword ngxDirective ssi_silent_errors
syn keyword ngxDirective ssi_types
syn keyword ngxDirective ssi_value_length
syn keyword ngxDirective ssl
syn keyword ngxDirective ssl_certificate
syn keyword ngxDirective ssl_certificate_key
syn keyword ngxDirective ssl_ciphers
syn keyword ngxDirective ssl_client_certificate
syn keyword ngxDirective ssl_crl
syn keyword ngxDirective ssl_dhparam
syn keyword ngxDirective ssl_engine
syn keyword ngxDirective ssl_prefer_server_ciphers
syn keyword ngxDirective ssl_protocols
syn keyword ngxDirective ssl_session_cache
syn keyword ngxDirective ssl_session_timeout
syn keyword ngxDirective ssl_verify_client
syn keyword ngxDirective ssl_verify_depth
syn keyword ngxDirective starttls
syn keyword ngxDirective stub_status
syn keyword ngxDirective sub_filter
syn keyword ngxDirective sub_filter_once
syn keyword ngxDirective sub_filter_types
syn keyword ngxDirective tcp_nodelay
syn keyword ngxDirective tcp_nopush
syn keyword ngxDirective thread_stack_size
syn keyword ngxDirective timeout
syn keyword ngxDirective timer_resolution
syn keyword ngxDirective types_hash_bucket_size
syn keyword ngxDirective types_hash_max_size
syn keyword ngxDirective underscores_in_headers
syn keyword ngxDirective uninitialized_variable_warn
syn keyword ngxDirective use
syn keyword ngxDirective user
syn keyword ngxDirective userid
syn keyword ngxDirective userid_domain
syn keyword ngxDirective userid_expires
syn keyword ngxDirective userid_mark
syn keyword ngxDirective userid_name
syn keyword ngxDirective userid_p3p
syn keyword ngxDirective userid_path
syn keyword ngxDirective userid_service
syn keyword ngxDirective valid_referers
syn keyword ngxDirective variables_hash_bucket_size
syn keyword ngxDirective variables_hash_max_size
syn keyword ngxDirective worker_connections
syn keyword ngxDirective worker_cpu_affinity
syn keyword ngxDirective worker_priority
syn keyword ngxDirective worker_processes
syn keyword ngxDirective worker_rlimit_core
syn keyword ngxDirective worker_rlimit_nofile
syn keyword ngxDirective worker_rlimit_sigpending
syn keyword ngxDirective worker_threads
syn keyword ngxDirective working_directory
syn keyword ngxDirective xclient
syn keyword ngxDirective xml_entities
syn keyword ngxDirective xslt_stylesheet
syn keyword ngxDirective xslt_types
" 3rd party module list:
" http://wiki.nginx.org/Nginx3rdPartyModules
" Accept Language Module <http://wiki.nginx.org/NginxAcceptLanguageModule>
" Parses the Accept-Language header and gives the most suitable locale from a list of supported locales.
syn keyword ngxDirectiveThirdParty set_from_accept_language
" Access Key Module <http://wiki.nginx.org/NginxHttpAccessKeyModule>
" Denies access unless the request URL contains an access key.
syn keyword ngxDirectiveThirdParty accesskey
syn keyword ngxDirectiveThirdParty accesskey_arg
syn keyword ngxDirectiveThirdParty accesskey_hashmethod
syn keyword ngxDirectiveThirdParty accesskey_signature
" Auth PAM Module <http://web.iti.upv.es/~sto/nginx/>
" HTTP Basic Authentication using PAM.
syn keyword ngxDirectiveThirdParty auth_pam
syn keyword ngxDirectiveThirdParty auth_pam_service_name
" Cache Purge Module <http://labs.frickle.com/nginx_ngx_cache_purge/>
" Module adding ability to purge content from FastCGI and proxy caches.
syn keyword ngxDirectiveThirdParty fastcgi_cache_purge
syn keyword ngxDirectiveThirdParty proxy_cache_purge
" Chunkin Module <http://wiki.nginx.org/NginxHttpChunkinModule>
" HTTP 1.1 chunked-encoding request body support for Nginx.
syn keyword ngxDirectiveThirdParty chunkin
syn keyword ngxDirectiveThirdParty chunkin_keepalive
syn keyword ngxDirectiveThirdParty chunkin_max_chunks_per_buf
syn keyword ngxDirectiveThirdParty chunkin_resume
" Circle GIF Module <http://wiki.nginx.org/NginxHttpCircleGifModule>
" Generates simple circle images with the colors and size specified in the URL.
syn keyword ngxDirectiveThirdParty circle_gif
syn keyword ngxDirectiveThirdParty circle_gif_max_radius
syn keyword ngxDirectiveThirdParty circle_gif_min_radius
syn keyword ngxDirectiveThirdParty circle_gif_step_radius
" Drizzle Module <http://github.com/chaoslawful/drizzle-nginx-module>
" Make nginx talk directly to mysql, drizzle, and sqlite3 by libdrizzle.
syn keyword ngxDirectiveThirdParty drizzle_connect_timeout
syn keyword ngxDirectiveThirdParty drizzle_dbname
syn keyword ngxDirectiveThirdParty drizzle_keepalive
syn keyword ngxDirectiveThirdParty drizzle_module_header
syn keyword ngxDirectiveThirdParty drizzle_pass
syn keyword ngxDirectiveThirdParty drizzle_query
syn keyword ngxDirectiveThirdParty drizzle_recv_cols_timeout
syn keyword ngxDirectiveThirdParty drizzle_recv_rows_timeout
syn keyword ngxDirectiveThirdParty drizzle_send_query_timeout
syn keyword ngxDirectiveThirdParty drizzle_server
" Echo Module <http://wiki.nginx.org/NginxHttpEchoModule>
" Brings 'echo', 'sleep', 'time', 'exec' and more shell-style goodies to Nginx config file.
syn keyword ngxDirectiveThirdParty echo
syn keyword ngxDirectiveThirdParty echo_after_body
syn keyword ngxDirectiveThirdParty echo_before_body
syn keyword ngxDirectiveThirdParty echo_blocking_sleep
syn keyword ngxDirectiveThirdParty echo_duplicate
syn keyword ngxDirectiveThirdParty echo_end
syn keyword ngxDirectiveThirdParty echo_exec
syn keyword ngxDirectiveThirdParty echo_flush
syn keyword ngxDirectiveThirdParty echo_foreach_split
syn keyword ngxDirectiveThirdParty echo_location
syn keyword ngxDirectiveThirdParty echo_location_async
syn keyword ngxDirectiveThirdParty echo_read_request_body
syn keyword ngxDirectiveThirdParty echo_request_body
syn keyword ngxDirectiveThirdParty echo_reset_timer
syn keyword ngxDirectiveThirdParty echo_sleep
syn keyword ngxDirectiveThirdParty echo_subrequest
syn keyword ngxDirectiveThirdParty echo_subrequest_async
" Events Module <http://docs.dutov.org/nginx_modules_events_en.html>
" Privides options for start/stop events.
syn keyword ngxDirectiveThirdParty on_start
syn keyword ngxDirectiveThirdParty on_stop
" EY Balancer Module <http://github.com/ry/nginx-ey-balancer>
" Adds a request queue to Nginx that allows the limiting of concurrent requests passed to the upstream.
syn keyword ngxDirectiveThirdParty max_connections
syn keyword ngxDirectiveThirdParty max_connections_max_queue_length
syn keyword ngxDirectiveThirdParty max_connections_queue_timeout
" Fancy Indexes Module <https://connectical.com/projects/ngx-fancyindex/wiki>
" Like the built-in autoindex module, but fancier.
syn keyword ngxDirectiveThirdParty fancyindex
syn keyword ngxDirectiveThirdParty fancyindex_exact_size
syn keyword ngxDirectiveThirdParty fancyindex_footer
syn keyword ngxDirectiveThirdParty fancyindex_header
syn keyword ngxDirectiveThirdParty fancyindex_localtime
syn keyword ngxDirectiveThirdParty fancyindex_readme
syn keyword ngxDirectiveThirdParty fancyindex_readme_mode
" GeoIP Module (DEPRECATED) <http://wiki.nginx.org/NginxHttp3rdPartyGeoIPModule>
" Country code lookups via the MaxMind GeoIP API.
syn keyword ngxDirectiveThirdParty geoip_country_file
" Headers More Module <http://wiki.nginx.org/NginxHttpHeadersMoreModule>
" Set and clear input and output headers...more than "add"!
syn keyword ngxDirectiveThirdParty more_clear_headers
syn keyword ngxDirectiveThirdParty more_clear_input_headers
syn keyword ngxDirectiveThirdParty more_set_headers
syn keyword ngxDirectiveThirdParty more_set_input_headers
" HTTP Push Module <http://pushmodule.slact.net/>
" Turn Nginx into an adept long-polling HTTP Push (Comet) server.
syn keyword ngxDirectiveThirdParty push_buffer_size
syn keyword ngxDirectiveThirdParty push_listener
syn keyword ngxDirectiveThirdParty push_message_timeout
syn keyword ngxDirectiveThirdParty push_queue_messages
syn keyword ngxDirectiveThirdParty push_sender
" HTTP Redis Module <http://people.FreeBSD.ORG/~osa/ngx_http_redis-0.3.1.tar.gz>>
" Redis <http://code.google.com/p/redis/> support.>
syn keyword ngxDirectiveThirdParty redis_bind
syn keyword ngxDirectiveThirdParty redis_buffer_size
syn keyword ngxDirectiveThirdParty redis_connect_timeout
syn keyword ngxDirectiveThirdParty redis_next_upstream
syn keyword ngxDirectiveThirdParty redis_pass
syn keyword ngxDirectiveThirdParty redis_read_timeout
syn keyword ngxDirectiveThirdParty redis_send_timeout
" HTTP JavaScript Module <http://wiki.github.com/kung-fu-tzu/ngx_http_js_module>
" Embedding SpiderMonkey. Nearly full port on Perl module.
syn keyword ngxDirectiveThirdParty js
syn keyword ngxDirectiveThirdParty js_filter
syn keyword ngxDirectiveThirdParty js_filter_types
syn keyword ngxDirectiveThirdParty js_load
syn keyword ngxDirectiveThirdParty js_maxmem
syn keyword ngxDirectiveThirdParty js_require
syn keyword ngxDirectiveThirdParty js_set
syn keyword ngxDirectiveThirdParty js_utf8
" Log Request Speed <http://wiki.nginx.org/NginxHttpLogRequestSpeed>
" Log the time it took to process each request.
syn keyword ngxDirectiveThirdParty log_request_speed_filter
syn keyword ngxDirectiveThirdParty log_request_speed_filter_timeout
" Memc Module <http://wiki.nginx.org/NginxHttpMemcModule>
" An extended version of the standard memcached module that supports set, add, delete, and many more memcached commands.
syn keyword ngxDirectiveThirdParty memc_buffer_size
syn keyword ngxDirectiveThirdParty memc_cmds_allowed
syn keyword ngxDirectiveThirdParty memc_connect_timeout
syn keyword ngxDirectiveThirdParty memc_flags_to_last_modified
syn keyword ngxDirectiveThirdParty memc_next_upstream
syn keyword ngxDirectiveThirdParty memc_pass
syn keyword ngxDirectiveThirdParty memc_read_timeout
syn keyword ngxDirectiveThirdParty memc_send_timeout
syn keyword ngxDirectiveThirdParty memc_upstream_fail_timeout
syn keyword ngxDirectiveThirdParty memc_upstream_max_fails
" Mogilefs Module <http://www.grid.net.ru/nginx/mogilefs.en.html>
" Implements a MogileFS client, provides a replace to the Perlbal reverse proxy of the original MogileFS.
syn keyword ngxDirectiveThirdParty mogilefs_connect_timeout
syn keyword ngxDirectiveThirdParty mogilefs_domain
syn keyword ngxDirectiveThirdParty mogilefs_methods
syn keyword ngxDirectiveThirdParty mogilefs_noverify
syn keyword ngxDirectiveThirdParty mogilefs_pass
syn keyword ngxDirectiveThirdParty mogilefs_read_timeout
syn keyword ngxDirectiveThirdParty mogilefs_send_timeout
syn keyword ngxDirectiveThirdParty mogilefs_tracker
" MP4 Streaming Lite Module <http://wiki.nginx.org/NginxMP4StreamingLite>
" Will seek to a certain time within H.264/MP4 files when provided with a 'start' parameter in the URL.
syn keyword ngxDirectiveThirdParty mp4
" Nginx Notice Module <http://xph.us/software/nginx-notice/>
" Serve static file to POST requests.
syn keyword ngxDirectiveThirdParty notice
syn keyword ngxDirectiveThirdParty notice_type
" Phusion Passenger <http://www.modrails.com/documentation.html>
" Easy and robust deployment of Ruby on Rails application on Apache and Nginx webservers.
syn keyword ngxDirectiveThirdParty passenger_base_uri
syn keyword ngxDirectiveThirdParty passenger_default_user
syn keyword ngxDirectiveThirdParty passenger_enabled
syn keyword ngxDirectiveThirdParty passenger_log_level
syn keyword ngxDirectiveThirdParty passenger_max_instances_per_app
syn keyword ngxDirectiveThirdParty passenger_max_pool_size
syn keyword ngxDirectiveThirdParty passenger_pool_idle_time
syn keyword ngxDirectiveThirdParty passenger_root
syn keyword ngxDirectiveThirdParty passenger_ruby
syn keyword ngxDirectiveThirdParty passenger_use_global_queue
syn keyword ngxDirectiveThirdParty passenger_user_switching
syn keyword ngxDirectiveThirdParty rack_env
syn keyword ngxDirectiveThirdParty rails_app_spawner_idle_time
syn keyword ngxDirectiveThirdParty rails_env
syn keyword ngxDirectiveThirdParty rails_framework_spawner_idle_time
syn keyword ngxDirectiveThirdParty rails_spawn_method
" RDS JSON Module <http://github.com/agentzh/rds-json-nginx-module>
" Help ngx_drizzle and other DBD modules emit JSON data.
syn keyword ngxDirectiveThirdParty rds_json
syn keyword ngxDirectiveThirdParty rds_json_content_type
syn keyword ngxDirectiveThirdParty rds_json_format
syn keyword ngxDirectiveThirdParty rds_json_ret
" RRD Graph Module <http://wiki.nginx.org/NginxNgx_rrd_graph>
" This module provides an HTTP interface to RRDtool's graphing facilities.
syn keyword ngxDirectiveThirdParty rrd_graph
syn keyword ngxDirectiveThirdParty rrd_graph_root
" Secure Download <http://wiki.nginx.org/NginxHttpSecureDownload>
" Create expiring links.
syn keyword ngxDirectiveThirdParty secure_download
syn keyword ngxDirectiveThirdParty secure_download_fail_location
syn keyword ngxDirectiveThirdParty secure_download_path_mode
syn keyword ngxDirectiveThirdParty secure_download_secret
" SlowFS Cache Module <http://labs.frickle.com/nginx_ngx_slowfs_cache/>
" Module adding ability to cache static files.
syn keyword ngxDirectiveThirdParty slowfs_big_file_size
syn keyword ngxDirectiveThirdParty slowfs_cache
syn keyword ngxDirectiveThirdParty slowfs_cache_key
syn keyword ngxDirectiveThirdParty slowfs_cache_min_uses
syn keyword ngxDirectiveThirdParty slowfs_cache_path
syn keyword ngxDirectiveThirdParty slowfs_cache_purge
syn keyword ngxDirectiveThirdParty slowfs_cache_valid
syn keyword ngxDirectiveThirdParty slowfs_temp_path
" Strip Module <http://wiki.nginx.org/NginxHttpStripModule>
" Whitespace remover.
syn keyword ngxDirectiveThirdParty strip
" Substitutions Module <http://wiki.nginx.org/NginxHttpSubsModule>
" A filter module which can do both regular expression and fixed string substitutions on response bodies.
syn keyword ngxDirectiveThirdParty subs_filter
syn keyword ngxDirectiveThirdParty subs_filter_types
" Supervisord Module <http://labs.frickle.com/nginx_ngx_supervisord/>
" Module providing nginx with API to communicate with supervisord and manage (start/stop) backends on-demand.
syn keyword ngxDirectiveThirdParty supervisord
syn keyword ngxDirectiveThirdParty supervisord_inherit_backend_status
syn keyword ngxDirectiveThirdParty supervisord_name
syn keyword ngxDirectiveThirdParty supervisord_start
syn keyword ngxDirectiveThirdParty supervisord_stop
" Upload Module <http://www.grid.net.ru/nginx/upload.en.html>
" Parses multipart/form-data allowing arbitrary handling of uploaded files.
syn keyword ngxDirectiveThirdParty upload_aggregate_form_field
syn keyword ngxDirectiveThirdParty upload_buffer_size
syn keyword ngxDirectiveThirdParty upload_cleanup
syn keyword ngxDirectiveThirdParty upload_limit_rate
syn keyword ngxDirectiveThirdParty upload_max_file_size
syn keyword ngxDirectiveThirdParty upload_max_output_body_len
syn keyword ngxDirectiveThirdParty upload_max_part_header_len
syn keyword ngxDirectiveThirdParty upload_pass
syn keyword ngxDirectiveThirdParty upload_pass_args
syn keyword ngxDirectiveThirdParty upload_pass_form_field
syn keyword ngxDirectiveThirdParty upload_set_form_field
syn keyword ngxDirectiveThirdParty upload_store
syn keyword ngxDirectiveThirdParty upload_store_access
" Upload Progress Module <http://wiki.nginx.org/NginxHttpUploadProgressModule>
" Tracks and reports upload progress.
syn keyword ngxDirectiveThirdParty report_uploads
syn keyword ngxDirectiveThirdParty track_uploads
syn keyword ngxDirectiveThirdParty upload_progress
syn keyword ngxDirectiveThirdParty upload_progress_content_type
syn keyword ngxDirectiveThirdParty upload_progress_header
syn keyword ngxDirectiveThirdParty upload_progress_json_output
syn keyword ngxDirectiveThirdParty upload_progress_template
" Upstream Fair Balancer <http://wiki.nginx.org/NginxHttpUpstreamFairModule>
" Sends an incoming request to the least-busy backend server, rather than distributing requests round-robin.
syn keyword ngxDirectiveThirdParty fair
syn keyword ngxDirectiveThirdParty upstream_fair_shm_size
" Upstream Consistent Hash <http://wiki.nginx.org/NginxHttpUpstreamConsistentHash>
" Select backend based on Consistent hash ring.
syn keyword ngxDirectiveThirdParty consistent_hash
" Upstream Hash Module <http://wiki.nginx.org/NginxHttpUpstreamRequestHashModule>
" Provides simple upstream load distribution by hashing a configurable variable.
syn keyword ngxDirectiveThirdParty hash
syn keyword ngxDirectiveThirdParty hash_again
" XSS Module <http://github.com/agentzh/xss-nginx-module>
" Native support for cross-site scripting (XSS) in an nginx.
syn keyword ngxDirectiveThirdParty xss_callback_arg
syn keyword ngxDirectiveThirdParty xss_get
syn keyword ngxDirectiveThirdParty xss_input_types
syn keyword ngxDirectiveThirdParty xss_output_type
" highlight
hi link ngxComment Comment
hi link ngxVariable Identifier
hi link ngxVariableBlock Identifier
hi link ngxVariableString PreProc
hi link ngxBlock Normal
hi link ngxString String
hi link ngxBoolean Boolean
hi link ngxDirectiveBlock Statement
hi link ngxDirectiveImportant Type
hi link ngxDirectiveControl Keyword
hi link ngxDirectiveError Constant
hi link ngxDirectiveDeprecated Error
hi link ngxDirective Identifier
hi link ngxDirectiveThirdParty Special
let b:current_syntax = "nginx"

View file

@ -0,0 +1,16 @@
*~
.DS_Store
*.log
*.tmp
*.swp
*.old
*.bkp
*.zip
*.rar
*.arj
*.[t]gz
*.[t]bz2
tmp/
log/

View file

@ -1,47 +0,0 @@
Snipmate Snippets
=================
This repository contains snippets files for various programming languages for
the famous [snipMate][1] plugin for vim. This repository is
community-maintained and many people have contributed snippet files and other
improvements already.
[vim-snipmate][1] was originally started by [Michael Sanders][2] who has now
unfortunately abandoned the project. [Rok Garbas][3] is now maintaining a
[fork][4] of the project in hopes of improving the existing code base.
Language maintainers
--------------------
No one can really be proficient in all programming languages. If you would like
to maintain snippets for a language, please get in touch.
* Python - [honza](http://github.com/honza)
* Javascript - [honza](http://github.com/honza)
* HTML Django - [honza](http://github.com/honza)
* Markdown - [honza](http://github.com/honza)
* Ruby - [taq](http://github.com/taq)
* PHP - [chrisyue](http://github.com/chrisyue)
Contributing notes
------------------
Until further work is done on `vim-snipmate`, please don't add folding markers
into snippets.
Authors
-------
For a list of authors, please see the `AUTHORS` files.
License
-------
Just as the original snipMate plugin, all the snippets are licensed under the
terms of the MIT license.
[1]: http://github.com/garbas/vim-snipmate
[2]: http://github.com/msanders
[3]: http://github.com/garbas
[4]: http://github.com/garbas/vim-snipmate

View file

@ -0,0 +1,24 @@
#require 'fileutils'
#include FileUtils
namespace :snippets_dir do
task :find do
vim_dir = File.join(ENV['VIMFILES'] || ENV['HOME'] || ENV['USERPROFILE'], RUBY_PLATFORM =~ /mswin|msys|mingw32/ ? "vimfiles" : ".vim")
pathogen_dir = File.join(vim_dir, "bundle")
@snippets_dir = File.directory?(pathogen_dir) ? File.join(pathogen_dir, "snipmate", "snippets") : File.join(vim_dir, "snippets")
end
desc "Purge the contents of the vim snippets directory"
task :purge => ["snippets_dir:find"] do
rm_rf @snippets_dir, :verbose => true if File.directory? @snippets_dir
mkdir @snippets_dir, :verbose => true
end
end
desc "Copy the snippets directories into ~/.vim/snippets"
task :deploy_local => ["snippets_dir:purge"] do
Dir.foreach(".") do |f|
cp_r f, @snippets_dir, :verbose => true if File.directory?(f) && f =~ /^[^\.]/
end
cp "support_functions.vim", @snippets_dir, :verbose => true
end

View file

@ -0,0 +1 @@
`strftime("%Y-%m-%d %H:%M:%S")`

View file

@ -0,0 +1 @@
`strftime("%Y-%m-%d")`

View file

@ -0,0 +1 @@
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

View file

@ -0,0 +1 @@
`Snippet_Modeline()`

View file

@ -0,0 +1,29 @@
<project name="PROJECT NAME" default="dist" basedir=".">
<description>
</description>
<!-- set global properties for this build -->
<property name="src" location="src"/>
<property name="build" location="build"/>
<property name="dist" location="dist"/>
<target name="init">
<tstamp/>
<mkdir dir="${build}"/>
</target>
<target name="compile" depends="init" description="compile the source " >
<javac srcdir="${src}" destdir="${build}"/>
</target>
<target name="dist" depends="compile" description="generate the distribution" >
<mkdir dir="${dist}/lib"/>
<jar jarfile="${dist}/lib/MyProject-${DSTAMP}.jar" basedir="${build}"/>
</target>
<target name="clean"
description="clean up" >
<delete dir="${build}"/>
<delete dir="${dist}"/>
</target>
</project>

View file

@ -0,0 +1,7 @@
class ${1:`Filename('$1_t', 'name')`} {
public:
$1 (${2:arguments});
virtual ~$1 ();
private:
${3:/* data */}
};

View file

@ -0,0 +1,3 @@
#ifndef $1
#define ${1:SYMBOL} ${2:value}
#endif${3}

View file

@ -0,0 +1,3 @@
do {
${2:/* code */}
} while (${1:/* condition */});

View file

@ -0,0 +1,3 @@
else {
${1}
}

View file

@ -0,0 +1,3 @@
for (${2:i} = 0; $2 < ${1:count}; $2${3:++}) {
${4:/* code */}
}

View file

@ -0,0 +1,3 @@
for (${1:i} = 0; ${2:$1 < 5}; $1${3:++}) {
${4:/* code */}
}

View file

@ -0,0 +1 @@
fprintf(${1:stderr}, "${2:%s}\n"${3});${4}

View file

@ -0,0 +1,4 @@
${1:void} ${2:function_name} (${3})
{
${4:/* code */}
}

View file

@ -0,0 +1,3 @@
if (${1:/* condition */}) {
${2:/* code */}
}

View file

@ -0,0 +1 @@
#include "${1:`Filename("$1.h")`}"${2}

View file

@ -0,0 +1 @@
#include <${1:stdio}.h>${2}

View file

@ -0,0 +1,5 @@
int main (int argc, char const* argv[])
{
${1:/* code */}
return 0;
}

View file

@ -0,0 +1 @@
std::map<${1:key}, ${2:value}> map${3};

View file

@ -0,0 +1,3 @@
namespace ${1:`Filename('', 'my')`} {
${2}
} /* $1 */

View file

@ -0,0 +1,6 @@
#ifndef ${1:`toupper(Filename('', 'UNTITLED').'_'.system("/usr/bin/ruby -e 'print (rand * 2821109907455).round.to_s(36)'"))`}
#define $1
${2}
#endif /* end of include guard: $1 */

View file

@ -0,0 +1 @@
printf("${1:%s}\n"${2});${3}

View file

@ -0,0 +1,7 @@
std::vector<char> v;
if (FILE *${2:fp} = fopen(${1:"filename"}, "r")) {
char buf[1024];
while (size_t len = fread(buf, 1, sizeof(buf), $2))
v.insert(v.end(), buf, buf + len);
fclose($2);
}${3}

View file

@ -0,0 +1,3 @@
struct ${1:`Filename('$1_t', 'name')`} {
${2:/* data */}
}${3: /* optional variable list */};${4}

View file

@ -0,0 +1 @@
${1:/* condition */} ? ${2:a} : ${3:b}'

View file

@ -0,0 +1 @@
typedef ${1:int} ${2:MyCustomType};

View file

@ -0,0 +1,3 @@
typedef struct {
${2:/* data */}
} ${1:`Filename('$1_t', 'name')`};

View file

@ -0,0 +1 @@
std::vector<${1:char}> v${2};

View file

@ -0,0 +1,3 @@
while (${1:/* condition */}) {
${2:/* code */}
}

View file

@ -0,0 +1,3 @@
#${1:id} {
${2}
}

View file

@ -0,0 +1 @@
background:${6: #${1:DDD}} url($2) ${3:repeat/repeat-x/repeat-y/no-repeat} ${4:scroll/fixed} ${5:top left/top center/top right/center left/center center/center right/bottom left/bottom center/bottom right/x-% y-%/x-pos y-pos};$0

View file

@ -0,0 +1 @@
background-attachment: ${1:scroll/fixed};$0

View file

@ -0,0 +1 @@
background-color: #${1:DDD};$0

View file

@ -0,0 +1 @@
background-color: ${1:red};$0

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