settings

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

commit fd19d3a930840644556d8f8aee87f201bef9e7f4
parent a82180edd495693ff28015a6be553c151ba411d5
Author: Paul Longtine <paul@nanner.co>
Date:   Thu Jul  2 22:56:58 2015

made vim more useable

Diffstat:
 vim/.vim/.netrwhist                        |   5 +-
 vim/.vim/autoload/nerdtree.vim             | 147 ++++++-
 vim/.vim/autoload/nerdtree/ui_glue.vim     | 644 +++++++++++++++++++++++++-
 vim/.vim/lib/nerdtree/bookmark.vim         | 319 ++++++++++++-
 vim/.vim/lib/nerdtree/creator.vim          | 362 ++++++++++++++-
 vim/.vim/lib/nerdtree/event.vim            |  13 +-
 vim/.vim/lib/nerdtree/flag_set.vim         |  56 ++-
 vim/.vim/lib/nerdtree/key_map.vim          | 159 ++++++-
 vim/.vim/lib/nerdtree/menu_controller.vim  | 180 +++++++-
 vim/.vim/lib/nerdtree/menu_item.vim        | 114 ++++-
 vim/.vim/lib/nerdtree/nerdtree.vim         | 137 +++++-
 vim/.vim/lib/nerdtree/notifier.vim         |  35 +-
 vim/.vim/lib/nerdtree/opener.vim           | 352 +++++++++++++-
 vim/.vim/lib/nerdtree/path.vim             | 785 ++++++++++++++++++++++++++++++-
 vim/.vim/lib/nerdtree/tree_dir_node.vim    | 551 +++++++++++++++++++++-
 vim/.vim/lib/nerdtree/tree_file_node.vim   | 431 ++++++++++++++++-
 vim/.vim/lib/nerdtree/ui.vim               | 506 +++++++++++++++++++-
 vim/.vim/nerdtree_plugin/exec_menuitem.vim |  41 ++-
 vim/.vim/nerdtree_plugin/fs_menu.vim       | 270 ++++++++++-
 vim/.vim/plugin/NERD_tree.vim              | 210 ++++++++-
 vim/.vim/syntax/nerdtree.vim               | 105 ++++-
 vim/.vimrc                                 |   9 +-
 22 files changed, 5428 insertions(+), 3 deletions(-)

