diff options
Diffstat (limited to 'vim/plugin')
-rw-r--r-- | vim/plugin/NERD_tree.vim | 4059 | ||||
-rw-r--r-- | vim/plugin/ScrollColor.vim | 457 | ||||
-rwxr-xr-x | vim/plugin/bufexplorer.vim | 1162 | ||||
-rw-r--r-- | vim/plugin/rspec.vim | 36 |
4 files changed, 0 insertions, 5714 deletions
diff --git a/vim/plugin/NERD_tree.vim b/vim/plugin/NERD_tree.vim deleted file mode 100644 index 6411b1d..0000000 --- a/vim/plugin/NERD_tree.vim +++ /dev/null @@ -1,4059 +0,0 @@ -" ============================================================================ -" 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: 1 December, 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. -" -" ============================================================================ -let s:NERD_tree_version = '4.1.0' - -" 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 . ' = ' . "'" . a:value . "'" - return 1 - endif - return 0 -endfunction - -"SECTION: Init variable calls and other random constants {{{2 -call s:initVariable("g:NERDChristmasTree", 1) -call s:initVariable("g:NERDTreeAutoCenter", 1) -call s:initVariable("g:NERDTreeAutoCenterThreshold", 3) -call s:initVariable("g:NERDTreeCaseSensitiveSort", 0) -call s:initVariable("g:NERDTreeChDirMode", 0) -if !exists("g:NERDTreeIgnore") - let g:NERDTreeIgnore = ['\~$'] -endif -call s:initVariable("g:NERDTreeBookmarksFile", expand('$HOME') . '/.NERDTreeBookmarks') -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: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) - -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 - -"we need to use this number many times for sorting... so we calculate it only -"once here -let s:NERDTreeSortStarIndex = index(g:NERDTreeSortOrder, '*') - -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) - -let s:running_windows = has("win16") || has("win32") || has("win64") - -"init the shell commands that will be used to copy nodes, and remove dir trees -" -"Note: the space after the command is important -if s:running_windows - 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") - -"SECTION: Script level variable declaration{{{2 -if s:running_windows - let s:escape_chars = " `\|\"#%&,?()\*^<>" -else - let s:escape_chars = " \\`\|\"#%&,?()\*^<>" -endif -let s:NERDTreeBufName = 'NERD_tree_' - -let s:tree_wid = 2 -let s:tree_markup_reg = '^[ `|]*[\-+~]' -let s:tree_up_dir_line = '.. (up a dir)' - -"the number to add to the nerd tree buffer name to make the buf name unique -let s:next_buffer_number = 1 - -" SECTION: Commands {{{1 -"============================================================ -"init the command that users start the nerd tree with -command! -n=? -complete=dir -bar NERDTree :call s:initNerdTree('<args>') -command! -n=? -complete=dir -bar NERDTreeToggle :call s:toggle('<args>') -command! -n=0 -bar NERDTreeClose :call s:closeTreeIfOpen() -command! -n=1 -complete=customlist,s:completeBookmarks -bar NERDTreeFromBookmark call s:initNerdTree('<args>') -command! -n=0 -bar NERDTreeMirror call s:initNerdTreeMirror() -command! -n=0 -bar NERDTreeFind call s:findAndRevealPath() -" SECTION: Auto commands {{{1 -"============================================================ -augroup NERDTree - "Save the cursor position whenever we close the nerd tree - exec "autocmd BufWinLeave ". s:NERDTreeBufName ."* call <SID>saveScreenState()" - "cache bookmarks when vim loads - autocmd VimEnter * call s:Bookmark.CacheBookmarks(0) - - "load all nerdtree plugins after vim starts - autocmd VimEnter * runtime! nerdtree_plugin/**/*.vim -augroup END - -if g:NERDTreeHijackNetrw - augroup NERDTreeHijackNetrw - autocmd VimEnter * silent! autocmd! FileExplorer - au BufEnter,VimEnter * call s:checkForBrowse(expand("<amatch>")) - augroup END -endif - -"SECTION: Classes {{{1 -"============================================================ -"CLASS: Bookmark {{{2 -"============================================================ -let s:Bookmark = {} -" FUNCTION: Bookmark.activate() {{{3 -function! s:Bookmark.activate() - if self.path.isDirectory - call self.toRoot() - else - if self.validate() - let n = s:TreeFileNode.New(self.path) - call n.open() - endif - endif -endfunction -" FUNCTION: Bookmark.AddBookmark(name, path) {{{3 -" Class method to add a new bookmark to the list, if a previous bookmark exists -" with the same name, just update the path for that bookmark -function! s:Bookmark.AddBookmark(name, path) - for i in s:Bookmark.Bookmarks() - if i.name ==# a:name - let i.path = a:path - return - endif - endfor - call add(s:Bookmark.Bookmarks(), s:Bookmark.New(a:name, a:path)) - call s:Bookmark.Sort() -endfunction -" Function: Bookmark.Bookmarks() {{{3 -" 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) {{{3 -" 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) {{{3 -" 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() {{{3 -" 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) {{{3 -" Class method to read all bookmarks from the bookmarks file intialize -" bookmark objects for each one. -" -" Args: -" silent - dont echo an error msg if invalid bookmarks are found -function! s:Bookmark.CacheBookmarks(silent) - if filereadable(g:NERDTreeBookmarksFile) - let g:NERDTreeBookmarks = [] - let g:NERDTreeInvalidBookmarks = [] - let bookmarkStrings = readfile(g:NERDTreeBookmarksFile) - let invalidBookmarksFound = 0 - for i in bookmarkStrings - - "ignore blank lines - if i != '' - - let name = substitute(i, '^\(.\{-}\) .*$', '\1', '') - let path = substitute(i, '^.\{-} \(.*\)$', '\1', '') - - try - let bookmark = s:Bookmark.New(name, s:Path.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 s:echo(invalidBookmarksFound . " invalid bookmarks were read. See :help NERDTreeInvalidBookmarks for info.") - endif - endif - call s:Bookmark.Sort() - endif -endfunction -" FUNCTION: Bookmark.compareTo(otherbookmark) {{{3 -" Compare these two bookmarks for sorting purposes -function! s:Bookmark.compareTo(otherbookmark) - return a:otherbookmark.name < self.name -endfunction -" FUNCTION: Bookmark.ClearAll() {{{3 -" 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() {{{3 -" 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) {{{3 -" 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 ? s:TreeDirNode.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) {{{3 -" 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() {{{3 -" 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() {{{3 -" 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() {{{3 -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) {{{3 -" 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.openInNewTab(options) {{{3 -" Create a new bookmark object with the given name and path object -function! s:Bookmark.openInNewTab(options) - let currentTab = tabpagenr() - if self.path.isDirectory - tabnew - call s:initNerdTree(self.name) - else - exec "tabedit " . bookmark.path.str({'format': 'Edit'}) - endif - - if has_key(a:options, 'stayInCurrentTab') - exec "tabnext " . currentTab - endif -endfunction -" Function: Bookmark.setPath(path) {{{3 -" makes this bookmark point to the given path -function! s:Bookmark.setPath(path) - let self.path = a:path -endfunction -" Function: Bookmark.Sort() {{{3 -" Class method that sorts all bookmarks -function! s:Bookmark.Sort() - let CompareFunc = function("s:compareBookmarks") - call sort(s:Bookmark.Bookmarks(), CompareFunc) -endfunction -" Function: Bookmark.str() {{{3 -" Get the string that should be rendered in the view for this bookmark -function! s:Bookmark.str() - let pathStrMaxLen = winwidth(s:getTreeWinNum()) - 4 - len(self.name) - if &nu - let pathStrMaxLen = pathStrMaxLen - &numberwidth - endif - - let pathStr = self.path.str({'format': 'UI'}) - if len(pathStr) > pathStrMaxLen - let pathStr = '<' . strpart(pathStr, len(pathStr) - pathStrMaxLen) - endif - return '>' . self.name . ' ' . pathStr -endfunction -" FUNCTION: Bookmark.toRoot() {{{3 -" 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 = s:TreeFileNode.New(s:Bookmark.BookmarkFor(self.name).path) - endtry - call targetNode.makeRoot() - call s:renderView() - call targetNode.putCursorHere(0, 0) - endif -endfunction -" FUNCTION: Bookmark.ToRoot(name) {{{3 -" 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() {{{3 -function! s:Bookmark.validate() - if self.path.exists() - return 1 - else - call s:Bookmark.CacheBookmarks(1) - call s:renderView() - call s:echo(self.name . "now points to an invalid location. See :help NERDTreeInvalidBookmarks for info.") - return 0 - endif -endfunction - -" Function: Bookmark.Write() {{{3 -" 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 -"CLASS: KeyMap {{{2 -"============================================================ -let s:KeyMap = {} -"FUNCTION: KeyMap.All() {{{3 -function! s:KeyMap.All() - if !exists("s:keyMaps") - let s:keyMaps = [] - endif - return s:keyMaps -endfunction - -"FUNCTION: KeyMap.BindAll() {{{3 -function! s:KeyMap.BindAll() - for i in s:KeyMap.All() - call i.bind() - endfor -endfunction - -"FUNCTION: KeyMap.bind() {{{3 -function! s:KeyMap.bind() - exec "nnoremap <silent> <buffer> ". self.key ." :call ". self.callback ."()<cr>" -endfunction - -"FUNCTION: KeyMap.Create(options) {{{3 -function! s:KeyMap.Create(options) - let newKeyMap = copy(self) - let newKeyMap.key = a:options['key'] - let newKeyMap.quickhelpText = a:options['quickhelpText'] - let newKeyMap.callback = a:options['callback'] - call add(s:KeyMap.All(), newKeyMap) -endfunction -"CLASS: MenuController {{{2 -"============================================================ -let s:MenuController = {} -"FUNCTION: MenuController.New(menuItems) {{{3 -"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() {{{3 -"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() {{{3 -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) {{{3 -"get the MenuItem that is curently selected -function! s:MenuController._current() - return self.menuItems[self.selection] -endfunction - -"FUNCTION: MenuController._handleKeypress(key) {{{3 -"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) {{{3 -"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) {{{3 -"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() {{{3 -"sets &cmdheight to whatever is needed to display the menu -function! s:MenuController._setCmdheight() - let &cmdheight = len(self.menuItems) + 3 -endfunction - -"FUNCTION: MenuController._saveOptions() {{{3 -"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() {{{3 -"restore the options we saved in _saveOptions() -function! s:MenuController._restoreOptions() - let &cmdheight = self._oldCmdheight - let &lazyredraw = self._oldLazyredraw -endfunction - -"FUNCTION: MenuController._cursorDown() {{{3 -"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() {{{3 -"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 - -"CLASS: MenuItem {{{2 -"============================================================ -let s:MenuItem = {} -"FUNCTION: MenuItem.All() {{{3 -"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() {{{3 -"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) {{{3 -"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) {{{3 -"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) {{{3 -"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() {{{3 -"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() {{{3 -"perform the action behind this menu item, if this menuitem has children then -"display a new menu for them, otherwise deletegate off to the menuitem's -"callback -function! s:MenuItem.execute() - if len(self.children) - let mc = s:MenuController.New(self.children) - call mc.showMenu() - else - if self.callback != -1 - call {self.callback}() - endif - endif -endfunction - -"FUNCTION: MenuItem.isSeparator() {{{3 -"return 1 if this menuitem is a separator -function! s:MenuItem.isSeparator() - return self.callback == -1 && self.children == [] -endfunction - -"FUNCTION: MenuItem.isSubmenu() {{{3 -"return 1 if this menuitem is a submenu -function! s:MenuItem.isSubmenu() - return self.callback == -1 && !empty(self.children) -endfunction - -"CLASS: TreeFileNode {{{2 -"This class is the parent of the TreeDirNode class and constitures the -"'Component' part of the composite design pattern between the treenode -"classes. -"============================================================ -let s:TreeFileNode = {} -"FUNCTION: TreeFileNode.activate(forceKeepWinOpen) {{{3 -function! s:TreeFileNode.activate(forceKeepWinOpen) - call self.open() - if !a:forceKeepWinOpen - call s:closeTreeIfQuitOnOpen() - end -endfunction -"FUNCTION: TreeFileNode.bookmark(name) {{{3 -"bookmark this node with a:name -function! s:TreeFileNode.bookmark(name) - try - let oldMarkedNode = s:Bookmark.GetNodeForName(a:name, 1) - call oldMarkedNode.path.cacheDisplayString() - catch /^NERDTree.BookmarkNotFoundError/ - endtry - - call s:Bookmark.AddBookmark(a:name, self.path) - call self.path.cacheDisplayString() - call s:Bookmark.Write() -endfunction -"FUNCTION: TreeFileNode.cacheParent() {{{3 -"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.compareNodes {{{3 -"This is supposed to be a class level method but i cant figure out how to -"get func refs to work from a dict.. -" -"A class level method that compares two nodes -" -"Args: -"n1, n2: the 2 nodes to compare -function! s:compareNodes(n1, n2) - return a:n1.path.compareTo(a:n2.path) -endfunction - -"FUNCTION: TreeFileNode.clearBoomarks() {{{3 -function! s:TreeFileNode.clearBoomarks() - for i in s:Bookmark.Bookmarks() - if i.path.equals(self.path) - call i.delete() - end - endfor - call self.path.cacheDisplayString() -endfunction -"FUNCTION: TreeFileNode.copy(dest) {{{3 -function! s:TreeFileNode.copy(dest) - call self.path.copy(a:dest) - let newPath = s:Path.New(a:dest) - let parent = b:NERDTreeRoot.findNode(newPath.getParent()) - if !empty(parent) - call parent.refresh() - endif - return parent.findNode(newPath) -endfunction - -"FUNCTION: TreeFileNode.delete {{{3 -"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() {{{3 -" -"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) {{{3 -" -"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) {{{3 -"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) {{{3 -" -"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) {{{3 -" -"Finds the next sibling for this node in the indicated direction -" -"Args: -"direction: 0 if you want to find the previous sibling, 1 for the next sibling -" -"Return: -"a treenode object or {} if no sibling could be found -function! s:TreeFileNode.findSibling(direction) - "if we have no parent then we can have no siblings - if self.parent != {} - - "get the index of this node in its parents children - let siblingIndx = self.parent.getChildIndex(self.path) - - if siblingIndx != -1 - "move a long to the next potential sibling node - let siblingIndx = a:direction ==# 1 ? siblingIndx+1 : siblingIndx-1 - - "keep moving along to the next sibling till we find one that is valid - let numSiblings = self.parent.getChildCount() - while siblingIndx >= 0 && siblingIndx < numSiblings - - "if the next node is not an ignored node (i.e. wont show up in the - "view) then return it - if self.parent.children[siblingIndx].path.ignore() ==# 0 - return self.parent.children[siblingIndx] - endif - - "go to next node - let siblingIndx = a:direction ==# 1 ? siblingIndx+1 : siblingIndx-1 - endwhile - endif - endif - - return {} -endfunction - -"FUNCTION: TreeFileNode.getLineNum(){{{3 -"returns the line number this node is rendered on, or -1 if it isnt rendered -function! s:TreeFileNode.getLineNum() - "if the node is the root then return the root line no. - if self.isRoot() - return s:TreeFileNode.GetRootLineNum() - endif - - let totalLines = line("$") - - "the path components we have matched so far - let pathcomponents = [substitute(b:NERDTreeRoot.path.str({'format': 'UI'}), '/ *$', '', '')] - "the index of the component we are searching for - let curPathComponent = 1 - - let fullpath = self.path.str({'format': 'UI'}) - - - let lnum = s:TreeFileNode.GetRootLineNum() - while lnum > 0 - let lnum = lnum + 1 - "have we reached the bottom of the tree? - if lnum ==# totalLines+1 - return -1 - endif - - let curLine = getline(lnum) - - let indent = s:indentLevelFor(curLine) - if indent ==# curPathComponent - let curLine = s:stripMarkupFromLine(curLine, 1) - - let curPath = join(pathcomponents, '/') . '/' . curLine - if stridx(fullpath, curPath, 0) ==# 0 - if fullpath ==# curPath || strpart(fullpath, len(curPath)-1,1) ==# '/' - let curLine = substitute(curLine, '/ *$', '', '') - call add(pathcomponents, curLine) - let curPathComponent = curPathComponent + 1 - - if fullpath ==# curPath - return lnum - endif - endif - endif - endif - endwhile - return -1 -endfunction - -"FUNCTION: TreeFileNode.GetRootForTab(){{{3 -"get the root node for this tab -function! s:TreeFileNode.GetRootForTab() - if s:treeExistsForTab() - return getbufvar(t:NERDTreeBufName, 'NERDTreeRoot') - end - return {} -endfunction -"FUNCTION: TreeFileNode.GetRootLineNum(){{{3 -"gets the line number of the root node -function! s:TreeFileNode.GetRootLineNum() - let rootLine = 1 - while getline(rootLine) !~ '^\(/\|<\)' - let rootLine = rootLine + 1 - endwhile - return rootLine -endfunction - -"FUNCTION: TreeFileNode.GetSelected() {{{3 -"gets the treenode that the cursor is currently over -function! s:TreeFileNode.GetSelected() - try - let path = s:getPath(line(".")) - if path ==# {} - return {} - endif - return b:NERDTreeRoot.findNode(path) - catch /NERDTree/ - return {} - endtry -endfunction -"FUNCTION: TreeFileNode.isVisible() {{{3 -"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() {{{3 -"returns 1 if this node is b:NERDTreeRoot -function! s:TreeFileNode.isRoot() - if !s:treeExistsForBuf() - throw "NERDTree.NoTreeError: No tree exists for the current buffer" - endif - - return self.equals(b:NERDTreeRoot) -endfunction - -"FUNCTION: TreeFileNode.makeRoot() {{{3 -"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 -endfunction -"FUNCTION: TreeFileNode.New(path) {{{3 -"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 s:TreeDirNode.New(a:path) - else - let newTreeNode = copy(self) - let newTreeNode.path = a:path - let newTreeNode.parent = {} - return newTreeNode - endif -endfunction - -"FUNCTION: TreeFileNode.open() {{{3 -"Open the file represented by the given node in the current window, splitting -"the window if needed -" -"ARGS: -"treenode: file node to open -function! s:TreeFileNode.open() - if b:NERDTreeType ==# "secondary" - exec 'edit ' . self.path.str({'format': 'Edit'}) - return - endif - - "if the file is already open in this tab then just stick the cursor in it - let winnr = bufwinnr('^' . self.path.str() . '$') - if winnr != -1 - call s:exec(winnr . "wincmd w") - - else - if !s:isWindowUsable(winnr("#")) && s:firstUsableWindow() ==# -1 - call self.openSplit() - else - try - if !s:isWindowUsable(winnr("#")) - call s:exec(s:firstUsableWindow() . "wincmd w") - else - call s:exec('wincmd p') - endif - exec ("edit " . self.path.str({'format': 'Edit'})) - catch /^Vim\%((\a\+)\)\=:E37/ - call s:putCursorInTreeWin() - throw "NERDTree.FileAlreadyOpenAndModifiedError: ". self.path.str() ." is already open and modified." - catch /^Vim\%((\a\+)\)\=:/ - echo v:exception - endtry - endif - endif -endfunction -"FUNCTION: TreeFileNode.openSplit() {{{3 -"Open this node in a new window -function! s:TreeFileNode.openSplit() - - if b:NERDTreeType ==# "secondary" - exec "split " . self.path.str({'format': 'Edit'}) - return - endif - - " 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 s: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 " . self.path.str({'format': 'Edit'})) - catch /^Vim\%((\a\+)\)\=:E37/ - call s:putCursorInTreeWin() - throw "NERDTree.FileAlreadyOpenAndModifiedError: ". self.path.str() ." is already open and modified." - catch /^Vim\%((\a\+)\)\=:/ - "do nothing - endtry - - "resize the tree window if no other window was open before - if onlyOneWin - let size = exists("b:NERDTreeOldWindowSize") ? b:NERDTreeOldWindowSize : g:NERDTreeWinSize - call s:exec(there) - exec("silent ". splitMode ." resize ". size) - call s:exec('wincmd p') - endif - - " Restore splitmode settings - let &splitbelow=savesplitbelow - let &splitright=savesplitright -endfunction -"FUNCTION: TreeFileNode.openVSplit() {{{3 -"Open this node in a new vertical window -function! s:TreeFileNode.openVSplit() - if b:NERDTreeType ==# "secondary" - exec "vnew " . self.path.str({'format': 'Edit'}) - return - endif - - let winwidth = winwidth(".") - if winnr("$")==#1 - let winwidth = g:NERDTreeWinSize - endif - - call s:exec("wincmd p") - exec "vnew " . self.path.str({'format': 'Edit'}) - - "resize the nerd tree back to the original size - call s:putCursorInTreeWin() - exec("silent vertical resize ". winwidth) - call s:exec('wincmd p') -endfunction -"FUNCTION: TreeFileNode.openInNewTab(options) {{{3 -function! s:TreeFileNode.openInNewTab(options) - let currentTab = tabpagenr() - - if !has_key(a:options, 'keepTreeOpen') - call s:closeTreeIfQuitOnOpen() - endif - - exec "tabedit " . self.path.str({'format': 'Edit'}) - - if has_key(a:options, 'stayInCurrentTab') && a:options['stayInCurrentTab'] - exec "tabnext " . currentTab - endif - -endfunction -"FUNCTION: TreeFileNode.putCursorHere(isJump, recurseUpward){{{3 -"Places the cursor on the line number this node is rendered on -" -"Args: -"isJump: 1 if this cursor movement should be counted as a jump by vim -"recurseUpward: try to put the cursor on the parent if the this node isnt -"visible -function! s:TreeFileNode.putCursorHere(isJump, recurseUpward) - let ln = self.getLineNum() - if ln != -1 - if a:isJump - mark ' - endif - call cursor(ln, col(".")) - else - if a:recurseUpward - let node = self - while node != {} && node.getLineNum() ==# -1 - let node = node.parent - call node.open() - endwhile - call s:renderView() - call node.putCursorHere(a:isJump, 0) - endif - endif -endfunction - -"FUNCTION: TreeFileNode.refresh() {{{3 -function! s:TreeFileNode.refresh() - call self.path.refresh() -endfunction -"FUNCTION: TreeFileNode.rename() {{{3 -"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 {{{3 -"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 j ==# 1 - let treeParts = treeParts . '| ' - else - let treeParts = treeParts . ' ' - 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 a:isLastChild - let treeParts = treeParts . '`' - else - let treeParts = treeParts . '|' - endif - - - "smack the appropriate dir/file symbol on the line before the file/dir - "name itself - if self.path.isDirectory - if self.isOpen - let treeParts = treeParts . '~' - else - let treeParts = treeParts . '+' - endif - else - let treeParts = treeParts . '-' - 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 -"CLASS: TreeDirNode {{{2 -"This class is a child of the TreeFileNode class and constitutes the -"'Composite' part of the composite design pattern between the treenode -"classes. -"============================================================ -let s:TreeDirNode = copy(s:TreeFileNode) -"FUNCTION: TreeDirNode.AbsoluteTreeRoot(){{{3 -"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(forceKeepWinOpen) {{{3 -unlet s:TreeDirNode.activate -function! s:TreeDirNode.activate(forceKeepWinOpen) - call self.toggleOpen() - call s:renderView() - call self.putCursorHere(0, 0) -endfunction -"FUNCTION: TreeDirNode.addChild(treenode, inOrder) {{{3 -"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() {{{3 -"Closes this directory -function! s:TreeDirNode.close() - let self.isOpen = 0 -endfunction - -"FUNCTION: TreeDirNode.closeChildren() {{{3 -"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) {{{3 -"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 = s:TreeFileNode.New(a:path) - call self.addChild(newTreeNode, a:inOrder) - return newTreeNode -endfunction - -"FUNCTION: TreeDirNode.findNode(path) {{{3 -"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() {{{3 -"Returns the number of children this node has -function! s:TreeDirNode.getChildCount() - return len(self.children) -endfunction - -"FUNCTION: TreeDirNode.getChild(path) {{{3 -"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) {{{3 -"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) {{{3 -"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() {{{3 -"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 = s:TreeFileNode.GetSelected() - if currentDir != {} && !currentDir.isRoot() - if currentDir.path.isDirectory ==# 0 - let currentDir = currentDir.parent - endif - endif - return currentDir -endfunction -"FUNCTION: TreeDirNode.getVisibleChildCount() {{{3 -"Returns the number of visible children this node has -function! s:TreeDirNode.getVisibleChildCount() - return len(self.getVisibleChildren()) -endfunction - -"FUNCTION: TreeDirNode.getVisibleChildren() {{{3 -"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() {{{3 -"returns 1 if this node has any childre, 0 otherwise.. -function! s:TreeDirNode.hasVisibleChildren() - return self.getVisibleChildCount() != 0 -endfunction - -"FUNCTION: TreeDirNode._initChildren() {{{3 -"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'}) - let filesStr = globpath(globDir, '*') . "\n" . globpath(globDir, '.*') - let files = split(filesStr, "\n") - - if !a:silent && len(files) > g:NERDTreeNotificationThreshold - call s:echo("Please wait, caching a large dir ...") - endif - - let invalidFilesFound = 0 - for i in files - - "filter out the .. and . directories - "Note: we must match .. AND ../ cos sometimes the globpath returns - "../ for path with strange chars (eg $) - if i !~ '\/\.\.\/\?$' && i !~ '\/\.\/\?$' - - "put the next file in a new node and attach it - try - let path = s:Path.New(i) - call self.createChild(path, 0) - catch /^NERDTree.\(InvalidArguments\|InvalidFiletype\)Error/ - let invalidFilesFound += 1 - endtry - endif - endfor - - call self.sortChildren() - - if !a:silent && len(files) > g:NERDTreeNotificationThreshold - call s:echo("Please wait, caching a large dir ... DONE (". self.getChildCount() ." nodes cached).") - endif - - if invalidFilesFound - call s:echoWarning(invalidFilesFound . " file(s) could not be loaded into the NERD tree") - endif - return self.getChildCount() -endfunction -"FUNCTION: TreeDirNode.New(path) {{{3 -"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() {{{3 -"Reads in all this nodes children -" -"Return: the number of child nodes read -unlet s:TreeDirNode.open -function! s:TreeDirNode.open() - let self.isOpen = 1 - if self.children ==# [] - return self._initChildren(0) - else - return 0 - endif -endfunction - -" FUNCTION: TreeDirNode.openExplorer() {{{3 -" opens an explorer window for this node in the previous window (could be a -" nerd tree or a netrw) -function! s:TreeDirNode.openExplorer() - let oldwin = winnr() - call s:exec('wincmd p') - if oldwin ==# winnr() || (&modified && s:bufInWindows(winbufnr(winnr())) < 2) - call s:exec('wincmd p') - call self.openSplit() - else - exec ("silent edit " . self.path.str({'format': 'Edit'})) - endif -endfunction -"FUNCTION: TreeDirNode.openInNewTab(options) {{{3 -unlet s:TreeDirNode.openInNewTab -function! s:TreeDirNode.openInNewTab(options) - let currentTab = tabpagenr() - - if !has_key(a:options, 'keepTreeOpen') || !a:options['keepTreeOpen'] - call s:closeTreeIfQuitOnOpen() - endif - - tabnew - call s:initNerdTree(self.path.str()) - - if has_key(a:options, 'stayInCurrentTab') && a:options['stayInCurrentTab'] - exec "tabnext " . currentTab - endif -endfunction -"FUNCTION: TreeDirNode.openRecursively() {{{3 -"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() {{{3 -"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() {{{3 -unlet s:TreeDirNode.refresh -function! s:TreeDirNode.refresh() - call self.path.refresh() - - "if this node was ever opened, refresh its children - if self.isOpen || !empty(self.children) - "go thru all the files/dirs under this node - let newChildNodes = [] - let invalidFilesFound = 0 - let dir = self.path - let globDir = dir.str({'format': 'Glob'}) - let filesStr = globpath(globDir, '*') . "\n" . globpath(globDir, '.*') - let files = split(filesStr, "\n") - for i in files - "filter out the .. and . directories - "Note: we must match .. AND ../ cos sometimes the globpath returns - "../ for path with strange chars (eg $) - if i !~ '\/\.\.\/\?$' && i !~ '\/\.\/\?$' - - try - "create a new path and see if it exists in this nodes children - let path = s:Path.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 = s:TreeFileNode.New(path) - let newNode.parent = self - call add(newChildNodes, newNode) - endif - - - catch /^NERDTree.InvalidArgumentsError/ - 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 s:echoWarning("some files could not be loaded into the NERD tree") - endif - endif -endfunction - -"FUNCTION: TreeDirNode.reveal(path) {{{3 -"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 s:renderView() - call n.putCursorHere(1,0) - return - endif - - let p = a:path - while !p.getParent().equals(self.path) - let p = p.getParent() - endwhile - - let n = self.findNode(p) - call n.reveal(a:path) -endfunction -"FUNCTION: TreeDirNode.removeChild(treenode) {{{3 -" -"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() {{{3 -" -"Sorts the children of this node according to alphabetical order and the -"directory priority. -" -function! s:TreeDirNode.sortChildren() - let CompareFunc = function("s:compareNodes") - call sort(self.children, CompareFunc) -endfunction - -"FUNCTION: TreeDirNode.toggleOpen() {{{3 -"Opens this directory if it is closed and vice versa -function! s:TreeDirNode.toggleOpen() - if self.isOpen ==# 1 - call self.close() - else - call self.open() - endif -endfunction - -"FUNCTION: TreeDirNode.transplantChild(newNode) {{{3 -"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 -"============================================================ -"CLASS: Path {{{2 -"============================================================ -let s:Path = {} -"FUNCTION: Path.AbsolutePathFor(str) {{{3 -function! s:Path.AbsolutePathFor(str) - let prependCWD = 0 - if s:running_windows - let prependCWD = 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() {{{3 -function! s:Path.bookmarkNames() - if !exists("self._bookmarkNames") - call self.cacheDisplayString() - endif - return self._bookmarkNames -endfunction -"FUNCTION: Path.cacheDisplayString() {{{3 -function! s:Path.cacheDisplayString() - let self.cachedDisplayString = self.getLastPathComponent(1) - - if self.isExecutable - let self.cachedDisplayString = self.cachedDisplayString . '*' - endif - - let self._bookmarkNames = [] - for i in s:Bookmark.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() {{{3 -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 s:echo("CWD is now: " . getcwd()) - catch - throw "NERDTree.PathChangeError: cannot change CWD to " . dir - endtry -endfunction - -"FUNCTION: Path.compareTo() {{{3 -" -"Compares this Path to the given path and returns 0 if they are equal, -1 if -"this Path is "less than" the given path, or 1 if it is "greater". -" -"Args: -"path: the path object to compare this to -" -"Return: -"1, -1 or 0 -function! s:Path.compareTo(path) - let thisPath = self.getLastPathComponent(1) - let thatPath = a:path.getLastPathComponent(1) - - "if the paths are the same then clearly we return 0 - if thisPath ==# thatPath - return 0 - endif - - let thisSS = self.getSortOrderIndex() - let thatSS = a:path.getSortOrderIndex() - - "compare the sort sequences, if they are different then the return - "value is easy - if thisSS < thatSS - return -1 - elseif thisSS > thatSS - return 1 - else - "if the sort sequences are the same then compare the paths - "alphabetically - let pathCompare = g:NERDTreeCaseSensitiveSort ? thisPath <# thatPath : thisPath <? thatPath - if pathCompare - return -1 - else - return 1 - endif - endif -endfunction - -"FUNCTION: Path.Create(fullpath) {{{3 -" -"Factory method. -" -"Creates a path object with the given path. The path is also created on the -"filesystem. If the path already exists, a NERDTree.Path.Exists exception is -"thrown. If any other errors occur, a NERDTree.Path exception is thrown. -" -"Args: -"fullpath: the full filesystem path to the file/dir to create -function! s:Path.Create(fullpath) - "bail if the a:fullpath already exists - if isdirectory(a:fullpath) || filereadable(a:fullpath) - throw "NERDTree.CreatePathError: Directory Exists: '" . a:fullpath . "'" - endif - - try - - "if it ends with a slash, assume its a dir create it - if a:fullpath =~ '\(\\\|\/\)$' - "whack the trailing slash off the end if it exists - let fullpath = substitute(a:fullpath, '\(\\\|\/\)$', '', '') - - call mkdir(fullpath, 'p') - - "assume its a file and create - else - call writefile([], a:fullpath) - endif - catch - throw "NERDTree.CreatePathError: Could not create path: '" . a:fullpath . "'" - endtry - - return s:Path.New(a:fullpath) -endfunction - -"FUNCTION: Path.copy(dest) {{{3 -" -"Copies the file/dir represented by this Path to the given location -" -"Args: -"dest: the location to copy this dir/file to -function! s:Path.copy(dest) - if !s:Path.CopyingSupported() - throw "NERDTree.CopyingNotSupportedError: Copying is not supported on this OS" - endif - - let dest = s:Path.WinToUnixPath(a:dest) - - let cmd = g:NERDTreeCopyCmd . " " . self.str() . " " . dest - let success = system(cmd) - if success != 0 - throw "NERDTree.CopyError: Could not copy ''". self.str() ."'' to: '" . a:dest . "'" - endif -endfunction - -"FUNCTION: Path.CopyingSupported() {{{3 -" -"returns 1 if copying is supported for this OS -function! s:Path.CopyingSupported() - return exists('g:NERDTreeCopyCmd') -endfunction - - -"FUNCTION: Path.copyingWillOverwrite(dest) {{{3 -" -"returns 1 if copy this path to the given location will cause files to -"overwritten -" -"Args: -"dest: the location this path will be copied to -function! s:Path.copyingWillOverwrite(dest) - if filereadable(a:dest) - return 1 - endif - - if isdirectory(a:dest) - let path = s:Path.JoinPathStrings(a:dest, self.getLastPathComponent(0)) - if filereadable(path) - return 1 - endif - endif -endfunction - -"FUNCTION: Path.delete() {{{3 -" -"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 = s:Bookmark.BookmarkFor(i) - call bookmark.delete() - endfor -endfunction - -"FUNCTION: Path.displayString() {{{3 -" -"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.extractDriveLetter(fullpath) {{{3 -" -"If running windows, cache the drive letter for this path -function! s:Path.extractDriveLetter(fullpath) - if s:running_windows - let self.drive = substitute(a:fullpath, '\(^[a-zA-Z]:\).*', '\1', '') - else - let self.drive = '' - endif - -endfunction -"FUNCTION: Path.exists() {{{3 -"return 1 if this path points to a location that is readable or is a directory -function! s:Path.exists() - let p = self.str() - return filereadable(p) || isdirectory(p) -endfunction -"FUNCTION: Path.getDir() {{{3 -" -"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() {{{3 -" -"Returns a new path object for this paths parent -" -"Return: -"a new Path object -function! s:Path.getParent() - if s:running_windows - 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) {{{3 -" -"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() {{{3 -"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.ignore() {{{3 -"returns true if this path should be ignored -function! s:Path.ignore() - let lastPathComponent = self.getLastPathComponent(0) - - "filter out the user specified paths to ignore - if b:NERDTreeIgnoreEnabled - for i in g:NERDTreeIgnore - if lastPathComponent =~ i - return 1 - endif - endfor - endif - - "dont show hidden files unless instructed to - if b:NERDTreeShowHidden ==# 0 && lastPathComponent =~ '^\.' - return 1 - endif - - if b:NERDTreeShowFiles ==# 0 && self.isDirectory ==# 0 - return 1 - endif - - return 0 -endfunction - -"FUNCTION: Path.isUnder(path) {{{3 -"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(...) {{{3 -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() {{{3 -" -"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() {{{3 -"The Constructor for the Path object -function! s:Path.New(path) - let newPath = copy(self) - - call newPath.readInfoFromDisk(s:Path.AbsolutePathFor(a:path)) - - let newPath.cachedDisplayString = "" - - return newPath -endfunction - -"FUNCTION: Path.Slash() {{{3 -"return the slash to use for the current OS -function! s:Path.Slash() - return s:running_windows ? '\' : '/' -endfunction - -"FUNCTION: Path.readInfoFromDisk(fullpath) {{{3 -" -" -"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 = resolve(self.strTrunk()) . '/' . lastPathComponent - - "if the last part of the path is a symlink then flag it as such - let self.isSymLink = (resolve(hardPath) != hardPath) - if self.isSymLink - let self.symLinkDest = 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() {{{3 -function! s:Path.refresh() - call self.readInfoFromDisk(self.str()) - call self.cacheDisplayString() -endfunction - -"FUNCTION: Path.rename() {{{3 -" -"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 = s:Bookmark.BookmarkFor(i) - call b.setPath(copy(self)) - endfor - call s:Bookmark.Write() -endfunction - -"FUNCTION: Path.str() {{{3 -" -"Returns a string representation of this Path -" -"Takes an optional dictionary param to specify how the output should be -"formatted. -" -"The dict may have the following keys: -" 'format' -" 'escape' -" 'truncateTo' -" -"The 'format' key may have a value of: -" 'Cd' - a string to be used with the :cd command -" 'Edit' - a string to be used with :e :sp :new :tabedit etc -" 'UI' - a string used in the NERD tree UI -" -"The 'escape' key, if specified will cause the output to be escaped with -"shellescape() -" -"The 'truncateTo' key causes the resulting string to be truncated to the value -"'truncateTo' maps to. A '<' char will be prepended. -function! s:Path.str(...) - let options = a:0 ? a:1 : {} - let toReturn = "" - - if has_key(options, 'format') - let format = options['format'] - if has_key(self, '_strFor' . format) - exec 'let toReturn = self._strFor' . format . '()' - else - raise 'NERDTree.UnknownFormatError: unknown format "'. format .'"' - endif - else - let toReturn = self._str() - endif - - if has_key(options, 'escape') && options['escape'] - let toReturn = shellescape(toReturn) - endif - - if has_key(options, 'truncateTo') - let limit = options['truncateTo'] - if len(toReturn) > limit - let toReturn = "<" . strpart(toReturn, len(toReturn) - limit + 1) - endif - endif - - return toReturn -endfunction - -"FUNCTION: Path._strForUI() {{{3 -function! s:Path._strForUI() - let toReturn = '/' . join(self.pathSegments, '/') - if self.isDirectory && toReturn != '/' - let toReturn = toReturn . '/' - endif - return toReturn -endfunction - -"FUNCTION: Path._strForCd() {{{3 -" -" returns a string that can be used with :cd -function! s:Path._strForCd() - return escape(self.str(), s:escape_chars) -endfunction -"FUNCTION: Path._strForEdit() {{{3 -" -"Return: the string for this path that is suitable to be used with the :edit -"command -function! s:Path._strForEdit() - let p = self.str({'format': 'UI'}) - let cwd = getcwd() - - if s:running_windows - let p = tolower(self.str()) - let cwd = tolower(getcwd()) - endif - - let p = escape(p, s:escape_chars) - - let cwd = cwd . s:Path.Slash() - - "return a relative path if we can - if stridx(p, cwd) ==# 0 - let p = strpart(p, strlen(cwd)) - endif - - if p ==# '' - let p = '.' - endif - - return p - -endfunction -"FUNCTION: Path._strForGlob() {{{3 -function! s:Path._strForGlob() - let lead = s:Path.Slash() - - "if we are running windows then slap a drive letter on the front - if s:running_windows - let lead = self.drive . '\' - endif - - let toReturn = lead . join(self.pathSegments, s:Path.Slash()) - - if !s:running_windows - let toReturn = escape(toReturn, s:escape_chars) - endif - return toReturn -endfunction -"FUNCTION: Path._str() {{{3 -" -"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 s:running_windows - let lead = self.drive . '\' - endif - - return lead . join(self.pathSegments, s:Path.Slash()) -endfunction - -"FUNCTION: Path.strTrunk() {{{3 -"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.WinToUnixPath(pathstr){{{3 -"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 !s:running_windows - return a:pathstr - endif - - let toReturn = a:pathstr - - "remove the x:\ of the front - let toReturn = substitute(toReturn, '^.*:\(\\\|/\)\?', '/', "") - - "convert all \ chars to / - let toReturn = substitute(toReturn, '\', '/', "g") - - return toReturn -endfunction - -" SECTION: General Functions {{{1 -"============================================================ -"FUNCTION: s:bufInWindows(bnum){{{2 -"[[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: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: s:checkForBrowse(dir) {{{2 -"inits a secondary nerd tree in the current buffer if appropriate -function! s:checkForBrowse(dir) - if a:dir != '' && isdirectory(a:dir) - call s:initNerdTreeInPlace(a:dir) - endif -endfunction -"FUNCTION: s:compareBookmarks(first, second) {{{2 -"Compares two bookmarks -function! s:compareBookmarks(first, second) - return a:first.compareTo(a:second) -endfunction - -" FUNCTION: s:completeBookmarks(A,L,P) {{{2 -" completion function for the bookmark commands -function! s:completeBookmarks(A,L,P) - return filter(s:Bookmark.BookmarkNames(), 'v:val =~ "^' . a:A . '"') -endfunction -" FUNCTION: s:exec(cmd) {{{2 -" same as :exec cmd but eventignore=all is set for the duration -function! s:exec(cmd) - let old_ei = &ei - set ei=all - exec a:cmd - let &ei = old_ei -endfunction -" FUNCTION: s:findAndRevealPath() {{{2 -function! s:findAndRevealPath() - try - let p = s:Path.New(expand("%")) - catch /^NERDTree.InvalidArgumentsError/ - call s:echo("no file for the current buffer") - return - endtry - - if !s:treeExistsForTab() - call s:initNerdTree(p.getParent().str()) - else - if !p.isUnder(s:TreeFileNode.GetRootForTab().path) - call s:initNerdTree(p.getParent().str()) - else - if !s:isTreeOpen() - call s:toggle("") - endif - endif - endif - call s:putCursorInTreeWin() - call b:NERDTreeRoot.reveal(p) -endfunction -"FUNCTION: s:initNerdTree(name) {{{2 -"Initialise the nerd tree for this tab. The tree will start in either the -"given directory, or the directory associated with the given bookmark -" -"Args: -"name: the name of a bookmark or a directory -function! s:initNerdTree(name) - let path = {} - if s:Bookmark.BookmarkExistsFor(a:name) - let path = s:Bookmark.BookmarkFor(a:name).path - else - let dir = a:name ==# '' ? getcwd() : a:name - - "hack to get an absolute path if a relative path is given - if dir =~ '^\.' - let dir = getcwd() . s:Path.Slash() . dir - endif - let dir = resolve(dir) - - try - let path = s:Path.New(dir) - catch /^NERDTree.InvalidArgumentsError/ - call s:echo("No bookmark or directory found for: " . a:name) - return - endtry - endif - if !path.isDirectory - let path = path.getParent() - 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 s:treeExistsForTab() - if s:isTreeOpen() - call s:closeTree() - endif - unlet t:NERDTreeBufName - endif - - let newRoot = s:TreeDirNode.New(path) - call newRoot.open() - - call s:createTreeWin() - let b:treeShowHelp = 0 - let b:NERDTreeIgnoreEnabled = 1 - let b:NERDTreeShowFiles = g:NERDTreeShowFiles - let b:NERDTreeShowHidden = g:NERDTreeShowHidden - let b:NERDTreeShowBookmarks = g:NERDTreeShowBookmarks - let b:NERDTreeRoot = newRoot - - let b:NERDTreeType = "primary" - - call s:renderView() - call b:NERDTreeRoot.putCursorHere(0, 0) -endfunction - -"FUNCTION: s:initNerdTreeInPlace(dir) {{{2 -function! s:initNerdTreeInPlace(dir) - try - let path = s:Path.New(a:dir) - catch /^NERDTree.InvalidArgumentsError/ - call s: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 " . s:nextBufferName() - - let b:NERDTreePreviousBuf = bufnr(previousBuf) - - let b:NERDTreeRoot = s:TreeDirNode.New(path) - call b:NERDTreeRoot.open() - - "throwaway buffer options - setlocal noswapfile - setlocal buftype=nofile - setlocal bufhidden=hide - setlocal nowrap - setlocal foldcolumn=0 - setlocal nobuflisted - setlocal nospell - if g:NERDTreeShowLineNumbers - setlocal nu - else - setlocal nonu - endif - - iabc <buffer> - - if g:NERDTreeHighlightCursorline - setlocal cursorline - endif - - call s:setupStatusline() - - let b:treeShowHelp = 0 - let b:NERDTreeIgnoreEnabled = 1 - let b:NERDTreeShowFiles = g:NERDTreeShowFiles - let b:NERDTreeShowHidden = g:NERDTreeShowHidden - let b:NERDTreeShowBookmarks = g:NERDTreeShowBookmarks - - let b:NERDTreeType = "secondary" - - call s:bindMappings() - setfiletype nerdtree - " syntax highlighting - if has("syntax") && exists("g:syntax_on") - call s:setupSyntaxHighlighting() - endif - - call s:renderView() -endfunction -" FUNCTION: s:initNerdTreeMirror() {{{2 -function! s:initNerdTreeMirror() - - "get the names off all the nerd tree buffers - let treeBufNames = [] - for i in range(1, tabpagenr("$")) - let nextName = s:tabpagevar(i, 'NERDTreeBufName') - if nextName != -1 && (!exists("t:NERDTreeBufName") || nextName != t:NERDTreeBufName) - call add(treeBufNames, nextName) - endif - endfor - let treeBufNames = s:unique(treeBufNames) - - "map the option names (that the user will be prompted with) to the nerd - "tree buffer names - let options = {} - let i = 0 - while i < len(treeBufNames) - let bufName = treeBufNames[i] - let treeRoot = getbufvar(bufName, "NERDTreeRoot") - let options[i+1 . '. ' . treeRoot.path.str() . ' (buf name: ' . bufName . ')'] = bufName - let i = i + 1 - endwhile - - "work out which tree to mirror, if there is more than 1 then ask the user - let bufferName = '' - if len(keys(options)) > 1 - let choices = ["Choose a tree to mirror"] - let choices = extend(choices, sort(keys(options))) - let choice = inputlist(choices) - if choice < 1 || choice > len(options) || choice ==# '' - return - endif - - let bufferName = options[sort(keys(options))[choice-1]] - elseif len(keys(options)) ==# 1 - let bufferName = values(options)[0] - else - call s:echo("No trees to mirror") - return - endif - - if s:treeExistsForTab() && s:isTreeOpen() - call s:closeTree() - endif - - let t:NERDTreeBufName = bufferName - call s:createTreeWin() - exec 'buffer ' . bufferName - if !&hidden - call s:renderView() - endif -endfunction -" FUNCTION: s:nextBufferName() {{{2 -" returns the buffer name for the next nerd tree -function! s:nextBufferName() - let name = s:NERDTreeBufName . s:next_buffer_number - let s:next_buffer_number += 1 - return name -endfunction -" FUNCTION: s:tabpagevar(tabnr, var) {{{2 -function! s: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:treeExistsForBuffer() {{{2 -" Returns 1 if a nerd tree root exists in the current buffer -function! s:treeExistsForBuf() - return exists("b:NERDTreeRoot") -endfunction -" Function: s:treeExistsForTab() {{{2 -" Returns 1 if a nerd tree root exists in the current tab -function! s:treeExistsForTab() - return exists("t:NERDTreeBufName") -endfunction -" Function: s:unique(list) {{{2 -" returns a:list without duplicates -function! s:unique(list) - let uniqlist = [] - for elem in a:list - if index(uniqlist, elem) ==# -1 - let uniqlist += [elem] - endif - endfor - return uniqlist -endfunction -" SECTION: Public API {{{1 -"============================================================ -let g:NERDTreePath = s:Path -let g:NERDTreeDirNode = s:TreeDirNode -let g:NERDTreeFileNode = s:TreeFileNode -let g:NERDTreeBookmark = s:Bookmark - -function! NERDTreeAddMenuItem(options) - call s:MenuItem.Create(a:options) -endfunction - -function! NERDTreeAddMenuSeparator(...) - let opts = a:0 ? a:1 : {} - call s:MenuItem.CreateSeparator(opts) -endfunction - -function! NERDTreeAddSubmenu(options) - return s:MenuItem.Create(a:options) -endfunction - -function! NERDTreeAddKeyMap(options) - call s:KeyMap.Create(a:options) -endfunction - -function! NERDTreeRender() - call s:renderView() -endfunction - -" SECTION: View Functions {{{1 -"============================================================ -"FUNCTION: s:centerView() {{{2 -"centers the nerd tree window around the cursor (provided the nerd tree -"options permit) -function! s:centerView() - if g:NERDTreeAutoCenter - let current_line = winline() - let lines_to_top = current_line - let lines_to_bottom = winheight(s:getTreeWinNum()) - current_line - if lines_to_top < g:NERDTreeAutoCenterThreshold || lines_to_bottom < g:NERDTreeAutoCenterThreshold - normal! zz - endif - endif -endfunction -"FUNCTION: s:closeTree() {{{2 -"Closes the primary NERD tree window for this tab -function! s:closeTree() - if !s:isTreeOpen() - throw "NERDTree.NoTreeFoundError: no NERDTree is open" - endif - - if winnr("$") != 1 - call s:exec(s:getTreeWinNum() . " wincmd w") - close - call s:exec("wincmd p") - else - close - endif -endfunction - -"FUNCTION: s:closeTreeIfOpen() {{{2 -"Closes the NERD tree window if it is open -function! s:closeTreeIfOpen() - if s:isTreeOpen() - call s:closeTree() - endif -endfunction -"FUNCTION: s:closeTreeIfQuitOnOpen() {{{2 -"Closes the NERD tree window if the close on open option is set -function! s:closeTreeIfQuitOnOpen() - if g:NERDTreeQuitOnOpen && s:isTreeOpen() - call s:closeTree() - endif -endfunction -"FUNCTION: s:createTreeWin() {{{2 -"Inits the NERD tree window. ie. opens it, sizes it, sets all the local -"options etc -function! s:createTreeWin() - "create the nerd tree window - let splitLocation = g:NERDTreeWinPos ==# "left" ? "topleft " : "botright " - let splitSize = g:NERDTreeWinSize - - if !exists('t:NERDTreeBufName') - let t:NERDTreeBufName = s: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 - - "throwaway buffer options - setlocal noswapfile - setlocal buftype=nofile - setlocal nowrap - setlocal foldcolumn=0 - setlocal nobuflisted - setlocal nospell - if g:NERDTreeShowLineNumbers - setlocal nu - else - setlocal nonu - endif - - iabc <buffer> - - if g:NERDTreeHighlightCursorline - setlocal cursorline - endif - - call s:setupStatusline() - - call s:bindMappings() - setfiletype nerdtree - " syntax highlighting - if has("syntax") && exists("g:syntax_on") - call s:setupSyntaxHighlighting() - endif -endfunction - -"FUNCTION: s:dumpHelp {{{2 -"prints out the quick help -function! s:dumpHelp() - let old_h = @h - if b:treeShowHelp ==# 1 - let @h= "\" NERD tree (" . s:NERD_tree_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."\"\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 - if len(s:KeyMap.All()) - let @h=@h."\"\n\" ----------------------------\n" - let @h=@h."\" Custom mappings~\n" - for i in s:KeyMap.All() - let @h=@h."\" ". i.key .": ". i.quickhelpText ."\n" - endfor - endif - - 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" - else - let @h="\" Press ". g:NERDTreeMapHelp ." for help\n" - endif - - silent! put h - - let @h = old_h -endfunction -"FUNCTION: s:echo {{{2 -"A wrapper for :echo. Appends 'NERDTree:' on the front of all messages -" -"Args: -"msg: the message to echo -function! s:echo(msg) - redraw - echomsg "NERDTree: " . a:msg -endfunction -"FUNCTION: s:echoWarning {{{2 -"Wrapper for s:echo, sets the message type to warningmsg for this message -"Args: -"msg: the message to echo -function! s:echoWarning(msg) - echohl warningmsg - call s:echo(a:msg) - echohl normal -endfunction -"FUNCTION: s:echoError {{{2 -"Wrapper for s:echo, sets the message type to errormsg for this message -"Args: -"msg: the message to echo -function! s:echoError(msg) - echohl errormsg - call s:echo(a:msg) - echohl normal -endfunction -"FUNCTION: s:firstUsableWindow(){{{2 -"find the window number of the first normal window -function! s: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: s:getPath(ln) {{{2 -"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:getPath(ln) - let line = getline(a:ln) - - let rootLine = s:TreeFileNode.GetRootLineNum() - - "check to see if we have the root node - if a:ln == rootLine - return b:NERDTreeRoot.path - endif - - " in case called from outside the tree - if line !~ '^ *[|`]' || line =~ '^$' - return {} - endif - - if line ==# s:tree_up_dir_line - return b:NERDTreeRoot.path.getParent() - endif - - let indent = s:indentLevelFor(line) - - "remove the tree parts and the leading space - let curFile = s:stripMarkupFromLine(line, 0) - - let wasdir = 0 - if curFile =~ '/$' - let wasdir = 1 - let curFile = substitute(curFile, '/\?$', '/', "") - endif - - let dir = "" - let lnum = a:ln - while lnum > 0 - let lnum = lnum - 1 - let curLine = getline(lnum) - let curLineStripped = s:stripMarkupFromLine(curLine, 1) - - "have we reached the top of the tree? - if lnum == rootLine - let dir = b:NERDTreeRoot.path.str({'format': 'UI'}) . dir - break - endif - if curLineStripped =~ '/$' - let lpindent = s: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 = s:Path.New(curFile) - return toReturn -endfunction - -"FUNCTION: s:getTreeWinNum() {{{2 -"gets the nerd tree window number for this tab -function! s:getTreeWinNum() - if exists("t:NERDTreeBufName") - return bufwinnr(t:NERDTreeBufName) - else - return -1 - endif -endfunction -"FUNCTION: s:indentLevelFor(line) {{{2 -function! s:indentLevelFor(line) - return match(a:line, '[^ \-+~`|]') / s:tree_wid -endfunction -"FUNCTION: s:isTreeOpen() {{{2 -function! s:isTreeOpen() - return s:getTreeWinNum() != -1 -endfunction -"FUNCTION: s:isWindowUsable(winnumber) {{{2 -"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:isWindowUsable(winnumber) - "gotta split if theres only one window (i.e. the NERD tree) - if winnr("$") ==# 1 - return 0 - endif - - let oldwinnr = winnr() - call s:exec(a:winnumber . "wincmd p") - let specialWindow = getbufvar("%", '&buftype') != '' || getwinvar('%', '&previewwindow') - let modified = &modified - call s: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 || s:bufInWindows(winbufnr(a:winnumber)) >= 2 -endfunction - -" FUNCTION: s:jumpToChild(direction) {{{2 -" Args: -" direction: 0 if going to first child, 1 if going to last -function! s:jumpToChild(direction) - let currentNode = s:TreeFileNode.GetSelected() - if currentNode ==# {} || currentNode.isRoot() - call s:echo("cannot jump to " . (a:direction ? "last" : "first") . " child") - return - end - let dirNode = currentNode.parent - let childNodes = dirNode.getVisibleChildren() - - let targetNode = childNodes[0] - if a:direction - let targetNode = childNodes[len(childNodes) - 1] - endif - - if targetNode.equals(currentNode) - let siblingDir = 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 s:centerView() -endfunction - - -"FUNCTION: s:promptToDelBuffer(bufnum, msg){{{2 -"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 nr2char(getchar()) ==# 'y' - exec "silent bdelete! " . a:bufnum - endif -endfunction - -"FUNCTION: s:putCursorOnBookmarkTable(){{{2 -"Places the cursor at the top of the bookmarks table -function! s:putCursorOnBookmarkTable() - if !b:NERDTreeShowBookmarks - throw "NERDTree.IllegalOperationError: cant find bookmark table, bookmarks arent active" - endif - - let rootNodeLine = s:TreeFileNode.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, 0) -endfunction - -"FUNCTION: s:putCursorInTreeWin(){{{2 -"Places the cursor in the nerd tree window -function! s:putCursorInTreeWin() - if !s:isTreeOpen() - throw "NERDTree.InvalidOperationError: cant put cursor in NERD tree window, no window exists" - endif - - call s:exec(s:getTreeWinNum() . "wincmd w") -endfunction - -"FUNCTION: s:renderBookmarks {{{2 -function! s:renderBookmarks() - - call setline(line(".")+1, ">----------Bookmarks----------") - call cursor(line(".")+1, col(".")) - - for i in s:Bookmark.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:renderView {{{2 -"The entry function for rendering the tree -function! s:renderView() - 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 s:dumpHelp() - - "delete the blank line before the help and add one after it - call setline(line(".")+1, "") - call cursor(line(".")+1, col(".")) - - if b:NERDTreeShowBookmarks - call s:renderBookmarks() - endif - - "add the 'up a dir' line - call setline(line(".")+1, s:tree_up_dir_line) - call cursor(line(".")+1, col(".")) - - "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: s:renderViewSavingPosition {{{2 -"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:renderViewSavingPosition() - let currentNode = s:TreeFileNode.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 s:renderView() - - if currentNode != {} - call currentNode.putCursorHere(0, 0) - endif -endfunction -"FUNCTION: s:restoreScreenState() {{{2 -" -"Sets the screen state back to what it was when s:saveScreenState was last -"called. -" -"Assumes the cursor is in the NERDTree window -function! s:restoreScreenState() - if !exists("b:NERDTreeOldTopLine") || !exists("b:NERDTreeOldPos") || !exists("b:NERDTreeOldWindowSize") - return - endif - exec("silent vertical resize ".b:NERDTreeOldWindowSize) - - let old_scrolloff=&scrolloff - let &scrolloff=0 - call cursor(b:NERDTreeOldTopLine, 0) - normal! zt - call setpos(".", b:NERDTreeOldPos) - let &scrolloff=old_scrolloff -endfunction - -"FUNCTION: s:saveScreenState() {{{2 -"Saves the current cursor position in the current buffer and the window -"scroll position -function! s:saveScreenState() - let win = winnr() - try - call s:putCursorInTreeWin() - let b:NERDTreeOldPos = getpos(".") - let b:NERDTreeOldTopLine = line("w0") - let b:NERDTreeOldWindowSize = winwidth("") - call s:exec(win . "wincmd w") - catch /^NERDTree.InvalidOperationError/ - endtry -endfunction - -"FUNCTION: s:setupStatusline() {{{2 -function! s:setupStatusline() - if g:NERDTreeStatusline != -1 - let &l:statusline = g:NERDTreeStatusline - endif -endfunction -"FUNCTION: s:setupSyntaxHighlighting() {{{2 -function! s:setupSyntaxHighlighting() - "treeFlags are syntax items that should be invisible, but give clues as to - "how things should be highlighted - syn match treeFlag #\~# - syn match treeFlag #\[RO\]# - - "highlighting for the .. (up dir) line at the top of the tree - execute "syn match treeUp #". s:tree_up_dir_line ."#" - - "highlighting for the ~/+ symbols for the directory nodes - syn match treeClosable #\~\<# - syn match treeClosable #\~\.# - syn match treeOpenable #+\<# - syn match treeOpenable #+\.#he=e-1 - - "highlighting for the tree structural parts - syn match treePart #|# - syn match treePart #`# - syn match treePartFile #[|`]-#hs=s+1 contains=treePart - - "quickhelp syntax elements - syn match treeHelpKey #" \{1,2\}[^ ]*:#hs=s+2,he=e-1 - syn match treeHelpKey #" \{1,2\}[^ ]*,#hs=s+2,he=e-1 - syn match treeHelpTitle #" .*\~#hs=s+2,he=e-1 contains=treeFlag - syn match treeToggleOn #".*(on)#hs=e-2,he=e-1 contains=treeHelpKey - syn match treeToggleOff #".*(off)#hs=e-3,he=e-1 contains=treeHelpKey - syn match treeHelpCommand #" :.\{-}\>#hs=s+3 - syn match treeHelp #^".*# contains=treeHelpKey,treeHelpTitle,treeFlag,treeToggleOff,treeToggleOn,treeHelpCommand - - "highlighting for readonly files - syn match treeRO #.*\[RO\]#hs=s+2 contains=treeFlag,treeBookmark,treePart,treePartFile - - "highlighting for sym links - syn match treeLink #[^-| `].* -> # contains=treeBookmark,treeOpenable,treeClosable,treeDirSlash - - "highlighing for directory nodes and file nodes - syn match treeDirSlash #/# - syn match treeDir #[^-| `].*/# contains=treeLink,treeDirSlash,treeOpenable,treeClosable - syn match treeExecFile #[|`]-.*\*\($\| \)# contains=treeLink,treePart,treeRO,treePartFile,treeBookmark - syn match treeFile #|-.*# contains=treeLink,treePart,treeRO,treePartFile,treeBookmark,treeExecFile - syn match treeFile #`-.*# contains=treeLink,treePart,treeRO,treePartFile,treeBookmark,treeExecFile - syn match treeCWD #^/.*$# - - "highlighting for bookmarks - syn match treeBookmark # {.*}#hs=s+1 - - "highlighting for the bookmarks table - syn match treeBookmarksLeader #^># - syn match treeBookmarksHeader #^>-\+Bookmarks-\+$# contains=treeBookmarksLeader - syn match treeBookmarkName #^>.\{-} #he=e-1 contains=treeBookmarksLeader - syn match treeBookmark #^>.*$# contains=treeBookmarksLeader,treeBookmarkName,treeBookmarksHeader - - if g:NERDChristmasTree - hi def link treePart Special - hi def link treePartFile Type - hi def link treeFile Normal - hi def link treeExecFile Title - hi def link treeDirSlash Identifier - hi def link treeClosable Type - else - hi def link treePart Normal - hi def link treePartFile Normal - hi def link treeFile Normal - hi def link treeClosable Title - endif - - hi def link treeBookmarksHeader statement - hi def link treeBookmarksLeader ignore - hi def link treeBookmarkName Identifier - hi def link treeBookmark normal - - hi def link treeHelp String - hi def link treeHelpKey Identifier - hi def link treeHelpCommand Identifier - hi def link treeHelpTitle Macro - hi def link treeToggleOn Question - hi def link treeToggleOff WarningMsg - - hi def link treeDir Directory - hi def link treeUp Directory - hi def link treeCWD Statement - hi def link treeLink Macro - hi def link treeOpenable Title - hi def link treeFlag ignore - hi def link treeRO WarningMsg - hi def link treeBookmark Statement - - hi def link NERDTreeCurrentNode Search -endfunction - -"FUNCTION: s:stripMarkupFromLine(line, removeLeadingSpaces){{{2 -"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:stripMarkupFromLine(line, removeLeadingSpaces) - let line = a:line - "remove the tree parts and the leading space - let line = substitute (line, s:tree_markup_reg,"","") - - "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\($\| \)', "","") - - 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:toggle(dir) {{{2 -"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:toggle(dir) - if s:treeExistsForTab() - if !s:isTreeOpen() - call s:createTreeWin() - if !&hidden - call s:renderView() - endif - call s:restoreScreenState() - else - call s:closeTree() - endif - else - call s:initNerdTree(a:dir) - endif -endfunction -"SECTION: Interface bindings {{{1 -"============================================================ -"FUNCTION: s:activateNode(forceKeepWindowOpen) {{{2 -"If the current node is a file, open it in the previous window (or a new one -"if the previous is modified). If it is a directory then it is opened. -" -"args: -"forceKeepWindowOpen - dont close the window even if NERDTreeQuitOnOpen is set -function! s:activateNode(forceKeepWindowOpen) - if getline(".") ==# s:tree_up_dir_line - return s:upDir(0) - endif - - let treenode = s:TreeFileNode.GetSelected() - if treenode != {} - call treenode.activate(a:forceKeepWindowOpen) - else - let bookmark = s:Bookmark.GetSelected() - if !empty(bookmark) - call bookmark.activate() - endif - endif -endfunction - -"FUNCTION: s:bindMappings() {{{2 -function! s:bindMappings() - " set up mappings and commands for this buffer - nnoremap <silent> <buffer> <middlerelease> :call <SID>handleMiddleMouse()<cr> - nnoremap <silent> <buffer> <leftrelease> <leftrelease>:call <SID>checkForActivate()<cr> - nnoremap <silent> <buffer> <2-leftmouse> :call <SID>activateNode(0)<cr> - - exec "nnoremap <silent> <buffer> ". g:NERDTreeMapActivateNode . " :call <SID>activateNode(0)<cr>" - exec "nnoremap <silent> <buffer> ". g:NERDTreeMapOpenSplit ." :call <SID>openEntrySplit(0,0)<cr>" - exec "nnoremap <silent> <buffer> <cr> :call <SID>activateNode(0)<cr>" - - exec "nnoremap <silent> <buffer> ". g:NERDTreeMapPreview ." :call <SID>previewNode(0)<cr>" - exec "nnoremap <silent> <buffer> ". g:NERDTreeMapPreviewSplit ." :call <SID>previewNode(1)<cr>" - - exec "nnoremap <silent> <buffer> ". g:NERDTreeMapOpenVSplit ." :call <SID>openEntrySplit(1,0)<cr>" - exec "nnoremap <silent> <buffer> ". g:NERDTreeMapPreviewVSplit ." :call <SID>previewNode(2)<cr>" - - exec "nnoremap <silent> <buffer> ". g:NERDTreeMapOpenRecursively ." :call <SID>openNodeRecursively()<cr>" - - exec "nnoremap <silent> <buffer> ". g:NERDTreeMapUpdirKeepOpen ." :call <SID>upDir(1)<cr>" - exec "nnoremap <silent> <buffer> ". g:NERDTreeMapUpdir ." :call <SID>upDir(0)<cr>" - exec "nnoremap <silent> <buffer> ". g:NERDTreeMapChangeRoot ." :call <SID>chRoot()<cr>" - - exec "nnoremap <silent> <buffer> ". g:NERDTreeMapChdir ." :call <SID>chCwd()<cr>" - - exec "nnoremap <silent> <buffer> ". g:NERDTreeMapQuit ." :call <SID>closeTreeWindow()<cr>" - - exec "nnoremap <silent> <buffer> ". g:NERDTreeMapRefreshRoot ." :call <SID>refreshRoot()<cr>" - exec "nnoremap <silent> <buffer> ". g:NERDTreeMapRefresh ." :call <SID>refreshCurrent()<cr>" - - exec "nnoremap <silent> <buffer> ". g:NERDTreeMapHelp ." :call <SID>displayHelp()<cr>" - exec "nnoremap <silent> <buffer> ". g:NERDTreeMapToggleZoom ." :call <SID>toggleZoom()<cr>" - exec "nnoremap <silent> <buffer> ". g:NERDTreeMapToggleHidden ." :call <SID>toggleShowHidden()<cr>" - exec "nnoremap <silent> <buffer> ". g:NERDTreeMapToggleFilters ." :call <SID>toggleIgnoreFilter()<cr>" - exec "nnoremap <silent> <buffer> ". g:NERDTreeMapToggleFiles ." :call <SID>toggleShowFiles()<cr>" - exec "nnoremap <silent> <buffer> ". g:NERDTreeMapToggleBookmarks ." :call <SID>toggleShowBookmarks()<cr>" - - exec "nnoremap <silent> <buffer> ". g:NERDTreeMapCloseDir ." :call <SID>closeCurrentDir()<cr>" - exec "nnoremap <silent> <buffer> ". g:NERDTreeMapCloseChildren ." :call <SID>closeChildren()<cr>" - - exec "nnoremap <silent> <buffer> ". g:NERDTreeMapMenu ." :call <SID>showMenu()<cr>" - - exec "nnoremap <silent> <buffer> ". g:NERDTreeMapJumpParent ." :call <SID>jumpToParent()<cr>" - exec "nnoremap <silent> <buffer> ". g:NERDTreeMapJumpNextSibling ." :call <SID>jumpToSibling(1)<cr>" - exec "nnoremap <silent> <buffer> ". g:NERDTreeMapJumpPrevSibling ." :call <SID>jumpToSibling(0)<cr>" - exec "nnoremap <silent> <buffer> ". g:NERDTreeMapJumpFirstChild ." :call <SID>jumpToFirstChild()<cr>" - exec "nnoremap <silent> <buffer> ". g:NERDTreeMapJumpLastChild ." :call <SID>jumpToLastChild()<cr>" - exec "nnoremap <silent> <buffer> ". g:NERDTreeMapJumpRoot ." :call <SID>jumpToRoot()<cr>" - - exec "nnoremap <silent> <buffer> ". g:NERDTreeMapOpenInTab ." :call <SID>openInNewTab(0)<cr>" - exec "nnoremap <silent> <buffer> ". g:NERDTreeMapOpenInTabSilent ." :call <SID>openInNewTab(1)<cr>" - - exec "nnoremap <silent> <buffer> ". g:NERDTreeMapOpenExpl ." :call <SID>openExplorer()<cr>" - - exec "nnoremap <silent> <buffer> ". g:NERDTreeMapDeleteBookmark ." :call <SID>deleteBookmark()<cr>" - - "bind all the user custom maps - call s:KeyMap.BindAll() - - command! -buffer -nargs=1 Bookmark :call <SID>bookmarkNode('<args>') - command! -buffer -complete=customlist,s:completeBookmarks -nargs=1 RevealBookmark :call <SID>revealBookmark('<args>') - command! -buffer -complete=customlist,s:completeBookmarks -nargs=1 OpenBookmark :call <SID>openBookmark('<args>') - command! -buffer -complete=customlist,s:completeBookmarks -nargs=* ClearBookmarks call <SID>clearBookmarks('<args>') - command! -buffer -complete=customlist,s:completeBookmarks -nargs=+ BookmarkToRoot call s:Bookmark.ToRoot('<args>') - command! -buffer -nargs=0 ClearAllBookmarks call s:Bookmark.ClearAll() <bar> call <SID>renderView() - command! -buffer -nargs=0 ReadBookmarks call s:Bookmark.CacheBookmarks(0) <bar> call <SID>renderView() - command! -buffer -nargs=0 WriteBookmarks call s:Bookmark.Write() -endfunction - -" FUNCTION: s:bookmarkNode(name) {{{2 -" Associate the current node with the given name -function! s:bookmarkNode(name) - let currentNode = s:TreeFileNode.GetSelected() - if currentNode != {} - try - call currentNode.bookmark(a:name) - call s:renderView() - catch /^NERDTree.IllegalBookmarkNameError/ - call s:echo("bookmark names must not contain spaces") - endtry - else - call s:echo("select a node first") - endif -endfunction -"FUNCTION: s:checkForActivate() {{{2 -"Checks if the click should open the current node, if so then activate() is -"called (directories are automatically opened if the symbol beside them is -"clicked) -function! s:checkForActivate() - let currentNode = s:TreeFileNode.GetSelected() - if currentNode != {} - let startToCur = strpart(getline(line(".")), 0, col(".")) - let char = strpart(startToCur, strlen(startToCur)-1, 1) - - "if they clicked a dir, check if they clicked on the + or ~ sign - "beside it - if currentNode.path.isDirectory - if startToCur =~ s:tree_markup_reg . '$' && char =~ '[+~]' - call s:activateNode(0) - return - endif - endif - - if (g:NERDTreeMouseMode ==# 2 && currentNode.path.isDirectory) || g:NERDTreeMouseMode ==# 3 - if char !~ s:tree_markup_reg && startToCur !~ '\/$' - call s:activateNode(0) - return - endif - endif - endif -endfunction - -" FUNCTION: s:chCwd() {{{2 -function! s:chCwd() - let treenode = s:TreeFileNode.GetSelected() - if treenode ==# {} - call s:echo("Select a node first") - return - endif - - try - call treenode.path.changeToDir() - catch /^NERDTree.PathChangeError/ - call s:echoWarning("could not change cwd") - endtry -endfunction - -" FUNCTION: s:chRoot() {{{2 -" changes the current root to the selected one -function! s:chRoot() - let treenode = s:TreeFileNode.GetSelected() - if treenode ==# {} - call s:echo("Select a node first") - return - endif - - call treenode.makeRoot() - call s:renderView() - call b:NERDTreeRoot.putCursorHere(0, 0) -endfunction - -" FUNCTION: s:clearBookmarks(bookmarks) {{{2 -function! s:clearBookmarks(bookmarks) - if a:bookmarks ==# '' - let currentNode = s:TreeFileNode.GetSelected() - if currentNode != {} - call currentNode.clearBoomarks() - endif - else - for name in split(a:bookmarks, ' ') - let bookmark = s:Bookmark.BookmarkFor(name) - call bookmark.delete() - endfor - endif - call s:renderView() -endfunction -" FUNCTION: s:closeChildren() {{{2 -" closes all childnodes of the current node -function! s:closeChildren() - let currentNode = s:TreeDirNode.GetSelected() - if currentNode ==# {} - call s:echo("Select a node first") - return - endif - - call currentNode.closeChildren() - call s:renderView() - call currentNode.putCursorHere(0, 0) -endfunction -" FUNCTION: s:closeCurrentDir() {{{2 -" closes the parent dir of the current node -function! s:closeCurrentDir() - let treenode = s:TreeFileNode.GetSelected() - if treenode ==# {} - call s:echo("Select a node first") - return - endif - - let parent = treenode.parent - if parent ==# {} || parent.isRoot() - call s:echo("cannot close tree root") - else - call treenode.parent.close() - call s:renderView() - call treenode.parent.putCursorHere(0, 0) - endif -endfunction -" FUNCTION: s:closeTreeWindow() {{{2 -" close the tree window -function! s:closeTreeWindow() - if b:NERDTreeType ==# "secondary" && b:NERDTreePreviousBuf != -1 - exec "buffer " . b:NERDTreePreviousBuf - else - if winnr("$") > 1 - call s:closeTree() - else - call s:echo("Cannot close last window") - endif - endif -endfunction -" FUNCTION: s:deleteBookmark() {{{2 -" if the cursor is on a bookmark, prompt to delete -function! s:deleteBookmark() - let bookmark = s:Bookmark.GetSelected() - if bookmark ==# {} - call s:echo("Put the cursor on a bookmark") - return - endif - - echo "Are you sure you wish to delete the bookmark:\n\"" . bookmark.name . "\" (yN):" - - if nr2char(getchar()) ==# 'y' - try - call bookmark.delete() - call s:renderView() - redraw - catch /^NERDTree/ - call s:echoWarning("Could not remove bookmark") - endtry - else - call s:echo("delete aborted" ) - endif - -endfunction - -" FUNCTION: s:displayHelp() {{{2 -" toggles the help display -function! s:displayHelp() - let b:treeShowHelp = b:treeShowHelp ? 0 : 1 - call s:renderView() - call s:centerView() -endfunction - -" FUNCTION: s:handleMiddleMouse() {{{2 -function! s:handleMiddleMouse() - let curNode = s:TreeFileNode.GetSelected() - if curNode ==# {} - call s:echo("Put the cursor on a node first" ) - return - endif - - if curNode.path.isDirectory - call s:openExplorer() - else - call s:openEntrySplit(0,0) - endif -endfunction - - -" FUNCTION: s:jumpToFirstChild() {{{2 -" wrapper for the jump to child method -function! s:jumpToFirstChild() - call s:jumpToChild(0) -endfunction - -" FUNCTION: s:jumpToLastChild() {{{2 -" wrapper for the jump to child method -function! s:jumpToLastChild() - call s:jumpToChild(1) -endfunction - -" FUNCTION: s:jumpToParent() {{{2 -" moves the cursor to the parent of the current node -function! s:jumpToParent() - let currentNode = s:TreeFileNode.GetSelected() - if !empty(currentNode) - if !empty(currentNode.parent) - call currentNode.parent.putCursorHere(1, 0) - call s:centerView() - else - call s:echo("cannot jump to parent") - endif - else - call s:echo("put the cursor on a node first") - endif -endfunction - -" FUNCTION: s:jumpToRoot() {{{2 -" moves the cursor to the root node -function! s:jumpToRoot() - call b:NERDTreeRoot.putCursorHere(1, 0) - call s:centerView() -endfunction - -" FUNCTION: s:jumpToSibling() {{{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(forward) - let currentNode = s:TreeFileNode.GetSelected() - if !empty(currentNode) - let sibling = currentNode.findSibling(a:forward) - - if !empty(sibling) - call sibling.putCursorHere(1, 0) - call s:centerView() - endif - else - call s:echo("put the cursor on a node first") - endif -endfunction - -" FUNCTION: s:openBookmark(name) {{{2 -" put the cursor on the given bookmark and, if its a file, open it -function! s:openBookmark(name) - try - let targetNode = s:Bookmark.GetNodeForName(a:name, 0) - call targetNode.putCursorHere(0, 1) - redraw! - catch /^NERDTree.BookmarkedNodeNotFoundError/ - call s:echo("note - target node is not cached") - let bookmark = s:Bookmark.BookmarkFor(a:name) - let targetNode = s:TreeFileNode.New(bookmark.path) - endtry - if targetNode.path.isDirectory - call targetNode.openExplorer() - else - call targetNode.open() - endif -endfunction -" FUNCTION: s:openEntrySplit(vertical, forceKeepWindowOpen) {{{2 -"Opens the currently selected file from the explorer in a -"new window -" -"args: -"forceKeepWindowOpen - dont close the window even if NERDTreeQuitOnOpen is set -function! s:openEntrySplit(vertical, forceKeepWindowOpen) - let treenode = s:TreeFileNode.GetSelected() - if treenode != {} - if a:vertical - call treenode.openVSplit() - else - call treenode.openSplit() - endif - if !a:forceKeepWindowOpen - call s:closeTreeIfQuitOnOpen() - endif - else - call s:echo("select a node first") - endif -endfunction - -" FUNCTION: s:openExplorer() {{{2 -function! s:openExplorer() - let treenode = s:TreeDirNode.GetSelected() - if treenode != {} - call treenode.openExplorer() - else - call s:echo("select a node first") - endif -endfunction - -" FUNCTION: s:openInNewTab(stayCurrentTab) {{{2 -" Opens the selected node or bookmark in a new tab -" Args: -" stayCurrentTab: if 1 then vim will stay in the current tab, if 0 then vim -" will go to the tab where the new file is opened -function! s:openInNewTab(stayCurrentTab) - let target = s:TreeFileNode.GetSelected() - if target == {} - let target = s:Bookmark.GetSelected() - endif - - if target != {} - call target.openInNewTab({'stayInCurrentTab': a:stayCurrentTab}) - endif -endfunction - -" FUNCTION: s:openNodeRecursively() {{{2 -function! s:openNodeRecursively() - let treenode = s:TreeFileNode.GetSelected() - if treenode ==# {} || treenode.path.isDirectory ==# 0 - call s:echo("Select a directory node first" ) - else - call s:echo("Recursively opening node. Please wait...") - call treenode.openRecursively() - call s:renderView() - redraw - call s:echo("Recursively opening node. Please wait... DONE") - endif - -endfunction - -"FUNCTION: s:previewNode() {{{2 -"Args: -" openNewWin: if 0, use the previous window, if 1 open in new split, if 2 -" open in a vsplit -function! s:previewNode(openNewWin) - let currentBuf = bufnr("") - if a:openNewWin > 0 - call s:openEntrySplit(a:openNewWin ==# 2,1) - else - call s:activateNode(1) - end - call s:exec(bufwinnr(currentBuf) . "wincmd w") -endfunction - -" FUNCTION: s:revealBookmark(name) {{{2 -" put the cursor on the node associate with the given name -function! s:revealBookmark(name) - try - let targetNode = s:Bookmark.GetNodeForName(a:name, 0) - call targetNode.putCursorHere(0, 1) - catch /^NERDTree.BookmarkNotFoundError/ - call s:echo("Bookmark isnt cached under the current root") - endtry -endfunction -" FUNCTION: s:refreshRoot() {{{2 -" Reloads the current root. All nodes below this will be lost and the root dir -" will be reloaded. -function! s:refreshRoot() - call s:echo("Refreshing the root node. This could take a while...") - call b:NERDTreeRoot.refresh() - call s:renderView() - redraw - call s:echo("Refreshing the root node. This could take a while... DONE") -endfunction - -" FUNCTION: s:refreshCurrent() {{{2 -" refreshes the root for the current node -function! s:refreshCurrent() - let treenode = s:TreeDirNode.GetSelected() - if treenode ==# {} - call s:echo("Refresh failed. Select a node first") - return - endif - - call s:echo("Refreshing node. This could take a while...") - call treenode.refresh() - call s:renderView() - redraw - call s:echo("Refreshing node. This could take a while... DONE") -endfunction -" FUNCTION: s:showMenu() {{{2 -function! s:showMenu() - let curNode = s:TreeFileNode.GetSelected() - if curNode ==# {} - call s:echo("Put the cursor on a node first" ) - return - endif - - let mc = s:MenuController.New(s:MenuItem.AllEnabled()) - call mc.showMenu() -endfunction - -" FUNCTION: s:toggleIgnoreFilter() {{{2 -" toggles the use of the NERDTreeIgnore option -function! s:toggleIgnoreFilter() - let b:NERDTreeIgnoreEnabled = !b:NERDTreeIgnoreEnabled - call s:renderViewSavingPosition() - call s:centerView() -endfunction - -" FUNCTION: s:toggleShowBookmarks() {{{2 -" toggles the display of bookmarks -function! s:toggleShowBookmarks() - let b:NERDTreeShowBookmarks = !b:NERDTreeShowBookmarks - if b:NERDTreeShowBookmarks - call s:renderView() - call s:putCursorOnBookmarkTable() - else - call s:renderViewSavingPosition() - endif - call s:centerView() -endfunction -" FUNCTION: s:toggleShowFiles() {{{2 -" toggles the display of hidden files -function! s:toggleShowFiles() - let b:NERDTreeShowFiles = !b:NERDTreeShowFiles - call s:renderViewSavingPosition() - call s:centerView() -endfunction - -" FUNCTION: s:toggleShowHidden() {{{2 -" toggles the display of hidden files -function! s:toggleShowHidden() - let b:NERDTreeShowHidden = !b:NERDTreeShowHidden - call s:renderViewSavingPosition() - call s:centerView() -endfunction - -" FUNCTION: s:toggleZoom() {{2 -" zoom (maximize/minimize) the NERDTree window -function! s: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:upDir(keepState) {{{2 -"moves the tree up a level -" -"Args: -"keepState: 1 if the current root should be left open when the tree is -"re-rendered -function! s:upDir(keepState) - let cwd = b:NERDTreeRoot.path.str({'format': 'UI'}) - if cwd ==# "/" || cwd =~ '^[^/]..$' - call s: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 = s:TreeDirNode.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 s:renderView() - call oldRoot.putCursorHere(0, 0) - endif -endfunction - - -"reset &cpo back to users setting -let &cpo = s:old_cpo - -" vim: set sw=4 sts=4 et fdm=marker: diff --git a/vim/plugin/ScrollColor.vim b/vim/plugin/ScrollColor.vim deleted file mode 100644 index 7c4960c..0000000 --- a/vim/plugin/ScrollColor.vim +++ /dev/null @@ -1,457 +0,0 @@ -" ScrollColors.vim - Colorsheme Scroller, Chooser, and Browser -" -" Author and maintainer: Yakov Lerner <iler_ml@fastmail.fm> -" Last Change: 2006-07-18 -" -" SYNOPSIS: -" This is colorscheme Scroller/Chooser/Browser. -" With this plugin, you walk through installed -" colorschemes using arrow keys. -" -" SHORT USAGE DESCRIPTION: -" Drop ScrollColors.vim into your plugin directory. -" Type :SCROLL -" Use arrow keys to walk through colorschemes, ? for help, Esc to exit. -" -" DETAILED DESCRIPTION: -" 1. source ScrollColors.vim " or drop ScrollColors.vim into -" " your ~/.vim/plugins directory -" 2. Type :SCROLL -" 3. Use arrows to scroll thgough colorschemes. -" 4. When done, press Esc to exit. You will be prompted -" wether to -" -" You can download 140 colorschemes pack from: -" http://www.vim.org/scripts/script.php?script_id=625 -" Having 140 installed colorschemes is in no way prerequisite for -" ScrollColors. But with ScrollColors you can preview 140 colorschemes -" in couple of minutes. -" -" CUSTOM KEY MAPPINGS: -" You can map two keys of your choice to NextColor and PrevColor actions. -" Choose pair of shortcut keys (for example <F2> and <f3>, or \n and \p) -" and map them as follows: -" map <silent><F3> :NEXTCOLOR<cr> -" map <silent><F2> :PREVCOLOR<cr> - - -if exists("g:scroll_colors") | finish | endif -let g:scroll_colors = 1 - -command! COLORSCROLL :call s:ColorScroller() -command! SCROLLCOLOR :call s:ColorScroller() -command! NEXTCOLOR :call s:NextColorscheme() -command! PREVCOLOR :call s:PrevColorscheme() - -" Example of convenience mappings: -"map <silent><F3> :NEXTCOLOR<cr> -"map <silent><F2> :PREVCOLOR<cr> -"map <silent><F4> :SCROLLCOLOR<cr> - -function! s:ScrollerHelp() - echo " " - echohl Title - echo "Color Scroller Help:" - echo "--------------------" - echohl NONE - echo "Arrows - change colorscheme" - echo "Esc,q,Enter - exit" - echo "h,j,k,l - change colorscheme" - echo "0,g - go to first colorscheme" - echo "$,G - go to last colorscheme" - echo "L - list colorschemes" - echo "PgUp,PgDown - jump by 10 colorschemes" - echo "# - go to colorscheme by index (1-N)" - echo "R - refresh colorscheme list" - echo "? - this help text" - echohl MoreMsg - echo "Press any key to continue" - echohl NONE - call getchar() -endfu - -function! s:Align(s, width) - if strlen(a:s) >= a:width - return a:s." " - else - let pad=" " - let res=a:s - while strlen(res) < a:width - let chunk = (a:width - strlen(res) > strlen(pad) ? strlen(pad) : a:width - strlen(res)) - let res = res . strpart(pad,0,chunk) - endw - return res - endif -endfu - -function! s:ListColors() - echo " " - let list=s:GetColorschemesList() - let width=18 - let pos=0 - while list != '' - let str=substitute(list,"\n.*","","") - let list=substitute(list,"[^\n]*\n", "", "") - let aligned = s:Align(str, width) - if( pos+strlen(aligned)+1 >= &columns) - echo " " - let pos=0 - endif - echon aligned - let pos = pos + strlen(aligned) - endw - echo "Press any key to continue" - call getchar() -endfu - -function! s:CurrentColor() - return exists("g:colors_name") ? g:colors_name : "" -endfu - -function! s:SetColor(name) - exe "color ".a:name - " if we do not assign a:colors_name, then - " bad things happen if file colors/name.vim conmtains wrong assignment inside. - " Wrong assignment inside happens when file was copied but - " assignment inside not fixed. - " Such wrong assignment cause up erratic switches unless - " we do our own assignment to g:colors_name - let g:colors_name=a:name -endfu - -function! s:JumpByIndex(list,total) - let ans = input("Enter colorscheme number (1-".a:total.") : ") - let index = (ans<=0? 1 : 1+(ans-1)%a:total ) - let name = s:EntryByIndex(a:list, index ) - call s:SetColor(name) -endfu - -function! s:JumpByIndex2(list,total, index) - let mod = (a:index <= 0? 1 : 1+(a:index-1)%a:total ) - let name = s:EntryByIndex(a:list, mod ) - call s:SetColor(name) -endfu - -function! s:ExitDialog(old, action) - let ans = 0 - - if a:old == s:CurrentColor() - let ans=1 - elseif a:action == '' - let ans = confirm("Keep this colorscheme ?", "&Yes\n&No\n&Cancel") - elseif action == 'keep' - ans = 1 - elseif action == 'revert' - ans = 2 - endif - - if ans == 1 || ans==0 - " exit, keep colorscheme - let msg = (a:old == s:CurrentColor() ? '' : "(original: '".a:old."')") - call s:FinalEcho( msg ) - elseif ans == 2 - " exit, revert colorscheme - call s:SetColor(a:old) - call s:FinalEcho('original color restored') - elseif ans == 3 - " do not exit, continue browsing - return -1 - endif -endfu - -function! s:ColorScroller() - let old = s:CurrentColor() - let list = s:GetColorschemesList() - let total = s:CountEntries(list) - let loop=0 - - if line("$") == 1 && getline(1) == "" && bufnr('$')==1 - " if buffer is empty, open something - echo "We will open sample text with syntax highlighting." - echo "Watch for the guiding prompt in the bottom line." - echo "When the text will open, use Arrow keys to switch colorschemes, ? for help." - echo " " - echo "Press any key to continue" - call getchar() - :e $VIMRUNTIME/syntax/abc.vim - :setlocal ro - syntax on - redraw - endif - - if !exists("g:syntax_on") - syntax on - redraw - endif - - while 1 - redraw - let index = s:FindIndex(list, s:CurrentColor()) - echo "[" - echohl Search - echon s:CurrentColor() - echohl NONE - if loop == 0 - echon "] ColorScroller: " - echohl MoreMsg | echon "Arrows" | echohl NONE | echon "-next/prev; " - echohl MoreMsg | echon "Esc" | echohl NONE | echon "-exit; " - echohl MoreMsg | echon "?" | echohl NONE | echon "-help > " - else - echon "] " - echon " " . index . "/" . total . " " - echon s:Align("", 12-strlen(s:CurrentColor())) - echon "> ColorScroll > " - echon "Arrows,Esc,? > " - endif - let key = getchar() - let c = nr2char(key) - - if key == "\<Left>" || key == "\<Up>" || c ==# 'h' || c ==# 'j' - call s:PrevSilent() - elseif key == "\<Down>" || key == "\<Right>" || c ==# 'l' || c==# 'k' || c==# ' ' - call s:NextSilent() - elseif c==# 'g' || c=='0' || c=='1' - call s:SetColor( s:GetFirstColors() ) - elseif c=='$' || c==# 'G' - call s:SetColor( s:GetLastColors() ) - elseif c ==# 'L' - " command 'L' list colors - call s:ListColors() - elseif c=='Z' || c=='z' || key == 13 || c=='q' || c=='Q' || c==':' || key == 27 - if s:ExitDialog(old, '') != -1 - break - endif - elseif key == 12 " c=="\<C-L>" - redraw - elseif c == '#' - call s:JumpByIndex(list,total) - elseif key == "\<PageDown>" - call s:JumpByIndex2(list,total, (index-10>=1 ? index-10 : index-10+total)) - elseif key == "\<PageUp>" - call s:JumpByIndex2(list,total, index+10) - elseif c == '?' - call s:ScrollerHelp() - elseif c == 'R' - call s:RefreshColorschemesList() - echo "Colorscheme list refreshed. Press any key to continue." - call getchar() - else - call s:ScrollerHelp() - endif - let loop = loop + 1 - endw -endfu - -" Get 1-based index of 'entry' in \n-separated 'list' -function! s:FindIndex(list,entry) - " we assume entry has no special chars or we could escape() it - let str = substitute("\n" . a:list . "\n", "\n" . a:entry . "\n.*$", "", "") - return 1 + s:CountEntries(str) -endfu - -" Get list element by 1-based index -function! s:EntryByIndex(list,index) - let k=1 - let tail=a:list - while tail != '' && k < a:index - let tail=substitute(tail, "^[^\n]*\n", "", "") - let k = k + 1 - endw - let tail = substitute(tail, "\n.*$", "", "") - return tail -endfu - -function! s:MakeWellFormedList(list) - - " make sure last \n is present - let str=a:list."\n" - " make sure leading \n are not present - let str=substitute(str, "^\n*", "", "") - " make sure entries are separated by exactly one \n - let str=substitute(str, "\n\\+", "\n", "g") - - return str -endfu - -function! s:CountEntries(list) - let str = s:MakeWellFormedList(a:list) - - let str=substitute(str, "[^\n]\\+\n", ".", "g") - - return strlen(str) -endfu - -function! s:RemoveDuplicates(list) - let sep = "\n" - let res = s:MakeWellFormedList(a:list . "\n") - let beg = 0 - while beg < strlen(res) - let end = matchend(res, sep, beg) - let str1 = strpart( res, beg, end - beg) - let res = strpart(res,0,end) . substitute("\n".strpart(res,end), "\n".str1,"\n","g") - let res = substitute(res, "\n\\+", "\n", "g") - let beg = end - endw - return res -endfu - -if v:version >= 700 - -" s:SortVar(): sort components of string @var separated -" by delimiter @sep, and returns the sorted string. -" For example, s:SortVar("c\nb\na", "\n") returns "a\nb\nc\n" -function! s:SortVar(list, sep) - let list = split( a:list, a:sep ) - let sorted = sort(list) - let result = join( sorted, "\n" ) - return result . "\n" -endfun - -endif - -if v:version < 700 -" s:SortVar(): sort components of string @var separated -" by delimiter @sep, and returns the sorted string. -" For example, s:SortVar("c\nb\na", "\n") returns "a\nb\nc\n" -function! s:SortVar(list, sep) - - let res=s:MakeWellFormedList(a:list . "\n") - while 1 - let disorder=0 - let index1=0 - - let len=strlen(res) - while 1 - let index2=matchend(res, a:sep, index1) - if index2 == -1 || index2>=len - break - endif - let index3=matchend(res, a:sep, index2) - if index3 == -1 - let index3=len - endif - let str1=strpart(res, index1, index2-index1) - let str2=strpart(res, index2, index3-index2) - if str1 > str2 - let disorder=1 - " swap str1 and str2 in res - let res=strpart(res,0,index1).str2.str1.strpart(res,index3) - let index1=index1 + strlen(str2) - else - let index1=index1 + strlen(str1) - endif - endw - - if !disorder - break - endif - endw - return res -endfu -endif " v:version < 700 - -let s:list = "" - -function! s:GetColorschemesList() - if s:list == "" - let s:list = s:RefreshColorschemesList() - endif - return s:list -endfunction - - -function! s:RefreshColorschemesList() - let x=globpath(&rtp, "colors/*.vim") - let y=substitute(x."\n","\\(^\\|\n\\)[^\n]*[/\\\\]", "\n", "g") - let z=substitute(y,"\\.vim\n", "\n", "g") - let sorted = s:SortVar(z, "\n") - let s:list = s:RemoveDuplicates(sorted) - return s:list -endfun - -function! s:GetFirstColors() - let list=s:GetColorschemesList() - let trim=substitute(list, "^\n\\+", "", "") - return substitute(trim, "\n.*", "", "") -endfu - -function! s:GetLastColors() - let list=s:GetColorschemesList() - let trim=substitute(list, "\n\\+$", "", "") - return substitute(trim, "^.*\n", "", "") -endfu - -function! s:FinalEcho(suffix) - let list = s:GetColorschemesList() - let total = s:CountEntries(list) - let index = s:FindIndex(list, s:CurrentColor()) - - redraw - echon "[" - echohl Search - echon s:CurrentColor() - echohl NONE - echon "] colorscheme #".index ." of " . total.". " - echon a:suffix -endfu - -function! s:GetNextColor(color) - let list=s:GetColorschemesList() - if ("\n".list) =~ ("\n".s:CurrentColor()."\n") - let next=substitute("\n".list."\n", ".*\n".a:color."\n", "", "") - let next = substitute(next, "\n.*", "", "") - return next=='' ? s:GetFirstColors() : next - else - return s:GetFirstColors() - endif -endfu - -function! s:GetPrevColor(color) - let list=s:GetColorschemesList() - if ("\n".list) =~ ("\n".a:color."\n") - let prev=substitute("\n".list."\n", "\n".a:color."\n.*", "", "") - let prev=substitute(prev, "^.*\n", "", "") - return prev=='' ? s:GetLastColors() : prev - else - return s:GetLastColors() - endif -endfu - -function! s:NextSilent() - let old = s:CurrentColor() - let next = s:GetNextColor(s:CurrentColor()) - call s:SetColor( next ) -endfu - -function! s:PrevSilent() - let old = s:CurrentColor() - let prev = s:GetPrevColor(s:CurrentColor()) - call s:SetColor( prev ) -endfu - -function! s:NextColorscheme() - let old = s:CurrentColor() - let next = s:GetNextColor(s:CurrentColor()) - call s:SetColor( next ) - redraw - call s:FinalEcho('previous: '.old) -endfun - -function! s:PrevColorscheme() - let old = s:CurrentColor() - let prev = s:GetPrevColor(s:CurrentColor()) - call s:SetColor( prev ) - redraw - call s:FinalEcho('previous: '.old) -endfun - -command! CN :call s:NextColorscheme() -command! CP :call s:PrevColorscheme() -map \n :CN<cr> -map \p :CP<cr> -map \c :echo g:colors_name<cr> - -" 2006-07-18 fixed bug with Align() -> s:Align() (affected L command) -" 2006-07-18 added colorlist cache (s:list) -" 2006-07-18 added R key to refresh colorlist -" 2006-07-19 for vim7, sort using builtin sort() (bubblesort is slow) diff --git a/vim/plugin/bufexplorer.vim b/vim/plugin/bufexplorer.vim deleted file mode 100755 index 8791363..0000000 --- a/vim/plugin/bufexplorer.vim +++ /dev/null @@ -1,1162 +0,0 @@ -"============================================================================== -" Copyright: Copyright (C) 2001-2010 Jeff Lanzarotta -" Permission is hereby granted to use and distribute this code, -" with or without modifications, provided that this copyright -" notice is copied with it. Like anything else that's free, -" bufexplorer.vim is provided *as is* and comes with no -" warranty of any kind, either expressed or implied. In no -" event will the copyright holder be liable for any damages -" resulting from the use of this software. -" Name Of File: bufexplorer.vim -" Description: Buffer Explorer Vim Plugin -" Maintainer: Jeff Lanzarotta (delux256-vim at yahoo dot com) -" Last Changed: Friday, 22 October 2010 -" Version: See g:bufexplorer_version for version number. -" Usage: This file should reside in the plugin directory and be -" automatically sourced. -" -" You may use the default keymappings of -" -" <Leader>be - Opens BE. -" <Leader>bs - Opens horizontally window BE. -" <Leader>bv - Opens vertically window BE. -" -" Or you can use -" -" ":BufExplorer" - Opens BE. -" ":BufExplorerHorizontalSplit" - Opens horizontally window BE. -" ":BufExplorerVerticalSplit" - Opens vertically window BE. -" -" For more help see supplied documentation. -" History: See supplied documentation. -"============================================================================== - -" Exit quickly if already running or when 'compatible' is set. {{{1 -if exists("g:bufexplorer_version") || &cp - finish -endif -"1}}} - -" Version number -let g:bufexplorer_version = "7.2.8" - -" Check for Vim version 700 or greater {{{1 -if v:version < 700 - echo "Sorry, bufexplorer ".g:bufexplorer_version."\nONLY runs with Vim 7.0 and greater." - finish -endif - -" Public Interface {{{1 -if maparg("<Leader>be") =~ 'BufExplorer' - nunmap <Leader>be -endif - -if maparg("<Leader>bs") =~ 'BufExplorerHorizontalSplit' - nunmap <Leader>bs -endif - -if maparg("<Leader>bv") =~ 'BufExplorerVerticalSplit' - nunmap <Leader>bv -endif - -nmap <script> <silent> <unique> <Leader>be :BufExplorer<CR> -nmap <script> <silent> <unique> <Leader>bs :BufExplorerHorizontalSplit<CR> -nmap <script> <silent> <unique> <Leader>bv :BufExplorerVerticalSplit<CR> - -" Create commands {{{1 -command! BufExplorer :call StartBufExplorer(has ("gui") ? "drop" : "hide edit") -command! BufExplorerHorizontalSplit :call BufExplorerHorizontalSplit() -command! BufExplorerVerticalSplit :call BufExplorerVerticalSplit() - -" BESet {{{1 -function! s:BESet(var, default) - if !exists(a:var) - if type(a:default) - exec "let" a:var "=" string(a:default) - else - exec "let" a:var "=" a:default - endif - - return 1 - endif - - return 0 -endfunction - -" BEReset {{{1 -function! s:BEReset() - " Build initial MRUList. This makes sure all the files specified on the - " command line are picked up correctly. - let s:MRUList = range(1, bufnr('$')) - - " Initialize one tab space array, ignore zero-based tabpagenr - " since all tabpagenr's start at 1. - " -1 signifies this is the first time we are referencing this - " tabpagenr. - let s:tabSpace = [ [-1], [-1] ] -endfunction - -" Setup the autocommands that handle the MRUList and other stuff. {{{1 -" This is only done once when Vim starts up. -augroup BufExplorerVimEnter - autocmd! - autocmd VimEnter * call s:BESetup() -augroup END - -" BESetup {{{1 -function! s:BESetup() - call s:BEReset() - - " Now that the MRUList is created, add the other autocmds. - augroup BufExplorer - " Deleting autocommands in case the script is reloaded - autocmd! - autocmd TabEnter * call s:BETabEnter() - autocmd BufNew * call s:BEAddBuffer() - autocmd BufEnter * call s:BEActivateBuffer() - - autocmd BufWipeOut * call s:BEDeactivateBuffer(1) - autocmd BufDelete * call s:BEDeactivateBuffer(0) - - autocmd BufWinEnter \[BufExplorer\] call s:BEInitialize() - autocmd BufWinLeave \[BufExplorer\] call s:BECleanup() - autocmd SessionLoadPost * call s:BEReset() - augroup END - - " Remove the VimEnter event as it is no longer needed - augroup SelectBufVimEnter - autocmd! - augroup END -endfunction - -" BETabEnter {{{1 -function! s:BETabEnter() - " Make s:tabSpace 1-based - if empty(s:tabSpace) || len(s:tabSpace) < (tabpagenr() + 1) - call add(s:tabSpace, [-1]) - endif -endfunction - -" BEAddBuffer {{{1 -function! s:BEAddBuffer() - if !exists('s:raw_buffer_listing') || empty(s:raw_buffer_listing) - silent let s:raw_buffer_listing = s:BEGetBufferInfo(0) - else - " We cannot use :buffers! or :ls! to gather information - " about this buffer since it was only just added. - " Any changes to the buffer (setlocal buftype, ...) - " happens after this event fires. - " - " So we will indicate the :buffers! command must be re-run. - " This should help with the performance of the plugin. - - " There are some checks which can be performed - " before deciding to refresh the buffer list. - let bufnr = expand('<abuf>') + 0 - - if s:BEIgnoreBuffer(bufnr) == 1 - return - else - let s:refreshBufferList = 1 - endif - endif - - call s:BEActivateBuffer() -endfunction - -" ActivateBuffer {{{1 -function! s:BEActivateBuffer() - let b = bufnr("%") - let l = get(s:tabSpace, tabpagenr(), []) - - if s:BEIgnoreBuffer(b) == 1 - return - endif - - if !empty(l) && l[0] == '-1' - " The first time we add a tab Vim uses the current - " buffer as it's starting page, even though we are about - " to edit a new page (BufEnter triggers after), so - " remove the -1 entry indicating we have covered this case. - let l = [] - let s:tabSpace[tabpagenr()] = l - elseif empty(l) || index(l, b) == -1 - " Add new buffer to this tab buffer list - let l = add(l, b) - let s:tabSpace[tabpagenr()] = l - - if g:bufExplorerOnlyOneTab == 1 - " If a buffer can only be available in 1 tab page - " ensure this buffer is not present in any other tabs - let tabidx = 1 - while tabidx < len(s:tabSpace) - if tabidx != tabpagenr() - let bufidx = index(s:tabSpace[tabidx], b) - if bufidx != -1 - call remove(s:tabSpace[tabidx], bufidx) - endif - endif - let tabidx = tabidx + 1 - endwhile - endif - endif - - call s:BEMRUPush(b) - - if exists('s:raw_buffer_listing') && !empty(s:raw_buffer_listing) - " Check if the buffer exists, but was deleted previously - " Careful use of ' and " so we do not have to escape all the \'s - " Regex: ^\s*bu\> - " ^ - Starting at the beginning of the string - " \s* - optional whitespace - " b - Vim's buffer number - " u\> - the buffer must be unlisted - let shortlist = filter(copy(s:raw_buffer_listing), "v:val.attributes =~ '".'^\s*'.b.'u\>'."'") - - if !empty(shortlist) - " If it is unlisted (ie deleted), but now we editing it again - " rebuild the buffer list. - let s:refreshBufferList = 1 - endif - endif -endfunction - -" BEDeactivateBuffer {{{1 -function! s:BEDeactivateBuffer(remove) - let _bufnr = str2nr(expand("<abuf>")) - - call s:BEMRUPop(_bufnr) - - if a:remove - call s:BEDeleteBufferListing(_bufnr) - else - let s:refreshBufferList = 1 - endif -endfunction - -" BEMRUPop {{{1 -function! s:BEMRUPop(buf) - call filter(s:MRUList, 'v:val != '.a:buf) -endfunction - -" BEMRUPush {{{1 -function! s:BEMRUPush(buf) - if s:BEIgnoreBuffer(a:buf) == 1 - return - endif - - " Remove the buffer number from the list if it already exists. - call s:BEMRUPop(a:buf) - - " Add the buffer number to the head of the list. - call insert(s:MRUList,a:buf) -endfunction - -" BEInitialize {{{1 -function! s:BEInitialize() - let s:_insertmode = &insertmode - set noinsertmode - - let s:_showcmd = &showcmd - set noshowcmd - - let s:_cpo = &cpo - set cpo&vim - - let s:_report = &report - let &report = 10000 - - let s:_list = &list - set nolist - - setlocal nonumber - setlocal foldcolumn=0 - setlocal nofoldenable - setlocal cursorline - setlocal nospell - setlocal nobuflisted - - let s:running = 1 -endfunction - -" BEIgnoreBuffer -function! s:BEIgnoreBuffer(buf) - " Check to see if this buffer should be ignore by BufExplorer. - - " Skip temporary buffers with buftype set. - if empty(getbufvar(a:buf, "&buftype") == 0) - return 1 - endif - - " Skip unlisted buffers. - if buflisted(a:buf) == 0 - return 1 - endif - - " Skip buffers with no name. - if empty(bufname(a:buf)) == 1 - return 1 - endif - - " Do not add the BufExplorer window to the list. - if fnamemodify(bufname(a:buf), ":t") == s:name - call s:BEError("The buffer name was [".s:name."] so it was skipped.") - return 1 - endif - - if index(s:MRU_Exclude_List, bufname(a:buf)) >= 0 - return 1 - end - - return 0 -endfunction - -" BECleanup {{{1 -function! s:BECleanup() - if exists("s:_insertmode")|let &insertmode = s:_insertmode|endif - if exists("s:_showcmd") |let &showcmd = s:_showcmd |endif - if exists("s:_cpo") |let &cpo = s:_cpo |endif - if exists("s:_report") |let &report = s:_report |endif - if exists("s:_list") |let &list = s:_list |endif - let s:running = 0 - let s:splitMode = "" - - delmarks! -endfunction - -" BufExplorerHorizontalSplit {{{1 -function! BufExplorerHorizontalSplit() - let s:splitMode = "sp" - exec "BufExplorer" -endfunction - -" BufExplorerVerticalSplit {{{1 -function! BufExplorerVerticalSplit() - let s:splitMode = "vsp" - exec "BufExplorer" -endfunction - -" StartBufExplorer {{{1 -function! StartBufExplorer(open) - let name = s:name - - if !has("win32") - " On non-Windows boxes, escape the name so that is shows up correctly. - let name = escape(name, "[]") - call s:BEError("Escaped") - endif - - " Make sure there is only one explorer open at a time. - if s:running == 1 - call s:BEError("WHAT THE 1") - " Go to the open buffer. - if has("gui") - call s:BEError("WHAT THE 2") - call s:BEError(name) - exec "drop" name - endif - - return - endif - - " Add zero to ensure the variable is treated as a Number. - let s:originBuffer = bufnr("%") + 0 - - " Create or rebuild the raw buffer list if necessary. - if !exists('s:raw_buffer_listing') || - \ empty(s:raw_buffer_listing) || - \ s:refreshBufferList == 1 - silent let s:raw_buffer_listing = s:BEGetBufferInfo(0) - endif - - let copy = copy(s:raw_buffer_listing) - - if (g:bufExplorerShowUnlisted == 0) - call filter(copy, 'v:val.attributes !~ "u"') - endif - - " We may have to split the current window. - if (s:splitMode != "") - " Save off the original settings. - let [_splitbelow, _splitright] = [&splitbelow, &splitright] - - " Set the setting to ours. - let [&splitbelow, &splitright] = [g:bufExplorerSplitBelow, g:bufExplorerSplitRight] - - " Do it. - exe 'keepalt '.s:splitMode - - " Restore the original settings. - let [&splitbelow, &splitright] = [_splitbelow, _splitright] - endif - - if !exists("b:displayMode") || b:displayMode != "winmanager" - " Do not use keepalt when opening bufexplorer to allow the buffer that we are - " leaving to become the new alternate buffer - exec "silent keepjumps ".a:open." ".name - endif - - call s:BEDisplayBufferList() -endfunction - -" BEDisplayBufferList {{{1 -function! s:BEDisplayBufferList() - " Do not set bufhidden since it wipes out - " the data if we switch away from the buffer - " using CTRL-^ - setlocal buftype=nofile - setlocal modifiable - setlocal noswapfile - setlocal nowrap - - " Delete all previous lines to the black hole register - call cursor(1,1) - exec 'silent! normal! "_dG' - - call s:BESetupSyntax() - call s:BEMapKeys() - call setline(1, s:BECreateHelp()) - call s:BEBuildBufferList() - call cursor(s:firstBufferLine, 1) - - if !g:bufExplorerResize - normal! zz - endif - - setlocal nomodifiable -endfunction - -" BEMapKeys {{{1 -function! s:BEMapKeys() - if exists("b:displayMode") && b:displayMode == "winmanager" - nnoremap <buffer> <silent> <tab> :call <SID>BESelectBuffer("tab")<cr> - endif - - nnoremap <buffer> <silent> <F1> :call <SID>BEToggleHelp()<cr> - nnoremap <buffer> <silent> <2-leftmouse> :call <SID>BESelectBuffer()<cr> - nnoremap <buffer> <silent> <cr> :call <SID>BESelectBuffer()<cr> - nnoremap <buffer> <silent> o :call <SID>BESelectBuffer()<cr> - nnoremap <buffer> <silent> t :call <SID>BESelectBuffer("tab")<cr> - nnoremap <buffer> <silent> <s-cr> :call <SID>BESelectBuffer("tab")<cr> - - nnoremap <buffer> <silent> d :call <SID>BERemoveBuffer("delete", "n")<cr> - xnoremap <buffer> <silent> d :call <SID>BERemoveBuffer("delete", "v")<cr> - nnoremap <buffer> <silent> D :call <SID>BERemoveBuffer("wipe", "n")<cr> - xnoremap <buffer> <silent> D :call <SID>BERemoveBuffer("wipe", "v")<cr> - - nnoremap <buffer> <silent> m :call <SID>BEMRUListShow()<cr> - nnoremap <buffer> <silent> p :call <SID>BEToggleSplitOutPathName()<cr> - nnoremap <buffer> <silent> q :call <SID>BEClose("quit")<cr> - nnoremap <buffer> <silent> r :call <SID>BESortReverse()<cr> - nnoremap <buffer> <silent> R :call <SID>BEToggleShowRelativePath()<cr> - nnoremap <buffer> <silent> s :call <SID>BESortSelect()<cr> - nnoremap <buffer> <silent> S :call <SID>BEReverseSortSelect()<cr> - nnoremap <buffer> <silent> u :call <SID>BEToggleShowUnlisted()<cr> - nnoremap <buffer> <silent> f :call <SID>BEToggleFindActive()<cr> - nnoremap <buffer> <silent> T :call <SID>BEToggleShowTabBuffer()<cr> - nnoremap <buffer> <silent> B :call <SID>BEToggleOnlyOneTab()<cr> - - for k in ["G", "n", "N", "L", "M", "H"] - exec "nnoremap <buffer> <silent>" k ":keepjumps normal!" k."<cr>" - endfor -endfunction - -" BESetupSyntax {{{1 -function! s:BESetupSyntax() - if has("syntax") - syn match bufExplorerHelp "^\".*" contains=bufExplorerSortBy,bufExplorerMapping,bufExplorerTitle,bufExplorerSortType,bufExplorerToggleSplit,bufExplorerToggleOpen - syn match bufExplorerOpenIn "Open in \w\+ window" contained - syn match bufExplorerSplit "\w\+ split" contained - syn match bufExplorerSortBy "Sorted by .*" contained contains=bufExplorerOpenIn,bufExplorerSplit - syn match bufExplorerMapping "\" \zs.\+\ze :" contained - syn match bufExplorerTitle "Buffer Explorer.*" contained - syn match bufExplorerSortType "'\w\{-}'" contained - syn match bufExplorerBufNbr /^\s*\d\+/ - syn match bufExplorerToggleSplit "toggle split type" contained - syn match bufExplorerToggleOpen "toggle open mode" contained - syn match bufExplorerModBuf /^\s*\d\+.\{4}+.*/ - syn match bufExplorerLockedBuf /^\s*\d\+.\{3}[\-=].*/ - syn match bufExplorerHidBuf /^\s*\d\+.\{2}h.*/ - syn match bufExplorerActBuf /^\s*\d\+.\{2}a.*/ - syn match bufExplorerCurBuf /^\s*\d\+.%.*/ - syn match bufExplorerAltBuf /^\s*\d\+.#.*/ - syn match bufExplorerUnlBuf /^\s*\d\+u.*/ - - hi def link bufExplorerBufNbr Number - hi def link bufExplorerMapping NonText - hi def link bufExplorerHelp Special - hi def link bufExplorerOpenIn Identifier - hi def link bufExplorerSortBy String - hi def link bufExplorerSplit NonText - hi def link bufExplorerTitle NonText - hi def link bufExplorerSortType bufExplorerSortBy - hi def link bufExplorerToggleSplit bufExplorerSplit - hi def link bufExplorerToggleOpen bufExplorerOpenIn - - hi def link bufExplorerActBuf Identifier - hi def link bufExplorerAltBuf String - hi def link bufExplorerCurBuf Type - hi def link bufExplorerHidBuf Constant - hi def link bufExplorerLockedBuf Special - hi def link bufExplorerModBuf Exception - hi def link bufExplorerUnlBuf Comment - endif -endfunction - -" BEToggleHelp {{{1 -function! s:BEToggleHelp() - let g:bufExplorerDetailedHelp = !g:bufExplorerDetailedHelp - - setlocal modifiable - - " Save position. - normal! ma - - " Remove old header. - if (s:firstBufferLine > 1) - exec "keepjumps 1,".(s:firstBufferLine - 1) "d _" - endif - - call append(0, s:BECreateHelp()) - - silent! normal! g`a - delmarks a - - setlocal nomodifiable - - if exists("b:displayMode") && b:displayMode == "winmanager" - call WinManagerForceReSize("BufExplorer") - endif -endfunction - -" BEGetHelpStatus {{{1 -function! s:BEGetHelpStatus() - let ret = '" Sorted by '.((g:bufExplorerReverseSort == 1) ? "reverse " : "").g:bufExplorerSortBy - let ret .= ' | '.((g:bufExplorerFindActive == 0) ? "Don't " : "")."Locate buffer" - let ret .= ((g:bufExplorerShowUnlisted == 0) ? "" : " | Show unlisted") - let ret .= ((g:bufExplorerShowTabBuffer == 0) ? "" : " | Show buffers/tab") - let ret .= ((g:bufExplorerOnlyOneTab == 1) ? "" : " | One tab / buffer") - let ret .= ' | '.((g:bufExplorerShowRelativePath == 0) ? "Absolute" : "Relative") - let ret .= ' '.((g:bufExplorerSplitOutPathName == 0) ? "Full" : "Split")." path" - - return ret -endfunction - -" BECreateHelp {{{1 -function! s:BECreateHelp() - if g:bufExplorerDefaultHelp == 0 && g:bufExplorerDetailedHelp == 0 - let s:firstBufferLine = 1 - return [] - endif - - let header = [] - - if g:bufExplorerDetailedHelp == 1 - call add(header, '" Buffer Explorer ('.g:bufexplorer_version.')') - call add(header, '" --------------------------') - call add(header, '" <F1> : toggle this help') - call add(header, '" <enter> or o or Mouse-Double-Click : open buffer under cursor') - call add(header, '" <shift-enter> or t : open buffer in another tab') - call add(header, '" d : delete buffer') - call add(header, '" D : wipe buffer') - call add(header, '" f : toggle find active buffer') - call add(header, '" p : toggle spliting of file and path name') - call add(header, '" q : quit') - call add(header, '" r : reverse sort') - call add(header, '" R : toggle showing relative or full paths') - call add(header, '" s : cycle thru "sort by" fields '.string(s:sort_by).'') - call add(header, '" S : reverse cycle thru "sort by" fields') - call add(header, '" T : toggle if to show only buffers for this tab or not') - call add(header, '" u : toggle showing unlisted buffers') - else - call add(header, '" Press <F1> for Help') - endif - - if (!exists("b:displayMode") || b:displayMode != "winmanager") || (b:displayMode == "winmanager" && g:bufExplorerDetailedHelp == 1) - call add(header, s:BEGetHelpStatus()) - call add(header, '"=') - endif - - let s:firstBufferLine = len(header) + 1 - - return header -endfunction - -" BEGetBufferInfo {{{1 -function! s:BEGetBufferInfo(bufnr) - redir => bufoutput - buffers! - redir END - - if (a:bufnr > 0) - " Since we are only interested in this specified buffer - " remove the other buffers listed - let bufoutput = substitute(bufoutput."\n", '^.*\n\(\s*'.a:bufnr.'\>.\{-}\)\n.*', '\1', '') - endif - - let [all, allwidths, listedwidths] = [[], {}, {}] - - for n in keys(s:types) - let allwidths[n] = [] - let listedwidths[n] = [] - endfor - - for buf in split(bufoutput, '\n') - let bits = split(buf, '"') - let b = {"attributes": bits[0], "line": substitute(bits[2], '\s*', '', '')} - - for [key, val] in items(s:types) - let b[key] = fnamemodify(bits[1], val) - endfor - - if getftype(b.fullname) == "dir" && g:bufExplorerShowDirectories == 1 - let b.shortname = "<DIRECTORY>" - endif - - call add(all, b) - - for n in keys(s:types) - call add(allwidths[n], len(b[n])) - - if b.attributes !~ "u" - call add(listedwidths[n], len(b[n])) - endif - endfor - endfor - - let [s:allpads, s:listedpads] = [{}, {}] - - for n in keys(s:types) - let s:allpads[n] = repeat(' ', max(allwidths[n])) - let s:listedpads[n] = repeat(' ', max(listedwidths[n])) - endfor - - let s:refreshBufferList = 1 - - return all -endfunction - -" BEBuildBufferList {{{1 -function! s:BEBuildBufferList() - let lines = [] - - " Loop through every buffer. - for buf in s:raw_buffer_listing - " Skip unlisted buffers if we are not to show them. - if (!g:bufExplorerShowUnlisted && buf.attributes =~ "u") - continue - endif - - if (g:bufExplorerShowTabBuffer) - let show_buffer = 0 - - for bufnr in s:tabSpace[tabpagenr()] - if (buf.attributes =~ '^\s*'.bufnr.'\>') - " Only buffers shown on the current tabpagenr - let show_buffer = 1 - break - endif - endfor - - if show_buffer == 0 - continue - endif - endif - - let line = buf.attributes." " - - if g:bufExplorerSplitOutPathName - let type = (g:bufExplorerShowRelativePath) ? "relativepath" : "path" - let path = buf[type] - let pad = (g:bufExplorerShowUnlisted) ? s:allpads.shortname : s:listedpads.shortname - let line .= buf.shortname." ".strpart(pad.path, len(buf.shortname)) - else - let type = (g:bufExplorerShowRelativePath) ? "relativename" : "fullname" - let path = buf[type] - let line .= path - endif - - let pads = (g:bufExplorerShowUnlisted) ? s:allpads : s:listedpads - - if !empty(pads[type]) - let line .= strpart(pads[type], len(path))." " - endif - - let line .= buf.line - - call add(lines, line) - endfor - - call setline(s:firstBufferLine, lines) - - call s:BESortListing() -endfunction - -" BESelectBuffer {{{1 -function! s:BESelectBuffer(...) - " Sometimes messages are not cleared when we get here so it looks like an error has - " occurred when it really has not. - echo "" - - " Are we on a line with a file name? - if line('.') < s:firstBufferLine - exec "normal! \<cr>" - return - endif - - let _bufNbr = str2nr(getline('.')) - - " Check and see if we are running BE via WinManager. - if exists("b:displayMode") && b:displayMode == "winmanager" - let bufname = expand("#"._bufNbr.":p") - - if (a:0 == 1) && (a:1 == "tab") - call WinManagerFileEdit(bufname, 1) - else - call WinManagerFileEdit(bufname, 0) - endif - - return - endif - - if bufexists(_bufNbr) - if bufnr("#") == _bufNbr && !exists("g:bufExplorerChgWin") - return s:BEClose("") - endif - - " Are we suppose to open the selected buffer in a tab? - if (a:0 == 1) && (a:1 == "tab") - " Yes, we are to open the selected buffer in a tab. - - " Restore [BufExplorer] buffer. - exec "keepjumps silent buffer!".s:originBuffer - - " Get the tab number where this buffer is located at. - let tabNbr = s:BEGetTabNbr(_bufNbr) - - " Was the tab found? - if tabNbr == 0 - " _bufNbr is not opened in any tabs. Open a new tab with the selected buffer in it. - exec "999tab split +buffer" . _bufNbr - else - " The _bufNbr is already opened in tab, go to that tab. - exec tabNbr . "tabnext" - - " Focus window. - exec s:BEGetWinNbr(tabNbr, _bufNbr) . "wincmd w" - endif - else - "No, the use did not ask to open the selected buffer in a tab. - - " Are we suppose to move to the tab where this active buffer is? - if exists("g:bufExplorerChgWin") - exe g:bufExplorerChgWin."wincmd w" - elseif bufloaded(_bufNbr) && g:bufExplorerFindActive - " Close the BE window. - call s:BEClose("") - - " Get the tab number where this buffer is located at. - let tabNbr = s:BEGetTabNbr(_bufNbr) - - " Was the tab found? - if tabNbr != 0 - " The buffer is located in a tab. Go to that tab number. - exec tabNbr . "tabnext" - else - " Nope, the buffer is not in a tab, simple switch to that buffer. - let bufname = expand("#"._bufNbr.":p") - exec bufname ? "drop ".escape(bufname, " ") : "buffer "._bufNbr - endif - endif - - " Switch to the buffer. - exec "keepalt keepjumps silent b!" _bufNbr - endif - - " Make the buffer 'listed' again. - call setbufvar(_bufNbr, "&buflisted", "1") - - " call any associated function references - " g:bufExplorerFuncRef may be an individual function reference - " or it may be a list containing function references. - " It will ignore anything that's not a function reference. - " See :help FuncRef for more on function references. - if exists("g:BufExplorerFuncRef") - if type(g:BufExplorerFuncRef) == 2 - keepj call g:BufExplorerFuncRef() - elseif type(g:BufExplorerFuncRef) == 3 - for FncRef in g:BufExplorerFuncRef - if type(FncRef) == 2 - keepj call FncRef() - endif - endfor - endif - endif - else - call s:BEError("Sorry, that buffer no longer exists, please select another") - call s:BEDeleteBuffer(_bufNbr, "wipe") - endif -endfunction - -" BEDeleteBufferListing {{{1 -function! s:BEDeleteBufferListing(buf) - if exists('s:raw_buffer_listing') && !empty(s:raw_buffer_listing) - " Delete the buffer from the raw buffer list. - " Careful use of ' and " so we do not have to escape all the \'s - " Regex: ^\s*\(10\|20\)\> - " ^ - Starting at the beginning of the string - " \s* - optional whitespace - " \(10\|20\) - either a 10 or a 20 - " \> - end of word (so it can't make 100 or 201) - call filter(s:raw_buffer_listing, "v:val.attributes !~ '".'^\s*\('.substitute(a:buf, ' ', '\\|', 'g').'\)\>'."'") - endif -endfunction - -" BERemoveBuffer {{{1 -function! s:BERemoveBuffer(type, mode) range - " Are we on a line with a file name? - if line('.') < s:firstBufferLine - return - endif - - " These commands are to temporarily suspend the activity of winmanager. - if exists("b:displayMode") && b:displayMode == "winmanager" - call WinManagerSuspendAUs() - endif - - let _bufNbrs = '' - - for lineNum in range(a:firstline, a:lastline) - let line = getline(lineNum) - - if line =~ '^\s*\(\d\+\)' - " Regex: ^\s*\(10\|20\)\> - " ^ - Starting at the beginning of the string - " \s* - optional whitespace - " \zs - start the match here - " \d\+ - any digits - " \> - end of word (so it can't make 100 or 201) - let bufNbr = matchstr(line, '^\s*\zs\d\+\>') - - " Add 0 to bufNbr to ensure Vim treats it as a Number - " for use with the getbufvar() function - if bufNbr !~ '^\d\+$' || getbufvar(bufNbr+0, '&modified') != 0 - call s:BEError("Sorry, no write since last change for buffer ".bufNbr.", unable to delete") - else - let _bufNbrs = _bufNbrs . (_bufNbrs==''?'':' '). bufNbr - endif - endif - endfor - - " Okay, everything is good, delete or wipe the buffers. - call s:BEDeleteBuffer(_bufNbrs, a:type) - - " Reactivate winmanager autocommand activity. - if exists("b:displayMode") && b:displayMode == "winmanager" - call WinManagerForceReSize("BufExplorer") - call WinManagerResumeAUs() - endif -endfunction - -" BEDeleteBuffer {{{1 -function! s:BEDeleteBuffer(bufNbr, mode) - " This routine assumes that the buffer to be removed is on the current line. - try - if a:mode == "wipe" - exe "bwipe" a:bufNbr - else - exe "bdelete" a:bufNbr - endif - - setlocal modifiable - - " Remove each of the lines beginning with the buffer numbers we are removing - " Regex: ^\s*\(10\|20\)\> - " ^ - Starting at the beginning of the string - " \s* - optional whitespace - " \(10\|20\) - either a 10 or a 20 - " \> - end of word (so it can't make 100 or 201) - exec 'silent! g/^\s*\('.substitute(a:bufNbr, ' ', '\\|', 'g').'\)\>/d_' - - setlocal nomodifiable - - call s:BEDeleteBufferListing(a:bufNbr) - catch - call s:BEError(v:exception) - endtry -endfunction - -" BEClose {{{1 -function! s:BEClose(mode) - " Get only the listed buffers. - let listed = filter(copy(s:MRUList), "buflisted(v:val)") - - " If we needed to split the main window, close the split one. -" if (s:splitMode) -" if (s:splitMode != "") - if (s:splitMode != "" && a:mode == "quit") - exec "wincmd c" - endif - - if len(listed) == 0 - exe "enew" - else - for b in reverse(listed[0:1]) - exec "keepjumps silent b ".b - endfor - endif -endfunction - -" BEToggleSplitOutPathName {{{1 -function! s:BEToggleSplitOutPathName() - let g:bufExplorerSplitOutPathName = !g:bufExplorerSplitOutPathName - call s:BERebuildBufferList() - call s:BEUpdateHelpStatus() -endfunction - -" BEToggleShowRelativePath {{{1 -function! s:BEToggleShowRelativePath() - let g:bufExplorerShowRelativePath = !g:bufExplorerShowRelativePath - call s:BERebuildBufferList() - call s:BEUpdateHelpStatus() -endfunction - -" BEToggleShowUnlisted {{{1 -function! s:BEToggleShowUnlisted() - let g:bufExplorerShowUnlisted = !g:bufExplorerShowUnlisted - let num_bufs = s:BERebuildBufferList(g:bufExplorerShowUnlisted == 0) - call s:BEUpdateHelpStatus() -endfunction - -" BEToggleFindActive {{{1 -function! s:BEToggleFindActive() - let g:bufExplorerFindActive = !g:bufExplorerFindActive - call s:BEUpdateHelpStatus() -endfunction - -" BEToggleShowTabBuffer {{{1 -function! s:BEToggleShowTabBuffer() - let g:bufExplorerShowTabBuffer = !g:bufExplorerShowTabBuffer - call s:BEDisplayBufferList() -endfunction - -" BEToggleOnlyOneTab {{{1 -function! s:BEToggleOnlyOneTab() - let g:bufExplorerOnlyOneTab = !g:bufExplorerOnlyOneTab - call s:BEDisplayBufferList() -endfunction - -" BERebuildBufferList {{{1 -function! s:BERebuildBufferList(...) - setlocal modifiable - - let curPos = getpos('.') - - if a:0 - " Clear the list first. - exec "keepjumps ".s:firstBufferLine.',$d "_' - endif - - let num_bufs = s:BEBuildBufferList() - - call setpos('.', curPos) - - setlocal nomodifiable - - return num_bufs -endfunction - -" BEUpdateHelpStatus {{{1 -function! s:BEUpdateHelpStatus() - setlocal modifiable - - let text = s:BEGetHelpStatus() - call setline(s:firstBufferLine - 2, text) - - setlocal nomodifiable -endfunction - -" BEMRUCmp {{{1 -function! s:BEMRUCmp(line1, line2) - return index(s:MRUList, str2nr(a:line1)) - index(s:MRUList, str2nr(a:line2)) -endfunction - -" BESortReverse {{{1 -function! s:BESortReverse() - let g:bufExplorerReverseSort = !g:bufExplorerReverseSort - call s:BEReSortListing() -endfunction - -" BESortSelect {{{1 -function! s:BESortSelect() - let g:bufExplorerSortBy = get(s:sort_by, index(s:sort_by, g:bufExplorerSortBy) + 1, s:sort_by[0]) - call s:BEReSortListing() -endfunction - -" BEReverseSortSelect {{{1 -function! s:BEReverseSortSelect() - let g:bufExplorerSortBy = get(s:sort_by, (index(s:sort_by, g:bufExplorerSortBy) + len(s:sort_by) - 1) % len(s:sort_by), s:sort_by[0]) - call s:BEReSortListing() -endfunction - -" BEReSortListing {{{1 -function! s:BEReSortListing() - setlocal modifiable - - let curPos = getpos('.') - - call s:BESortListing() - call s:BEUpdateHelpStatus() - - call setpos('.', curPos) - - setlocal nomodifiable -endfunction - -" BESortListing {{{1 -function! s:BESortListing() - let sort = s:firstBufferLine.",$sort".((g:bufExplorerReverseSort == 1) ? "!": "") - - if g:bufExplorerSortBy == "number" - " Easiest case. - exec sort 'n' - elseif g:bufExplorerSortBy == "name" - if g:bufExplorerSplitOutPathName - exec sort 'ir /\d.\{7}\zs\f\+\ze/' - else - exec sort 'ir /\zs[^\/\\]\+\ze\s*line/' - endif - elseif g:bufExplorerSortBy == "fullpath" - if g:bufExplorerSplitOutPathName - " Sort twice - first on the file name then on the path. - exec sort 'ir /\d.\{7}\zs\f\+\ze/' - endif - - exec sort 'ir /\zs\f\+\ze\s\+line/' - elseif g:bufExplorerSortBy == "extension" - exec sort 'ir /\.\zs\w\+\ze\s/' - elseif g:bufExplorerSortBy == "mru" - let l = getline(s:firstBufferLine, "$") - - call sort(l, "<SID>BEMRUCmp") - - if g:bufExplorerReverseSort - call reverse(l) - endif - - call setline(s:firstBufferLine, l) - endif -endfunction - -" BEMRUListShow {{{1 -function! s:BEMRUListShow() - echomsg "MRUList=".string(s:MRUList) -endfunction - -" BEError {{{1 -function! s:BEError(msg) - echohl ErrorMsg | echo a:msg | echohl none -endfunction - -" BEWarning {{{1 -function! s:BEWarning(msg) - echohl WarningMsg | echo a:msg | echohl none -endfunction - -" GetTabNbr {{{1 -function! s:BEGetTabNbr(bufNbr) - " Searching buffer bufno, in tabs. - for i in range(tabpagenr("$")) - if index(tabpagebuflist(i + 1), a:bufNbr) != -1 - return i + 1 - endif - endfor - - return 0 -endfunction - -" GetWinNbr" {{{1 -function! s:BEGetWinNbr(tabNbr, bufNbr) - " window number in tabpage. - return index(tabpagebuflist(a:tabNbr), a:bufNbr) + 1 -endfunction - -" Winmanager Integration {{{1 -let g:BufExplorer_title = "\[Buf\ List\]" -call s:BESet("g:bufExplorerResize", 1) -call s:BESet("g:bufExplorerMaxHeight", 25) " Handles dynamic resizing of the window. - -" Function to start display. Set the mode to 'winmanager' for this buffer. -" This is to figure out how this plugin was called. In a standalone fashion -" or by winmanager. -function! BufExplorer_Start() - let b:displayMode = "winmanager" - call StartBufExplorer("e") -endfunction - -" Returns whether the display is okay or not. -function! BufExplorer_IsValid() - return 0 -endfunction - -" Handles dynamic refreshing of the window. -function! BufExplorer_Refresh() - let b:displayMode = "winmanager" - call StartBufExplorer("e") -endfunction - -function! BufExplorer_ReSize() - if !g:bufExplorerResize - return - endif - - let nlines = min([line("$"), g:bufExplorerMaxHeight]) - - exe nlines." wincmd _" - - " The following lines restore the layout so that the last file line is also - " the last window line. Sometimes, when a line is deleted, although the - " window size is exactly equal to the number of lines in the file, some of - " the lines are pushed up and we see some lagging '~'s. - let pres = getpos(".") - - exe $ - - let _scr = &scrolloff - let &scrolloff = 0 - - normal! z- - - let &scrolloff = _scr - - call setpos(".", pres) -endfunction - -" Default values {{{1 -call s:BESet("g:bufExplorerDefaultHelp", 1) " Show default help? -call s:BESet("g:bufExplorerDetailedHelp", 0) " Show detailed help? -call s:BESet("g:bufExplorerFindActive", 1) " When selecting an active buffer, take you to the window where it is active? -call s:BESet("g:bufExplorerReverseSort", 0) " sort reverse? -call s:BESet("g:bufExplorerShowDirectories", 1) " (Dir's are added by commands like ':e .') -call s:BESet("g:bufExplorerShowRelativePath", 0) " Show listings with relative or absolute paths? -call s:BESet("g:bufExplorerShowUnlisted", 0) " Show unlisted buffers? -call s:BESet("g:bufExplorerSortBy", "mru") " Sorting methods are in s:sort_by: -call s:BESet("g:bufExplorerSplitOutPathName", 1) " Split out path and file name? -call s:BESet("g:bufExplorerSplitRight", &splitright) " Should vertical splits be on the right or left of current window? -call s:BESet("g:bufExplorerSplitBelow", &splitbelow) " Should horizontal splits be below or above current window? -call s:BESet("g:bufExplorerShowTabBuffer", 0) " Show only buffer(s) for this tab? -call s:BESet("g:bufExplorerOnlyOneTab", 1) " If ShowTabBuffer = 1, only store the most recent tab for this buffer. - -" Global variables {{{1 -call s:BEReset() -let s:running = 0 -let s:sort_by = ["number", "name", "fullpath", "mru", "extension"] -let s:types = {"fullname": ':p', "path": ':p:h', "relativename": ':~:.', "relativepath": ':~:.:h', "shortname": ':t'} -let s:originBuffer = 0 -let s:splitMode = "" -let s:name = '[BufExplorer]' -let s:refreshBufferList = 1 -let s:MRU_Exclude_List = ["[BufExplorer]","__MRU_Files__"] -"1}}} - -" vim:ft=vim foldmethod=marker sw=2 diff --git a/vim/plugin/rspec.vim b/vim/plugin/rspec.vim deleted file mode 100644 index d244476..0000000 --- a/vim/plugin/rspec.vim +++ /dev/null @@ -1,36 +0,0 @@ -fun! GetRubyBin() - for [key, val] in items(g:ruby_bin_list) - if match(expand("%:p"), key) == 0 - return val - endif - endfor - return "ruby" -endfun - -fun! GetSpecBin() - for [key, val] in items(g:spec_bin_list) - if match(expand("%:p"), key) == 0 - return val - endif - endfor - return "spec" -endfun - -fun! GetLibDirs() - let l:lib_dirs = [] - for [key, val] in items(g:lib_dirs_list) - if match(expand("%:p"), key) == 0 - call extend(l:lib_dirs, val) - endif - endfor - return "-I\"".join(l:lib_dirs, "\" -I\"")."\"" -endfun - -fun! RunSpec() - let l:current_file = expand("%:p") - let l:ruby_bin = GetRubyBin() - let l:spec_bin = GetSpecBin() - let l:lib_dirs = GetLibDirs() - let l:cmd = l:ruby_bin." ".l:lib_dirs." ".l:spec_bin." ".l:current_file - exec "!".l:cmd -endfun |