diff --git a/.vim/bundle/nerdcommenter/plugin/NERD_commenter.vim b/.vim/bundle/nerdcommenter/plugin/NERD_commenter.vim index c61524b..982b140 100644 --- a/.vim/bundle/nerdcommenter/plugin/NERD_commenter.vim +++ b/.vim/bundle/nerdcommenter/plugin/NERD_commenter.vim @@ -3,7 +3,7 @@ " Description: vim global plugin that provides easy code commenting " Maintainer: Martin Grenfell " Version: 2.2.2 -" Last Change: 30th March, 2008 +" Last Change: 09th October, 2010 " 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 @@ -702,7 +702,7 @@ function s:CommentLinesMinimal(firstLine, lastLine) "if we need to use place holders for the comment, make sure they are "enabled for this filetype if !g:NERDUsePlaceHolders && s:DoesBlockHaveMultipartDelim(a:firstLine, a:lastLine) - throw 'NERDCommenter.Settings exception: Placeoholders are required but disabled.' + throw 'NERDCommenter.Settings exception: Place holders are required but disabled.' endif "get the left and right delims to smack on @@ -976,7 +976,7 @@ function s:InvertComment(firstLine, lastLine) "move to the line after last line of the sexy comment let numLinesAfterSexyComRemoved = s:NumLinesInBuf() - let currentLine = bottomBound - (numLinesBeforeSexyComRemoved - numLinesAfterSexyComRemoved) + 1 + let currentLine = sexyComBounds[1] - (numLinesBeforeSexyComRemoved - numLinesAfterSexyComRemoved) + 1 " the line isnt commented else diff --git a/.vim/bundle/nerdtree/.gitignore b/.vim/bundle/nerdtree/.gitignore new file mode 100644 index 0000000..3698c0e --- /dev/null +++ b/.vim/bundle/nerdtree/.gitignore @@ -0,0 +1,3 @@ +*~ +*.swp +tags diff --git a/.vim/bundle/nerdtree/Rakefile b/.vim/bundle/nerdtree/Rakefile new file mode 100644 index 0000000..f6c72b8 --- /dev/null +++ b/.vim/bundle/nerdtree/Rakefile @@ -0,0 +1,75 @@ +# written by travis jeffery +# contributions by scrooloose + +require 'rake' +require 'find' +require 'pathname' + +IGNORE = [/\.gitignore$/, /Rakefile$/] + +files = `git ls-files`.split("\n") +files.reject! { |f| IGNORE.any? { |re| f.match(re) } } + +desc 'Zip up the project files' +task :zip do + zip_name = File.basename(File.dirname(__FILE__)) + zip_name.gsub!(/ /, '_') + zip_name = "#{zip_name}.zip" + + if File.exist?(zip_name) + abort("Zip file #{zip_name} already exists. Remove it first.") + end + + puts "Creating zip file: #{zip_name}" + system("zip #{zip_name} #{files.join(" ")}") +end + +desc 'Install plugin and documentation' +task :install do + vimfiles = if ENV['VIMFILES'] + ENV['VIMFILES'] + elsif RUBY_PLATFORM =~ /(win|w)32$/ + File.expand_path("~/vimfiles") + else + File.expand_path("~/.vim") + end + files.each do |file| + target_file = File.join(vimfiles, file) + FileUtils.mkdir_p File.dirname(target_file) + FileUtils.cp file, target_file + + puts "Installed #{file} to #{target_file}" + end + +end + +desc 'Pulls from origin' +task :pull do + puts "Updating local repo..." + system("cd " << Dir.new(File.dirname(__FILE__)).path << " && git pull") +end + +desc 'Calls pull task and then install task' +task :update => ['pull', 'install'] do + puts "Update of vim script complete." +end + +desc 'Uninstall plugin and documentation' +task :uninstall do + vimfiles = if ENV['VIMFILES'] + ENV['VIMFILES'] + elsif RUBY_PLATFORM =~ /(win|w)32$/ + File.expand_path("~/vimfiles") + else + File.expand_path("~/.vim") + end + files.each do |file| + target_file = File.join(vimfiles, file) + FileUtils.rm target_file + + puts "Uninstalled #{target_file}" + end + +end + +task :default => ['update'] diff --git a/.vim/bundle/nerdtree/doc/NERD_tree.txt b/.vim/bundle/nerdtree/doc/NERD_tree.txt new file mode 100644 index 0000000..2e2278c --- /dev/null +++ b/.vim/bundle/nerdtree/doc/NERD_tree.txt @@ -0,0 +1,1222 @@ +*NERD_tree.txt* A tree explorer plugin that owns your momma! + + + + omg its ... ~ + + ________ ________ _ ____________ ____ __________ ____________~ + /_ __/ / / / ____/ / | / / ____/ __ \/ __ \ /_ __/ __ \/ ____/ ____/~ + / / / /_/ / __/ / |/ / __/ / /_/ / / / / / / / /_/ / __/ / __/ ~ + / / / __ / /___ / /| / /___/ _, _/ /_/ / / / / _, _/ /___/ /___ ~ + /_/ /_/ /_/_____/ /_/ |_/_____/_/ |_/_____/ /_/ /_/ |_/_____/_____/ ~ + + + Reference Manual~ + + + + +============================================================================== +CONTENTS *NERDTree-contents* + + 1.Intro...................................|NERDTree| + 2.Functionality provided..................|NERDTreeFunctionality| + 2.1.Global commands...................|NERDTreeGlobalCommands| + 2.2.Bookmarks.........................|NERDTreeBookmarks| + 2.2.1.The bookmark table..........|NERDTreeBookmarkTable| + 2.2.2.Bookmark commands...........|NERDTreeBookmarkCommands| + 2.2.3.Invalid bookmarks...........|NERDTreeInvalidBookmarks| + 2.3.NERD tree mappings................|NERDTreeMappings| + 2.4.The NERD tree menu................|NERDTreeMenu| + 3.Options.................................|NERDTreeOptions| + 3.1.Option summary....................|NERDTreeOptionSummary| + 3.2.Option details....................|NERDTreeOptionDetails| + 4.The NERD tree API.......................|NERDTreeAPI| + 4.1.Key map API.......................|NERDTreeKeymapAPI| + 4.2.Menu API..........................|NERDTreeMenuAPI| + 5.About...................................|NERDTreeAbout| + 6.Changelog...............................|NERDTreeChangelog| + 7.Credits.................................|NERDTreeCredits| + 8.License.................................|NERDTreeLicense| + +============================================================================== +1. Intro *NERDTree* + +What is this "NERD tree"?? + +The NERD tree allows you to explore your filesystem and to open files and +directories. It presents the filesystem to you in the form of a tree which you +manipulate with the keyboard and/or mouse. It also allows you to perform +simple filesystem operations. + +The following features and functionality are provided by the NERD tree: + * Files and directories are displayed in a hierarchical tree structure + * Different highlighting is provided for the following types of nodes: + * files + * directories + * sym-links + * windows .lnk files + * read-only files + * executable files + * Many (customisable) mappings are provided to manipulate the tree: + * Mappings to open/close/explore directory nodes + * Mappings to open files in new/existing windows/tabs + * Mappings to change the current root of the tree + * Mappings to navigate around the tree + * ... + * Directories and files can be bookmarked. + * Most NERD tree navigation can also be done with the mouse + * Filtering of tree content (can be toggled at runtime) + * custom file filters to prevent e.g. vim backup files being displayed + * optional displaying of hidden files (. files) + * files can be "turned off" so that only directories are displayed + * The position and size of the NERD tree window can be customised + * The order in which the nodes in the tree are listed can be customised. + * A model of your filesystem is created/maintained as you explore it. This + has several advantages: + * All filesystem information is cached and is only re-read on demand + * If you revisit a part of the tree that you left earlier in your + session, the directory nodes will be opened/closed as you left them + * The script remembers the cursor position and window position in the NERD + tree so you can toggle it off (or just close the tree window) and then + reopen it (with NERDTreeToggle) the NERD tree window will appear exactly + as you left it + * You can have a separate NERD tree for each tab, share trees across tabs, + or a mix of both. + * By default the script overrides the default file browser (netw), so if + you :edit a directory a (slighly modified) NERD tree will appear in the + current window + * A programmable menu system is provided (simulates right clicking on a + node) + * one default menu plugin is provided to perform basic filesytem + operations (create/delete/move/copy files/directories) + * There's an API for adding your own keymappings + + +============================================================================== +2. Functionality provided *NERDTreeFunctionality* + +------------------------------------------------------------------------------ +2.1. Global Commands *NERDTreeGlobalCommands* + +:NERDTree [ | ] *:NERDTree* + Opens a fresh NERD tree. The root of the tree depends on the argument + given. There are 3 cases: If no argument is given, the current directory + will be used. If a directory is given, that will be used. If a bookmark + name is given, the corresponding directory will be used. For example: > + :NERDTree /home/marty/vim7/src + :NERDTree foo (foo is the name of a bookmark) +< +:NERDTreeFromBookmark *:NERDTreeFromBookmark* + Opens a fresh NERD tree with the root initialized to the dir for + . This only reason to use this command over :NERDTree is for + the completion (which is for bookmarks rather than directories). + +:NERDTreeToggle [ | ] *:NERDTreeToggle* + If a NERD tree already exists for this tab, it is reopened and rendered + again. If no NERD tree exists for this tab then this command acts the + same as the |:NERDTree| command. + +:NERDTreeMirror *:NERDTreeMirror* + Shares an existing NERD tree, from another tab, in the current tab. + Changes made to one tree are reflected in both as they are actually the + same buffer. + + If only one other NERD tree exists, that tree is automatically mirrored. If + more than one exists, the script will ask which tree to mirror. + +:NERDTreeClose *:NERDTreeClose* + Close the NERD tree in this tab. + +:NERDTreeFind *:NERDTreeFind* + Find the current file in the tree. If no tree exists for the current tab, + or the file is not under the current root, then initialize a new tree where + the root is the directory of the current file. + +------------------------------------------------------------------------------ +2.2. Bookmarks *NERDTreeBookmarks* + +Bookmarks in the NERD tree are a way to tag files or directories of interest. +For example, you could use bookmarks to tag all of your project directories. + +------------------------------------------------------------------------------ +2.2.1. The Bookmark Table *NERDTreeBookmarkTable* + +If the bookmark table is active (see |NERDTree-B| and +|'NERDTreeShowBookmarks'|), it will be rendered above the tree. You can double +click bookmarks or use the |NERDTree-o| mapping to activate them. See also, +|NERDTree-t| and |NERDTree-T| + +------------------------------------------------------------------------------ +2.2.2. Bookmark commands *NERDTreeBookmarkCommands* + +Note that the following commands are only available in the NERD tree buffer. + +:Bookmark + Bookmark the current node as . If there is already a + bookmark, it is overwritten. must not contain spaces. + +:BookmarkToRoot + Make the directory corresponding to the new root. If a treenode + corresponding to is already cached somewhere in the tree then + the current tree will be used, otherwise a fresh tree will be opened. + Note that if points to a file then its parent will be used + instead. + +:RevealBookmark + If the node is cached under the current root then it will be revealed + (i.e. directory nodes above it will be opened) and the cursor will be + placed on it. + +:OpenBookmark + must point to a file. The file is opened as though |NERDTree-o| + was applied. If the node is cached under the current root then it will be + revealed and the cursor will be placed on it. + +:ClearBookmarks [] + Remove all the given bookmarks. If no bookmarks are given then remove all + bookmarks on the current node. + +:ClearAllBookmarks + Remove all bookmarks. + +:ReadBookmarks + Re-read the bookmarks in the |'NERDTreeBookmarksFile'|. + +See also |:NERDTree| and |:NERDTreeFromBookmark|. + +------------------------------------------------------------------------------ +2.2.3. Invalid Bookmarks *NERDTreeInvalidBookmarks* + +If invalid bookmarks are detected, the script will issue an error message and +the invalid bookmarks will become unavailable for use. + +These bookmarks will still be stored in the bookmarks file (see +|'NERDTreeBookmarksFile'|), down the bottom. There will always be a blank line +after the valid bookmarks but before the invalid ones. + +Each line in the bookmarks file represents one bookmark. The proper format is: + + +After you have corrected any invalid bookmarks, either restart vim, or go +:ReadBookmarks from the NERD tree window. + +------------------------------------------------------------------------------ +2.3. NERD tree Mappings *NERDTreeMappings* + +Default Description~ help-tag~ +Key~ + +o.......Open files, directories and bookmarks....................|NERDTree-o| +go......Open selected file, but leave cursor in the NERDTree.....|NERDTree-go| +t.......Open selected node/bookmark in a new tab.................|NERDTree-t| +T.......Same as 't' but keep the focus on the current tab........|NERDTree-T| +i.......Open selected file in a split window.....................|NERDTree-i| +gi......Same as i, but leave the cursor on the NERDTree..........|NERDTree-gi| +s.......Open selected file in a new vsplit.......................|NERDTree-s| +gs......Same as s, but leave the cursor on the NERDTree..........|NERDTree-gs| +O.......Recursively open the selected directory..................|NERDTree-O| +x.......Close the current nodes parent...........................|NERDTree-x| +X.......Recursively close all children of the current node.......|NERDTree-X| +e.......Edit the current dif.....................................|NERDTree-e| + +...............same as |NERDTree-o|. +double-click.......same as the |NERDTree-o| map. +middle-click.......same as |NERDTree-i| for files, same as + |NERDTree-e| for dirs. + +D.......Delete the current bookmark .............................|NERDTree-D| + +P.......Jump to the root node....................................|NERDTree-P| +p.......Jump to current nodes parent.............................|NERDTree-p| +K.......Jump up inside directories at the current tree depth.....|NERDTree-K| +J.......Jump down inside directories at the current tree depth...|NERDTree-J| +...Jump down to the next sibling of the current directory...|NERDTree-C-J| +...Jump up to the previous sibling of the current directory.|NERDTree-C-K| + +C.......Change the tree root to the selected dir.................|NERDTree-C| +u.......Move the tree root up one directory......................|NERDTree-u| +U.......Same as 'u' except the old root node is left open........|NERDTree-U| +r.......Recursively refresh the current directory................|NERDTree-r| +R.......Recursively refresh the current root.....................|NERDTree-R| +m.......Display the NERD tree menu...............................|NERDTree-m| +cd......Change the CWD to the dir of the selected node...........|NERDTree-cd| + +I.......Toggle whether hidden files displayed....................|NERDTree-I| +f.......Toggle whether the file filters are used.................|NERDTree-f| +F.......Toggle whether files are displayed.......................|NERDTree-F| +B.......Toggle whether the bookmark table is displayed...........|NERDTree-B| + +q.......Close the NERDTree window................................|NERDTree-q| +A.......Zoom (maximize/minimize) the NERDTree window.............|NERDTree-A| +?.......Toggle the display of the quick help.....................|NERDTree-?| + +------------------------------------------------------------------------------ + *NERDTree-o* +Default key: o +Map option: NERDTreeMapActivateNode +Applies to: files and directories. + +If a file node is selected, it is opened in the previous window. + +If a directory is selected it is opened or closed depending on its current +state. + +If a bookmark that links to a directory is selected then that directory +becomes the new root. + +If a bookmark that links to a file is selected then that file is opened in the +previous window. + +------------------------------------------------------------------------------ + *NERDTree-go* +Default key: go +Map option: None +Applies to: files. + +If a file node is selected, it is opened in the previous window, but the +cursor does not move. + +The key combo for this mapping is always "g" + NERDTreeMapActivateNode (see +|NERDTree-o|). + +------------------------------------------------------------------------------ + *NERDTree-t* +Default key: t +Map option: NERDTreeMapOpenInTab +Applies to: files and directories. + +Opens the selected file in a new tab. If a directory is selected, a fresh +NERD Tree for that directory is opened in a new tab. + +If a bookmark which points to a directory is selected, open a NERD tree for +that directory in a new tab. If the bookmark points to a file, open that file +in a new tab. + +------------------------------------------------------------------------------ + *NERDTree-T* +Default key: T +Map option: NERDTreeMapOpenInTabSilent +Applies to: files and directories. + +The same as |NERDTree-t| except that the focus is kept in the current tab. + +------------------------------------------------------------------------------ + *NERDTree-i* +Default key: i +Map option: NERDTreeMapOpenSplit +Applies to: files. + +Opens the selected file in a new split window and puts the cursor in the new +window. + +------------------------------------------------------------------------------ + *NERDTree-gi* +Default key: gi +Map option: None +Applies to: files. + +The same as |NERDTree-i| except that the cursor is not moved. + +The key combo for this mapping is always "g" + NERDTreeMapOpenSplit (see +|NERDTree-i|). + +------------------------------------------------------------------------------ + *NERDTree-s* +Default key: s +Map option: NERDTreeMapOpenVSplit +Applies to: files. + +Opens the selected file in a new vertically split window and puts the cursor in +the new window. + +------------------------------------------------------------------------------ + *NERDTree-gs* +Default key: gs +Map option: None +Applies to: files. + +The same as |NERDTree-s| except that the cursor is not moved. + +The key combo for this mapping is always "g" + NERDTreeMapOpenVSplit (see +|NERDTree-s|). + +------------------------------------------------------------------------------ + *NERDTree-O* +Default key: O +Map option: NERDTreeMapOpenRecursively +Applies to: directories. + +Recursively opens the selelected directory. + +All files and directories are cached, but if a directory would not be +displayed due to file filters (see |'NERDTreeIgnore'| |NERDTree-f|) or the +hidden file filter (see |'NERDTreeShowHidden'|) then its contents are not +cached. This is handy, especially if you have .svn directories. + +------------------------------------------------------------------------------ + *NERDTree-x* +Default key: x +Map option: NERDTreeMapCloseDir +Applies to: files and directories. + +Closes the parent of the selected node. + +------------------------------------------------------------------------------ + *NERDTree-X* +Default key: X +Map option: NERDTreeMapCloseChildren +Applies to: directories. + +Recursively closes all children of the selected directory. + +Tip: To quickly "reset" the tree, use |NERDTree-P| with this mapping. + +------------------------------------------------------------------------------ + *NERDTree-e* +Default key: e +Map option: NERDTreeMapOpenExpl +Applies to: files and directories. + +|:edit|s the selected directory, or the selected file's directory. This could +result in a NERD tree or a netrw being opened, depending on +|'NERDTreeHijackNetrw'|. + +------------------------------------------------------------------------------ + *NERDTree-D* +Default key: D +Map option: NERDTreeMapDeleteBookmark +Applies to: lines in the bookmarks table + +Deletes the currently selected bookmark. + +------------------------------------------------------------------------------ + *NERDTree-P* +Default key: P +Map option: NERDTreeMapJumpRoot +Applies to: no restrictions. + +Jump to the tree root. + +------------------------------------------------------------------------------ + *NERDTree-p* +Default key: p +Map option: NERDTreeMapJumpParent +Applies to: files and directories. + +Jump to the parent node of the selected node. + +------------------------------------------------------------------------------ + *NERDTree-K* +Default key: K +Map option: NERDTreeMapJumpFirstChild +Applies to: files and directories. + +Jump to the first child of the current nodes parent. + +If the cursor is already on the first node then do the following: + * loop back thru the siblings of the current nodes parent until we find an + open dir with children + * go to the first child of that node + +------------------------------------------------------------------------------ + *NERDTree-J* +Default key: J +Map option: NERDTreeMapJumpLastChild +Applies to: files and directories. + +Jump to the last child of the current nodes parent. + +If the cursor is already on the last node then do the following: + * loop forward thru the siblings of the current nodes parent until we find + an open dir with children + * go to the last child of that node + +------------------------------------------------------------------------------ + *NERDTree-C-J* +Default key: +Map option: NERDTreeMapJumpNextSibling +Applies to: files and directories. + +Jump to the next sibling of the selected node. + +------------------------------------------------------------------------------ + *NERDTree-C-K* +Default key: +Map option: NERDTreeMapJumpPrevSibling +Applies to: files and directories. + +Jump to the previous sibling of the selected node. + +------------------------------------------------------------------------------ + *NERDTree-C* +Default key: C +Map option: NERDTreeMapChdir +Applies to: directories. + +Make the selected directory node the new tree root. If a file is selected, its +parent is used. + +------------------------------------------------------------------------------ + *NERDTree-u* +Default key: u +Map option: NERDTreeMapUpdir +Applies to: no restrictions. + +Move the tree root up a dir (like doing a "cd .."). + +------------------------------------------------------------------------------ + *NERDTree-U* +Default key: U +Map option: NERDTreeMapUpdirKeepOpen +Applies to: no restrictions. + +Like |NERDTree-u| except that the old tree root is kept open. + +------------------------------------------------------------------------------ + *NERDTree-r* +Default key: r +Map option: NERDTreeMapRefresh +Applies to: files and directories. + +If a dir is selected, recursively refresh that dir, i.e. scan the filesystem +for changes and represent them in the tree. + +If a file node is selected then the above is done on it's parent. + +------------------------------------------------------------------------------ + *NERDTree-R* +Default key: R +Map option: NERDTreeMapRefreshRoot +Applies to: no restrictions. + +Recursively refresh the tree root. + +------------------------------------------------------------------------------ + *NERDTree-m* +Default key: m +Map option: NERDTreeMapMenu +Applies to: files and directories. + +Display the NERD tree menu. See |NERDTreeMenu| for details. + +------------------------------------------------------------------------------ + *NERDTree-cd* +Default key: cd +Map option: NERDTreeMapChdir +Applies to: files and directories. + +Change vims current working directory to that of the selected node. + +------------------------------------------------------------------------------ + *NERDTree-I* +Default key: I +Map option: NERDTreeMapToggleHidden +Applies to: no restrictions. + +Toggles whether hidden files (i.e. "dot files") are displayed. + +------------------------------------------------------------------------------ + *NERDTree-f* +Default key: f +Map option: NERDTreeMapToggleFilters +Applies to: no restrictions. + +Toggles whether file filters are used. See |'NERDTreeIgnore'| for details. + +------------------------------------------------------------------------------ + *NERDTree-F* +Default key: F +Map option: NERDTreeMapToggleFiles +Applies to: no restrictions. + +Toggles whether file nodes are displayed. + +------------------------------------------------------------------------------ + *NERDTree-B* +Default key: B +Map option: NERDTreeMapToggleBookmarks +Applies to: no restrictions. + +Toggles whether the bookmarks table is displayed. + +------------------------------------------------------------------------------ + *NERDTree-q* +Default key: q +Map option: NERDTreeMapQuit +Applies to: no restrictions. + +Closes the NERDtree window. + +------------------------------------------------------------------------------ + *NERDTree-A* +Default key: A +Map option: NERDTreeMapToggleZoom +Applies to: no restrictions. + +Maximize (zoom) and minimize the NERDtree window. + +------------------------------------------------------------------------------ + *NERDTree-?* +Default key: ? +Map option: NERDTreeMapHelp +Applies to: no restrictions. + +Toggles whether the quickhelp is displayed. + +------------------------------------------------------------------------------ +2.3. The NERD tree menu *NERDTreeMenu* + +The NERD tree has a menu that can be programmed via the an API (see +|NERDTreeMenuAPI|). The idea is to simulate the "right click" menus that most +file explorers have. + +The script comes with two default menu plugins: exec_menuitem.vim and +fs_menu.vim. fs_menu.vim adds some basic filesystem operations to the menu for +creating/deleting/moving/copying files and dirs. exec_menuitem.vim provides a +menu item to execute executable files. + +Related tags: |NERDTree-m| |NERDTreeApi| + +============================================================================== +3. Customisation *NERDTreeOptions* + + +------------------------------------------------------------------------------ +3.1. Customisation summary *NERDTreeOptionSummary* + +The script provides the following options that can customise the behaviour the +NERD tree. These options should be set in your vimrc. + +|'loaded_nerd_tree'| Turns off the script. + +|'NERDChristmasTree'| Tells the NERD tree to make itself colourful + and pretty. + +|'NERDTreeAutoCenter'| Controls whether the NERD tree window centers + when the cursor moves within a specified + distance to the top/bottom of the window. +|'NERDTreeAutoCenterThreshold'| Controls the sensitivity of autocentering. + +|'NERDTreeCaseSensitiveSort'| Tells the NERD tree whether to be case + sensitive or not when sorting nodes. + +|'NERDTreeChDirMode'| Tells the NERD tree if/when it should change + vim's current working directory. + +|'NERDTreeHighlightCursorline'| Tell the NERD tree whether to highlight the + current cursor line. + +|'NERDTreeHijackNetrw'| Tell the NERD tree whether to replace the netrw + autocommands for exploring local directories. + +|'NERDTreeIgnore'| Tells the NERD tree which files to ignore. + +|'NERDTreeBookmarksFile'| Where the bookmarks are stored. + +|'NERDTreeMouseMode'| Tells the NERD tree how to handle mouse + clicks. + +|'NERDTreeQuitOnOpen'| Closes the tree window after opening a file. + +|'NERDTreeShowBookmarks'| Tells the NERD tree whether to display the + bookmarks table on startup. + +|'NERDTreeShowFiles'| Tells the NERD tree whether to display files + in the tree on startup. + +|'NERDTreeShowHidden'| Tells the NERD tree whether to display hidden + files on startup. + +|'NERDTreeShowLineNumbers'| Tells the NERD tree whether to display line + numbers in the tree window. + +|'NERDTreeSortOrder'| Tell the NERD tree how to sort the nodes in + the tree. + +|'NERDTreeStatusline'| Set a statusline for NERD tree windows. + +|'NERDTreeWinPos'| Tells the script where to put the NERD tree + window. + +|'NERDTreeWinSize'| Sets the window size when the NERD tree is + opened. + +------------------------------------------------------------------------------ +3.2. Customisation details *NERDTreeOptionDetails* + +To enable any of the below options you should put the given line in your +~/.vimrc + + *'loaded_nerd_tree'* +If this plugin is making you feel homicidal, it may be a good idea to turn it +off with this line in your vimrc: > + let loaded_nerd_tree=1 +< +------------------------------------------------------------------------------ + *'NERDChristmasTree'* +Values: 0 or 1. +Default: 1. + +If this option is set to 1 then some extra syntax highlighting elements are +added to the nerd tree to make it more colourful. + +Set it to 0 for a more vanilla looking tree. + +------------------------------------------------------------------------------ + *'NERDTreeAutoCenter'* +Values: 0 or 1. +Default: 1 + +If set to 1, the NERD tree window will center around the cursor if it moves to +within |'NERDTreeAutoCenterThreshold'| lines of the top/bottom of the window. + +This is ONLY done in response to tree navigation mappings, +i.e. |NERDTree-J| |NERDTree-K| |NERDTree-C-J| |NERDTree-C-K| |NERDTree-p| +|NERDTree-P| + +The centering is done with a |zz| operation. + +------------------------------------------------------------------------------ + *'NERDTreeAutoCenterThreshold'* +Values: Any natural number. +Default: 3 + +This option controls the "sensitivity" of the NERD tree auto centering. See +|'NERDTreeAutoCenter'| for details. + +------------------------------------------------------------------------------ + *'NERDTreeCaseSensitiveSort'* +Values: 0 or 1. +Default: 0. + +By default the NERD tree does not sort nodes case sensitively, i.e. nodes +could appear like this: > + bar.c + Baz.c + blarg.c + boner.c + Foo.c +< +But, if you set this option to 1 then the case of the nodes will be taken into +account. The above nodes would then be sorted like this: > + Baz.c + Foo.c + bar.c + blarg.c + boner.c +< +------------------------------------------------------------------------------ + *'NERDTreeChDirMode'* + +Values: 0, 1 or 2. +Default: 0. + +Use this option to tell the script when (if at all) to change the current +working directory (CWD) for vim. + +If it is set to 0 then the CWD is never changed by the NERD tree. + +If set to 1 then the CWD is changed when the NERD tree is first loaded to the +directory it is initialized in. For example, if you start the NERD tree with > + :NERDTree /home/marty/foobar +< +then the CWD will be changed to /home/marty/foobar and will not be changed +again unless you init another NERD tree with a similar command. + +If the option is set to 2 then it behaves the same as if set to 1 except that +the CWD is changed whenever the tree root is changed. For example, if the CWD +is /home/marty/foobar and you make the node for /home/marty/foobar/baz the new +root then the CWD will become /home/marty/foobar/baz. + +------------------------------------------------------------------------------ + *'NERDTreeHighlightCursorline'* +Values: 0 or 1. +Default: 1. + +If set to 1, the current cursor line in the NERD tree buffer will be +highlighted. This is done using the |'cursorline'| option. + +------------------------------------------------------------------------------ + *'NERDTreeHijackNetrw'* +Values: 0 or 1. +Default: 1. + +If set to 1, doing a > + :edit +< +will open up a "secondary" NERD tree instead of a netrw in the target window. + +Secondary NERD trees behaves slighly different from a regular trees in the +following respects: + 1. 'o' will open the selected file in the same window as the tree, + replacing it. + 2. you can have as many secondary tree as you want in the same tab. + +------------------------------------------------------------------------------ + *'NERDTreeIgnore'* +Values: a list of regular expressions. +Default: ['\~$']. + +This option is used to specify which files the NERD tree should ignore. It +must be a list of regular expressions. When the NERD tree is rendered, any +files/dirs that match any of the regex's in 'NERDTreeIgnore' wont be +displayed. + +For example if you put the following line in your vimrc: > + let NERDTreeIgnore=['\.vim$', '\~$'] +< +then all files ending in .vim or ~ will be ignored. + +Note: to tell the NERD tree not to ignore any files you must use the following +line: > + let NERDTreeIgnore=[] +< + +The file filters can be turned on and off dynamically with the |NERDTree-f| +mapping. + +------------------------------------------------------------------------------ + *'NERDTreeBookmarksFile'* +Values: a path +Default: $HOME/.NERDTreeBookmarks + +This is where bookmarks are saved. See |NERDTreeBookmarkCommands|. + +------------------------------------------------------------------------------ + *'NERDTreeMouseMode'* +Values: 1, 2 or 3. +Default: 1. + +If set to 1 then a double click on a node is required to open it. +If set to 2 then a single click will open directory nodes, while a double +click will still be required for file nodes. +If set to 3 then a single click will open any node. + +Note: a double click anywhere on a line that a tree node is on will +activate it, but all single-click activations must be done on name of the node +itself. For example, if you have the following node: > + | | |-application.rb +< +then (to single click activate it) you must click somewhere in +'application.rb'. + +------------------------------------------------------------------------------ + *'NERDTreeQuitOnOpen'* + +Values: 0 or 1. +Default: 0 + +If set to 1, the NERD tree window will close after opening a file with the +|NERDTree-o|, |NERDTree-i|, |NERDTree-t| and |NERDTree-T| mappings. + +------------------------------------------------------------------------------ + *'NERDTreeShowBookmarks'* +Values: 0 or 1. +Default: 0. + +If this option is set to 1 then the bookmarks table will be displayed. + +This option can be toggled dynamically, per tree, with the |NERDTree-B| +mapping. + +------------------------------------------------------------------------------ + *'NERDTreeShowFiles'* +Values: 0 or 1. +Default: 1. + +If this option is set to 1 then files are displayed in the NERD tree. If it is +set to 0 then only directories are displayed. + +This option can be toggled dynamically, per tree, with the |NERDTree-F| +mapping and is useful for drastically shrinking the tree when you are +navigating to a different part of the tree. + +------------------------------------------------------------------------------ + *'NERDTreeShowHidden'* +Values: 0 or 1. +Default: 0. + +This option tells vim whether to display hidden files by default. This option +can be dynamically toggled, per tree, with the |NERDTree-I| mapping. Use one +of the follow lines to set this option: > + let NERDTreeShowHidden=0 + let NERDTreeShowHidden=1 +< + +------------------------------------------------------------------------------ + *'NERDTreeShowLineNumbers'* +Values: 0 or 1. +Default: 0. + +This option tells vim whether to display line numbers for the NERD tree +window. Use one of the follow lines to set this option: > + let NERDTreeShowLineNumbers=0 + let NERDTreeShowLineNumbers=1 +< + +------------------------------------------------------------------------------ + *'NERDTreeSortOrder'* +Values: a list of regular expressions. +Default: ['\/$', '*', '\.swp$', '\.bak$', '\~$'] + +This option is set to a list of regular expressions which are used to +specify the order of nodes under their parent. + +For example, if the option is set to: > + ['\.vim$', '\.c$', '\.h$', '*', 'foobar'] +< +then all .vim files will be placed at the top, followed by all .c files then +all .h files. All files containing the string 'foobar' will be placed at the +end. The star is a special flag: it tells the script that every node that +doesnt match any of the other regexps should be placed here. + +If no star is present in 'NERDTreeSortOrder' then one is automatically +appended to the array. + +The regex '\/$' should be used to match directory nodes. + +After this sorting is done, the files in each group are sorted alphabetically. + +Other examples: > + (1) ['*', '\/$'] + (2) [] + (3) ['\/$', '\.rb$', '\.php$', '*', '\.swp$', '\.bak$', '\~$'] +< +1. Directories will appear last, everything else will appear above. +2. Everything will simply appear in alphabetical order. +3. Dirs will appear first, then ruby and php. Swap files, bak files and vim + backup files will appear last with everything else preceding them. + +------------------------------------------------------------------------------ + *'NERDTreeStatusline'* +Values: Any valid statusline setting. +Default: %{b:NERDTreeRoot.path.strForOS(0)} + +Tells the script what to use as the |'statusline'| setting for NERD tree +windows. + +Note that the statusline is set using |:let-&| not |:set| so escaping spaces +isn't necessary. + +Setting this option to -1 will will deactivate it so that your global +statusline setting is used instead. + +------------------------------------------------------------------------------ + *'NERDTreeWinPos'* +Values: "left" or "right" +Default: "left". + +This option is used to determine where NERD tree window is placed on the +screen. + +This option makes it possible to use two different explorer plugins +simultaneously. For example, you could have the taglist plugin on the left of +the window and the NERD tree on the right. + +------------------------------------------------------------------------------ + *'NERDTreeWinSize'* +Values: a positive integer. +Default: 31. + +This option is used to change the size of the NERD tree when it is loaded. + +============================================================================== +4. The NERD tree API *NERDTreeAPI* + +The NERD tree script allows you to add custom key mappings and menu items via +a set of API calls. Any scripts that use this API should be placed in +~/.vim/nerdtree_plugin/ (*nix) or ~/vimfiles/nerdtree_plugin (windows). + +The script exposes some prototype objects that can be used to manipulate the +tree and/or get information from it: > + g:NERDTreePath + g:NERDTreeDirNode + g:NERDTreeFileNode + g:NERDTreeBookmark +< +See the code/comments in NERD_tree.vim to find how to use these objects. The +following code conventions are used: + * class members start with a capital letter + * instance members start with a lower case letter + * private members start with an underscore + +See this blog post for more details: + http://got-ravings.blogspot.com/2008/09/vim-pr0n-prototype-based-objects.html + +------------------------------------------------------------------------------ +4.1. Key map API *NERDTreeKeymapAPI* + +NERDTreeAddKeyMap({options}) *NERDTreeAddKeyMap()* + Adds a new keymapping for all NERD tree buffers. + {options} must be a dictionary, and must contain the following keys: + "key" - the trigger key for the new mapping + "callback" - the function the new mapping will be bound to + "quickhelpText" - the text that will appear in the quickhelp (see + |NERDTree-?|) + + Example: > + call NERDTreeAddKeyMap({ + \ 'key': 'b', + \ 'callback': 'NERDTreeEchoCurrentNode', + \ 'quickhelpText': 'echo full path of current node' }) + + function! NERDTreeEchoCurrentNode() + let n = g:NERDTreeFileNode.GetSelected() + if n != {} + echomsg 'Current node: ' . n.path.str() + endif + endfunction +< + This code should sit in a file like ~/.vim/nerdtree_plugin/mymapping.vim. + It adds a (rather useless) mapping on 'b' which echos the full path to the + current node. + +------------------------------------------------------------------------------ +4.2. Menu API *NERDTreeMenuAPI* + +NERDTreeAddSubmenu({options}) *NERDTreeAddSubmenu()* + Creates and returns a new submenu. + + {options} must be a dictionary and must contain the following keys: + "text" - the text of the submenu that the user will see + "shortcut" - a shortcut key for the submenu (need not be unique) + + The following keys are optional: + "isActiveCallback" - a function that will be called to determine whether + this submenu item will be displayed or not. The callback function must return + 0 or 1. + "parent" - the parent submenu of the new submenu (returned from a previous + invocation of NERDTreeAddSubmenu()). If this key is left out then the new + submenu will sit under the top level menu. + + See below for an example. + +NERDTreeAddMenuItem({options}) *NERDTreeAddMenuItem()* + Adds a new menu item to the NERD tree menu (see |NERDTreeMenu|). + + {options} must be a dictionary and must contain the + following keys: + "text" - the text of the menu item which the user will see + "shortcut" - a shortcut key for the menu item (need not be unique) + "callback" - the function that will be called when the user activates the + menu item. + + The following keys are optional: + "isActiveCallback" - a function that will be called to determine whether + this menu item will be displayed or not. The callback function must return + 0 or 1. + "parent" - if the menu item belongs under a submenu then this key must be + specified. This value for this key will be the object that + was returned when the submenu was created with |NERDTreeAddSubmenu()|. + + See below for an example. + +NERDTreeAddMenuSeparator([{options}]) *NERDTreeAddMenuSeparator()* + Adds a menu separator (a row of dashes). + + {options} is an optional dictionary that may contain the following keys: + "isActiveCallback" - see description in |NERDTreeAddMenuItem()|. + +Below is an example of the menu API in action. > + call NERDTreeAddMenuSeparator() + + call NERDTreeAddMenuItem({ + \ 'text': 'a (t)op level menu item', + \ 'shortcut': 't', + \ 'callback': 'SomeFunction' }) + + let submenu = NERDTreeAddSubmenu({ + \ 'text': 'a (s)ub menu', + \ 'shortcut': 's' }) + + call NERDTreeAddMenuItem({ + \ 'text': '(n)ested item 1', + \ 'shortcut': 'n', + \ 'callback': 'SomeFunction', + \ 'parent': submenu }) + + call NERDTreeAddMenuItem({ + \ 'text': '(n)ested item 2', + \ 'shortcut': 'n', + \ 'callback': 'SomeFunction', + \ 'parent': submenu }) +< +This will create the following menu: > + -------------------- + a (t)op level menu item + a (s)ub menu +< +Where selecting "a (s)ub menu" will lead to a second menu: > + (n)ested item 1 + (n)ested item 2 +< +When any of the 3 concrete menu items are selected the function "SomeFunction" +will be called. + +------------------------------------------------------------------------------ +NERDTreeRender() *NERDTreeRender()* + Re-renders the NERD tree buffer. Useful if you change the state of the + tree and you want to it to be reflected in the UI. + +============================================================================== +5. About *NERDTreeAbout* + +The author of the NERD tree is a terrible terrible monster called Martyzilla +who gobbles up small children with milk and sugar for breakfast. + +He can be reached at martin.grenfell at gmail dot com. He would love to hear +from you, so feel free to send him suggestions and/or comments about this +plugin. Don't be shy --- the worst he can do is slaughter you and stuff you in +the fridge for later ;) + +The latest stable versions can be found at + http://www.vim.org/scripts/script.php?script_id=1658 + +The latest dev versions are on github + http://github.com/scrooloose/nerdtree + + +============================================================================== +6. Changelog *NERDTreeChangelog* + +4.1.0 + features: + - NERDTreeFind to reveal the node for the current buffer in the tree, + see |NERDTreeFind|. This effectively merges the FindInNERDTree plugin (by + Doug McInnes) into the script. + - make NERDTreeQuitOnOpen apply to the t/T keymaps too. Thanks to Stefan + Ritter and Rémi Prévost. + - truncate the root node if wider than the tree window. Thanks to Victor + Gonzalez. + + bugfixes: + - really fix window state restoring + - fix some win32 path escaping issues. Thanks to Stephan Baumeister, Ricky, + jfilip1024, and Chris Chambers + +4.0.0 + - add a new programmable menu system (see :help NERDTreeMenu). + - add new APIs to add menus/menu-items to the menu system as well as + custom key mappings to the NERD tree buffer (see :help NERDTreeAPI). + - removed the old API functions + - added a mapping to maximize/restore the size of nerd tree window, thanks + to Guillaume Duranceau for the patch. See :help NERDTree-A for details. + + - fix a bug where secondary nerd trees (netrw hijacked trees) and + NERDTreeQuitOnOpen didnt play nicely, thanks to Curtis Harvey. + - fix a bug where the script ignored directories whose name ended in a dot, + thanks to Aggelos Orfanakos for the patch. + - fix a bug when using the x mapping on the tree root, thanks to Bryan + Venteicher for the patch. + - fix a bug where the cursor position/window size of the nerd tree buffer + wasnt being stored on closing the window, thanks to Richard Hart. + - fix a bug where NERDTreeMirror would mirror the wrong tree + +3.1.1 + - fix a bug where a non-listed no-name buffer was getting created every + time the tree windows was created, thanks to Derek Wyatt and owen1 + - make behave the same as the 'o' mapping + - some helptag fixes in the doc, thanks strull + - fix a bug when using :set nohidden and opening a file where the previous + buf was modified. Thanks iElectric + - other minor fixes + +3.1.0 + New features: + - add mappings to open files in a vsplit, see :help NERDTree-s and :help + NERDTree-gs + - make the statusline for the nerd tree window default to something + hopefully more useful. See :help 'NERDTreeStatusline' + Bugfixes: + - make the hijack netrw functionality work when vim is started with "vim + " (thanks to Alf Mikula for the patch). + - fix a bug where the CWD wasnt being changed for some operations even when + NERDTreeChDirMode==2 (thanks to Lucas S. Buchala) + - add -bar to all the nerd tree :commands so they can chain with other + :commands (thanks to tpope) + - fix bugs when ignorecase was set (thanks to nach) + - fix a bug with the relative path code (thanks to nach) + - fix a bug where doing a :cd would cause :NERDTreeToggle to fail (thanks nach) + + +3.0.1 + Bugfixes: + - fix bugs with :NERDTreeToggle and :NERDTreeMirror when 'hidden + was not set + - fix a bug where :NERDTree would fail if was relative and + didnt start with a ./ or ../ Thanks to James Kanze. + - make the q mapping work with secondary (:e style) trees, + thanks to jamessan + - fix a bunch of small bugs with secondary trees + + More insane refactoring. + +3.0.0 + - hijack netrw so that doing an :edit will put a NERD tree in + the window rather than a netrw browser. See :help 'NERDTreeHijackNetrw' + - allow sharing of trees across tabs, see :help :NERDTreeMirror + - remove "top" and "bottom" as valid settings for NERDTreeWinPos + - change the '' mapping to 'i' + - change the 'H' mapping to 'I' + - lots of refactoring + +============================================================================== +7. Credits *NERDTreeCredits* + +Thanks to the following people for testing, bug reports, ideas etc. Without +you I probably would have got bored of the hacking the NERD tree and +just downloaded pr0n instead. + + Tim Carey-Smith (halorgium) + Vigil + Nick Brettell + Thomas Scott Urban + Terrance Cohen + Yegappan Lakshmanan + Jason Mills + Michael Geddes (frogonwheels) + Yu Jun + Michael Madsen + AOYAMA Shotaro + Zhang Weiwu + Niels Aan de Brugh + Olivier Yiptong + Zhang Shuhan + Cory Echols + Piotr Czachur + Yuan Jiang + Matan Nassau + Maxim Kim + Charlton Wang + Matt Wozniski (godlygeek) + knekk + Sean Chou + Ryan Penn + Simon Peter Nicholls + Michael Foobar + Tomasz Chomiuk + Denis Pokataev + Tim Pope (tpope) + James Kanze + James Vega (jamessan) + Frederic Chanal (nach) + Alf Mikula + Lucas S. Buchala + Curtis Harvey + Guillaume Duranceau + Richard Hart (hates) + Doug McInnes + Stefan Ritter + Rémi Prévost + Victor Gonzalez + Stephan Baumeister + Ricky + jfilip1024 + Chris Chambers + +============================================================================== +8. License *NERDTreeLicense* + +The NERD tree is released under the wtfpl. +See http://sam.zoy.org/wtfpl/COPYING. diff --git a/.vim/bundle/nerdtree/nerdtree_plugin/exec_menuitem.vim b/.vim/bundle/nerdtree/nerdtree_plugin/exec_menuitem.vim new file mode 100644 index 0000000..e7a7c53 --- /dev/null +++ b/.vim/bundle/nerdtree/nerdtree_plugin/exec_menuitem.vim @@ -0,0 +1,41 @@ +" ============================================================================ +" File: exec_menuitem.vim +" Description: plugin for NERD Tree that provides an execute file menu item +" Maintainer: Martin Grenfell +" Last Change: 22 July, 2009 +" License: This program is free software. It comes without any warranty, +" to the extent permitted by applicable law. You can redistribute +" it and/or modify it under the terms of the Do What The Fuck You +" Want To Public License, Version 2, as published by Sam Hocevar. +" See http://sam.zoy.org/wtfpl/COPYING for more details. +" +" ============================================================================ +if exists("g:loaded_nerdtree_exec_menuitem") + finish +endif +let g:loaded_nerdtree_exec_menuitem = 1 + +call NERDTreeAddMenuItem({ + \ 'text': '(!)Execute file', + \ 'shortcut': '!', + \ 'callback': 'NERDTreeExecFile', + \ 'isActiveCallback': 'NERDTreeExecFileActive' }) + +function! NERDTreeExecFileActive() + let node = g:NERDTreeFileNode.GetSelected() + return !node.path.isDirectory && node.path.isExecutable +endfunction + +function! NERDTreeExecFile() + let treenode = g:NERDTreeFileNode.GetSelected() + echo "==========================================================\n" + echo "Complete the command to execute (add arguments etc):\n" + let cmd = treenode.path.str({'escape': 1}) + let cmd = input(':!', cmd . ' ') + + if cmd != '' + exec ':!' . cmd + else + echo "Aborted" + endif +endfunction diff --git a/.vim/bundle/nerdtree/nerdtree_plugin/fs_menu.vim b/.vim/bundle/nerdtree/nerdtree_plugin/fs_menu.vim new file mode 100644 index 0000000..e25b38c --- /dev/null +++ b/.vim/bundle/nerdtree/nerdtree_plugin/fs_menu.vim @@ -0,0 +1,194 @@ +" ============================================================================ +" File: fs_menu.vim +" Description: plugin for the NERD Tree that provides a file system menu +" Maintainer: Martin Grenfell +" Last Change: 17 July, 2009 +" License: This program is free software. It comes without any warranty, +" to the extent permitted by applicable law. You can redistribute +" it and/or modify it under the terms of the Do What The Fuck You +" Want To Public License, Version 2, as published by Sam Hocevar. +" See http://sam.zoy.org/wtfpl/COPYING for more details. +" +" ============================================================================ +if exists("g:loaded_nerdtree_fs_menu") + finish +endif +let g:loaded_nerdtree_fs_menu = 1 + +call NERDTreeAddMenuItem({'text': '(a)dd a childnode', 'shortcut': 'a', 'callback': 'NERDTreeAddNode'}) +call NERDTreeAddMenuItem({'text': '(m)ove the curent node', 'shortcut': 'm', 'callback': 'NERDTreeMoveNode'}) +call NERDTreeAddMenuItem({'text': '(d)elete the curent node', 'shortcut': 'd', 'callback': 'NERDTreeDeleteNode'}) +if g:NERDTreePath.CopyingSupported() + call NERDTreeAddMenuItem({'text': '(c)copy the current node', 'shortcut': 'c', 'callback': 'NERDTreeCopyNode'}) +endif + +"FUNCTION: s:echo(msg){{{1 +function! s:echo(msg) + redraw + echomsg "NERDTree: " . a:msg +endfunction + +"FUNCTION: s:echoWarning(msg){{{1 +function! s:echoWarning(msg) + echohl warningmsg + call s:echo(a:msg) + echohl normal +endfunction + +"FUNCTION: s:promptToDelBuffer(bufnum, msg){{{1 +"prints out the given msg and, if the user responds by pushing 'y' then the +"buffer with the given bufnum is deleted +" +"Args: +"bufnum: the buffer that may be deleted +"msg: a message that will be echoed to the user asking them if they wish to +" del the buffer +function! s:promptToDelBuffer(bufnum, msg) + echo a:msg + if nr2char(getchar()) ==# 'y' + exec "silent bdelete! " . a:bufnum + endif +endfunction + +"FUNCTION: NERDTreeAddNode(){{{1 +function! NERDTreeAddNode() + let curDirNode = g:NERDTreeDirNode.GetSelected() + + let newNodeName = input("Add a childnode\n". + \ "==========================================================\n". + \ "Enter the dir/file name to be created. Dirs end with a '/'\n" . + \ "", curDirNode.path.str({'format': 'Glob'}) . g:NERDTreePath.Slash()) + + if newNodeName ==# '' + call s:echo("Node Creation Aborted.") + return + endif + + try + let newPath = g:NERDTreePath.Create(newNodeName) + let parentNode = b:NERDTreeRoot.findNode(newPath.getParent()) + + let newTreeNode = g:NERDTreeFileNode.New(newPath) + if parentNode.isOpen || !empty(parentNode.children) + call parentNode.addChild(newTreeNode, 1) + call NERDTreeRender() + call newTreeNode.putCursorHere(1, 0) + endif + catch /^NERDTree/ + call s:echoWarning("Node Not Created.") + endtry +endfunction + +"FUNCTION: NERDTreeMoveNode(){{{1 +function! NERDTreeMoveNode() + let curNode = g:NERDTreeFileNode.GetSelected() + let newNodePath = input("Rename the current node\n" . + \ "==========================================================\n" . + \ "Enter the new path for the node: \n" . + \ "", curNode.path.str()) + + if newNodePath ==# '' + call s:echo("Node Renaming Aborted.") + return + endif + + try + let bufnum = bufnr(curNode.path.str()) + + call curNode.rename(newNodePath) + call NERDTreeRender() + + "if the node is open in a buffer, ask the user if they want to + "close that buffer + if bufnum != -1 + let prompt = "\nNode renamed.\n\nThe old file is open in buffer ". bufnum . (bufwinnr(bufnum) ==# -1 ? " (hidden)" : "") .". Delete this buffer? (yN)" + call s:promptToDelBuffer(bufnum, prompt) + endif + + call curNode.putCursorHere(1, 0) + + redraw + catch /^NERDTree/ + call s:echoWarning("Node Not Renamed.") + endtry +endfunction + +" FUNCTION: NERDTreeDeleteNode() {{{1 +function! NERDTreeDeleteNode() + let currentNode = g:NERDTreeFileNode.GetSelected() + let confirmed = 0 + + if currentNode.path.isDirectory + let choice =input("Delete the current node\n" . + \ "==========================================================\n" . + \ "STOP! To delete this entire directory, type 'yes'\n" . + \ "" . currentNode.path.str() . ": ") + let confirmed = choice ==# 'yes' + else + echo "Delete the current node\n" . + \ "==========================================================\n". + \ "Are you sure you wish to delete the node:\n" . + \ "" . currentNode.path.str() . " (yN):" + let choice = nr2char(getchar()) + let confirmed = choice ==# 'y' + endif + + + if confirmed + try + call currentNode.delete() + call NERDTreeRender() + + "if the node is open in a buffer, ask the user if they want to + "close that buffer + let bufnum = bufnr(currentNode.path.str()) + if buflisted(bufnum) + let prompt = "\nNode deleted.\n\nThe file is open in buffer ". bufnum . (bufwinnr(bufnum) ==# -1 ? " (hidden)" : "") .". Delete this buffer? (yN)" + call s:promptToDelBuffer(bufnum, prompt) + endif + + redraw + catch /^NERDTree/ + call s:echoWarning("Could not remove node") + endtry + else + call s:echo("delete aborted") + endif + +endfunction + +" FUNCTION: NERDTreeCopyNode() {{{1 +function! NERDTreeCopyNode() + let currentNode = g:NERDTreeFileNode.GetSelected() + let newNodePath = input("Copy the current node\n" . + \ "==========================================================\n" . + \ "Enter the new path to copy the node to: \n" . + \ "", currentNode.path.str()) + + if newNodePath != "" + "strip trailing slash + let newNodePath = substitute(newNodePath, '\/$', '', '') + + let confirmed = 1 + if currentNode.path.copyingWillOverwrite(newNodePath) + call s:echo("Warning: copying may overwrite files! Continue? (yN)") + let choice = nr2char(getchar()) + let confirmed = choice ==# 'y' + endif + + if confirmed + try + let newNode = currentNode.copy(newNodePath) + call NERDTreeRender() + call newNode.putCursorHere(0, 0) + catch /^NERDTree/ + call s:echoWarning("Could not copy node") + endtry + endif + else + call s:echo("Copy aborted.") + endif + redraw +endfunction + +" vim: set sw=4 sts=4 et fdm=marker: diff --git a/.vim/plugin/NERD_tree.vim b/.vim/bundle/nerdtree/plugin/NERD_tree.vim similarity index 82% rename from .vim/plugin/NERD_tree.vim rename to .vim/bundle/nerdtree/plugin/NERD_tree.vim index 709328f..c5a014c 100644 --- a/.vim/plugin/NERD_tree.vim +++ b/.vim/bundle/nerdtree/plugin/NERD_tree.vim @@ -1,8 +1,8 @@ " ============================================================================ " File: NERD_tree.vim " Description: vim global plugin that provides a nice tree explorer -" Maintainer: Martin Grenfell -" Last Change: 27 Jan, 2009 +" Maintainer: Martin Grenfell +" 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 @@ -10,7 +10,7 @@ " See http://sam.zoy.org/wtfpl/COPYING for more details. " " ============================================================================ -let s:NERD_tree_version = '3.1.0' +let s:NERD_tree_version = '4.1.0' " SECTION: Script init stuff {{{1 "============================================================ @@ -39,7 +39,7 @@ set cpo&vim "1 if the var is set, 0 otherwise function! s:initVariable(var, value) if !exists(a:var) - exec 'let ' . a:var . ' = ' . "'" . a:value . "'" + exec 'let ' . a:var . ' = ' . "'" . substitute(a:value, "'", "''", "g") . "'" return 1 endif return 0 @@ -79,7 +79,14 @@ endif "once here let s:NERDTreeSortStarIndex = index(g:NERDTreeSortOrder, '*') -call s:initVariable("g:NERDTreeStatusline", "%{b:NERDTreeRoot.path.strForOS(0)}") +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) @@ -103,8 +110,7 @@ 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:NERDTreeMapExecute", "!") -call s:initVariable("g:NERDTreeMapFilesystemMenu", "m") +call s:initVariable("g:NERDTreeMapMenu", "m") call s:initVariable("g:NERDTreeMapHelp", "?") call s:initVariable("g:NERDTreeMapJumpFirstChild", "K") call s:initVariable("g:NERDTreeMapJumpLastChild", "J") @@ -128,22 +134,22 @@ 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 -let s:escape_chars = " \\`\|\"#%&,?()\*^<>" +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)' -let s:os_slash = '/' -if s:running_windows - let s:os_slash = '\' -endif - "the number to add to the nerd tree buffer name to make the buf name unique let s:next_buffer_number = 1 @@ -154,14 +160,18 @@ command! -n=? -complete=dir -bar NERDTree :call s:initNerdTree('') command! -n=? -complete=dir -bar NERDTreeToggle :call s:toggle('') command! -n=0 -bar NERDTreeClose :call s:closeTreeIfOpen() command! -n=1 -complete=customlist,s:completeBookmarks -bar NERDTreeFromBookmark call s:initNerdTree('') -command! -n=0 -complete=customlist,s:completeNERDTreeMirrors -bar NERDTreeMirror call s:initNerdTreeMirror() +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 saveScreenState()" + exec "autocmd BufWinLeave ". s:NERDTreeBufName ."* call 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 @@ -176,6 +186,18 @@ endif "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() + call s:closeTreeIfQuitOnOpen() + 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 @@ -316,6 +338,21 @@ 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 @@ -330,7 +367,7 @@ 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.strForOS(0) + \ self.name ."\" points to a non existing location: \"". self.path.str() endif endfunction " FUNCTION: Bookmark.New(name, path) {{{3 @@ -345,6 +382,21 @@ function! s:Bookmark.New(name, path) 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) @@ -364,7 +416,7 @@ function! s:Bookmark.str() let pathStrMaxLen = pathStrMaxLen - &numberwidth endif - let pathStr = self.path.strForOS(0) + let pathStr = self.path.str({'format': 'UI'}) if len(pathStr) > pathStrMaxLen let pathStr = '<' . strpart(pathStr, len(pathStr) - pathStrMaxLen) endif @@ -409,7 +461,7 @@ endfunction function! s:Bookmark.Write() let bookmarkStrings = [] for i in s:Bookmark.Bookmarks() - call add(bookmarkStrings, i.name . ' ' . i.path.strForOS(0)) + call add(bookmarkStrings, i.name . ' ' . i.path.str()) endfor "add a blank line before the invalid ones @@ -420,24 +472,358 @@ function! s:Bookmark.Write() 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 ". self.key ." :call ". self.callback ."()" +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) + + "if a bookmark exists with the same name and the node is cached then save + "it so we can update its display string + let oldMarkedNode = {} try let oldMarkedNode = s:Bookmark.GetNodeForName(a:name, 1) - call oldMarkedNode.path.cacheDisplayString() catch /^NERDTree.BookmarkNotFoundError/ + catch /^NERDTree.BookmarkedNodeNotFoundError/ endtry call s:Bookmark.AddBookmark(a:name, self.path) call self.path.cacheDisplayString() call s:Bookmark.Write() + + if !empty(oldMarkedNode) + call oldMarkedNode.path.cacheDisplayString() + endif endfunction "FUNCTION: TreeFileNode.cacheParent() {{{3 "initializes self.parent if it isnt already @@ -489,83 +875,17 @@ function! s:TreeFileNode.delete() call self.parent.removeChild(self) 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) +"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 - -"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.strDisplay() - - 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 "FUNCTION: TreeFileNode.equals(treenode) {{{3 " "Compares this treenode to the input treenode and returns 1 if they are the @@ -577,7 +897,7 @@ endfunction "Args: "treenode: the other treenode to compare to function! s:TreeFileNode.equals(treenode) - return self.path.str(1) ==# a:treenode.path.str(1) + return self.path.str() ==# a:treenode.path.str() endfunction "FUNCTION: TreeFileNode.findNode(path) {{{3 @@ -667,11 +987,11 @@ function! s:TreeFileNode.getLineNum() let totalLines = line("$") "the path components we have matched so far - let pathcomponents = [substitute(b:NERDTreeRoot.path.str(0), '/ *$', '', '')] + 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(0) + let fullpath = self.path.str({'format': 'UI'}) let lnum = s:TreeFileNode.GetRootLineNum() @@ -705,11 +1025,19 @@ function! s:TreeFileNode.getLineNum() 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) !~ '^/' + while getline(rootLine) !~ '^\(/\|<\)' let rootLine = rootLine + 1 endwhile return rootLine @@ -758,7 +1086,7 @@ function! s:TreeFileNode.makeRoot() "change dir to the dir of the new root if instructed to if g:NERDTreeChDirMode ==# 2 - exec "cd " . b:NERDTreeRoot.path.strForEditCmd() + exec "cd " . b:NERDTreeRoot.path.str({'format': 'Edit'}) endif endfunction "FUNCTION: TreeFileNode.New(path) {{{3 @@ -770,7 +1098,6 @@ function! s:TreeFileNode.New(path) if a:path.isDirectory return s:TreeDirNode.New(a:path) else - let newTreeNode = {} let newTreeNode = copy(self) let newTreeNode.path = a:path let newTreeNode.parent = {} @@ -786,29 +1113,29 @@ endfunction "treenode: file node to open function! s:TreeFileNode.open() if b:NERDTreeType ==# "secondary" - exec 'edit ' . self.path.strForEditCmd() + 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.strForOS(0) . '$') + let winnr = bufwinnr('^' . self.path.str() . '$') if winnr != -1 call s:exec(winnr . "wincmd w") else - if !s:isWindowUsable(winnr("#")) && s:firstNormalWindow() ==# -1 + if !s:isWindowUsable(winnr("#")) && s:firstUsableWindow() ==# -1 call self.openSplit() else try if !s:isWindowUsable(winnr("#")) - call s:exec(s:firstNormalWindow() . "wincmd w") + call s:exec(s:firstUsableWindow() . "wincmd w") else call s:exec('wincmd p') endif - exec ("edit " . self.path.strForEditCmd()) + exec ("edit " . self.path.str({'format': 'Edit'})) catch /^Vim\%((\a\+)\)\=:E37/ call s:putCursorInTreeWin() - throw "NERDTree.FileAlreadyOpenAndModifiedError: ". self.path.str(0) ." is already open and modified." + throw "NERDTree.FileAlreadyOpenAndModifiedError: ". self.path.str() ." is already open and modified." catch /^Vim\%((\a\+)\)\=:/ echo v:exception endtry @@ -820,7 +1147,7 @@ endfunction function! s:TreeFileNode.openSplit() if b:NERDTreeType ==# "secondary" - exec "split " . self.path.strForEditCmd() + exec "split " . self.path.str({'format': 'Edit'}) return endif @@ -861,10 +1188,10 @@ function! s:TreeFileNode.openSplit() " Open the new window try - exec(splitMode." sp " . self.path.strForEditCmd()) + exec(splitMode." sp " . self.path.str({'format': 'Edit'})) catch /^Vim\%((\a\+)\)\=:E37/ call s:putCursorInTreeWin() - throw "NERDTree.FileAlreadyOpenAndModifiedError: ". self.path.str(0) ." is already open and modified." + throw "NERDTree.FileAlreadyOpenAndModifiedError: ". self.path.str() ." is already open and modified." catch /^Vim\%((\a\+)\)\=:/ "do nothing endtry @@ -885,7 +1212,7 @@ endfunction "Open this node in a new vertical window function! s:TreeFileNode.openVSplit() if b:NERDTreeType ==# "secondary" - exec "vnew " . self.path.strForEditCmd() + exec "vnew " . self.path.str({'format': 'Edit'}) return endif @@ -895,13 +1222,28 @@ function! s:TreeFileNode.openVSplit() endif call s:exec("wincmd p") - exec "vnew " . self.path.strForEditCmd() + 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 " @@ -940,7 +1282,7 @@ function! s:TreeFileNode.rename(newName) call self.path.rename(newName) call self.parent.removeChild(self) - let parentPath = self.path.getPathTrunk() + let parentPath = self.path.getParent() let newParent = b:NERDTreeRoot.findNode(parentPath) if newParent != {} @@ -948,17 +1290,83 @@ function! s:TreeFileNode.rename(newName) call newParent.refresh() endif endfunction -"FUNCTION: TreeFileNode.strDisplay() {{{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.strDisplay() - return self.path.strDisplay() +"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 @@ -974,6 +1382,13 @@ function! s:TreeDirNode.AbsoluteTreeRoot() 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 " @@ -1032,7 +1447,7 @@ function! s:TreeDirNode.findNode(path) if a:path.equals(self.path) return self endif - if stridx(a:path.str(1), self.path.str(1), 0) ==# -1 + if stridx(a:path.str(), self.path.str(), 0) ==# -1 return {} endif @@ -1061,7 +1476,7 @@ endfunction "Args: "path: a path object function! s:TreeDirNode.getChild(path) - if stridx(a:path.str(1), self.path.str(1), 0) ==# -1 + if stridx(a:path.str(), self.path.str(), 0) ==# -1 return {} endif @@ -1097,7 +1512,7 @@ endfunction "Args: "path: a path object function! s:TreeDirNode.getChildIndex(path) - if stridx(a:path.str(1), self.path.str(1), 0) ==# -1 + if stridx(a:path.str(), self.path.str(), 0) ==# -1 return -1 endif @@ -1173,7 +1588,8 @@ function! s:TreeDirNode._initChildren(silent) "get an array of all the files in the nodes dir let dir = self.path - let filesStr = globpath(dir.strForGlob(), '*') . "\n" . globpath(dir.strForGlob(), '.*') + 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 @@ -1186,7 +1602,7 @@ function! s:TreeDirNode._initChildren(silent) "filter out the .. and . directories "Note: we must match .. AND ../ cos sometimes the globpath returns "../ for path with strange chars (eg $) - if i !~ '\.\.\/\?$' && i !~ '\.\/\?$' + if i !~ '\/\.\.\/\?$' && i !~ '\/\.\/\?$' "put the next file in a new node and attach it try @@ -1254,7 +1670,23 @@ function! s:TreeDirNode.openExplorer() call s:exec('wincmd p') call self.openSplit() else - exec ("silent edit " . self.path.strForEditCmd()) + 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 @@ -1300,10 +1732,14 @@ function! s:TreeDirNode.refresh() let newChildNodes = [] let invalidFilesFound = 0 let dir = self.path - let filesStr = globpath(dir.strForGlob(), '*') . "\n" . globpath(dir.strForGlob(), '.*') + let globDir = dir.str({'format': 'Glob'}) + let filesStr = globpath(globDir, '*') . "\n" . globpath(globDir, '.*') let files = split(filesStr, "\n") for i in files - if i !~ '\.\.$' && i !~ '\.$' + "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 @@ -1337,6 +1773,31 @@ function! s:TreeDirNode.refresh() 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 @@ -1407,7 +1868,7 @@ function! s:Path.AbsolutePathFor(str) let toReturn = a:str if prependCWD - let toReturn = getcwd() . s:os_slash . a:str + let toReturn = getcwd() . s:Path.Slash() . a:str endif return toReturn @@ -1447,9 +1908,9 @@ function! s:Path.cacheDisplayString() endfunction "FUNCTION: Path.changeToDir() {{{3 function! s:Path.changeToDir() - let dir = self.strForCd() + let dir = self.str({'format': 'Cd'}) if self.isDirectory ==# 0 - let dir = self.getPathTrunk().strForCd() + let dir = self.getParent().str({'format': 'Cd'}) endif try @@ -1549,10 +2010,10 @@ function! s:Path.copy(dest) let dest = s:Path.WinToUnixPath(a:dest) - let cmd = g:NERDTreeCopyCmd . " " . self.strForOS(0) . " " . dest + let cmd = g:NERDTreeCopyCmd . " " . self.str() . " " . dest let success = system(cmd) if success != 0 - throw "NERDTree.CopyError: Could not copy ''". self.strForOS(0) ."'' to: '" . a:dest . "'" + throw "NERDTree.CopyError: Could not copy ''". self.str() ."'' to: '" . a:dest . "'" endif endfunction @@ -1593,22 +2054,16 @@ endfunction function! s:Path.delete() if self.isDirectory - let cmd = "" - if s:running_windows - "if we are runnnig windows then put quotes around the pathstring - let cmd = g:NERDTreeRemoveDirCmd . self.strForOS(1) - else - let cmd = g:NERDTreeRemoveDirCmd . self.strForOS(1) - endif + 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.strForOS(0) . "'" + throw "NERDTree.PathDeletionError: Could not delete directory: '" . self.str() . "'" endif else - let success = delete(self.strForOS(0)) + let success = delete(self.str()) if success != 0 - throw "NERDTree.PathDeletionError: Could not delete file: '" . self.str(0) . "'" + throw "NERDTree.PathDeletionError: Could not delete file: '" . self.str() . "'" endif endif @@ -1619,6 +2074,17 @@ function! s:Path.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 @@ -1633,7 +2099,8 @@ 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() - return filereadable(self.strForOS(0)) || isdirectory(self.strForOS(0)) + let p = self.str() + return filereadable(p) || isdirectory(p) endfunction "FUNCTION: Path.getDir() {{{3 " @@ -1655,7 +2122,12 @@ endfunction "Return: "a new Path object function! s:Path.getParent() - let path = '/'. join(self.pathSegments[0:-2], '/') + 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 @@ -1676,12 +2148,6 @@ function! s:Path.getLastPathComponent(dirSlash) return toReturn endfunction -"FUNCTION: Path.getPathTrunk() {{{3 -"Gets the path without the last segment on the end. -function! s:Path.getPathTrunk() - return s:Path.New(self.strTrunk()) -endfunction - "FUNCTION: Path.getSortOrderIndex() {{{3 "returns the index of the pattern in g:NERDTreeSortOrder that this path matches function! s:Path.getSortOrderIndex() @@ -1721,6 +2187,20 @@ function! s:Path.ignore() 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 = [] @@ -1738,7 +2218,7 @@ endfunction "Args: "path: the other path obj to compare this with function! s:Path.equals(path) - return self.str(0) ==# a:path.str(0) + return self.str() ==# a:path.str() endfunction "FUNCTION: Path.New() {{{3 @@ -1753,6 +2233,12 @@ function! s:Path.New(path) 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 " " @@ -1809,7 +2295,7 @@ endfunction "FUNCTION: Path.refresh() {{{3 function! s:Path.refresh() - call self.readInfoFromDisk(self.strForOS(0)) + call self.readInfoFromDisk(self.str()) call self.cacheDisplayString() endfunction @@ -1821,9 +2307,9 @@ function! s:Path.rename(newPath) throw "NERDTree.InvalidArgumentsError: Invalid newPath for renaming = ". a:newPath endif - let success = rename(self.strForOS(0), a:newPath) + let success = rename(self.str(), a:newPath) if success != 0 - throw "NERDTree.PathRenameError: Could not rename: '" . self.strForOS(0) . "'" . 'to:' . a:newPath + throw "NERDTree.PathRenameError: Could not rename: '" . self.str() . "'" . 'to:' . a:newPath endif call self.readInfoFromDisk(a:newPath) @@ -1834,76 +2320,88 @@ function! s:Path.rename(newPath) call s:Bookmark.Write() endfunction -"FUNCTION: Path.str(esc) {{{3 +"FUNCTION: Path.str() {{{3 " -"Gets the actual string path that this obj represents. +"Returns a string representation of this Path " -"Args: -"esc: if 1 then all the tricky chars in the returned string will be escaped -function! s:Path.str(esc) +"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 - - if a:esc - let toReturn = escape(toReturn, s:escape_chars) - endif return toReturn endfunction -"FUNCTION: Path.strAbs() {{{3 -" -"Returns a string representing this path with all the symlinks resolved -" -"Return: -"string -function! s:Path.strAbs() - return resolve(self.str(1)) -endfunction - -"FUNCTION: Path.strForCd() {{{3 +"FUNCTION: Path._strForCd() {{{3 " " returns a string that can be used with :cd -" -"Return: -"a string that can be used in the view to represent this path -function! s:Path.strForCd() - if s:running_windows - return self.strForOS(0) - else - return self.strForOS(1) - endif +function! s:Path._strForCd() + return escape(self.str(), s:escape_chars) endfunction -"FUNCTION: Path.strDisplay() {{{3 -" -"Returns a string that specifies how the path should be represented as a -"string -" -"Return: -"a string that can be used in the view to represent this path -function! s:Path.strDisplay() - if self.cachedDisplayString ==# "" - call self.cacheDisplayString() - endif - - return self.cachedDisplayString -endfunction - -"FUNCTION: Path.strForEditCmd() {{{3 +"FUNCTION: Path._strForEdit() {{{3 " "Return: the string for this path that is suitable to be used with the :edit "command -function! s:Path.strForEditCmd() - let p = self.str(1) +function! s:Path._strForEdit() + let p = self.str({'format': 'UI'}) let cwd = getcwd() if s:running_windows - let p = tolower(self.strForOS(0)) + let p = tolower(self.str()) let cwd = tolower(getcwd()) endif - let cwd = cwd . s:os_slash + 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 @@ -1917,49 +2415,36 @@ function! s:Path.strForEditCmd() return p endfunction -"FUNCTION: Path.strForGlob() {{{3 -function! s:Path.strForGlob() - let lead = s:os_slash +"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:os_slash) + 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.strForOS(esc) {{{3 +"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 -" -"Args: -"esc: if 1 then all the tricky chars in the returned string will be -" escaped. If we are running windows then the str is double quoted instead. -function! s:Path.strForOS(esc) - let lead = s:os_slash +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 - let toReturn = lead . join(self.pathSegments, s:os_slash) - - if a:esc - if s:running_windows - let toReturn = '"' . toReturn . '"' - else - let toReturn = escape(toReturn, s:escape_chars) - endif - endif - return toReturn + return lead . join(self.pathSegments, s:Path.Slash()) endfunction "FUNCTION: Path.strTrunk() {{{3 @@ -2042,6 +2527,29 @@ function! s:exec(cmd) 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 @@ -2057,7 +2565,7 @@ function! s:initNerdTree(name) "hack to get an absolute path if a relative path is given if dir =~ '^\.' - let dir = getcwd() . s:os_slash . dir + let dir = getcwd() . s:Path.Slash() . dir endif let dir = resolve(dir) @@ -2075,7 +2583,7 @@ function! s:initNerdTree(name) "if instructed to, then change the vim CWD to the dir the NERDTree is "inited in if g:NERDTreeChDirMode != 0 - exec 'cd ' . path.strForCd() + call path.changeToDir() endif if s:treeExistsForTab() @@ -2158,7 +2666,7 @@ function! s:initNerdTreeInPlace(dir) call s:bindMappings() setfiletype nerdtree " syntax highlighting - if has("syntax") && exists("g:syntax_on") && !has("syntax_items") + if has("syntax") && exists("g:syntax_on") call s:setupSyntaxHighlighting() endif @@ -2184,7 +2692,7 @@ function! s:initNerdTreeMirror() while i < len(treeBufNames) let bufName = treeBufNames[i] let treeRoot = getbufvar(bufName, "NERDTreeRoot") - let options[i+1 . '. ' . treeRoot.path.strForOS(0) . ' (buf name: ' . bufName . ')'] = bufName + let options[i+1 . '. ' . treeRoot.path.str() . ' (buf name: ' . bufName . ')'] = bufName let i = i + 1 endwhile @@ -2198,7 +2706,7 @@ function! s:initNerdTreeMirror() return endif - let bufferName = options[keys(options)[choice-1]] + let bufferName = options[sort(keys(options))[choice-1]] elseif len(keys(options)) ==# 1 let bufferName = values(options)[0] else @@ -2262,45 +2770,32 @@ function! s:unique(list) endfor return uniqlist endfunction -" SECTION: Public Functions {{{1 +" SECTION: Public API {{{1 "============================================================ -"Returns the node that the cursor is currently on. -" -"If the cursor is not in the NERDTree window, it is temporarily put there. -" -"If no NERD tree window exists for the current tab, a NERDTree.NoTreeForTab -"exception is thrown. -" -"If the cursor is not on a node then an empty dictionary {} is returned. -function! NERDTreeGetCurrentNode() - if !s:treeExistsForTab() || !s:isTreeOpen() - throw "NERDTree.NoTreeForTabError: there is no NERD tree open for the current tab" - endif +let g:NERDTreePath = s:Path +let g:NERDTreeDirNode = s:TreeDirNode +let g:NERDTreeFileNode = s:TreeFileNode +let g:NERDTreeBookmark = s:Bookmark - let winnr = winnr() - if winnr != s:getTreeWinNum() - call s:putCursorInTreeWin() - endif - - let treenode = s:TreeFileNode.GetSelected() - - if winnr != winnr() - call s:exec('wincmd w') - endif - - return treenode +function! NERDTreeAddMenuItem(options) + call s:MenuItem.Create(a:options) endfunction -"Returns the path object for the current node. -" -"Subject to the same conditions as NERDTreeGetCurrentNode -function! NERDTreeGetCurrentPath() - let node = NERDTreeGetCurrentNode() - if node != {} - return node.path - else - return {} - endif +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 @@ -2319,18 +2814,26 @@ function! s:centerView() endif endfunction "FUNCTION: s:closeTree() {{{2 -"Closes the NERD tree window +"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 + if winnr() == s:getTreeWinNum() + wincmd p + let bufnr = bufnr("") + wincmd p + else + let bufnr = bufnr("") + endif + call s:exec(s:getTreeWinNum() . " wincmd w") close - call s:exec("wincmd p") + call s:exec(bufwinnr(bufnr) . " wincmd w") else - :q + close endif endfunction @@ -2344,7 +2847,7 @@ endfunction "FUNCTION: s:closeTreeIfQuitOnOpen() {{{2 "Closes the NERD tree window if the close on open option is set function! s:closeTreeIfQuitOnOpen() - if g:NERDTreeQuitOnOpen + if g:NERDTreeQuitOnOpen && s:isTreeOpen() call s:closeTree() endif endfunction @@ -2355,12 +2858,13 @@ function! s:createTreeWin() "create the nerd tree window let splitLocation = g:NERDTreeWinPos ==# "left" ? "topleft " : "botright " let splitSize = g:NERDTreeWinSize - silent! exec splitLocation . 'vertical ' . splitSize . ' new' 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 @@ -2390,7 +2894,7 @@ function! s:createTreeWin() call s:bindMappings() setfiletype nerdtree " syntax highlighting - if has("syntax") && exists("g:syntax_on") && !has("syntax_items") + if has("syntax") && exists("g:syntax_on") call s:setupSyntaxHighlighting() endif endfunction @@ -2404,6 +2908,7 @@ function! s:dumpHelp() let @h=@h."\" ============================\n" let @h=@h."\" File node mappings~\n" let @h=@h."\" ". (g:NERDTreeMouseMode ==# 3 ? "single" : "double") ."-click,\n" + let @h=@h."\" ,\n" if b:NERDTreeType ==# "primary" let @h=@h."\" ". g:NERDTreeMapActivateNode .": open in prev window\n" else @@ -2419,7 +2924,6 @@ function! s:dumpHelp() 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."\" ". g:NERDTreeMapExecute.": Execute file\n" let @h=@h."\"\n\" ----------------------------\n" let @h=@h."\" Directory node mappings~\n" @@ -2458,7 +2962,7 @@ function! s:dumpHelp() 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:NERDTreeMapFilesystemMenu .": Show filesystem menu\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" @@ -2469,9 +2973,20 @@ function! s:dumpHelp() 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" @@ -2516,14 +3031,15 @@ function! s:echoError(msg) call s:echo(a:msg) echohl normal endfunction -"FUNCTION: s:firstNormalWindow(){{{2 +"FUNCTION: s:firstUsableWindow(){{{2 "find the window number of the first normal window -function! s:firstNormalWindow() +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 @@ -2544,8 +3060,10 @@ endfunction function! s:getPath(ln) let line = getline(a:ln) + let rootLine = s:TreeFileNode.GetRootLineNum() + "check to see if we have the root node - if line =~ '^\/' + if a:ln == rootLine return b:NERDTreeRoot.path endif @@ -2569,7 +3087,6 @@ function! s:getPath(ln) let curFile = substitute(curFile, '/\?$', '/', "") endif - let dir = "" let lnum = a:ln while lnum > 0 @@ -2578,8 +3095,8 @@ function! s:getPath(ln) let curLineStripped = s:stripMarkupFromLine(curLine, 1) "have we reached the top of the tree? - if curLine =~ '^/' - let dir = substitute (curLine, ' *$', "", "") . dir + if lnum == rootLine + let dir = b:NERDTreeRoot.path.str({'format': 'UI'}) . dir break endif if curLineStripped =~ '/$' @@ -2597,21 +3114,6 @@ function! s:getPath(ln) return toReturn endfunction -"FUNCTION: s:getSelectedBookmark() {{{2 -"returns the bookmark the cursor is over in the bookmarks table or {} -function! s:getSelectedBookmark() - 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: s:getTreeWinNum() {{{2 "gets the nerd tree window number for this tab function! s:getTreeWinNum() @@ -2630,8 +3132,8 @@ function! s:isTreeOpen() return s:getTreeWinNum() != -1 endfunction "FUNCTION: s:isWindowUsable(winnumber) {{{2 -"Returns 1 if opening a file from the tree in the given window requires it to -"be split +"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 @@ -2778,7 +3280,8 @@ function! s:renderView() call cursor(line(".")+1, col(".")) "draw the header line - call setline(line(".")+1, b:NERDTreeRoot.path.str(0)) + let header = b:NERDTreeRoot.path.str({'format': 'UI', 'truncateTo': winwidth(0)}) + call setline(line(".")+1, header) call cursor(line(".")+1, col(".")) "draw the tree @@ -2999,10 +3502,10 @@ function! s:toggle(dir) if s:treeExistsForTab() if !s:isTreeOpen() call s:createTreeWin() - call s:restoreScreenState() if !&hidden call s:renderView() endif + call s:restoreScreenState() else call s:closeTree() endif @@ -3025,26 +3528,11 @@ function! s:activateNode(forceKeepWindowOpen) let treenode = s:TreeFileNode.GetSelected() if treenode != {} - if treenode.path.isDirectory - call treenode.toggleOpen() - call s:renderView() - call treenode.putCursorHere(0, 0) - else - call treenode.open() - if !a:forceKeepWindowOpen - call s:closeTreeIfQuitOnOpen() - end - endif + call treenode.activate(a:forceKeepWindowOpen) else - let bookmark = s:getSelectedBookmark() + let bookmark = s:Bookmark.GetSelected() if !empty(bookmark) - if bookmark.path.isDirectory - call bookmark.toRoot() - else - if bookmark.validate() - call (s:TreeFileNode.New(bookmark.path)).open() - endif - endif + call bookmark.activate() endif endif endfunction @@ -3058,6 +3546,7 @@ function! s:bindMappings() exec "nnoremap ". g:NERDTreeMapActivateNode . " :call activateNode(0)" exec "nnoremap ". g:NERDTreeMapOpenSplit ." :call openEntrySplit(0,0)" + exec "nnoremap :call activateNode(0)" exec "nnoremap ". g:NERDTreeMapPreview ." :call previewNode(0)" exec "nnoremap ". g:NERDTreeMapPreviewSplit ." :call previewNode(1)" @@ -3065,8 +3554,6 @@ function! s:bindMappings() exec "nnoremap ". g:NERDTreeMapOpenVSplit ." :call openEntrySplit(1,0)" exec "nnoremap ". g:NERDTreeMapPreviewVSplit ." :call previewNode(2)" - exec "nnoremap ". g:NERDTreeMapExecute ." :call executeNode()" - exec "nnoremap ". g:NERDTreeMapOpenRecursively ." :call openNodeRecursively()" exec "nnoremap ". g:NERDTreeMapUpdirKeepOpen ." :call upDir(1)" @@ -3081,6 +3568,7 @@ function! s:bindMappings() exec "nnoremap ". g:NERDTreeMapRefresh ." :call refreshCurrent()" exec "nnoremap ". g:NERDTreeMapHelp ." :call displayHelp()" + exec "nnoremap ". g:NERDTreeMapToggleZoom ." :call toggleZoom()" exec "nnoremap ". g:NERDTreeMapToggleHidden ." :call toggleShowHidden()" exec "nnoremap ". g:NERDTreeMapToggleFilters ." :call toggleIgnoreFilter()" exec "nnoremap ". g:NERDTreeMapToggleFiles ." :call toggleShowFiles()" @@ -3089,7 +3577,7 @@ function! s:bindMappings() exec "nnoremap ". g:NERDTreeMapCloseDir ." :call closeCurrentDir()" exec "nnoremap ". g:NERDTreeMapCloseChildren ." :call closeChildren()" - exec "nnoremap ". g:NERDTreeMapFilesystemMenu ." :call showFileSystemMenu()" + exec "nnoremap ". g:NERDTreeMapMenu ." :call showMenu()" exec "nnoremap ". g:NERDTreeMapJumpParent ." :call jumpToParent()" exec "nnoremap ". g:NERDTreeMapJumpNextSibling ." :call jumpToSibling(1)" @@ -3105,6 +3593,9 @@ function! s:bindMappings() exec "nnoremap ". g:NERDTreeMapDeleteBookmark ." :call deleteBookmark()" + "bind all the user custom maps + call s:KeyMap.BindAll() + command! -buffer -nargs=1 Bookmark :call bookmarkNode('') command! -buffer -complete=customlist,s:completeBookmarks -nargs=1 RevealBookmark :call revealBookmark('') command! -buffer -complete=customlist,s:completeBookmarks -nargs=1 OpenBookmark :call openBookmark('') @@ -3225,7 +3716,7 @@ function! s:closeCurrentDir() endif let parent = treenode.parent - if parent.isRoot() + if parent ==# {} || parent.isRoot() call s:echo("cannot close tree root") else call treenode.parent.close() @@ -3240,55 +3731,16 @@ function! s:closeTreeWindow() exec "buffer " . b:NERDTreePreviousBuf else if winnr("$") > 1 - wincmd c + call s:closeTree() else call s:echo("Cannot close last window") endif endif endfunction -" FUNCTION: s:copyNode() {{{2 -function! s:copyNode() - let currentNode = s:TreeFileNode.GetSelected() - if currentNode ==# {} - call s:echo("Put the cursor on a file node first") - return - endif - - let newNodePath = input("Copy the current node\n" . - \ "==========================================================\n" . - \ "Enter the new path to copy the node to: \n" . - \ "", currentNode.path.str(0)) - - if newNodePath != "" - "strip trailing slash - let newNodePath = substitute(newNodePath, '\/$', '', '') - - let confirmed = 1 - if currentNode.path.copyingWillOverwrite(newNodePath) - call s:echo("\nWarning: copying may overwrite files! Continue? (yN)") - let choice = nr2char(getchar()) - let confirmed = choice ==# 'y' - endif - - if confirmed - try - let newNode = currentNode.copy(newNodePath) - call s:renderView() - call newNode.putCursorHere(0, 0) - catch /^NERDTree/ - call s:echoWarning("Could not copy node") - endtry - endif - else - call s:echo("Copy aborted.") - endif - redraw -endfunction - " FUNCTION: s:deleteBookmark() {{{2 " if the cursor is on a bookmark, prompt to delete function! s:deleteBookmark() - let bookmark = s:getSelectedBookmark() + let bookmark = s:Bookmark.GetSelected() if bookmark ==# {} call s:echo("Put the cursor on a bookmark") return @@ -3310,57 +3762,6 @@ function! s:deleteBookmark() endfunction -" FUNCTION: s:deleteNode() {{{2 -" if the current node is a file, pops up a dialog giving the user the option -" to delete it -function! s:deleteNode() - let currentNode = s:TreeFileNode.GetSelected() - if currentNode ==# {} - call s:echo("Put the cursor on a file node first") - return - endif - - let confirmed = 0 - - if currentNode.path.isDirectory - let choice =input("Delete the current node\n" . - \ "==========================================================\n" . - \ "STOP! To delete this entire directory, type 'yes'\n" . - \ "" . currentNode.path.strForOS(0) . ": ") - let confirmed = choice ==# 'yes' - else - echo "Delete the current node\n" . - \ "==========================================================\n". - \ "Are you sure you wish to delete the node:\n" . - \ "" . currentNode.path.strForOS(0) . " (yN):" - let choice = nr2char(getchar()) - let confirmed = choice ==# 'y' - endif - - - if confirmed - try - call currentNode.delete() - call s:renderView() - - "if the node is open in a buffer, ask the user if they want to - "close that buffer - let bufnum = bufnr(currentNode.path.str(0)) - if buflisted(bufnum) - let prompt = "\nNode deleted.\n\nThe file is open in buffer ". bufnum . (bufwinnr(bufnum) ==# -1 ? " (hidden)" : "") .". Delete this buffer? (yN)" - call s:promptToDelBuffer(bufnum, prompt) - endif - - redraw - catch /^NERDTree/ - call s:echoWarning("Could not remove node") - endtry - else - call s:echo("delete aborted" ) - endif - -endfunction - " FUNCTION: s:displayHelp() {{{2 " toggles the help display function! s:displayHelp() @@ -3369,26 +3770,6 @@ function! s:displayHelp() call s:centerView() endfunction -" FUNCTION: s:executeNode() {{{2 -function! s:executeNode() - let treenode = s:TreeFileNode.GetSelected() - if treenode ==# {} || treenode.path.isDirectory - call s:echo("Select an executable file node first" ) - else - echo "NERDTree executor\n" . - \ "==========================================================\n". - \ "Complete the command to execute (add arguments etc): \n\n" - let cmd = treenode.path.strForOS(1) - let cmd = input(':!', cmd . ' ') - - if cmd != '' - exec ':!' . cmd - else - call s:echo("command aborted") - endif - endif -endfunction - " FUNCTION: s:handleMiddleMouse() {{{2 function! s:handleMiddleMouse() let curNode = s:TreeFileNode.GetSelected() @@ -3405,40 +3786,6 @@ function! s:handleMiddleMouse() endfunction -" FUNCTION: s:insertNewNode() {{{2 -" Adds a new node to the filesystem and then into the tree -function! s:insertNewNode() - let curDirNode = s:TreeDirNode.GetSelected() - if curDirNode ==# {} - call s:echo("Put the cursor on a node first" ) - return - endif - - let newNodeName = input("Add a childnode\n". - \ "==========================================================\n". - \ "Enter the dir/file name to be created. Dirs end with a '/'\n" . - \ "", curDirNode.path.strForGlob() . s:os_slash) - - if newNodeName ==# '' - call s:echo("Node Creation Aborted.") - return - endif - - try - let newPath = s:Path.Create(newNodeName) - let parentNode = b:NERDTreeRoot.findNode(newPath.getPathTrunk()) - - let newTreeNode = s:TreeFileNode.New(newPath) - if parentNode.isOpen || !empty(parentNode.children) - call parentNode.addChild(newTreeNode, 1) - call s:renderView() - call newTreeNode.putCursorHere(1, 0) - endif - catch /^NERDTree/ - call s:echoWarning("Node Not Created.") - endtry -endfunction - " FUNCTION: s:jumpToFirstChild() {{{2 " wrapper for the jump to child method function! s:jumpToFirstChild() @@ -3550,29 +3897,13 @@ endfunction " 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 currentTab = tabpagenr() - - let treenode = s:TreeFileNode.GetSelected() - if treenode != {} - if treenode.path.isDirectory - tabnew - call s:initNerdTree(treenode.path.strForOS(0)) - else - exec "tabedit " . treenode.path.strForEditCmd() - endif - else - let bookmark = s:getSelectedBookmark() - if bookmark != {} - if bookmark.path.isDirectory - tabnew - call s:initNerdTree(bookmark.name) - else - exec "tabedit " . bookmark.path.strForEditCmd() - endif - endif + let target = s:TreeFileNode.GetSelected() + if target == {} + let target = s:Bookmark.GetSelected() endif - if a:stayCurrentTab - exec "tabnext " . currentTab + + if target != {} + call target.openInNewTab({'stayInCurrentTab': a:stayCurrentTab}) endif endfunction @@ -3641,80 +3972,16 @@ function! s:refreshCurrent() redraw call s:echo("Refreshing node. This could take a while... DONE") endfunction -" FUNCTION: s:renameCurrent() {{{2 -" allows the user to rename the current node -function! s:renameCurrent() +" 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 newNodePath = input("Rename the current node\n" . - \ "==========================================================\n" . - \ "Enter the new path for the node: \n" . - \ "", curNode.path.strForOS(0)) - - if newNodePath ==# '' - call s:echo("Node Renaming Aborted.") - return - endif - - try - let bufnum = bufnr(curNode.path.str(0)) - - call curNode.rename(newNodePath) - call s:renderView() - - "if the node is open in a buffer, ask the user if they want to - "close that buffer - if bufnum != -1 - let prompt = "\nNode renamed.\n\nThe old file is open in buffer ". bufnum . (bufwinnr(bufnum) ==# -1 ? " (hidden)" : "") .". Delete this buffer? (yN)" - call s:promptToDelBuffer(bufnum, prompt) - endif - - call curNode.putCursorHere(1, 0) - - redraw - catch /^NERDTree/ - call s:echoWarning("Node Not Renamed.") - endtry -endfunction - -" FUNCTION: s:showFileSystemMenu() {{{2 -function! s:showFileSystemMenu() - let curNode = s:TreeFileNode.GetSelected() - if curNode ==# {} - call s:echo("Put the cursor on a node first" ) - return - endif - - - let prompt = "NERDTree Filesystem Menu\n" . - \ "==========================================================\n". - \ "Select the desired operation: \n" . - \ " (a)dd a childnode\n". - \ " (m)ove the current node\n". - \ " (d)elete the current node\n" - if s:Path.CopyingSupported() - let prompt = prompt . " (c)opy the current node\n\n" - else - let prompt = prompt . " \n" - endif - - echo prompt - - let choice = nr2char(getchar()) - - if choice ==? "a" - call s:insertNewNode() - elseif choice ==? "m" - call s:renameCurrent() - elseif choice ==? "d" - call s:deleteNode() - elseif choice ==? "c" && s:Path.CopyingSupported() - call s:copyNode() - endif + let mc = s:MenuController.New(s:MenuItem.AllEnabled()) + call mc.showMenu() endfunction " FUNCTION: s:toggleIgnoreFilter() {{{2 @@ -3753,6 +4020,19 @@ function! s:toggleShowHidden() 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 " @@ -3760,7 +4040,7 @@ endfunction "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(0) + let cwd = b:NERDTreeRoot.path.str({'format': 'UI'}) if cwd ==# "/" || cwd =~ '^[^/]..$' call s:echo("already at top dir") else @@ -3771,7 +4051,7 @@ function! s:upDir(keepState) let oldRoot = b:NERDTreeRoot if empty(b:NERDTreeRoot.parent) - let path = b:NERDTreeRoot.path.getPathTrunk() + let path = b:NERDTreeRoot.path.getParent() let newRoot = s:TreeDirNode.New(path) call newRoot.open() call newRoot.transplantChild(b:NERDTreeRoot) @@ -3781,7 +4061,7 @@ function! s:upDir(keepState) endif if g:NERDTreeChDirMode ==# 2 - exec 'cd ' . b:NERDTreeRoot.path.strForCd() + call b:NERDTreeRoot.path.changeToDir() endif call s:renderView()