diff --git a/vim/.vim/.netrwhist b/vim/.vim/.netrwhist @@ -1,3 +1,6 @@ let g:netrw_dirhistmax =10 -let g:netrw_dirhist_cnt =1 +let g:netrw_dirhist_cnt =4 let g:netrw_dirhist_1='/home/paul/.vim' +let g:netrw_dirhist_2='/home/paul/src/pnbp/src' +let g:netrw_dirhist_3='/home/paul/.config' +let g:netrw_dirhist_4='/home/paul/.irssi' diff --git a/vim/.vim/autoload/nerdtree.vim b/vim/.vim/autoload/nerdtree.vim @@ -0,0 +1,147 @@ +if exists("g:loaded_nerdtree_autoload") + finish +endif +let g:loaded_nerdtree_autoload = 1 + +function! nerdtree#version() + return '4.2.0' +endfunction + +" SECTION: General Functions {{{1 +"============================================================ + +"FUNCTION: nerdtree#checkForBrowse(dir) {{{2 +"inits a secondary nerd tree in the current buffer if appropriate +function! nerdtree#checkForBrowse(dir) + if a:dir != '' && isdirectory(a:dir) + call g:NERDTreeCreator.CreateSecondary(a:dir) + endif +endfunction + +" FUNCTION: nerdtree#completeBookmarks(A,L,P) {{{2 +" completion function for the bookmark commands +function! nerdtree#completeBookmarks(A,L,P) + return filter(g:NERDTreeBookmark.BookmarkNames(), 'v:val =~# "^' . a:A . '"') +endfunction + +"FUNCTION: nerdtree#compareBookmarks(dir) {{{2 +function! nerdtree#compareBookmarks(first, second) + return a:first.compareTo(a:second) +endfunction + +"FUNCTION: nerdtree#compareNodes(dir) {{{2 +function! nerdtree#compareNodes(n1, n2) + return a:n1.path.compareTo(a:n2.path) +endfunction + +"FUNCTION: nerdtree#compareNodesBySortKey(n1, n2) {{{2 +function! nerdtree#compareNodesBySortKey(n1, n2) + if a:n1.path.getSortKey() < a:n2.path.getSortKey() + return -1 + elseif a:n1.path.getSortKey() > a:n2.path.getSortKey() + return 1 + else + return 0 + endif +endfunction + +" FUNCTION: nerdtree#deprecated(func, [msg]) {{{2 +" Issue a deprecation warning for a:func. If a second arg is given, use this +" as the deprecation message +function! nerdtree#deprecated(func, ...) + let msg = a:0 ? a:func . ' ' . a:1 : a:func . ' is deprecated' + + if !exists('s:deprecationWarnings') + let s:deprecationWarnings = {} + endif + if !has_key(s:deprecationWarnings, a:func) + let s:deprecationWarnings[a:func] = 1 + echomsg msg + endif +endfunction + +" FUNCTION: nerdtree#exec(cmd) {{{2 +" same as :exec cmd but eventignore=all is set for the duration +function! nerdtree#exec(cmd) + let old_ei = &ei + set ei=all + exec a:cmd + let &ei = old_ei +endfunction + +" FUNCTION: nerdtree#has_opt(options, name) {{{2 +function! nerdtree#has_opt(options, name) + return has_key(a:options, a:name) && a:options[a:name] == 1 +endfunction + +" FUNCTION: nerdtree#loadClassFiles() {{{2 +function! nerdtree#loadClassFiles() + runtime lib/nerdtree/path.vim + runtime lib/nerdtree/menu_controller.vim + runtime lib/nerdtree/menu_item.vim + runtime lib/nerdtree/key_map.vim + runtime lib/nerdtree/bookmark.vim + runtime lib/nerdtree/tree_file_node.vim + runtime lib/nerdtree/tree_dir_node.vim + runtime lib/nerdtree/opener.vim + runtime lib/nerdtree/creator.vim + runtime lib/nerdtree/flag_set.vim + runtime lib/nerdtree/nerdtree.vim + runtime lib/nerdtree/ui.vim + runtime lib/nerdtree/event.vim + runtime lib/nerdtree/notifier.vim +endfunction + +" FUNCTION: nerdtree#postSourceActions() {{{2 +function! nerdtree#postSourceActions() + call g:NERDTreeBookmark.CacheBookmarks(0) + call nerdtree#ui_glue#createDefaultBindings() + + "load all nerdtree plugins + runtime! nerdtree_plugin/**/*.vim +endfunction + +"FUNCTION: nerdtree#runningWindows(dir) {{{2 +function! nerdtree#runningWindows() + return has("win16") || has("win32") || has("win64") +endfunction + +" SECTION: View Functions {{{1 +"============================================================ + +"FUNCTION: nerdtree#echo {{{2 +"A wrapper for :echo. Appends 'NERDTree:' on the front of all messages +" +"Args: +"msg: the message to echo +function! nerdtree#echo(msg) + redraw + echomsg "NERDTree: " . a:msg +endfunction + +"FUNCTION: nerdtree#echoError {{{2 +"Wrapper for nerdtree#echo, sets the message type to errormsg for this message +"Args: +"msg: the message to echo +function! nerdtree#echoError(msg) + echohl errormsg + call nerdtree#echo(a:msg) + echohl normal +endfunction + +"FUNCTION: nerdtree#echoWarning {{{2 +"Wrapper for nerdtree#echo, sets the message type to warningmsg for this message +"Args: +"msg: the message to echo +function! nerdtree#echoWarning(msg) + echohl warningmsg + call nerdtree#echo(a:msg) + echohl normal +endfunction + +"FUNCTION: nerdtree#renderView {{{2 +function! nerdtree#renderView() + call b:NERDTree.render() +endfunction + +" vim: set sw=4 sts=4 et fdm=marker: diff --git a/vim/.vim/autoload/nerdtree/ui_glue.vim b/vim/.vim/autoload/nerdtree/ui_glue.vim @@ -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(".") ==# g:NERDTreeUI.UpDirLine() + 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() +endfunction + +"FUNCTION: s:activateFileNode() {{{1 +"handle the user activating a tree node +function! s:activateFileNode(node) + call a:node.activate({'reuse': 'all', '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 g:NERDTree.Close() + 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 !g:NERDTree.IsOpen() + call g:NERDTreeCreator.TogglePrimary('') + else + call g:NERDTree.CursorToTreeWin() + endif + let b:NERDTreeShowHidden = g:NERDTreeShowHidden + call s:chRoot(g:NERDTreeDirNode.New(p.getParent())) + else + if !g:NERDTree.IsOpen() + call g:NERDTreeCreator.TogglePrimary("") + endif + endif + endif + call g:NERDTree.CursorToTreeWin() + 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 =~# g:NERDTreeUI.MarkupReg() && 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 !~# g:NERDTreeUI.MarkupReg() + if currentNode.path.isDirectory + call currentNode.activate() + else + call currentNode.activate({'reuse': 'all', '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 g:NERDTree.Close() + 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: diff --git a/vim/.vim/lib/nerdtree/bookmark.vim b/vim/.vim/lib/nerdtree/bookmark.vim @@ -0,0 +1,319 @@ +"CLASS: Bookmark +"============================================================ +let s:Bookmark = {} +let g:NERDTreeBookmark = s:Bookmark + +" FUNCTION: Bookmark.activate() {{{1 +function! s:Bookmark.activate(...) + call self.open(a:0 ? a:1 : {}) +endfunction + +" FUNCTION: Bookmark.AddBookmark(name, path) {{{1 +" Class method to add a new bookmark to the list, if a previous bookmark exists +" with the same name, just update the path for that bookmark +function! s:Bookmark.AddBookmark(name, path) + for i in s:Bookmark.Bookmarks() + if i.name ==# a:name + let i.path = a:path + return + endif + endfor + call add(s:Bookmark.Bookmarks(), s:Bookmark.New(a:name, a:path)) + if g:NERDTreeBookmarksSort ==# 1 + call s:Bookmark.Sort() + endif +endfunction + +" FUNCTION: Bookmark.Bookmarks() {{{1 +" Class method to get all bookmarks. Lazily initializes the bookmarks global +" variable +function! s:Bookmark.Bookmarks() + if !exists("g:NERDTreeBookmarks") + let g:NERDTreeBookmarks = [] + endif + return g:NERDTreeBookmarks +endfunction + +" FUNCTION: Bookmark.BookmarkExistsFor(name) {{{1 +" class method that returns 1 if a bookmark with the given name is found, 0 +" otherwise +function! s:Bookmark.BookmarkExistsFor(name) + try + call s:Bookmark.BookmarkFor(a:name) + return 1 + catch /^NERDTree.BookmarkNotFoundError/ + return 0 + endtry +endfunction + +" FUNCTION: Bookmark.BookmarkFor(name) {{{1 +" Class method to get the bookmark that has the given name. {} is return if no +" bookmark is found +function! s:Bookmark.BookmarkFor(name) + for i in s:Bookmark.Bookmarks() + if i.name ==# a:name + return i + endif + endfor + throw "NERDTree.BookmarkNotFoundError: no bookmark found for name: \"". a:name .'"' +endfunction + +" FUNCTION: Bookmark.BookmarkNames() {{{1 +" Class method to return an array of all bookmark names +function! s:Bookmark.BookmarkNames() + let names = [] + for i in s:Bookmark.Bookmarks() + call add(names, i.name) + endfor + return names +endfunction + +" FUNCTION: Bookmark.CacheBookmarks(silent) {{{1 +" Class method to read all bookmarks from the bookmarks file initialize +" bookmark objects for each one. +" +" Args: +" silent - dont echo an error msg if invalid bookmarks are found +function! s:Bookmark.CacheBookmarks(silent) + if filereadable(g:NERDTreeBookmarksFile) + let g:NERDTreeBookmarks = [] + let g:NERDTreeInvalidBookmarks = [] + let bookmarkStrings = readfile(g:NERDTreeBookmarksFile) + let invalidBookmarksFound = 0 + for i in bookmarkStrings + + "ignore blank lines + if i != '' + + let name = substitute(i, '^\(.\{-}\) .*$', '\1', '') + let path = substitute(i, '^.\{-} \(.*\)$', '\1', '') + + try + let bookmark = s:Bookmark.New(name, g:NERDTreePath.New(path)) + call add(g:NERDTreeBookmarks, bookmark) + catch /^NERDTree.InvalidArgumentsError/ + call add(g:NERDTreeInvalidBookmarks, i) + let invalidBookmarksFound += 1 + endtry + endif + endfor + if invalidBookmarksFound + call s:Bookmark.Write() + if !a:silent + call nerdtree#echo(invalidBookmarksFound . " invalid bookmarks were read. See :help NERDTreeInvalidBookmarks for info.") + endif + endif + if g:NERDTreeBookmarksSort ==# 1 + call s:Bookmark.Sort() + endif + endif +endfunction + +" FUNCTION: Bookmark.compareTo(otherbookmark) {{{1 +" Compare these two bookmarks for sorting purposes +function! s:Bookmark.compareTo(otherbookmark) + return a:otherbookmark.name < self.name +endfunction +" FUNCTION: Bookmark.ClearAll() {{{1 +" Class method to delete all bookmarks. +function! s:Bookmark.ClearAll() + for i in s:Bookmark.Bookmarks() + call i.delete() + endfor + call s:Bookmark.Write() +endfunction + +" FUNCTION: Bookmark.delete() {{{1 +" Delete this bookmark. If the node for this bookmark is under the current +" root, then recache bookmarks for its Path object +function! s:Bookmark.delete() + let node = {} + try + let node = self.getNode(1) + catch /^NERDTree.BookmarkedNodeNotFoundError/ + endtry + call remove(s:Bookmark.Bookmarks(), index(s:Bookmark.Bookmarks(), self)) + if !empty(node) + call node.path.cacheDisplayString() + endif + call s:Bookmark.Write() +endfunction + +" FUNCTION: Bookmark.getNode(searchFromAbsoluteRoot) {{{1 +" Gets the treenode for this bookmark +" +" Args: +" searchFromAbsoluteRoot: specifies whether we should search from the current +" tree root, or the highest cached node +function! s:Bookmark.getNode(searchFromAbsoluteRoot) + let searchRoot = a:searchFromAbsoluteRoot ? g:NERDTreeDirNode.AbsoluteTreeRoot() : b:NERDTreeRoot + let targetNode = searchRoot.findNode(self.path) + if empty(targetNode) + throw "NERDTree.BookmarkedNodeNotFoundError: no node was found for bookmark: " . self.name + endif + return targetNode +endfunction + +" FUNCTION: Bookmark.GetNodeForName(name, searchFromAbsoluteRoot) {{{1 +" Class method that finds the bookmark with the given name and returns the +" treenode for it. +function! s:Bookmark.GetNodeForName(name, searchFromAbsoluteRoot) + let bookmark = s:Bookmark.BookmarkFor(a:name) + return bookmark.getNode(a:searchFromAbsoluteRoot) +endfunction + +" FUNCTION: Bookmark.GetSelected() {{{1 +" returns the Bookmark the cursor is over, or {} +function! s:Bookmark.GetSelected() + let line = getline(".") + let name = substitute(line, '^>\(.\{-}\) .\+$', '\1', '') + if name != line + try + return s:Bookmark.BookmarkFor(name) + catch /^NERDTree.BookmarkNotFoundError/ + return {} + endtry + endif + return {} +endfunction + +" FUNCTION: Bookmark.InvalidBookmarks() {{{1 +" Class method to get all invalid bookmark strings read from the bookmarks +" file +function! s:Bookmark.InvalidBookmarks() + if !exists("g:NERDTreeInvalidBookmarks") + let g:NERDTreeInvalidBookmarks = [] + endif + return g:NERDTreeInvalidBookmarks +endfunction + +" FUNCTION: Bookmark.mustExist() {{{1 +function! s:Bookmark.mustExist() + if !self.path.exists() + call s:Bookmark.CacheBookmarks(1) + throw "NERDTree.BookmarkPointsToInvalidLocationError: the bookmark \"". + \ self.name ."\" points to a non existing location: \"". self.path.str() + endif +endfunction + +" FUNCTION: Bookmark.New(name, path) {{{1 +" Create a new bookmark object with the given name and path object +function! s:Bookmark.New(name, path) + if a:name =~# ' ' + throw "NERDTree.IllegalBookmarkNameError: illegal name:" . a:name + endif + + let newBookmark = copy(self) + let newBookmark.name = a:name + let newBookmark.path = a:path + return newBookmark +endfunction + +" FUNCTION: Bookmark.open([options]) {{{1 +"Args: +"A dictionary containing the following keys (all optional): +" 'where': Specifies whether the node should be opened in new split/tab or in +" the previous window. Can be either 'v' (vertical split), 'h' +" (horizontal split), 't' (new tab) or 'p' (previous window). +" 'reuse': if a window is displaying the file then jump the cursor there +" 'keepopen': dont close the tree window +" 'stay': open the file, but keep the cursor in the tree win +" +function! s:Bookmark.open(...) + let opts = a:0 ? a:1 : {} + + if self.path.isDirectory && !has_key(opts, 'where') + call self.toRoot() + else + let opener = g:NERDTreeOpener.New(self.path, opts) + call opener.open(self) + endif +endfunction + +" FUNCTION: Bookmark.openInNewTab(options) {{{1 +" Create a new bookmark object with the given name and path object +function! s:Bookmark.openInNewTab(options) + call nerdtree#deprecated('Bookmark.openInNewTab', 'is deprecated, use open() instead') + call self.open(a:options) +endfunction + +" FUNCTION: Bookmark.setPath(path) {{{1 +" makes this bookmark point to the given path +function! s:Bookmark.setPath(path) + let self.path = a:path +endfunction + +" FUNCTION: Bookmark.Sort() {{{1 +" Class method that sorts all bookmarks +function! s:Bookmark.Sort() + let CompareFunc = function("nerdtree#compareBookmarks") + call sort(s:Bookmark.Bookmarks(), CompareFunc) +endfunction + +" FUNCTION: Bookmark.str() {{{1 +" Get the string that should be rendered in the view for this bookmark +function! s:Bookmark.str() + let pathStrMaxLen = winwidth(g:NERDTree.GetWinNum()) - 4 - len(self.name) + if &nu + let pathStrMaxLen = pathStrMaxLen - &numberwidth + endif + + let pathStr = self.path.str({'format': 'UI'}) + if len(pathStr) > pathStrMaxLen + let pathStr = '<' . strpart(pathStr, len(pathStr) - pathStrMaxLen) + endif + return '>' . self.name . ' ' . pathStr +endfunction + +" FUNCTION: Bookmark.toRoot() {{{1 +" Make the node for this bookmark the new tree root +function! s:Bookmark.toRoot() + if self.validate() + try + let targetNode = self.getNode(1) + catch /^NERDTree.BookmarkedNodeNotFoundError/ + let targetNode = g:NERDTreeFileNode.New(s:Bookmark.BookmarkFor(self.name).path) + endtry + call targetNode.makeRoot() + call b:NERDTree.render() + call targetNode.putCursorHere(0, 0) + endif +endfunction + +" FUNCTION: Bookmark.ToRoot(name) {{{1 +" Make the node for this bookmark the new tree root +function! s:Bookmark.ToRoot(name) + let bookmark = s:Bookmark.BookmarkFor(a:name) + call bookmark.toRoot() +endfunction + +" FUNCTION: Bookmark.validate() {{{1 +function! s:Bookmark.validate() + if self.path.exists() + return 1 + else + call s:Bookmark.CacheBookmarks(1) + call b:NERDTree.render() + call nerdtree#echo(self.name . "now points to an invalid location. See :help NERDTreeInvalidBookmarks for info.") + return 0 + endif +endfunction + +" FUNCTION: Bookmark.Write() {{{1 +" Class method to write all bookmarks to the bookmarks file +function! s:Bookmark.Write() + let bookmarkStrings = [] + for i in s:Bookmark.Bookmarks() + call add(bookmarkStrings, i.name . ' ' . i.path.str()) + endfor + + "add a blank line before the invalid ones + call add(bookmarkStrings, "") + + for j in s:Bookmark.InvalidBookmarks() + call add(bookmarkStrings, j) + endfor + call writefile(bookmarkStrings, g:NERDTreeBookmarksFile) +endfunction + +" vim: set sw=4 sts=4 et fdm=marker: diff --git a/vim/.vim/lib/nerdtree/creator.vim b/vim/.vim/lib/nerdtree/creator.vim @@ -0,0 +1,362 @@ +"CLASS: Creator +"Creates primary/secondary/mirror nerdtree windows. Sets up all the window and +"buffer options and key mappings etc. +"============================================================ +let s:Creator = {} +let g:NERDTreeCreator = s:Creator + +"FUNCTION: s:Creator._bindMappings() {{{1 +function! s:Creator._bindMappings() + "make <cr> do the same as the activate node mapping + nnoremap <silent> <buffer> <cr> :call nerdtree#ui_glue#invokeKeyMap(g:NERDTreeMapActivateNode)<cr> + + call g:NERDTreeKeyMap.BindAll() + + command! -buffer -nargs=? Bookmark :call nerdtree#ui_glue#bookmarkNode('<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#ui_glue#openBookmark('<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 -nargs=0 ClearAllBookmarks call g:NERDTreeBookmark.ClearAll() <bar> call b:NERDTree.render() + command! -buffer -nargs=0 ReadBookmarks call g:NERDTreeBookmark.CacheBookmarks(0) <bar> call b:NERDTree.render() + command! -buffer -nargs=0 WriteBookmarks call g:NERDTreeBookmark.Write() +endfunction + +"FUNCTION: s:Creator._broadcastInitEvent() {{{1 +function! s:Creator._broadcastInitEvent() + silent doautocmd User NERDTreeInit +endfunction + +" FUNCTION: s:Creator.BufNamePrefix() {{{2 +function! s:Creator.BufNamePrefix() + return 'NERD_tree_' +endfunction + +"FUNCTION: s:Creator.CreatePrimary(a:name) {{{1 +function! s:Creator.CreatePrimary(name) + let creator = s:Creator.New() + call creator.createPrimary(a:name) +endfunction + +"FUNCTION: s:Creator.createPrimary(a:name) {{{1 +"name: the name of a bookmark or a directory +function! s:Creator.createPrimary(name) + let path = self._pathForString(a:name) + + "abort if exception was thrown (bookmark/dir doesn't exist) + if empty(path) + return + endif + + "if instructed to, then change the vim CWD to the dir the NERDTree is + "inited in + if g:NERDTreeChDirMode != 0 + call path.changeToDir() + endif + + if g:NERDTree.ExistsForTab() + if g:NERDTree.IsOpen() + call g:NERDTree.Close() + endif + unlet t:NERDTreeBufName + endif + + call self._createTreeWin() + call self._createNERDTree(path) + let b:NERDTreeType = "primary" + let b:treeShowHelp = 0 + let b:NERDTreeIgnoreEnabled = 1 + let b:NERDTreeShowFiles = g:NERDTreeShowFiles + let b:NERDTreeShowHidden = g:NERDTreeShowHidden + let b:NERDTreeShowBookmarks = g:NERDTreeShowBookmarks + + call b:NERDTree.render() + call b:NERDTreeRoot.putCursorHere(0, 0) + + call self._broadcastInitEvent() +endfunction + +"FUNCTION: s:Creator.CreateSecondary(dir) {{{1 +function! s:Creator.CreateSecondary(dir) + let creator = s:Creator.New() + call creator.createSecondary(a:dir) +endfunction + +"FUNCTION: s:Creator.createSecondary(dir) {{{1 +function! s:Creator.createSecondary(dir) + try + let path = g:NERDTreePath.New(a:dir) + catch /^NERDTree.InvalidArgumentsError/ + call nerdtree#echo("Invalid directory name:" . a:name) + return + endtry + + "we want the directory buffer to disappear when we do the :edit below + setlocal bufhidden=wipe + + let previousBuf = expand("#") + + "we need a unique name for each secondary tree buffer to ensure they are + "all independent + exec "silent edit " . self._nextBufferName() + + let b:NERDTreePreviousBuf = bufnr(previousBuf) + call self._createNERDTree(path) + call self._setCommonBufOptions() + let b:NERDTreeType = "secondary" + + call b:NERDTree.render() + + call self._broadcastInitEvent() +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() + let creator = s:Creator.New() + call creator.createMirror() +endfunction + +" FUNCTION: s:Creator.createMirror() {{{1 +function! s:Creator.createMirror() + "get the names off all the nerd tree buffers + let treeBufNames = [] + for i in range(1, tabpagenr("$")) + let nextName = self._tabpagevar(i, 'NERDTreeBufName') + if nextName != -1 && (!exists("t:NERDTreeBufName") || nextName != t:NERDTreeBufName) + call add(treeBufNames, nextName) + endif + endfor + let treeBufNames = self._uniq(treeBufNames) + + "map the option names (that the user will be prompted with) to the nerd + "tree buffer names + let options = {} + let i = 0 + while i < len(treeBufNames) + let bufName = treeBufNames[i] + let treeRoot = getbufvar(bufName, "NERDTreeRoot") + let options[i+1 . '. ' . treeRoot.path.str() . ' (buf name: ' . bufName . ')'] = bufName + let i = i + 1 + endwhile + + "work out which tree to mirror, if there is more than 1 then ask the user + let bufferName = '' + if len(keys(options)) > 1 + let choices = ["Choose a tree to mirror"] + let choices = extend(choices, sort(keys(options))) + let choice = inputlist(choices) + if choice < 1 || choice > len(options) || choice ==# '' + return + endif + + let bufferName = options[sort(keys(options))[choice-1]] + elseif len(keys(options)) ==# 1 + let bufferName = values(options)[0] + else + call nerdtree#echo("No trees to mirror") + return + endif + + if g:NERDTree.ExistsForTab() && g:NERDTree.IsOpen() + call g:NERDTree.Close() + endif + + let t:NERDTreeBufName = bufferName + call self._createTreeWin() + exec 'buffer ' . bufferName + if !&hidden + call b:NERDTree.render() + endif +endfunction + +"FUNCTION: s:Creator._createTreeWin() {{{1 +"Inits the NERD tree window. ie. opens it, sizes it, sets all the local +"options etc +function! s:Creator._createTreeWin() + "create the nerd tree window + let splitLocation = g:NERDTreeWinPos ==# "left" ? "topleft " : "botright " + let splitSize = g:NERDTreeWinSize + + if !exists('t:NERDTreeBufName') + let t:NERDTreeBufName = self._nextBufferName() + silent! exec splitLocation . 'vertical ' . splitSize . ' new' + silent! exec "edit " . t:NERDTreeBufName + else + silent! exec splitLocation . 'vertical ' . splitSize . ' split' + silent! exec "buffer " . t:NERDTreeBufName + endif + + setlocal winfixwidth + call self._setCommonBufOptions() +endfunction + +"FUNCTION: s:Creator.New() {{{1 +function! s:Creator.New() + let newCreator = copy(self) + return newCreator +endfunction + +" FUNCTION: s:Creator._nextBufferName() {{{2 +" returns the buffer name for the next nerd tree +function! s:Creator._nextBufferName() + let name = s:Creator.BufNamePrefix() . self._nextBufferNumber() + return name +endfunction + +" FUNCTION: s:Creator._nextBufferNumber() {{{2 +" the number to add to the nerd tree buffer name to make the buf name unique +function! s:Creator._nextBufferNumber() + if !exists("s:Creator._NextBufNum") + let s:Creator._NextBufNum = 1 + else + let s:Creator._NextBufNum += 1 + endif + + return s:Creator._NextBufNum +endfunction + +"FUNCTION: s:Creator._pathForString(str) {{{1 +"find a bookmark or adirectory for the given string +function! s:Creator._pathForString(str) + let path = {} + if g:NERDTreeBookmark.BookmarkExistsFor(a:str) + let path = g:NERDTreeBookmark.BookmarkFor(a:str).path + else + let dir = a:str ==# '' ? getcwd() : a:str + + "hack to get an absolute path if a relative path is given + if dir =~# '^\.' + let dir = getcwd() . g:NERDTreePath.Slash() . dir + endif + let dir = g:NERDTreePath.Resolve(dir) + + try + let path = g:NERDTreePath.New(dir) + catch /^NERDTree.InvalidArgumentsError/ + call nerdtree#echo("No bookmark or directory found for: " . a:str) + return + endtry + endif + if !path.isDirectory + let path = path.getParent() + endif + + return path +endfunction + +"FUNCTION: s:Creator._setCommonBufOptions() {{{1 +function! s:Creator._setCommonBufOptions() + "throwaway buffer options + setlocal noswapfile + setlocal buftype=nofile + setlocal bufhidden=hide + setlocal nowrap + setlocal foldcolumn=0 + setlocal foldmethod=manual + setlocal nofoldenable + setlocal nobuflisted + setlocal nospell + if g:NERDTreeShowLineNumbers + setlocal nu + else + setlocal nonu + if v:version >= 703 + setlocal nornu + endif + endif + + iabc <buffer> + + if g:NERDTreeHighlightCursorline + setlocal cursorline + endif + + call self._setupStatusline() + + let b:treeShowHelp = 0 + let b:NERDTreeIgnoreEnabled = 1 + let b:NERDTreeShowFiles = g:NERDTreeShowFiles + let b:NERDTreeShowHidden = g:NERDTreeShowHidden + let b:NERDTreeShowBookmarks = g:NERDTreeShowBookmarks + call self._bindMappings() + setlocal filetype=nerdtree +endfunction + +"FUNCTION: s:Creator._setupStatusline() {{{1 +function! s:Creator._setupStatusline() + if g:NERDTreeStatusline != -1 + let &l:statusline = g:NERDTreeStatusline + endif +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) + let creator = s:Creator.New() + call creator.togglePrimary(a:dir) +endfunction + +"FUNCTION: s:Creator.togglePrimary(dir) {{{1 +"Toggles the NERD tree. I.e the NERD tree is open, it is closed, if it is +"closed it is restored or initialized (if it doesnt exist) +" +"Args: +"dir: the full path for the root node (is only used if the NERD tree is being +"initialized. +function! s:Creator.togglePrimary(dir) + if g:NERDTree.ExistsForTab() + if !g:NERDTree.IsOpen() + call self._createTreeWin() + if !&hidden + call b:NERDTree.render() + endif + call b:NERDTree.ui.restoreScreenState() + else + call g:NERDTree.Close() + endif + else + call self.createPrimary(a:dir) + endif +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: diff --git a/vim/.vim/lib/nerdtree/event.vim b/vim/.vim/lib/nerdtree/event.vim @@ -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 diff --git a/vim/.vim/lib/nerdtree/flag_set.vim b/vim/.vim/lib/nerdtree/flag_set.vim @@ -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 diff --git a/vim/.vim/lib/nerdtree/key_map.vim b/vim/.vim/lib/nerdtree/key_map.vim @@ -0,0 +1,159 @@ +"CLASS: KeyMap +"============================================================ +let s:KeyMap = {} +let g:NERDTreeKeyMap = s:KeyMap + +"FUNCTION: KeyMap.All() {{{1 +function! s:KeyMap.All() + if !exists("s:keyMaps") + let s:keyMaps = [] + endif + return s:keyMaps +endfunction + +"FUNCTION: KeyMap.FindFor(key, scope) {{{1 +function! s:KeyMap.FindFor(key, scope) + for i in s:KeyMap.All() + if i.key ==# a:key && i.scope ==# a:scope + return i + endif + endfor + return {} +endfunction + +"FUNCTION: KeyMap.BindAll() {{{1 +function! s:KeyMap.BindAll() + for i in s:KeyMap.All() + call i.bind() + endfor +endfunction + +"FUNCTION: KeyMap.bind() {{{1 +function! s:KeyMap.bind() + " If the key sequence we're trying to map contains any '<>' notation, we + " must replace each of the '<' characters with '<lt>' to ensure the string + " is not translated into its corresponding keycode during the later part + " of the map command below + " :he <> + let specialNotationRegex = '\m<\([[:alnum:]_-]\+>\)' + if self.key =~# specialNotationRegex + let keymapInvokeString = substitute(self.key, specialNotationRegex, '<lt>\1', 'g') + else + let keymapInvokeString = self.key + endif + + let premap = self.key == "<LeftRelease>" ? " <LeftRelease>" : " " + + exec 'nnoremap <buffer> <silent> '. self.key . premap . ':call nerdtree#ui_glue#invokeKeyMap("'. keymapInvokeString .'")<cr>' +endfunction + +"FUNCTION: KeyMap.Remove(key, scope) {{{1 +function! s:KeyMap.Remove(key, scope) + let maps = s:KeyMap.All() + for i in range(len(maps)) + if maps[i].key ==# a:key && maps[i].scope ==# a:scope + return remove(maps, i) + endif + endfor +endfunction + +"FUNCTION: KeyMap.invoke() {{{1 +"Call the KeyMaps callback function +function! s:KeyMap.invoke(...) + let Callback = function(self.callback) + if a:0 + call Callback(a:1) + else + call Callback() + endif +endfunction + +"FUNCTION: KeyMap.Invoke() {{{1 +"Find a keymapping for a:key and the current scope invoke it. +" +"Scope is determined as follows: +" * if the cursor is on a dir node then "DirNode" +" * if the cursor is on a file node then "FileNode" +" * if the cursor is on a bookmark then "Bookmark" +" +"If a keymap has the scope of "all" then it will be called if no other keymap +"is found for a:key and the scope. +function! s:KeyMap.Invoke(key) + + "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() + if !empty(node) + + "try file node + if !node.path.isDirectory + let km = s:KeyMap.FindFor(a:key, "FileNode") + if !empty(km) + return km.invoke(node) + endif + endif + + "try dir node + if node.path.isDirectory + let km = s:KeyMap.FindFor(a:key, "DirNode") + if !empty(km) + return km.invoke(node) + endif + endif + + "try generic node + let km = s:KeyMap.FindFor(a:key, "Node") + if !empty(km) + return km.invoke(node) + endif + + endif + + "try bookmark + let bm = g:NERDTreeBookmark.GetSelected() + if !empty(bm) + let km = s:KeyMap.FindFor(a:key, "Bookmark") + if !empty(km) + return km.invoke(bm) + endif + endif + + "try all + let km = s:KeyMap.FindFor(a:key, "all") + if !empty(km) + return km.invoke() + endif +endfunction + +"FUNCTION: KeyMap.Create(options) {{{1 +function! s:KeyMap.Create(options) + let 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.quickhelpText = opts['quickhelpText'] + let newKeyMap.callback = opts['callback'] + let newKeyMap.scope = opts['scope'] + + call s:KeyMap.Add(newKeyMap) +endfunction + +"FUNCTION: KeyMap.Add(keymap) {{{1 +function! s:KeyMap.Add(keymap) + call s:KeyMap.Remove(a:keymap.key, a:keymap.scope) + call add(s:KeyMap.All(), a:keymap) +endfunction + +" vim: set sw=4 sts=4 et fdm=marker: diff --git a/vim/.vim/lib/nerdtree/menu_controller.vim b/vim/.vim/lib/nerdtree/menu_controller.vim @@ -0,0 +1,180 @@ +"CLASS: MenuController +"============================================================ +let s:MenuController = {} +let g:NERDTreeMenuController = s:MenuController + +"FUNCTION: MenuController.New(menuItems) {{{1 +"create a new menu controller that operates on the given menu items +function! s:MenuController.New(menuItems) + let newMenuController = copy(self) + if a:menuItems[0].isSeparator() + let newMenuController.menuItems = a:menuItems[1:-1] + else + let newMenuController.menuItems = a:menuItems + endif + return newMenuController +endfunction + +"FUNCTION: MenuController.showMenu() {{{1 +"start the main loop of the menu and get the user to choose/execute a menu +"item +function! s:MenuController.showMenu() + call self._saveOptions() + + try + let self.selection = 0 + + let done = 0 + while !done + redraw! + call self._echoPrompt() + let key = nr2char(getchar()) + let done = self._handleKeypress(key) + endwhile + finally + call self._restoreOptions() + endtry + + if self.selection != -1 + let m = self._current() + call m.execute() + endif +endfunction + +"FUNCTION: MenuController._echoPrompt() {{{1 +function! s:MenuController._echoPrompt() + echo "NERDTree Menu. Use j/k/enter and the shortcuts indicated" + echo "==========================================================" + + for i in range(0, len(self.menuItems)-1) + if self.selection == i + echo "> " . self.menuItems[i].text + else + echo " " . self.menuItems[i].text + endif + endfor +endfunction + +"FUNCTION: MenuController._current(key) {{{1 +"get the MenuItem that is currently selected +function! s:MenuController._current() + return self.menuItems[self.selection] +endfunction + +"FUNCTION: MenuController._handleKeypress(key) {{{1 +"change the selection (if appropriate) and return 1 if the user has made +"their choice, 0 otherwise +function! s:MenuController._handleKeypress(key) + if a:key == 'j' + call self._cursorDown() + elseif a:key == 'k' + call self._cursorUp() + elseif a:key == nr2char(27) "escape + let self.selection = -1 + return 1 + elseif a:key == "\r" || a:key == "\n" "enter and ctrl-j + return 1 + else + let index = self._nextIndexFor(a:key) + if index != -1 + let self.selection = index + if len(self._allIndexesFor(a:key)) == 1 + return 1 + endif + endif + endif + + return 0 +endfunction + +"FUNCTION: MenuController._allIndexesFor(shortcut) {{{1 +"get indexes to all menu items with the given shortcut +function! s:MenuController._allIndexesFor(shortcut) + let toReturn = [] + + for i in range(0, len(self.menuItems)-1) + if self.menuItems[i].shortcut == a:shortcut + call add(toReturn, i) + endif + endfor + + return toReturn +endfunction + +"FUNCTION: MenuController._nextIndexFor(shortcut) {{{1 +"get the index to the next menu item with the given shortcut, starts from the +"current cursor location and wraps around to the top again if need be +function! s:MenuController._nextIndexFor(shortcut) + for i in range(self.selection+1, len(self.menuItems)-1) + if self.menuItems[i].shortcut == a:shortcut + return i + endif + endfor + + for i in range(0, self.selection) + if self.menuItems[i].shortcut == a:shortcut + return i + endif + endfor + + return -1 +endfunction + +"FUNCTION: MenuController._setCmdheight() {{{1 +"sets &cmdheight to whatever is needed to display the menu +function! s:MenuController._setCmdheight() + let &cmdheight = len(self.menuItems) + 3 +endfunction + +"FUNCTION: MenuController._saveOptions() {{{1 +"set any vim options that are required to make the menu work (saving their old +"values) +function! s:MenuController._saveOptions() + let self._oldLazyredraw = &lazyredraw + let self._oldCmdheight = &cmdheight + set nolazyredraw + call self._setCmdheight() +endfunction + +"FUNCTION: MenuController._restoreOptions() {{{1 +"restore the options we saved in _saveOptions() +function! s:MenuController._restoreOptions() + let &cmdheight = self._oldCmdheight + let &lazyredraw = self._oldLazyredraw +endfunction + +"FUNCTION: MenuController._cursorDown() {{{1 +"move the cursor to the next menu item, skipping separators +function! s:MenuController._cursorDown() + let done = 0 + while !done + if self.selection < len(self.menuItems)-1 + let self.selection += 1 + else + let self.selection = 0 + endif + + if !self._current().isSeparator() + let done = 1 + endif + endwhile +endfunction + +"FUNCTION: MenuController._cursorUp() {{{1 +"move the cursor to the previous menu item, skipping separators +function! s:MenuController._cursorUp() + let done = 0 + while !done + if self.selection > 0 + let self.selection -= 1 + else + let self.selection = len(self.menuItems)-1 + endif + + if !self._current().isSeparator() + let done = 1 + endif + endwhile +endfunction + +" vim: set sw=4 sts=4 et fdm=marker: diff --git a/vim/.vim/lib/nerdtree/menu_item.vim b/vim/.vim/lib/nerdtree/menu_item.vim @@ -0,0 +1,114 @@ +"CLASS: MenuItem +"============================================================ +let s:MenuItem = {} +let g:NERDTreeMenuItem = s:MenuItem + +"FUNCTION: MenuItem.All() {{{1 +"get all top level menu items +function! s:MenuItem.All() + if !exists("s:menuItems") + let s:menuItems = [] + endif + return s:menuItems +endfunction + +"FUNCTION: MenuItem.AllEnabled() {{{1 +"get all top level menu items that are currently enabled +function! s:MenuItem.AllEnabled() + let toReturn = [] + for i in s:MenuItem.All() + if i.enabled() + call add(toReturn, i) + endif + endfor + return toReturn +endfunction + +"FUNCTION: MenuItem.Create(options) {{{1 +"make a new menu item and add it to the global list +function! s:MenuItem.Create(options) + let newMenuItem = copy(self) + + let newMenuItem.text = a:options['text'] + let newMenuItem.shortcut = a:options['shortcut'] + let newMenuItem.children = [] + + let newMenuItem.isActiveCallback = -1 + if has_key(a:options, 'isActiveCallback') + let newMenuItem.isActiveCallback = a:options['isActiveCallback'] + endif + + let newMenuItem.callback = -1 + if has_key(a:options, 'callback') + let newMenuItem.callback = a:options['callback'] + endif + + if has_key(a:options, 'parent') + call add(a:options['parent'].children, newMenuItem) + else + call add(s:MenuItem.All(), newMenuItem) + endif + + return newMenuItem +endfunction + +"FUNCTION: MenuItem.CreateSeparator(options) {{{1 +"make a new separator menu item and add it to the global list +function! s:MenuItem.CreateSeparator(options) + let standard_options = { 'text': '--------------------', + \ 'shortcut': -1, + \ 'callback': -1 } + let options = extend(a:options, standard_options, "force") + + return s:MenuItem.Create(options) +endfunction + +"FUNCTION: MenuItem.CreateSubmenu(options) {{{1 +"make a new submenu and add it to global list +function! s:MenuItem.CreateSubmenu(options) + let standard_options = { 'callback': -1 } + let options = extend(a:options, standard_options, "force") + + return s:MenuItem.Create(options) +endfunction + +"FUNCTION: MenuItem.enabled() {{{1 +"return 1 if this menu item should be displayed +" +"delegates off to the isActiveCallback, and defaults to 1 if no callback was +"specified +function! s:MenuItem.enabled() + if self.isActiveCallback != -1 + return {self.isActiveCallback}() + endif + return 1 +endfunction + +"FUNCTION: MenuItem.execute() {{{1 +"perform the action behind this menu item, if this menuitem has children then +"display a new menu for them, otherwise deletegate off to the menuitem's +"callback +function! s:MenuItem.execute() + if len(self.children) + let mc = g:NERDTreeMenuController.New(self.children) + call mc.showMenu() + else + if self.callback != -1 + call {self.callback}() + endif + endif +endfunction + +"FUNCTION: MenuItem.isSeparator() {{{1 +"return 1 if this menuitem is a separator +function! s:MenuItem.isSeparator() + return self.callback == -1 && self.children == [] +endfunction + +"FUNCTION: MenuItem.isSubmenu() {{{1 +"return 1 if this menuitem is a submenu +function! s:MenuItem.isSubmenu() + return self.callback == -1 && !empty(self.children) +endfunction + +" vim: set sw=4 sts=4 et fdm=marker: diff --git a/vim/.vim/lib/nerdtree/nerdtree.vim b/vim/.vim/lib/nerdtree/nerdtree.vim @@ -0,0 +1,137 @@ +"CLASS: NERDTree +"============================================================ +let s:NERDTree = {} +let g:NERDTree = s:NERDTree + +"FUNCTION: s:NERDTree.AddPathFilter() {{{1 +function! s:NERDTree.AddPathFilter(callback) + call add(s:NERDTree.PathFilters(), a:callback) +endfunction + +"FUNCTION: s:NERDTree.Close() {{{1 +"Closes the primary NERD tree window for this tab +function! s:NERDTree.Close() + if !s:NERDTree.IsOpen() + return + endif + + if winnr("$") != 1 + if winnr() == s:NERDTree.GetWinNum() + call nerdtree#exec("wincmd p") + let bufnr = bufnr("") + call nerdtree#exec("wincmd p") + else + let bufnr = bufnr("") + endif + + call nerdtree#exec(s:NERDTree.GetWinNum() . " wincmd w") + close + call nerdtree#exec(bufwinnr(bufnr) . " wincmd w") + else + close + endif +endfunction + +"FUNCTION: s:NERDTree.CloseIfQuitOnOpen() {{{1 +"Closes the NERD tree window if the close on open option is set +function! s:NERDTree.CloseIfQuitOnOpen() + if g:NERDTreeQuitOnOpen && s:NERDTree.IsOpen() + call s:NERDTree.Close() + endif +endfunction + +"FUNCTION: s:NERDTree.CursorToBookmarkTable(){{{1 +"Places the cursor at the top of the bookmarks table +function! s:NERDTree.CursorToBookmarkTable() + if !b:NERDTreeShowBookmarks + throw "NERDTree.IllegalOperationError: cant find bookmark table, bookmarks arent active" + endif + + if g:NERDTreeMinimalUI + return cursor(1, 2) + endif + + let rootNodeLine = b:NERDTree.ui.getRootLineNum() + + let line = 1 + while getline(line) !~# '^>-\+Bookmarks-\+$' + let line = line + 1 + if line >= rootNodeLine + throw "NERDTree.BookmarkTableNotFoundError: didnt find the bookmarks table" + endif + endwhile + call cursor(line, 2) +endfunction + +"FUNCTION: s:NERDTree.CursorToTreeWin(){{{1 +"Places the cursor in the nerd tree window +function! s:NERDTree.CursorToTreeWin() + call g:NERDTree.MustBeOpen() + call nerdtree#exec(g:NERDTree.GetWinNum() . "wincmd w") +endfunction + +" 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.GetWinNum() {{{1 +"gets the nerd tree window number for this tab +function! s:NERDTree.GetWinNum() + if exists("t:NERDTreeBufName") + return bufwinnr(t:NERDTreeBufName) + else + return -1 + endif +endfunction + +"FUNCTION: s:NERDTree.IsOpen() {{{1 +function! s:NERDTree.IsOpen() + return s:NERDTree.GetWinNum() != -1 +endfunction + +"FUNCTION: s:NERDTree.MustBeOpen() {{{1 +function! s:NERDTree.MustBeOpen() + if !s:NERDTree.IsOpen() + throw "NERDTree.TreeNotOpen" + endif +endfunction + +"FUNCTION: s:NERDTree.New() {{{1 +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.PathFilters() {{{1 +function! s:NERDTree.PathFilters() + if !exists('s:NERDTree._PathFilters') + let s:NERDTree._PathFilters = [] + endif + return s:NERDTree._PathFilters +endfunction + + +"FUNCTION: s:NERDTree.render() {{{1 +"A convenience function - since this is called often +function! s:NERDTree.render() + call self.ui.render() +endfunction diff --git a/vim/.vim/lib/nerdtree/notifier.vim b/vim/.vim/lib/nerdtree/notifier.vim @@ -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) + diff --git a/vim/.vim/lib/nerdtree/opener.vim b/vim/.vim/lib/nerdtree/opener.vim @@ -0,0 +1,352 @@ +"CLASS: Opener +"============================================================ +let 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 +"Check the class options and global options (i.e. NERDTreeQuitOnOpen) to see +"if the tree should be closed now. +" +"Args: +"a:newtab - boolean. If set, only close the tree now if we are opening the +"target in a new tab. This is needed because we have to close tree before we +"leave the tab +function! s:Opener._checkToCloseTree(newtab) + if self._keepopen + return + endif + + if (a:newtab && self._where == 't') || !a:newtab + call g:NERDTree.CloseIfQuitOnOpen() + endif +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! s:Opener._gotoTargetWin() + if b:NERDTreeType ==# "secondary" + if self._where == 'v' + vsplit + elseif self._where == 'h' + split + elseif self._where == 't' + tabnew + endif + else + call self._checkToCloseTree(1) + + if self._where == 'v' + call self._newVSplit() + elseif self._where == 'h' + call self._newSplit() + elseif self._where == 't' + tabnew + elseif self._where == 'p' + call self._previousWindow() + endif + + call self._checkToCloseTree(0) + endif +endfunction + +"FUNCTION: 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 +"Args: +" +"a:path: The path object that is to be opened. +" +"a:opts: +" +"A dictionary containing the following keys (all optional): +" 'where': Specifies whether the node should be opened in new split/tab or in +" the previous window. Can be either 'v' or 'h' or 't' (for open in +" new tab) +" 'reuse': if a window is displaying the file then jump the cursor there. Can +" 'all', 'currenttab' or empty to not reuse. +" 'keepopen': dont close the tree window +" 'stay': open the file, but keep the cursor in the tree win +function! s:Opener.New(path, opts) + let newObj = copy(self) + + let newObj._path = a:path + let newObj._stay = nerdtree#has_opt(a:opts, 'stay') + + if has_key(a:opts, 'reuse') + let newObj._reuse = a:opts['reuse'] + else + let newObj._reuse = '' + endif + + let newObj._keepopen = nerdtree#has_opt(a:opts, 'keepopen') + let newObj._where = has_key(a:opts, 'where') ? a:opts['where'] : '' + let newObj._treetype = b:NERDTreeType + call newObj._saveCursorPos() + + return newObj +endfunction + +"FUNCTION: Opener._newSplit() {{{1 +function! s:Opener._newSplit() + " Save the user's settings for splitbelow and splitright + let savesplitbelow=&splitbelow + let savesplitright=&splitright + + " 'there' will be set to a command to move from the split window + " back to the explorer window + " + " 'back' will be set to a command to move from the explorer window + " back to the newly split window + " + " 'right' and 'below' will be set to the settings needed for + " splitbelow and splitright IF the explorer is the only window. + " + let there= g:NERDTreeWinPos ==# "left" ? "wincmd h" : "wincmd l" + let back = g:NERDTreeWinPos ==# "left" ? "wincmd l" : "wincmd h" + let right= g:NERDTreeWinPos ==# "left" + let below=0 + + " Attempt to go to adjacent window + call nerdtree#exec(back) + + let onlyOneWin = (winnr("$") ==# 1) + + " If no adjacent window, set splitright and splitbelow appropriately + if onlyOneWin + let &splitright=right + let &splitbelow=below + else + " found adjacent window - invert split direction + let &splitright=!right + let &splitbelow=!below + endif + + let splitMode = onlyOneWin ? "vertical" : "" + + " Open the new window + try + exec(splitMode." sp ") + catch /^Vim\%((\a\+)\)\=:E37/ + call g:NERDTree.CursorToTreeWin() + throw "NERDTree.FileAlreadyOpenAndModifiedError: ". self._path.str() ." is already open and modified." + catch /^Vim\%((\a\+)\)\=:/ + "do nothing + endtry + + "resize the tree window if no other window was open before + if onlyOneWin + let size = exists("b:NERDTreeOldWindowSize") ? b:NERDTreeOldWindowSize : g:NERDTreeWinSize + call nerdtree#exec(there) + exec("silent ". splitMode ." resize ". size) + call nerdtree#exec('wincmd p') + endif + + " Restore splitmode settings + let &splitbelow=savesplitbelow + let &splitright=savesplitright +endfunction + +"FUNCTION: Opener._newVSplit() {{{1 +function! s:Opener._newVSplit() + let winwidth = winwidth(".") + if winnr("$")==#1 + let winwidth = g:NERDTreeWinSize + endif + + call nerdtree#exec("wincmd p") + vnew + + "resize the nerd tree back to the original size + call g:NERDTree.CursorToTreeWin() + exec("silent vertical resize ". winwidth) + call nerdtree#exec('wincmd p') +endfunction + +"FUNCTION: Opener.open(target) {{{1 +function! s:Opener.open(target) + if self._path.isDirectory + call self._openDirectory(a:target) + else + call self._openFile() + endif +endfunction + +"FUNCTION: Opener._openFile() {{{1 +function! s:Opener._openFile() + if self._reuseWindow() + return + endif + + call self._gotoTargetWin() + + if self._treetype ==# "secondary" + call self._path.edit() + else + call self._path.edit() + + + if self._stay + call self._restoreCursorPos() + endif + endif +endfunction + +"FUNCTION: Opener._openDirectory(node) {{{1 +function! s:Opener._openDirectory(node) + if self._treetype ==# "secondary" + call self._gotoTargetWin() + call g:NERDTreeCreator.CreateSecondary(a:node.path.str()) + else + call self._gotoTargetWin() + if empty(self._where) + call a:node.makeRoot() + call b:NERDTree.render() + call a:node.putCursorHere(0, 0) + elseif self._where == 't' + call g:NERDTreeCreator.CreatePrimary(a:node.path.str()) + else + call g:NERDTreeCreator.CreateSecondary(a:node.path.str()) + endif + endif + + if self._stay + call self._restoreCursorPos() + endif +endfunction + +"FUNCTION: Opener._previousWindow() {{{1 +function! s:Opener._previousWindow() + if !self._isWindowUsable(winnr("#")) && self._firstUsableWindow() ==# -1 + call self._newSplit() + else + try + if !self._isWindowUsable(winnr("#")) + call nerdtree#exec(self._firstUsableWindow() . "wincmd w") + else + call nerdtree#exec('wincmd p') + endif + catch /^Vim\%((\a\+)\)\=:E37/ + call g:NERDTree.CursorToTreeWin() + throw "NERDTree.FileAlreadyOpenAndModifiedError: ". self._path.str() ." is already open and modified." + catch /^Vim\%((\a\+)\)\=:/ + echo v:exception + endtry + endif +endfunction + +"FUNCTION: Opener._restoreCursorPos(){{{1 +function! s:Opener._restoreCursorPos() + call nerdtree#exec('normal ' . self._tabnr . 'gt') + call nerdtree#exec(bufwinnr(self._bufnr) . 'wincmd w') +endfunction + +"FUNCTION: Opener._reuseWindow(){{{1 +"put the cursor in the first window we find for this file +" +"return 1 if we were successful +function! s:Opener._reuseWindow() + if empty(self._reuse) + return 0 + endif + + "check the current tab for the window + let winnr = bufwinnr('^' . self._path.str() . '$') + if winnr != -1 + call nerdtree#exec(winnr . "wincmd w") + call self._checkToCloseTree(0) + return 1 + endif + + if self._reuse == 'currenttab' + return 0 + endif + + "check other tabs + let tabnr = self._path.tabnr() + if tabnr + call self._checkToCloseTree(1) + call nerdtree#exec('normal! ' . tabnr . 'gt') + let winnr = bufwinnr('^' . self._path.str() . '$') + call nerdtree#exec(winnr . "wincmd w") + return 1 + endif + + return 0 +endfunction + +"FUNCTION: Opener._saveCursorPos(){{{1 +function! s:Opener._saveCursorPos() + let self._bufnr = bufnr("") + let self._tabnr = tabpagenr() +endfunction + +" vim: set sw=4 sts=4 et fdm=marker: diff --git a/vim/.vim/lib/nerdtree/path.vim b/vim/.vim/lib/nerdtree/path.vim @@ -0,0 +1,785 @@ +"we need to use this number many times for sorting... so we calculate it only +"once here +let s:NERDTreeSortStarIndex = index(g:NERDTreeSortOrder, '*') +" used in formating sortKey, e.g. '%04d' +if exists("log10") + let s:sortKeyFormat = "%0" . float2nr(ceil(log10(len(g:NERDTreeSortOrder)))) . "d" +else + let s:sortKeyFormat = "%04d" +endif + +"CLASS: Path +"============================================================ +let s:Path = {} +let g:NERDTreePath = s:Path + +"FUNCTION: Path.AbsolutePathFor(str) {{{1 +function! s:Path.AbsolutePathFor(str) + let prependCWD = 0 + if nerdtree#runningWindows() + let prependCWD = a:str !~# '^.:\(\\\|\/\)' && a:str !~# '^\(\\\\\|\/\/\)' + else + let prependCWD = a:str !~# '^/' + endif + + let toReturn = a:str + if prependCWD + let toReturn = getcwd() . s:Path.Slash() . a:str + endif + + return toReturn +endfunction + +"FUNCTION: Path.bookmarkNames() {{{1 +function! s:Path.bookmarkNames() + if !exists("self._bookmarkNames") + call self.cacheDisplayString() + endif + return self._bookmarkNames +endfunction + +"FUNCTION: Path.cacheDisplayString() {{{1 +function! s:Path.cacheDisplayString() abort + let self.cachedDisplayString = self.flagSet.renderToString() + + let self.cachedDisplayString .= self.getLastPathComponent(1) + + if self.isExecutable + let self.cachedDisplayString = self.cachedDisplayString . '*' + endif + + let self._bookmarkNames = [] + for i in g:NERDTreeBookmark.Bookmarks() + if i.path.equals(self) + call add(self._bookmarkNames, i.name) + endif + endfor + if !empty(self._bookmarkNames) + let self.cachedDisplayString .= ' {' . join(self._bookmarkNames) . '}' + endif + + if self.isSymLink + let self.cachedDisplayString .= ' -> ' . self.symLinkDest + endif + + if self.isReadOnly + let self.cachedDisplayString .= ' [RO]' + endif +endfunction + +"FUNCTION: Path.changeToDir() {{{1 +function! s:Path.changeToDir() + let dir = self.str({'format': 'Cd'}) + if self.isDirectory ==# 0 + let dir = self.getParent().str({'format': 'Cd'}) + endif + + try + execute "cd " . dir + call nerdtree#echo("CWD is now: " . getcwd()) + catch + throw "NERDTree.PathChangeError: cannot change CWD to " . dir + endtry +endfunction + +"FUNCTION: Path.compareTo() {{{1 +" +"Compares this Path to the given path and returns 0 if they are equal, -1 if +"this Path is "less than" the given path, or 1 if it is "greater". +" +"Args: +"path: the path object to compare this to +" +"Return: +"1, -1 or 0 +function! s:Path.compareTo(path) + let thisPath = self.getLastPathComponent(1) + let thatPath = a:path.getLastPathComponent(1) + + "if the paths are the same then clearly we return 0 + if thisPath ==# thatPath + return 0 + endif + + let thisSS = self.getSortOrderIndex() + let thatSS = a:path.getSortOrderIndex() + + "compare the sort sequences, if they are different then the return + "value is easy + if thisSS < thatSS + return -1 + elseif thisSS > thatSS + return 1 + else + if !g:NERDTreeSortHiddenFirst + let thisPath = substitute(thisPath, '^[._]', '', '') + let thatPath = substitute(thatPath, '^[._]', '', '') + endif + "if the sort sequences are the same then compare the paths + "alphabetically + let pathCompare = g:NERDTreeCaseSensitiveSort ? thisPath <# thatPath : thisPath <? thatPath + if pathCompare + return -1 + else + return 1 + endif + endif +endfunction + +"FUNCTION: Path.Create(fullpath) {{{1 +" +"Factory method. +" +"Creates a path object with the given path. The path is also created on the +"filesystem. If the path already exists, a NERDTree.Path.Exists exception is +"thrown. If any other errors occur, a NERDTree.Path exception is thrown. +" +"Args: +"fullpath: the full filesystem path to the file/dir to create +function! s:Path.Create(fullpath) + "bail if the a:fullpath already exists + if isdirectory(a:fullpath) || filereadable(a:fullpath) + throw "NERDTree.CreatePathError: Directory Exists: '" . a:fullpath . "'" + endif + + try + + "if it ends with a slash, assume its a dir create it + if a:fullpath =~# '\(\\\|\/\)$' + "whack the trailing slash off the end if it exists + let fullpath = substitute(a:fullpath, '\(\\\|\/\)$', '', '') + + call mkdir(fullpath, 'p') + + "assume its a file and create + else + call s:Path.createParentDirectories(a:fullpath) + call writefile([], a:fullpath) + endif + catch + throw "NERDTree.CreatePathError: Could not create path: '" . a:fullpath . "'" + endtry + + return s:Path.New(a:fullpath) +endfunction + +"FUNCTION: Path.copy(dest) {{{1 +" +"Copies the file/dir represented by this Path to the given location +" +"Args: +"dest: the location to copy this dir/file to +function! s:Path.copy(dest) + if !s:Path.CopyingSupported() + throw "NERDTree.CopyingNotSupportedError: Copying is not supported on this OS" + endif + + call s:Path.createParentDirectories(a:dest) + + let dest = s:Path.WinToUnixPath(a:dest) + + let cmd = g:NERDTreeCopyCmd . " " . escape(self.str(), self._escChars()) . " " . escape(dest, self._escChars()) + let success = system(cmd) + if success != 0 + throw "NERDTree.CopyError: Could not copy ''". self.str() ."'' to: '" . a:dest . "'" + endif +endfunction + +"FUNCTION: Path.CopyingSupported() {{{1 +" +"returns 1 if copying is supported for this OS +function! s:Path.CopyingSupported() + return exists('g:NERDTreeCopyCmd') +endfunction + +"FUNCTION: Path.copyingWillOverwrite(dest) {{{1 +" +"returns 1 if copy this path to the given location will cause files to +"overwritten +" +"Args: +"dest: the location this path will be copied to +function! s:Path.copyingWillOverwrite(dest) + if filereadable(a:dest) + return 1 + endif + + if isdirectory(a:dest) + let path = s:Path.JoinPathStrings(a:dest, self.getLastPathComponent(0)) + if filereadable(path) + return 1 + endif + endif +endfunction + +"FUNCTION: Path.createParentDirectories(path) {{{1 +" +"create parent directories for this path if needed +"without throwing any errors is those directories already exist +" +"Args: +"path: full path of the node whose parent directories may need to be created +function! s:Path.createParentDirectories(path) + let dir_path = fnamemodify(a:path, ':h') + if !isdirectory(dir_path) + call mkdir(dir_path, 'p') + endif +endfunction + +"FUNCTION: Path.delete() {{{1 +" +"Deletes the file represented by this path. +"Deletion of directories is not supported +" +"Throws NERDTree.Path.Deletion exceptions +function! s:Path.delete() + if self.isDirectory + + let cmd = g:NERDTreeRemoveDirCmd . self.str({'escape': 1}) + let success = system(cmd) + + if v:shell_error != 0 + throw "NERDTree.PathDeletionError: Could not delete directory: '" . self.str() . "'" + endif + else + let success = delete(self.str()) + if success != 0 + throw "NERDTree.PathDeletionError: Could not delete file: '" . self.str() . "'" + endif + endif + + "delete all bookmarks for this path + for i in self.bookmarkNames() + let bookmark = g:NERDTreeBookmark.BookmarkFor(i) + call bookmark.delete() + endfor +endfunction + +"FUNCTION: Path.displayString() {{{1 +" +"Returns a string that specifies how the path should be represented as a +"string +function! s:Path.displayString() + if self.cachedDisplayString ==# "" + call self.cacheDisplayString() + endif + + return self.cachedDisplayString +endfunction + +"FUNCTION: Path.edit() {{{1 +function! s:Path.edit() + exec "edit " . self.str({'format': 'Edit'}) +endfunction + +"FUNCTION: Path.extractDriveLetter(fullpath) {{{1 +" +"If running windows, cache the drive letter for this path +function! s:Path.extractDriveLetter(fullpath) + if nerdtree#runningWindows() + if a:fullpath =~ '^\(\\\\\|\/\/\)' + "For network shares, the 'drive' consists of the first two parts of the path, i.e. \\boxname\share + let self.drive = substitute(a:fullpath, '^\(\(\\\\\|\/\/\)[^\\\/]*\(\\\|\/\)[^\\\/]*\).*', '\1', '') + let self.drive = substitute(self.drive, '/', '\', "g") + else + let self.drive = substitute(a:fullpath, '\(^[a-zA-Z]:\).*', '\1', '') + endif + else + let self.drive = '' + endif + +endfunction + +"FUNCTION: Path.exists() {{{1 +"return 1 if this path points to a location that is readable or is a directory +function! s:Path.exists() + let p = self.str() + return filereadable(p) || isdirectory(p) +endfunction + +"FUNCTION: Path._escChars() {{{1 +function! s:Path._escChars() + if nerdtree#runningWindows() + return " `\|\"#%&,?()\*^<>" + endif + + return " \\`\|\"#%&,?()\*^<>[]" +endfunction + +"FUNCTION: Path.getDir() {{{1 +" +"Returns this path if it is a directory, else this paths parent. +" +"Return: +"a Path object +function! s:Path.getDir() + if self.isDirectory + return self + else + return self.getParent() + endif +endfunction + +"FUNCTION: Path.getParent() {{{1 +" +"Returns a new path object for this paths parent +" +"Return: +"a new Path object +function! s:Path.getParent() + if nerdtree#runningWindows() + let path = self.drive . '\' . join(self.pathSegments[0:-2], '\') + else + let path = '/'. join(self.pathSegments[0:-2], '/') + endif + + return s:Path.New(path) +endfunction + +"FUNCTION: Path.getLastPathComponent(dirSlash) {{{1 +" +"Gets the last part of this path. +" +"Args: +"dirSlash: if 1 then a trailing slash will be added to the returned value for +"directory nodes. +function! s:Path.getLastPathComponent(dirSlash) + if empty(self.pathSegments) + return '' + endif + let toReturn = self.pathSegments[-1] + if a:dirSlash && self.isDirectory + let toReturn = toReturn . '/' + endif + return toReturn +endfunction + +"FUNCTION: Path.getSortOrderIndex() {{{1 +"returns the index of the pattern in g:NERDTreeSortOrder that this path matches +function! s:Path.getSortOrderIndex() + let i = 0 + while i < len(g:NERDTreeSortOrder) + if self.getLastPathComponent(1) =~# g:NERDTreeSortOrder[i] + return i + endif + let i = i + 1 + endwhile + return s:NERDTreeSortStarIndex +endfunction + +"FUNCTION: Path.getSortKey() {{{1 +"returns a string used in compare function for sorting +function! s:Path.getSortKey() + if !exists("self._sortKey") + let path = self.getLastPathComponent(1) + if !g:NERDTreeSortHiddenFirst + let path = substitute(path, '^[._]', '', '') + endif + if !g:NERDTreeCaseSensitiveSort + let path = tolower(path) + endif + let self._sortKey = printf(s:sortKeyFormat, self.getSortOrderIndex()) . path + endif + + return self._sortKey +endfunction + + +"FUNCTION: Path.isUnixHiddenFile() {{{1 +"check for unix hidden files +function! s:Path.isUnixHiddenFile() + return self.getLastPathComponent(0) =~# '^\.' +endfunction + +"FUNCTION: Path.isUnixHiddenPath() {{{1 +"check for unix path with hidden components +function! s:Path.isUnixHiddenPath() + if self.getLastPathComponent(0) =~# '^\.' + return 1 + else + for segment in self.pathSegments + if segment =~# '^\.' + return 1 + endif + endfor + return 0 + endif +endfunction + +"FUNCTION: Path.ignore() {{{1 +"returns true if this path should be ignored +function! s:Path.ignore() + "filter out the user specified paths to ignore + if b:NERDTreeIgnoreEnabled + for i in g:NERDTreeIgnore + if self._ignorePatternMatches(i) + return 1 + endif + endfor + + for callback in g:NERDTree.PathFilters() + if {callback}({'path': self, 'nerdtree': b:NERDTree}) + return 1 + endif + endfor + endif + + "dont show hidden files unless instructed to + if b:NERDTreeShowHidden ==# 0 && self.isUnixHiddenFile() + return 1 + endif + + if b:NERDTreeShowFiles ==# 0 && self.isDirectory ==# 0 + return 1 + endif + + return 0 +endfunction + +"FUNCTION: Path._ignorePatternMatches(pattern) {{{1 +"returns true if this path matches the given ignore pattern +function! s:Path._ignorePatternMatches(pattern) + let pat = a:pattern + if strpart(pat,len(pat)-7) == '[[dir]]' + if !self.isDirectory + return 0 + endif + let pat = strpart(pat,0, len(pat)-7) + elseif strpart(pat,len(pat)-8) == '[[file]]' + if self.isDirectory + return 0 + endif + let pat = strpart(pat,0, len(pat)-8) + endif + + return self.getLastPathComponent(0) =~# pat +endfunction + +"FUNCTION: Path.isUnder(path) {{{1 +"return 1 if this path is somewhere under the given path in the filesystem. +" +"a:path should be a dir +function! s:Path.isUnder(path) + if a:path.isDirectory == 0 + return 0 + endif + + let this = self.str() + let that = a:path.str() + return stridx(this, that . s:Path.Slash()) == 0 +endfunction + +"FUNCTION: Path.JoinPathStrings(...) {{{1 +function! s:Path.JoinPathStrings(...) + let components = [] + for i in a:000 + let components = extend(components, split(i, '/')) + endfor + return '/' . join(components, '/') +endfunction + +"FUNCTION: Path.equals() {{{1 +" +"Determines whether 2 path objects are "equal". +"They are equal if the paths they represent are the same +" +"Args: +"path: the other path obj to compare this with +function! s:Path.equals(path) + return self.str() ==# a:path.str() +endfunction + +"FUNCTION: Path.New() {{{1 +"The Constructor for the Path object +function! s:Path.New(path) + let newPath = copy(self) + + call newPath.readInfoFromDisk(s:Path.AbsolutePathFor(a:path)) + + let newPath.cachedDisplayString = "" + let newPath.flagSet = g:NERDTreeFlagSet.New() + + return newPath +endfunction + +"FUNCTION: Path.Slash() {{{1 +"return the slash to use for the current OS +function! s:Path.Slash() + return nerdtree#runningWindows() ? '\' : '/' +endfunction + +"FUNCTION: Path.Resolve() {{{1 +"Invoke the vim resolve() function and return the result +"This is necessary because in some versions of vim resolve() removes trailing +"slashes while in other versions it doesn't. This always removes the trailing +"slash +function! s:Path.Resolve(path) + let tmp = resolve(a:path) + return tmp =~# '.\+/$' ? substitute(tmp, '/$', '', '') : tmp +endfunction + +"FUNCTION: Path.readInfoFromDisk(fullpath) {{{1 +" +" +"Throws NERDTree.Path.InvalidArguments exception. +function! s:Path.readInfoFromDisk(fullpath) + call self.extractDriveLetter(a:fullpath) + + let fullpath = s:Path.WinToUnixPath(a:fullpath) + + if getftype(fullpath) ==# "fifo" + throw "NERDTree.InvalidFiletypeError: Cant handle FIFO files: " . a:fullpath + endif + + let self.pathSegments = split(fullpath, '/') + + let self.isReadOnly = 0 + if isdirectory(a:fullpath) + let self.isDirectory = 1 + elseif filereadable(a:fullpath) + let self.isDirectory = 0 + let self.isReadOnly = filewritable(a:fullpath) ==# 0 + else + throw "NERDTree.InvalidArgumentsError: Invalid path = " . a:fullpath + endif + + let self.isExecutable = 0 + if !self.isDirectory + let self.isExecutable = getfperm(a:fullpath) =~# 'x' + endif + + "grab the last part of the path (minus the trailing slash) + let lastPathComponent = self.getLastPathComponent(0) + + "get the path to the new node with the parent dir fully resolved + let hardPath = s:Path.Resolve(self.strTrunk()) . '/' . lastPathComponent + + "if the last part of the path is a symlink then flag it as such + let self.isSymLink = (s:Path.Resolve(hardPath) != hardPath) + if self.isSymLink + let self.symLinkDest = s:Path.Resolve(fullpath) + + "if the link is a dir then slap a / on the end of its dest + if isdirectory(self.symLinkDest) + + "we always wanna treat MS windows shortcuts as files for + "simplicity + if hardPath !~# '\.lnk$' + + let self.symLinkDest = self.symLinkDest . '/' + endif + endif + endif +endfunction + +"FUNCTION: Path.refresh() {{{1 +function! s:Path.refresh() + call self.readInfoFromDisk(self.str()) + call 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() +endfunction + +"FUNCTION: Path.rename() {{{1 +" +"Renames this node on the filesystem +function! s:Path.rename(newPath) + if a:newPath ==# '' + throw "NERDTree.InvalidArgumentsError: Invalid newPath for renaming = ". a:newPath + endif + + let success = rename(self.str(), a:newPath) + if success != 0 + throw "NERDTree.PathRenameError: Could not rename: '" . self.str() . "'" . 'to:' . a:newPath + endif + call self.readInfoFromDisk(a:newPath) + + for i in self.bookmarkNames() + let b = g:NERDTreeBookmark.BookmarkFor(i) + call b.setPath(copy(self)) + endfor + call g:NERDTreeBookmark.Write() +endfunction + +"FUNCTION: Path.str() {{{1 +" +"Returns a string representation of this Path +" +"Takes an optional dictionary param to specify how the output should be +"formatted. +" +"The dict may have the following keys: +" 'format' +" 'escape' +" 'truncateTo' +" +"The 'format' key may have a value of: +" 'Cd' - a string to be used with the :cd command +" 'Edit' - a string to be used with :e :sp :new :tabedit etc +" 'UI' - a string used in the NERD tree UI +" +"The 'escape' key, if specified will cause the output to be escaped with +"shellescape() +" +"The 'truncateTo' key causes the resulting string to be truncated to the value +"'truncateTo' maps to. A '<' char will be prepended. +function! s:Path.str(...) + let options = a:0 ? a:1 : {} + let toReturn = "" + + if has_key(options, 'format') + let format = options['format'] + if has_key(self, '_strFor' . format) + exec 'let toReturn = self._strFor' . format . '()' + else + throw 'NERDTree.UnknownFormatError: unknown format "'. format .'"' + endif + else + let toReturn = self._str() + endif + + if nerdtree#has_opt(options, 'escape') + let toReturn = shellescape(toReturn) + endif + + if has_key(options, 'truncateTo') + let limit = options['truncateTo'] + if len(toReturn) > limit-1 + let toReturn = toReturn[(len(toReturn)-limit+1):] + if len(split(toReturn, '/')) > 1 + let toReturn = '</' . join(split(toReturn, '/')[1:], '/') . '/' + else + let toReturn = '<' . toReturn + endif + endif + endif + + return toReturn +endfunction + +"FUNCTION: Path._strForUI() {{{1 +function! s:Path._strForUI() + let toReturn = '/' . join(self.pathSegments, '/') + if self.isDirectory && toReturn != '/' + let toReturn = toReturn . '/' + endif + return toReturn +endfunction + +"FUNCTION: Path._strForCd() {{{1 +" +" returns a string that can be used with :cd +function! s:Path._strForCd() + return escape(self.str(), self._escChars()) +endfunction + +"FUNCTION: Path._strForEdit() {{{1 +" +"Return: the string for this path that is suitable to be used with the :edit +"command +function! s:Path._strForEdit() + let p = escape(self.str(), self._escChars()) + + "make it relative + let p = fnamemodify(p, ':.') + + "handle the edge case where the file begins with a + (vim interprets + "the +foo in `:e +foo` as an option to :edit) + if p[0] == "+" + let p = '\' . p + endif + + if p ==# '' + let p = '.' + endif + + return p +endfunction + +"FUNCTION: Path._strForGlob() {{{1 +function! s:Path._strForGlob() + let lead = s:Path.Slash() + + "if we are running windows then slap a drive letter on the front + if nerdtree#runningWindows() + let lead = self.drive . '\' + endif + + let toReturn = lead . join(self.pathSegments, s:Path.Slash()) + + if !nerdtree#runningWindows() + let toReturn = escape(toReturn, self._escChars()) + endif + return toReturn +endfunction + +"FUNCTION: Path._str() {{{1 +" +"Gets the string path for this path object that is appropriate for the OS. +"EG, in windows c:\foo\bar +" in *nix /foo/bar +function! s:Path._str() + let lead = s:Path.Slash() + + "if we are running windows then slap a drive letter on the front + if nerdtree#runningWindows() + let lead = self.drive . '\' + endif + + return lead . join(self.pathSegments, s:Path.Slash()) +endfunction + +"FUNCTION: Path.strTrunk() {{{1 +"Gets the path without the last segment on the end. +function! s:Path.strTrunk() + return self.drive . '/' . join(self.pathSegments[0:-2], '/') +endfunction + +" FUNCTION: Path.tabnr() {{{1 +" return the number of the first tab that is displaying this file +" +" return 0 if no tab was found +function! s:Path.tabnr() + let str = self.str() + for t in range(tabpagenr('$')) + for b in tabpagebuflist(t+1) + if str == expand('#' . b . ':p') + return t+1 + endif + endfor + endfor + return 0 +endfunction + +"FUNCTION: Path.WinToUnixPath(pathstr){{{1 +"Takes in a windows path and returns the unix equiv +" +"A class level method +" +"Args: +"pathstr: the windows path to convert +function! s:Path.WinToUnixPath(pathstr) + if !nerdtree#runningWindows() + return a:pathstr + endif + + let toReturn = a:pathstr + + "remove the x:\ of the front + let toReturn = substitute(toReturn, '^.*:\(\\\|/\)\?', '/', "") + + "remove the \\ network share from the front + let toReturn = substitute(toReturn, '^\(\\\\\|\/\/\)[^\\\/]*\(\\\|\/\)[^\\\/]*\(\\\|\/\)\?', '/', "") + + "convert all \ chars to / + let toReturn = substitute(toReturn, '\', '/', "g") + + return toReturn +endfunction + +" vim: set sw=4 sts=4 et fdm=marker: diff --git a/vim/.vim/lib/nerdtree/tree_dir_node.vim b/vim/.vim/lib/nerdtree/tree_dir_node.vim @@ -0,0 +1,551 @@ +"CLASS: TreeDirNode +"A subclass of NERDTreeFileNode. +" +"The 'composite' part of the file/dir composite. +"============================================================ +let s:TreeDirNode = copy(g:NERDTreeFileNode) +let g:NERDTreeDirNode = s:TreeDirNode + +"FUNCTION: TreeDirNode.AbsoluteTreeRoot(){{{1 +"class method that returns the highest cached ancestor of the current root +function! s:TreeDirNode.AbsoluteTreeRoot() + let currentNode = b:NERDTreeRoot + while currentNode.parent != {} + let currentNode = currentNode.parent + endwhile + return currentNode +endfunction + +"FUNCTION: TreeDirNode.activate([options]) {{{1 +unlet s:TreeDirNode.activate +function! s:TreeDirNode.activate(...) + let opts = a:0 ? a:1 : {} + call self.toggleOpen(opts) + call b:NERDTree.render() + call self.putCursorHere(0, 0) +endfunction + +"FUNCTION: TreeDirNode.addChild(treenode, inOrder) {{{1 +"Adds the given treenode to the list of children for this node +" +"Args: +"-treenode: the node to add +"-inOrder: 1 if the new node should be inserted in sorted order +function! s:TreeDirNode.addChild(treenode, inOrder) + call add(self.children, a:treenode) + let a:treenode.parent = self + + if a:inOrder + call self.sortChildren() + endif +endfunction + +"FUNCTION: TreeDirNode.close() {{{1 +"Closes this directory +function! s:TreeDirNode.close() + let self.isOpen = 0 +endfunction + +"FUNCTION: TreeDirNode.closeChildren() {{{1 +"Closes all the child dir nodes of this node +function! s:TreeDirNode.closeChildren() + for i in self.children + if i.path.isDirectory + call i.close() + call i.closeChildren() + endif + endfor +endfunction + +"FUNCTION: TreeDirNode.createChild(path, inOrder) {{{1 +"Instantiates a new child node for this node with the given path. The new +"nodes parent is set to this node. +" +"Args: +"path: a Path object that this node will represent/contain +"inOrder: 1 if the new node should be inserted in sorted order +" +"Returns: +"the newly created node +function! s:TreeDirNode.createChild(path, inOrder) + let newTreeNode = g:NERDTreeFileNode.New(a:path) + call self.addChild(newTreeNode, a:inOrder) + return newTreeNode +endfunction + +"FUNCTION: TreeDirNode.findNode(path) {{{1 +"Will find one of the children (recursively) that has the given path +" +"Args: +"path: a path object +unlet s:TreeDirNode.findNode +function! s:TreeDirNode.findNode(path) + if a:path.equals(self.path) + return self + endif + if stridx(a:path.str(), self.path.str(), 0) ==# -1 + return {} + endif + + if self.path.isDirectory + for i in self.children + let retVal = i.findNode(a:path) + if retVal != {} + return retVal + endif + endfor + endif + return {} +endfunction + +"FUNCTION: TreeDirNode.getChildCount() {{{1 +"Returns the number of children this node has +function! s:TreeDirNode.getChildCount() + return len(self.children) +endfunction + +"FUNCTION: TreeDirNode.getChild(path) {{{1 +"Returns child node of this node that has the given path or {} if no such node +"exists. +" +"This function doesnt not recurse into child dir nodes +" +"Args: +"path: a path object +function! s:TreeDirNode.getChild(path) + if stridx(a:path.str(), self.path.str(), 0) ==# -1 + return {} + endif + + let index = self.getChildIndex(a:path) + if index ==# -1 + return {} + else + return self.children[index] + endif + +endfunction + +"FUNCTION: TreeDirNode.getChildByIndex(indx, visible) {{{1 +"returns the child at the given index +"Args: +"indx: the index to get the child from +"visible: 1 if only the visible children array should be used, 0 if all the +"children should be searched. +function! s:TreeDirNode.getChildByIndex(indx, visible) + let array_to_search = a:visible? self.getVisibleChildren() : self.children + if a:indx > len(array_to_search) + throw "NERDTree.InvalidArgumentsError: Index is out of bounds." + endif + return array_to_search[a:indx] +endfunction + +"FUNCTION: TreeDirNode.getChildIndex(path) {{{1 +"Returns the index of the child node of this node that has the given path or +"-1 if no such node exists. +" +"This function doesnt not recurse into child dir nodes +" +"Args: +"path: a path object +function! s:TreeDirNode.getChildIndex(path) + if stridx(a:path.str(), self.path.str(), 0) ==# -1 + return -1 + endif + + "do a binary search for the child + let a = 0 + let z = self.getChildCount() + while a < z + let mid = (a+z)/2 + let diff = a:path.compareTo(self.children[mid].path) + + if diff ==# -1 + let z = mid + elseif diff ==# 1 + let a = mid+1 + else + return mid + endif + endwhile + return -1 +endfunction + +"FUNCTION: TreeDirNode.GetSelected() {{{1 +"Returns the current node if it is a dir node, or else returns the current +"nodes parent +unlet s:TreeDirNode.GetSelected +function! s:TreeDirNode.GetSelected() + let currentDir = g:NERDTreeFileNode.GetSelected() + if currentDir != {} && !currentDir.isRoot() + if currentDir.path.isDirectory ==# 0 + let currentDir = currentDir.parent + endif + endif + return currentDir +endfunction + +"FUNCTION: TreeDirNode.getVisibleChildCount() {{{1 +"Returns the number of visible children this node has +function! s:TreeDirNode.getVisibleChildCount() + return len(self.getVisibleChildren()) +endfunction + +"FUNCTION: TreeDirNode.getVisibleChildren() {{{1 +"Returns a list of children to display for this node, in the correct order +" +"Return: +"an array of treenodes +function! s:TreeDirNode.getVisibleChildren() + let toReturn = [] + for i in self.children + if i.path.ignore() ==# 0 + call add(toReturn, i) + endif + endfor + return toReturn +endfunction + +"FUNCTION: TreeDirNode.hasVisibleChildren() {{{1 +"returns 1 if this node has any childre, 0 otherwise.. +function! s:TreeDirNode.hasVisibleChildren() + return self.getVisibleChildCount() != 0 +endfunction + +"FUNCTION: TreeDirNode._initChildren() {{{1 +"Removes all childen from this node and re-reads them +" +"Args: +"silent: 1 if the function should not echo any "please wait" messages for +"large directories +" +"Return: the number of child nodes read +function! s:TreeDirNode._initChildren(silent) + "remove all the current child nodes + let self.children = [] + + "get an array of all the files in the nodes dir + let dir = self.path + let globDir = dir.str({'format': 'Glob'}) + + if version >= 703 + let filesStr = globpath(globDir, '*', !g:NERDTreeRespectWildIgnore) . "\n" . globpath(globDir, '.*', !g:NERDTreeRespectWildIgnore) + else + let filesStr = globpath(globDir, '*') . "\n" . globpath(globDir, '.*') + endif + + let files = split(filesStr, "\n") + + if !a:silent && len(files) > g:NERDTreeNotificationThreshold + call nerdtree#echo("Please wait, caching a large dir ...") + endif + + let invalidFilesFound = 0 + for i in files + + "filter out the .. and . directories + "Note: we must match .. AND ../ cos sometimes the globpath returns + "../ for path with strange chars (eg $) +" if i !~# '\/\.\.\/\?$' && i !~# '\/\.\/\?$' +" + " Regular expression is too expensive. Use simply string comparison + " instead + if i[len(i)-3:2] != ".." && i[len(i)-2:2] != ".." && + \ i[len(i)-2:1] != "." && i[len(i)-1] != "." + "put the next file in a new node and attach it + try + let path = g:NERDTreePath.New(i) + call self.createChild(path, 0) + call g:NERDTreePathNotifier.NotifyListeners('init', path, {}) + catch /^NERDTree.\(InvalidArguments\|InvalidFiletype\)Error/ + let invalidFilesFound += 1 + endtry + endif + endfor + + call self.sortChildren() + + if !a:silent && len(files) > g:NERDTreeNotificationThreshold + call nerdtree#echo("Please wait, caching a large dir ... DONE (". self.getChildCount() ." nodes cached).") + endif + + if invalidFilesFound + call nerdtree#echoWarning(invalidFilesFound . " file(s) could not be loaded into the NERD tree") + endif + return self.getChildCount() +endfunction + +"FUNCTION: TreeDirNode.New(path) {{{1 +"Returns a new TreeNode object with the given path and parent +" +"Args: +"path: a path object representing the full filesystem path to the file/dir that the node represents +unlet s:TreeDirNode.New +function! s:TreeDirNode.New(path) + if a:path.isDirectory != 1 + throw "NERDTree.InvalidArgumentsError: A TreeDirNode object must be instantiated with a directory Path object." + endif + + let newTreeNode = copy(self) + let newTreeNode.path = a:path + + let newTreeNode.isOpen = 0 + let newTreeNode.children = [] + + let newTreeNode.parent = {} + + return newTreeNode +endfunction + +"FUNCTION: TreeDirNode.open([opts]) {{{1 +"Open the dir in the current tree or in a new tree elsewhere. +" +"If opening in the current tree, return the number of cached nodes. +unlet s:TreeDirNode.open +function! s:TreeDirNode.open(...) + let opts = a:0 ? a:1 : {} + + if has_key(opts, 'where') && !empty(opts['where']) + let opener = g:NERDTreeOpener.New(self.path, opts) + call opener.open(self) + else + let self.isOpen = 1 + if self.children ==# [] + return self._initChildren(0) + else + return 0 + endif + endif +endfunction + +"FUNCTION: TreeDirNode.openAlong([opts]) {{{1 +"recursive open the dir if it has only one directory child. +" +"return the level of opened directories. +function! s:TreeDirNode.openAlong(...) + let opts = a:0 ? a:1 : {} + let level = 0 + + let node = self + while node.path.isDirectory + call node.open(opts) + let level += 1 + if node.getVisibleChildCount() == 1 + let node = node.getChildByIndex(0, 1) + else + break + endif + endwhile + return level +endfunction + +" FUNCTION: TreeDirNode.openExplorer() {{{1 +" opens an explorer window for this node in the previous window (could be a +" nerd tree or a netrw) +function! s:TreeDirNode.openExplorer() + call self.open({'where': 'p'}) +endfunction + +"FUNCTION: TreeDirNode.openInNewTab(options) {{{1 +unlet s:TreeDirNode.openInNewTab +function! s:TreeDirNode.openInNewTab(options) + call nerdtree#deprecated('TreeDirNode.openInNewTab', 'is deprecated, use open() instead') + call self.open({'where': 't'}) +endfunction + +"FUNCTION: TreeDirNode._openInNewTab() {{{1 +function! s:TreeDirNode._openInNewTab() + tabnew + call g:NERDTreeCreator.CreatePrimary(self.path.str()) +endfunction + +"FUNCTION: TreeDirNode.openRecursively() {{{1 +"Opens this treenode and all of its children whose paths arent 'ignored' +"because of the file filters. +" +"This method is actually a wrapper for the OpenRecursively2 method which does +"the work. +function! s:TreeDirNode.openRecursively() + call self._openRecursively2(1) +endfunction + +"FUNCTION: TreeDirNode._openRecursively2() {{{1 +"Opens this all children of this treenode recursively if either: +" *they arent filtered by file filters +" *a:forceOpen is 1 +" +"Args: +"forceOpen: 1 if this node should be opened regardless of file filters +function! s:TreeDirNode._openRecursively2(forceOpen) + if self.path.ignore() ==# 0 || a:forceOpen + let self.isOpen = 1 + if self.children ==# [] + call self._initChildren(1) + endif + + for i in self.children + if i.path.isDirectory ==# 1 + call i._openRecursively2(0) + endif + endfor + endif +endfunction + +"FUNCTION: TreeDirNode.refresh() {{{1 +unlet s:TreeDirNode.refresh +function! s:TreeDirNode.refresh() + call self.path.refresh() + + "if this node was ever opened, refresh its children + if self.isOpen || !empty(self.children) + "go thru all the files/dirs under this node + let newChildNodes = [] + let invalidFilesFound = 0 + let dir = self.path + let globDir = dir.str({'format': 'Glob'}) + let filesStr = globpath(globDir, '*') . "\n" . globpath(globDir, '.*') + let files = split(filesStr, "\n") + for i in files + "filter out the .. and . directories + "Note: we must match .. AND ../ cos sometimes the globpath returns + "../ for path with strange chars (eg $) + "if i !~# '\/\.\.\/\?$' && i !~# '\/\.\/\?$' + + " Regular expression is too expensive. Use simply string comparison + " instead + if i[len(i)-3:2] != ".." && i[len(i)-2:2] != ".." && + \ i[len(i)-2:1] != "." && i[len(i)-1] != "." + try + "create a new path and see if it exists in this nodes children + let path = g:NERDTreePath.New(i) + let newNode = self.getChild(path) + if newNode != {} + call newNode.refresh() + call add(newChildNodes, newNode) + + "the node doesnt exist so create it + else + let newNode = g:NERDTreeFileNode.New(path) + let newNode.parent = self + call add(newChildNodes, newNode) + endif + + + catch /^NERDTree.\(InvalidArguments\|InvalidFiletype\)Error/ + let invalidFilesFound = 1 + endtry + endif + endfor + + "swap this nodes children out for the children we just read/refreshed + let self.children = newChildNodes + call self.sortChildren() + + if invalidFilesFound + call nerdtree#echoWarning("some files could not be loaded into the NERD tree") + endif + endif +endfunction + +"FUNCTION: TreeDirNode.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 +"reveal the given path, i.e. cache and open all treenodes needed to display it +"in the UI +function! s:TreeDirNode.reveal(path) + if !a:path.isUnder(self.path) + throw "NERDTree.InvalidArgumentsError: " . a:path.str() . " should be under " . self.path.str() + endif + + call self.open() + + if self.path.equals(a:path.getParent()) + let n = self.findNode(a:path) + call b:NERDTree.render() + call n.putCursorHere(1,0) + return + endif + + let p = a:path + while !p.getParent().equals(self.path) + let p = p.getParent() + endwhile + + let n = self.findNode(p) + call n.reveal(a:path) +endfunction + +"FUNCTION: TreeDirNode.removeChild(treenode) {{{1 +" +"Removes the given treenode from this nodes set of children +" +"Args: +"treenode: the node to remove +" +"Throws a NERDTree.ChildNotFoundError if the given treenode is not found +function! s:TreeDirNode.removeChild(treenode) + for i in range(0, self.getChildCount()-1) + if self.children[i].equals(a:treenode) + call remove(self.children, i) + return + endif + endfor + + throw "NERDTree.ChildNotFoundError: child node was not found" +endfunction + +"FUNCTION: TreeDirNode.sortChildren() {{{1 +" +"Sorts the children of this node according to alphabetical order and the +"directory priority. +" +function! s:TreeDirNode.sortChildren() + let CompareFunc = function("nerdtree#compareNodesBySortKey") + call sort(self.children, CompareFunc) +endfunction + +"FUNCTION: TreeDirNode.toggleOpen([options]) {{{1 +"Opens this directory if it is closed and vice versa +function! s:TreeDirNode.toggleOpen(...) + let opts = a:0 ? a:1 : {} + if self.isOpen ==# 1 + call self.close() + else + if g:NERDTreeCascadeOpenSingleChildDir == 0 + call self.open(opts) + else + call self.openAlong(opts) + endif + endif +endfunction + +"FUNCTION: TreeDirNode.transplantChild(newNode) {{{1 +"Replaces the child of this with the given node (where the child node's full +"path matches a:newNode's fullpath). The search for the matching node is +"non-recursive +" +"Arg: +"newNode: the node to graft into the tree +function! s:TreeDirNode.transplantChild(newNode) + for i in range(0, self.getChildCount()-1) + if self.children[i].equals(a:newNode) + let self.children[i] = a:newNode + let a:newNode.parent = self + break + endif + endfor +endfunction + +" vim: set sw=4 sts=4 et fdm=marker: diff --git a/vim/.vim/lib/nerdtree/tree_file_node.vim b/vim/.vim/lib/nerdtree/tree_file_node.vim @@ -0,0 +1,431 @@ +"CLASS: TreeFileNode +"This class is the parent of the TreeDirNode class and is the +"'Component' part of the composite design pattern between the treenode +"classes. +"============================================================ +let s:TreeFileNode = {} +let g:NERDTreeFileNode = s:TreeFileNode + +"FUNCTION: TreeFileNode.activate(...) {{{1 +function! s:TreeFileNode.activate(...) + call self.open(a:0 ? a:1 : {}) +endfunction + +"FUNCTION: TreeFileNode.bookmark(name) {{{1 +"bookmark this node with a:name +function! s:TreeFileNode.bookmark(name) + + "if a bookmark exists with the same name and the node is cached then save + "it so we can update its display string + let oldMarkedNode = {} + try + let oldMarkedNode = g:NERDTreeBookmark.GetNodeForName(a:name, 1) + catch /^NERDTree.BookmarkNotFoundError/ + catch /^NERDTree.BookmarkedNodeNotFoundError/ + endtry + + call g:NERDTreeBookmark.AddBookmark(a:name, self.path) + call self.path.cacheDisplayString() + call g:NERDTreeBookmark.Write() + + if !empty(oldMarkedNode) + call oldMarkedNode.path.cacheDisplayString() + endif +endfunction + +"FUNCTION: TreeFileNode.cacheParent() {{{1 +"initializes self.parent if it isnt already +function! s:TreeFileNode.cacheParent() + if empty(self.parent) + let parentPath = self.path.getParent() + if parentPath.equals(self.path) + throw "NERDTree.CannotCacheParentError: already at root" + endif + let self.parent = s:TreeFileNode.New(parentPath) + endif +endfunction + +"FUNCTION: TreeFileNode.clearBookmarks() {{{1 +function! s:TreeFileNode.clearBookmarks() + for i in g:NERDTreeBookmark.Bookmarks() + if i.path.equals(self.path) + call i.delete() + end + endfor + call self.path.cacheDisplayString() +endfunction + +"FUNCTION: TreeFileNode.copy(dest) {{{1 +function! s:TreeFileNode.copy(dest) + call self.path.copy(a:dest) + let newPath = g:NERDTreePath.New(a:dest) + let parent = b:NERDTreeRoot.findNode(newPath.getParent()) + if !empty(parent) + call parent.refresh() + return parent.findNode(newPath) + else + return {} + endif +endfunction + +"FUNCTION: TreeFileNode.delete {{{1 +"Removes this node from the tree and calls the Delete method for its path obj +function! s:TreeFileNode.delete() + call self.path.delete() + call self.parent.removeChild(self) +endfunction + +"FUNCTION: TreeFileNode.displayString() {{{1 +" +"Returns a string that specifies how the node should be represented as a +"string +" +"Return: +"a string that can be used in the view to represent this node +function! s:TreeFileNode.displayString() + return self.path.displayString() +endfunction + +"FUNCTION: TreeFileNode.equals(treenode) {{{1 +" +"Compares this treenode to the input treenode and returns 1 if they are the +"same node. +" +"Use this method instead of == because sometimes when the treenodes contain +"many children, vim seg faults when doing == +" +"Args: +"treenode: the other treenode to compare to +function! s:TreeFileNode.equals(treenode) + return self.path.str() ==# a:treenode.path.str() +endfunction + +"FUNCTION: TreeFileNode.findNode(path) {{{1 +"Returns self if this node.path.Equals the given path. +"Returns {} if not equal. +" +"Args: +"path: the path object to compare against +function! s:TreeFileNode.findNode(path) + if a:path.equals(self.path) + return self + endif + return {} +endfunction + +"FUNCTION: TreeFileNode.findOpenDirSiblingWithVisibleChildren(direction) {{{1 +" +"Finds the next sibling for this node in the indicated direction. This sibling +"must be a directory and may/may not have children as specified. +" +"Args: +"direction: 0 if you want to find the previous sibling, 1 for the next sibling +" +"Return: +"a treenode object or {} if no appropriate sibling could be found +function! s:TreeFileNode.findOpenDirSiblingWithVisibleChildren(direction) + "if we have no parent then we can have no siblings + if self.parent != {} + let nextSibling = self.findSibling(a:direction) + + while nextSibling != {} + if nextSibling.path.isDirectory && nextSibling.hasVisibleChildren() && nextSibling.isOpen + return nextSibling + endif + let nextSibling = nextSibling.findSibling(a:direction) + endwhile + endif + + return {} +endfunction + +"FUNCTION: TreeFileNode.findSibling(direction) {{{1 +" +"Finds the next sibling for this node in the indicated direction +" +"Args: +"direction: 0 if you want to find the previous sibling, 1 for the next sibling +" +"Return: +"a treenode object or {} if no sibling could be found +function! s:TreeFileNode.findSibling(direction) + "if we have no parent then we can have no siblings + if self.parent != {} + + "get the index of this node in its parents children + let siblingIndx = self.parent.getChildIndex(self.path) + + if siblingIndx != -1 + "move a long to the next potential sibling node + let siblingIndx = a:direction ==# 1 ? siblingIndx+1 : siblingIndx-1 + + "keep moving along to the next sibling till we find one that is valid + let numSiblings = self.parent.getChildCount() + while siblingIndx >= 0 && siblingIndx < numSiblings + + "if the next node is not an ignored node (i.e. wont show up in the + "view) then return it + if self.parent.children[siblingIndx].path.ignore() ==# 0 + return self.parent.children[siblingIndx] + endif + + "go to next node + let siblingIndx = a:direction ==# 1 ? siblingIndx+1 : siblingIndx-1 + endwhile + endif + endif + + return {} +endfunction + +"FUNCTION: TreeFileNode.GetRootForTab(){{{1 +"get the root node for this tab +function! s:TreeFileNode.GetRootForTab() + if g:NERDTree.ExistsForTab() + return getbufvar(t:NERDTreeBufName, 'NERDTreeRoot') + end + return {} +endfunction + +"FUNCTION: TreeFileNode.GetSelected() {{{1 +"gets the treenode that the cursor is currently over +function! s:TreeFileNode.GetSelected() + try + let path = b:NERDTree.ui.getPath(line(".")) + if path ==# {} + return {} + endif + return b:NERDTreeRoot.findNode(path) + catch /^NERDTree/ + return {} + endtry +endfunction + +"FUNCTION: TreeFileNode.isVisible() {{{1 +"returns 1 if this node should be visible according to the tree filters and +"hidden file filters (and their on/off status) +function! s:TreeFileNode.isVisible() + return !self.path.ignore() +endfunction + +"FUNCTION: TreeFileNode.isRoot() {{{1 +"returns 1 if this node is b:NERDTreeRoot +function! s:TreeFileNode.isRoot() + if !g:NERDTree.ExistsForBuf() + throw "NERDTree.NoTreeError: No tree exists for the current buffer" + endif + + return self.equals(b:NERDTreeRoot) +endfunction + +"FUNCTION: TreeFileNode.makeRoot() {{{1 +"Make this node the root of the tree +function! s:TreeFileNode.makeRoot() + if self.path.isDirectory + let b:NERDTreeRoot = self + else + call self.cacheParent() + let b:NERDTreeRoot = self.parent + endif + + call b:NERDTreeRoot.open() + + "change dir to the dir of the new root if instructed to + if g:NERDTreeChDirMode ==# 2 + exec "cd " . b:NERDTreeRoot.path.str({'format': 'Edit'}) + endif + + silent doautocmd User NERDTreeNewRoot +endfunction + +"FUNCTION: TreeFileNode.New(path) {{{1 +"Returns a new TreeNode object with the given path and parent +" +"Args: +"path: a path object representing the full filesystem path to the file/dir that the node represents +function! s:TreeFileNode.New(path) + if a:path.isDirectory + return g:NERDTreeDirNode.New(a:path) + else + let newTreeNode = copy(self) + let newTreeNode.path = a:path + let newTreeNode.parent = {} + return newTreeNode + endif +endfunction + +"FUNCTION: TreeFileNode.open() {{{1 +function! s:TreeFileNode.open(...) + let opts = a:0 ? a:1 : {} + let opener = g:NERDTreeOpener.New(self.path, opts) + call opener.open(self) +endfunction + +"FUNCTION: TreeFileNode.openSplit() {{{1 +"Open this node in a new window +function! s:TreeFileNode.openSplit() + call nerdtree#deprecated('TreeFileNode.openSplit', 'is deprecated, use .open() instead.') + call self.open({'where': 'h'}) +endfunction + +"FUNCTION: TreeFileNode.openVSplit() {{{1 +"Open this node in a new vertical window +function! s:TreeFileNode.openVSplit() + call nerdtree#deprecated('TreeFileNode.openVSplit', 'is deprecated, use .open() instead.') + call self.open({'where': 'v'}) +endfunction + +"FUNCTION: TreeFileNode.openInNewTab(options) {{{1 +function! s:TreeFileNode.openInNewTab(options) + echomsg 'TreeFileNode.openInNewTab is deprecated' + call self.open(extend({'where': 't'}, a:options)) +endfunction + +"FUNCTION: TreeFileNode.putCursorHere(isJump, recurseUpward){{{1 +"Places the cursor on the line number this node is rendered on +" +"Args: +"isJump: 1 if this cursor movement should be counted as a jump by vim +"recurseUpward: try to put the cursor on the parent if the this node isnt +"visible +function! s:TreeFileNode.putCursorHere(isJump, recurseUpward) + let ln = b:NERDTree.ui.getLineNum(self) + if ln != -1 + if a:isJump + mark ' + endif + call cursor(ln, col(".")) + else + if a:recurseUpward + let node = self + while node != {} && b:NERDTree.ui.getLineNum(node) ==# -1 + let node = node.parent + call node.open() + endwhile + call b:NERDTree.render() + call node.putCursorHere(a:isJump, 0) + endif + endif +endfunction + +"FUNCTION: TreeFileNode.refresh() {{{1 +function! s:TreeFileNode.refresh() + call self.path.refresh() +endfunction + +"FUNCTION: TreeFileNode.refreshFlags() {{{1 +function! s:TreeFileNode.refreshFlags() + call self.path.refreshFlags() +endfunction + +"FUNCTION: TreeFileNode.rename() {{{1 +"Calls the rename method for this nodes path obj +function! s:TreeFileNode.rename(newName) + let newName = substitute(a:newName, '\(\\\|\/\)$', '', '') + call self.path.rename(newName) + call self.parent.removeChild(self) + + let parentPath = self.path.getParent() + let newParent = b:NERDTreeRoot.findNode(parentPath) + + if newParent != {} + call newParent.createChild(self.path, 1) + call newParent.refresh() + endif +endfunction + +"FUNCTION: TreeFileNode.renderToString {{{1 +"returns a string representation for this tree to be rendered in the view +function! s:TreeFileNode.renderToString() + return self._renderToString(0, 0, [], self.getChildCount() ==# 1) +endfunction + +"Args: +"depth: the current depth in the tree for this call +"drawText: 1 if we should actually draw the line for this node (if 0 then the +"child nodes are rendered only) +"vertMap: a binary array that indicates whether a vertical bar should be draw +"for each depth in the tree +"isLastChild:true if this curNode is the last child of its parent +function! s:TreeFileNode._renderToString(depth, drawText, vertMap, isLastChild) + let output = "" + if a:drawText ==# 1 + + let treeParts = '' + + "get all the leading spaces and vertical tree parts for this line + if a:depth > 1 + for j in a:vertMap[0:-2] + if g:NERDTreeDirArrows + let treeParts = treeParts . ' ' + else + if j ==# 1 + let treeParts = treeParts . '| ' + else + let treeParts = treeParts . ' ' + endif + endif + endfor + endif + + "get the last vertical tree part for this line which will be different + "if this node is the last child of its parent + if !g:NERDTreeDirArrows + if a:isLastChild + let treeParts = treeParts . '`' + else + let treeParts = treeParts . '|' + endif + endif + + "smack the appropriate dir/file symbol on the line before the file/dir + "name itself + if self.path.isDirectory + if self.isOpen + if g:NERDTreeDirArrows + let treeParts = treeParts . '▾ ' + else + let treeParts = treeParts . '~' + endif + else + if g:NERDTreeDirArrows + let treeParts = treeParts . '▸ ' + else + let treeParts = treeParts . '+' + endif + endif + else + if g:NERDTreeDirArrows + let treeParts = treeParts . ' ' + else + let treeParts = treeParts . '-' + endif + endif + let line = treeParts . self.displayString() + + let output = output . line . "\n" + endif + + "if the node is an open dir, draw its children + if self.path.isDirectory ==# 1 && self.isOpen ==# 1 + + let childNodesToDraw = self.getVisibleChildren() + if len(childNodesToDraw) > 0 + + "draw all the nodes children except the last + let lastIndx = len(childNodesToDraw)-1 + if lastIndx > 0 + for i in childNodesToDraw[0:lastIndx-1] + let output = output . i._renderToString(a:depth + 1, 1, add(copy(a:vertMap), 1), 0) + endfor + endif + + "draw the last child, indicating that it IS the last + let output = output . childNodesToDraw[lastIndx]._renderToString(a:depth + 1, 1, add(copy(a:vertMap), 0), 1) + endif + endif + + return output +endfunction + +" vim: set sw=4 sts=4 et fdm=marker: diff --git a/vim/.vim/lib/nerdtree/ui.vim b/vim/.vim/lib/nerdtree/ui.vim @@ -0,0 +1,506 @@ +"CLASS: UI +"============================================================ +let s:UI = {} +let g:NERDTreeUI = s:UI + +"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(g:NERDTree.GetWinNum()) - current_line + if lines_to_top < g:NERDTreeAutoCenterThreshold || lines_to_bottom < g:NERDTreeAutoCenterThreshold + normal! zz + endif + endif +endfunction + +"FUNCTION: s:UI._dumpHelp {{{1 +"prints out the quick help +function! s:UI._dumpHelp() + let old_h = @h + if b:treeShowHelp ==# 1 + let @h= "\" NERD tree (" . nerdtree#version() . ") quickhelp~\n" + let @h=@h."\" ============================\n" + let @h=@h."\" File node mappings~\n" + let @h=@h."\" ". (g:NERDTreeMouseMode ==# 3 ? "single" : "double") ."-click,\n" + let @h=@h."\" <CR>,\n" + if b:NERDTreeType ==# "primary" + let @h=@h."\" ". g:NERDTreeMapActivateNode .": open in prev window\n" + else + let @h=@h."\" ". g:NERDTreeMapActivateNode .": open in current window\n" + endif + if b:NERDTreeType ==# "primary" + let @h=@h."\" ". g:NERDTreeMapPreview .": preview\n" + endif + let @h=@h."\" ". g:NERDTreeMapOpenInTab.": open in new tab\n" + let @h=@h."\" ". g:NERDTreeMapOpenInTabSilent .": open in new tab silently\n" + let @h=@h."\" middle-click,\n" + let @h=@h."\" ". g:NERDTreeMapOpenSplit .": open split\n" + let @h=@h."\" ". g:NERDTreeMapPreviewSplit .": preview split\n" + let @h=@h."\" ". g:NERDTreeMapOpenVSplit .": open vsplit\n" + let @h=@h."\" ". g:NERDTreeMapPreviewVSplit .": preview vsplit\n" + + let @h=@h."\"\n\" ----------------------------\n" + let @h=@h."\" Directory node mappings~\n" + let @h=@h."\" ". (g:NERDTreeMouseMode ==# 1 ? "double" : "single") ."-click,\n" + let @h=@h."\" ". g:NERDTreeMapActivateNode .": open & close node\n" + let @h=@h."\" ". g:NERDTreeMapOpenRecursively .": recursively open node\n" + let @h=@h."\" ". g:NERDTreeMapCloseDir .": close parent of node\n" + let @h=@h."\" ". g:NERDTreeMapCloseChildren .": close all child nodes of\n" + let @h=@h."\" current node recursively\n" + let @h=@h."\" middle-click,\n" + let @h=@h."\" ". g:NERDTreeMapOpenExpl.": explore selected dir\n" + + let @h=@h."\"\n\" ----------------------------\n" + let @h=@h."\" Bookmark table mappings~\n" + let @h=@h."\" double-click,\n" + let @h=@h."\" ". g:NERDTreeMapActivateNode .": open bookmark\n" + let @h=@h."\" ". g:NERDTreeMapOpenInTab.": open in new tab\n" + let @h=@h."\" ". g:NERDTreeMapOpenInTabSilent .": open in new tab silently\n" + let @h=@h."\" ". g:NERDTreeMapDeleteBookmark .": delete bookmark\n" + + let @h=@h."\"\n\" ----------------------------\n" + let @h=@h."\" Tree navigation mappings~\n" + let @h=@h."\" ". g:NERDTreeMapJumpRoot .": go to root\n" + let @h=@h."\" ". g:NERDTreeMapJumpParent .": go to parent\n" + let @h=@h."\" ". g:NERDTreeMapJumpFirstChild .": go to first child\n" + let @h=@h."\" ". g:NERDTreeMapJumpLastChild .": go to last child\n" + let @h=@h."\" ". g:NERDTreeMapJumpNextSibling .": go to next sibling\n" + let @h=@h."\" ". g:NERDTreeMapJumpPrevSibling .": go to prev sibling\n" + + let @h=@h."\"\n\" ----------------------------\n" + let @h=@h."\" Filesystem mappings~\n" + let @h=@h."\" ". g:NERDTreeMapChangeRoot .": change tree root to the\n" + let @h=@h."\" selected dir\n" + let @h=@h."\" ". g:NERDTreeMapUpdir .": move tree root up a dir\n" + let @h=@h."\" ". g:NERDTreeMapUpdirKeepOpen .": move tree root up a dir\n" + let @h=@h."\" but leave old root open\n" + let @h=@h."\" ". g:NERDTreeMapRefresh .": refresh cursor dir\n" + let @h=@h."\" ". g:NERDTreeMapRefreshRoot .": refresh current root\n" + let @h=@h."\" ". g:NERDTreeMapMenu .": Show menu\n" + let @h=@h."\" ". g:NERDTreeMapChdir .":change the CWD to the\n" + let @h=@h."\" selected dir\n" + let @h=@h."\" ". g:NERDTreeMapCWD .":change tree root to CWD\n" + + let @h=@h."\"\n\" ----------------------------\n" + let @h=@h."\" Tree filtering mappings~\n" + let @h=@h."\" ". g:NERDTreeMapToggleHidden .": hidden files (" . (b:NERDTreeShowHidden ? "on" : "off") . ")\n" + let @h=@h."\" ". g:NERDTreeMapToggleFilters .": file filters (" . (b:NERDTreeIgnoreEnabled ? "on" : "off") . ")\n" + let @h=@h."\" ". g:NERDTreeMapToggleFiles .": files (" . (b:NERDTreeShowFiles ? "on" : "off") . ")\n" + let @h=@h."\" ". g:NERDTreeMapToggleBookmarks .": bookmarks (" . (b:NERDTreeShowBookmarks ? "on" : "off") . ")\n" + + "add quickhelp entries for each custom key map + let @h=@h."\"\n\" ----------------------------\n" + let @h=@h."\" Custom mappings~\n" + for i in g:NERDTreeKeyMap.All() + if !empty(i.quickhelpText) + let @h=@h."\" ". i.key .": ". i.quickhelpText ."\n" + endif + endfor + + let @h=@h."\"\n\" ----------------------------\n" + let @h=@h."\" Other mappings~\n" + let @h=@h."\" ". g:NERDTreeMapQuit .": Close the NERDTree window\n" + let @h=@h."\" ". g:NERDTreeMapToggleZoom .": Zoom (maximize-minimize)\n" + let @h=@h."\" the NERDTree window\n" + let @h=@h."\" ". g:NERDTreeMapHelp .": toggle help\n" + let @h=@h."\"\n\" ----------------------------\n" + let @h=@h."\" Bookmark commands~\n" + let @h=@h."\" :Bookmark [<name>]\n" + let @h=@h."\" :BookmarkToRoot <name>\n" + let @h=@h."\" :RevealBookmark <name>\n" + let @h=@h."\" :OpenBookmark <name>\n" + let @h=@h."\" :ClearBookmarks [<names>]\n" + let @h=@h."\" :ClearAllBookmarks\n" + silent! put h + elseif g:NERDTreeMinimalUI == 0 + let @h="\" Press ". g:NERDTreeMapHelp ." for help\n" + silent! put h + endif + + let @h = old_h +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 ==# s:UI.UpDirLine() + return b:NERDTreeRoot.path.getParent() + endif + + let indent = self._indentLevelFor(line) + + "remove the tree parts and the leading space + let curFile = self._stripMarkup(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 = self._stripMarkup(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 = self._stripMarkup(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) {{{1 +function! s:UI._indentLevelFor(line) + let level = match(a:line, '[^ \-+~▸▾`|]') / s:UI.IndentWid() + " 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.IndentWid() {{{1 +function! s:UI.IndentWid() + return 2 +endfunction + +"FUNCTION: s:UI.MarkupReg() {{{1 +function! s:UI.MarkupReg() + if g:NERDTreeDirArrows + return '^\([▾▸] \| \+[▾▸] \| \+\)' + endif + + return '^[ `|]*[\-+~]' +endfunction + +"FUNCTION: s:UI._renderBookmarks {{{1 +function! s:UI._renderBookmarks() + + if g:NERDTreeMinimalUI == 0 + call setline(line(".")+1, ">----------Bookmarks----------") + call cursor(line(".")+1, col(".")) + endif + + for i in g:NERDTreeBookmark.Bookmarks() + call setline(line(".")+1, i.str()) + call cursor(line(".")+1, col(".")) + endfor + + call setline(line(".")+1, '') + call cursor(line(".")+1, col(".")) +endfunction + +"FUNCTION: s:UI.restoreScreenState() {{{1 +" +"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() {{{1 +"Saves the current cursor position in the current buffer and the window +"scroll position +function! s:UI.saveScreenState() + let win = winnr() + call g:NERDTree.CursorToTreeWin() + 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") +endfunction + +"FUNCTION: s:UI._stripMarkup(line, removeLeadingSpaces){{{1 +"returns the given line with all the tree parts stripped off +" +"Args: +"line: the subject line +"removeLeadingSpaces: 1 if leading spaces are to be removed (leading spaces = +"any spaces before the actual text of the node) +function! s:UI._stripMarkup(line, removeLeadingSpaces) + let line = a:line + "remove the tree parts and the leading space + let line = substitute (line, g:NERDTreeUI.MarkupReg(),"","") + + "strip off any read only flag + let line = substitute (line, ' \[RO\]', "","") + + "strip off any bookmark flags + let line = substitute (line, ' {[^}]*}', "","") + + "strip off any executable flags + let line = substitute (line, '*\ze\($\| \)', "","") + + "strip off any generic flags + let line = substitute (line, '\[[^]]*\]', "","") + + let wasdir = 0 + if line =~# '/$' + let wasdir = 1 + endif + let line = substitute (line,' -> .*',"","") " remove link to + if wasdir ==# 1 + let line = substitute (line, '/\?$', '/', "") + endif + + if a:removeLeadingSpaces + let line = substitute (line, '^ *', '', '') + endif + + return line +endfunction + +"FUNCTION: s:UI.render() {{{1 +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 self._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 self._renderBookmarks() + endif + + "add the 'up a dir' line + if !g:NERDTreeMinimalUI + call setline(line(".")+1, s:UI.UpDirLine()) + 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 g:NERDTree.CursorToBookmarkTable() + 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 + +"FUNCTION: s:UI.UpDirLine() {{{1 +function! s:UI.UpDirLine() + return '.. (up a dir)' +endfunction diff --git a/vim/.vim/nerdtree_plugin/exec_menuitem.vim b/vim/.vim/nerdtree_plugin/exec_menuitem.vim @@ -0,0 +1,41 @@ +" ============================================================================ +" File: exec_menuitem.vim +" Description: plugin for NERD Tree that provides an execute file menu item +" Maintainer: Martin Grenfell <martin.grenfell at gmail dot com> +" Last Change: 22 July, 2009 +" 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_nerdtree_exec_menuitem") + finish +endif +let g:loaded_nerdtree_exec_menuitem = 1 + +call NERDTreeAddMenuItem({ + \ 'text': '(!)Execute file', + \ 'shortcut': '!', + \ 'callback': 'NERDTreeExecFile', + \ 'isActiveCallback': 'NERDTreeExecFileActive' }) + +function! NERDTreeExecFileActive() + let node = g:NERDTreeFileNode.GetSelected() + return !node.path.isDirectory && node.path.isExecutable +endfunction + +function! NERDTreeExecFile() + let treenode = g:NERDTreeFileNode.GetSelected() + echo "==========================================================\n" + echo "Complete the command to execute (add arguments etc):\n" + let cmd = treenode.path.str({'escape': 1}) + let cmd = input(':!', cmd . ' ') + + if cmd != '' + exec ':!' . cmd + else + echo "Aborted" + endif +endfunction diff --git a/vim/.vim/nerdtree_plugin/fs_menu.vim b/vim/.vim/nerdtree_plugin/fs_menu.vim @@ -0,0 +1,270 @@ +" ============================================================================ +" File: fs_menu.vim +" Description: plugin for the NERD Tree that provides a file system menu +" Maintainer: Martin Grenfell <martin.grenfell at gmail dot com> +" Last Change: 17 July, 2009 +" 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_nerdtree_fs_menu") + finish +endif +let g:loaded_nerdtree_fs_menu = 1 + +"Automatically delete the buffer after deleting or renaming a file +if !exists("g:NERDTreeAutoDeleteBuffer") + let g:NERDTreeAutoDeleteBuffer = 0 +endif + +call NERDTreeAddMenuItem({'text': '(a)dd a childnode', 'shortcut': 'a', 'callback': 'NERDTreeAddNode'}) +call NERDTreeAddMenuItem({'text': '(m)ove the current node', 'shortcut': 'm', 'callback': 'NERDTreeMoveNode'}) +call NERDTreeAddMenuItem({'text': '(d)elete the current node', 'shortcut': 'd', 'callback': 'NERDTreeDeleteNode'}) + +if has("gui_mac") || has("gui_macvim") + call NERDTreeAddMenuItem({'text': '(r)eveal in Finder the current node', 'shortcut': 'r', 'callback': 'NERDTreeRevealInFinder'}) + call NERDTreeAddMenuItem({'text': '(o)pen the current node with system editor', 'shortcut': 'o', 'callback': 'NERDTreeExecuteFile'}) + call NERDTreeAddMenuItem({'text': '(q)uicklook the current node', 'shortcut': 'q', 'callback': 'NERDTreeQuickLook'}) +endif + +if g:NERDTreePath.CopyingSupported() + call NERDTreeAddMenuItem({'text': '(c)opy the current node', 'shortcut': 'c', 'callback': 'NERDTreeCopyNode'}) +endif + +"FUNCTION: s:echo(msg){{{1 +function! s:echo(msg) + redraw + echomsg "NERDTree: " . a:msg +endfunction + +"FUNCTION: s:echoWarning(msg){{{1 +function! s:echoWarning(msg) + echohl warningmsg + call s:echo(a:msg) + echohl normal +endfunction + +"FUNCTION: s:promptToDelBuffer(bufnum, msg){{{1 +"prints out the given msg and, if the user responds by pushing 'y' then the +"buffer with the given bufnum is deleted +" +"Args: +"bufnum: the buffer that may be deleted +"msg: a message that will be echoed to the user asking them if they wish to +" del the buffer +function! s:promptToDelBuffer(bufnum, msg) + echo a:msg + if g:NERDTreeAutoDeleteBuffer || nr2char(getchar()) ==# 'y' + " 1. ensure that all windows which display the just deleted filename + " now display an empty buffer (so a layout is preserved). + " Is not it better to close single tabs with this file only ? + let s:originalTabNumber = tabpagenr() + let s:originalWindowNumber = winnr() + exec "tabdo windo if winbufnr(0) == " . a:bufnum . " | exec ':enew! ' | endif" + exec "tabnext " . s:originalTabNumber + exec s:originalWindowNumber . "wincmd w" + " 3. We don't need a previous buffer anymore + exec "bwipeout! " . a:bufnum + endif +endfunction + +"FUNCTION: s:promptToRenameBuffer(bufnum, msg){{{1 +"prints out the given msg and, if the user responds by pushing 'y' then the +"buffer with the given bufnum is replaced with a new one +" +"Args: +"bufnum: the buffer that may be deleted +"msg: a message that will be echoed to the user asking them if they wish to +" del the buffer +function! s:promptToRenameBuffer(bufnum, msg, newFileName) + echo a:msg + if g:NERDTreeAutoDeleteBuffer || nr2char(getchar()) ==# 'y' + let quotedFileName = "'" . a:newFileName . "'" + " 1. ensure that a new buffer is loaded + exec "badd " . quotedFileName + " 2. ensure that all windows which display the just deleted filename + " display a buffer for a new filename. + let s:originalTabNumber = tabpagenr() + let s:originalWindowNumber = winnr() + let editStr = g:NERDTreePath.New(a:newFileName).str({'format': 'Edit'}) + exec "tabdo windo if winbufnr(0) == " . a:bufnum . " | exec ':e! " . editStr . "' | endif" + exec "tabnext " . s:originalTabNumber + exec s:originalWindowNumber . "wincmd w" + " 3. We don't need a previous buffer anymore + exec "bwipeout! " . a:bufnum + endif +endfunction +"FUNCTION: NERDTreeAddNode(){{{1 +function! NERDTreeAddNode() + let curDirNode = g:NERDTreeDirNode.GetSelected() + + let newNodeName = input("Add a childnode\n". + \ "==========================================================\n". + \ "Enter the dir/file name to be created. Dirs end with a '/'\n" . + \ "", curDirNode.path.str() . g:NERDTreePath.Slash(), "file") + + if newNodeName ==# '' + call s:echo("Node Creation Aborted.") + return + endif + + try + let newPath = g:NERDTreePath.Create(newNodeName) + let parentNode = b:NERDTreeRoot.findNode(newPath.getParent()) + + let newTreeNode = g:NERDTreeFileNode.New(newPath) + if empty(parentNode) + call b:NERDTreeRoot.refresh() + call b:NERDTree.render() + elseif parentNode.isOpen || !empty(parentNode.children) + call parentNode.addChild(newTreeNode, 1) + call NERDTreeRender() + call newTreeNode.putCursorHere(1, 0) + endif + catch /^NERDTree/ + call s:echoWarning("Node Not Created.") + endtry +endfunction + +"FUNCTION: NERDTreeMoveNode(){{{1 +function! NERDTreeMoveNode() + let curNode = g:NERDTreeFileNode.GetSelected() + let newNodePath = input("Rename the current node\n" . + \ "==========================================================\n" . + \ "Enter the new path for the node: \n" . + \ "", curNode.path.str(), "file") + + if newNodePath ==# '' + call s:echo("Node Renaming Aborted.") + return + endif + + try + let bufnum = bufnr("^".curNode.path.str()."$") + + call curNode.rename(newNodePath) + call NERDTreeRender() + + "if the node is open in a buffer, ask the user if they want to + "close that buffer + if bufnum != -1 + let prompt = "\nNode renamed.\n\nThe old file is open in buffer ". bufnum . (bufwinnr(bufnum) ==# -1 ? " (hidden)" : "") .". Replace this buffer with a new file? (yN)" + call s:promptToRenameBuffer(bufnum, prompt, newNodePath) + endif + + call curNode.putCursorHere(1, 0) + + redraw + catch /^NERDTree/ + call s:echoWarning("Node Not Renamed.") + endtry +endfunction + +" FUNCTION: NERDTreeDeleteNode() {{{1 +function! NERDTreeDeleteNode() + let currentNode = g:NERDTreeFileNode.GetSelected() + let confirmed = 0 + + if currentNode.path.isDirectory + let choice =input("Delete the current node\n" . + \ "==========================================================\n" . + \ "STOP! To delete this entire directory, type 'yes'\n" . + \ "" . currentNode.path.str() . ": ") + let confirmed = choice ==# 'yes' + else + echo "Delete the current node\n" . + \ "==========================================================\n". + \ "Are you sure you wish to delete the node:\n" . + \ "" . currentNode.path.str() . " (yN):" + let choice = nr2char(getchar()) + let confirmed = choice ==# 'y' + endif + + + if confirmed + try + call currentNode.delete() + call NERDTreeRender() + + "if the node is open in a buffer, ask the user if they want to + "close that buffer + let bufnum = bufnr("^".currentNode.path.str()."$") + if buflisted(bufnum) + let prompt = "\nNode deleted.\n\nThe file is open in buffer ". bufnum . (bufwinnr(bufnum) ==# -1 ? " (hidden)" : "") .". Delete this buffer? (yN)" + call s:promptToDelBuffer(bufnum, prompt) + endif + + redraw + catch /^NERDTree/ + call s:echoWarning("Could not remove node") + endtry + else + call s:echo("delete aborted") + endif + +endfunction + +" FUNCTION: NERDTreeCopyNode() {{{1 +function! NERDTreeCopyNode() + let currentNode = g:NERDTreeFileNode.GetSelected() + let newNodePath = input("Copy the current node\n" . + \ "==========================================================\n" . + \ "Enter the new path to copy the node to: \n" . + \ "", currentNode.path.str(), "file") + + if newNodePath != "" + "strip trailing slash + let newNodePath = substitute(newNodePath, '\/$', '', '') + + let confirmed = 1 + if currentNode.path.copyingWillOverwrite(newNodePath) + call s:echo("Warning: copying may overwrite files! Continue? (yN)") + let choice = nr2char(getchar()) + let confirmed = choice ==# 'y' + endif + + if confirmed + try + let newNode = currentNode.copy(newNodePath) + if empty(newNode) + call b:NERDTreeRoot.refresh() + call b:NERDTree.render() + else + call NERDTreeRender() + call newNode.putCursorHere(0, 0) + endif + catch /^NERDTree/ + call s:echoWarning("Could not copy node") + endtry + endif + else + call s:echo("Copy aborted.") + endif + redraw +endfunction + +function! NERDTreeQuickLook() + let treenode = g:NERDTreeFileNode.GetSelected() + if treenode != {} + call system("qlmanage -p 2>/dev/null '" . treenode.path.str() . "'") + endif +endfunction + +function! NERDTreeRevealInFinder() + let treenode = g:NERDTreeFileNode.GetSelected() + if treenode != {} + let x = system("open -R '" . treenode.path.str() . "'") + endif +endfunction + +function! NERDTreeExecuteFile() + let treenode = g:NERDTreeFileNode.GetSelected() + if treenode != {} + let x = system("open '" . treenode.path.str() . "'") + endif +endfunction + +" vim: set sw=4 sts=4 et fdm=marker: diff --git a/vim/.vim/plugin/NERD_tree.vim b/vim/.vim/plugin/NERD_tree.vim @@ -0,0 +1,210 @@ +" ============================================================================ +" File: NERD_tree.vim +" Description: vim global plugin that provides a nice tree explorer +" Maintainer: Martin Grenfell <martin.grenfell at gmail dot com> +" Last Change: 28 December, 2011 +" 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. +" +" ============================================================================ +" +" SECTION: Script init stuff {{{1 +"============================================================ +if exists("loaded_nerd_tree") + finish +endif +if v:version < 700 + echoerr "NERDTree: this plugin requires vim >= 7. DOWNLOAD IT! You'll thank me later!" + finish +endif +let loaded_nerd_tree = 1 + +"for line continuation - i.e dont want C in &cpo +let s:old_cpo = &cpo +set cpo&vim + +"Function: s:initVariable() function {{{2 +"This function is used to initialise a given variable to a given value. The +"variable is only initialised if it does not exist prior +" +"Args: +"var: the name of the var to be initialised +"value: the value to initialise var to +" +"Returns: +"1 if the var is set, 0 otherwise +function! s:initVariable(var, value) + if !exists(a:var) + exec 'let ' . a:var . ' = ' . "'" . substitute(a:value, "'", "''", "g") . "'" + return 1 + endif + return 0 +endfunction + +"SECTION: Init variable calls and other random constants {{{2 +call s:initVariable("g:NERDTreeAutoCenter", 1) +call s:initVariable("g:NERDTreeAutoCenterThreshold", 3) +call s:initVariable("g:NERDTreeCaseSensitiveSort", 0) +call s:initVariable("g:NERDTreeSortHiddenFirst", 1) +call s:initVariable("g:NERDTreeChDirMode", 0) +call s:initVariable("g:NERDTreeMinimalUI", 0) +if !exists("g:NERDTreeIgnore") + let g:NERDTreeIgnore = ['\~$'] +endif +call s:initVariable("g:NERDTreeBookmarksFile", expand('$HOME') . '/.NERDTreeBookmarks') +call s:initVariable("g:NERDTreeBookmarksSort", 1) +call s:initVariable("g:NERDTreeHighlightCursorline", 1) +call s:initVariable("g:NERDTreeHijackNetrw", 1) +call s:initVariable("g:NERDTreeMouseMode", 1) +call s:initVariable("g:NERDTreeNotificationThreshold", 100) +call s:initVariable("g:NERDTreeQuitOnOpen", 0) +call s:initVariable("g:NERDTreeRespectWildIgnore", 0) +call s:initVariable("g:NERDTreeShowBookmarks", 0) +call s:initVariable("g:NERDTreeShowFiles", 1) +call s:initVariable("g:NERDTreeShowHidden", 0) +call s:initVariable("g:NERDTreeShowLineNumbers", 0) +call s:initVariable("g:NERDTreeSortDirs", 1) +call s:initVariable("g:NERDTreeDirArrows", !nerdtree#runningWindows()) +call s:initVariable("g:NERDTreeCascadeOpenSingleChildDir", 1) + +if !exists("g:NERDTreeSortOrder") + let g:NERDTreeSortOrder = ['\/$', '*', '\.swp$', '\.bak$', '\~$'] +else + "if there isnt a * in the sort sequence then add one + if count(g:NERDTreeSortOrder, '*') < 1 + call add(g:NERDTreeSortOrder, '*') + endif +endif + +if !exists('g:NERDTreeStatusline') + + "the exists() crap here is a hack to stop vim spazzing out when + "loading a session that was created with an open nerd tree. It spazzes + "because it doesnt store b:NERDTreeRoot (its a b: var, and its a hash) + let g:NERDTreeStatusline = "%{exists('b:NERDTreeRoot')?b:NERDTreeRoot.path.str():''}" + +endif +call s:initVariable("g:NERDTreeWinPos", "left") +call s:initVariable("g:NERDTreeWinSize", 31) + +"init the shell commands that will be used to copy nodes, and remove dir trees +" +"Note: the space after the command is important +if nerdtree#runningWindows() + call s:initVariable("g:NERDTreeRemoveDirCmd", 'rmdir /s /q ') +else + call s:initVariable("g:NERDTreeRemoveDirCmd", 'rm -rf ') + call s:initVariable("g:NERDTreeCopyCmd", 'cp -r ') +endif + + +"SECTION: Init variable calls for key mappings {{{2 +call s:initVariable("g:NERDTreeMapActivateNode", "o") +call s:initVariable("g:NERDTreeMapChangeRoot", "C") +call s:initVariable("g:NERDTreeMapChdir", "cd") +call s:initVariable("g:NERDTreeMapCloseChildren", "X") +call s:initVariable("g:NERDTreeMapCloseDir", "x") +call s:initVariable("g:NERDTreeMapDeleteBookmark", "D") +call s:initVariable("g:NERDTreeMapMenu", "m") +call s:initVariable("g:NERDTreeMapHelp", "?") +call s:initVariable("g:NERDTreeMapJumpFirstChild", "K") +call s:initVariable("g:NERDTreeMapJumpLastChild", "J") +call s:initVariable("g:NERDTreeMapJumpNextSibling", "<C-j>") +call s:initVariable("g:NERDTreeMapJumpParent", "p") +call s:initVariable("g:NERDTreeMapJumpPrevSibling", "<C-k>") +call s:initVariable("g:NERDTreeMapJumpRoot", "P") +call s:initVariable("g:NERDTreeMapOpenExpl", "e") +call s:initVariable("g:NERDTreeMapOpenInTab", "t") +call s:initVariable("g:NERDTreeMapOpenInTabSilent", "T") +call s:initVariable("g:NERDTreeMapOpenRecursively", "O") +call s:initVariable("g:NERDTreeMapOpenSplit", "i") +call s:initVariable("g:NERDTreeMapOpenVSplit", "s") +call s:initVariable("g:NERDTreeMapPreview", "g" . NERDTreeMapActivateNode) +call s:initVariable("g:NERDTreeMapPreviewSplit", "g" . NERDTreeMapOpenSplit) +call s:initVariable("g:NERDTreeMapPreviewVSplit", "g" . NERDTreeMapOpenVSplit) +call s:initVariable("g:NERDTreeMapQuit", "q") +call s:initVariable("g:NERDTreeMapRefresh", "r") +call s:initVariable("g:NERDTreeMapRefreshRoot", "R") +call s:initVariable("g:NERDTreeMapToggleBookmarks", "B") +call s:initVariable("g:NERDTreeMapToggleFiles", "F") +call s:initVariable("g:NERDTreeMapToggleFilters", "f") +call s:initVariable("g:NERDTreeMapToggleHidden", "I") +call s:initVariable("g:NERDTreeMapToggleZoom", "A") +call s:initVariable("g:NERDTreeMapUpdir", "u") +call s:initVariable("g:NERDTreeMapUpdirKeepOpen", "U") +call s:initVariable("g:NERDTreeMapCWD", "CD") + +"SECTION: Load class files{{{2 +call nerdtree#loadClassFiles() + +" SECTION: Commands {{{1 +"============================================================ +call nerdtree#ui_glue#setupCommands() + +" SECTION: Auto commands {{{1 +"============================================================ +augroup NERDTree + "Save the cursor position whenever we close the nerd tree + exec "autocmd BufLeave ". g:NERDTreeCreator.BufNamePrefix() ."* if g:NERDTree.IsOpen() | call b:NERDTree.ui.saveScreenState() | endif" + + "disallow insert mode in the NERDTree + exec "autocmd BufEnter ". g:NERDTreeCreator.BufNamePrefix() ."* stopinsert" +augroup END + +if g:NERDTreeHijackNetrw + augroup NERDTreeHijackNetrw + autocmd VimEnter * silent! autocmd! FileExplorer + au BufEnter,VimEnter * call nerdtree#checkForBrowse(expand("<amatch>")) + augroup END +endif + +" SECTION: Public API {{{1 +"============================================================ +function! NERDTreeAddMenuItem(options) + call g:NERDTreeMenuItem.Create(a:options) +endfunction + +function! NERDTreeAddMenuSeparator(...) + let opts = a:0 ? a:1 : {} + call g:NERDTreeMenuItem.CreateSeparator(opts) +endfunction + +function! NERDTreeAddSubmenu(options) + return g:NERDTreeMenuItem.Create(a:options) +endfunction + +function! NERDTreeAddKeyMap(options) + call g:NERDTreeKeyMap.Create(a:options) +endfunction + +function! NERDTreeRender() + call nerdtree#renderView() +endfunction + +function! NERDTreeFocus() + if g:NERDTree.IsOpen() + call g:NERDTree.CursorToTreeWin() + else + call g:NERDTreeCreator.TogglePrimary("") + endif +endfunction + +function! NERDTreeCWD() + call NERDTreeFocus() + call nerdtree#ui_glue#chRootCwd() +endfunction + +function! NERDTreeAddPathFilter(callback) + call g:NERDTree.AddPathFilter(a:callback) +endfunction + +" SECTION: Post Source Actions {{{1 +call nerdtree#postSourceActions() + +"reset &cpo back to users setting +let &cpo = s:old_cpo + +" vim: set sw=4 sts=4 et fdm=marker: diff --git a/vim/.vim/syntax/nerdtree.vim b/vim/.vim/syntax/nerdtree.vim @@ -0,0 +1,105 @@ +let s:tree_up_dir_line = '.. (up a dir)' +syn match NERDTreeIgnore #\~# +syn match NERDTreeIgnore #\[RO\]# + +"highlighting for the .. (up dir) line at the top of the tree +execute "syn match NERDTreeUp #\\V". s:tree_up_dir_line ."#" + +"quickhelp syntax elements +syn match NERDTreeHelpKey #" \{1,2\}[^ ]*:#ms=s+2,me=e-1 +syn match NERDTreeHelpKey #" \{1,2\}[^ ]*,#ms=s+2,me=e-1 +syn match NERDTreeHelpTitle #" .*\~#ms=s+2,me=e-1 +syn match NERDTreeToggleOn #(on)#ms=s+1,he=e-1 +syn match NERDTreeToggleOff #(off)#ms=e-3,me=e-1 +syn match NERDTreeHelpCommand #" :.\{-}\>#hs=s+3 +syn match NERDTreeHelp #^".*# contains=NERDTreeHelpKey,NERDTreeHelpTitle,NERDTreeIgnore,NERDTreeToggleOff,NERDTreeToggleOn,NERDTreeHelpCommand + +"highlighting for sym links +syn match NERDTreeLinkTarget #->.*# containedin=NERDTreeDir,NERDTreeFile +syn match NERDTreeLinkFile #.* ->#me=e-3 containedin=NERDTreeFile +syn match NERDTreeLinkDir #.*/ ->#me=e-3 containedin=NERDTreeDir + +"highlighing for directory nodes and file nodes +syn match NERDTreeDirSlash #/# containedin=NERDTreeDir + +if g:NERDTreeDirArrows + syn match NERDTreeClosable #▾# containedin=NERDTreeDir,NERDTreeFile + syn match NERDTreeOpenable #▸# containedin=NERDTreeDir,NERDTreeFile + + syn match NERDTreeDir #[^▾▸ ].*/# + syn match NERDTreeExecFile #^ .*\*\($\| \)# contains=NERDTreeRO,NERDTreeBookmark + syn match NERDTreeFile #^[^"\.▾▸] *[^▾▸]*# contains=NERDTreeLink,NERDTreeRO,NERDTreeBookmark,NERDTreeExecFile + + "highlighting for readonly files + syn match NERDTreeRO # *\zs.*\ze \[RO\]# contains=NERDTreeIgnore,NERDTreeBookmark,NERDTreeFile + + syn match NERDTreeFlags #^ *\zs\[.\]# containedin=NERDTreeFile + syn match NERDTreeFlags #\[.\]# containedin=NERDTreeDir +else + "highlighting for the ~/+ symbols for the directory nodes + syn match NERDTreeClosable #\~\<# + syn match NERDTreeClosable #\~\.# + syn match NERDTreeOpenable #+\<# + syn match NERDTreeOpenable #+\.#he=e-1 + + "highlighting for the tree structural parts + syn match NERDTreePart #|# + syn match NERDTreePart #`# + syn match NERDTreePartFile #[|`]-#hs=s+1 contains=NERDTreePart + + syn match NERDTreeDir #[^-| `].*/# contains=NERDTreeLink,NERDTreeOpenable,NERDTreeClosable + syn match NERDTreeExecFile #[|` ].*\*\($\| \)# contains=NERDTreeLink,NERDTreePart,NERDTreePartFile,NERDTreeBookmark + syn match NERDTreeFile #|-.*# contains=NERDTreeLink,NERDTreePart,NERDTreePartFile,NERDTreeBookmark,NERDTreeExecFile + syn match NERDTreeFile #`-.*# contains=NERDTreeLink,NERDTreePart,NERDTreePartFile,NERDTreeBookmark,NERDTreeExecFile + + "highlighting for readonly files + 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 + +syn match NERDTreeCWD #^[</].*$# + +"highlighting for bookmarks +syn match NERDTreeBookmark # {.*}#hs=s+1 + +"highlighting for the bookmarks table +syn match NERDTreeBookmarksLeader #^># +syn match NERDTreeBookmarksHeader #^>-\+Bookmarks-\+$# contains=NERDTreeBookmarksLeader +syn match NERDTreeBookmarkName #^>.\{-} #he=e-1 contains=NERDTreeBookmarksLeader +syn match NERDTreeBookmark #^>.*$# contains=NERDTreeBookmarksLeader,NERDTreeBookmarkName,NERDTreeBookmarksHeader + +hi def link NERDTreePart Special +hi def link NERDTreePartFile Type +hi def link NERDTreeExecFile Title +hi def link NERDTreeDirSlash Identifier + +hi def link NERDTreeBookmarksHeader statement +hi def link NERDTreeBookmarksLeader ignore +hi def link NERDTreeBookmarkName Identifier +hi def link NERDTreeBookmark normal + +hi def link NERDTreeHelp String +hi def link NERDTreeHelpKey Identifier +hi def link NERDTreeHelpCommand Identifier +hi def link NERDTreeHelpTitle Macro +hi def link NERDTreeToggleOn Question +hi def link NERDTreeToggleOff WarningMsg + +hi def link NERDTreeLinkTarget Type +hi def link NERDTreeLinkFile Macro +hi def link NERDTreeLinkDir Macro + +hi def link NERDTreeDir Directory +hi def link NERDTreeUp Directory +hi def link NERDTreeFile Normal +hi def link NERDTreeCWD Statement +hi def link NERDTreeOpenable Title +hi def link NERDTreeClosable Title +hi def link NERDTreeIgnore ignore +hi def link NERDTreeRO WarningMsg +hi def link NERDTreeBookmark Statement +hi def link NERDTreeFlags Number + +hi def link NERDTreeCurrentNode Search diff --git a/vim/.vimrc b/vim/.vimrc @@ -21,11 +21,14 @@ set list " Switch to alternate file map <M-x> :bnext<cr> map <M-c> :bprevious<cr> -map <C-d> <Ins> -" Switch tabs +" tabs map <C-x> :tabp<cr> map <C-c> :tabn<cr> +map <C-o> :tabnew<cr> + +" Toggle NERDTree +map <C-v> :NERDTreeToggle<CR> " YAY COLOR syntax on @@ -39,3 +42,5 @@ hi LineNr ctermfg=black cterm=bold ctermbg=black hi TabLineFill ctermfg=black ctermbg=black hi TabLine ctermfg=grey ctermbg=black cterm=none hi TabLineSel ctermfg=white ctermbg=black +highlight OverLength ctermbg=red ctermfg=white guibg=#592929 +match OverLength /\%81v.\+/