1
0
Fork 0
mirror of synced 2024-11-22 00:35:35 -05:00

Updated plugins

This commit is contained in:
amix 2014-08-03 23:02:51 +01:00
parent b92f0f2eb1
commit 2a9908e4f0
88 changed files with 2839 additions and 2014 deletions

View file

@ -64,7 +64,7 @@ function! s:setup_pad(bufnr, vert, size)
execute win . 'wincmd w' execute win . 'wincmd w'
execute (a:vert ? 'vertical ' : '') . 'resize ' . max([0, a:size]) execute (a:vert ? 'vertical ' : '') . 'resize ' . max([0, a:size])
augroup goyop augroup goyop
autocmd WinEnter <buffer> call s:blank() autocmd WinEnter,CursorMoved <buffer> call s:blank()
augroup END augroup END
" To hide scrollbars of pad windows in GVim " To hide scrollbars of pad windows in GVim
@ -127,6 +127,7 @@ function! s:goyo_on(width)
\ { 'laststatus': &laststatus, \ { 'laststatus': &laststatus,
\ 'showtabline': &showtabline, \ 'showtabline': &showtabline,
\ 'fillchars': &fillchars, \ 'fillchars': &fillchars,
\ 'winminwidth': &winminwidth,
\ 'winwidth': &winwidth, \ 'winwidth': &winwidth,
\ 'winminheight': &winminheight, \ 'winminheight': &winminheight,
\ 'winheight': &winheight, \ 'winheight': &winheight,
@ -145,6 +146,12 @@ function! s:goyo_on(width)
silent! GitGutterDisable silent! GitGutterDisable
endif endif
" vim-signify
let t:goyo_disabled_signify = exists('b:sy') && b:sy.active
if t:goyo_disabled_signify
SignifyToggle
endif
" vim-airline " vim-airline
let t:goyo_disabled_airline = exists("#airline") let t:goyo_disabled_airline = exists("#airline")
if t:goyo_disabled_airline if t:goyo_disabled_airline
@ -177,10 +184,10 @@ function! s:goyo_on(width)
endif endif
" Global options " Global options
set winwidth=1
let &winheight = max([&winminheight, 1]) let &winheight = max([&winminheight, 1])
set winminheight=1 set winminheight=1
set winheight=1 set winheight=1
set winminwidth=1 winwidth=1
set laststatus=0 set laststatus=0
set showtabline=0 set showtabline=0
set noruler set noruler
@ -241,6 +248,7 @@ function! s:goyo_off()
let goyo_revert = t:goyo_revert let goyo_revert = t:goyo_revert
let goyo_disabled_gitgutter = t:goyo_disabled_gitgutter let goyo_disabled_gitgutter = t:goyo_disabled_gitgutter
let goyo_disabled_signify = t:goyo_disabled_signify
let goyo_disabled_airline = t:goyo_disabled_airline let goyo_disabled_airline = t:goyo_disabled_airline
let goyo_disabled_powerline = t:goyo_disabled_powerline let goyo_disabled_powerline = t:goyo_disabled_powerline
let goyo_disabled_lightline = t:goyo_disabled_lightline let goyo_disabled_lightline = t:goyo_disabled_lightline
@ -258,6 +266,10 @@ function! s:goyo_off()
execute printf('normal! %dG%d|', line, col) execute printf('normal! %dG%d|', line, col)
endif endif
let wmw = remove(goyo_revert, 'winminwidth')
let ww = remove(goyo_revert, 'winwidth')
let &winwidth = ww
let &winminwidth = wmw
let wmh = remove(goyo_revert, 'winminheight') let wmh = remove(goyo_revert, 'winminheight')
let wh = remove(goyo_revert, 'winheight') let wh = remove(goyo_revert, 'winheight')
let &winheight = max([wmh, 1]) let &winheight = max([wmh, 1])
@ -273,6 +285,12 @@ function! s:goyo_off()
silent! GitGutterEnable silent! GitGutterEnable
endif endif
if goyo_disabled_signify
silent! if !b:sy.active
SignifyToggle
endif
endif
if goyo_disabled_airline && !exists("#airline") if goyo_disabled_airline && !exists("#airline")
AirlineToggle AirlineToggle
silent! AirlineRefresh silent! AirlineRefresh
@ -296,9 +314,14 @@ function! s:goyo_off()
endif endif
endfunction endfunction
function! s:goyo(...) function! s:goyo(bang, ...)
let width = a:0 > 0 ? a:1 : get(g:, 'goyo_width', 80) let width = a:0 > 0 ? a:1 : get(g:, 'goyo_width', 80)
if a:bang
if exists('#goyo')
call s:goyo_off()
endif
else
if exists('#goyo') == 0 if exists('#goyo') == 0
call s:goyo_on(width) call s:goyo_on(width)
elseif a:0 > 0 elseif a:0 > 0
@ -307,9 +330,10 @@ function! s:goyo(...)
else else
call s:goyo_off() call s:goyo_off()
end end
end
endfunction endfunction
command! -nargs=? Goyo call s:goyo(<args>) command! -nargs=? -bar -bang Goyo call s:goyo('<bang>' == '!', <args>)
let &cpo = s:cpo_save let &cpo = s:cpo_save
unlet s:cpo_save unlet s:cpo_save

View file

@ -83,7 +83,7 @@ __Q. How can I open a NERDTree automatically when vim starts up if no files were
A. Stick this in your vimrc A. Stick this in your vimrc
autocmd StdinReadPre * let s:std_in=1 autocmd StdinReadPre * let s:std_in=1
autocmd VimEnter * if !argc() == 0 && !exists("s:std_in") | NERDTree | endif autocmd VimEnter * if argc() == 0 && !exists("s:std_in") | NERDTree | endif
__Q. How can I map a specific key or shortcut to open NERDTree?__ __Q. How can I map a specific key or shortcut to open NERDTree?__

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,644 @@
if exists("g:loaded_nerdtree_ui_glue_autoload")
finish
endif
let g:loaded_nerdtree_ui_glue_autoload = 1
" FUNCTION: nerdtree#ui_glue#createDefaultBindings() {{{1
function! nerdtree#ui_glue#createDefaultBindings()
let s = '<SNR>' . s:SID() . '_'
call NERDTreeAddKeyMap({ 'key': '<MiddleRelease>', 'scope': "all", 'callback': s."handleMiddleMouse" })
call NERDTreeAddKeyMap({ 'key': '<LeftRelease>', 'scope': "all", 'callback': s."handleLeftClick" })
call NERDTreeAddKeyMap({ 'key': '<2-LeftMouse>', 'scope': "DirNode", 'callback': s."activateDirNode" })
call NERDTreeAddKeyMap({ 'key': '<2-LeftMouse>', 'scope': "FileNode", 'callback': s."activateFileNode" })
call NERDTreeAddKeyMap({ 'key': '<2-LeftMouse>', 'scope': "Bookmark", 'callback': s."activateBookmark" })
call NERDTreeAddKeyMap({ 'key': '<2-LeftMouse>', 'scope': "all", 'callback': s."activateAll" })
call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapActivateNode, 'scope': "DirNode", 'callback': s."activateDirNode" })
call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapActivateNode, 'scope': "FileNode", 'callback': s."activateFileNode" })
call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapActivateNode, 'scope': "Bookmark", 'callback': s."activateBookmark" })
call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapActivateNode, 'scope': "all", 'callback': s."activateAll" })
call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapOpenSplit, 'scope': "Node", 'callback': s."openHSplit" })
call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapOpenVSplit, 'scope': "Node", 'callback': s."openVSplit" })
call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapOpenSplit, 'scope': "Bookmark", 'callback': s."openHSplit" })
call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapOpenVSplit, 'scope': "Bookmark", 'callback': s."openVSplit" })
call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapPreview, 'scope': "Node", 'callback': s."previewNodeCurrent" })
call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapPreviewVSplit, 'scope': "Node", 'callback': s."previewNodeVSplit" })
call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapPreviewSplit, 'scope': "Node", 'callback': s."previewNodeHSplit" })
call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapPreview, 'scope': "Bookmark", 'callback': s."previewNodeCurrent" })
call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapPreviewVSplit, 'scope': "Bookmark", 'callback': s."previewNodeVSplit" })
call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapPreviewSplit, 'scope': "Bookmark", 'callback': s."previewNodeHSplit" })
call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapOpenRecursively, 'scope': "DirNode", 'callback': s."openNodeRecursively" })
call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapUpdir, 'scope': "all", 'callback': s."upDirCurrentRootClosed" })
call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapUpdirKeepOpen, 'scope': "all", 'callback': s."upDirCurrentRootOpen" })
call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapChangeRoot, 'scope': "Node", 'callback': s."chRoot" })
call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapChdir, 'scope': "Node", 'callback': s."chCwd" })
call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapQuit, 'scope': "all", 'callback': s."closeTreeWindow" })
call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapCWD, 'scope': "all", 'callback': "nerdtree#ui_glue#chRootCwd" })
call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapRefreshRoot, 'scope': "all", 'callback': s."refreshRoot" })
call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapRefresh, 'scope': "Node", 'callback': s."refreshCurrent" })
call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapHelp, 'scope': "all", 'callback': s."displayHelp" })
call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapToggleZoom, 'scope': "all", 'callback': s."toggleZoom" })
call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapToggleHidden, 'scope': "all", 'callback': s."toggleShowHidden" })
call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapToggleFilters, 'scope': "all", 'callback': s."toggleIgnoreFilter" })
call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapToggleFiles, 'scope': "all", 'callback': s."toggleShowFiles" })
call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapToggleBookmarks, 'scope': "all", 'callback': s."toggleShowBookmarks" })
call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapCloseDir, 'scope': "Node", 'callback': s."closeCurrentDir" })
call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapCloseChildren, 'scope': "DirNode", 'callback': s."closeChildren" })
call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapMenu, 'scope': "Node", 'callback': s."showMenu" })
call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapJumpParent, 'scope': "Node", 'callback': s."jumpToParent" })
call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapJumpFirstChild, 'scope': "Node", 'callback': s."jumpToFirstChild" })
call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapJumpLastChild, 'scope': "Node", 'callback': s."jumpToLastChild" })
call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapJumpRoot, 'scope': "all", 'callback': s."jumpToRoot" })
call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapJumpNextSibling, 'scope': "Node", 'callback': s."jumpToNextSibling" })
call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapJumpPrevSibling, 'scope': "Node", 'callback': s."jumpToPrevSibling" })
call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapOpenInTab, 'scope': "Node", 'callback': s."openInNewTab" })
call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapOpenInTabSilent, 'scope': "Node", 'callback': s."openInNewTabSilent" })
call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapOpenInTab, 'scope': "Bookmark", 'callback': s."openInNewTab" })
call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapOpenInTabSilent, 'scope': "Bookmark", 'callback': s."openInNewTabSilent" })
call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapOpenExpl, 'scope': "DirNode", 'callback': s."openExplorer" })
call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapDeleteBookmark, 'scope': "Bookmark", 'callback': s."deleteBookmark" })
endfunction
"SECTION: Interface bindings {{{1
"============================================================
"FUNCTION: s:activateAll() {{{1
"handle the user activating the updir line
function! s:activateAll()
if getline(".") ==# nerdtree#treeUpDirLine()
return nerdtree#ui_glue#upDir(0)
endif
endfunction
"FUNCTION: s:activateDirNode() {{{1
"handle the user activating a tree node
function! s:activateDirNode(node)
call a:node.activate({'reuse': 1})
endfunction
"FUNCTION: s:activateFileNode() {{{1
"handle the user activating a tree node
function! s:activateFileNode(node)
call a:node.activate({'reuse': 1, 'where': 'p'})
endfunction
"FUNCTION: s:activateBookmark() {{{1
"handle the user activating a bookmark
function! s:activateBookmark(bm)
call a:bm.activate(!a:bm.path.isDirectory ? {'where': 'p'} : {})
endfunction
" FUNCTION: nerdtree#ui_glue#bookmarkNode(name) {{{1
" Associate the current node with the given name
function! nerdtree#ui_glue#bookmarkNode(...)
let currentNode = g:NERDTreeFileNode.GetSelected()
if currentNode != {}
let name = a:1
if empty(name)
let name = currentNode.path.getLastPathComponent(0)
endif
try
call currentNode.bookmark(name)
call b:NERDTree.render()
catch /^NERDTree.IllegalBookmarkNameError/
call nerdtree#echo("bookmark names must not contain spaces")
endtry
else
call nerdtree#echo("select a node first")
endif
endfunction
" FUNCTION: s:chCwd(node) {{{1
function! s:chCwd(node)
try
call a:node.path.changeToDir()
catch /^NERDTree.PathChangeError/
call nerdtree#echoWarning("could not change cwd")
endtry
endfunction
" FUNCTION: s:chRoot(node) {{{1
" changes the current root to the selected one
function! s:chRoot(node)
call a:node.makeRoot()
call b:NERDTree.render()
call b:NERDTreeRoot.putCursorHere(0, 0)
endfunction
" FUNCTION: s:nerdtree#ui_glue#chRootCwd() {{{1
" changes the current root to CWD
function! nerdtree#ui_glue#chRootCwd()
try
let cwd = g:NERDTreePath.New(getcwd())
catch /^NERDTree.InvalidArgumentsError/
call nerdtree#echo("current directory does not exist.")
return
endtry
if cwd.str() == g:NERDTreeFileNode.GetRootForTab().path.str()
return
endif
call s:chRoot(g:NERDTreeDirNode.New(cwd))
endfunction
" FUNCTION: nnerdtree#ui_glue#clearBookmarks(bookmarks) {{{1
function! nerdtree#ui_glue#clearBookmarks(bookmarks)
if a:bookmarks ==# ''
let currentNode = g:NERDTreeFileNode.GetSelected()
if currentNode != {}
call currentNode.clearBookmarks()
endif
else
for name in split(a:bookmarks, ' ')
let bookmark = g:NERDTreeBookmark.BookmarkFor(name)
call bookmark.delete()
endfor
endif
call b:NERDTree.render()
endfunction
" FUNCTION: s:closeChildren(node) {{{1
" closes all childnodes of the current node
function! s:closeChildren(node)
call a:node.closeChildren()
call b:NERDTree.render()
call a:node.putCursorHere(0, 0)
endfunction
" FUNCTION: s:closeCurrentDir(node) {{{1
" closes the parent dir of the current node
function! s:closeCurrentDir(node)
let parent = a:node.parent
if parent ==# {} || parent.isRoot()
call nerdtree#echo("cannot close tree root")
else
while g:NERDTreeCascadeOpenSingleChildDir && !parent.parent.isRoot()
if parent.parent.getVisibleChildCount() == 1
call parent.close()
let parent = parent.parent
else
break
endif
endwhile
call parent.close()
call b:NERDTree.render()
call parent.putCursorHere(0, 0)
endif
endfunction
" FUNCTION: s:closeTreeWindow() {{{1
" close the tree window
function! s:closeTreeWindow()
if b:NERDTreeType ==# "secondary" && b:NERDTreePreviousBuf != -1
exec "buffer " . b:NERDTreePreviousBuf
else
if winnr("$") > 1
call nerdtree#closeTree()
else
call nerdtree#echo("Cannot close last window")
endif
endif
endfunction
" FUNCTION: s:deleteBookmark(bm) {{{1
" if the cursor is on a bookmark, prompt to delete
function! s:deleteBookmark(bm)
echo "Are you sure you wish to delete the bookmark:\n\"" . a:bm.name . "\" (yN):"
if nr2char(getchar()) ==# 'y'
try
call a:bm.delete()
call b:NERDTree.render()
redraw
catch /^NERDTree/
call nerdtree#echoWarning("Could not remove bookmark")
endtry
else
call nerdtree#echo("delete aborted" )
endif
endfunction
" FUNCTION: s:displayHelp() {{{1
" toggles the help display
function! s:displayHelp()
let b:treeShowHelp = b:treeShowHelp ? 0 : 1
call b:NERDTree.render()
call b:NERDTree.ui.centerView()
endfunction
" FUNCTION: s:findAndRevealPath() {{{1
function! s:findAndRevealPath()
try
let p = g:NERDTreePath.New(expand("%:p"))
catch /^NERDTree.InvalidArgumentsError/
call nerdtree#echo("no file for the current buffer")
return
endtry
if p.isUnixHiddenPath()
let showhidden=g:NERDTreeShowHidden
let g:NERDTreeShowHidden = 1
endif
if !g:NERDTree.ExistsForTab()
try
let cwd = g:NERDTreePath.New(getcwd())
catch /^NERDTree.InvalidArgumentsError/
call nerdtree#echo("current directory does not exist.")
let cwd = p.getParent()
endtry
if p.isUnder(cwd)
call g:NERDTreeCreator.CreatePrimary(cwd.str())
else
call g:NERDTreeCreator.CreatePrimary(p.getParent().str())
endif
else
if !p.isUnder(g:NERDTreeFileNode.GetRootForTab().path)
if !nerdtree#isTreeOpen()
call g:NERDTreeCreator.TogglePrimary('')
else
call nerdtree#putCursorInTreeWin()
endif
let b:NERDTreeShowHidden = g:NERDTreeShowHidden
call s:chRoot(g:NERDTreeDirNode.New(p.getParent()))
else
if !nerdtree#isTreeOpen()
call g:NERDTreeCreator.TogglePrimary("")
endif
endif
endif
call nerdtree#putCursorInTreeWin()
call b:NERDTreeRoot.reveal(p)
if p.isUnixHiddenFile()
let g:NERDTreeShowHidden = showhidden
endif
endfunction
"FUNCTION: s:handleLeftClick() {{{1
"Checks if the click should open the current node
function! s:handleLeftClick()
let currentNode = g:NERDTreeFileNode.GetSelected()
if currentNode != {}
"the dir arrows are multibyte chars, and vim's string functions only
"deal with single bytes - so split the line up with the hack below and
"take the line substring manually
let line = split(getline(line(".")), '\zs')
let startToCur = ""
for i in range(0,len(line)-1)
let startToCur .= line[i]
endfor
if currentNode.path.isDirectory
if startToCur =~# nerdtree#treeMarkupReg() && startToCur =~# '[+~▾▸] \?$'
call currentNode.activate()
return
endif
endif
if (g:NERDTreeMouseMode ==# 2 && currentNode.path.isDirectory) || g:NERDTreeMouseMode ==# 3
let char = strpart(startToCur, strlen(startToCur)-1, 1)
if char !~# nerdtree#treeMarkupReg()
if currentNode.path.isDirectory
call currentNode.activate()
else
call currentNode.activate({'reuse': 1, 'where': 'p'})
endif
return
endif
endif
endif
endfunction
" FUNCTION: s:handleMiddleMouse() {{{1
function! s:handleMiddleMouse()
let curNode = g:NERDTreeFileNode.GetSelected()
if curNode ==# {}
call nerdtree#echo("Put the cursor on a node first" )
return
endif
if curNode.path.isDirectory
call nerdtree#openExplorer(curNode)
else
call curNode.open({'where': 'h'})
endif
endfunction
" FUNCTION: s:jumpToChild(direction) {{{2
" Args:
" direction: 0 if going to first child, 1 if going to last
function! s:jumpToChild(currentNode, direction)
if a:currentNode.isRoot()
return nerdtree#echo("cannot jump to " . (a:direction ? "last" : "first") . " child")
end
let dirNode = a:currentNode.parent
let childNodes = dirNode.getVisibleChildren()
let targetNode = childNodes[0]
if a:direction
let targetNode = childNodes[len(childNodes) - 1]
endif
if targetNode.equals(a:currentNode)
let siblingDir = a:currentNode.parent.findOpenDirSiblingWithVisibleChildren(a:direction)
if siblingDir != {}
let indx = a:direction ? siblingDir.getVisibleChildCount()-1 : 0
let targetNode = siblingDir.getChildByIndex(indx, 1)
endif
endif
call targetNode.putCursorHere(1, 0)
call b:NERDTree.ui.centerView()
endfunction
" FUNCTION: nerdtree#ui_glue#invokeKeyMap(key) {{{1
"this is needed since I cant figure out how to invoke dict functions from a
"key map
function! nerdtree#ui_glue#invokeKeyMap(key)
call g:NERDTreeKeyMap.Invoke(a:key)
endfunction
" FUNCTION: s:jumpToFirstChild() {{{1
" wrapper for the jump to child method
function! s:jumpToFirstChild(node)
call s:jumpToChild(a:node, 0)
endfunction
" FUNCTION: s:jumpToLastChild() {{{1
" wrapper for the jump to child method
function! s:jumpToLastChild(node)
call s:jumpToChild(a:node, 1)
endfunction
" FUNCTION: s:jumpToParent(node) {{{1
" moves the cursor to the parent of the current node
function! s:jumpToParent(node)
if !empty(a:node.parent)
call a:node.parent.putCursorHere(1, 0)
call b:NERDTree.ui.centerView()
else
call nerdtree#echo("cannot jump to parent")
endif
endfunction
" FUNCTION: s:jumpToRoot() {{{1
" moves the cursor to the root node
function! s:jumpToRoot()
call b:NERDTreeRoot.putCursorHere(1, 0)
call b:NERDTree.ui.centerView()
endfunction
" FUNCTION: s:jumpToNextSibling(node) {{{1
function! s:jumpToNextSibling(node)
call s:jumpToSibling(a:node, 1)
endfunction
" FUNCTION: s:jumpToPrevSibling(node) {{{1
function! s:jumpToPrevSibling(node)
call s:jumpToSibling(a:node, 0)
endfunction
" FUNCTION: s:jumpToSibling(currentNode, forward) {{{2
" moves the cursor to the sibling of the current node in the given direction
"
" Args:
" forward: 1 if the cursor should move to the next sibling, 0 if it should
" move back to the previous sibling
function! s:jumpToSibling(currentNode, forward)
let sibling = a:currentNode.findSibling(a:forward)
if !empty(sibling)
call sibling.putCursorHere(1, 0)
call b:NERDTree.ui.centerView()
endif
endfunction
" FUNCTION: nerdtree#ui_glue#openBookmark(name) {{{1
" put the cursor on the given bookmark and, if its a file, open it
function! nerdtree#ui_glue#openBookmark(name)
try
let targetNode = g:NERDTreeBookmark.GetNodeForName(a:name, 0)
call targetNode.putCursorHere(0, 1)
redraw!
catch /^NERDTree.BookmarkedNodeNotFoundError/
call nerdtree#echo("note - target node is not cached")
let bookmark = g:NERDTreeBookmark.BookmarkFor(a:name)
let targetNode = g:NERDTreeFileNode.New(bookmark.path)
endtry
if targetNode.path.isDirectory
call targetNode.openExplorer()
else
call targetNode.open({'where': 'p'})
endif
endfunction
" FUNCTION: s:openHSplit(target) {{{1
function! s:openHSplit(target)
call a:target.activate({'where': 'h'})
endfunction
" FUNCTION: s:openVSplit(target) {{{1
function! s:openVSplit(target)
call a:target.activate({'where': 'v'})
endfunction
" FUNCTION: s:openExplorer(node) {{{1
function! s:openExplorer(node)
call a:node.openExplorer()
endfunction
" FUNCTION: s:openInNewTab(target) {{{1
function! s:openInNewTab(target)
call a:target.activate({'where': 't'})
endfunction
" FUNCTION: s:openInNewTabSilent(target) {{{1
function! s:openInNewTabSilent(target)
call a:target.activate({'where': 't', 'stay': 1})
endfunction
" FUNCTION: s:openNodeRecursively(node) {{{1
function! s:openNodeRecursively(node)
call nerdtree#echo("Recursively opening node. Please wait...")
call a:node.openRecursively()
call b:NERDTree.render()
redraw
call nerdtree#echo("Recursively opening node. Please wait... DONE")
endfunction
"FUNCTION: s:previewNodeCurrent(node) {{{1
function! s:previewNodeCurrent(node)
call a:node.open({'stay': 1, 'where': 'p', 'keepopen': 1})
endfunction
"FUNCTION: s:previewNodeHSplit(node) {{{1
function! s:previewNodeHSplit(node)
call a:node.open({'stay': 1, 'where': 'h', 'keepopen': 1})
endfunction
"FUNCTION: s:previewNodeVSplit(node) {{{1
function! s:previewNodeVSplit(node)
call a:node.open({'stay': 1, 'where': 'v', 'keepopen': 1})
endfunction
" FUNCTION: nerdtree#ui_glue#revealBookmark(name) {{{1
" put the cursor on the node associate with the given name
function! nerdtree#ui_glue#revealBookmark(name)
try
let targetNode = g:NERDTreeBookmark.GetNodeForName(a:name, 0)
call targetNode.putCursorHere(0, 1)
catch /^NERDTree.BookmarkNotFoundError/
call nerdtree#echo("Bookmark isnt cached under the current root")
endtry
endfunction
" FUNCTION: s:refreshRoot() {{{1
" Reloads the current root. All nodes below this will be lost and the root dir
" will be reloaded.
function! s:refreshRoot()
call nerdtree#echo("Refreshing the root node. This could take a while...")
call b:NERDTreeRoot.refresh()
call b:NERDTree.render()
redraw
call nerdtree#echo("Refreshing the root node. This could take a while... DONE")
endfunction
" FUNCTION: s:refreshCurrent(node) {{{1
" refreshes the root for the current node
function! s:refreshCurrent(node)
let node = a:node
if !node.path.isDirectory
let node = node.parent
endif
call nerdtree#echo("Refreshing node. This could take a while...")
call node.refresh()
call b:NERDTree.render()
redraw
call nerdtree#echo("Refreshing node. This could take a while... DONE")
endfunction
" FUNCTION: nerdtree#ui_glue#setupCommands() {{{1
function! nerdtree#ui_glue#setupCommands()
command! -n=? -complete=dir -bar NERDTree :call g:NERDTreeCreator.CreatePrimary('<args>')
command! -n=? -complete=dir -bar NERDTreeToggle :call g:NERDTreeCreator.TogglePrimary('<args>')
command! -n=0 -bar NERDTreeClose :call nerdtree#closeTreeIfOpen()
command! -n=1 -complete=customlist,nerdtree#completeBookmarks -bar NERDTreeFromBookmark call g:NERDTreeCreator.CreatePrimary('<args>')
command! -n=0 -bar NERDTreeMirror call g:NERDTreeCreator.CreateMirror()
command! -n=0 -bar NERDTreeFind call s:findAndRevealPath()
command! -n=0 -bar NERDTreeFocus call NERDTreeFocus()
command! -n=0 -bar NERDTreeCWD call NERDTreeCWD()
endfunction
" Function: s:SID() {{{1
function s:SID()
if !exists("s:sid")
let s:sid = matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze_SID$')
endif
return s:sid
endfun
" FUNCTION: s:showMenu(node) {{{1
function! s:showMenu(node)
let mc = g:NERDTreeMenuController.New(g:NERDTreeMenuItem.AllEnabled())
call mc.showMenu()
endfunction
" FUNCTION: s:toggleIgnoreFilter() {{{1
function! s:toggleIgnoreFilter()
call b:NERDTree.ui.toggleIgnoreFilter()
endfunction
" FUNCTION: s:toggleShowBookmarks() {{{1
function! s:toggleShowBookmarks()
call b:NERDTree.ui.toggleShowBookmarks()
endfunction
" FUNCTION: s:toggleShowFiles() {{{1
function! s:toggleShowFiles()
call b:NERDTree.ui.toggleShowFiles()
endfunction
" FUNCTION: s:toggleShowHidden() {{{1
" toggles the display of hidden files
function! s:toggleShowHidden()
call b:NERDTree.ui.toggleShowHidden()
endfunction
" FUNCTION: s:toggleZoom() {{{1
function! s:toggleZoom()
call b:NERDTree.ui.toggleZoom()
endfunction
"FUNCTION: nerdtree#ui_glue#upDir(keepState) {{{1
"moves the tree up a level
"
"Args:
"keepState: 1 if the current root should be left open when the tree is
"re-rendered
function! nerdtree#ui_glue#upDir(keepState)
let cwd = b:NERDTreeRoot.path.str({'format': 'UI'})
if cwd ==# "/" || cwd =~# '^[^/]..$'
call nerdtree#echo("already at top dir")
else
if !a:keepState
call b:NERDTreeRoot.close()
endif
let oldRoot = b:NERDTreeRoot
if empty(b:NERDTreeRoot.parent)
let path = b:NERDTreeRoot.path.getParent()
let newRoot = g:NERDTreeDirNode.New(path)
call newRoot.open()
call newRoot.transplantChild(b:NERDTreeRoot)
let b:NERDTreeRoot = newRoot
else
let b:NERDTreeRoot = b:NERDTreeRoot.parent
endif
if g:NERDTreeChDirMode ==# 2
call b:NERDTreeRoot.path.changeToDir()
endif
call b:NERDTree.render()
call oldRoot.putCursorHere(0, 0)
endif
endfunction
" FUNCTION: s:upDirCurrentRootOpen() {{{1
function! s:upDirCurrentRootOpen()
call nerdtree#ui_glue#upDir(1)
endfunction
" FUNCTION: s:upDirCurrentRootClosed() {{{1
function! s:upDirCurrentRootClosed()
call nerdtree#ui_glue#upDir(0)
endfunction
" vim: set sw=4 sts=4 et fdm=marker:

View file

@ -1060,6 +1060,9 @@ NERDTreeAddKeyMap({options}) *NERDTreeAddKeyMap()*
"callback" - the function the new mapping will be bound to "callback" - the function the new mapping will be bound to
"quickhelpText" - the text that will appear in the quickhelp (see "quickhelpText" - the text that will appear in the quickhelp (see
|NERDTree-?|) |NERDTree-?|)
"override" - if 1 then this new mapping will override whatever previous
mapping was defined for the key/scope combo. Useful for overriding the
default mappings.
Additionally, a "scope" argument may be supplied. This constrains the Additionally, a "scope" argument may be supplied. This constrains the
mapping so that it is only activated if the cursor is on a certain object. mapping so that it is only activated if the cursor is on a certain object.

View file

@ -275,7 +275,7 @@ function! s:Bookmark.toRoot()
let targetNode = g:NERDTreeFileNode.New(s:Bookmark.BookmarkFor(self.name).path) let targetNode = g:NERDTreeFileNode.New(s:Bookmark.BookmarkFor(self.name).path)
endtry endtry
call targetNode.makeRoot() call targetNode.makeRoot()
call nerdtree#renderView() call b:NERDTree.render()
call targetNode.putCursorHere(0, 0) call targetNode.putCursorHere(0, 0)
endif endif
endfunction endfunction
@ -293,7 +293,7 @@ function! s:Bookmark.validate()
return 1 return 1
else else
call s:Bookmark.CacheBookmarks(1) call s:Bookmark.CacheBookmarks(1)
call nerdtree#renderView() call b:NERDTree.render()
call nerdtree#echo(self.name . "now points to an invalid location. See :help NERDTreeInvalidBookmarks for info.") call nerdtree#echo(self.name . "now points to an invalid location. See :help NERDTreeInvalidBookmarks for info.")
return 0 return 0
endif endif

View file

@ -7,18 +7,18 @@ let g:NERDTreeCreator = s:Creator
"FUNCTION: s:Creator._bindMappings() {{{1 "FUNCTION: s:Creator._bindMappings() {{{1
function! s:Creator._bindMappings() function! s:Creator._bindMappings()
"make <cr> do the same as the default 'o' mapping "make <cr> do the same as the activate node mapping
exec "nnoremap <silent> <buffer> <cr> :call nerdtree#invokeKeyMap('". g:NERDTreeMapActivateNode ."')<cr>" nnoremap <silent> <buffer> <cr> :call nerdtree#ui_glue#invokeKeyMap(g:NERDTreeMapActivateNode)<cr>
call g:NERDTreeKeyMap.BindAll() call g:NERDTreeKeyMap.BindAll()
command! -buffer -nargs=? Bookmark :call nerdtree#bookmarkNode('<args>') command! -buffer -nargs=? Bookmark :call nerdtree#ui_glue#bookmarkNode('<args>')
command! -buffer -complete=customlist,nerdtree#completeBookmarks -nargs=1 RevealBookmark :call nerdtree#revealBookmark('<args>') command! -buffer -complete=customlist,nerdtree#completeBookmarks -nargs=1 RevealBookmark :call nerdtree#ui_glue#revealBookmark('<args>')
command! -buffer -complete=customlist,nerdtree#completeBookmarks -nargs=1 OpenBookmark :call nerdtree#openBookmark('<args>') command! -buffer -complete=customlist,nerdtree#completeBookmarks -nargs=1 OpenBookmark :call nerdtree#ui_glue#openBookmark('<args>')
command! -buffer -complete=customlist,nerdtree#completeBookmarks -nargs=* ClearBookmarks call nerdtree#clearBookmarks('<args>') command! -buffer -complete=customlist,nerdtree#completeBookmarks -nargs=* ClearBookmarks call nerdtree#ui_glue#clearBookmarks('<args>')
command! -buffer -complete=customlist,nerdtree#completeBookmarks -nargs=+ BookmarkToRoot call g:NERDTreeBookmark.ToRoot('<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 ClearAllBookmarks call g:NERDTreeBookmark.ClearAll() <bar> call b:NERDTree.render()
command! -buffer -nargs=0 ReadBookmarks call g:NERDTreeBookmark.CacheBookmarks(0) <bar> call nerdtree#renderView() command! -buffer -nargs=0 ReadBookmarks call g:NERDTreeBookmark.CacheBookmarks(0) <bar> call b:NERDTree.render()
command! -buffer -nargs=0 WriteBookmarks call g:NERDTreeBookmark.Write() command! -buffer -nargs=0 WriteBookmarks call g:NERDTreeBookmark.Write()
endfunction endfunction
@ -49,26 +49,23 @@ function! s:Creator.createPrimary(name)
call path.changeToDir() call path.changeToDir()
endif endif
if nerdtree#treeExistsForTab() if g:NERDTree.ExistsForTab()
if nerdtree#isTreeOpen() if nerdtree#isTreeOpen()
call nerdtree#closeTree() call nerdtree#closeTree()
endif endif
unlet t:NERDTreeBufName unlet t:NERDTreeBufName
endif endif
let newRoot = g:NERDTreeDirNode.New(path)
call newRoot.open()
call self._createTreeWin() call self._createTreeWin()
call self._createNERDTree(path)
let b:NERDTreeType = "primary"
let b:treeShowHelp = 0 let b:treeShowHelp = 0
let b:NERDTreeIgnoreEnabled = 1 let b:NERDTreeIgnoreEnabled = 1
let b:NERDTreeShowFiles = g:NERDTreeShowFiles let b:NERDTreeShowFiles = g:NERDTreeShowFiles
let b:NERDTreeShowHidden = g:NERDTreeShowHidden let b:NERDTreeShowHidden = g:NERDTreeShowHidden
let b:NERDTreeShowBookmarks = g:NERDTreeShowBookmarks let b:NERDTreeShowBookmarks = g:NERDTreeShowBookmarks
let b:NERDTreeRoot = newRoot
let b:NERDTreeType = "primary"
call nerdtree#renderView() call b:NERDTree.render()
call b:NERDTreeRoot.putCursorHere(0, 0) call b:NERDTreeRoot.putCursorHere(0, 0)
call self._broadcastInitEvent() call self._broadcastInitEvent()
@ -99,18 +96,26 @@ function! s:Creator.createSecondary(dir)
exec "silent edit " . self._nextBufferName() exec "silent edit " . self._nextBufferName()
let b:NERDTreePreviousBuf = bufnr(previousBuf) let b:NERDTreePreviousBuf = bufnr(previousBuf)
call self._createNERDTree(path)
let b:NERDTreeRoot = g:NERDTreeDirNode.New(path)
call b:NERDTreeRoot.open()
call self._setCommonBufOptions() call self._setCommonBufOptions()
let b:NERDTreeType = "secondary" let b:NERDTreeType = "secondary"
call nerdtree#renderView() call b:NERDTree.render()
call self._broadcastInitEvent() call self._broadcastInitEvent()
endfunction endfunction
" FUNCTION: s:Creator._createNERDTree(path) {{{1
function! s:Creator._createNERDTree(path)
let b:NERDTree = g:NERDTree.New(a:path)
"TODO: This is kept for compatability only since many things use
"b:NERDTreeRoot instead of the new NERDTree.root
"Remove this one day
let b:NERDTreeRoot = b:NERDTree.root
call b:NERDTree.root.open()
endfunction
" FUNCTION: s:Creator.CreateMirror() {{{1 " FUNCTION: s:Creator.CreateMirror() {{{1
function! s:Creator.CreateMirror() function! s:Creator.CreateMirror()
let creator = s:Creator.New() let creator = s:Creator.New()
@ -122,12 +127,12 @@ function! s:Creator.createMirror()
"get the names off all the nerd tree buffers "get the names off all the nerd tree buffers
let treeBufNames = [] let treeBufNames = []
for i in range(1, tabpagenr("$")) for i in range(1, tabpagenr("$"))
let nextName = nerdtree#tabpagevar(i, 'NERDTreeBufName') let nextName = self._tabpagevar(i, 'NERDTreeBufName')
if nextName != -1 && (!exists("t:NERDTreeBufName") || nextName != t:NERDTreeBufName) if nextName != -1 && (!exists("t:NERDTreeBufName") || nextName != t:NERDTreeBufName)
call add(treeBufNames, nextName) call add(treeBufNames, nextName)
endif endif
endfor endfor
let treeBufNames = nerdtree#unique(treeBufNames) let treeBufNames = self._uniq(treeBufNames)
"map the option names (that the user will be prompted with) to the nerd "map the option names (that the user will be prompted with) to the nerd
"tree buffer names "tree buffer names
@ -158,7 +163,7 @@ function! s:Creator.createMirror()
return return
endif endif
if nerdtree#treeExistsForTab() && nerdtree#isTreeOpen() if g:NERDTree.ExistsForTab() && nerdtree#isTreeOpen()
call nerdtree#closeTree() call nerdtree#closeTree()
endif endif
@ -166,7 +171,7 @@ function! s:Creator.createMirror()
call self._createTreeWin() call self._createTreeWin()
exec 'buffer ' . bufferName exec 'buffer ' . bufferName
if !&hidden if !&hidden
call nerdtree#renderView() call b:NERDTree.render()
endif endif
endfunction endfunction
@ -290,6 +295,24 @@ function! s:Creator._setupStatusline()
endif endif
endfunction endfunction
" FUNCTION: s:Creator._tabpagevar(tabnr, var) {{{1
function! s:Creator._tabpagevar(tabnr, var)
let currentTab = tabpagenr()
let old_ei = &ei
set ei=all
exec "tabnext " . a:tabnr
let v = -1
if exists('t:' . a:var)
exec 'let v = t:' . a:var
endif
exec "tabnext " . currentTab
let &ei = old_ei
return v
endfunction
"FUNCTION: s:Creator.TogglePrimary(dir) {{{1 "FUNCTION: s:Creator.TogglePrimary(dir) {{{1
function! s:Creator.TogglePrimary(dir) function! s:Creator.TogglePrimary(dir)
let creator = s:Creator.New() let creator = s:Creator.New()
@ -304,13 +327,13 @@ endfunction
"dir: the full path for the root node (is only used if the NERD tree is being "dir: the full path for the root node (is only used if the NERD tree is being
"initialized. "initialized.
function! s:Creator.togglePrimary(dir) function! s:Creator.togglePrimary(dir)
if nerdtree#treeExistsForTab() if g:NERDTree.ExistsForTab()
if !nerdtree#isTreeOpen() if !nerdtree#isTreeOpen()
call self._createTreeWin() call self._createTreeWin()
if !&hidden if !&hidden
call nerdtree#renderView() call b:NERDTree.render()
endif endif
call nerdtree#restoreScreenState() call b:NERDTree.ui.restoreScreenState()
else else
call nerdtree#closeTree() call nerdtree#closeTree()
endif endif
@ -319,4 +342,16 @@ function! s:Creator.togglePrimary(dir)
endif endif
endfunction endfunction
" Function: s:Creator._uniq(list) {{{1
" returns a:list without duplicates
function! s:Creator._uniq(list)
let uniqlist = []
for elem in a:list
if index(uniqlist, elem) ==# -1
let uniqlist += [elem]
endif
endfor
return uniqlist
endfunction
" vim: set sw=4 sts=4 et fdm=marker: " vim: set sw=4 sts=4 et fdm=marker:

View file

@ -0,0 +1,13 @@
"CLASS: Event
"============================================================
let s:Event = {}
let g:NERDTreeEvent = s:Event
function! s:Event.New(nerdtree, subject, action, params) abort
let newObj = copy(self)
let newObj.nerdtree = a:nerdtree
let newObj.subject = a:subject
let newObj.action = a:action
let newObj.params = a:params
return newObj
endfunction

View file

@ -0,0 +1,56 @@
"CLASS: FlagSet
"============================================================
let s:FlagSet = {}
let g:NERDTreeFlagSet = s:FlagSet
"FUNCTION: FlagSet.addFlag(scope, flag) {{{1
function! s:FlagSet.addFlag(scope, flag)
let flags = self._flagsForScope(a:scope)
if index(flags, a:flag) == -1
call add(flags, a:flag)
end
endfunction
"FUNCTION: FlagSet.clearFlags(scope) {{{1
function! s:FlagSet.clearFlags(scope)
let self._flags[a:scope] = []
endfunction
"FUNCTION: FlagSet._flagsForScope(scope) {{{1
function! s:FlagSet._flagsForScope(scope)
if !has_key(self._flags, a:scope)
let self._flags[a:scope] = []
endif
return self._flags[a:scope]
endfunction
"FUNCTION: FlagSet.New() {{{1
function! s:FlagSet.New()
let newObj = copy(self)
let newObj._flags = {}
return newObj
endfunction
"FUNCTION: FlagSet.removeFlag(scope, flag) {{{1
function! s:FlagSet.removeFlag(scope, flag)
let flags = self._flagsForScope(a:scope)
let i = index(flags, a:flag)
if i >= 0
call remove(flags, i)
endif
endfunction
"FUNCTION: FlagSet.renderToString() {{{1
function! s:FlagSet.renderToString()
let flagstring = ""
for i in values(self._flags)
let flagstring .= join(i)
endfor
if len(flagstring) == 0
return ""
endif
return '[' . flagstring . ']'
endfunction

View file

@ -44,7 +44,7 @@ function! s:KeyMap.bind()
let premap = self.key == "<LeftRelease>" ? " <LeftRelease>" : " " let premap = self.key == "<LeftRelease>" ? " <LeftRelease>" : " "
exec 'nnoremap <buffer> <silent> '. self.key . premap . ':call nerdtree#invokeKeyMap("'. keymapInvokeString .'")<cr>' exec 'nnoremap <buffer> <silent> '. self.key . premap . ':call nerdtree#ui_glue#invokeKeyMap("'. keymapInvokeString .'")<cr>'
endfunction endfunction
"FUNCTION: KeyMap.Remove(key, scope) {{{1 "FUNCTION: KeyMap.Remove(key, scope) {{{1
@ -79,6 +79,16 @@ endfunction
"If a keymap has the scope of "all" then it will be called if no other keymap "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. "is found for a:key and the scope.
function! s:KeyMap.Invoke(key) function! s:KeyMap.Invoke(key)
"required because clicking the command window below another window still
"invokes the <LeftRelease> mapping - but changes the window cursor
"is in first
"
"TODO: remove this check when the vim bug is fixed
if !g:NERDTree.ExistsForBuf()
return {}
endif
let node = g:NERDTreeFileNode.GetSelected() let node = g:NERDTreeFileNode.GetSelected()
if !empty(node) if !empty(node)
@ -124,8 +134,14 @@ endfunction
"FUNCTION: KeyMap.Create(options) {{{1 "FUNCTION: KeyMap.Create(options) {{{1
function! s:KeyMap.Create(options) function! s:KeyMap.Create(options)
let newKeyMap = copy(self)
let opts = extend({'scope': 'all', 'quickhelpText': ''}, copy(a:options)) let opts = extend({'scope': 'all', 'quickhelpText': ''}, copy(a:options))
"dont override other mappings unless the 'override' option is given
if get(opts, 'override', 0) == 0 && !empty(s:KeyMap.FindFor(opts['key'], opts['scope']))
return
end
let newKeyMap = copy(self)
let newKeyMap.key = opts['key'] let newKeyMap.key = opts['key']
let newKeyMap.quickhelpText = opts['quickhelpText'] let newKeyMap.quickhelpText = opts['quickhelpText']
let newKeyMap.callback = opts['callback'] let newKeyMap.callback = opts['callback']

View file

@ -0,0 +1,39 @@
"CLASS: NERDTree
"============================================================
let s:NERDTree = {}
let g:NERDTree = s:NERDTree
" Function: s:NERDTree.ExistsForBuffer() {{{1
" Returns 1 if a nerd tree root exists in the current buffer
function! s:NERDTree.ExistsForBuf()
return exists("b:NERDTreeRoot")
endfunction
" Function: s:NERDTree.ExistsForTab() {{{1
" Returns 1 if a nerd tree root exists in the current tab
function! s:NERDTree.ExistsForTab()
return exists("t:NERDTreeBufName")
endfunction
function! s:NERDTree.ForCurrentBuf()
if s:NERDTree.ExistsForBuf()
return b:NERDTree
else
return {}
endif
endfunction
function! s:NERDTree.New(path)
let newObj = copy(self)
let newObj.ui = g:NERDTreeUI.New(newObj)
let newObj.root = g:NERDTreeDirNode.New(a:path)
return newObj
endfunction
"FUNCTION: s:NERDTree.render() {{{1
"A convenience function - since this is called often
function! s:NERDTree.render()
call self.ui.render()
endfunction

View file

@ -0,0 +1,35 @@
"CLASS: Notifier
"============================================================
let s:Notifier = {}
function! s:Notifier.AddListener(event, funcname)
let listeners = s:Notifier.GetListenersForEvent(a:event)
if listeners == []
let listenersMap = s:Notifier.GetListenersMap()
let listenersMap[a:event] = listeners
endif
call add(listeners, a:funcname)
endfunction
function! s:Notifier.NotifyListeners(event, path, params)
let event = g:NERDTreeEvent.New(b:NERDTree, a:path, a:event, a:params)
for listener in s:Notifier.GetListenersForEvent(a:event)
call {listener}(event)
endfor
endfunction
function! s:Notifier.GetListenersMap()
if !exists("s:refreshListenersMap")
let s:refreshListenersMap = {}
endif
return s:refreshListenersMap
endfunction
function! s:Notifier.GetListenersForEvent(name)
let listenersMap = s:Notifier.GetListenersMap()
return get(listenersMap, a:name, [])
endfunction
let g:NERDTreePathNotifier = deepcopy(s:Notifier)

View file

@ -3,6 +3,29 @@
let s:Opener = {} let s:Opener = {}
let g:NERDTreeOpener = s:Opener let g:NERDTreeOpener = s:Opener
"FUNCTION: s:Opener._bufInWindows(bnum){{{1
"[[STOLEN FROM VTREEEXPLORER.VIM]]
"Determine the number of windows open to this buffer number.
"Care of Yegappan Lakshman. Thanks!
"
"Args:
"bnum: the subject buffers buffer number
function! s:Opener._bufInWindows(bnum)
let cnt = 0
let winnum = 1
while 1
let bufnum = winbufnr(winnum)
if bufnum < 0
break
endif
if bufnum ==# a:bnum
let cnt = cnt + 1
endif
let winnum = winnum + 1
endwhile
return cnt
endfunction
"FUNCTION: Opener._checkToCloseTree(newtab) {{{1 "FUNCTION: Opener._checkToCloseTree(newtab) {{{1
"Check the class options and global options (i.e. NERDTreeQuitOnOpen) to see "Check the class options and global options (i.e. NERDTreeQuitOnOpen) to see
"if the tree should be closed now. "if the tree should be closed now.
@ -21,6 +44,24 @@ function! s:Opener._checkToCloseTree(newtab)
endif endif
endfunction endfunction
"FUNCTION: s:Opener._firstUsableWindow(){{{1
"find the window number of the first normal window
function! s:Opener._firstUsableWindow()
let i = 1
while i <= winnr("$")
let bnum = winbufnr(i)
if bnum != -1 && getbufvar(bnum, '&buftype') ==# ''
\ && !getwinvar(i, '&previewwindow')
\ && (!getbufvar(bnum, '&modified') || &hidden)
return i
endif
let i += 1
endwhile
return -1
endfunction
"FUNCTION: Opener._gotoTargetWin() {{{1 "FUNCTION: Opener._gotoTargetWin() {{{1
function! s:Opener._gotoTargetWin() function! s:Opener._gotoTargetWin()
if b:NERDTreeType ==# "secondary" if b:NERDTreeType ==# "secondary"
@ -48,6 +89,37 @@ function! s:Opener._gotoTargetWin()
endif endif
endfunction endfunction
"FUNCTION: s:Opener._isWindowUsable(winnumber) {{{1
"Returns 0 if opening a file from the tree in the given window requires it to
"be split, 1 otherwise
"
"Args:
"winnumber: the number of the window in question
function! s:Opener._isWindowUsable(winnumber)
"gotta split if theres only one window (i.e. the NERD tree)
if winnr("$") ==# 1
return 0
endif
let oldwinnr = winnr()
call nerdtree#exec(a:winnumber . "wincmd p")
let specialWindow = getbufvar("%", '&buftype') != '' || getwinvar('%', '&previewwindow')
let modified = &modified
call nerdtree#exec(oldwinnr . "wincmd p")
"if its a special window e.g. quickfix or another explorer plugin then we
"have to split
if specialWindow
return 0
endif
if &hidden
return 1
endif
return !modified || self._bufInWindows(winbufnr(a:winnumber)) >= 2
endfunction
"FUNCTION: Opener.New(path, opts) {{{1 "FUNCTION: Opener.New(path, opts) {{{1
"Args: "Args:
" "
@ -190,7 +262,7 @@ function! s:Opener._openDirectory(node)
call self._gotoTargetWin() call self._gotoTargetWin()
if empty(self._where) if empty(self._where)
call a:node.makeRoot() call a:node.makeRoot()
call nerdtree#renderView() call b:NERDTree.render()
call a:node.putCursorHere(0, 0) call a:node.putCursorHere(0, 0)
elseif self._where == 't' elseif self._where == 't'
call g:NERDTreeCreator.CreatePrimary(a:node.path.str()) call g:NERDTreeCreator.CreatePrimary(a:node.path.str())
@ -206,12 +278,12 @@ endfunction
"FUNCTION: Opener._previousWindow() {{{1 "FUNCTION: Opener._previousWindow() {{{1
function! s:Opener._previousWindow() function! s:Opener._previousWindow()
if !nerdtree#isWindowUsable(winnr("#")) && nerdtree#firstUsableWindow() ==# -1 if !self._isWindowUsable(winnr("#")) && self._firstUsableWindow() ==# -1
call self._newSplit() call self._newSplit()
else else
try try
if !nerdtree#isWindowUsable(winnr("#")) if !self._isWindowUsable(winnr("#"))
call nerdtree#exec(nerdtree#firstUsableWindow() . "wincmd w") call nerdtree#exec(self._firstUsableWindow() . "wincmd w")
else else
call nerdtree#exec('wincmd p') call nerdtree#exec('wincmd p')
endif endif

View file

@ -33,8 +33,10 @@ function! s:Path.bookmarkNames()
endfunction endfunction
"FUNCTION: Path.cacheDisplayString() {{{1 "FUNCTION: Path.cacheDisplayString() {{{1
function! s:Path.cacheDisplayString() function! s:Path.cacheDisplayString() abort
let self.cachedDisplayString = self.getLastPathComponent(1) let self.cachedDisplayString = self.flagSet.renderToString()
let self.cachedDisplayString .= self.getLastPathComponent(1)
if self.isExecutable if self.isExecutable
let self.cachedDisplayString = self.cachedDisplayString . '*' let self.cachedDisplayString = self.cachedDisplayString . '*'
@ -170,7 +172,7 @@ function! s:Path.copy(dest)
let dest = s:Path.WinToUnixPath(a:dest) let dest = s:Path.WinToUnixPath(a:dest)
let cmd = g:NERDTreeCopyCmd . " " . escape(self.str(), nerdtree#escChars()) . " " . escape(dest, nerdtree#escChars()) let cmd = g:NERDTreeCopyCmd . " " . escape(self.str(), self._escChars()) . " " . escape(dest, self._escChars())
let success = system(cmd) let success = system(cmd)
if success != 0 if success != 0
throw "NERDTree.CopyError: Could not copy ''". self.str() ."'' to: '" . a:dest . "'" throw "NERDTree.CopyError: Could not copy ''". self.str() ."'' to: '" . a:dest . "'"
@ -289,6 +291,15 @@ function! s:Path.exists()
return filereadable(p) || isdirectory(p) return filereadable(p) || isdirectory(p)
endfunction endfunction
"FUNCTION: Path._escChars() {{{1
function! s:Path._escChars()
if nerdtree#runningWindows()
return " `\|\"#%&,?()\*^<>"
endif
return " \\`\|\"#%&,?()\*^<>[]"
endfunction
"FUNCTION: Path.getDir() {{{1 "FUNCTION: Path.getDir() {{{1
" "
"Returns this path if it is a directory, else this paths parent. "Returns this path if it is a directory, else this paths parent.
@ -460,6 +471,7 @@ function! s:Path.New(path)
call newPath.readInfoFromDisk(s:Path.AbsolutePathFor(a:path)) call newPath.readInfoFromDisk(s:Path.AbsolutePathFor(a:path))
let newPath.cachedDisplayString = "" let newPath.cachedDisplayString = ""
let newPath.flagSet = g:NERDTreeFlagSet.New()
return newPath return newPath
endfunction endfunction
@ -537,6 +549,13 @@ endfunction
"FUNCTION: Path.refresh() {{{1 "FUNCTION: Path.refresh() {{{1
function! s:Path.refresh() function! s:Path.refresh()
call self.readInfoFromDisk(self.str()) call self.readInfoFromDisk(self.str())
call g:NERDTreePathNotifier.NotifyListeners('refresh', self, {})
call self.cacheDisplayString()
endfunction
"FUNCTION: Path.refreshFlags() {{{1
function! s:Path.refreshFlags()
call g:NERDTreePathNotifier.NotifyListeners('refreshFlags', self, {})
call self.cacheDisplayString() call self.cacheDisplayString()
endfunction endfunction
@ -625,7 +644,7 @@ endfunction
" "
" returns a string that can be used with :cd " returns a string that can be used with :cd
function! s:Path._strForCd() function! s:Path._strForCd()
return escape(self.str(), nerdtree#escChars()) return escape(self.str(), self._escChars())
endfunction endfunction
"FUNCTION: Path._strForEdit() {{{1 "FUNCTION: Path._strForEdit() {{{1
@ -633,7 +652,7 @@ endfunction
"Return: the string for this path that is suitable to be used with the :edit "Return: the string for this path that is suitable to be used with the :edit
"command "command
function! s:Path._strForEdit() function! s:Path._strForEdit()
let p = escape(self.str({'format': 'UI'}), nerdtree#escChars()) let p = escape(self.str({'format': 'UI'}), self._escChars())
let cwd = getcwd() . s:Path.Slash() let cwd = getcwd() . s:Path.Slash()
"return a relative path if we can "return a relative path if we can
@ -673,7 +692,7 @@ function! s:Path._strForGlob()
let toReturn = lead . join(self.pathSegments, s:Path.Slash()) let toReturn = lead . join(self.pathSegments, s:Path.Slash())
if !nerdtree#runningWindows() if !nerdtree#runningWindows()
let toReturn = escape(toReturn, nerdtree#escChars()) let toReturn = escape(toReturn, self._escChars())
endif endif
return toReturn return toReturn
endfunction endfunction

View file

@ -21,7 +21,7 @@ unlet s:TreeDirNode.activate
function! s:TreeDirNode.activate(...) function! s:TreeDirNode.activate(...)
let opts = a:0 ? a:1 : {} let opts = a:0 ? a:1 : {}
call self.toggleOpen(opts) call self.toggleOpen(opts)
call nerdtree#renderView() call b:NERDTree.render()
call self.putCursorHere(0, 0) call self.putCursorHere(0, 0)
endfunction endfunction
@ -252,6 +252,7 @@ function! s:TreeDirNode._initChildren(silent)
try try
let path = g:NERDTreePath.New(i) let path = g:NERDTreePath.New(i)
call self.createChild(path, 0) call self.createChild(path, 0)
call g:NERDTreePathNotifier.NotifyListeners('init', path, {})
catch /^NERDTree.\(InvalidArguments\|InvalidFiletype\)Error/ catch /^NERDTree.\(InvalidArguments\|InvalidFiletype\)Error/
let invalidFilesFound += 1 let invalidFilesFound += 1
endtry endtry
@ -438,6 +439,20 @@ function! s:TreeDirNode.refresh()
endif endif
endfunction endfunction
"FUNCTION: TreeDirNode.refreshFlags() {{{1
unlet s:TreeDirNode.refreshFlags
function! s:TreeDirNode.refreshFlags()
call self.path.refreshFlags()
for i in self.children
call i.refreshFlags()
endfor
endfunction
"FUNCTION: TreeDirNode.refreshDirFlags() {{{1
function! s:TreeDirNode.refreshDirFlags()
call self.path.refreshFlags()
endfunction
"FUNCTION: TreeDirNode.reveal(path) {{{1 "FUNCTION: TreeDirNode.reveal(path) {{{1
"reveal the given path, i.e. cache and open all treenodes needed to display it "reveal the given path, i.e. cache and open all treenodes needed to display it
"in the UI "in the UI
@ -450,7 +465,7 @@ function! s:TreeDirNode.reveal(path)
if self.path.equals(a:path.getParent()) if self.path.equals(a:path.getParent())
let n = self.findNode(a:path) let n = self.findNode(a:path)
call nerdtree#renderView() call b:NERDTree.render()
call n.putCursorHere(1,0) call n.putCursorHere(1,0)
return return
endif endif

View file

@ -178,79 +178,20 @@ function! s:TreeFileNode.findSibling(direction)
return {} return {}
endfunction 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 "FUNCTION: TreeFileNode.GetRootForTab(){{{1
"get the root node for this tab "get the root node for this tab
function! s:TreeFileNode.GetRootForTab() function! s:TreeFileNode.GetRootForTab()
if nerdtree#treeExistsForTab() if g:NERDTree.ExistsForTab()
return getbufvar(t:NERDTreeBufName, 'NERDTreeRoot') return getbufvar(t:NERDTreeBufName, 'NERDTreeRoot')
end end
return {} return {}
endfunction 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 "FUNCTION: TreeFileNode.GetSelected() {{{1
"gets the treenode that the cursor is currently over "gets the treenode that the cursor is currently over
function! s:TreeFileNode.GetSelected() function! s:TreeFileNode.GetSelected()
try try
let path = nerdtree#getPath(line(".")) let path = b:NERDTree.ui.getPath(line("."))
if path ==# {} if path ==# {}
return {} return {}
endif endif
@ -270,7 +211,7 @@ endfunction
"FUNCTION: TreeFileNode.isRoot() {{{1 "FUNCTION: TreeFileNode.isRoot() {{{1
"returns 1 if this node is b:NERDTreeRoot "returns 1 if this node is b:NERDTreeRoot
function! s:TreeFileNode.isRoot() function! s:TreeFileNode.isRoot()
if !nerdtree#treeExistsForBuf() if !g:NERDTree.ExistsForBuf()
throw "NERDTree.NoTreeError: No tree exists for the current buffer" throw "NERDTree.NoTreeError: No tree exists for the current buffer"
endif endif
@ -348,7 +289,7 @@ endfunction
"recurseUpward: try to put the cursor on the parent if the this node isnt "recurseUpward: try to put the cursor on the parent if the this node isnt
"visible "visible
function! s:TreeFileNode.putCursorHere(isJump, recurseUpward) function! s:TreeFileNode.putCursorHere(isJump, recurseUpward)
let ln = self.getLineNum() let ln = b:NERDTree.ui.getLineNum(self)
if ln != -1 if ln != -1
if a:isJump if a:isJump
mark ' mark '
@ -357,11 +298,11 @@ function! s:TreeFileNode.putCursorHere(isJump, recurseUpward)
else else
if a:recurseUpward if a:recurseUpward
let node = self let node = self
while node != {} && node.getLineNum() ==# -1 while node != {} && b:NERDTree.ui.getLineNum(node) ==# -1
let node = node.parent let node = node.parent
call node.open() call node.open()
endwhile endwhile
call nerdtree#renderView() call b:NERDTree.render()
call node.putCursorHere(a:isJump, 0) call node.putCursorHere(a:isJump, 0)
endif endif
endif endif
@ -372,6 +313,11 @@ function! s:TreeFileNode.refresh()
call self.path.refresh() call self.path.refresh()
endfunction endfunction
"FUNCTION: TreeFileNode.refreshFlags() {{{1
function! s:TreeFileNode.refreshFlags()
call self.path.refreshFlags()
endfunction
"FUNCTION: TreeFileNode.rename() {{{1 "FUNCTION: TreeFileNode.rename() {{{1
"Calls the rename method for this nodes path obj "Calls the rename method for this nodes path obj
function! s:TreeFileNode.rename(newName) function! s:TreeFileNode.rename(newName)

View file

@ -0,0 +1,332 @@
"CLASS: UI
"============================================================
let s:UI = {}
let g:NERDTreeUI = s:UI
function! s:UI.lolcats()
echomsg "lolcats"
endfunction
"FUNCTION: s:UI.centerView() {{{2
"centers the nerd tree window around the cursor (provided the nerd tree
"options permit)
function! s:UI.centerView()
if g:NERDTreeAutoCenter
let current_line = winline()
let lines_to_top = current_line
let lines_to_bottom = winheight(nerdtree#getTreeWinNum()) - current_line
if lines_to_top < g:NERDTreeAutoCenterThreshold || lines_to_bottom < g:NERDTreeAutoCenterThreshold
normal! zz
endif
endif
endfunction
"FUNCTION: s:UI.new(nerdtree) {{{1
function! s:UI.New(nerdtree)
let newObj = copy(self)
let newObj.nerdtree = a:nerdtree
return newObj
endfunction
"FUNCTION: s:UI.getPath(ln) {{{1
"Gets the full path to the node that is rendered on the given line number
"
"Args:
"ln: the line number to get the path for
"
"Return:
"A path if a node was selected, {} if nothing is selected.
"If the 'up a dir' line was selected then the path to the parent of the
"current root is returned
function! s:UI.getPath(ln)
let line = getline(a:ln)
let rootLine = self.getRootLineNum()
"check to see if we have the root node
if a:ln == rootLine
return b:NERDTreeRoot.path
endif
if !g:NERDTreeDirArrows
" in case called from outside the tree
if line !~# '^ *[|`▸▾ ]' || line =~# '^$'
return {}
endif
endif
if line ==# nerdtree#treeUpDirLine()
return b:NERDTreeRoot.path.getParent()
endif
let indent = self._indentLevelFor(line)
"remove the tree parts and the leading space
let curFile = nerdtree#stripMarkupFromLine(line, 0)
let wasdir = 0
if curFile =~# '/$'
let wasdir = 1
let curFile = substitute(curFile, '/\?$', '/', "")
endif
let dir = ""
let lnum = a:ln
while lnum > 0
let lnum = lnum - 1
let curLine = getline(lnum)
let curLineStripped = nerdtree#stripMarkupFromLine(curLine, 1)
"have we reached the top of the tree?
if lnum == rootLine
let dir = b:NERDTreeRoot.path.str({'format': 'UI'}) . dir
break
endif
if curLineStripped =~# '/$'
let lpindent = self._indentLevelFor(curLine)
if lpindent < indent
let indent = indent - 1
let dir = substitute (curLineStripped,'^\\', "", "") . dir
continue
endif
endif
endwhile
let curFile = b:NERDTreeRoot.path.drive . dir . curFile
let toReturn = g:NERDTreePath.New(curFile)
return toReturn
endfunction
"FUNCTION: s:UI.getLineNum(file_node){{{1
"returns the line number this node is rendered on, or -1 if it isnt rendered
function! s:UI.getLineNum(file_node)
"if the node is the root then return the root line no.
if a:file_node.isRoot()
return b:NERDTree.ui.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 = a:file_node.path.str({'format': 'UI'})
let lnum = b:NERDTree.ui.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 = self._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: s:UI.getRootLineNum(){{{1
"gets the line number of the root node
function! s:UI.getRootLineNum()
let rootLine = 1
while getline(rootLine) !~# '^\(/\|<\)'
let rootLine = rootLine + 1
endwhile
return rootLine
endfunction
"FUNCTION: s:UI._indentLevelFor(line) {{{2
function! s:UI._indentLevelFor(line)
let level = match(a:line, '[^ \-+~▸▾`|]') / nerdtree#treeWid()
" check if line includes arrows
if match(a:line, '[▸▾]') > -1
" decrement level as arrow uses 3 ascii chars
let level = level - 1
endif
return level
endfunction
"FUNCTION: s:UI.restoreScreenState() {{{2
"
"Sets the screen state back to what it was when nerdtree#saveScreenState was last
"called.
"
"Assumes the cursor is in the NERDTree window
function! s:UI.restoreScreenState()
if !has_key(self, '_screenState')
return
endif
exec("silent vertical resize " . self._screenState['oldWindowSize'])
let old_scrolloff=&scrolloff
let &scrolloff=0
call cursor(self._screenState['oldTopLine'], 0)
normal! zt
call setpos(".", self._screenState['oldPos'])
let &scrolloff=old_scrolloff
endfunction
"FUNCTION: s:UI.saveScreenState() {{{2
"Saves the current cursor position in the current buffer and the window
"scroll position
function! s:UI.saveScreenState()
let win = winnr()
try
call nerdtree#putCursorInTreeWin()
let self._screenState = {}
let self._screenState['oldPos'] = getpos(".")
let self._screenState['oldTopLine'] = line("w0")
let self._screenState['oldWindowSize']= winwidth("")
call nerdtree#exec(win . "wincmd w")
catch /^NERDTree.InvalidOperationError/
endtry
endfunction
"FUNCTION: s:UI.render() {{{2
function! s:UI.render()
setlocal modifiable
"remember the top line of the buffer and the current line so we can
"restore the view exactly how it was
let curLine = line(".")
let curCol = col(".")
let topLine = line("w0")
"delete all lines in the buffer (being careful not to clobber a register)
silent 1,$delete _
call nerdtree#dumpHelp()
"delete the blank line before the help and add one after it
if g:NERDTreeMinimalUI == 0
call setline(line(".")+1, "")
call cursor(line(".")+1, col("."))
endif
if b:NERDTreeShowBookmarks
call nerdtree#renderBookmarks()
endif
"add the 'up a dir' line
if !g:NERDTreeMinimalUI
call setline(line(".")+1, nerdtree#treeUpDirLine())
call cursor(line(".")+1, col("."))
endif
"draw the header line
let header = b:NERDTreeRoot.path.str({'format': 'UI', 'truncateTo': winwidth(0)})
call setline(line(".")+1, header)
call cursor(line(".")+1, col("."))
"draw the tree
let old_o = @o
let @o = b:NERDTreeRoot.renderToString()
silent put o
let @o = old_o
"delete the blank line at the top of the buffer
silent 1,1delete _
"restore the view
let old_scrolloff=&scrolloff
let &scrolloff=0
call cursor(topLine, 1)
normal! zt
call cursor(curLine, curCol)
let &scrolloff = old_scrolloff
setlocal nomodifiable
endfunction
"FUNCTION: UI.renderViewSavingPosition {{{1
"Renders the tree and ensures the cursor stays on the current node or the
"current nodes parent if it is no longer available upon re-rendering
function! s:UI.renderViewSavingPosition()
let currentNode = g:NERDTreeFileNode.GetSelected()
"go up the tree till we find a node that will be visible or till we run
"out of nodes
while currentNode != {} && !currentNode.isVisible() && !currentNode.isRoot()
let currentNode = currentNode.parent
endwhile
call b:NERDTree.render()
if currentNode != {}
call currentNode.putCursorHere(0, 0)
endif
endfunction
" FUNCTION: s:UI.toggleIgnoreFilter() {{{1
" toggles the use of the NERDTreeIgnore option
function! s:UI.toggleIgnoreFilter()
let b:NERDTreeIgnoreEnabled = !b:NERDTreeIgnoreEnabled
call b:NERDTree.ui.renderViewSavingPosition()
call b:NERDTree.ui.centerView()
endfunction
" FUNCTION: s:UI.toggleShowBookmarks() {{{1
" toggles the display of bookmarks
function! s:UI.toggleShowBookmarks()
let b:NERDTreeShowBookmarks = !b:NERDTreeShowBookmarks
if b:NERDTreeShowBookmarks
call b:NERDTree.render()
call nerdtree#putCursorOnBookmarkTable()
else
call b:NERDTree.ui.renderViewSavingPosition()
endif
call b:NERDTree.ui.centerView()
endfunction
" FUNCTION: s:UI.toggleShowFiles() {{{1
" toggles the display of hidden files
function! s:UI.toggleShowFiles()
let b:NERDTreeShowFiles = !b:NERDTreeShowFiles
call b:NERDTree.ui.renderViewSavingPosition()
call b:NERDTree.ui.centerView()
endfunction
" FUNCTION: s:UI.toggleShowHidden() {{{1
" toggles the display of hidden files
function! s:UI.toggleShowHidden()
let b:NERDTreeShowHidden = !b:NERDTreeShowHidden
call b:NERDTree.ui.renderViewSavingPosition()
call self.centerView()
endfunction
" FUNCTION: s:UI.toggleZoom() {{{1
" zoom (maximize/minimize) the NERDTree window
function! s:UI.toggleZoom()
if exists("b:NERDTreeZoomed") && b:NERDTreeZoomed
let size = exists("b:NERDTreeOldWindowSize") ? b:NERDTreeOldWindowSize : g:NERDTreeWinSize
exec "silent vertical resize ". size
let b:NERDTreeZoomed = 0
else
exec "vertical resize"
let b:NERDTreeZoomed = 1
endif
endfunction

View file

@ -117,7 +117,7 @@ function! NERDTreeAddNode()
let newTreeNode = g:NERDTreeFileNode.New(newPath) let newTreeNode = g:NERDTreeFileNode.New(newPath)
if empty(parentNode) if empty(parentNode)
call b:NERDTreeRoot.refresh() call b:NERDTreeRoot.refresh()
call nerdtree#renderView() call b:NERDTree.render()
elseif parentNode.isOpen || !empty(parentNode.children) elseif parentNode.isOpen || !empty(parentNode.children)
call parentNode.addChild(newTreeNode, 1) call parentNode.addChild(newTreeNode, 1)
call NERDTreeRender() call NERDTreeRender()
@ -230,7 +230,7 @@ function! NERDTreeCopyNode()
let newNode = currentNode.copy(newNodePath) let newNode = currentNode.copy(newNodePath)
if empty(newNode) if empty(newNode)
call b:NERDTreeRoot.refresh() call b:NERDTreeRoot.refresh()
call nerdtree#renderView() call b:NERDTree.render()
else else
call NERDTreeRender() call NERDTreeRender()
call newNode.putCursorHere(0, 0) call newNode.putCursorHere(0, 0)

View file

@ -142,20 +142,13 @@ call nerdtree#loadClassFiles()
" SECTION: Commands {{{1 " SECTION: Commands {{{1
"============================================================ "============================================================
"init the command that users start the nerd tree with call nerdtree#ui_glue#setupCommands()
command! -n=? -complete=dir -bar NERDTree :call g:NERDTreeCreator.CreatePrimary('<args>')
command! -n=? -complete=dir -bar NERDTreeToggle :call g:NERDTreeCreator.TogglePrimary('<args>')
command! -n=0 -bar NERDTreeClose :call nerdtree#closeTreeIfOpen()
command! -n=1 -complete=customlist,nerdtree#completeBookmarks -bar NERDTreeFromBookmark call g:NERDTreeCreator.CreatePrimary('<args>')
command! -n=0 -bar NERDTreeMirror call g:NERDTreeCreator.CreateMirror()
command! -n=0 -bar NERDTreeFind call nerdtree#findAndRevealPath()
command! -n=0 -bar NERDTreeFocus call NERDTreeFocus()
command! -n=0 -bar NERDTreeCWD call NERDTreeCWD()
" SECTION: Auto commands {{{1 " SECTION: Auto commands {{{1
"============================================================ "============================================================
augroup NERDTree augroup NERDTree
"Save the cursor position whenever we close the nerd tree "Save the cursor position whenever we close the nerd tree
exec "autocmd BufWinLeave ". g:NERDTreeCreator.BufNamePrefix() ."* call nerdtree#saveScreenState()" exec "autocmd BufLeave ". g:NERDTreeCreator.BufNamePrefix() ."* call b:NERDTree.ui.saveScreenState()"
"disallow insert mode in the NERDTree "disallow insert mode in the NERDTree
exec "autocmd BufEnter ". g:NERDTreeCreator.BufNamePrefix() ."* stopinsert" exec "autocmd BufEnter ". g:NERDTreeCreator.BufNamePrefix() ."* stopinsert"
@ -201,7 +194,7 @@ endfunction
function! NERDTreeCWD() function! NERDTreeCWD()
call NERDTreeFocus() call NERDTreeFocus()
call nerdtree#chRootCwd() call nerdtree#ui_glue#chRootCwd()
endfunction endfunction
" SECTION: Post Source Actions {{{1 " SECTION: Post Source Actions {{{1
call nerdtree#postSourceActions() call nerdtree#postSourceActions()

View file

@ -1,8 +1,6 @@
let s:tree_up_dir_line = '.. (up a dir)' let s:tree_up_dir_line = '.. (up a dir)'
"NERDTreeFlags are syntax items that should be invisible, but give clues as to syn match NERDTreeIgnore #\~#
"how things should be highlighted syn match NERDTreeIgnore #\[RO\]#
syn match NERDTreeFlag #\~#
syn match NERDTreeFlag #\[RO\]#
"highlighting for the .. (up dir) line at the top of the tree "highlighting for the .. (up dir) line at the top of the tree
execute "syn match NERDTreeUp #\\V". s:tree_up_dir_line ."#" execute "syn match NERDTreeUp #\\V". s:tree_up_dir_line ."#"
@ -14,7 +12,7 @@ syn match NERDTreeHelpTitle #" .*\~#ms=s+2,me=e-1
syn match NERDTreeToggleOn #(on)#ms=s+1,he=e-1 syn match NERDTreeToggleOn #(on)#ms=s+1,he=e-1
syn match NERDTreeToggleOff #(off)#ms=e-3,me=e-1 syn match NERDTreeToggleOff #(off)#ms=e-3,me=e-1
syn match NERDTreeHelpCommand #" :.\{-}\>#hs=s+3 syn match NERDTreeHelpCommand #" :.\{-}\>#hs=s+3
syn match NERDTreeHelp #^".*# contains=NERDTreeHelpKey,NERDTreeHelpTitle,NERDTreeFlag,NERDTreeToggleOff,NERDTreeToggleOn,NERDTreeHelpCommand syn match NERDTreeHelp #^".*# contains=NERDTreeHelpKey,NERDTreeHelpTitle,NERDTreeIgnore,NERDTreeToggleOff,NERDTreeToggleOn,NERDTreeHelpCommand
"highlighting for sym links "highlighting for sym links
syn match NERDTreeLinkTarget #->.*# containedin=NERDTreeDir,NERDTreeFile syn match NERDTreeLinkTarget #->.*# containedin=NERDTreeDir,NERDTreeFile
@ -33,7 +31,10 @@ if g:NERDTreeDirArrows
syn match NERDTreeFile #^[^"\.▾▸] *[^▾▸]*# contains=NERDTreeLink,NERDTreeRO,NERDTreeBookmark,NERDTreeExecFile syn match NERDTreeFile #^[^"\.▾▸] *[^▾▸]*# contains=NERDTreeLink,NERDTreeRO,NERDTreeBookmark,NERDTreeExecFile
"highlighting for readonly files "highlighting for readonly files
syn match NERDTreeRO # *\zs.*\ze \[RO\]# contains=NERDTreeFlag,NERDTreeBookmark,NERDTreeFile syn match NERDTreeRO # *\zs.*\ze \[RO\]# contains=NERDTreeIgnore,NERDTreeBookmark,NERDTreeFile
syn match NERDTreeFlags #^ *\zs\[.\]# containedin=NERDTreeFile
syn match NERDTreeFlags #\[.\]# containedin=NERDTreeDir
else else
"highlighting for the ~/+ symbols for the directory nodes "highlighting for the ~/+ symbols for the directory nodes
syn match NERDTreeClosable #\~\<# syn match NERDTreeClosable #\~\<#
@ -52,7 +53,10 @@ else
syn match NERDTreeFile #`-.*# contains=NERDTreeLink,NERDTreePart,NERDTreePartFile,NERDTreeBookmark,NERDTreeExecFile syn match NERDTreeFile #`-.*# contains=NERDTreeLink,NERDTreePart,NERDTreePartFile,NERDTreeBookmark,NERDTreeExecFile
"highlighting for readonly files "highlighting for readonly files
syn match NERDTreeRO #|-.*\[RO\]#he=e-5 contains=NERDTreeFlag,NERDTreeBookmark,NERDTreePart,NERDTreePartFile syn match NERDTreeRO #|-.*\[RO\]#he=e-5 contains=NERDTreeIgnore,NERDTreeBookmark,NERDTreePart,NERDTreePartFile
syn match NERDTreeFlags #-\[.\]# containedin=NERDTreeFile,NERDTreePartFile
syn match NERDTreeFlags #[+~]\zs\[.\]# containedin=NERDTreeDir
endif endif
syn match NERDTreeCWD #^[</].*$# syn match NERDTreeCWD #^[</].*$#
@ -93,8 +97,9 @@ hi def link NERDTreeFile Normal
hi def link NERDTreeCWD Statement hi def link NERDTreeCWD Statement
hi def link NERDTreeOpenable Title hi def link NERDTreeOpenable Title
hi def link NERDTreeClosable Title hi def link NERDTreeClosable Title
hi def link NERDTreeFlag ignore hi def link NERDTreeIgnore ignore
hi def link NERDTreeRO WarningMsg hi def link NERDTreeRO WarningMsg
hi def link NERDTreeBookmark Statement hi def link NERDTreeBookmark Statement
hi def link NERDTreeFlags Number
hi def link NERDTreeCurrentNode Search hi def link NERDTreeCurrentNode Search

View file

@ -35,16 +35,16 @@ the user is notified and is happy because they didn't have to compile their
code or execute their script to find them. code or execute their script to find them.
At the time of this writing, syntax checking plugins exist for ActionScript, At the time of this writing, syntax checking plugins exist for ActionScript,
Ada, AppleScript, AsciiDoc, ASM, BEMHTML, Bro, Bourne shell, C, C++, C#, Cabal, Ada, AppleScript, Arduino, AsciiDoc, ASM, BEMHTML, Bro, Bourne shell, C,
Chef, CoffeeScript, Coco, Coq, CSS, Cucumber, CUDA, D, Dart, DocBook, Dust, C++, C#, Cabal, Chef, CoffeeScript, Coco, Coq, CSS, Cucumber, CUDA, D, Dart,
Elixir, Erlang, eRuby, Fortran, Gentoo metadata, GLSL, Go, Haml, Haskell, Haxe, DocBook, Dust, Elixir, Erlang, eRuby, Fortran, Gentoo metadata, GLSL, Go,
Handlebars, HSS, HTML, Java, JavaScript, JSON, JSX, LESS, Lex, Limbo, LISP, Haml, Haskell, Haxe, Handlebars, HSS, HTML, Java, JavaScript, JSON, JSX, LESS,
LLVM intermediate language, Lua, MATLAB, NASM, Objective-C, Objective-C++, Lex, Limbo, LISP, LLVM intermediate language, Lua, MATLAB, NASM, Objective-C,
OCaml, Perl, Perl POD, PHP, gettext Portable Object, OS X and iOS property Objective-C++, OCaml, Perl, Perl POD, PHP, gettext Portable Object, OS X
lists, Puppet, Python, Racket, R, reStructuredText, Ruby, SASS/SCSS, Scala, and iOS property lists, Puppet, Python, Racket, R, reStructuredText, Ruby,
Slim, Tcl, TeX, Texinfo, Twig, TypeScript, Vala, Verilog, VHDL, VimL, xHtml, SASS/SCSS, Scala, Slim, Tcl, TeX, Texinfo, Twig, TypeScript, Vala, Verilog,
XML, XSLT, YACC, YAML, z80, Zope page templates, and zsh. See the [wiki][3] VHDL, VimL, xHtml, XML, XSLT, YACC, YAML, z80, Zope page templates, and zsh.
for details about the corresponding supported checkers. See the [wiki][3] for details about the corresponding supported checkers.
Below is a screenshot showing the methods that Syntastic uses to display syntax Below is a screenshot showing the methods that Syntastic uses to display syntax
errors. Note that, in practise, you will only have a subset of these methods errors. Note that, in practise, you will only have a subset of these methods
@ -137,7 +137,8 @@ statements in your file (cf. [perlrun][10]). This is probably fine if you
wrote the file yourself, but it's a security problem if you're checking third wrote the file yourself, but it's a security problem if you're checking third
party files. Since there is currently no way to disable this behaviour while party files. Since there is currently no way to disable this behaviour while
still producing useful results, the checker is now disabled by default. To still producing useful results, the checker is now disabled by default. To
(re-)enable it, set `g:syntastic_enable_perl_checker` to 1 in your vimrc: (re-)enable it, make sure the `g:syntastic_perl_checkers` list includes `perl`,
and set `g:syntastic_enable_perl_checker` to 1 in your vimrc:
```vim ```vim
let g:syntastic_enable_perl_checker = 1 let g:syntastic_enable_perl_checker = 1
``` ```

View file

@ -154,17 +154,10 @@ function! s:logRedirect(on) " {{{2
endif endif
endfunction " }}}2 endfunction " }}}2
function! s:logTimestamp_smart() " {{{2 function! s:logTimestamp() " {{{2
return 'syntastic: ' . split(reltimestr(reltime(g:syntastic_start)))[0] . ': ' return 'syntastic: ' . split(reltimestr(reltime(g:syntastic_start)))[0] . ': '
endfunction " }}}2 endfunction " }}}2
function! s:logTimestamp_dumb() " {{{2
return 'syntastic: debug: '
endfunction " }}}2
let s:logTimestamp = function(has('reltime') ? 's:logTimestamp_smart' : 's:logTimestamp_dumb')
lockvar s:logTimestamp
function! s:formatVariable(name) " {{{2 function! s:formatVariable(name) " {{{2
let vals = [] let vals = []
if exists('g:syntastic_' . a:name) if exists('g:syntastic_' . a:name)

View file

@ -37,10 +37,10 @@ endfunction " }}}2
function! syntastic#util#parseShebang() " {{{2 function! syntastic#util#parseShebang() " {{{2
for lnum in range(1, 5) for lnum in range(1, 5)
let line = getline(lnum) let line = getline(lnum)
if line =~ '^#!' if line =~ '^#!'
let exe = matchstr(line, '\m^#!\s*\zs[^ \t]*') let line = substitute(line, '\v^#!\s*(\S+/env(\s+-\S+)*\s+)?', '', '')
let args = split(matchstr(line, '\m^#!\s*[^ \t]*\zs.*')) let exe = matchstr(line, '\m^\S*\ze')
let args = split(matchstr(line, '\m^\S*\zs.*'))
return { 'exe': exe, 'args': args } return { 'exe': exe, 'args': args }
endif endif
endfor endfor
@ -58,7 +58,7 @@ endfunction " }}}2
" Parse a version string. Return an array of version components. " Parse a version string. Return an array of version components.
function! syntastic#util#parseVersion(version) " {{{2 function! syntastic#util#parseVersion(version) " {{{2
return split(matchstr( a:version, '\v^\D*\zs\d+(\.\d+)+\ze' ), '\m\.') return map(split(matchstr( a:version, '\v^\D*\zs\d+(\.\d+)+\ze' ), '\m\.'), 'str2nr(v:val)')
endfunction " }}}2 endfunction " }}}2
" Run 'command' in a shell and parse output as a version string. " Run 'command' in a shell and parse output as a version string.
@ -74,15 +74,21 @@ endfunction " }}}2
" "
" See http://semver.org for info about version numbers. " See http://semver.org for info about version numbers.
function! syntastic#util#versionIsAtLeast(installed, required) " {{{2 function! syntastic#util#versionIsAtLeast(installed, required) " {{{2
for idx in range(max([len(a:installed), len(a:required)])) return syntastic#util#compareLexi(a:installed, a:required) >= 0
let installed_element = get(a:installed, idx, 0) endfunction " }}}2
let required_element = get(a:required, idx, 0)
if installed_element != required_element " Almost lexicographic comparison of two lists of integers. :) If lists
return installed_element > required_element " have different lengths, the "missing" elements are assumed to be 0.
function! syntastic#util#compareLexi(a, b) " {{{2
for idx in range(max([len(a:a), len(a:b)]))
let a_element = str2nr(get(a:a, idx, 0))
let b_element = str2nr(get(a:b, idx, 0))
if a_element != b_element
return a_element > b_element ? 1 : -1
endif endif
endfor endfor
" Everything matched, so it is at least the required version. " Everything matched, so it is at least the required version.
return 1 return 0
endfunction " }}}2 endfunction " }}}2
" strwidth() was added in Vim 7.3; if it doesn't exist, we use strlen() " strwidth() was added in Vim 7.3; if it doesn't exist, we use strlen()
@ -226,6 +232,13 @@ function! syntastic#util#sortLoclist(errors) " {{{2
call sort(a:errors, 's:compareErrorItems') call sort(a:errors, 's:compareErrorItems')
endfunction " }}}2 endfunction " }}}2
" Return a [high, low] list of integers, representing the time
" (hopefully high resolution) since program start
" TODO: This assumes reltime() returns a list of integers.
function! syntastic#util#stamp() " {{{2
return reltime(g:syntastic_start)
endfunction " }}}2
" }}}1 " }}}1
" Private functions {{{1 " Private functions {{{1

View file

@ -36,12 +36,14 @@ CONTENTS *syntastic-contents*
5.3.Configuring specific checkers..........|syntastic-config-makeprg| 5.3.Configuring specific checkers..........|syntastic-config-makeprg|
6.Notes........................................|syntastic-notes| 6.Notes........................................|syntastic-notes|
6.1.Handling of composite filetypes........|syntastic-composite| 6.1.Handling of composite filetypes........|syntastic-composite|
6.2.Interaction with python-mode...........|syntastic-pymode| 6.2.Editing files over network.............|syntastic-netrw|
6.3.Interaction with the fish shell........|syntastic-fish| 6.3.Interaction with python-mode...........|syntastic-pymode|
6.4.Interaction with PowerShell............|syntastic-powershell| 6.4.Interaction with YouCompleteMe.........|syntastic-ycm|
6.5.Using syntastic with the fizsh shell...|syntastic-fizsh| 6.5.Interaction with the fish shell........|syntastic-fish|
6.6.Interaction with Eclim.................|syntastic-eclim| 6.6.Interaction with PowerShell............|syntastic-powershell|
6.7.Interaction with vim-virtualenv........|syntastic-vim-virtualenv| 6.7.Using syntastic with the fizsh shell...|syntastic-fizsh|
6.8.Interaction with Eclim.................|syntastic-eclim|
6.9.Interaction with vim-virtualenv........|syntastic-vim-virtualenv|
7.About........................................|syntastic-about| 7.About........................................|syntastic-about|
8.License......................................|syntastic-license| 8.License......................................|syntastic-license|
@ -321,8 +323,8 @@ error symbols can be customized:
syntastic_style_warning_symbol - For style warnings, defaults to 'S>' syntastic_style_warning_symbol - For style warnings, defaults to 'S>'
Example: > Example: >
let g:syntastic_error_symbol = '✗' let g:syntastic_error_symbol = "✗"
let g:syntastic_warning_symbol = '⚠' let g:syntastic_warning_symbol = "⚠"
< <
*'syntastic_enable_balloons'* *'syntastic_enable_balloons'*
Default: 1 Default: 1
@ -394,12 +396,12 @@ Default: {}
Use this option to map non-standard filetypes to standard ones. Corresponding Use this option to map non-standard filetypes to standard ones. Corresponding
checkers are mapped accordingly, which allows syntastic to check files with checkers are mapped accordingly, which allows syntastic to check files with
non-standard filetypes: > non-standard filetypes: >
let g:syntastic_filetype_map = { 'latex': 'tex', let g:syntastic_filetype_map = { "latex": "tex",
\ 'gentoo-metadata': 'xml' } \ "gentoo-metadata": "xml" }
< <
Composite filetypes can also be mapped to simple types, which disables the Composite filetypes can also be mapped to simple types, which disables the
default behaviour of running both checkers against the input file: > default behaviour of running both checkers against the input file: >
let g:syntastic_filetype_map = { 'handlebars.html': 'handlebars' } let g:syntastic_filetype_map = { "handlebars.html": "handlebars" }
< <
*'syntastic_mode_map'* *'syntastic_mode_map'*
Default: { "mode": "active", Default: { "mode": "active",
@ -411,26 +413,26 @@ done).
The option should be set to something like: > The option should be set to something like: >
let g:syntastic_mode_map = { 'mode': 'active', let g:syntastic_mode_map = { "mode": "active",
\ 'active_filetypes': ['ruby', 'php'], \ "active_filetypes": ["ruby", "php"],
\ 'passive_filetypes': ['puppet'] } \ "passive_filetypes": ["puppet"] }
< <
"mode" can be mapped to one of two values - "active" or "passive". When set to "mode" can be mapped to one of two values - "active" or "passive". When set
active, syntastic does automatic checking whenever a buffer is saved or to "active", syntastic does automatic checking whenever a buffer is saved or
initially opened. When set to "passive" syntastic only checks when the user initially opened. When set to "passive" syntastic only checks when the user
calls |:SyntasticCheck|. calls |:SyntasticCheck|.
The exceptions to these rules are defined with "active_filetypes" and The exceptions to these rules are defined with "active_filetypes" and
"passive_filetypes". In passive mode, automatic checks are still done "passive_filetypes". In passive mode, automatic checks are still done for
for all filetypes in the "active_filetypes" array. In active mode, filetypes in the "active_filetypes" array (and "passive_filetypes" is
automatic checks are not done for any filetypes in the ignored). In active mode, automatic checks are not done for any filetypes in
"passive_filetypes" array. the "passive_filetypes" array ("active_filetypes" is ignored).
If any of "mode", "active_filetypes", or "passive_filetypes" are left
unspecified, they default to values above.
At runtime, the |:SyntasticToggleMode| command can be used to switch between At runtime, the |:SyntasticToggleMode| command can be used to switch between
active and passive mode. active and passive modes.
If any of "mode", "active_filetypes", or "passive_filetypes" are not specified
then they will default to their default value as above.
*'syntastic_quiet_messages'* *'syntastic_quiet_messages'*
Default: {} Default: {}
@ -471,7 +473,7 @@ Since filter elements with values [] or '' are ignored, you can disable global
filters for particular checkers, by setting the values of the corresponding filters for particular checkers, by setting the values of the corresponding
elements in |'syntastic_<filetype>_<checker>_quiet_messages'| to [] or ''. For elements in |'syntastic_<filetype>_<checker>_quiet_messages'| to [] or ''. For
example, the following setting will silence all warnings, except for the example, the following setting will silence all warnings, except for the
ones produced by 'pylint': > ones produced by "pylint": >
let g:syntastic_quiet_messages = { "level": "warnings" } let g:syntastic_quiet_messages = { "level": "warnings" }
let g:syntastic_python_pylint_quiet_messages = { "level" : [] } let g:syntastic_python_pylint_quiet_messages = { "level" : [] }
< <
@ -540,7 +542,7 @@ List of filetypes handled by checkers external to syntastic. If you have a Vim
plugin that adds a checker for syntastic, and if the said checker deals with a plugin that adds a checker for syntastic, and if the said checker deals with a
filetype that is unknown to syntastic, you might consider adding that filetype filetype that is unknown to syntastic, you might consider adding that filetype
to this list: > to this list: >
let g:syntastic_extra_filetypes = [ 'make', 'gitcommit' ] let g:syntastic_extra_filetypes = [ "make", "gitcommit" ]
< <
This will allow |:SyntasticInfo| to do proper tab completion for the new This will allow |:SyntasticInfo| to do proper tab completion for the new
filetypes. filetypes.
@ -554,14 +556,14 @@ filetypes.
*'g:syntastic_<filetype>_checkers'* *'g:syntastic_<filetype>_checkers'*
You can tell syntastic which checkers to run for a given filetype by setting a You can tell syntastic which checkers to run for a given filetype by setting a
variable 'g:syntastic_<filetype>_checkers' to a list of checkers, e.g. > variable 'g:syntastic_<filetype>_checkers' to a list of checkers, e.g. >
let g:syntastic_php_checkers = ['php', 'phpcs', 'phpmd'] let g:syntastic_php_checkers = ["php", "phpcs", "phpmd"]
< <
*'b:syntastic_checkers'* *'b:syntastic_checkers'*
There is also a per-buffer version of this setting, 'b:syntastic_checkers'. There is also a per-buffer version of this setting, 'b:syntastic_checkers'.
When set, it takes precedence over |'g:syntastic_<filetype>_checkers'|. You can When set, it takes precedence over |'g:syntastic_<filetype>_checkers'|. You can
use this in an autocmd to configure specific checkers for particular paths: > use this in an autocmd to configure specific checkers for particular paths: >
autocmd FileType python if stridx(expand('%:p'), '/some/path/') == 0 | autocmd FileType python if stridx(expand("%:p"), "/some/path/") == 0 |
\ let b:syntastic_checkers = ['pylint'] | endif \ let b:syntastic_checkers = ["pylint"] | endif
< <
If neither |'g:syntastic_<filetype>_checkers'| nor |'b:syntastic_checkers'| If neither |'g:syntastic_<filetype>_checkers'| nor |'b:syntastic_checkers'|
is set, a default list of checker is used. Beware however that this list is set, a default list of checker is used. Beware however that this list
@ -592,21 +594,27 @@ default - in fact you can customise every part of the command that gets called.
*'syntastic_<filetype>_<checker>_<option>'* *'syntastic_<filetype>_<checker>_<option>'*
Checkers that use 'makeprgBuild()' construct a 'makeprg' like this: > Checkers that use 'makeprgBuild()' construct a 'makeprg' like this: >
let makeprg = self.makeprgBuild({ let makeprg = self.makeprgBuild({
\ 'exe': self.getExec(), \ "exe": self.getExec(),
\ 'args': '-a -b -c', \ "args": "-a -b -c",
\ 'post_args': '--more --args', \ "post_args": "--more --args",
\ 'tail': '> /tmp/output' }) \ "tail": "2>/dev/null" })
< <
The result is a 'makeprg' of the form: > The result is a 'makeprg' of the form: >
<exe> <args> <fname> <post_args> <tail> <exe> <args> <fname> <post_args> <tail>
< <
*'syntastic_<filetype>_<checker>_exe'*
All arguments above are optional, and can be overridden by setting global All arguments above are optional, and can be overridden by setting global
variables 'g:syntastic_<filetype>_<checker-name>_<option-name>' - even variables 'g:syntastic_<filetype>_<checker-name>_<option-name>' - even
parameters not specified in the call to makeprgBuild(). These variables also parameters not specified in the call to makeprgBuild(). These variables also
have local versions 'b:syntastic_<filetype>_<checker-name>_<option-name>', have local versions 'b:syntastic_<filetype>_<checker-name>_<option-name>',
which take precedence over the global ones in the corresponding buffers. which take precedence over the global ones in the corresponding buffers.
If one of these variables has a non-empty default and you want it to be empty,
you can set it to a space, e.g.: >
let g:syntastic_javascript_jslint_args = " "
<
(setting it to an empty string doesn't work, for implementation reasons).
*'syntastic_<filetype>_<checker>_exe'*
The 'exe' is normally the same as the 'exec' attribute described above, in The 'exe' is normally the same as the 'exec' attribute described above, in
which case it may be omitted. However, you can use it to add environment which case it may be omitted. However, you can use it to add environment
variables or additional parameters, e.g. to tell the mri checker to use KANJI variables or additional parameters, e.g. to tell the mri checker to use KANJI
@ -641,37 +649,56 @@ See |syntastic_quiet_messages| for the syntax.
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
6.1. Handling of composite filetypes *syntastic-composite* 6.1. Handling of composite filetypes *syntastic-composite*
Some Vim plugins use composite filetypes, such as 'django.python' or Some Vim plugins use composite filetypes, such as "django.python" or
'handlebars.html'. Normally, syntastic deals with this situation by splitting "handlebars.html". Normally, syntastic deals with this situation by splitting
the filetype in its simple components, and calling all checkers that apply. the filetype in its simple components, and calling all checkers that apply.
If this behaviour is not desirable, you can disable it by mapping the If this behaviour is not desirable, you can disable it by mapping the
composite filetypes to a simple ones using |syntastic_filetype_map|, e.g.: > composite filetypes to a simple ones using |syntastic_filetype_map|, e.g.: >
let g:syntastic_filetype_map = { 'handlebars.html': 'handlebars' } let g:syntastic_filetype_map = { "handlebars.html": "handlebars" }
< <
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
6.2 Interaction with python-mode *syntastic-pymode* 6.2 Editing files over network *syntastic-netrw*
The standard plugin |netrw| allows Vim to transparently edit files over
network and inside archives. Currently syntastic doesn't support this mode
of operation. It can only check files that can be accessed directly by local
checkers, without any translation or conversion.
------------------------------------------------------------------------------
6.3 Interaction with python-mode *syntastic-pymode*
Syntastic can be used along with the 'python-mode' Vim plugin (see Syntastic can be used along with the 'python-mode' Vim plugin (see
https://github.com/klen/python-mode). However, they both run syntax checks by https://github.com/klen/python-mode). However, they both run syntax checks by
default when you save buffers to disk, and this is probably not what you want. default when you save buffers to disk, and this is probably not what you want.
To avoid both plugins opening error windows, you can either set passive mode To avoid both plugins opening error windows, you can either set passive mode
for python in syntastic (see |syntastic_mode_map|), or disable lint checks in for python in syntastic (see |syntastic_mode_map|), or disable lint checks in
python-mode, by setting |pymode_lint_write| to 0. E.g.: > 'python-mode', by setting |pymode_lint_write| to 0. E.g.: >
let g:pymode_lint_write = 0 let g:pymode_lint_write = 0
< <
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
6.3 Interaction with the fish shell *syntastic-fish* 6.4 Interaction with YouCompleteMe *syntastic-ycm*
Syntastic can be used together with the 'YouCompleteMe' Vim plugin (see
http://valloric.github.io/YouCompleteMe/). However, by default 'YouCompleteMe'
disables syntastic"s checkers for the "c", "cpp", "objc", and "objcpp"
filetypes, in order to allow its own checkers to run. If you want to use YCM's
identifier completer but still run syntastic's checkers for those filetypes you
have to set |ycm_show_diagnostics_ui| to 0. E.g.: >
let g:ycm_show_diagnostics_ui = 0
<
------------------------------------------------------------------------------
6.5 Interaction with the fish shell *syntastic-fish*
At the time of this writing the 'fish' shell (see http://fishshell.com/) At the time of this writing the 'fish' shell (see http://fishshell.com/)
doesn't support the standard UNIX syntax for file redirections, and thus it doesn't support the standard UNIX syntax for file redirections, and thus it
can't be used together with syntastic. You don't need to change your login can't be used together with syntastic. You don't need to change your login
shell to address this problem, but you do have to point Vim's 'shell' to a more shell to address this problem, but you do have to point Vim's 'shell' to a more
traditional shell, such as 'zsh', 'bash', 'ksh', or even the original Bourne traditional shell, such as "zsh", "bash", "ksh", or even the original Bourne
'sh': > "sh": >
set shell=bash set shell=bash
< <
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
6.4. Interaction with PowerShell *syntastic-powershell* 6.6. Interaction with PowerShell *syntastic-powershell*
At the time of this writing, syntastic is not compatible with using 'Windows At the time of this writing, syntastic is not compatible with using 'Windows
PowerShell' (http://technet.microsoft.com/en-us/library/bb978526.aspx) as Vim's PowerShell' (http://technet.microsoft.com/en-us/library/bb978526.aspx) as Vim's
@ -680,7 +707,7 @@ Vim's 'shell' to a more traditional program, such as 'cmd.exe': >
set shell=cmd.exe set shell=cmd.exe
< <
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
6.5. Using syntastic with the fizsh shell *syntastic-fizsh* 6.7. Using syntastic with the fizsh shell *syntastic-fizsh*
Using syntastic with the 'fizsh' shell (see https://github.com/zsh-users/fizsh) Using syntastic with the 'fizsh' shell (see https://github.com/zsh-users/fizsh)
is possible, but potentially problematic. In order to do it you'll need to set is possible, but potentially problematic. In order to do it you'll need to set
@ -688,12 +715,12 @@ is possible, but potentially problematic. In order to do it you'll need to set
set shellredir=>%s\ 2>&1 set shellredir=>%s\ 2>&1
< <
Please keep in mind however that Vim can't take advantage of any of the Please keep in mind however that Vim can't take advantage of any of the
interactive features of 'fizsh'. Using a more traditional shell such as 'zsh', interactive features of 'fizsh'. Using a more traditional shell such as "zsh",
'bash', 'ksh', or the original Bourne 'sh' might be a better choice: > "bash", "ksh", or the original Bourne "sh" might be a better choice: >
set shell=zsh set shell=zsh
< <
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
6.6. Interaction with Eclim *syntastic-eclim* 6.8. Interaction with Eclim *syntastic-eclim*
As far as syntastic is concerned there shouldn't be any compatibility problems As far as syntastic is concerned there shouldn't be any compatibility problems
with the 'Eclim' Vim plugin (see http://eclim.org/). However, at the time of with the 'Eclim' Vim plugin (see http://eclim.org/). However, at the time of
@ -702,7 +729,7 @@ makes syntastic forget some of its configuration parameters. No solutions or
workarounds are known for now. workarounds are known for now.
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
6.7. Interaction with vim-virtualenv *syntastic-vim-virtualenv* 6.9. Interaction with vim-virtualenv *syntastic-vim-virtualenv*
At the time of this writing, syntastic can't run checkers installed At the time of this writing, syntastic can't run checkers installed
in Python virtual environments activated by 'vim-virtualenv' (see in Python virtual environments activated by 'vim-virtualenv' (see

View file

@ -19,12 +19,12 @@ if has('reltime')
lockvar! g:syntastic_start lockvar! g:syntastic_start
endif endif
let g:syntastic_version = '3.4.0-90' let g:syntastic_version = '3.4.0-117'
lockvar g:syntastic_version lockvar g:syntastic_version
" Sanity checks {{{1 " Sanity checks {{{1
for s:feature in ['autocmd', 'eval', 'modify_fname', 'quickfix', 'user_commands'] for s:feature in ['autocmd', 'eval', 'modify_fname', 'quickfix', 'reltime', 'user_commands']
if !has(s:feature) if !has(s:feature)
call syntastic#log#error("need Vim compiled with feature " . s:feature) call syntastic#log#error("need Vim compiled with feature " . s:feature)
finish finish
@ -65,10 +65,11 @@ let g:syntastic_defaults = {
\ 'filetype_map': {}, \ 'filetype_map': {},
\ 'full_redraws': !(has('gui_running') || has('gui_macvim')), \ 'full_redraws': !(has('gui_running') || has('gui_macvim')),
\ 'id_checkers': 1, \ 'id_checkers': 1,
\ 'ignore_extensions': '\c\v^([gx]?z|lzma|bz2)$',
\ 'ignore_files': [], \ 'ignore_files': [],
\ 'loc_list_height': 10, \ 'loc_list_height': 10,
\ 'quiet_messages': {}, \ 'quiet_messages': {},
\ 'reuse_loc_lists': (v:version >= 704), \ 'reuse_loc_lists': 0,
\ 'sort_aggregated_errors': 1, \ 'sort_aggregated_errors': 1,
\ 'stl_format': '[Syntax: line:%F (%t)]', \ 'stl_format': '[Syntax: line:%F (%t)]',
\ 'style_error_symbol': 'S>', \ 'style_error_symbol': 'S>',
@ -167,7 +168,7 @@ command! -nargs=* -complete=custom,s:CompleteCheckerName SyntasticCheck
\ call syntastic#util#redraw(g:syntastic_full_redraws) \ call syntastic#util#redraw(g:syntastic_full_redraws)
command! Errors call s:ShowLocList() command! Errors call s:ShowLocList()
command! -nargs=? -complete=custom,s:CompleteFiletypes SyntasticInfo command! -nargs=? -complete=custom,s:CompleteFiletypes SyntasticInfo
\ call s:modemap.echoMode() | \ call s:modemap.modeInfo(<f-args>) |
\ call s:registry.echoInfoFor(s:resolveFiletypes(<f-args>)) \ call s:registry.echoInfoFor(s:resolveFiletypes(<f-args>))
command! SyntasticReset command! SyntasticReset
\ call s:ClearCache() | \ call s:ClearCache() |
@ -237,6 +238,11 @@ endfunction " }}}2
"refresh and redraw all the error info for this buf when saving or reading "refresh and redraw all the error info for this buf when saving or reading
function! s:UpdateErrors(auto_invoked, ...) " {{{2 function! s:UpdateErrors(auto_invoked, ...) " {{{2
call syntastic#log#debugShowVariables(g:SyntasticDebugTrace, 'version')
call syntastic#log#debugShowOptions(g:SyntasticDebugTrace, s:debug_dump_options)
call syntastic#log#debugDump(g:SyntasticDebugVariables)
call syntastic#log#debug(g:SyntasticDebugTrace, 'UpdateErrors' . (a:auto_invoked ? ' (auto)' : '') .
\ ': ' . (a:0 ? join(a:000) : 'default checkers'))
if s:skipFile() if s:skipFile()
return return
endif endif
@ -288,14 +294,13 @@ endfunction " }}}2
"detect and cache all syntax errors in this buffer "detect and cache all syntax errors in this buffer
function! s:CacheErrors(checker_names) " {{{2 function! s:CacheErrors(checker_names) " {{{2
call syntastic#log#debug(g:SyntasticDebugTrace, 'CacheErrors: ' .
\ (len(a:checker_names) ? join(a:checker_names) : 'default checkers'))
call s:ClearCache() call s:ClearCache()
let newLoclist = g:SyntasticLoclist.New([]) let newLoclist = g:SyntasticLoclist.New([])
if !s:skipFile() if !s:skipFile()
" debug logging {{{3 " debug logging {{{3
call syntastic#log#debugShowVariables(g:SyntasticDebugTrace, 'version')
call syntastic#log#debugShowOptions(g:SyntasticDebugTrace, s:debug_dump_options)
call syntastic#log#debugDump(g:SyntasticDebugVariables)
call syntastic#log#debugShowVariables(g:SyntasticDebugTrace, 'aggregate_errors') call syntastic#log#debugShowVariables(g:SyntasticDebugTrace, 'aggregate_errors')
call syntastic#log#debug(g:SyntasticDebugTrace, 'getcwd() = ' . getcwd()) call syntastic#log#debug(g:SyntasticDebugTrace, 'getcwd() = ' . getcwd())
" }}}3 " }}}3
@ -376,7 +381,6 @@ function! s:CacheErrors(checker_names) " {{{2
endif endif
endif endif
call newLoclist.setOwner(bufnr(''))
call newLoclist.deploy() call newLoclist.deploy()
endfunction " }}}2 endfunction " }}}2
@ -408,7 +412,9 @@ endfunction " }}}2
" 'preprocess' - a function to be applied to the error file before parsing errors " 'preprocess' - a function to be applied to the error file before parsing errors
" 'postprocess' - a list of functions to be applied to the error list " 'postprocess' - a list of functions to be applied to the error list
" 'cwd' - change directory to the given path before running the checker " 'cwd' - change directory to the given path before running the checker
" 'env' - environment variables to set before running the checker
" 'returns' - a list of valid exit codes for the checker " 'returns' - a list of valid exit codes for the checker
" @vimlint(EVL102, 1, l:env_save)
function! SyntasticMake(options) " {{{2 function! SyntasticMake(options) " {{{2
call syntastic#log#debug(g:SyntasticDebugTrace, 'SyntasticMake: called with options:', a:options) call syntastic#log#debug(g:SyntasticDebugTrace, 'SyntasticMake: called with options:', a:options)
@ -432,11 +438,31 @@ function! SyntasticMake(options) " {{{2
execute 'lcd ' . fnameescape(a:options['cwd']) execute 'lcd ' . fnameescape(a:options['cwd'])
endif endif
" set environment variables {{{3
let env_save = {}
if has_key(a:options, 'env') && len(a:options['env'])
for key in keys(a:options['env'])
if key =~? '\m^[a-z_]\+$'
exec 'let env_save[' . string(key) . '] = $' . key
exec 'let $' . key . ' = ' . string(a:options['env'][key])
endif
endfor
endif
let $LC_MESSAGES = 'C' let $LC_MESSAGES = 'C'
let $LC_ALL = '' let $LC_ALL = ''
" }}}3
let err_lines = split(system(a:options['makeprg']), "\n", 1) let err_lines = split(system(a:options['makeprg']), "\n", 1)
" restore environment variables {{{3
let $LC_ALL = old_lc_all let $LC_ALL = old_lc_all
let $LC_MESSAGES = old_lc_messages let $LC_MESSAGES = old_lc_messages
if len(env_save)
for key in keys(env_save)
exec 'let $' . key . ' = ' . string(env_save[key])
endfor
endif
" }}}3
call syntastic#log#debug(g:SyntasticDebugLoclist, 'checker output:', err_lines) call syntastic#log#debug(g:SyntasticDebugLoclist, 'checker output:', err_lines)
@ -497,6 +523,7 @@ function! SyntasticMake(options) " {{{2
return errors return errors
endfunction " }}}2 endfunction " }}}2
" @vimlint(EVL102, 0, l:env_save)
"return a string representing the state of buffer according to "return a string representing the state of buffer according to
"g:syntastic_stl_format "g:syntastic_stl_format
@ -527,9 +554,14 @@ endfunction " }}}2
" Skip running in special buffers " Skip running in special buffers
function! s:skipFile() " {{{2 function! s:skipFile() " {{{2
let force_skip = exists('b:syntastic_skip_checks') ? b:syntastic_skip_checks : 0
let fname = expand('%') let fname = expand('%')
return force_skip || (&buftype != '') || !filereadable(fname) || getwinvar(0, '&diff') || s:ignoreFile(fname) let skip = (exists('b:syntastic_skip_checks') ? b:syntastic_skip_checks : 0) ||
\ (&buftype != '') || !filereadable(fname) || getwinvar(0, '&diff') ||
\ s:ignoreFile(fname) || fnamemodify(fname, ':e') =~? g:syntastic_ignore_extensions
if skip
call syntastic#log#debug(g:SyntasticDebugTrace, 'skipFile: skipping')
endif
return skip
endfunction " }}}2 endfunction " }}}2
" Take a list of errors and add default values to them from a:options " Take a list of errors and add default values to them from a:options

View file

@ -43,6 +43,7 @@ endfunction " }}}2
" Reset the error balloons " Reset the error balloons
" @vimlint(EVL103, 1, a:loclist) " @vimlint(EVL103, 1, a:loclist)
function! g:SyntasticBalloonsNotifier.reset(loclist) " {{{2 function! g:SyntasticBalloonsNotifier.reset(loclist) " {{{2
let b:syntastic_balloons = {}
if has('balloon_eval') if has('balloon_eval')
call syntastic#log#debug(g:SyntasticDebugNotifications, 'balloons: reset') call syntastic#log#debug(g:SyntasticDebugNotifications, 'balloons: reset')
set nobeval set nobeval

View file

@ -32,8 +32,8 @@ endfunction " }}}2
" Sets error highlights in the cuirrent window " Sets error highlights in the cuirrent window
function! g:SyntasticHighlightingNotifier.refresh(loclist) " {{{2 function! g:SyntasticHighlightingNotifier.refresh(loclist) " {{{2
if self.enabled() if self.enabled()
call self.reset(a:loclist)
call syntastic#log#debug(g:SyntasticDebugNotifications, 'highlighting: refresh') call syntastic#log#debug(g:SyntasticDebugNotifications, 'highlighting: refresh')
call self._reset()
let buf = bufnr('') let buf = bufnr('')
let issues = filter(a:loclist.copyRaw(), 'v:val["bufnr"] == buf') let issues = filter(a:loclist.copyRaw(), 'v:val["bufnr"] == buf')
for item in issues for item in issues
@ -64,11 +64,7 @@ endfunction " }}}2
function! g:SyntasticHighlightingNotifier.reset(loclist) " {{{2 function! g:SyntasticHighlightingNotifier.reset(loclist) " {{{2
if s:has_highlighting if s:has_highlighting
call syntastic#log#debug(g:SyntasticDebugNotifications, 'highlighting: reset') call syntastic#log#debug(g:SyntasticDebugNotifications, 'highlighting: reset')
for match in getmatches() call self._reset()
if stridx(match['group'], 'Syntastic') == 0
call matchdelete(match['id'])
endif
endfor
endif endif
endfunction " }}}2 endfunction " }}}2
" @vimlint(EVL103, 0, a:loclist) " @vimlint(EVL103, 0, a:loclist)
@ -95,6 +91,14 @@ function! g:SyntasticHighlightingNotifier._setup() " {{{2
endif endif
endfunction " }}}2 endfunction " }}}2
function! g:SyntasticHighlightingNotifier._reset() " {{{2
for match in getmatches()
if stridx(match['group'], 'Syntastic') == 0
call matchdelete(match['id'])
endif
endfor
endfunction " }}}2
" }}}1 " }}}1
" vim: set sw=4 sts=4 et fdm=marker: " vim: set sw=4 sts=4 et fdm=marker:

View file

@ -46,6 +46,14 @@ function! g:SyntasticLoclist.isEmpty() " {{{2
return empty(self._rawLoclist) return empty(self._rawLoclist)
endfunction " }}}2 endfunction " }}}2
function! g:SyntasticLoclist.isNewerThan(stamp) " {{{2
if !exists("self._stamp")
let self._stamp = []
return 0
endif
return syntastic#util#compareLexi(self._stamp, a:stamp) > 0
endfunction " }}}2
function! g:SyntasticLoclist.copyRaw() " {{{2 function! g:SyntasticLoclist.copyRaw() " {{{2
return copy(self._rawLoclist) return copy(self._rawLoclist)
endfunction " }}}2 endfunction " }}}2
@ -132,6 +140,8 @@ function! g:SyntasticLoclist.setOwner(buffer) " {{{2
endfunction " }}}2 endfunction " }}}2
function! g:SyntasticLoclist.deploy() " {{{2 function! g:SyntasticLoclist.deploy() " {{{2
call self.setOwner(bufnr(''))
let self._stamp = syntastic#util#stamp()
for buf in self.getBuffers() for buf in self.getBuffers()
call setbufvar(buf, 'syntastic_loclist', self) call setbufvar(buf, 'syntastic_loclist', self)
endfor endfor

View file

@ -19,8 +19,8 @@ endfunction " }}}2
function! g:SyntasticModeMap.synch() " {{{2 function! g:SyntasticModeMap.synch() " {{{2
if exists('g:syntastic_mode_map') if exists('g:syntastic_mode_map')
let self._mode = get(g:syntastic_mode_map, 'mode', 'active') let self._mode = get(g:syntastic_mode_map, 'mode', 'active')
let self._activeFiletypes = get(g:syntastic_mode_map, 'active_filetypes', []) let self._activeFiletypes = copy(get(g:syntastic_mode_map, 'active_filetypes', []))
let self._passiveFiletypes = get(g:syntastic_mode_map, 'passive_filetypes', []) let self._passiveFiletypes = copy(get(g:syntastic_mode_map, 'passive_filetypes', []))
else else
let self._mode = 'active' let self._mode = 'active'
let self._activeFiletypes = [] let self._activeFiletypes = []
@ -62,6 +62,27 @@ function! g:SyntasticModeMap.echoMode() " {{{2
echo "Syntastic: " . self._mode . " mode enabled" echo "Syntastic: " . self._mode . " mode enabled"
endfunction " }}}2 endfunction " }}}2
function! g:SyntasticModeMap.modeInfo(...) " {{{2
echomsg 'Syntastic version: ' . g:syntastic_version
let type = a:0 ? a:1 : &filetype
echomsg 'Info for filetype: ' . type
call self.synch()
echomsg 'Mode: ' . self._mode
if self._mode ==# 'active'
if len(self._passiveFiletypes)
let plural = len(self._passiveFiletypes) != 1 ? 's' : ''
echomsg 'Passive filetype' . plural . ': ' . join(sort(copy(self._passiveFiletypes)))
endif
else
if len(self._activeFiletypes)
let plural = len(self._activeFiletypes) != 1 ? 's' : ''
echomsg 'Active filetype' . plural . ': ' . join(sort(copy(self._activeFiletypes)))
endif
endif
echomsg 'Filetype ' . type . ' is ' . (self.allowsAutoChecking(type) ? 'active' : 'passive')
endfunction " }}}2
" }}}1 " }}}1
" Private methods {{{1 " Private methods {{{1

View file

@ -8,6 +8,9 @@ let g:SyntasticNotifiers = {}
let s:notifier_types = ['signs', 'balloons', 'highlighting', 'cursor', 'autoloclist'] let s:notifier_types = ['signs', 'balloons', 'highlighting', 'cursor', 'autoloclist']
lockvar! s:notifier_types lockvar! s:notifier_types
let s:persistent_notifiers = ['signs', 'balloons']
lockvar! s:persistent_notifiers
" Public methods {{{1 " Public methods {{{1
function! g:SyntasticNotifiers.Instance() " {{{2 function! g:SyntasticNotifiers.Instance() " {{{2
@ -20,11 +23,27 @@ function! g:SyntasticNotifiers.Instance() " {{{2
endfunction " }}}2 endfunction " }}}2
function! g:SyntasticNotifiers.refresh(loclist) " {{{2 function! g:SyntasticNotifiers.refresh(loclist) " {{{2
if !a:loclist.isEmpty() && !a:loclist.isNewerThan([])
" loclist not fully constructed yet
return
endif
call syntastic#log#debug(g:SyntasticDebugNotifications, 'notifiers: refresh') call syntastic#log#debug(g:SyntasticDebugNotifications, 'notifiers: refresh')
for type in self._enabled_types for type in self._enabled_types
let class = substitute(type, '\m.*', 'Syntastic\u&Notifier', '') let class = substitute(type, '\m.*', 'Syntastic\u&Notifier', '')
if !has_key(g:{class}, 'enabled') || self._notifier[type].enabled() if !has_key(g:{class}, 'enabled') || self._notifier[type].enabled()
if index(s:persistent_notifiers, type) > -1
" refresh only if loclist has changed since last call
if !exists('b:syntastic_' . type . '_stamp')
let b:syntastic_{type}_stamp = []
endif
if a:loclist.isNewerThan(b:syntastic_{type}_stamp) || a:loclist.isEmpty()
call self._notifier[type].refresh(a:loclist) call self._notifier[type].refresh(a:loclist)
let b:syntastic_{type}_stamp = syntastic#util#stamp()
endif
else
call self._notifier[type].refresh(a:loclist)
endif
endif endif
endfor endfor
endfunction " }}}2 endfunction " }}}2
@ -40,6 +59,11 @@ function! g:SyntasticNotifiers.reset(loclist) " {{{2
if has_key(g:{class}, 'reset') if has_key(g:{class}, 'reset')
call self._notifier[type].reset(a:loclist) call self._notifier[type].reset(a:loclist)
endif endif
" also reset stamps
if index(s:persistent_notifiers, type) > -1
let b:syntastic_{type}_stamp = []
endif
endfor endfor
endfunction " }}}2 endfunction " }}}2

View file

@ -9,6 +9,7 @@ let s:defaultCheckers = {
\ 'actionscript':['mxmlc'], \ 'actionscript':['mxmlc'],
\ 'ada': ['gcc'], \ 'ada': ['gcc'],
\ 'applescript': ['osacompile'], \ 'applescript': ['osacompile'],
\ 'arduino': ['avrgcc'],
\ 'asciidoc': ['asciidoc'], \ 'asciidoc': ['asciidoc'],
\ 'asm': ['gcc'], \ 'asm': ['gcc'],
\ 'bro': ['bro'], \ 'bro': ['bro'],
@ -29,7 +30,7 @@ let s:defaultCheckers = {
\ 'dart': ['dartanalyzer'], \ 'dart': ['dartanalyzer'],
\ 'docbk': ['xmllint'], \ 'docbk': ['xmllint'],
\ 'dustjs': ['swiffer'], \ 'dustjs': ['swiffer'],
\ 'elixir': ['elixir'], \ 'elixir': [],
\ 'erlang': ['escript'], \ 'erlang': ['escript'],
\ 'eruby': ['ruby'], \ 'eruby': ['ruby'],
\ 'fortran': ['gfortran'], \ 'fortran': ['gfortran'],
@ -178,9 +179,6 @@ function! g:SyntasticRegistry.getNamesOfAvailableCheckers(ftalias) " {{{2
endfunction " }}}2 endfunction " }}}2
function! g:SyntasticRegistry.echoInfoFor(ftalias_list) " {{{2 function! g:SyntasticRegistry.echoInfoFor(ftalias_list) " {{{2
echomsg "Syntastic version: " . g:syntastic_version
echomsg "Info for filetype: " . join(a:ftalias_list, '.')
let ft_list = syntastic#util#unique(map( copy(a:ftalias_list), 's:normaliseFiletype(v:val)' )) let ft_list = syntastic#util#unique(map( copy(a:ftalias_list), 's:normaliseFiletype(v:val)' ))
if len(ft_list) != 1 if len(ft_list) != 1
let available = [] let available = []
@ -196,8 +194,15 @@ function! g:SyntasticRegistry.echoInfoFor(ftalias_list) " {{{2
let active = map(self.getCheckersAvailable(ft, []), 'v:val.getName()') let active = map(self.getCheckersAvailable(ft, []), 'v:val.getName()')
endif endif
echomsg "Available checker(s): " . join(sort(available)) let cnt = len(available)
echomsg "Currently enabled checker(s): " . join(active) let plural = cnt != 1 ? 's' : ''
let cklist = cnt ? join(sort(available)) : '-'
echomsg 'Available checker' . plural . ': ' . cklist
let cnt = len(active)
let plural = cnt != 1 ? 's' : ''
let cklist = cnt ? join(active) : '-'
echomsg 'Currently enabled checker' . plural . ': ' . cklist
endfunction " }}}2 endfunction " }}}2
" }}}1 " }}}1

View file

@ -42,7 +42,6 @@ function! g:SyntasticSignsNotifier.refresh(loclist) " {{{2
call self._signErrors(a:loclist) call self._signErrors(a:loclist)
endif endif
call self._removeSigns(old_signs) call self._removeSigns(old_signs)
let s:first_sign_id = exists('s:next_sign_id') ? s:next_sign_id : 5000
endfunction " }}}2 endfunction " }}}2
" }}}1 " }}}1
@ -88,18 +87,22 @@ function! g:SyntasticSignsNotifier._signErrors(loclist) " {{{2
let loclist = a:loclist let loclist = a:loclist
if !loclist.isEmpty() if !loclist.isEmpty()
" errors some first, so that they are not masked by warnings
let buf = bufnr('') let buf = bufnr('')
if !bufloaded(buf)
" signs can be placed only in loaded buffers
return
endif
" errors come first, so that they are not masked by warnings
let issues = copy(loclist.errors()) let issues = copy(loclist.errors())
call extend(issues, loclist.warnings()) call extend(issues, loclist.warnings())
call filter(issues, 'v:val["bufnr"] == buf') call filter(issues, 'v:val["bufnr"] == buf')
let seen = {} let seen = {}
for i in issues for i in issues
if !has_key(seen, i['lnum']) if i['lnum'] > 0 && !has_key(seen, i['lnum'])
let seen[i['lnum']] = 1 let seen[i['lnum']] = 1
if i['lnum'] > 0
let sign_severity = i['type'] ==? 'W' ? 'Warning' : 'Error' let sign_severity = i['type'] ==? 'W' ? 'Warning' : 'Error'
let sign_subtype = get(i, 'subtype', '') let sign_subtype = get(i, 'subtype', '')
let sign_type = 'Syntastic' . sign_subtype . sign_severity let sign_type = 'Syntastic' . sign_subtype . sign_severity
@ -108,7 +111,6 @@ function! g:SyntasticSignsNotifier._signErrors(loclist) " {{{2
call add(self._bufSignIds(), s:next_sign_id) call add(self._bufSignIds(), s:next_sign_id)
let s:next_sign_id += 1 let s:next_sign_id += 1
endif endif
endif
endfor endfor
endif endif
endfunction " }}}2 endfunction " }}}2

View file

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

View file

@ -53,3 +53,5 @@ call g:SyntasticRegistry.CreateAndRegisterChecker({
let &cpo = s:save_cpo let &cpo = s:save_cpo
unlet s:save_cpo unlet s:save_cpo
" vim: set et sts=4 sw=4:

View file

@ -24,6 +24,11 @@ function! SyntaxCheckers_elixir_elixir_IsAvailable() dict
endfunction endfunction
function! SyntaxCheckers_elixir_elixir_GetLocList() dict function! SyntaxCheckers_elixir_elixir_GetLocList() dict
if !exists('g:syntastic_enable_elixir_checker') || !g:syntastic_enable_elixir_checker
call syntastic#log#error('checker elixir/elixir: checks disabled for security reasons; ' .
\ 'set g:syntastic_enable_elixir_checker to 1 to override')
return []
endif
let make_options = {} let make_options = {}
let compile_command = 'elixir' let compile_command = 'elixir'

View file

@ -30,7 +30,7 @@ function! SyntaxCheckers_erlang_escript_GetLocList() dict
endif endif
let shebang = syntastic#util#parseShebang() let shebang = syntastic#util#parseShebang()
if shebang['exe'] =~# '\m\<escript$' || (shebang['exe'] ==# '/usr/bin/env' && shebang['args'][0] ==# 'escript') if shebang['exe'] ==# 'escript'
let args = '-s' let args = '-s'
let post_args = '' let post_args = ''
else else

View file

@ -38,3 +38,5 @@ call g:SyntasticRegistry.CreateAndRegisterChecker({
let &cpo = s:save_cpo let &cpo = s:save_cpo
unlet s:save_cpo unlet s:save_cpo
" vim: set et sts=4 sw=4:

View file

@ -22,24 +22,14 @@ function! SyntaxCheckers_eruby_ruby_IsAvailable() dict
if !exists('g:syntastic_eruby_ruby_exec') && exists('g:syntastic_ruby_exec') if !exists('g:syntastic_eruby_ruby_exec') && exists('g:syntastic_ruby_exec')
let g:syntastic_eruby_ruby_exec = g:syntastic_ruby_exec let g:syntastic_eruby_ruby_exec = g:syntastic_ruby_exec
endif endif
let s:exe = self.getExec() return executable(self.getExec())
if executable(s:exe)
let s:exe = syntastic#util#shescape(s:exe)
if !syntastic#util#isRunningWindows()
let s:exe = 'RUBYOPT= ' . s:exe
endif
return 1
endif
return 0
endfunction endfunction
function! SyntaxCheckers_eruby_ruby_GetLocList() dict function! SyntaxCheckers_eruby_ruby_GetLocList() dict
let fname = "'" . escape(expand('%'), "\\'") . "'" let fname = "'" . escape(expand('%'), "\\'") . "'"
" TODO: encodings became useful in ruby 1.9 :) " TODO: encodings became useful in ruby 1.9 :)
if syntastic#util#versionIsAtLeast(syntastic#util#getVersion(s:exe . ' --version'), [1, 9]) if syntastic#util#versionIsAtLeast(syntastic#util#getVersion(self.getExecEscaped(). ' --version'), [1, 9])
let enc = &fileencoding != '' ? &fileencoding : &encoding let enc = &fileencoding != '' ? &fileencoding : &encoding
let encoding_spec = ', :encoding => "' . (enc ==? 'utf-8' ? 'UTF-8' : 'BINARY') . '"' let encoding_spec = ', :encoding => "' . (enc ==? 'utf-8' ? 'UTF-8' : 'BINARY') . '"'
else else
@ -48,11 +38,11 @@ function! SyntaxCheckers_eruby_ruby_GetLocList() dict
"gsub fixes issue #7, rails has it's own eruby syntax "gsub fixes issue #7, rails has it's own eruby syntax
let makeprg = let makeprg =
\ s:exe . ' -rerb -e ' . \ self.getExecEscaped() . ' -rerb -e ' .
\ syntastic#util#shescape('puts ERB.new(File.read(' . \ syntastic#util#shescape('puts ERB.new(File.read(' .
\ fname . encoding_spec . \ fname . encoding_spec .
\ ').gsub(''<%='',''<%''), nil, ''-'').src') . \ ').gsub(''<%='',''<%''), nil, ''-'').src') .
\ ' | ' . s:exe . ' -c' \ ' | ' . self.getExecEscaped() . ' -c'
let errorformat = let errorformat =
\ '%-GSyntax OK,'. \ '%-GSyntax OK,'.
@ -61,9 +51,12 @@ function! SyntaxCheckers_eruby_ruby_GetLocList() dict
\ '%Z%p^,'. \ '%Z%p^,'.
\ '%-C%.%#' \ '%-C%.%#'
let env = syntastic#util#isRunningWindows() ? {} : { 'RUBYOPT': '' }
return SyntasticMake({ return SyntasticMake({
\ 'makeprg': makeprg, \ 'makeprg': makeprg,
\ 'errorformat': errorformat, \ 'errorformat': errorformat,
\ 'env': env,
\ 'defaults': { 'bufnr': bufnr(""), 'vcol': 1 } }) \ 'defaults': { 'bufnr': bufnr(""), 'vcol': 1 } })
endfunction endfunction

View file

@ -31,6 +31,8 @@ function! SyntaxCheckers_html_jshint_GetLocList() dict
let errorformat = '%A%f: line %l\, col %v\, %m \(%t%*\d\)' let errorformat = '%A%f: line %l\, col %v\, %m \(%t%*\d\)'
call self.setWantSort(1)
return SyntasticMake({ return SyntasticMake({
\ 'makeprg': makeprg, \ 'makeprg': makeprg,
\ 'errorformat': errorformat, \ 'errorformat': errorformat,

View file

@ -186,9 +186,7 @@ function! s:Args()
endfunction endfunction
function! SyntaxCheckers_html_tidy_GetLocList() dict function! SyntaxCheckers_html_tidy_GetLocList() dict
let makeprg = self.makeprgBuild({ let makeprg = self.makeprgBuild({ 'args_after': s:Args() })
\ 'args_after': s:Args(),
\ 'tail': '2>&1' })
let errorformat = let errorformat =
\ '%Wline %l column %v - Warning: %m,' . \ '%Wline %l column %v - Warning: %m,' .

View file

@ -399,8 +399,7 @@ function! SyntaxCheckers_java_javac_GetLocList() dict
let makeprg = self.makeprgBuild({ let makeprg = self.makeprgBuild({
\ 'args': javac_opts, \ 'args': javac_opts,
\ 'fname': syntastic#util#shescape(fname), \ 'fname': syntastic#util#shescape(fname) })
\ 'tail': '2>&1' })
" unashamedly stolen from *errorformat-javac* (quickfix.txt) and modified to include error types " unashamedly stolen from *errorformat-javac* (quickfix.txt) and modified to include error types
let errorformat = let errorformat =

View file

@ -40,6 +40,8 @@ function! SyntaxCheckers_javascript_jshint_GetLocList() dict
\ '%A%f: line %l\, col %v\, %m \(%t%*\d\)' : \ '%A%f: line %l\, col %v\, %m \(%t%*\d\)' :
\ '%E%f: line %l\, col %v\, %m' \ '%E%f: line %l\, col %v\, %m'
call self.setWantSort(1)
return SyntasticMake({ return SyntasticMake({
\ 'makeprg': makeprg, \ 'makeprg': makeprg,
\ 'errorformat': errorformat, \ 'errorformat': errorformat,

View file

@ -19,8 +19,7 @@ function! SyntaxCheckers_python_flake8_GetHighlightRegex(item)
endfunction endfunction
function! SyntaxCheckers_python_flake8_GetLocList() dict function! SyntaxCheckers_python_flake8_GetLocList() dict
let makeprg = self.makeprgBuild({ let makeprg = self.makeprgBuild({})
\ 'exe_before': (syntastic#util#isRunningWindows() ? '' : 'TERM=dumb') })
let errorformat = let errorformat =
\ '%E%f:%l: could not compile,%-Z%p^,' . \ '%E%f:%l: could not compile,%-Z%p^,' .
@ -28,9 +27,12 @@ function! SyntaxCheckers_python_flake8_GetLocList() dict
\ '%A%f:%l: %t%n %m,' . \ '%A%f:%l: %t%n %m,' .
\ '%-G%.%#' \ '%-G%.%#'
let env = syntastic#util#isRunningWindows() ? {} : { 'TERM': 'dumb' }
let loclist = SyntasticMake({ let loclist = SyntasticMake({
\ 'makeprg': makeprg, \ 'makeprg': makeprg,
\ 'errorformat': errorformat }) \ 'errorformat': errorformat,
\ 'env': env })
for e in loclist for e in loclist
" E*** and W*** are pep8 errors " E*** and W*** are pep8 errors

View file

@ -19,9 +19,7 @@ let s:save_cpo = &cpo
set cpo&vim set cpo&vim
function! SyntaxCheckers_python_frosted_GetLocList() dict function! SyntaxCheckers_python_frosted_GetLocList() dict
let makeprg = self.makeprgBuild({ let makeprg = self.makeprgBuild({ 'args_after': '-vb' })
\ 'exe_before': (syntastic#util#isRunningWindows() ? '' : 'TERM=dumb'),
\ 'args_after': '-vb' })
let errorformat = let errorformat =
\ '%f:%l:%c:%m,' . \ '%f:%l:%c:%m,' .
@ -29,9 +27,12 @@ function! SyntaxCheckers_python_frosted_GetLocList() dict
\ '%-Z%p^,' . \ '%-Z%p^,' .
\ '%-G%.%#' \ '%-G%.%#'
let env = syntastic#util#isRunningWindows() ? {} : { 'TERM': 'dumb' }
let loclist = SyntasticMake({ let loclist = SyntasticMake({
\ 'makeprg': makeprg, \ 'makeprg': makeprg,
\ 'errorformat': errorformat, \ 'errorformat': errorformat,
\ 'env': env,
\ 'returns': [0, 1] }) \ 'returns': [0, 1] })
for e in loclist for e in loclist

View file

@ -19,8 +19,7 @@ function! SyntaxCheckers_python_pep257_GetLocList() dict
\ self.getExecEscaped() . ' --version'), [0, 3]) \ self.getExecEscaped() . ' --version'), [0, 3])
endif endif
let makeprg = self.makeprgBuild({ let makeprg = self.makeprgBuild({})
\ 'exe_before': (syntastic#util#isRunningWindows() ? '' : 'TERM=dumb') })
if s:pep257_new if s:pep257_new
let errorformat = let errorformat =
@ -33,9 +32,12 @@ function! SyntaxCheckers_python_pep257_GetLocList() dict
\ '%+C %m' \ '%+C %m'
endif endif
let env = syntastic#util#isRunningWindows() ? {} : { 'TERM': 'dumb' }
let loclist = SyntasticMake({ let loclist = SyntasticMake({
\ 'makeprg': makeprg, \ 'makeprg': makeprg,
\ 'errorformat': errorformat, \ 'errorformat': errorformat,
\ 'env': env,
\ 'subtype': 'Style', \ 'subtype': 'Style',
\ 'preprocess': 'killEmpty', \ 'preprocess': 'killEmpty',
\ 'postprocess': ['compressWhitespace'] }) \ 'postprocess': ['compressWhitespace'] })

View file

@ -21,14 +21,16 @@ let s:save_cpo = &cpo
set cpo&vim set cpo&vim
function! SyntaxCheckers_python_pep8_GetLocList() dict function! SyntaxCheckers_python_pep8_GetLocList() dict
let makeprg = self.makeprgBuild({ let makeprg = self.makeprgBuild({})
\ 'exe_before': (syntastic#util#isRunningWindows() ? '' : 'TERM=dumb') })
let errorformat = '%f:%l:%c: %m' let errorformat = '%f:%l:%c: %m'
let env = syntastic#util#isRunningWindows() ? {} : { 'TERM': 'dumb' }
let loclist = SyntasticMake({ let loclist = SyntasticMake({
\ 'makeprg': makeprg, \ 'makeprg': makeprg,
\ 'errorformat': errorformat, \ 'errorformat': errorformat,
\ 'env': env,
\ 'subtype': 'Style' }) \ 'subtype': 'Style' })
for e in loclist for e in loclist

View file

@ -14,14 +14,16 @@ let s:save_cpo = &cpo
set cpo&vim set cpo&vim
function! SyntaxCheckers_python_py3kwarn_GetLocList() dict function! SyntaxCheckers_python_py3kwarn_GetLocList() dict
let makeprg = self.makeprgBuild({ let makeprg = self.makeprgBuild({})
\ 'exe_before': (syntastic#util#isRunningWindows() ? '' : 'TERM=dumb') })
let errorformat = '%W%f:%l:%c: %m' let errorformat = '%W%f:%l:%c: %m'
let env = syntastic#util#isRunningWindows() ? {} : { 'TERM': 'dumb' }
return SyntasticMake({ return SyntasticMake({
\ 'makeprg': makeprg, \ 'makeprg': makeprg,
\ 'errorformat': errorformat }) \ 'errorformat': errorformat,
\ 'env': env })
endfunction endfunction
call g:SyntasticRegistry.CreateAndRegisterChecker({ call g:SyntasticRegistry.CreateAndRegisterChecker({

View file

@ -40,8 +40,7 @@ function! SyntaxCheckers_python_pyflakes_GetHighlightRegex(i)
endfunction endfunction
function! SyntaxCheckers_python_pyflakes_GetLocList() dict function! SyntaxCheckers_python_pyflakes_GetLocList() dict
let makeprg = self.makeprgBuild({ let makeprg = self.makeprgBuild({})
\ 'exe_before': (syntastic#util#isRunningWindows() ? '' : 'TERM=dumb') })
let errorformat = let errorformat =
\ '%E%f:%l: could not compile,'. \ '%E%f:%l: could not compile,'.
@ -50,9 +49,12 @@ function! SyntaxCheckers_python_pyflakes_GetLocList() dict
\ '%E%f:%l: %m,'. \ '%E%f:%l: %m,'.
\ '%-G%.%#' \ '%-G%.%#'
let env = syntastic#util#isRunningWindows() ? {} : { 'TERM': 'dumb' }
let loclist = SyntasticMake({ let loclist = SyntasticMake({
\ 'makeprg': makeprg, \ 'makeprg': makeprg,
\ 'errorformat': errorformat, \ 'errorformat': errorformat,
\ 'env': env,
\ 'defaults': {'text': "Syntax error"} }) \ 'defaults': {'text': "Syntax error"} })
for e in loclist for e in loclist

View file

@ -23,18 +23,19 @@ function! SyntaxCheckers_python_pylama_GetHighlightRegex(item)
endfunction endfunction
function! SyntaxCheckers_python_pylama_GetLocList() dict function! SyntaxCheckers_python_pylama_GetLocList() dict
let makeprg = self.makeprgBuild({ let makeprg = self.makeprgBuild({ 'args_after': '-f pep8' })
\ 'exe_before': (syntastic#util#isRunningWindows() ? '' : 'TERM=dumb'),
\ 'args_after': '-f pep8' })
" TODO: "WARNING:pylama:..." messages are probably a logging bug " TODO: "WARNING:pylama:..." messages are probably a logging bug
let errorformat = let errorformat =
\ '%-GWARNING:pylama:%.%#,' . \ '%-GWARNING:pylama:%.%#,' .
\ '%A%f:%l:%c: %m' \ '%A%f:%l:%c: %m'
let env = syntastic#util#isRunningWindows() ? {} : { 'TERM': 'dumb' }
let loclist = SyntasticMake({ let loclist = SyntasticMake({
\ 'makeprg': makeprg, \ 'makeprg': makeprg,
\ 'errorformat': errorformat }) \ 'errorformat': errorformat,
\ 'env': env })
" adjust for weirdness in each checker " adjust for weirdness in each checker
for e in loclist for e in loclist

View file

@ -23,7 +23,6 @@ endfunction
function! SyntaxCheckers_python_pylint_GetLocList() dict function! SyntaxCheckers_python_pylint_GetLocList() dict
let makeprg = self.makeprgBuild({ let makeprg = self.makeprgBuild({
\ 'exe_before': (syntastic#util#isRunningWindows() ? '' : 'TERM=dumb'),
\ 'args_after': (s:pylint_new ? '-f text --msg-template="{path}:{line}:{column}:{C}: [{symbol}] {msg}" -r n' : '-f parseable -r n -i y') }) \ 'args_after': (s:pylint_new ? '-f text --msg-template="{path}:{line}:{column}:{C}: [{symbol}] {msg}" -r n' : '-f parseable -r n -i y') })
let errorformat = let errorformat =
@ -33,9 +32,12 @@ function! SyntaxCheckers_python_pylint_GetLocList() dict
\ '%-Z%p^%.%#,' . \ '%-Z%p^%.%#,' .
\ '%-G%.%#' \ '%-G%.%#'
let env = syntastic#util#isRunningWindows() ? {} : { 'TERM': 'dumb' }
let loclist = SyntasticMake({ let loclist = SyntasticMake({
\ 'makeprg': makeprg, \ 'makeprg': makeprg,
\ 'errorformat': errorformat, \ 'errorformat': errorformat,
\ 'env': env,
\ 'returns': range(32) }) \ 'returns': range(32) })
for e in loclist for e in loclist

View file

@ -26,15 +26,16 @@ function! SyntaxCheckers_python_python_IsAvailable() dict
endfunction endfunction
function! SyntaxCheckers_python_python_GetLocList() dict function! SyntaxCheckers_python_python_GetLocList() dict
let makeprg = self.makeprgBuild({ let makeprg = self.makeprgBuild({ 'exe': [self.getExec(), s:compiler] })
\ 'exe_before': (syntastic#util#isRunningWindows() ? '' : 'TERM=dumb'),
\ 'exe': [self.getExec(), s:compiler] })
let errorformat = '%E%f:%l:%c: %m' let errorformat = '%E%f:%l:%c: %m'
let env = syntastic#util#isRunningWindows() ? {} : { 'TERM': 'dumb' }
return SyntasticMake({ return SyntasticMake({
\ 'makeprg': makeprg, \ 'makeprg': makeprg,
\ 'errorformat': errorformat, \ 'errorformat': errorformat,
\ 'env': env,
\ 'returns': [0] }) \ 'returns': [0] })
endfunction endfunction

View file

@ -20,7 +20,6 @@ set cpo&vim
function! SyntaxCheckers_ruby_jruby_GetLocList() dict function! SyntaxCheckers_ruby_jruby_GetLocList() dict
let makeprg = self.makeprgBuild({ let makeprg = self.makeprgBuild({
\ 'exe_before': (syntastic#util#isRunningWindows() ? '' : 'RUBYOPT='),
\ 'args': (syntastic#util#isRunningWindows() ? '-T1' : ''), \ 'args': (syntastic#util#isRunningWindows() ? '-T1' : ''),
\ 'args_after': '-W1 -c' }) \ 'args_after': '-W1 -c' })
@ -33,9 +32,12 @@ function! SyntaxCheckers_ruby_jruby_GetLocList() dict
\ '%W%f:%l: %m,'. \ '%W%f:%l: %m,'.
\ '%-C%.%#' \ '%-C%.%#'
let env = syntastic#util#isRunningWindows() ? {} : { 'RUBYOPT': '' }
return SyntasticMake({ return SyntasticMake({
\ 'makeprg': makeprg, \ 'makeprg': makeprg,
\ 'errorformat': errorformat }) \ 'errorformat': errorformat,
\ 'env': env })
endfunction endfunction
call g:SyntasticRegistry.CreateAndRegisterChecker({ call g:SyntasticRegistry.CreateAndRegisterChecker({

View file

@ -18,9 +18,7 @@ let s:save_cpo = &cpo
set cpo&vim set cpo&vim
function! SyntaxCheckers_ruby_macruby_GetLocList() dict function! SyntaxCheckers_ruby_macruby_GetLocList() dict
let makeprg = self.makeprgBuild({ let makeprg = self.makeprgBuild({ 'args_after': '-W1 -c' })
\ 'exe_before': 'RUBYOPT=',
\ 'args_after': '-W1 -c' })
let errorformat = let errorformat =
\ '%-GSyntax OK,'. \ '%-GSyntax OK,'.
@ -31,9 +29,12 @@ function! SyntaxCheckers_ruby_macruby_GetLocList() dict
\ '%W%f:%l: %m,'. \ '%W%f:%l: %m,'.
\ '%-C%.%#' \ '%-C%.%#'
let env = { 'RUBYOPT': '' }
return SyntasticMake({ return SyntasticMake({
\ 'makeprg': makeprg, \ 'makeprg': makeprg,
\ 'errorformat': errorformat }) \ 'errorformat': errorformat,
\ 'env': env })
endfunction endfunction
call g:SyntasticRegistry.CreateAndRegisterChecker({ call g:SyntasticRegistry.CreateAndRegisterChecker({

View file

@ -35,9 +35,7 @@ function! SyntaxCheckers_ruby_mri_GetHighlightRegex(i)
endfunction endfunction
function! SyntaxCheckers_ruby_mri_GetLocList() dict function! SyntaxCheckers_ruby_mri_GetLocList() dict
let makeprg = self.makeprgBuild({ let makeprg = self.makeprgBuild({ 'args_after': '-w -T1 -c' })
\ 'exe_before': (syntastic#util#isRunningWindows() ? '' : 'RUBYOPT='),
\ 'args_after': '-w -T1 -c' })
"this is a hack to filter out a repeated useless warning in rspec files "this is a hack to filter out a repeated useless warning in rspec files
"containing lines like "containing lines like
@ -62,9 +60,12 @@ function! SyntaxCheckers_ruby_mri_GetLocList() dict
\ '%W%f:%l: %m,'. \ '%W%f:%l: %m,'.
\ '%-C%.%#' \ '%-C%.%#'
let env = syntastic#util#isRunningWindows() ? {} : { 'RUBYOPT': '' }
return SyntasticMake({ return SyntasticMake({
\ 'makeprg': makeprg, \ 'makeprg': makeprg,
\ 'errorformat': errorformat }) \ 'errorformat': errorformat,
\ 'env': env })
endfunction endfunction
call g:SyntasticRegistry.CreateAndRegisterChecker({ call g:SyntasticRegistry.CreateAndRegisterChecker({

View file

@ -53,7 +53,7 @@ function! SyntaxCheckers_vim_vimlint_GetLocList() dict
" value 3: the message is a warning " value 3: the message is a warning
" "
" References: :help vimlint-errorcode and :help vimlint-variables " References: :help vimlint-errorcode and :help vimlint-variables
return vimlint#vimlint(expand('%'), { let param = {
\ 'output': function('s:vimlintOutput'), \ 'output': function('s:vimlintOutput'),
\ 'quiet': 1, \ 'quiet': 1,
\ 'EVL102': 3, \ 'EVL102': 3,
@ -63,7 +63,16 @@ function! SyntaxCheckers_vim_vimlint_GetLocList() dict
\ 'EVL106': 3, \ 'EVL106': 3,
\ 'EVL201': 3, \ 'EVL201': 3,
\ 'EVL204': 3, \ 'EVL204': 3,
\ 'EVL205': 3 }) \ 'EVL205': 3 }
if exists('g:syntastic_vimlint_options')
if type(g:syntastic_vimlint_options) == type({})
let options = filter(copy(g:syntastic_vimlint_options), 'v:key =~# "\\m^EVL"')
call extend(param, options, 'force')
endif
endif
return vimlint#vimlint(expand('%'), param)
endfunction endfunction
" @vimlint(EVL103, 1, a:filename) " @vimlint(EVL103, 1, a:filename)

View file

@ -1,15 +1,8 @@
" arg.vim
" @Author: Tom Link (micathom AT gmail com?subject=[vim]) " @Author: Tom Link (micathom AT gmail com?subject=[vim])
" @Website: http://www.vim.org/account/profile.php?user_id=4037 " @Website: http://www.vim.org/account/profile.php?user_id=4037
" @License: GPL (see http://www.gnu.org/licenses/gpl.txt) " @License: GPL (see http://www.gnu.org/licenses/gpl.txt)
" @Created: 2007-06-30. " @Last Change: 2014-07-01.
" @Last Change: 2009-02-15. " @Revision: 63
" @Revision: 0.0.50
if &cp || exists("loaded_tlib_arg_autoload")
finish
endif
let loaded_tlib_arg_autoload = 1
" :def: function! tlib#arg#Get(n, var, ?default="", ?test='') " :def: function! tlib#arg#Get(n, var, ?default="", ?test='')
@ -50,17 +43,19 @@ function! tlib#arg#Key(list, ...) "{{{3
endf endf
" :def: function! tlib#arg#StringAsKeyArgs(string, ?keys=[], ?evaluate=0) " :def: function! tlib#arg#StringAsKeyArgs(string, ?keys=[], ?evaluate=0, ?sep=':')
function! tlib#arg#StringAsKeyArgs(string, ...) "{{{1 function! tlib#arg#StringAsKeyArgs(string, ...) "{{{1
TVarArg ['keys', {}], ['evaluate', 0] TVarArg ['keys', {}], ['evaluate', 0], ['sep', ':']
let keyargs = {} let keyargs = {}
let args = split(a:string, '\\\@<! ') let args = split(a:string, '\\\@<! ')
let arglist = map(args, 'matchlist(v:val, ''^\(\w\+\):\(.*\)$'')') let arglist = map(args, 'matchlist(v:val, ''^\%(\(\w\+\)'. sep .'\(.*\)\|\(.*\)\)$'')')
" TLogVAR a:string, args, arglist " TLogVAR a:string, args, arglist
let pos = 0
for matchlist in arglist for matchlist in arglist
if len(matchlist) < 3 if !empty(matchlist[3])
throw 'Malformed key arguments: '. string(matchlist) .' in '. a:string let keyargs[pos] = matchlist[3]
endif let pos += 1
else
let [match, key, val; rest] = matchlist let [match, key, val; rest] = matchlist
if empty(keys) || has_key(keys, key) if empty(keys) || has_key(keys, key)
let val = substitute(val, '\\\\', '\\', 'g') let val = substitute(val, '\\\\', '\\', 'g')
@ -71,11 +66,17 @@ function! tlib#arg#StringAsKeyArgs(string, ...) "{{{1
else else
echom 'Unknown key: '. key .'='. val echom 'Unknown key: '. key .'='. val
endif endif
endif
endfor endfor
return keyargs return keyargs
endf endf
function! tlib#arg#StringAsKeyArgsEqual(string) "{{{1
return tlib#arg#StringAsKeyArgs(a:string, [], 0, '=')
endf
""" Command line {{{1 """ Command line {{{1

View file

@ -3,8 +3,8 @@
" @Website: http://www.vim.org/account/profile.php?user_id=4037 " @Website: http://www.vim.org/account/profile.php?user_id=4037
" @License: GPL (see http://www.gnu.org/licenses/gpl.txt) " @License: GPL (see http://www.gnu.org/licenses/gpl.txt)
" @Created: 2007-06-30. " @Created: 2007-06-30.
" @Last Change: 2013-09-25. " @Last Change: 2014-07-07.
" @Revision: 0.0.37 " @Revision: 0.0.38
if &cp || exists("loaded_tlib_dir_autoload") if &cp || exists("loaded_tlib_dir_autoload")
finish finish
@ -21,10 +21,11 @@ let s:dir_stack = []
" tlib#dir#CanonicName('foo/bar') " tlib#dir#CanonicName('foo/bar')
" => 'foo/bar/' " => 'foo/bar/'
function! tlib#dir#CanonicName(dirname) "{{{3 function! tlib#dir#CanonicName(dirname) "{{{3
if a:dirname !~ '[/\\]$' let dirname = tlib#file#Canonic(a:dirname)
return a:dirname . g:tlib#dir#sep if dirname !~ '[/\\]$'
return dirname . g:tlib#dir#sep
endif endif
return a:dirname return dirname
endf endf

View file

@ -3,8 +3,8 @@
" @Website: http://www.vim.org/account/profile.php?user_id=4037 " @Website: http://www.vim.org/account/profile.php?user_id=4037
" @License: GPL (see http://www.gnu.org/licenses/gpl.txt) " @License: GPL (see http://www.gnu.org/licenses/gpl.txt)
" @Created: 2007-06-30. " @Created: 2007-06-30.
" @Last Change: 2013-09-25. " @Last Change: 2014-07-07.
" @Revision: 0.0.142 " @Revision: 0.0.150
if &cp || exists("loaded_tlib_file_autoload") if &cp || exists("loaded_tlib_file_autoload")
finish finish
@ -103,6 +103,25 @@ function! tlib#file#Absolute(filename, ...) "{{{3
endf endf
function! tlib#file#Canonic(filename, ...) "{{{3
TVarArg ['mode', '']
if a:filename =~ '^\\\\'
let mode = 'windows'
elseif a:filename =~ '^\(file\|ftp\|http\)s\?:'
let mode = 'url'
elseif (empty(mode) && g:tlib#sys#windows)
let mode = 'windows'
endif
let filename = a:filename
if mode == 'windows'
let filename = substitute(filename, '/', '\\', 'g')
else
let filename = substitute(filename, '\\', '/', 'g')
endif
return filename
endf
function! s:SetScrollBind(world) "{{{3 function! s:SetScrollBind(world) "{{{3
let sb = get(a:world, 'scrollbind', &scrollbind) let sb = get(a:world, 'scrollbind', &scrollbind)
if sb != &scrollbind if sb != &scrollbind

View file

@ -4,7 +4,7 @@
" @License: GPL (see http://www.gnu.org/licenses/gpl.txt) " @License: GPL (see http://www.gnu.org/licenses/gpl.txt)
" @Created: 2007-06-30. " @Created: 2007-06-30.
" @Last Change: 2011-03-18. " @Last Change: 2011-03-18.
" @Revision: 53 " @Revision: 57
""" List related functions {{{1 """ List related functions {{{1
@ -166,3 +166,15 @@ function! tlib#list#Uniq(list, ...) "{{{3
return uniques return uniques
endf endf
function! tlib#list#ToDictionary(list, default, ...) "{{{3
TVarArg ['generator', '']
let dict = {}
for item in a:list
if !empty(item)
let dict[item] = empty(generator) ? a:default : call(generator, [item, a:default])
endif
endfor
return dict
endf

View file

@ -0,0 +1,127 @@
" @Author: Tom Link (mailto:micathom AT gmail com?subject=[vim])
" @License: GPL (see http://www.gnu.org/licenses/gpl.txt)
" @Last Change: 2014-06-30.
" @Revision: 25
if !exists('g:tlib#sys#windows')
let g:tlib#sys#windows = &shell !~ 'sh' && (has('win16') || has('win32') || has('win64')) "{{{2
endif
if !exists('g:tlib#sys#null')
let g:tlib#sys#null = g:tlib#sys#windows ? 'NUL' : (filereadable('/dev/null') ? '/dev/null' : '') "{{{2
endif
let s:executables = {}
function! tlib#sys#IsExecutable(cmd, ...) "{{{3
" TLogVAR a:cmd
" echom "DBG has_key(s:executables, a:cmd)" has_key(s:executables, a:cmd)
if !has_key(s:executables, a:cmd)
let executable = executable(a:cmd)
" TLogVAR 1, executable
let ignore_cyg = a:0 >= 1 ? a:1 : !g:tlib#sys#windows
if !executable && !ignore_cyg
let executable = tlib#sys#IsCygwinBin(a:cmd)
" TLogVAR 2, executable
endif
let s:executables[a:cmd] = executable
endif
" echom "DBG s:executables[a:cmd]" s:executables[a:cmd]
return s:executables[a:cmd]
endf
if !exists('g:tlib#sys#check_cygpath')
" If true, check whether we have to convert a path via cyppath --
" see |tlib#sys#MaybeUseCygpath|
let g:tlib#sys#check_cygpath = g:tlib#sys#windows && tlib#sys#IsExecutable('cygpath') "{{{2
endif
if !exists('g:tlib#sys#cygwin_path_rx')
" If a full windows filename (with slashes instead of backslashes)
" matches this |regexp|, it is assumed to be a cygwin executable.
let g:tlib#sys#cygwin_path_rx = '/cygwin/' "{{{2
endif
if !exists('g:tlib#sys#cygwin_expr')
" For cygwin binaries, convert command calls using this vim
" expression.
let g:tlib#sys#cygwin_expr = '"bash -c ''". escape(%s, "''\\") ."''"' "{{{2
endif
let s:cygwin = {}
function! tlib#sys#IsCygwinBin(cmd) "{{{3
" TLogVAR a:cmd
if !g:tlib#sys#windows
return 0
elseif has_key(s:cygwin, a:cmd)
let rv = s:cygwin[a:cmd]
else
if !tlib#sys#IsExecutable('cygpath', 1) || !tlib#sys#IsExecutable('which', 1)
let rv = 0
else
let which = substitute(system('which '. shellescape(a:cmd)), '\n$', '', '')
" echom "DBG which:" which
if which =~ '^/'
let filename = system('cygpath -ma '. shellescape(which))
" echom "DBG filename:" filename
let rv = filename =~ g:tlib#sys#cygwin_path_rx
else
let rv = 0
endif
endif
let s:cygwin[a:cmd] = rv
endif
" TLogVAR rv
return rv
endf
function! tlib#sys#GetCmd(cmd) "{{{3
if !empty(g:tlib#sys#cygwin_expr) && tlib#sys#IsCygwinBin(matchstr(a:cmd, '^\S\+'))
let cmd = eval(printf(g:tlib#sys#cygwin_expr, string(a:cmd)))
" TLogVAR cmd
return cmd
else
return a:cmd
endif
endf
" If cmd seems to be a cygwin executable, use cygpath to convert
" filenames. This assumes that cygwin's which command returns full
" filenames for non-cygwin executables.
function! tlib#sys#MaybeUseCygpath(cmd) "{{{3
" echom "DBG" a:cmd
if g:tlib#sys#check_cygpath && tlib#sys#IsCygwinBin(a:cmd)
return 'cygpath -u "%s"'
endif
return ''
endf
function! tlib#sys#ConvertPath(converter, filename) "{{{3
return tlib#string#Chomp(system(printf(a:converter, shellescape(a:filename))))
endf
let s:native_filenames = {}
function! tlib#sys#FileArgs(cmd, files) "{{{3
let cygpath = tlib#sys#MaybeUseCygpath(a:cmd)
" TLogVAR cygpath
if empty(cygpath)
return a:files
else
let files = map(copy(a:files), 'has_key(s:native_filenames, v:val) ? s:native_filenames[v:val] : tlib#sys#CygPath(v:val)')
return files
endif
endf

View file

@ -3,8 +3,8 @@
" @Website: http://www.vim.org/account/profile.php?user_id=4037 " @Website: http://www.vim.org/account/profile.php?user_id=4037
" @License: GPL (see http://www.gnu.org/licenses/gpl.txt) " @License: GPL (see http://www.gnu.org/licenses/gpl.txt)
" @Created: 2007-06-30. " @Created: 2007-06-30.
" @Last Change: 2009-02-15. " @Last Change: 2014-07-03.
" @Revision: 0.0.23 " @Revision: 0.0.26
if &cp || exists("loaded_tlib_var_autoload") if &cp || exists("loaded_tlib_var_autoload")
finish finish
@ -58,10 +58,12 @@ endf
" echo tlib#var#Get('foo', 'bg') => 2 " echo tlib#var#Get('foo', 'bg') => 2
" echo tlib#var#Get('foo', 'wbg') => 3 " echo tlib#var#Get('foo', 'wbg') => 3
function! tlib#var#Get(var, namespace, ...) "{{{3 function! tlib#var#Get(var, namespace, ...) "{{{3
let var_ = substitute(a:var, '#', '_', 'g')
for namespace in split(a:namespace, '\zs') for namespace in split(a:namespace, '\zs')
let var = namespace .':'. a:var let vname = namespace == 'g' ? a:var : var_
let var = namespace .':'. vname
if exists(var) if exists(var)
return eval(var) return {var}
endif endif
endfor endfor
return a:0 >= 1 ? a:1 : '' return a:0 >= 1 ? a:1 : ''

View file

@ -2,8 +2,8 @@
" @Author: Tom Link (mailto:micathom AT gmail com?subject=[vim]) " @Author: Tom Link (mailto:micathom AT gmail com?subject=[vim])
" @License: GPL (see http://www.gnu.org/licenses/gpl.txt) " @License: GPL (see http://www.gnu.org/licenses/gpl.txt)
" @Created: 2012-03-08. " @Created: 2012-03-08.
" @Last Change: 2012-09-10. " @Last Change: 2014-07-01.
" @Revision: 122 " @Revision: 131
" A dictionarie of supported VCS (currently: git, hg, svn, bzr). " A dictionarie of supported VCS (currently: git, hg, svn, bzr).
@ -49,16 +49,21 @@ if !empty(g:tlib#vcs#check)
let g:tlib#vcs#executables[s:cmd] = executable(s:cmd1) ? s:cmd1 : '' let g:tlib#vcs#executables[s:cmd] = executable(s:cmd1) ? s:cmd1 : ''
endif endif
endfor endfor
unlet! s:cmd s:def s:cmd1
endif endif
function! tlib#vcs#Executable(type) "{{{3
return get(g:tlib#vcs#executables, a:type, '')
endf
function! tlib#vcs#FindVCS(filename) "{{{3 function! tlib#vcs#FindVCS(filename) "{{{3
let type = '' let type = ''
let dir = '' let dir = ''
" let path = escape(fnamemodify(a:filename, ':p'), ',:') .';' let dirname = fnamemodify(a:filename, isdirectory(a:filename) ? ':p' : ':p:h')
let filename = fnamemodify(a:filename, isdirectory(a:filename) ? ':p:h' : ':p') let path = escape(dirname, ';') .';'
let path = escape(filename, ';') .';' " TLogVAR a:filename, dirname, path
" TLogVAR a:filename, path
let depth = -1 let depth = -1
for vcs in keys(g:tlib#vcs#def) for vcs in keys(g:tlib#vcs#def)
let subdir = g:tlib#vcs#def[vcs].dir let subdir = g:tlib#vcs#def[vcs].dir

View file

@ -77,6 +77,7 @@ Contents~
tlib#list#RemoveAll .................... |tlib#list#RemoveAll()| tlib#list#RemoveAll .................... |tlib#list#RemoveAll()|
tlib#list#Zip .......................... |tlib#list#Zip()| tlib#list#Zip .......................... |tlib#list#Zip()|
tlib#list#Uniq ......................... |tlib#list#Uniq()| tlib#list#Uniq ......................... |tlib#list#Uniq()|
tlib#list#ToDictionary ................. |tlib#list#ToDictionary()|
tlib#cmd#OutputAsList .................. |tlib#cmd#OutputAsList()| tlib#cmd#OutputAsList .................. |tlib#cmd#OutputAsList()|
tlib#cmd#BrowseOutput .................. |tlib#cmd#BrowseOutput()| tlib#cmd#BrowseOutput .................. |tlib#cmd#BrowseOutput()|
tlib#cmd#BrowseOutputWithCallback ...... |tlib#cmd#BrowseOutputWithCallback()| tlib#cmd#BrowseOutputWithCallback ...... |tlib#cmd#BrowseOutputWithCallback()|
@ -92,6 +93,7 @@ Contents~
g:tlib#vcs#def ......................... |g:tlib#vcs#def| g:tlib#vcs#def ......................... |g:tlib#vcs#def|
g:tlib#vcs#executables ................. |g:tlib#vcs#executables| g:tlib#vcs#executables ................. |g:tlib#vcs#executables|
g:tlib#vcs#check ....................... |g:tlib#vcs#check| g:tlib#vcs#check ....................... |g:tlib#vcs#check|
tlib#vcs#Executable .................... |tlib#vcs#Executable()|
tlib#vcs#FindVCS ....................... |tlib#vcs#FindVCS()| tlib#vcs#FindVCS ....................... |tlib#vcs#FindVCS()|
tlib#vcs#Ls ............................ |tlib#vcs#Ls()| tlib#vcs#Ls ............................ |tlib#vcs#Ls()|
tlib#vcs#Diff .......................... |tlib#vcs#Diff()| tlib#vcs#Diff .......................... |tlib#vcs#Diff()|
@ -239,7 +241,19 @@ Contents~
tlib#file#Join ......................... |tlib#file#Join()| tlib#file#Join ......................... |tlib#file#Join()|
tlib#file#Relative ..................... |tlib#file#Relative()| tlib#file#Relative ..................... |tlib#file#Relative()|
tlib#file#Absolute ..................... |tlib#file#Absolute()| tlib#file#Absolute ..................... |tlib#file#Absolute()|
tlib#file#Canonic ...................... |tlib#file#Canonic()|
tlib#file#With ......................... |tlib#file#With()| tlib#file#With ......................... |tlib#file#With()|
g:tlib#sys#windows ..................... |g:tlib#sys#windows|
g:tlib#sys#null ........................ |g:tlib#sys#null|
tlib#sys#IsExecutable .................. |tlib#sys#IsExecutable()|
g:tlib#sys#check_cygpath ............... |g:tlib#sys#check_cygpath|
g:tlib#sys#cygwin_path_rx .............. |g:tlib#sys#cygwin_path_rx|
g:tlib#sys#cygwin_expr ................. |g:tlib#sys#cygwin_expr|
tlib#sys#IsCygwinBin ................... |tlib#sys#IsCygwinBin()|
tlib#sys#GetCmd ........................ |tlib#sys#GetCmd()|
tlib#sys#MaybeUseCygpath ............... |tlib#sys#MaybeUseCygpath()|
tlib#sys#ConvertPath ................... |tlib#sys#ConvertPath()|
tlib#sys#FileArgs ...................... |tlib#sys#FileArgs()|
tlib#paragraph#GetMetric ............... |tlib#paragraph#GetMetric()| tlib#paragraph#GetMetric ............... |tlib#paragraph#GetMetric()|
tlib#paragraph#Move .................... |tlib#paragraph#Move()| tlib#paragraph#Move .................... |tlib#paragraph#Move()|
g:tlib_inputlist_pct ................... |g:tlib_inputlist_pct| g:tlib_inputlist_pct ................... |g:tlib_inputlist_pct|
@ -269,6 +283,7 @@ Contents~
tlib#arg#Let ........................... |tlib#arg#Let()| tlib#arg#Let ........................... |tlib#arg#Let()|
tlib#arg#Key ........................... |tlib#arg#Key()| tlib#arg#Key ........................... |tlib#arg#Key()|
tlib#arg#StringAsKeyArgs ............... |tlib#arg#StringAsKeyArgs()| tlib#arg#StringAsKeyArgs ............... |tlib#arg#StringAsKeyArgs()|
tlib#arg#StringAsKeyArgsEqual .......... |tlib#arg#StringAsKeyArgsEqual()|
tlib#arg#Ex ............................ |tlib#arg#Ex()| tlib#arg#Ex ............................ |tlib#arg#Ex()|
tlib#fixes#Winpos ...................... |tlib#fixes#Winpos()| tlib#fixes#Winpos ...................... |tlib#fixes#Winpos()|
g:tlib#dir#sep ......................... |g:tlib#dir#sep| g:tlib#dir#sep ......................... |g:tlib#dir#sep|
@ -658,6 +673,9 @@ tlib#list#Zip(lists, ?default='')
*tlib#list#Uniq()* *tlib#list#Uniq()*
tlib#list#Uniq(list, ...) tlib#list#Uniq(list, ...)
*tlib#list#ToDictionary()*
tlib#list#ToDictionary(list, default, ...)
======================================================================== ========================================================================
autoload/tlib/cmd.vim~ autoload/tlib/cmd.vim~
@ -747,6 +765,9 @@ g:tlib#vcs#check (default: has('win16') || has('win32') || has('wi
If non-empty, use it as a format string to check whether a VCS is If non-empty, use it as a format string to check whether a VCS is
installed on your computer. installed on your computer.
*tlib#vcs#Executable()*
tlib#vcs#Executable(type)
*tlib#vcs#FindVCS()* *tlib#vcs#FindVCS()*
tlib#vcs#FindVCS(filename) tlib#vcs#FindVCS(filename)
@ -1571,10 +1592,59 @@ tlib#file#Relative(filename, basedir)
*tlib#file#Absolute()* *tlib#file#Absolute()*
tlib#file#Absolute(filename, ...) tlib#file#Absolute(filename, ...)
*tlib#file#Canonic()*
tlib#file#Canonic(filename, ...)
*tlib#file#With()* *tlib#file#With()*
tlib#file#With(fcmd, bcmd, files, ?world={}) tlib#file#With(fcmd, bcmd, files, ?world={})
========================================================================
autoload/tlib/sys.vim~
*g:tlib#sys#windows*
g:tlib#sys#windows (default: &shell !~ 'sh' && (has('win16') || has('win32') || has('win64')))
*g:tlib#sys#null*
g:tlib#sys#null (default: g:tlib#sys#windows ? 'NUL' : (filereadable('/dev/null') ? '/dev/null' : ''))
*tlib#sys#IsExecutable()*
tlib#sys#IsExecutable(cmd, ...)
*g:tlib#sys#check_cygpath*
g:tlib#sys#check_cygpath (default: g:tlib#sys#windows && tlib#sys#IsExecutable('cygpath'))
If true, check whether we have to convert a path via cyppath --
see |tlib#sys#MaybeUseCygpath|
*g:tlib#sys#cygwin_path_rx*
g:tlib#sys#cygwin_path_rx (default: '/cygwin/')
If a full windows filename (with slashes instead of backslashes)
matches this |regexp|, it is assumed to be a cygwin executable.
*g:tlib#sys#cygwin_expr*
g:tlib#sys#cygwin_expr (default: '"bash -c ''". escape(%s, "''\\") ."''"')
For cygwin binaries, convert command calls using this vim
expression.
*tlib#sys#IsCygwinBin()*
tlib#sys#IsCygwinBin(cmd)
*tlib#sys#GetCmd()*
tlib#sys#GetCmd(cmd)
*tlib#sys#MaybeUseCygpath()*
tlib#sys#MaybeUseCygpath(cmd)
If cmd seems to be a cygwin executable, use cygpath to convert
filenames. This assumes that cygwin's which command returns full
filenames for non-cygwin executables.
*tlib#sys#ConvertPath()*
tlib#sys#ConvertPath(converter, filename)
*tlib#sys#FileArgs()*
tlib#sys#FileArgs(cmd, files)
======================================================================== ========================================================================
autoload/tlib/paragraph.vim~ autoload/tlib/paragraph.vim~
@ -1734,7 +1804,10 @@ tlib#arg#Key(dict, list, ?default='')
See |:TKeyArg|. See |:TKeyArg|.
*tlib#arg#StringAsKeyArgs()* *tlib#arg#StringAsKeyArgs()*
tlib#arg#StringAsKeyArgs(string, ?keys=[], ?evaluate=0) tlib#arg#StringAsKeyArgs(string, ?keys=[], ?evaluate=0, ?sep=':')
*tlib#arg#StringAsKeyArgsEqual()*
tlib#arg#StringAsKeyArgsEqual(string)
*tlib#arg#Ex()* *tlib#arg#Ex()*
tlib#arg#Ex(arg, ?chars='%#! ') tlib#arg#Ex(arg, ?chars='%#! ')

View file

@ -1,8 +1,8 @@
" @Author: Tom Link (micathom AT gmail com?subject=[vim]) " @Author: Tom Link (micathom AT gmail com?subject=[vim])
" @Created: 2007-04-10. " @Created: 2007-04-10.
" @Last Change: 2013-09-25. " @Last Change: 2014-07-03.
" @License: GPL (see http://www.gnu.org/licenses/gpl.txt) " @License: GPL (see http://www.gnu.org/licenses/gpl.txt)
" @Revision: 751 " @Revision: 753
" @Website: http://www.vim.org/account/profile.php?user_id=4037 " @Website: http://www.vim.org/account/profile.php?user_id=4037
" GetLatestVimScripts: 1863 1 tlib.vim " GetLatestVimScripts: 1863 1 tlib.vim
" tlib.vim -- Some utility functions " tlib.vim -- Some utility functions
@ -14,7 +14,7 @@ if v:version < 700 "{{{2
echoerr "tlib requires Vim >= 7" echoerr "tlib requires Vim >= 7"
finish finish
endif endif
let loaded_tlib = 110 let loaded_tlib = 112
let s:save_cpo = &cpo let s:save_cpo = &cpo
set cpo&vim set cpo&vim

View file

@ -211,6 +211,10 @@ function! airline#extensions#load()
call airline#extensions#nrrwrgn#init(s:ext) call airline#extensions#nrrwrgn#init(s:ext)
endif endif
if (get(g:, 'airline#extensions#capslock#enabled', 1) && exists('*CapsLockStatusline'))
call airline#extensions#capslock#init(s:ext)
endif
if !get(g:, 'airline#extensions#disable_rtp_load', 0) if !get(g:, 'airline#extensions#disable_rtp_load', 0)
" load all other extensions, which are not part of the default distribution. " load all other extensions, which are not part of the default distribution.
" (autoload/airline/extensions/*.vim outside of our s:script_path). " (autoload/airline/extensions/*.vim outside of our s:script_path).

View file

@ -0,0 +1,14 @@
" MIT License. Copyright (c) 2014 Mathias Andersson.
" vim: et ts=2 sts=2 sw=2
if !exists('*CapsLockStatusline')
finish
endif
function! airline#extensions#capslock#status()
return CapsLockStatusline() == '[caps]' ? 'CAPS' : ''
endfunction
function! airline#extensions#capslock#init(ext)
call airline#parts#define_function('capslock', 'airline#extensions#capslock#status')
endfunction

View file

@ -79,6 +79,7 @@ function! airline#init#bootstrap()
call airline#parts#define_raw('linenr', '%{g:airline_symbols.linenr}%#__accent_bold#%4l%#__restore__#') call airline#parts#define_raw('linenr', '%{g:airline_symbols.linenr}%#__accent_bold#%4l%#__restore__#')
call airline#parts#define_function('ffenc', 'airline#parts#ffenc') call airline#parts#define_function('ffenc', 'airline#parts#ffenc')
call airline#parts#define_empty(['hunks', 'branch', 'tagbar', 'syntastic', 'eclim', 'whitespace']) call airline#parts#define_empty(['hunks', 'branch', 'tagbar', 'syntastic', 'eclim', 'whitespace'])
call airline#parts#define_text('capslock', '')
unlet g:airline#init#bootstrapping unlet g:airline#init#bootstrapping
endfunction endfunction
@ -86,7 +87,7 @@ endfunction
function! airline#init#sections() function! airline#init#sections()
let spc = g:airline_symbols.space let spc = g:airline_symbols.space
if !exists('g:airline_section_a') if !exists('g:airline_section_a')
let g:airline_section_a = airline#section#create_left(['mode', 'paste', 'iminsert']) let g:airline_section_a = airline#section#create_left(['mode', 'paste', 'capslock', 'iminsert'])
endif endif
if !exists('g:airline_section_b') if !exists('g:airline_section_b')
let g:airline_section_b = airline#section#create(['hunks', 'branch']) let g:airline_section_b = airline#section#create(['hunks', 'branch'])

View file

@ -139,7 +139,7 @@ COMMANDS *airline-commands*
Toggles between the standard 'statusline' and airline. Toggles between the standard 'statusline' and airline.
:AirlineRefresh *:AirlineRefresh* :AirlineRefresh *:AirlineRefresh*
Refreshes all highlight groups. Refreshes all highlight groups and redraws the statusline.
============================================================================== ==============================================================================
CUSTOMIZATION *airline-customization* CUSTOMIZATION *airline-customization*
@ -502,6 +502,12 @@ NrrwRgn <https://github.com/chrisbra/NrrwRgn>
* enable/disable NrrwRgn integration > * enable/disable NrrwRgn integration >
let g:airline#extensions#nrrwrgn#enabled = 1 let g:airline#extensions#nrrwrgn#enabled = 1
------------------------------------- *airline-capslock*
vim-capslock <https://github.com/tpope/vim-capslock>
* enable/disable vim-capslock integration >
let g:airline#extensions#capslock#enabled = 1
<
============================================================================== ==============================================================================
ADVANCED CUSTOMIZATION *airline-advanced-customization* ADVANCED CUSTOMIZATION *airline-advanced-customization*

View file

@ -103,7 +103,7 @@ endfunction
command! -nargs=? -complete=customlist,<sid>get_airline_themes AirlineTheme call <sid>airline_theme(<f-args>) command! -nargs=? -complete=customlist,<sid>get_airline_themes AirlineTheme call <sid>airline_theme(<f-args>)
command! AirlineToggleWhitespace call airline#extensions#whitespace#toggle() command! AirlineToggleWhitespace call airline#extensions#whitespace#toggle()
command! AirlineToggle call <sid>airline_toggle() command! AirlineToggle call <sid>airline_toggle()
command! AirlineRefresh call airline#load_theme() command! AirlineRefresh call airline#load_theme() | call airline#update_statusline()
call <sid>airline_toggle() call <sid>airline_toggle()

View file

@ -55,15 +55,13 @@ and `Git!` to open the output of a command in a temp file.
## Installation ## Installation
If you don't have a preferred installation method, I recommend If you don't have a preferred installation method, one option is to install
installing [pathogen.vim](https://github.com/tpope/vim-pathogen), and [pathogen.vim](https://github.com/tpope/vim-pathogen), and then copy
then simply copy and paste: and paste:
cd ~/.vim/bundle cd ~/.vim/bundle
git clone git://github.com/tpope/vim-fugitive.git git clone git://github.com/tpope/vim-fugitive.git
vim -u NONE -c "helptags vim-fugitive/doc" -c q
Once help tags have been generated, you can view the manual with
`:help fugitive`.
If your Vim version is below 7.2, I recommend also installing If your Vim version is below 7.2, I recommend also installing
[vim-git](https://github.com/tpope/vim-git) for syntax highlighting and [vim-git](https://github.com/tpope/vim-git) for syntax highlighting and

View file

@ -185,9 +185,11 @@ function! fugitive#detect(path) abort
if expand('%:p') =~# '//' if expand('%:p') =~# '//'
call buffer.setvar('&path', s:sub(buffer.getvar('&path'), '^\.%(,|$)', '')) call buffer.setvar('&path', s:sub(buffer.getvar('&path'), '^\.%(,|$)', ''))
endif endif
if stridx(buffer.getvar('&tags'), escape(b:git_dir.'/tags', ', ')) == -1 if stridx(buffer.getvar('&tags'), escape(b:git_dir, ', ')) == -1
if filereadable(b:git_dir.'/tags')
call buffer.setvar('&tags', escape(b:git_dir.'/tags', ', ').','.buffer.getvar('&tags')) call buffer.setvar('&tags', escape(b:git_dir.'/tags', ', ').','.buffer.getvar('&tags'))
if &filetype !=# '' endif
if &filetype !=# '' && filereadable(b:git_dir.'/'.&filetype.'.tags')
call buffer.setvar('&tags', escape(b:git_dir.'/'.&filetype.'.tags', ', ').','.buffer.getvar('&tags')) call buffer.setvar('&tags', escape(b:git_dir.'/'.&filetype.'.tags', ', ').','.buffer.getvar('&tags'))
endif endif
endif endif
@ -1007,9 +1009,10 @@ function! s:Commit(args, ...) abort
let error = get(errors,-2,get(errors,-1,'!')) let error = get(errors,-2,get(errors,-1,'!'))
if error =~# 'false''\=\.$' if error =~# 'false''\=\.$'
let args = a:args let args = a:args
let args = s:gsub(args,'%(%(^| )-- )@<!%(^| )@<=%(-[esp]|--edit|--interactive|patch|--signoff)%($| )','') let args = s:gsub(args,'%(%(^| )-- )@<!%(^| )@<=%(-[esp]|--edit|--interactive|--patch|--signoff)%($| )','')
let args = s:gsub(args,'%(%(^| )-- )@<!%(^| )@<=%(-c|--reedit-message|--reuse-message|-F|--file|-m|--message)%(\s+|\=)%(''[^'']*''|"%(\\.|[^"])*"|\\.|\S)*','') let args = s:gsub(args,'%(%(^| )-- )@<!%(^| )@<=%(-c|--reedit-message|--reuse-message|-F|--file|-m|--message)%(\s+|\=)%(''[^'']*''|"%(\\.|[^"])*"|\\.|\S)*','')
let args = s:gsub(args,'%(^| )@<=[%#]%(:\w)*','\=expand(submatch(0))') let args = s:gsub(args,'%(^| )@<=[%#]%(:\w)*','\=expand(submatch(0))')
let args = s:sub(args, '\ze -- |$', ' --no-edit --no-interactive --no-signoff')
let args = '-F '.s:shellesc(msgfile).' '.args let args = '-F '.s:shellesc(msgfile).' '.args
if args !~# '\%(^\| \)--cleanup\>' if args !~# '\%(^\| \)--cleanup\>'
let args = '--cleanup=strip '.args let args = '--cleanup=strip '.args
@ -1162,7 +1165,7 @@ function! s:Merge(cmd, bang, args) abort
if empty(filter(getqflist(),'v:val.valid')) if empty(filter(getqflist(),'v:val.valid'))
if !had_merge_msg && filereadable(s:repo().dir('MERGE_MSG')) if !had_merge_msg && filereadable(s:repo().dir('MERGE_MSG'))
cclose cclose
return 'Gcommit --no-status -t '.s:shellesc(s:repo().dir('MERGE_MSG')) return 'Gcommit --no-status -n -t '.s:shellesc(s:repo().dir('MERGE_MSG'))
endif endif
endif endif
let qflist = getqflist() let qflist = getqflist()
@ -2172,17 +2175,29 @@ function! s:Browse(bang,line1,count,...) abort
let raw = remote let raw = remote
endif endif
let url = s:github_url(s:repo(),raw,rev,commit,path,type,a:line1,a:count) for Handler in g:fugitive_browse_handlers
if url == '' let url = call(Handler, [{
let url = s:instaweb_url(s:repo(),rev,commit,path,type,a:count > 0 ? a:line1 : 0) \ 'repo': s:repo(),
\ 'remote': raw,
\ 'revision': rev,
\ 'commit': commit,
\ 'path': path,
\ 'type': type,
\ 'line1': a:count > 0 ? a:line1 : 0,
\ 'line2': a:count > 0 ? a:count : 0}])
if !empty(url)
break
endif endif
endfor
if url == '' if empty(url)
call s:throw("Instaweb failed to start and '".remote."' is not a GitHub remote") call s:throw("Instaweb failed to start and '".remote."' is not a supported remote")
endif endif
if a:bang if a:bang
if has('clipboard')
let @* = url let @* = url
endif
return 'echomsg '.string(url) return 'echomsg '.string(url)
elseif exists(':Browse') == 2 elseif exists(':Browse') == 2
return 'echomsg '.string(url).'|Browse '.url return 'echomsg '.string(url).'|Browse '.url
@ -2194,24 +2209,27 @@ function! s:Browse(bang,line1,count,...) abort
endtry endtry
endfunction endfunction
function! s:github_url(repo,url,rev,commit,path,type,line1,line2) abort function! s:github_url(opts, ...) abort
let path = a:path if a:0 || type(a:opts) != type({})
return ''
endif
let domain_pattern = 'github\.com' let domain_pattern = 'github\.com'
let domains = exists('g:fugitive_github_domains') ? g:fugitive_github_domains : [] let domains = exists('g:fugitive_github_domains') ? g:fugitive_github_domains : []
for domain in domains for domain in domains
let domain_pattern .= '\|' . escape(split(domain, '://')[-1], '.') let domain_pattern .= '\|' . escape(split(domain, '://')[-1], '.')
endfor endfor
let repo = matchstr(a:url,'^\%(https\=://\|git://\|git@\)\=\zs\('.domain_pattern.'\)[/:].\{-\}\ze\%(\.git\)\=$') let repo = matchstr(get(a:opts, 'remote'), '^\%(https\=://\|git://\|git@\)\=\zs\('.domain_pattern.'\)[/:].\{-\}\ze\%(\.git\)\=$')
if repo ==# '' if repo ==# ''
return '' return ''
endif endif
let path = a:opts.path
if index(domains, 'http://' . matchstr(repo, '^[^:/]*')) >= 0 if index(domains, 'http://' . matchstr(repo, '^[^:/]*')) >= 0
let root = 'http://' . s:sub(repo,':','/') let root = 'http://' . s:sub(repo,':','/')
else else
let root = 'https://' . s:sub(repo,':','/') let root = 'https://' . s:sub(repo,':','/')
endif endif
if path =~# '^\.git/refs/heads/' if path =~# '^\.git/refs/heads/'
let branch = a:repo.git_chomp('config','branch.'.path[16:-1].'.merge')[11:-1] let branch = a:opts.repo.git_chomp('config','branch.'.path[16:-1].'.merge')[11:-1]
if branch ==# '' if branch ==# ''
return root . '/commits/' . path[16:-1] return root . '/commits/' . path[16:-1]
else else
@ -2224,27 +2242,27 @@ function! s:github_url(repo,url,rev,commit,path,type,line1,line2) abort
elseif path =~# '^\.git\>' elseif path =~# '^\.git\>'
return root return root
endif endif
if a:rev =~# '^[[:alnum:]._-]\+:' if a:opts.revision =~# '^[[:alnum:]._-]\+:'
let commit = matchstr(a:rev,'^[^:]*') let commit = matchstr(a:opts.revision,'^[^:]*')
elseif a:commit =~# '^\d\=$' elseif a:opts.commit =~# '^\d\=$'
let local = matchstr(a:repo.head_ref(),'\<refs/heads/\zs.*') let local = matchstr(a:opts.repo.head_ref(),'\<refs/heads/\zs.*')
let commit = a:repo.git_chomp('config','branch.'.local.'.merge')[11:-1] let commit = a:opts.repo.git_chomp('config','branch.'.local.'.merge')[11:-1]
if commit ==# '' if commit ==# ''
let commit = local let commit = local
endif endif
else else
let commit = a:commit let commit = a:opts.commit
endif endif
if a:type == 'tree' if a:opts.type == 'tree'
let url = s:sub(root . '/tree/' . commit . '/' . path,'/$','') let url = s:sub(root . '/tree/' . commit . '/' . path,'/$','')
elseif a:type == 'blob' elseif a:opts.type == 'blob'
let url = root . '/blob/' . commit . '/' . path let url = root . '/blob/' . commit . '/' . path
if a:line2 > 0 && a:line1 == a:line2 if get(a:opts, 'line2') && a:opts.line1 == a:opts.line2
let url .= '#L' . a:line1 let url .= '#L' . a:opts.line1
elseif a:line2 > 0 elseif get(a:opts, 'line2')
let url .= '#L' . a:line1 . '-' . a:line2 let url .= '#L' . a:opts.line1 . '-' . a:opts.line2
endif endif
elseif a:type == 'tag' elseif a:opts.type == 'tag'
let commit = matchstr(getline(3),'^tag \zs.*') let commit = matchstr(getline(3),'^tag \zs.*')
let url = root . '/tree/' . commit let url = root . '/tree/' . commit
else else
@ -2253,47 +2271,54 @@ function! s:github_url(repo,url,rev,commit,path,type,line1,line2) abort
return url return url
endfunction endfunction
function! s:instaweb_url(repo,rev,commit,path,type,...) abort function! s:instaweb_url(opts) abort
let output = a:repo.git_chomp('instaweb','-b','unknown') let output = a:opts.repo.git_chomp('instaweb','-b','unknown')
if output =~# 'http://' if output =~# 'http://'
let root = matchstr(output,'http://.*').'/?p='.fnamemodify(a:repo.dir(),':t') let root = matchstr(output,'http://.*').'/?p='.fnamemodify(a:opts.repo.opts.dir(),':t')
else else
return '' return ''
endif endif
if a:path =~# '^\.git/refs/.' if a:opts.path =~# '^\.git/refs/.'
return root . ';a=shortlog;h=' . matchstr(a:path,'^\.git/\zs.*') return root . ';a=shortlog;h=' . matchstr(a:opts.path,'^\.git/\zs.*')
elseif a:path =~# '^\.git\>' elseif a:opts.path =~# '^\.git\>'
return root return root
endif endif
let url = root let url = root
if a:commit =~# '^\x\{40\}$' if a:opts.commit =~# '^\x\{40\}$'
if a:type ==# 'commit' if a:opts.type ==# 'commit'
let url .= ';a=commit' let url .= ';a=commit'
endif endif
let url .= ';h=' . a:repo.rev_parse(a:commit . (a:path == '' ? '' : ':' . a:path)) let url .= ';h=' . a:opts.repo.rev_parse(a:opts.commit . (a:opts.path == '' ? '' : ':' . a:opts.path))
else else
if a:type ==# 'blob' if a:opts.type ==# 'blob'
let tmp = tempname() let tmp = tempname()
silent execute 'write !'.a:repo.git_command('hash-object','-w','--stdin').' > '.tmp silent execute 'write !'.a:opts.repo.git_command('hash-object','-w','--stdin').' > '.tmp
let url .= ';h=' . readfile(tmp)[0] let url .= ';h=' . readfile(tmp)[0]
else else
try try
let url .= ';h=' . a:repo.rev_parse((a:commit == '' ? 'HEAD' : ':' . a:commit) . ':' . a:path) let url .= ';h=' . a:opts.repo.rev_parse((a:opts.commit == '' ? 'HEAD' : ':' . a:opts.commit) . ':' . a:opts.path)
catch /^fugitive:/ catch /^fugitive:/
call s:throw('fugitive: cannot browse uncommitted file') call s:throw('fugitive: cannot browse uncommitted file')
endtry endtry
endif endif
let root .= ';hb=' . matchstr(a:repo.head_ref(),'[^ ]\+$') let root .= ';hb=' . matchstr(a:opts.repo.head_ref(),'[^ ]\+$')
endif endif
if a:path !=# '' if a:opts.path !=# ''
let url .= ';f=' . a:path let url .= ';f=' . a:opts.path
endif endif
if a:0 && a:1 if get(a:opts, 'line1')
let url .= '#l' . a:1 let url .= '#l' . a:opts.line1
endif endif
return url return url
endfunction endfunction
if !exists('g:fugitive_browse_handlers')
let g:fugitive_browse_handlers = []
endif
call extend(g:fugitive_browse_handlers,
\ [s:function('s:github_url'), s:function('s:instaweb_url')])
" Section: File access " Section: File access
function! s:ReplaceCmd(cmd,...) abort function! s:ReplaceCmd(cmd,...) abort
@ -2597,7 +2622,7 @@ augroup fugitive_temp
\ let b:git_type = 'temp' | \ let b:git_type = 'temp' |
\ let b:git_args = s:temp_files[tolower(expand('<afile>:p'))].args | \ let b:git_args = s:temp_files[tolower(expand('<afile>:p'))].args |
\ call fugitive#detect(expand('<afile>:p')) | \ call fugitive#detect(expand('<afile>:p')) |
\ setlocal bufhidden=delete | \ setlocal bufhidden=delete nobuflisted |
\ nnoremap <buffer> <silent> q :<C-U>bdelete<CR>| \ nnoremap <buffer> <silent> q :<C-U>bdelete<CR>|
\ endif \ endif
augroup END augroup END

View file

@ -75,12 +75,14 @@ syn region markdownLink matchgroup=markdownLinkDelimiter start="(" end=")" conta
syn region markdownId matchgroup=markdownIdDelimiter start="\[" end="\]" keepend contained syn region markdownId matchgroup=markdownIdDelimiter start="\[" end="\]" keepend contained
syn region markdownAutomaticLink matchgroup=markdownUrlDelimiter start="<\%(\w\+:\|[[:alnum:]_+-]\+@\)\@=" end=">" keepend oneline syn region markdownAutomaticLink matchgroup=markdownUrlDelimiter start="<\%(\w\+:\|[[:alnum:]_+-]\+@\)\@=" end=">" keepend oneline
syn region markdownItalic start="\S\@<=\*\|\*\S\@=" end="\S\@<=\*\|\*\S\@=" keepend contains=markdownLineStart let s:concealends = has('conceal') ? ' concealends' : ''
syn region markdownItalic start="\S\@<=_\|_\S\@=" end="\S\@<=_\|_\S\@=" keepend contains=markdownLineStart exe 'syn region markdownItalic matchgroup=markdownItalicDelimiter start="\S\@<=\*\|\*\S\@=" end="\S\@<=\*\|\*\S\@=" keepend contains=markdownLineStart' . s:concealends
syn region markdownBold start="\S\@<=\*\*\|\*\*\S\@=" end="\S\@<=\*\*\|\*\*\S\@=" keepend contains=markdownLineStart,markdownItalic exe 'syn region markdownItalic matchgroup=markdownItalicDelimiter start="\S\@<=_\|_\S\@=" end="\S\@<=_\|_\S\@=" keepend contains=markdownLineStart' . s:concealends
syn region markdownBold start="\S\@<=__\|__\S\@=" end="\S\@<=__\|__\S\@=" keepend contains=markdownLineStart,markdownItalic exe 'syn region markdownBold matchgroup=markdownBoldDelimiter start="\S\@<=\*\*\|\*\*\S\@=" end="\S\@<=\*\*\|\*\*\S\@=" keepend contains=markdownLineStart,markdownItalic' . s:concealends
syn region markdownBoldItalic start="\S\@<=\*\*\*\|\*\*\*\S\@=" end="\S\@<=\*\*\*\|\*\*\*\S\@=" keepend contains=markdownLineStart exe 'syn region markdownBold matchgroup=markdownBoldDelimiter start="\S\@<=__\|__\S\@=" end="\S\@<=__\|__\S\@=" keepend contains=markdownLineStart,markdownItalic' . s:concealends
syn region markdownBoldItalic start="\S\@<=___\|___\S\@=" end="\S\@<=___\|___\S\@=" keepend contains=markdownLineStart exe 'syn region markdownBoldItalic matchgroup=markdownBoldItalicDelimiter start="\S\@<=\*\*\*\|\*\*\*\S\@=" end="\S\@<=\*\*\*\|\*\*\*\S\@=" keepend contains=markdownLineStart' . s:concealends
exe 'syn region markdownBoldItalic matchgroup=markdownBoldItalicDelimiter start="\S\@<=___\|___\S\@=" end="\S\@<=___\|___\S\@=" keepend contains=markdownLineStart' . s:concealends
syn region markdownCode matchgroup=markdownCodeDelimiter start="`" end="`" keepend contains=markdownLineStart syn region markdownCode matchgroup=markdownCodeDelimiter start="`" end="`" keepend contains=markdownLineStart
syn region markdownCode matchgroup=markdownCodeDelimiter start="`` \=" end=" \=``" keepend contains=markdownLineStart syn region markdownCode matchgroup=markdownCodeDelimiter start="`` \=" end=" \=``" keepend contains=markdownLineStart
syn region markdownCode matchgroup=markdownCodeDelimiter start="^\s*```.*$" end="^\s*```\ze\s*$" keepend syn region markdownCode matchgroup=markdownCodeDelimiter start="^\s*```.*$" end="^\s*```\ze\s*$" keepend
@ -125,8 +127,11 @@ hi def link markdownUrlDelimiter htmlTag
hi def link markdownUrlTitleDelimiter Delimiter hi def link markdownUrlTitleDelimiter Delimiter
hi def link markdownItalic htmlItalic hi def link markdownItalic htmlItalic
hi def link markdownItalicDelimiter markdownItalic
hi def link markdownBold htmlBold hi def link markdownBold htmlBold
hi def link markdownBoldDelimiter markdownBold
hi def link markdownBoldItalic htmlBoldItalic hi def link markdownBoldItalic htmlBoldItalic
hi def link markdownBoldItalicDelimiter markdownBoldItalic
hi def link markdownCodeDelimiter Delimiter hi def link markdownCodeDelimiter Delimiter
hi def link markdownEscape Special hi def link markdownEscape Special

View file

@ -10,7 +10,7 @@ catch /.*/
endtry endtry
" match $ which doesn't follow a \ " match $ which doesn't follow a \
let s:d = '\%([\\]\@<!\$\)' let s:d = nr2char(31)
fun! Filename(...) fun! Filename(...)
let filename = expand('%:t:r') let filename = expand('%:t:r')
@ -103,6 +103,7 @@ endfunction
" Prepare snippet to be processed by s:BuildTabStops " Prepare snippet to be processed by s:BuildTabStops
fun! s:ProcessSnippet(snip) fun! s:ProcessSnippet(snip)
let snippet = a:snip let snippet = a:snip
let esc_bslash = '\%(\\\@<!\%(\\\\\)*\)\@<='
if exists('b:snipmate_content_visual') if exists('b:snipmate_content_visual')
let visual = b:snipmate_content_visual let visual = b:snipmate_content_visual
@ -118,7 +119,7 @@ fun! s:ProcessSnippet(snip)
" Using a loop here instead of a regex fixes a bug with nested "\=". " Using a loop here instead of a regex fixes a bug with nested "\=".
if stridx(snippet, '`') != -1 if stridx(snippet, '`') != -1
let new = [] let new = []
let snip = split(snippet, '\%(\\\@<!\%(\\\\\)*\)\@<=`', 1) let snip = split(snippet, esc_bslash . '`', 1)
let isexp = 0 let isexp = 0
for i in snip for i in snip
if isexp if isexp
@ -131,13 +132,15 @@ fun! s:ProcessSnippet(snip)
let snippet = join(new, '') let snippet = join(new, '')
let snippet = substitute(snippet, "\r", "\n", 'g') let snippet = substitute(snippet, "\r", "\n", 'g')
let snippet = substitute(snippet, '\\`', "`", 'g') let snippet = substitute(snippet, '\\`', "`", 'g')
let snippet = substitute(snippet, '\\\\', "\\", 'g')
endif endif
" Place all text after a colon in a tab stop after the tab stop " Place all text after a colon in a tab stop after the tab stop
" (e.g. "${#:foo}" becomes "${:foo}foo"). " (e.g. "${#:foo}" becomes "${:foo}foo").
" This helps tell the position of the tab stops later. " This helps tell the position of the tab stops later.
let snippet = substitute(snippet, s:d.'{\d\+:\(.\{-}\)}', '&\1', 'g') let snippet = substitute(snippet, esc_bslash . '\$\({\d\+:\(.\{-}\)}\|{\d\+}\)', s:d . '\1\2', 'g')
let snippet = substitute(snippet, esc_bslash . '\$\(\d\+\)', s:d . '\1', 'g')
let snippet = substitute(snippet, esc_bslash . '\\\$', '$', 'g')
let snippet = substitute(snippet, '\\\\', "\\", 'g')
" Update the a:snip so that all the $# become the text after " Update the a:snip so that all the $# become the text after
" the colon in their associated ${#}. " the colon in their associated ${#}.
@ -153,14 +156,14 @@ fun! s:ProcessSnippet(snip)
" Add ${0} tab stop if found " Add ${0} tab stop if found
if snippet =~ s:d . '{0' if snippet =~ s:d . '{0'
let snippet = substitute(snippet, s:d.'{0', '${'.i, '') let snippet = substitute(snippet, s:d.'{0', s:d . '{' . i, '')
let s = matchstr(snippet, s:d.'{'.i.':\zs.\{-}\ze}') let s = matchstr(snippet, s:d.'{'.i.':\zs.\{-}\ze}')
if s != '' if s != ''
let snippet = substitute(snippet, s:d.'0', '$'.i, 'g') let snippet = substitute(snippet, s:d.'0', s:d . i, 'g')
let snippet = substitute(snippet, s:d.i, s.'&', 'g') let snippet = substitute(snippet, s:d.i, s.'&', 'g')
endif endif
else else
let snippet .= '${'.i.'}' let snippet .= s:d . '{'.i.'}'
endif endif
if &et " Expand tabs to spaces if 'expandtab' is set. if &et " Expand tabs to spaces if 'expandtab' is set.
@ -194,7 +197,7 @@ endf
fun! s:BuildTabStops(snip, lnum, col, indent) fun! s:BuildTabStops(snip, lnum, col, indent)
let snipPos = [] let snipPos = []
let i = 1 let i = 1
let withoutVars = substitute(a:snip, '$\d\+', '', 'g') let withoutVars = substitute(a:snip, s:d . '\d\+', '', 'g')
while a:snip =~ s:d.'{'.i while a:snip =~ s:d.'{'.i
let beforeTabStop = matchstr(withoutVars, '^.*\ze'.s:d .'{'.i.'\D') let beforeTabStop = matchstr(withoutVars, '^.*\ze'.s:d .'{'.i.'\D')
let withoutOthers = substitute(withoutVars, ''.s:d .'{\('.i.'\D\)\@!\d\+.\{-}}', '', 'g') let withoutOthers = substitute(withoutVars, ''.s:d .'{\('.i.'\D\)\@!\d\+.\{-}}', '', 'g')
@ -243,13 +246,12 @@ function! s:state_proto.jump_stop(backwards)
" Loop over the snippet when going backwards from the beginning " Loop over the snippet when going backwards from the beginning
if self.stop_no < 0 | let self.stop_no = self.stop_count - 1 | endif if self.stop_no < 0 | let self.stop_no = self.stop_count - 1 | endif
if self.stop_no == self.stop_count
call self.remove()
return ''
endif
call self.set_stop(self.stop_no) call self.set_stop(self.stop_no)
return self.select_word() let ret = self.select_word()
if self.stop_no == self.stop_count - 1
call self.remove()
endif
return ret
endfunction endfunction
" Updates tab stops/vars " Updates tab stops/vars

View file

@ -117,7 +117,7 @@ function! s:load_scopes(bang, ...)
let gb.snipMate.scope_aliases['_'] = join(split(get(gb.snipMate.scope_aliases, '_', ''), ',') + a:000, ',') let gb.snipMate.scope_aliases['_'] = join(split(get(gb.snipMate.scope_aliases, '_', ''), ',') + a:000, ',')
endfunction endfunction
command! -bang -bar -nargs=+ SnipMateLoadScopes command! -bang -bar -nargs=+ SnipMateLoadScope
\ call s:load_scopes(<bang>0, <f-args>) \ call s:load_scopes(<bang>0, <f-args>)
" Edit snippet files " Edit snippet files

View file

@ -0,0 +1 @@
*.pyc

View file

@ -1,3 +1,5 @@
extends html
priority -50 priority -50
# TextMate added these variables to cope with changes in ERB handling # TextMate added these variables to cope with changes in ERB handling

View file

@ -184,7 +184,7 @@ else if ($1)`!p nl(snip)`{
} }
endsnippet endsnippet
snippet /el(se)?/ "else" r snippet el "else" w
else`!p nl(snip)`{ else`!p nl(snip)`{
$0 $0
} }

View file

@ -3,6 +3,5 @@ priority -50
snippet t "Transaction" b snippet t "Transaction" b
${1:`!v strftime("%Y")`}-${2:`!v strftime("%m")`}-${3:`!v strftime("%d")`} ${4:*} ${5:Payee} ${1:`!v strftime("%Y")`}-${2:`!v strftime("%m")`}-${3:`!v strftime("%d")`} ${4:*} ${5:Payee}
${6:Expenses} \$${7:0.00} ${6:Expenses} \$${7:0.00}
${8:Assets:Checking} ${8:Assets:Checking}$0
$0
endsnippet endsnippet

View file

@ -224,7 +224,7 @@ class $1
{ {
public function ${3:__construct}(${4:$options}) public function ${3:__construct}(${4:$options})
{ {
${4:// code} ${5:// code}
} }
} }
$0 $0

View file

@ -560,6 +560,13 @@ snippet ar "Assert raises" b
self.assertRaises(${1:exception}, ${2:func}${3/.+/, /}${3:arguments}) self.assertRaises(${1:exception}, ${2:func}${3/.+/, /}${3:arguments})
endsnippet endsnippet
snippet an "Assert is None" b
self.assertIsNone(${0:expression})
endsnippet
snippet ann "Assert is not None" b
self.assertIsNotNone(${0:expression})
endsnippet
snippet testcase "pyunit testcase" b snippet testcase "pyunit testcase" b
class Test${1:Class}(${2:unittest.TestCase}): class Test${1:Class}(${2:unittest.TestCase}):

View file

@ -42,18 +42,9 @@ INCLUDABLE_DIRECTIVES = ['image', 'figure', 'include']
CJK_RE = re.compile(u'[⺀-⺙⺛-⻳⼀-⿕々〇〡-〩〸-〺〻㐀-䶵一-鿃豈-鶴侮-頻並-龎]', re.UNICODE) CJK_RE = re.compile(u'[⺀-⺙⺛-⻳⼀-⿕々〇〡-〩〸-〺〻㐀-䶵一-鿃豈-鶴侮-頻並-龎]', re.UNICODE)
def has_cjk(char): def has_cjk(s):
""" """Detect if s contains CJK characters."""
Detect char contains CJK character return CJK_RE.search(s) is not None
:param char: characters needs to be detect
"""
try:
CJK_RE.finditer(char).next()
except StopIteration:
return False
else:
return True
def real_filename(filename): def real_filename(filename):
"""pealeextension name off if possible """pealeextension name off if possible
@ -74,15 +65,17 @@ def check_file_exist(rst_path, relative_path):
return abs_path return abs_path
def rst_char_len(char): try:
""" rst_char_len = vim.strwidth # Requires Vim 7.3+
return len of string which fit in rst except AttributeError:
For instance:chinese "我" decode as only one character, from unicodedata import east_asian_width
However, the rst interpreter needs 2 "=" instead of 1. def rst_char_len(s):
"""Return the required over-/underline length for s."""
result = 0
for c in s:
result += 2 if east_asian_width(c) in ('W', 'F') else 1
return result
:param: char needs to be count
"""
return len(re.findall(r'[^\u4e00-\u9fff\s]', char))+len(char)
def make_items(times, leading='+'): def make_items(times, leading='+'):
""" """
@ -94,7 +87,7 @@ def make_items(times, leading='+'):
times = int(times) times = int(times)
if leading == 1: if leading == 1:
msg = "" msg = ""
for x in xrange(1, times+1): for x in range(1, times+1):
msg += "%s. Item\n" % x msg += "%s. Item\n" % x
return msg return msg
else: else:
@ -136,43 +129,43 @@ endglobal
snippet part "Part" b snippet part "Part" b
`!p snip.rv = rst_char_len(t[1])*'#'` `!p snip.rv = rst_char_len(t[1])*'#'`
${1:Part name} ${1:${VISUAL:Part name}}
`!p snip.rv = rst_char_len(t[1])*'#'` `!p snip.rv = rst_char_len(t[1])*'#'`
$0 $0
endsnippet endsnippet
snippet sec "Section" b
${1:Section name}
`!p snip.rv = rst_char_len(t[1])*'='`
$0
endsnippet
snippet ssec "Subsection" b
${1:Section name}
`!p snip.rv = rst_char_len(t[1])*'-'`
$0
endsnippet
snippet sssec "Subsubsection" b
${1:Section name}
`!p snip.rv = rst_char_len(t[1])*'^'`
$0
endsnippet
snippet chap "Chapter" b snippet chap "Chapter" b
`!p snip.rv = rst_char_len(t[1])*'*'` `!p snip.rv = rst_char_len(t[1])*'*'`
${1:Chapter name} ${1:${VISUAL:Chapter name}}
`!p snip.rv = rst_char_len(t[1])*'*'` `!p snip.rv = rst_char_len(t[1])*'*'`
$0 $0
endsnippet endsnippet
snippet sec "Section" b
${1:${VISUAL:Section name}}
`!p snip.rv = rst_char_len(t[1])*'='`
$0
endsnippet
snippet ssec "Subsection" b
${1:${VISUAL:Subsection name}}
`!p snip.rv = rst_char_len(t[1])*'-'`
$0
endsnippet
snippet sssec "Subsubsection" b
${1:${VISUAL:Subsubsection name}}
`!p snip.rv = rst_char_len(t[1])*'^'`
$0
endsnippet
snippet para "Paragraph" b snippet para "Paragraph" b
${1:Paragraph name} ${1:${VISUAL:Paragraph name}}
`!p snip.rv = rst_char_len(t[1])*'"'` `!p snip.rv = rst_char_len(t[1])*'"'`
$0 $0
@ -180,7 +173,7 @@ endsnippet
snippet em "Emphasize string" i snippet em "Emphasize string" i
`!p `!p
# dirty but works with CJK charactor detection # dirty but works with CJK character detection
if has_cjk(vim.current.line): if has_cjk(vim.current.line):
snip.rv ="\ "`*${1:${VISUAL:Em}}*`!p snip.rv ="\ "`*${1:${VISUAL:Em}}*`!p
if has_cjk(vim.current.line): if has_cjk(vim.current.line):
@ -224,7 +217,7 @@ endsnippet
snippet cb "Code Block" b snippet cb "Code Block" b
.. code-block:: ${1:`!p snip.rv = get_popular_code_type()`} .. code-block:: ${1:`!p snip.rv = get_popular_code_type()`}
${2:code} ${2:${VISUAL:code}}
$0 $0
endsnippet endsnippet
@ -247,7 +240,10 @@ if di == 'fi':
:alt: {0} :alt: {0}
{0}""".format(real_name) {0}""".format(real_name)
` `
..`!p snip.rv = " %s" % link if link else ""` $1`!p snip.rv=complete(t[1], INCLUDABLE_DIRECTIVES)`:: ${2:file}`!p if content: ..`!p snip.rv = " %s" % link if link else ""` $1`!p
snip.rv=complete(t[1], INCLUDABLE_DIRECTIVES)
`:: ${2:${VISUAL:file}}`!p
if content:
snip.rv +=" "+content` snip.rv +=" "+content`
`!p `!p
# Tip of whether file is exist in comment type # Tip of whether file is exist in comment type
@ -261,7 +257,7 @@ endsnippet
snippet di "Directives" b snippet di "Directives" b
.. $1`!p snip.rv=complete(t[1], DIRECTIVES)`:: $2 .. $1`!p snip.rv=complete(t[1], DIRECTIVES)`:: $2
${3:Content} ${3:${VISUAL:Content}}
$0 $0
endsnippet endsnippet
@ -273,7 +269,7 @@ endsnippet
snippet sa "Specific Admonitions" b snippet sa "Specific Admonitions" b
.. $1`!p snip.rv =complete(t[1], SPECIFIC_ADMONITIONS)`:: .. $1`!p snip.rv =complete(t[1], SPECIFIC_ADMONITIONS)`::
${2:Content} ${2:${VISUAL:Content}}
$0 $0
endsnippet endsnippet
@ -292,6 +288,6 @@ endsnippet
snippet sid "SideBar" b snippet sid "SideBar" b
.. sidebar:: ${1:SideBar Title} .. sidebar:: ${1:SideBar Title}
${2:SideBar Content} ${2:${VISUAL:SideBar Content}}
endsnippet endsnippet
# vim:ft=snippets: # vim:ft=snippets:

View file

@ -47,6 +47,9 @@ snippet backspace
# ⎋ # ⎋
snippet esc snippet esc
&#x238B; &#x238B;
# comment
snippet //
<!-- ${1} -->${0}
# Generic Doctype # Generic Doctype
snippet doctype HTML 4.01 Strict snippet doctype HTML 4.01 Strict
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"

View file

@ -94,6 +94,9 @@ snippet gett
# console.log (Firebug) # console.log (Firebug)
snippet cl snippet cl
console.log(${0}); console.log(${0});
# console.debug (Firebug)
snippet cd
console.debug(${0});
# return # return
snippet ret snippet ret
return ${0:result} return ${0:result}

View file

@ -0,0 +1,484 @@
snippet art
assert_redirected_to ${1:action}: '${2:index}'
snippet artnp
assert_redirected_to ${1:parent}_${2:child}_path(${3:@$1}, ${0:@$2})
snippet artnpp
assert_redirected_to ${1:parent}_${2:child}_path(${0:@$1})
snippet artp
assert_redirected_to ${1:model}_path(${0:@$1})
snippet artpp
assert_redirected_to ${0:model}s_path
snippet asd
assert_difference '${1:Model}.${2:count}', ${3:1} do
${0}
end
snippet asnd
assert_no_difference '${1:Model}.${2:count}' do
${0}
end
snippet asre
assert_response :${1:success}, @response.body
snippet asrj
assert_rjs :${1:replace}, '${0:dom id}'
snippet ass assert_select(..)
assert_select '${1:path}', ${2:text}: '${3:inner_html}' ${4:do}
${0}
end
snippet ba
before_action :${0:method}
snippet bf
before_filter :${0:method}
snippet bt
belongs_to :${0:association}
snippet btp
belongs_to :${1:association}, polymorphic: true
snippet crw
cattr_accessor :${0:attr_names}
snippet defcreate
def create
@${1:model_class_name} = ${2:ModelClassName}.new(params[:$1])
respond_to do |format|
if @$1.save
flash[:notice] = '$2 was successfully created.'
format.html { redirect_to(@$1) }
format.xml { render xml: @$1, status: :created, location: @$1 }
else
format.html { render action: 'new' }
format.xml { render xml: @$1.errors, status: :unprocessable_entity }
end
end
end
snippet defdestroy
def destroy
@${1:model_class_name} = ${2:ModelClassName}.find(params[:id])
@$1.destroy
respond_to do |format|
format.html { redirect_to($1s_url) }
format.xml { head :ok }
end
end
snippet defedit
def edit
@${1:model_class_name} = ${0:ModelClassName}.find(params[:id])
end
snippet defindex
def index
@${1:model_class_name} = ${2:ModelClassName}.all
respond_to do |format|
format.html # index.html.erb
format.xml { render xml: @$1s }
end
end
snippet defnew
def new
@${1:model_class_name} = ${2:ModelClassName}.new
respond_to do |format|
format.html # new.html.erb
format.xml { render xml: @$1 }
end
end
snippet defshow
def show
@${1:model_class_name} = ${2:ModelClassName}.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.xml { render xml: @$1 }
end
end
snippet defupdate
def update
@${1:model_class_name} = ${2:ModelClassName}.find(params[:id])
respond_to do |format|
if @$1.update_attributes(params[:$1])
flash[:notice] = '$2 was successfully updated.'
format.html { redirect_to(@$1) }
format.xml { head :ok }
else
format.html { render action: 'edit' }
format.xml { render xml: @$1.errors, status: :unprocessable_entity }
end
end
end
snippet dele delegate .. to
delegate :${1:methods}, to: :${0:object}
snippet dele delegate .. to .. prefix .. allow_nil
delegate :${1:methods}, to: :${2:object}, prefix: :${3:prefix}, allow_nil: ${0:allow_nil}
snippet flash
flash[:${1:notice}] = '${0}'
snippet habtm
has_and_belongs_to_many :${1:object}, join_table: '${2:table_name}', foreign_key: '${3}_id'
snippet hm
has_many :${0:object}
snippet hmd
has_many :${1:other}s, class_name: '${2:$1}', foreign_key: '${3:$1}_id', dependent: :destroy
snippet hmt
has_many :${1:object}, through: :${0:object}
snippet ho
has_one :${0:object}
snippet hod
has_one :${1:object}, dependent: :${0:destroy}
snippet i18
I18n.t('${1:type.key}')
snippet ist
<%= image_submit_tag('${1:agree.png}', id: '${2:id}'${0}) %>
snippet log
Rails.logger.${1:debug} ${0}
snippet log2
RAILS_DEFAULT_LOGGER.${1:debug} ${0}
snippet logd
logger.debug { '${1:message}' }
snippet loge
logger.error { '${1:message}' }
snippet logf
logger.fatal { '${1:message}' }
snippet logi
logger.info { '${1:message}' }
snippet logw
logger.warn { '${1:message}' }
snippet mapc
${1:map}.${2:connect} '${0:controller/:action/:id}'
snippet mapca
${1:map}.catch_all '*${2:anything}', controller: '${3:default}', action: '${4:error}'
snippet mapr
${1:map}.resource :${0:resource}
snippet maprs
${1:map}.resources :${0:resource}
snippet mapwo
${1:map}.with_options ${2:controller}: '${3:thing}' do |$3|
${0}
end
###############################
# model callback snippets #
###############################
# before callback
snippet mbv
before_validation :${0:method}
snippet mbc
before_create :${0:method}
snippet mbu
before_update :${0:method}
snippet mbs
before_save :${0:method}
snippet mbd
before_destroy :${0:method}
# after callback
snippet mav
after_validation :${0:method}
snippet maf
after_find :${0:method}
snippet mat
after_touch :${0:method}
snippet macr
after_create :${0:method}
snippet mau
after_update :${0:method}
snippet mas
after_save :${0:method}
snippet mad
after_destroy :${0:method}
# around callback
snippet marc
around_create :${0:method}
snippet maru
around_update :${0:method}
snippet mars
around_save :${0:method}
snippet mard
around_destroy :${0:method}
snippet mcht
change_table :${1:table_name} do |t|
${0}
end
snippet mp
map(&:${0:id})
snippet mrw
mattr_accessor :${0:attr_names}
snippet oa
order('${0:field}')
snippet od
order('${0:field} DESC')
snippet pa
params[:${1:id}]
snippet ra
render action: '${0:action}'
snippet ral
render action: '${1:action}', layout: '${0:layoutname}'
snippet rest
respond_to do |format|
format.${1:html} { ${0} }
end
snippet rf
render file: '${0:filepath}'
snippet rfu
render file: '${1:filepath}', use_full_path: ${0:false}
snippet ri
render inline: "${0:<%= 'hello' %>}"
snippet ril
render inline: "${1:<%= 'hello' %>}", locals: { ${2:name}: '${3:value}'${0} }
snippet rit
render inline: "${1:<%= 'hello' %>}", type: ${0::rxml}
snippet rjson
render json: '${0:text to render}'
snippet rl
render layout: '${0:layoutname}'
snippet rn
render nothing: ${0:true}
snippet rns
render nothing: ${1:true}, status: ${0:401}
snippet rp
render partial: '${0:item}'
snippet rpc
render partial: '${1:item}', collection: ${0:@$1s}
snippet rpl
render partial: '${1:item}', locals: { ${2:$1}: ${0:@$1} }
snippet rpo
render partial: '${1:item}', object: ${0:@$1}
snippet rps
render partial: '${1:item}', status: ${0:500}
snippet rt
render text: '${0:text to render}'
snippet rtl
render text: '${1:text to render}', layout: '${0:layoutname}'
snippet rtlt
render text: '${1:text to render}', layout: ${0:true}
snippet rts
render text: '${1:text to render}', status: ${0:401}
snippet ru
render :update do |${1:page}|
$1.${0}
end
snippet rxml
render xml: '${0:text to render}'
snippet sc
scope :${1:name}, -> { where(${2:field}: ${0:value}) }
snippet sl
scope :${1:name}, lambda do |${2:value}|
where('${3:field = ?}', ${0:value})
end
snippet sha1
Digest::SHA1.hexdigest(${0:string})
snippet sweeper
class ${1:ModelClassName}Sweeper < ActionController::Caching::Sweeper
observe $1
def after_save(${0:model_class_name})
expire_cache($2)
end
def after_destroy($2)
expire_cache($2)
end
def expire_cache($2)
expire_page
end
end
snippet va validates_associated
validates_associated :${0:attribute}
snippet va validates .., acceptance: true
validates :${0:terms}, acceptance: true
snippet vc
validates :${0:attribute}, confirmation: true
snippet ve
validates :${1:attribute}, exclusion: { in: ${0:%w( mov avi )} }
snippet vf
validates :${1:attribute}, format: { with: /${0:regex}/ }
snippet vi
validates :${1:attribute}, inclusion: { in: %w(${0: mov avi }) }
snippet vl
validates :${1:attribute}, length: { in: ${2:3}..${0:20} }
snippet vn
validates :${0:attribute}, numericality: true
snippet vp
validates :${0:attribute}, presence: true
snippet vu
validates :${0:attribute}, uniqueness: true
snippet format
format.${1:js|xml|html} { ${0} }
snippet wc
where(${1:'conditions'}${0:, bind_var})
snippet wf
where(${1:field}: ${0:value})
snippet xdelete
xhr :delete, :${1:destroy}, id: ${2:1}
snippet xget
xhr :get, :${1:show}, id: ${2:1}
snippet xpost
xhr :post, :${1:create}, ${2:object}: ${3:object}
snippet xput
xhr :put, :${1:update}, id: ${2:1}, ${3:object}: ${4:object}
snippet test
test 'should ${1:do something}' do
${0}
end
###########################
# migrations snippets #
###########################
snippet mac
add_column :${1:table_name}, :${2:column_name}, :${0:data_type}
snippet mai
add_index :${1:table_name}, :${0:column_name}
snippet mrc
remove_column :${1:table_name}, :${0:column_name}
snippet mrnc
rename_column :${1:table_name}, :${2:old_column_name}, :${0:new_column_name}
snippet mcc
change_column :${1:table}, :${2:column}, :${0:type}
snippet mnc
t.${1:string} :${2:title}${3:, null: false}
snippet mct
create_table :${1:table_name} do |t|
${0}
end
snippet migration class .. < ActiveRecord::Migration .. def up .. def down .. end
class ${1:class_name} < ActiveRecord::Migration
def up
${0}
end
def down
end
end
snippet migration class .. < ActiveRecord::Migration .. def change .. end
class ${1:class_name} < ActiveRecord::Migration
def change
${0}
end
end
snippet trc
t.remove :${0:column}
snippet tre
t.rename :${1:old_column_name}, :${2:new_column_name}
${0}
snippet tref
t.references :${0:model}
snippet tcb
t.boolean :${1:title}
${0}
snippet tcbi
t.binary :${1:title}, limit: ${2:2}.megabytes
${0}
snippet tcd
t.decimal :${1:title}, precision: ${2:10}, scale: ${3:2}
${0}
snippet tcda
t.date :${1:title}
${0}
snippet tcdt
t.datetime :${1:title}
${0}
snippet tcf
t.float :${1:title}
${0}
snippet tch
t.change :${1:name}, :${2:string}, ${3:limit}: ${4:80}
${0}
snippet tci
t.integer :${1:title}
${0}
snippet tcl
t.integer :lock_version, null: false, default: 0
${0}
snippet tcr
t.references :${1:taggable}, polymorphic: { default: '${2:Photo}' }
${0}
snippet tcs
t.string :${1:title}
${0}
snippet tct
t.text :${1:title}
${0}
snippet tcti
t.time :${1:title}
${0}
snippet tcts
t.timestamp :${1:title}
${0}
snippet tctss
t.timestamps
${0}
##########################
# Rspec snippets #
##########################
#ShouldaMatchers#ActionController
snippet isfp
it { should filter_param :${0:key} }
snippet isrt
it { should redirect_to ${0:url} }
snippet isrtp
it { should render_template ${0} }
snippet isrwl
it { should render_with_layout ${0} }
snippet isrf
it { should rescue_from ${0:exception} }
snippet isrw
it { should respond_with ${0:status} }
snippet isr
it { should route(:${1:method}, '${0:path}') }
snippet isss
it { should set_session :${0:key} }
snippet issf
it { should set_the_flash('${0}') }
#ShouldaMatchers#ActiveModel
snippet isama
it { should allow_mass_assignment_of :${0} }
snippet isav
it { should allow_value(${1}).for :${0} }
snippet isee
it { should ensure_exclusion_of :${0} }
snippet isei
it { should ensure_inclusion_of :${0} }
snippet isel
it { should ensure_length_of :${0} }
snippet isva
it { should validate_acceptance_of :${0} }
snippet isvc
it { should validate_confirmation_of :${0} }
snippet isvn
it { should validate_numericality_of :${0} }
snippet isvp
it { should validate_presence_of :${0} }
snippet isvu
it { should validate_uniqueness_of :${0} }
#ShouldaMatchers#ActiveRecord
snippet isana
it { should accept_nested_attributes_for :${0} }
snippet isbt
it { should belong_to :${0} }
snippet isbtcc
it { should belong_to(:${1}).counter_cache ${0:true} }
snippet ishbtm
it { should have_and_belong_to_many :${0} }
snippet isbv
it { should be_valid }
snippet ishc
it { should have_db_column :${0} }
snippet ishi
it { should have_db_index :${0} }
snippet ishm
it { should have_many :${0} }
snippet ishmt
it { should have_many(:${1}).through :${0} }
snippet isho
it { should have_one :${0} }
snippet ishro
it { should have_readonly_attribute :${0} }
snippet iss
it { should serialize :${0} }
snippet isres
it { should respond_to :${0} }
snippet isresw
it { should respond_to(:${1}).with(${0}).arguments }
snippet super_call
${1:super_class}.instance_method(:${0:method}).bind(self).call

View file

@ -1,7 +1,3 @@
########################################
# Ruby snippets - for Rails, see below #
########################################
# encoding for Ruby 1.9 # encoding for Ruby 1.9
snippet enc snippet enc
# encoding: utf-8 # encoding: utf-8
@ -35,9 +31,9 @@ snippet beg
end end
snippet req require snippet req require
require "${1}" require '${1}'
snippet reqr snippet reqr
require_relative "${1}" require_relative '${1}'
snippet # snippet #
# => # =>
snippet end snippet end
@ -232,13 +228,13 @@ snippet array
snippet hash snippet hash
Hash.new { |${1:hash}, ${2:key}| $1[$2] = ${0} } Hash.new { |${1:hash}, ${2:key}| $1[$2] = ${0} }
snippet file File.foreach() { |line| .. } snippet file File.foreach() { |line| .. }
File.foreach(${1:"path/to/file"}) { |${2:line}| ${0} } File.foreach(${1:'path/to/file'}) { |${2:line}| ${0} }
snippet file File.read() snippet file File.read()
File.read(${1:"path/to/file"}) File.read(${1:'path/to/file'})
snippet Dir Dir.global() { |file| .. } snippet Dir Dir.global() { |file| .. }
Dir.glob(${1:"dir/glob/*"}) { |${2:file}| ${0} } Dir.glob(${1:'dir/glob/*'}) { |${2:file}| ${0} }
snippet Dir Dir[".."] snippet Dir Dir[".."]
Dir[${1:"glob/**/*.rb"}] Dir[${1:'glob/**/*.rb'}]
snippet dir snippet dir
Filename.dirname(__FILE__) Filename.dirname(__FILE__)
snippet deli snippet deli
@ -247,7 +243,7 @@ snippet fil
fill(${1:range}) { |${2:i}| ${0} } fill(${1:range}) { |${2:i}| ${0} }
# flatten_once() # flatten_once()
snippet flao snippet flao
inject(Array.new) { |${1:arr}, ${2:a}| $1.push(*$2)} reduce(Array.new) { |${1:arr}, ${2:a}| $1.push(*$2) }
snippet zip snippet zip
zip(${1:enums}) { |${2:row}| ${0} } zip(${1:enums}) { |${2:row}| ${0} }
# downto(0) { |n| .. } # downto(0) { |n| .. }
@ -419,6 +415,10 @@ snippet seld
end end
snippet lam snippet lam
lambda { |${1:args}| ${0} } lambda { |${1:args}| ${0} }
snippet ->
-> { ${0} }
snippet ->a
->(${1:args}) { ${0} }
# I'm pretty sure that ruby users expect do to expand to do .. end # I'm pretty sure that ruby users expect do to expand to do .. end
snippet do snippet do
do do
@ -432,12 +432,12 @@ snippet dov
${2} ${2}
end end
snippet : snippet :
:${1:key} => ${2:"value"} ${1:key}: ${2:'value'}
snippet ope snippet ope
open(${1:"path/or/url/or/pipe"}, "${2:w}") { |${3:io}| ${0} } open('${1:path/or/url/or/pipe}', '${2:w}') { |${3:io}| ${0} }
# path_from_here() # path_from_here()
snippet fpath snippet fpath
File.join(File.dirname(__FILE__), *%2[${1:rel path here}]) File.join(File.dirname(__FILE__), *['${1:rel path here}'])
# unix_filter {} # unix_filter {}
snippet unif snippet unif
ARGF.each_line${1} do |${2:line}| ARGF.each_line${1} do |${2:line}|
@ -445,21 +445,21 @@ snippet unif
end end
# option_parse {} # option_parse {}
snippet optp snippet optp
require "optparse" require 'optparse'
options = {${0:default => "args"}} options = { ${0:default: 'args'} }
ARGV.options do |opts| ARGV.options do |opts|
opts.banner = "Usage: #{File.basename($PROGRAM_NAME)} opts.banner = "Usage: #{File.basename($PROGRAM_NAME)}"
end
snippet opt snippet opt
opts.on( "-${1:o}", "--${2:long-option-name}", ${3:String}, opts.on('-${1:o}', '--${2:long-option-name}', ${3:String}, '${4:Option description.}') do |${5:opt}|
"${4:Option description.}") do |${5:opt}|
${0} ${0}
end end
snippet tc snippet tc
require "test/unit" require 'test/unit'
require "${1:library_file_name}" require '${1:library_file_name}'
class Test${2:$1} < Test::Unit::TestCase class Test${2:$1} < Test::Unit::TestCase
def test_${3:case_name} def test_${3:case_name}
@ -467,12 +467,12 @@ snippet tc
end end
end end
snippet ts snippet ts
require "test/unit" require 'test/unit'
require "tc_${1:test_case_file}" require 'tc_${1:test_case_file}'
require "tc_${2:test_case_file}" require 'tc_${2:test_case_file}'
snippet as snippet as
assert ${1:test}, "${2:Failure message.}" assert ${1:test}, '${2:Failure message.}'
snippet ase snippet ase
assert_equal ${1:expected}, ${2:actual} assert_equal ${1:expected}, ${2:actual}
snippet asne snippet asne
@ -490,9 +490,9 @@ snippet asn
snippet asnn snippet asnn
assert_not_nil ${1:instance} assert_not_nil ${1:instance}
snippet asm snippet asm
assert_match /${1:expected_pattern}/, ${2:actual_string} assert_match(/${1:expected_pattern}/, ${2:actual_string})
snippet asnm snippet asnm
assert_no_match /${1:unexpected_pattern}/, ${2:actual_string} assert_no_match(/${1:unexpected_pattern}/, ${2:actual_string})
snippet aso snippet aso
assert_operator ${1:left}, :${2:operator}, ${3:right} assert_operator ${1:left}, :${2:operator}, ${3:right}
snippet asr snippet asr
@ -516,7 +516,7 @@ snippet ass assert_send(..)
snippet asns snippet asns
assert_not_same ${1:unexpected}, ${2:actual} assert_not_same ${1:unexpected}, ${2:actual}
snippet ast snippet ast
assert_throws :${1:expected} { ${0} } assert_throws :${1:expected}, -> { ${0} }
snippet astd snippet astd
assert_throws :${1:expected} do assert_throws :${1:expected} do
${0} ${0}
@ -528,7 +528,7 @@ snippet asntd
${0} ${0}
end end
snippet fl snippet fl
flunk "${1:Failure message.}" flunk '${1:Failure message.}'
# Benchmark.bmbm do .. end # Benchmark.bmbm do .. end
snippet bm- snippet bm-
TESTS = ${1:10_000} TESTS = ${1:10_000}
@ -536,31 +536,31 @@ snippet bm-
${0} ${0}
end end
snippet rep snippet rep
results.report("${1:name}:") { TESTS.times { ${0} }} results.report('${1:name}:') { TESTS.times { ${0} } }
# Marshal.dump(.., file) # Marshal.dump(.., file)
snippet Md snippet Md
File.open(${1:"path/to/file.dump"}, "wb") { |${2:file}| Marshal.dump(${3:obj}, $2) } File.open('${1:path/to/file.dump}', 'wb') { |${2:file}| Marshal.dump(${3:obj}, $2) }
# Mashal.load(obj) # Mashal.load(obj)
snippet Ml snippet Ml
File.open(${1:"path/to/file.dump"}, "rb") { |${2:file}| Marshal.load($2) } File.open('${1:path/to/file.dump}', 'rb') { |${2:file}| Marshal.load($2) }
# deep_copy(..) # deep_copy(..)
snippet deec snippet deec
Marshal.load(Marshal.dump(${1:obj_to_copy})) Marshal.load(Marshal.dump(${1:obj_to_copy}))
snippet Pn- snippet Pn-
PStore.new(${1:"file_name.pstore"}) PStore.new('${1:file_name.pstore}')
snippet tra snippet tra
transaction(${1:true}) { ${0} } transaction(${1:true}) { ${0} }
# xmlread(..) # xmlread(..)
snippet xml- snippet xml-
REXML::Document.new(File.read(${1:"path/to/file"})) REXML::Document.new(File.read('${1:path/to/file}'))
# xpath(..) { .. } # xpath(..) { .. }
snippet xpa snippet xpa
elements.each(${1:"//Xpath"}) do |${2:node}| elements.each('${1://Xpath}') do |${2:node}|
${0} ${0}
end end
# class_from_name() # class_from_name()
snippet clafn snippet clafn
split("::").inject(Object) { |par, const| par.const_get(const) } split('::').inject(Object) { |par, const| par.const_get(const) }
# singleton_class() # singleton_class()
snippet sinc snippet sinc
class << self; self end class << self; self end
@ -569,8 +569,8 @@ snippet nam
${0} ${0}
end end
snippet tas snippet tas
desc "${1:Task description}" desc '${1:Task description}'
task :${2:task_name => [:dependent, :tasks]} do task ${2:task_name: [:dependent, :tasks]} do
${0} ${0}
end end
# block # block
@ -578,7 +578,7 @@ snippet b
{ |${1:var}| ${0} } { |${1:var}| ${0} }
snippet begin snippet begin
begin begin
raise 'A test exception.' fail 'A test exception.'
rescue Exception => e rescue Exception => e
puts e.message puts e.message
puts e.backtrace.inspect puts e.backtrace.inspect
@ -594,418 +594,68 @@ snippet debug
snippet pry snippet pry
require 'pry'; binding.pry require 'pry'; binding.pry
snippet strf snippet strf
strftime("${1:%Y-%m-%d %H:%M:%S %z}")${0} strftime('${1:%Y-%m-%d %H:%M:%S %z}')${0}
############################################# #
# Rails snippets - for pure Ruby, see above # # Minitest snippets
############################################# #
snippet art snippet mb
assert_redirected_to ${1::action => "${2:index}"} must_be ${0}
snippet artnp snippet wb
assert_redirected_to ${1:parent}_${2:child}_path(${3:@$1}, ${0:@$2}) wont_be ${0}
snippet artnpp snippet mbe
assert_redirected_to ${1:parent}_${2:child}_path(${0:@$1}) must_be_empty
snippet artp snippet wbe
assert_redirected_to ${1:model}_path(${0:@$1}) wont_be_empty
snippet artpp snippet mbio
assert_redirected_to ${0:model}s_path must_be_instance_of ${0:Class}
snippet asd snippet wbio
assert_difference "${1:Model}.${2:count}", ${3:1} do wont_be_instance_of ${0:Class}
${0} snippet mbko
end must_be_kind_of ${0:Class}
snippet asnd snippet wbko
assert_no_difference "${1:Model}.${2:count}" do wont_be_kind_of ${0:Class}
${0} snippet mbn
end must_be_nil
snippet asre snippet wbn
assert_response :${1:success}, @response.body wont_be_nil
snippet asrj snippet mbsa
assert_rjs :${1:replace}, "${0:dom id}" must_be_same_as ${0:other}
snippet ass assert_select(..) snippet wbsa
assert_select '${1:path}', :${2:text} => '${3:inner_html' ${4:do} wont_be_same_as ${0:other}
snippet ba snippet mbsi
before_action :${0:method} -> { ${0} }.must_be_silent
snippet bf snippet mbwd
before_filter :${0:method} must_be_within_delta ${1:0.1}, ${2:0.1}
snippet bt snippet wbwd
belongs_to :${0:association} wont_be_within_delta ${1:0.1}, ${2:0.1}
snippet btp snippet mbwe
belongs_to :${1:association}, :polymorphic => true must_be_within_epsilon ${1:0.1}, ${2:0.1}
snippet crw snippet wbwe
cattr_accessor :${0:attr_names} wont_be_within_epsilon ${1:0.1}, ${2:0.1}
snippet defcreate snippet me
def create must_equal ${0:other}
@${1:model_class_name} = ${2:ModelClassName}.new(params[:$1]) snippet we
wont_equal ${0:other}
respond_to do |format| snippet mi
if @$1.save must_include ${0:what}
flash[:notice] = '$2 was successfully created.' snippet wi
format.html { redirect_to(@$1) } wont_include ${0:what}
format.xml { render :xml => @$1, :status => :created, :location => @$1 } snippet mm
else must_match /${0:regex}/
format.html { render :action => "new" } snippet wm
format.xml { render :xml => @$1.errors, :status => :unprocessable_entity } wont_match /${0:regex}/
end snippet mout
end -> { ${1} }.must_output '${0}'
end snippet mra
snippet defdestroy -> { ${1} }.must_raise ${0:Exception}
def destroy snippet mrt
@${1:model_class_name} = ${2:ModelClassName}.find(params[:id]) must_respond_to :${0:method}
@$1.destroy snippet wrt
wont_respond_to :${0:method}
respond_to do |format| snippet msend
format.html { redirect_to($1s_url) } must_send [ ${1:what}, :${2:method}, ${3:args} ]
format.xml { head :ok } snippet mthrow
end -> { throw :${1:error} }.must_throw :${2:error}
end
snippet defedit
def edit
@${1:model_class_name} = ${0:ModelClassName}.find(params[:id])
end
snippet defindex
def index
@${1:model_class_name} = ${2:ModelClassName}.all
respond_to do |format|
format.html # index.html.erb
format.xml { render :xml => @$1s }
end
end
snippet defnew
def new
@${1:model_class_name} = ${2:ModelClassName}.new
respond_to do |format|
format.html # new.html.erb
format.xml { render :xml => @$1 }
end
end
snippet defshow
def show
@${1:model_class_name} = ${2:ModelClassName}.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.xml { render :xml => @$1 }
end
end
snippet defupdate
def update
@${1:model_class_name} = ${2:ModelClassName}.find(params[:id])
respond_to do |format|
if @$1.update_attributes(params[:$1])
flash[:notice] = '$2 was successfully updated.'
format.html { redirect_to(@$1) }
format.xml { head :ok }
else
format.html { render :action => "edit" }
format.xml { render :xml => @$1.errors, :status => :unprocessable_entity }
end
end
end
snippet dele delegate .. to
delegate :${1:methods}, :to => :${0:object}
snippet dele delegate .. to .. prefix .. allow_nil
delegate :${1:methods}, :to => :${2:object}, :prefix => :${3:prefix}, :allow_nil => ${0:allow_nil}
snippet flash
flash[:${1:notice}] = "${0}"
snippet habtm
has_and_belongs_to_many :${1:object}, :join_table => "${2:table_name}", :foreign_key => "${3}_id"
snippet hm
has_many :${0:object}
snippet hmd
has_many :${1:other}s, :class_name => "${2:$1}", :foreign_key => "${3:$1}_id", :dependent => :destroy
snippet hmt
has_many :${1:object}, :through => :${0:object}
snippet ho
has_one :${0:object}
snippet hod
has_one :${1:object}, dependent: :${0:destroy}
snippet i18
I18n.t('${1:type.key}')
snippet ist
<%= image_submit_tag("${1:agree.png}", :id => "${2:id}"${0} %>
snippet log
Rails.logger.${1:debug} ${0}
snippet log2
RAILS_DEFAULT_LOGGER.${1:debug} ${0}
snippet logd
logger.debug { "${1:message}" }
snippet loge
logger.error { "${1:message}" }
snippet logf
logger.fatal { "${1:message}" }
snippet logi
logger.info { "${1:message}" }
snippet logw
logger.warn { "${1:message}" }
snippet mapc
${1:map}.${2:connect} '${0:controller/:action/:id}'
snippet mapca
${1:map}.catch_all "*${2:anything}", :controller => "${3:default}", :action => "${4:error}"
snippet mapr
${1:map}.resource :${0:resource}
snippet maprs
${1:map}.resources :${0:resource}
snippet mapwo
${1:map}.with_options :${2:controller} => '${3:thing}' do |$3|
${0}
end
###############################
# model callback snippets #
###############################
# before callback
snippet mbv
before_validation :${0:method}
snippet mbc
before_create :${0:method}
snippet mbu
before_update :${0:method}
snippet mbs
before_save :${0:method}
snippet mbd
before_destroy :${0:method}
# after callback
snippet mav
after_validation :${0:method}
snippet maf
after_find :${0:method}
snippet mat
after_touch :${0:method}
snippet macr
after_create :${0:method}
snippet mau
after_update :${0:method}
snippet mas
after_save :${0:method}
snippet mad
after_destroy :${0:method}
# around callback
snippet marc
around_create :${0:method}
snippet maru
around_update :${0:method}
snippet mars
around_save :${0:method}
snippet mard
around_destroy :${0:method}
snippet mcht
change_table :${1:table_name} do |t|
${0}
end
snippet mp
map(&:${0:id})
snippet mrw
mattr_accessor :${0:attr_names}
snippet oa
order("${0:field}")
snippet od
order("${0:field} DESC")
snippet pa
params[:${1:id}]
snippet ra
render :action => "${0:action}"
snippet ral
render :action => "${1:action}", :layout => "${0:layoutname}"
snippet rest
respond_to do |format|
format.${1:html} { ${0} }
end
snippet rf
render :file => "${0:filepath}"
snippet rfu
render :file => "${1:filepath}", :use_full_path => ${0:false}
snippet ri
render :inline => "${0:<%= 'hello' %>}"
snippet ril
render :inline => "${1:<%= 'hello' %>}", :locals => { ${2::name} => "${3:value}"${0} }
snippet rit
render :inline => "${1:<%= 'hello' %>}", :type => ${0::rxml}
snippet rjson
render :json => ${0:text to render}
snippet rl
render :layout => "${0:layoutname}"
snippet rn
render :nothing => ${0:true}
snippet rns
render :nothing => ${1:true}, :status => ${0:401}
snippet rp
render :partial => "${0:item}"
snippet rpc
render :partial => "${1:item}", :collection => ${0:@$1s}
snippet rpl
render :partial => "${1:item}", :locals => { :${2:$1} => ${0:@$1}
snippet rpo
render :partial => "${1:item}", :object => ${0:@$1}
snippet rps
render :partial => "${1:item}", :status => ${0:500}
snippet rt
render :text => "${0:text to render}"
snippet rtl
render :text => "${1:text to render}", :layout => "${0:layoutname}"
snippet rtlt
render :text => "${1:text to render}", :layout => ${0:true}
snippet rts
render :text => "${1:text to render}", :status => ${0:401}
snippet ru
render :update do |${1:page}|
$1.${0}
end
snippet rxml
render :xml => ${0:text to render}
snippet sc
scope :${1:name}, -> { where(${2:field}: ${0:value}) }
snippet sl
scope :${1:name}, lambda do |${2:value}|
where("${3:field = ?}", ${0:bind var})
end
snippet sha1
Digest::SHA1.hexdigest(${0:string})
snippet sweeper
class ${1:ModelClassName}Sweeper < ActionController::Caching::Sweeper
observe $1
def after_save(${0:model_class_name})
expire_cache($2)
end
def after_destroy($2)
expire_cache($2)
end
def expire_cache($2)
expire_page
end
end
snippet va validates_associated
validates_associated :${0:attribute}
snippet va validates .., :acceptance => true
validates :${0:terms}, :acceptance => true
snippet vc
validates :${0:attribute}, :confirmation => true
snippet ve
validates :${1:attribute}, :exclusion => { :in => ${0:%w( mov avi )} }
snippet vf
validates :${1:attribute}, :format => { :with => /${0:regex}/ }
snippet vi
validates :${1:attribute}, :inclusion => { :in => %w(${0: mov avi }) }
snippet vl
validates :${1:attribute}, :length => { :in => ${2:3}..${0:20} }
snippet vn
validates :${0:attribute}, :numericality => true
snippet vp
validates :${0:attribute}, :presence => true
snippet vu
validates :${0:attribute}, :uniqueness => true
snippet format
format.${1:js|xml|html} { ${0} }
snippet wc
where(${1:"conditions"}${0:, bind_var})
snippet wf
where(${1:field} => ${0:value})
snippet xdelete
xhr :delete, :${1:destroy}, :id => ${2:1}
snippet xget
xhr :get, :${1:show}, :id => ${2:1}
snippet xpost
xhr :post, :${1:create}, :${2:object} => { ${0} }
snippet xput
xhr :put, :${1:update}, :id => ${2:1}, :${3:object} => { ${4} }
snippet test
test "should ${1:do something}" do
${0}
end
###########################
# migrations snippets #
###########################
snippet mac
add_column :${1:table_name}, :${2:column_name}, :${0:data_type}
snippet mai
add_index :${1:table_name}, :${0:column_name}
snippet mrc
remove_column :${1:table_name}, :${0:column_name}
snippet mrnc
rename_column :${1:table_name}, :${2:old_column_name}, :${0:new_column_name}
snippet mcc
change_column :${1:table}, :${2:column}, :${0:type}
snippet mnc
t.${1:string} :${2:title}${3:, null: false}
snippet mct
create_table :${1:table_name} do |t|
${0}
end
snippet migration class .. < ActiveRecord::Migration .. def up .. def down .. end
class ${1:class_name} < ActiveRecord::Migration
def up
${0}
end
def down
end
end
snippet migration class .. < ActiveRecord::Migration .. def change .. end
class ${1:class_name} < ActiveRecord::Migration
def change
${0}
end
end
snippet trc
t.remove :${0:column}
snippet tre
t.rename :${1:old_column_name}, :${2:new_column_name}
${0}
snippet tref
t.references :${0:model}
snippet tcb
t.boolean :${1:title}
${0}
snippet tcbi
t.binary :${1:title}, :limit => ${2:2}.megabytes
${0}
snippet tcd
t.decimal :${1:title}, :precision => ${2:10}, :scale => ${3:2}
${0}
snippet tcda
t.date :${1:title}
${0}
snippet tcdt
t.datetime :${1:title}
${0}
snippet tcf
t.float :${1:title}
${0}
snippet tch
t.change :${1:name}, :${2:string}, :${3:limit} => ${4:80}
${0}
snippet tci
t.integer :${1:title}
${0}
snippet tcl
t.integer :lock_version, :null => false, :default => 0
${0}
snippet tcr
t.references :${1:taggable}, :polymorphic => { :default => '${2:Photo}' }
${0}
snippet tcs
t.string :${1:title}
${0}
snippet tct
t.text :${1:title}
${0}
snippet tcti
t.time :${1:title}
${0}
snippet tcts
t.timestamp :${1:title}
${0}
snippet tctss
t.timestamps
${0}
########################## ##########################
# Rspec snippets # # Rspec snippets #
########################## ##########################
@ -1014,11 +664,11 @@ snippet desc
${0} ${0}
end end
snippet descm snippet descm
describe "${1:#method}" do describe '${1:#method}' do
${0:pending "Not implemented"} ${0:pending 'Not implemented'}
end end
snippet cont snippet cont
context "${1:message}" do context '${1:message}' do
${0} ${0}
end end
snippet bef snippet bef
@ -1046,11 +696,11 @@ snippet expb
snippet experr snippet experr
expect { ${1:object} }.to raise_error ${2:StandardError}, /${0:message_regex}/ expect { ${1:object} }.to raise_error ${2:StandardError}, /${0:message_regex}/
snippet shared snippet shared
shared_examples ${0:"shared examples name"} shared_examples ${0:'shared examples name'}
snippet ibl snippet ibl
it_behaves_like ${0:"shared examples name"} it_behaves_like ${0:'shared examples name'}
snippet it snippet it
it "${1:spec_name}" do it '${1:spec_name}' do
${0} ${0}
end end
snippet its snippet its
@ -1059,74 +709,3 @@ snippet is
it { should ${0} } it { should ${0} }
snippet isn snippet isn
it { should_not ${0} } it { should_not ${0} }
#ShouldaMatchers#ActionController
snippet isfp
it { should filter_param :${0:key} }
snippet isrt
it { should redirect_to ${0:url} }
snippet isrtp
it { should render_template ${0} }
snippet isrwl
it { should render_with_layout ${0} }
snippet isrf
it { should rescue_from ${0:exception} }
snippet isrw
it { should respond_with ${0:status} }
snippet isr
it { should route(:${1:method}, '${0:path}') }
snippet isss
it { should set_session :${0:key} }
snippet issf
it { should set_the_flash('${0}') }
#ShouldaMatchers#ActiveModel
snippet isama
it { should allow_mass_assignment_of :${0} }
snippet isav
it { should allow_value(${1}).for :${0} }
snippet isee
it { should ensure_exclusion_of :${0} }
snippet isei
it { should ensure_inclusion_of :${0} }
snippet isel
it { should ensure_length_of :${0} }
snippet isva
it { should validate_acceptance_of :${0} }
snippet isvc
it { should validate_confirmation_of :${0} }
snippet isvn
it { should validate_numericality_of :${0} }
snippet isvp
it { should validate_presence_of :${0} }
snippet isvu
it { should validate_uniqueness_of :${0} }
#ShouldaMatchers#ActiveRecord
snippet isana
it { should accept_nested_attributes_for :${0} }
snippet isbt
it { should belong_to :${0} }
snippet isbtcc
it { should belong_to(:${1}).counter_cache ${0:true} }
snippet ishbtm
it { should have_and_belong_to_many :${0} }
snippet isbv
it { should be_valid }
snippet ishc
it { should have_db_column :${0} }
snippet ishi
it { should have_db_index :${0} }
snippet ishm
it { should have_many :${0} }
snippet ishmt
it { should have_many(:${1}).through :${0} }
snippet isho
it { should have_one :${0} }
snippet ishro
it { should have_readonly_attribute :${0} }
snippet iss
it { should serialize :${0} }
snippet isres
it { should respond_to :${0} }
snippet isresw
it { should respond_to(:${1}).with(${0}).arguments }
snippet super_call
${1:super_class}.instance_method(:${0:method}).bind(self).call

View file

@ -1,7 +1,7 @@
#PREAMBLE #PREAMBLE
#newcommand #newcommand
snippet nc \newcommand snippet nc \newcommand
\newcommand{\${1:cmd}}[${2:opt}]{${3:realcmd}} ${0} \newcommand{\\${1:cmd}}[${2:opt}]{${3:realcmd}} ${0}
#usepackage #usepackage
snippet up \usepackage snippet up \usepackage
\usepackage[${1:options}]{${2:package}} ${0} \usepackage[${1:options}]{${2:package}} ${0}

View file

@ -416,7 +416,7 @@ function! s:dosurround(...) " {{{1
exe 'norm! df'.char exe 'norm! df'.char
else else
" One character backwards " One character backwards
call search('.','bW') call search('\m.', 'bW')
exe "norm! da".char exe "norm! da".char
endif endif
let removed = getreg('"') let removed = getreg('"')

View file

@ -26,7 +26,7 @@ au FileType javascript call JavaScriptFold()
au FileType javascript setl fen au FileType javascript setl fen
au FileType javascript setl nocindent au FileType javascript setl nocindent
au FileType javascript imap <c-t> AJS.log();<esc>hi au FileType javascript imap <c-t> $log();<esc>hi
au FileType javascript imap <c-a> alert();<esc>hi au FileType javascript imap <c-a> alert();<esc>hi
au FileType javascript inoremap <buffer> $r return au FileType javascript inoremap <buffer> $r return