commit 7886c38f33699ba5af22737cb595680418e604ed Author: Thomas Ruoff Date: Mon Aug 31 09:35:47 2009 +0200 initial commit diff --git a/create_symlinks.py b/create_symlinks.py new file mode 100755 index 0000000..3df7859 --- /dev/null +++ b/create_symlinks.py @@ -0,0 +1,86 @@ +#!/usr/bin/env python +import os +import logging + + +logging.basicConfig(level=logging.WARN) + +home = os.path.abspath(os.environ['HOME']) +path = os.path.join(home, '.dotfiles') +excludes = ['create_symlinks.py', 'delete_symlinks.py'] + +""" + Recursivly create symbolic links for all files found beneath src_path to + dst_path. The directory structure will be created as needed. + +""" +def symlink_rec(src_path, dst_path): + logging.debug("symlink_rec called with %s and %s" % + (src_path, dst_path)) + if not os.path.isdir(src_path): + raise Exception + for f in os.listdir(src_path): + if f.startswith('.'): + continue + if f not in excludes: + n_src_path = os.path.join(src_path, f) + if os.path.isdir(n_src_path): + logging.debug("Go down into %s" % (n_src_path)) + n_dst_path = os.path.join(dst_path, f) + if not os.path.exists(n_dst_path): + try: + logging.warn("Make directory %s" % (n_dst_path)) + os.mkdir(n_dst_path) + except Exception, msg: + logging.error("Failed creating directory %s" % + (n_dst_path)) + logging.error(msg) + return # abort or lower levels might fail too + symlink_rec(n_src_path, n_dst_path) + logging.debug("Finished directory %s" % (n_src_path)) + elif os.path.isfile(n_src_path): + n_dst_path = os.path.join(dst_path, f) + try: + logging.warn("Symlinking %s to %s" % + (n_src_path, n_dst_path)) + os.symlink(n_src_path, n_dst_path) + except Exception, msg: + logging.error("Failed to symlink %s to %s " % + (n_src_path, n_dst_path)) + logging.error(msg) + + +""" + Create symbolic links from files in to with '.'-prefixed. + For directories in will be '.'-prefixed created in if + needed and symlink_rec is called on them. + +""" +for f in os.listdir(path): + print f + if f.startswith('.'): + continue + if f not in excludes: + src_path = os.path.join(path, f) + if os.path.isdir(src_path): + logging.debug("Go down into %s" % (src_path)) + dst_path = os.path.join(home, '.' + f) + if not os.path.exists(dst_path): + try: + logging.warn("Make directory %s" % (dst_path)) + os.mkdir(dst_path) + except Exception, msg: + logging.error("Failed creating directory %s" % + (dst_path)) + logging.error(msg) + symlink_rec(src_path, dst_path) + logging.debug("Finished directory %s" % (src_path)) + elif os.path.isfile(src_path): + dst_path = os.path.join(home, '.' + f) + try: + logging.warn("Symlinking %s to %s" % (src_path, dst_path)) + os.symlink(src_path, dst_path) + except Exception, msg: + logging.error("Failed to symlink %s to %s " % + (src_path, dst_path)) + logging.error(msg) diff --git a/delete_symlinks.py b/delete_symlinks.py new file mode 100755 index 0000000..3db7917 --- /dev/null +++ b/delete_symlinks.py @@ -0,0 +1,85 @@ +#!/usr/bin/env python +import os +import logging + + +logging.basicConfig(level=logging.WARN) + +home = os.path.abspath(os.environ['HOME']) +path = os.path.join(home, '.dotfiles') +excludes = ['create_symlinks.py', 'delete_symlinks.py'] + +""" + Recursivly delte symbolic links for all files found beneath src_path to + dst_path. + +""" +def symlink_rec(src_path, dst_path): + logging.debug("symlink_rec called with %s and %s" % + (src_path, dst_path)) + if not os.path.isdir(src_path): + raise Exception + for f in os.listdir(src_path): + if f.startswith('.'): + continue + if f not in excludes: + n_src_path = os.path.join(src_path, f) + if os.path.isdir(n_src_path): + n_dst_path = os.path.join(dst_path, f) + if not os.path.exists(n_dst_path): + #nothing to do here + continue + logging.debug("Go down into %s" % (n_src_path)) + symlink_rec(n_src_path, n_dst_path) + logging.debug("Finished directory %s" % (n_src_path)) + elif os.path.isfile(n_src_path): + n_dst_path = os.path.join(dst_path, f) + try: + if not os.path.islink(n_dst_path): + loggin.warn("Won't delete %s, not a symbolic link" + % n_dst_path) + continue + logging.warn("Removing symbolic link %s" % + (n_dst_path)) + os.remove(n_dst_path) + except Exception, msg: + logging.error("Failed to delete symlink %s" % + (n_dst_path)) + logging.error(msg) + + +""" + Remove symbolic links from files in to with '.'-prefixed. + For directories in the '.'-prefixed name will be searched in + for further symbolic links to delete. + +""" + +print "Do you really want to delete all symbolic links in %s to the files in %s ? (YES,No)" % (home, path) + +for f in os.listdir(path): + print f + if f.startswith('.'): + continue + if f not in excludes: + src_path = os.path.join(path, f) + if os.path.isdir(src_path): + logging.debug("Go down into %s" % (src_path)) + dst_path = os.path.join(home, '.' + f) + if not os.path.exists(dst_path): + #nothing to delete in here + continue + symlink_rec(src_path, dst_path) + logging.debug("Finished directory %s" % (src_path)) + elif os.path.isfile(src_path): + dst_path = os.path.join(home, '.' + f) + if not os.path.islink(dst_path): + logging.warn("Won't remove %s. Is not a symbolic link") + continue + try: + logging.warn("Remove %s" % (dst_path)) + os.remove(dst_path) + except Exception, msg: + logging.error("Failed to remove %s to %s " % + (src_path, dst_path)) + logging.error(msg) diff --git a/gitconfig b/gitconfig new file mode 100644 index 0000000..6eac049 --- /dev/null +++ b/gitconfig @@ -0,0 +1,8 @@ +[user] + name = Thomas Ruoff + email = ThomasRuoff@gmail.com +[color] + branch = auto + diff = auto + interactive = auto + status = auto diff --git a/vim/doc/NERD_tree.txt b/vim/doc/NERD_tree.txt new file mode 100644 index 0000000..5e6c109 --- /dev/null +++ b/vim/doc/NERD_tree.txt @@ -0,0 +1,1227 @@ +*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 filesystem menu...............|NERDTreeFilesysMenu| + 3.Options.................................|NERDTreeOptions| + 3.1 Option summary....................|NERDTreeOptionSummary| + 3.2 Option details....................|NERDTreeOptionDetails| + 4.Public functions........................|NERDTreePublicFunctions| + 5.TODO list...............................|NERDTreeTodo| + 6.The Author..............................|NERDTreeAuthor| + 7.Changelog...............................|NERDTreeChangelog| + 8.Credits.................................|NERDTreeCredits| + 9.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 + * Dynamic customisation of tree content + * 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 + * A textual filesystem menu is provided which allows you to + create/delete/move file and directory nodes as well as copy (for + supported OSs) + * 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 + +============================================================================== +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. + +:NERDTreeClose + Close the NERD tree in this tab. + +------------------------------------------------------------------------------ +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| +...Open selected file in a split window.....................|NERDTree-tab| +g..Same as , but leave the cursor on the NERDTree......|NERDTree-gtab| +!.......Execute the current file.................................|NERDTree-!| +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.......Open a netrw for the current dir.........................|NERDTree-e| + +double-click.......same as the |NERDTree-o| map. +middle-click.......same as |NERDTree-tab| 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 filesystem menu..............................|NERDTree-m| +cd......Change the CWD to the dir of the selected node...........|NERDTree-cd| + +H.......Toggle whether hidden files displayed....................|NERDTree-H| +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| +?.......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-tab* +Default key: +Map option: NERDTreeMapOpenSplit +Applies to: files. + +Opens the selected file in a new split window and puts the cursor in the new +window. + +------------------------------------------------------------------------------ + *NERDTree-gtab* +Default key: g +Map option: None +Applies to: files. + +The same as |NERDTree-tab| except that the cursor is not moved. + +The key combo for this mapping is always "g" + NERDTreeMapOpenSplit (see +|NERDTree-tab|). + +------------------------------------------------------------------------------ + *NERDTree-!* +Default key: ! +Map option: NERDTreeMapExecute +Applies to: files. + +Executes the selected file, prompting for arguments first. + +------------------------------------------------------------------------------ + *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. + +Opens a netrw on the selected directory, or the selected file's directory. + +------------------------------------------------------------------------------ + *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: NERDTreeMapFilesystemMenu +Applies to: files and directories. + +Display the filesystem menu. See |NERDTreeFilesysMenu| for details. + +------------------------------------------------------------------------------ + *NERDTree-H* +Default key: H +Map option: NERDTreeMapToggleHidden +Applies to: no restrictions. + +Toggles whether hidden files are displayed. Hidden files are any +file/directory that starts with a "." + +------------------------------------------------------------------------------ + *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-?* +Default key: ? +Map option: NERDTreeMapHelp +Applies to: no restrictions. + +Toggles whether the quickhelp is displayed. + +------------------------------------------------------------------------------ +2.3. The filesystem menu *NERDTreeFilesysMenu* + +The purpose of the filesystem menu is to allow you to perform basic filesystem +operations quickly from the NERD tree rather than the console. + +The filesystem menu can be accessed with 'm' mapping and has four supported +operations: > + 1. Adding nodes. + 2. Move nodes. + 3. Deleting nodes. + 3. Copying nodes. +< +1. Adding nodes: +To add a node move the cursor onto (or anywhere inside) the directory you wish +to create the new node inside. Select the 'add node' option from the +filesystem menu and type a filename. If the filename you type ends with a '/' +character then a directory will be created. Once the operation is completed, +the cursor is placed on the new node. + +2. Move nodes: +To move/rename a node, put the cursor on it and select the 'move' option from +the filesystem menu. Enter the new location for the node and it will be +moved. If the old file is open in a buffer, you will be asked if you wish to +delete that buffer. Once the operation is complete the cursor will be placed +on the renamed node. + +3. Deleting nodes: +To delete a node put the cursor on it and select the 'delete' option from the +filesystem menu. After confirmation the node will be deleted. If a file is +deleted but still exists as a buffer you will be given the option to delete +that buffer. + +4. Copying nodes: +To copy a node put the cursor on it and select the 'copy' option from the +filesystem menu. Enter the new location and you're done. Note: copying is +currently only supported for *nix operating systems. If someone knows a +one line copying command for windows that doesnt require user confirmation +then id be grateful if you'd email me. + +============================================================================== +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. + +|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. + +|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. + +------------------------------------------------------------------------------ + *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| or |NERDTree-tab| 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-H| 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. + +------------------------------------------------------------------------------ + *NERDTreeWinPos* +Values: "left", "right", "top" or "bottom" +Default: "left". + +This option is used to determine where NERD tree window is placed on the +screen. + +"top" or "bottom", will cause a horizontal split to be created for the tree, +while "left" and "right" will cause a vertical split. + +This option is makes it possible to use two different explorer type +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. + +============================================================================== + *NERDTreePublicFunctions* +5. Public functions ~ + +The script provides 2 public functions for your hacking pleasure. Their +signatures are: > + function! NERDTreeGetCurrentNode() + function! NERDTreeGetCurrentPath() +< +The first returns the node object that the cursor is currently on, while the +second returns the corresponding path object. + +This is probably a good time to mention that the script implements prototype +style OO. To see the functions that each class provides you can read look at +the code. + +Use the node objects to manipulate the structure of the tree. Use the path +objects to access the data the tree represents and to make changes to the +filesystem. + +============================================================================== +5. TODO list *NERDTreeTodo* + +Window manager integration? + +============================================================================== +6. The Author *NERDTreeAuthor* + +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 msn.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 ;) + +============================================================================== +7. Changelog *NERDTreeChangelog* + +2.14.0 + - fix a bug where the o mapping would cause the tree window to be + incorrectly sized when reopened. + - add keymapping to delete bookmarks from the bookmarks table, see + :help NERDTree-D + - lots of refactoring +2.13.0 + - make NERDTreeChDir option default to 0 (i.e. never change vims current + working dir by default) + - when moving/deleting nodes with the filesystem menu, move/delete any + associated bookmarks + - make the t/T on directory nodes open a fresh NERD tree for the selected + dir in a new tab, rather than a netrw. + - place the cursor at the top of the bookmarks table when opening it with B + - make NERDTreeQuitOnOpen option work with the g and go mappings, + thanks to Maxim Kim for the bug report + - change how invalid bookmarks are handled. Now they are not deleted. If a + bookmark is malformed (in the bookmarks file) or points to an + invalid/nonexisting location then print an error and place the offending + bookmarks at the bottom of the bookmarks file. See :help + |NERDTreeInvalidBookmarks| for info. Thanks to Zhang Shuhan for the + suggestion and the testing. + - fix a bug with the 'o' mapping that occurred when opening a new buffer + for a file whose name was a substring of an already open file. Thanks to + Charlton Wang for the report. + - stop the script from going into an infinite loop when it tries to cache + a named pipe. Thanks to Charlton Wang for the report. + +2.12.0 + - added a UI for bookmarks. See :help NERDTreeBookmarkTable for details. + Thanks to Zhang Shuhan for testing and bug reports. + - relaxed the restrictions on bookmark names, now the only restriction is + that they cant contain spaces. This allows for e.g. Chinese bookmark + names. Thanks to Zhang Shuhan for the suggestion. + - combined the NERDTreeWinPos and NERDTreeSplitVertical options. See :help + NERDTreeWinPos. + - applied a patch from Matan Nassau to add the NERDTreeQuitOnOpen option + which closes the tree window after opening a file. See :help + NERDTreeQuitOnOpen. + - optimised the nerd tree rendering. Now it takes just over 1/3 of the time + it previously took to render. + - now the tree filter mappings toggle the filters "per tree" rather than + globally. The global filter variables are used to set the initial filter + settings for each new NERD tree. + - fix to window resizing when opening a file when NERD tree is the only + window open + - other fixes + +2.11.0 + - changes to the 'o' mapping when opening files: + - dont clobber "special" windows (eg taglist/quickfix/etc). This should + make the NERD tree play nicer with other explorer plugins. Thanks to + Yuan Jiang for the suggestion. + - if the file is already open in the current tab, just move the cursor + to that window + - highlight executable files, made some slight changes to other + highlighting + - if the user resizes the tree window, keep that new size. Dont reset to + the default during the mapping, or :NERDTreeToggle command. Only + reset the size if a fresh tree is started with :NERDTree. + - remove the "magic" functionality from the / mappings (it was + more confusing than helpful) + - other minor fixes + +2.10.0 + - added bookmarks, see :help NERDTreeBookmarkCommands for details. Thanks + to Piotr Czachur for all his testing and suggestions. + - fixed screen jumping bug with when &scrolloff != 0 + - fixed some bugs with copying nodes + - other random fixes + - change license to wtfpl + +2.9.0 + + - path handling improvements, thanks to Zhang Shuhan for heaps of + testing/bug reports + * improved how paths are stored, now the script will no longer get + confused about drives on MF Windows + * made the script way better at handling paths with strange characters + in them (eg '$@; etc) + - applied a patch from Cory Echols + * add the command :NERDTreeClose to close the tree for the current tab + * set the filetype for the NERD tree buffer to "nerdtree" + +2.8.0 + - added an option to enable/disable line numbers in the NERD tree window, + thanks to Olivier Yiptong for the email. + +2.7.1 + - Changed the keys for the filesystem menu to be mnemonic rather than + arbitrary integers + - Documented the copying functionality in the filesystem menu + +2.7.0 + - Bug fix: Now when you have the tree on the right and you open it with + multiple windows stacked, it will take up the full height of the vim + window. + - Now line numbers always turned off in the tree by default + - Implemented copying of nodes (via the filesystem menu) for *nix/macosx + - took the help doc out of the script and repackaged the whole thing as a + zip + +2.6.2 + - Now when you try to open a file node into a window that is modified, the + window is not split if the &hidden option is set. Thanks to Niels Aan + de Brugh for this suggestion. + +2.6.1 + - Fixed a major bug with the mapping. Thanks to Zhang Weiwu for + emailing me. + +2.6.0 + - Extended the behaviour of . Now if the cursor is on a file node + and you use the cursor will jump to its PARENTS next/previous + sibling. Go :help NERDTree-c-j and :help NERDTree-c-k for info. + - Extended the behaviour of the J/K mappings. Now if the cursor is on the + last child of a node and you push J/K it will jump down to the last child + of the next/prev of its parents siblings that is open and has children. + Go :help NERDTree-J and :help NERDTree-K for info. + - The goal of these changes is to make tree navigation faster. + - Reorganised the help page a bit. + - Removed the E mapping. + - bugfixes + +2.5.0 + - Added an option to enforce case sensitivity when sorting tree nodes. + Read :help NERDTreeCaseSensitiveSort for details. (thanks to Michael + Madsen for emailing me about this). Case sensitivity defaults to off. + - Made the script echo a "please wait" style message when opening large + directories. Thanks to AOYAMA Shotaro for this suggestion. + - Added 2 public functions that can be used to retrieve the treenode and + path that the cursor is on. Read :help NERDTreePublicFunctions for + details (thanks again to AOYAMA Shotaro for the idea :). + - added 2 new mappings for file nodes: "g" and "go". These are the + same as the "" and "o" maps except that the cursor stays in the + NERDTree. Note: these maps are slaved to the o and mappings, so if + eg you remap "" to "i" then the "g" map will also be changed + to "gi". + - Renamed many of the help tags to be simpler. + - Simplified the ascii "graphics" for the filesystem menu + - Fixed bugs. + - Probably created bugs. + - Refactoring. + +2.4.0 + - Added the P mapping to jump to the tree root. + - Added window centering functionality that can be triggered when doing + using any of the tree nav mappings. Essentially, if the cursor comes + within a certain distance of the top/bottom of the window then a zz is + done in the window. Two related options were added: NERDTreeAutoCenter + to turn this functionality on/off, and NERDTreeAutoCenterThreshold to + control how close the cursor has to be to the window edge to trigger the + centering. + +2.3.0 + - Tree navigation changes: + - Added J and K mappings to jump to last/first child of the current dir. + Options to customise these mappings have also been added. + - Remapped the jump to next/prev sibling commands to be and by + default. + These changes should hopefully make tree navigation mappings easier to + remember and use as the j and k keys are simply reused 3 times (twice + with modifier keys). + + - Made it so that, when any of the tree filters are toggled, the cursor + stays with the selected node (or goes to its parent/grandparent/... if + that node is no longer visible) + - Fixed an error in the doc for the mouse mode option. + - Made the quickhelp correctly display the current single/double click + mappings for opening nodes as specified by the NERDTreeMouseMode option. + - Fixed a bug where the script was spazzing after prompting you to delete + a modified buffer when using the filesystem menu. + - Refactoring +2.2.3 + - Refactored the :echo output from the script. + - Fixed some minor typos in the doc. + - Made some minor changes to the output of the 'Tree filtering mappings' + part of the quickhelp + +2.2.2 + - More bugfixes... doh. + +2.2.1 + - Bug fix that was causing an exception when closing the nerd tree. Thanks + to Tim carey-smith and Yu Jun for pointing this out. + +2.2.0 + - Now 'cursorline' is set in the NERD tree buffer by default. See :help + NERDTreeHighlightCursorline for how to disable it. + +2.1.2 + - Stopped the script from clobbering the 1,2,3 .. 9 registers. + - Made it "silent!"ly delete buffers when renaming/deleting file nodes. + - Minor correction to the doc + - Fixed a bug when refreshing that was occurring when the node you + refreshed had been deleted externally. + - Fixed a bug that was occurring when you open a file that is already open + and modified. + +2.1.1 + - Added a bit more info about the buffers you are prompted to delete when + renaming/deleting nodes from the filesystem menu that are already loaded + into buffers. + - Refactoring and bugfixes + +2.1.0 + - Finally removed the blank line that always appears at the top of the + NERDTree buffer + - Added NERDTreeMouseMode option. If set to 1, then a double click is + required to activate all nodes, if set to 2 then a single click will + activate directory nodes, if set to 3 then a single click will activate + all nodes. + - Now if you delete a file node and have it open in a buffer you are given + the option to delete that buffer as well. Similarly if you rename a file + you are given the option to delete any buffers containing the old file + (if any exist) + - When you rename or create a node, the cursor is now put on the new node, + this makes it easy immediately edit the new file. + - Fixed a bug with the ! mapping that was occurring on windows with paths + containing spaces. + - Made all the mappings customisable. See |NERD_tree-mappings| for + details. A side effect is that a lot of the "double mappings" have + disappeared. E.g 'o' is now the key that is used to activate a node, + is no longer mapped to the same. + - Made the script echo warnings in some places rather than standard echos + - Insane amounts of refactoring all over the place. + +2.0.0 + - Added two new NERDChristmasTree decorations. First person to spot them + and email me gets a free copy of the NERDTree. + - Made it so that when you jump around the tree (with the p, s and S + mappings) it is counted as a jump by vim. This means if you, eg, push + 'p' one too many times then you can go `` or ctrl-o. + - Added a new option called NERDTreeSortOrder which takes an array of + regexs and is used to determine the order that the treenodes are listed + in. Go :help NERDTreeSortOrder for details. + - Removed the NERDTreeSortDirs option because it is consumed by + NERDTreeSortOrder + - Added the 'i' mapping which is the same as but requires less + effort to reach. + - Added the ! mapping which is used to execute file in the tree (after it + prompts you for arguments etc) + + +============================================================================== +8. Credits *NERDTreeCredits* + +Thanks to Tim Carey-Smith for testing/using the NERD tree from the first +pre-beta version, for his many suggestions and for his constant stream of bug +complaints. + +Thanks to Vigil for trying it out before the first release :) and suggesting +that mappings to open files in new tabs should be implemented. + +Thanks to Nick Brettell for testing, fixing my spelling and suggesting i put a + .. (up a directory) +line in the gui. + +Thanks to Thomas Scott Urban - the author of the vtreeexplorer plugin - whose +gui code i borrowed from. + +Thanks to Terrance Cohen for pointing out a bug where the script was changing +vims CWD all over the show. + +Thanks to Yegappan Lakshmanan (author of Taglist and other orgasmically +wonderful plugins) for telling me how to fix a bug that was causing vim to go +into visual mode everytime you double clicked a node :) + +Thanks to Jason Mills for sending me a fix that allows windows paths to use +forward slashes as well as backward. + +Thanks to Michael Geddes (frogonwheels on #vim at freenode) for giving me some +tips about syntax highlighting when i was doing highlighting for the +quickhelp. + +Thanks to Yu Jun for emailing me about a bug that was occurring when closing +the tree. + +Thanks to Michael Madsen for emailing me about making case sensitivity +optional when sorting nodes. + +Thanks to AOYAMA Shotaro for suggesting that i echo a "please wait" message +when opening large directories. + +Thanks to Michael Madsen for requesting the NERDTreeCaseSensitiveSort option. + +Thanks to AOYAMA Shotaro for suggesting that a "please wait" style message be +echoed when opening large directories. Also, thanks for the suggestion of +having public functions in the script to access the internal data :D + +Thanks to Zhang Weiwu for emailing me about a bug with the the mapping +in 2.6.0 + +Thanks to Niels Aan de Brugh for the suggestion that the script now split the +window if you try to open a file in a window containing a modified buffer when +the &hidden option is set. + +Thanks to Olivier Yiptong for prompting me to make line numbers in the +NERD tree window optional. + +Thanks to Zhang Shuhan for all of his emails and testing to help improve the +NERD tree path handling. Thanks also for suggesting the bookmarks gui, and for +testing and his many suggestions and bugreports about bookmarks. + +Thanks to Cory Echols for sending a patch to add the :NERDTreeClose command and +set the NERD tree buffers filetype to 'nerdtree' + +Thanks to Piotr Czachur for all his suggestions and testing for the bookmarks +feature. + +Thanks to Yuan Jiang for suggesting the "o" mapping shouldnt clobber "special" +windows, like taglist. + +Thanks to Matan Nassau for the patch to add the NERDTreeQuitOnOpen option. + +Thanks to Maxim Kim for reporting a bug with g and go mappings when +NERDTreeQuitOnOpen was set. + +Thanks to Charlton Wang for reporting bugs with the 'o' mapping and with +handling named pipes. + +============================================================================== +9. License *NERDTreeLicense* + +The NERD tree is released under the wtfpl. +See http://sam.zoy.org/wtfpl/COPYING. diff --git a/vim/doc/tags b/vim/doc/tags new file mode 100644 index 0000000..2fd1b50 --- /dev/null +++ b/vim/doc/tags @@ -0,0 +1,160 @@ +'Tlist_Auto_Highlight_Tag' taglist.txt /*'Tlist_Auto_Highlight_Tag'* +'Tlist_Auto_Open' taglist.txt /*'Tlist_Auto_Open'* +'Tlist_Auto_Update' taglist.txt /*'Tlist_Auto_Update'* +'Tlist_Close_On_Select' taglist.txt /*'Tlist_Close_On_Select'* +'Tlist_Compact_Format' taglist.txt /*'Tlist_Compact_Format'* +'Tlist_Ctags_Cmd' taglist.txt /*'Tlist_Ctags_Cmd'* +'Tlist_Display_Prototype' taglist.txt /*'Tlist_Display_Prototype'* +'Tlist_Display_Tag_Scope' taglist.txt /*'Tlist_Display_Tag_Scope'* +'Tlist_Enable_Fold_Column' taglist.txt /*'Tlist_Enable_Fold_Column'* +'Tlist_Exit_OnlyWindow' taglist.txt /*'Tlist_Exit_OnlyWindow'* +'Tlist_File_Fold_Auto_Close' taglist.txt /*'Tlist_File_Fold_Auto_Close'* +'Tlist_GainFocus_On_ToggleOpen' taglist.txt /*'Tlist_GainFocus_On_ToggleOpen'* +'Tlist_Highlight_Tag_On_BufEnter' taglist.txt /*'Tlist_Highlight_Tag_On_BufEnter'* +'Tlist_Inc_Winwidth' taglist.txt /*'Tlist_Inc_Winwidth'* +'Tlist_Max_Submenu_Items' taglist.txt /*'Tlist_Max_Submenu_Items'* +'Tlist_Max_Tag_Length' taglist.txt /*'Tlist_Max_Tag_Length'* +'Tlist_Process_File_Always' taglist.txt /*'Tlist_Process_File_Always'* +'Tlist_Show_Menu' taglist.txt /*'Tlist_Show_Menu'* +'Tlist_Show_One_File' taglist.txt /*'Tlist_Show_One_File'* +'Tlist_Sort_Type' taglist.txt /*'Tlist_Sort_Type'* +'Tlist_Use_Horiz_Window' taglist.txt /*'Tlist_Use_Horiz_Window'* +'Tlist_Use_Right_Window' taglist.txt /*'Tlist_Use_Right_Window'* +'Tlist_Use_SingleClick' taglist.txt /*'Tlist_Use_SingleClick'* +'Tlist_WinHeight' taglist.txt /*'Tlist_WinHeight'* +'Tlist_WinWidth' taglist.txt /*'Tlist_WinWidth'* +:NERDTree NERD_tree.txt /*:NERDTree* +:NERDTreeFromBookmark NERD_tree.txt /*:NERDTreeFromBookmark* +:NERDTreeToggle NERD_tree.txt /*:NERDTreeToggle* +:Snippet snippets_emu.txt /*:Snippet* +:TlistAddFiles taglist.txt /*:TlistAddFiles* +:TlistAddFilesRecursive taglist.txt /*:TlistAddFilesRecursive* +:TlistClose taglist.txt /*:TlistClose* +:TlistDebug taglist.txt /*:TlistDebug* +:TlistHighlightTag taglist.txt /*:TlistHighlightTag* +:TlistLock taglist.txt /*:TlistLock* +:TlistMessages taglist.txt /*:TlistMessages* +:TlistOpen taglist.txt /*:TlistOpen* +:TlistSessionLoad taglist.txt /*:TlistSessionLoad* +:TlistSessionSave taglist.txt /*:TlistSessionSave* +:TlistShowPrototype taglist.txt /*:TlistShowPrototype* +:TlistShowTag taglist.txt /*:TlistShowTag* +:TlistToggle taglist.txt /*:TlistToggle* +:TlistUndebug taglist.txt /*:TlistUndebug* +:TlistUnlock taglist.txt /*:TlistUnlock* +:TlistUpdate taglist.txt /*:TlistUpdate* +CreateBundleSnippet snippets_emu.txt /*CreateBundleSnippet* +CreateSnippet snippets_emu.txt /*CreateSnippet* +NERDChristmasTree NERD_tree.txt /*NERDChristmasTree* +NERDTree NERD_tree.txt /*NERDTree* +NERDTree-! NERD_tree.txt /*NERDTree-!* +NERDTree-? NERD_tree.txt /*NERDTree-?* +NERDTree-B NERD_tree.txt /*NERDTree-B* +NERDTree-C NERD_tree.txt /*NERDTree-C* +NERDTree-D NERD_tree.txt /*NERDTree-D* +NERDTree-F NERD_tree.txt /*NERDTree-F* +NERDTree-H NERD_tree.txt /*NERDTree-H* +NERDTree-J NERD_tree.txt /*NERDTree-J* +NERDTree-K NERD_tree.txt /*NERDTree-K* +NERDTree-O NERD_tree.txt /*NERDTree-O* +NERDTree-P NERD_tree.txt /*NERDTree-P* +NERDTree-R NERD_tree.txt /*NERDTree-R* +NERDTree-T NERD_tree.txt /*NERDTree-T* +NERDTree-U NERD_tree.txt /*NERDTree-U* +NERDTree-X NERD_tree.txt /*NERDTree-X* +NERDTree-c-j NERD_tree.txt /*NERDTree-c-j* +NERDTree-c-k NERD_tree.txt /*NERDTree-c-k* +NERDTree-contents NERD_tree.txt /*NERDTree-contents* +NERDTree-e NERD_tree.txt /*NERDTree-e* +NERDTree-f NERD_tree.txt /*NERDTree-f* +NERDTree-go NERD_tree.txt /*NERDTree-go* +NERDTree-gtab NERD_tree.txt /*NERDTree-gtab* +NERDTree-m NERD_tree.txt /*NERDTree-m* +NERDTree-o NERD_tree.txt /*NERDTree-o* +NERDTree-p NERD_tree.txt /*NERDTree-p* +NERDTree-q NERD_tree.txt /*NERDTree-q* +NERDTree-r NERD_tree.txt /*NERDTree-r* +NERDTree-t NERD_tree.txt /*NERDTree-t* +NERDTree-tab NERD_tree.txt /*NERDTree-tab* +NERDTree-u NERD_tree.txt /*NERDTree-u* +NERDTree-x NERD_tree.txt /*NERDTree-x* +NERDTreeAuthor NERD_tree.txt /*NERDTreeAuthor* +NERDTreeAutoCenter NERD_tree.txt /*NERDTreeAutoCenter* +NERDTreeAutoCenterThreshold NERD_tree.txt /*NERDTreeAutoCenterThreshold* +NERDTreeBookmarkCommands NERD_tree.txt /*NERDTreeBookmarkCommands* +NERDTreeBookmarkTable NERD_tree.txt /*NERDTreeBookmarkTable* +NERDTreeBookmarks NERD_tree.txt /*NERDTreeBookmarks* +NERDTreeBookmarksFile NERD_tree.txt /*NERDTreeBookmarksFile* +NERDTreeCaseSensitiveSort NERD_tree.txt /*NERDTreeCaseSensitiveSort* +NERDTreeChDirMode NERD_tree.txt /*NERDTreeChDirMode* +NERDTreeChangelog NERD_tree.txt /*NERDTreeChangelog* +NERDTreeCredits NERD_tree.txt /*NERDTreeCredits* +NERDTreeFilesysMenu NERD_tree.txt /*NERDTreeFilesysMenu* +NERDTreeFunctionality NERD_tree.txt /*NERDTreeFunctionality* +NERDTreeGlobalCommands NERD_tree.txt /*NERDTreeGlobalCommands* +NERDTreeHighlightCursorline NERD_tree.txt /*NERDTreeHighlightCursorline* +NERDTreeIgnore NERD_tree.txt /*NERDTreeIgnore* +NERDTreeInvalidBookmarks NERD_tree.txt /*NERDTreeInvalidBookmarks* +NERDTreeLicense NERD_tree.txt /*NERDTreeLicense* +NERDTreeMappings NERD_tree.txt /*NERDTreeMappings* +NERDTreeMouseMode NERD_tree.txt /*NERDTreeMouseMode* +NERDTreeOptionDetails NERD_tree.txt /*NERDTreeOptionDetails* +NERDTreeOptionSummary NERD_tree.txt /*NERDTreeOptionSummary* +NERDTreeOptions NERD_tree.txt /*NERDTreeOptions* +NERDTreePublicFunctions NERD_tree.txt /*NERDTreePublicFunctions* +NERDTreeQuitOnOpen NERD_tree.txt /*NERDTreeQuitOnOpen* +NERDTreeShowBookmarks NERD_tree.txt /*NERDTreeShowBookmarks* +NERDTreeShowFiles NERD_tree.txt /*NERDTreeShowFiles* +NERDTreeShowHidden NERD_tree.txt /*NERDTreeShowHidden* +NERDTreeShowLineNumbers NERD_tree.txt /*NERDTreeShowLineNumbers* +NERDTreeSortOrder NERD_tree.txt /*NERDTreeSortOrder* +NERDTreeTodo NERD_tree.txt /*NERDTreeTodo* +NERDTreeWinPos NERD_tree.txt /*NERDTreeWinPos* +NERDTreeWinSize NERD_tree.txt /*NERDTreeWinSize* +NERD_tree.txt NERD_tree.txt /*NERD_tree.txt* +Tlist_Get_Tag_Prototype_By_Line() taglist.txt /*Tlist_Get_Tag_Prototype_By_Line()* +Tlist_Get_Tagname_By_Line() taglist.txt /*Tlist_Get_Tagname_By_Line()* +Tlist_Set_App() taglist.txt /*Tlist_Set_App()* +Tlist_Update_File_Tags() taglist.txt /*Tlist_Update_File_Tags()* +basic-snippet snippets_emu.txt /*basic-snippet* +creating-snippets snippets_emu.txt /*creating-snippets* +loaded_nerd_tree NERD_tree.txt /*loaded_nerd_tree* +named-tags snippets_emu.txt /*named-tags* +snip-advanced-tag-commands snippets_emu.txt /*snip-advanced-tag-commands* +snip-buffer-specific snippets_emu.txt /*snip-buffer-specific* +snip-bundles snippets_emu.txt /*snip-bundles* +snip-contact-details snippets_emu.txt /*snip-contact-details* +snip-contributors snippets_emu.txt /*snip-contributors* +snip-detailed-explanations snippets_emu.txt /*snip-detailed-explanations* +snip-elem-delimiter snippets_emu.txt /*snip-elem-delimiter* +snip-ftplugin snippets_emu.txt /*snip-ftplugin* +snip-limitations snippets_emu.txt /*snip-limitations* +snip-menu snippets_emu.txt /*snip-menu* +snip-remap-key snippets_emu.txt /*snip-remap-key* +snip-snippet-commands snippets_emu.txt /*snip-snippet-commands* +snip-special-vars snippets_emu.txt /*snip-special-vars* +snip-start-end-tags snippets_emu.txt /*snip-start-end-tags* +snip-tag-name-syntax snippets_emu.txt /*snip-tag-name-syntax* +snippet-commands snippets_emu.txt /*snippet-commands* +snippets_emu-bugs snippets_emu.txt /*snippets_emu-bugs* +snippets_emu-features snippets_emu.txt /*snippets_emu-features* +snippets_emu-options snippets_emu.txt /*snippets_emu-options* +snippets_emu-troubleshooting snippets_emu.txt /*snippets_emu-troubleshooting* +snippets_emu.txt snippets_emu.txt /*snippets_emu.txt* +taglist-commands taglist.txt /*taglist-commands* +taglist-debug taglist.txt /*taglist-debug* +taglist-extend taglist.txt /*taglist-extend* +taglist-faq taglist.txt /*taglist-faq* +taglist-functions taglist.txt /*taglist-functions* +taglist-install taglist.txt /*taglist-install* +taglist-internet taglist.txt /*taglist-internet* +taglist-intro taglist.txt /*taglist-intro* +taglist-keys taglist.txt /*taglist-keys* +taglist-license taglist.txt /*taglist-license* +taglist-menu taglist.txt /*taglist-menu* +taglist-options taglist.txt /*taglist-options* +taglist-requirements taglist.txt /*taglist-requirements* +taglist-session taglist.txt /*taglist-session* +taglist-todo taglist.txt /*taglist-todo* +taglist-using taglist.txt /*taglist-using* +taglist.txt taglist.txt /*taglist.txt* diff --git a/vim/ftplugin/python.vim b/vim/ftplugin/python.vim new file mode 100644 index 0000000..100f650 --- /dev/null +++ b/vim/ftplugin/python.vim @@ -0,0 +1,58 @@ +python << EOF +def SetBreakpoint(): + import re + nLine = int( vim.eval( 'line(".")')) + + strLine = vim.current.line + strWhite = re.search( '^(\s*)', strLine).group(1) + + vim.current.buffer.append( + "%(space)spdb.set_trace() %(mark)s Breakpoint %(mark)s" % + {'space':strWhite, 'mark': '#' * 30}, nLine - 1) + + for strLine in vim.current.buffer: + if strLine == "import pdb": + break + else: + vim.current.buffer.append( 'import pdb', 0) + vim.command( 'normal j1') + +vim.command( 'map :py SetBreakpoint()') + +def RemoveBreakpoints(): + import re + + nCurrentLine = int( vim.eval( 'line(".")')) + + nLines = [] + nLine = 1 + for strLine in vim.current.buffer: + if strLine == 'import pdb' or strLine.lstrip()[:15] == 'pdb.set_trace()': + nLines.append( nLine) + nLine += 1 + + nLines.reverse() + + for nLine in nLines: + vim.command( 'normal %dG' % nLine) + vim.command( 'normal dd') + if nLine < nCurrentLine: + nCurrentLine -= 1 + + vim.command( 'normal %dG' % nCurrentLine) + +vim.command( 'map :py RemoveBreakpoints()') +EOF + +set makeprg=python\ -c\ \"import\ py_compile,sys;\ sys.stderr=sys.stdout;\ py_compile.compile(r'%')\" +set efm=%C\ %.%#,%A\ \ File\ \"%f\"\\,\ line\ %l%.%#,%Z%[%^\ ]%\\@=%m + +"PEP 8 Friendly +setlocal tabstop=4 +setlocal softtabstop=4 +setlocal shiftwidth=4 +setlocal textwidth=80 +setlocal smarttab +setlocal expandtab +setlocal smartindent + diff --git a/vim/plugin/NERD_tree.vim b/vim/plugin/NERD_tree.vim new file mode 100644 index 0000000..1a0df82 --- /dev/null +++ b/vim/plugin/NERD_tree.vim @@ -0,0 +1,3530 @@ +" ============================================================================ +" File: NERD_tree.vim +" Description: vim global plugin that provides a nice tree explorer +" Maintainer: Martin Grenfell +" Last Change: 20 July, 2008 +" License: This program is free software. It comes without any warranty, +" to the extent permitted by applicable law. You can redistribute +" it and/or modify it under the terms of the Do What The Fuck You +" Want To Public License, Version 2, as published by Sam Hocevar. +" See http://sam.zoy.org/wtfpl/COPYING for more details. +" +" ============================================================================ +let s:NERD_tree_version = '2.14.0' + +" SECTION: Script init stuff {{{1 +"============================================================ +if exists("loaded_nerd_tree") + finish +endif +if v:version < 700 + echoerr "NERDTree: this plugin requires vim >= 7. DOWNLOAD IT! You'll thank me later!" + finish +endif +let loaded_nerd_tree = 1 +"Function: s:initVariable() function {{{2 +"This function is used to initialise a given variable to a given value. The +"variable is only initialised if it does not exist prior +" +"Args: +"var: the name of the var to be initialised +"value: the value to initialise var to +" +"Returns: +"1 if the var is set, 0 otherwise +function! s:initVariable(var, value) + if !exists(a:var) + exec 'let ' . a:var . ' = ' . "'" . a:value . "'" + return 1 + endif + return 0 +endfunction + +"SECTION: Init variable calls and other random constants {{{2 +call s:initVariable("g:NERDChristmasTree", 1) +call s:initVariable("g:NERDTreeAutoCenter", 1) +call s:initVariable("g:NERDTreeAutoCenterThreshold", 3) +call s:initVariable("g:NERDTreeCaseSensitiveSort", 0) +call s:initVariable("g:NERDTreeChDirMode", 0) +if !exists("g:NERDTreeIgnore") + let g:NERDTreeIgnore = ['\~$'] +endif +call s:initVariable("g:NERDTreeHighlightCursorline", 1) +call s:initVariable("g:NERDTreeBookmarksFile", expand('$HOME') . '/.NERDTreeBookmarks') +call s:initVariable("g:NERDTreeMouseMode", 1) +call s:initVariable("g:NERDTreeNotificationThreshold", 100) +call s:initVariable("g:NERDTreeQuitOnOpen", 0) +call s:initVariable("g:NERDTreeShowBookmarks", 0) +call s:initVariable("g:NERDTreeShowFiles", 1) +call s:initVariable("g:NERDTreeShowHidden", 0) +call s:initVariable("g:NERDTreeShowLineNumbers", 0) +call s:initVariable("g:NERDTreeSortDirs", 1) + +if !exists("g:NERDTreeSortOrder") + let g:NERDTreeSortOrder = ['\/$', '*', '\.swp$', '\.bak$', '\~$'] +else + "if there isnt a * in the sort sequence then add one + if count(g:NERDTreeSortOrder, '*') < 1 + call add(g:NERDTreeSortOrder, '*') + endif +endif + +"we need to use this number many times for sorting... so we calculate it only +"once here +let s:NERDTreeSortStarIndex = index(g:NERDTreeSortOrder, '*') + +call s:initVariable("g:NERDTreeWinPos", "left") +call s:initVariable("g:NERDTreeWinSize", 31) + +let s:running_windows = has("win16") || has("win32") || has("win64") + +"init the shell commands that will be used to copy nodes, and remove dir trees +" +"Note: the space after the command is important +if s:running_windows + call s:initVariable("g:NERDTreeRemoveDirCmd", 'rmdir /s /q ') +else + call s:initVariable("g:NERDTreeRemoveDirCmd", 'rm -rf ') + call s:initVariable("g:NERDTreeCopyCmd", 'cp -r ') +endif + + +"SECTION: Init variable calls for key mappings {{{2 +call s:initVariable("g:NERDTreeMapActivateNode", "o") +call s:initVariable("g:NERDTreeMapChangeRoot", "C") +call s:initVariable("g:NERDTreeMapChdir", "cd") +call s:initVariable("g:NERDTreeMapCloseChildren", "X") +call s:initVariable("g:NERDTreeMapCloseDir", "x") +call s:initVariable("g:NERDTreeMapDeleteBookmark", "D") +call s:initVariable("g:NERDTreeMapExecute", "!") +call s:initVariable("g:NERDTreeMapFilesystemMenu", "m") +call s:initVariable("g:NERDTreeMapHelp", "?") +call s:initVariable("g:NERDTreeMapJumpFirstChild", "K") +call s:initVariable("g:NERDTreeMapJumpLastChild", "J") +call s:initVariable("g:NERDTreeMapJumpNextSibling", "") +call s:initVariable("g:NERDTreeMapJumpParent", "p") +call s:initVariable("g:NERDTreeMapJumpPrevSibling", "") +call s:initVariable("g:NERDTreeMapJumpRoot", "P") +call s:initVariable("g:NERDTreeMapOpenExpl", "e") +call s:initVariable("g:NERDTreeMapOpenInTab", "t") +call s:initVariable("g:NERDTreeMapOpenInTabSilent", "T") +call s:initVariable("g:NERDTreeMapOpenRecursively", "O") +call s:initVariable("g:NERDTreeMapOpenSplit", "") +call s:initVariable("g:NERDTreeMapPreview", "g" . NERDTreeMapActivateNode) +call s:initVariable("g:NERDTreeMapPreviewSplit", "g" . NERDTreeMapOpenSplit) +call s:initVariable("g:NERDTreeMapQuit", "q") +call s:initVariable("g:NERDTreeMapRefresh", "r") +call s:initVariable("g:NERDTreeMapRefreshRoot", "R") +call s:initVariable("g:NERDTreeMapToggleBookmarks", "B") +call s:initVariable("g:NERDTreeMapToggleFiles", "F") +call s:initVariable("g:NERDTreeMapToggleFilters", "f") +call s:initVariable("g:NERDTreeMapToggleHidden", "H") +call s:initVariable("g:NERDTreeMapUpdir", "u") +call s:initVariable("g:NERDTreeMapUpdirKeepOpen", "U") + +"SECTION: Script level variable declaration{{{2 +let s:escape_chars = " \\`\|\"#%&,?()\*^<>" +let s:NERDTreeWinName = '_NERD_tree_' + +let s:tree_wid = 2 +let s:tree_markup_reg = '[ \-+~`|]' +let s:tree_markup_reg_neg = '[^ \-+~`|]' +let s:tree_up_dir_line = '.. (up a dir)' + +let s:os_slash = '/' +if s:running_windows + let s:os_slash = '\' +endif + + +" SECTION: Commands {{{1 +"============================================================ +"init the command that users start the nerd tree with +command! -n=? -complete=dir NERDTree :call s:initNerdTree('') +command! -n=? -complete=dir NERDTreeToggle :call s:toggle('') +command! -n=0 NERDTreeClose :call s:closeTreeIfOpen() +command! -n=1 -complete=customlist,s:completeBookmarks NERDTreeFromBookmark call s:initNerdTree('') +" SECTION: Auto commands {{{1 +"============================================================ +"Save the cursor position whenever we close the nerd tree +exec "autocmd BufWinLeave *". s:NERDTreeWinName ." call saveScreenState()" +"cache bookmarks when vim loads +autocmd VimEnter * call s:Bookmark.CacheBookmarks(0) + +"SECTION: Classes {{{1 +"============================================================ +"CLASS: Bookmark {{{2 +"============================================================ +let s:Bookmark = {} +" FUNCTION: Bookmark.AddBookmark(name, path) {{{3 +" Class method to add a new bookmark to the list, if a previous bookmark exists +" with the same name, just update the path for that bookmark +function! s:Bookmark.AddBookmark(name, path) + for i in s:Bookmark.Bookmarks() + if i.name == a:name + let i.path = a:path + return + endif + endfor + call add(s:Bookmark.Bookmarks(), s:Bookmark.New(a:name, a:path)) + call s:Bookmark.Sort() +endfunction +" Function: Bookmark.Bookmarks() {{{3 +" Class method to get all bookmarks. Lazily initializes the bookmarks global +" variable +function! s:Bookmark.Bookmarks() + if !exists("g:NERDTreeBookmarks") + let g:NERDTreeBookmarks = [] + endif + return g:NERDTreeBookmarks +endfunction +" Function: Bookmark.BookmarkExistsFor(name) {{{3 +" class method that returns 1 if a bookmark with the given name is found, 0 +" otherwise +function! s:Bookmark.BookmarkExistsFor(name) + try + call s:Bookmark.BookmarkFor(a:name) + return 1 + catch /NERDTree.BookmarkNotFound/ + return 0 + endtry +endfunction +" Function: Bookmark.BookmarkFor(name) {{{3 +" Class method to get the bookmark that has the given name. {} is return if no +" bookmark is found +function! s:Bookmark.BookmarkFor(name) + for i in s:Bookmark.Bookmarks() + if i.name == a:name + return i + endif + endfor + throw "NERDTree.BookmarkNotFound exception: no bookmark found for name: \"". a:name .'"' +endfunction +" Function: Bookmark.BookmarkNames() {{{3 +" Class method to return an array of all bookmark names +function! s:Bookmark.BookmarkNames() + let names = [] + for i in s:Bookmark.Bookmarks() + call add(names, i.name) + endfor + return names +endfunction +" FUNCTION: Bookmark.CacheBookmarks(silent) {{{3 +" Class method to read all bookmarks from the bookmarks file intialize +" bookmark objects for each one. +" +" Args: +" silent - dont echo an error msg if invalid bookmarks are found +function! s:Bookmark.CacheBookmarks(silent) + if filereadable(g:NERDTreeBookmarksFile) + let g:NERDTreeBookmarks = [] + let g:NERDTreeInvalidBookmarks = [] + let bookmarkStrings = readfile(g:NERDTreeBookmarksFile) + let invalidBookmarksFound = 0 + for i in bookmarkStrings + + "ignore blank lines + if i != '' + + let name = substitute(i, '^\(.\{-}\) .*$', '\1', '') + let path = substitute(i, '^.\{-} \(.*\)$', '\1', '') + + try + let bookmark = s:Bookmark.New(name, s:Path.New(path)) + call add(g:NERDTreeBookmarks, bookmark) + catch /NERDTree.Path.InvalidArguments/ + call add(g:NERDTreeInvalidBookmarks, i) + let invalidBookmarksFound += 1 + endtry + endif + endfor + if invalidBookmarksFound + call s:Bookmark.Write() + if !a:silent + call s:echo(invalidBookmarksFound . " invalid bookmarks were read. See :help NERDTreeInvalidBookmarks for info.") + endif + endif + call s:Bookmark.Sort() + endif +endfunction +" FUNCTION: Bookmark.compareTo(otherbookmark) {{{3 +" Compare these two bookmarks for sorting purposes +function! s:Bookmark.compareTo(otherbookmark) + return a:otherbookmark.name < self.name +endfunction +" FUNCTION: Bookmark.ClearAll() {{{3 +" Class method to delete all bookmarks. +function! s:Bookmark.ClearAll() + for i in s:Bookmark.Bookmarks() + call i.delete() + endfor + call s:Bookmark.Write() +endfunction +" FUNCTION: Bookmark.delete() {{{3 +" Delete this bookmark. If the node for this bookmark is under the current +" root, then recache bookmarks for its Path object +function! s:Bookmark.delete() + let node = {} + try + let node = self.getNode(1) + catch /NERDTree.BookmarkedNodeNotFound/ + endtry + call remove(s:Bookmark.Bookmarks(), index(s:Bookmark.Bookmarks(), self)) + if !empty(node) + call node.path.cacheDisplayString() + endif + call s:Bookmark.Write() +endfunction +" FUNCTION: Bookmark.getNode(searchFromAbsoluteRoot) {{{3 +" Gets the treenode for this bookmark +" +" Args: +" searchFromAbsoluteRoot: specifies whether we should search from the current +" tree root, or the highest cached node +function! s:Bookmark.getNode(searchFromAbsoluteRoot) + let searchRoot = a:searchFromAbsoluteRoot ? s:TreeDirNode.AbsoluteTreeRoot() : t:NERDTreeRoot + let targetNode = searchRoot.findNode(self.path) + if empty(targetNode) + throw "NERDTree.BookmarkedNodeNotFound no node was found for bookmark: " . self.name + endif + return targetNode +endfunction +" FUNCTION: Bookmark.GetNodeForName(name, searchFromAbsoluteRoot) {{{3 +" Class method that finds the bookmark with the given name and returns the +" treenode for it. +function! s:Bookmark.GetNodeForName(name, searchFromAbsoluteRoot) + let bookmark = s:Bookmark.BookmarkFor(a:name) + return bookmark.getNode(a:searchFromAbsoluteRoot) +endfunction +" Function: Bookmark.InvalidBookmarks() {{{3 +" Class method to get all invalid bookmark strings read from the bookmarks +" file +function! s:Bookmark.InvalidBookmarks() + if !exists("g:NERDTreeInvalidBookmarks") + let g:NERDTreeInvalidBookmarks = [] + endif + return g:NERDTreeInvalidBookmarks +endfunction +" FUNCTION: Bookmark.mustExist() {{{3 +function! s:Bookmark.mustExist() + if !self.path.exists() + call s:Bookmark.CacheBookmarks(1) + throw "NERDTree.BookmarkPointsToInvalidLocation exception: the bookmark \"". + \ self.name ."\" points to a non existing location: \"". self.path.strForOS(0) + endif +endfunction +" FUNCTION: Bookmark.New(name, path) {{{3 +" Create a new bookmark object with the given name and path object +function! s:Bookmark.New(name, path) + if a:name =~ ' ' + throw "NERDTree.IllegalBookmarkName illegal name:" . a:name + endif + + let newBookmark = copy(self) + let newBookmark.name = a:name + let newBookmark.path = a:path + return newBookmark +endfunction +" Function: Bookmark.setPath(path) {{{3 +" makes this bookmark point to the given path +function! s:Bookmark.setPath(path) + let self.path = a:path +endfunction +" Function: Bookmark.Sort() {{{3 +" Class method that sorts all bookmarks +function! s:Bookmark.Sort() + let CompareFunc = function("s:compareBookmarks") + call sort(s:Bookmark.Bookmarks(), CompareFunc) +endfunction +" Function: Bookmark.str() {{{3 +" Get the string that should be rendered in the view for this bookmark +function! s:Bookmark.str() + let pathStrMaxLen = winwidth(s:getTreeWinNum()) - 4 - len(self.name) + if &nu + let pathStrMaxLen = pathStrMaxLen - &numberwidth + endif + + let pathStr = self.path.strForOS(0) + if len(pathStr) > pathStrMaxLen + let pathStr = '<' . strpart(pathStr, len(pathStr) - pathStrMaxLen) + endif + return '>' . self.name . ' ' . pathStr +endfunction +" FUNCTION: Bookmark.toRoot() {{{3 +" Make the node for this bookmark the new tree root +function! s:Bookmark.toRoot() + if self.validate() + try + let targetNode = s:Bookmark.GetNodeForName(self.name, 1) + catch /NERDTree.BookmarkedNodeNotFound/ + let targetNode = s:TreeFileNode.New(s:Bookmark.BookmarkFor(self.name).path) + endtry + call targetNode.makeRoot() + call s:renderView() + call s:putCursorOnNode(targetNode, 0, 0) + endif +endfunction +" FUNCTION: Bookmark.ToRoot(name) {{{3 +" Make the node for this bookmark the new tree root +function! s:Bookmark.ToRoot(name) + let bookmark = s:Bookmark.BookmarkFor(a:name) + call bookmark.toRoot() +endfunction + + +"FUNCTION: Bookmark.validate() {{{3 +function! s:Bookmark.validate() + if self.path.exists() + return 1 + else + call s:Bookmark.CacheBookmarks(1) + call s:renderView() + call s:echo(self.name . "now points to an invalid location. See :help NERDTreeInvalidBookmarks for info.") + return 0 + endif +endfunction + +" Function: Bookmark.Write() {{{3 +" Class method to write all bookmarks to the bookmarks file +function! s:Bookmark.Write() + let bookmarkStrings = [] + for i in s:Bookmark.Bookmarks() + call add(bookmarkStrings, i.name . ' ' . i.path.strForOS(0)) + endfor + + "add a blank line before the invalid ones + call add(bookmarkStrings, "") + + for j in s:Bookmark.InvalidBookmarks() + call add(bookmarkStrings, j) + endfor + call writefile(bookmarkStrings, g:NERDTreeBookmarksFile) +endfunction +"CLASS: 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.bookmark(name) {{{3 +"bookmark this node with a:name +function! s:TreeFileNode.bookmark(name) + try + let oldMarkedNode = s:Bookmark.GetNodeForName(a:name, 1) + call oldMarkedNode.path.cacheDisplayString() + catch /NERDTree.Bookmark\(DoesntExist\|NotFound\)/ + endtry + + call s:Bookmark.AddBookmark(a:name, self.path) + call self.path.cacheDisplayString() + call s:Bookmark.Write() +endfunction +"FUNCTION: TreeFileNode.cacheParent() {{{3 +"initializes self.parent if it isnt already +function! s:TreeFileNode.cacheParent() + if empty(self.parent) + let parentPath = self.path.getParent() + if parentPath.equals(self.path) + throw "NERDTree.CannotCacheParent exception: already at root" + endif + let self.parent = s:TreeFileNode.New(parentPath) + endif +endfunction +"FUNCTION: TreeFileNode.compareNodes {{{3 +"This is supposed to be a class level method but i cant figure out how to +"get func refs to work from a dict.. +" +"A class level method that compares two nodes +" +"Args: +"n1, n2: the 2 nodes to compare +function! s:compareNodes(n1, n2) + return a:n1.path.compareTo(a:n2.path) +endfunction + +"FUNCTION: TreeFileNode.clearBoomarks() {{{3 +function! s:TreeFileNode.clearBoomarks() + for i in s:Bookmark.Bookmarks() + if i.path.equals(self.path) + call i.delete() + end + endfor + call self.path.cacheDisplayString() +endfunction +"FUNCTION: TreeFileNode.copy(dest) {{{3 +function! s:TreeFileNode.copy(dest) + call self.path.copy(a:dest) + let newPath = s:Path.New(a:dest) + let parent = t:NERDTreeRoot.findNode(newPath.getParent()) + if !empty(parent) + call parent.refresh() + endif + return parent.findNode(newPath) +endfunction + +"FUNCTION: TreeFileNode.delete {{{3 +"Removes this node from the tree and calls the Delete method for its path obj +function! s:TreeFileNode.delete() + call self.path.delete() + call self.parent.removeChild(self) +endfunction + +"FUNCTION: TreeFileNode.equals(treenode) {{{3 +" +"Compares this treenode to the input treenode and returns 1 if they are the +"same node. +" +"Use this method instead of == because sometimes when the treenodes contain +"many children, vim seg faults when doing == +" +"Args: +"treenode: the other treenode to compare to +function! s:TreeFileNode.equals(treenode) + return self.path.str(1) == a:treenode.path.str(1) +endfunction + +"FUNCTION: TreeFileNode.findNode(path) {{{3 +"Returns self if this node.path.Equals the given path. +"Returns {} if not equal. +" +"Args: +"path: the path object to compare against +function! s:TreeFileNode.findNode(path) + if a:path.equals(self.path) + return self + endif + return {} +endfunction +"FUNCTION: TreeFileNode.findOpenDirSiblingWithChildren(direction) {{{3 +" +"Finds the next sibling for this node in the indicated direction. This sibling +"must be a directory and may/may not have children as specified. +" +"Args: +"direction: 0 if you want to find the previous sibling, 1 for the next sibling +" +"Return: +"a treenode object or {} if no appropriate sibling could be found +function! s:TreeFileNode.findOpenDirSiblingWithChildren(direction) + "if we have no parent then we can have no siblings + if self.parent != {} + let nextSibling = self.findSibling(a:direction) + + while nextSibling != {} + if nextSibling.path.isDirectory && nextSibling.hasVisibleChildren() && nextSibling.isOpen + return nextSibling + endif + let nextSibling = nextSibling.findSibling(a:direction) + endwhile + endif + + return {} +endfunction +"FUNCTION: TreeFileNode.findSibling(direction) {{{3 +" +"Finds the next sibling for this node in the indicated direction +" +"Args: +"direction: 0 if you want to find the previous sibling, 1 for the next sibling +" +"Return: +"a treenode object or {} if no sibling could be found +function! s:TreeFileNode.findSibling(direction) + "if we have no parent then we can have no siblings + if self.parent != {} + + "get the index of this node in its parents children + let siblingIndx = self.parent.getChildIndex(self.path) + + if siblingIndx != -1 + "move a long to the next potential sibling node + let siblingIndx = a:direction == 1 ? siblingIndx+1 : siblingIndx-1 + + "keep moving along to the next sibling till we find one that is valid + let numSiblings = self.parent.getChildCount() + while siblingIndx >= 0 && siblingIndx < numSiblings + + "if the next node is not an ignored node (i.e. wont show up in the + "view) then return it + if self.parent.children[siblingIndx].path.ignore() == 0 + return self.parent.children[siblingIndx] + endif + + "go to next node + let siblingIndx = a:direction == 1 ? siblingIndx+1 : siblingIndx-1 + endwhile + endif + endif + + return {} +endfunction + +"FUNCTION: TreeFileNode.isVisible() {{{3 +"returns 1 if this node should be visible according to the tree filters and +"hidden file filters (and their on/off status) +function! s:TreeFileNode.isVisible() + return !self.path.ignore() +endfunction + + +"FUNCTION: TreeFileNode.isRoot() {{{3 +"returns 1 if this node is t:NERDTreeRoot +function! s:TreeFileNode.isRoot() + if !s:treeExistsForTab() + throw "NERDTree.TreeFileNode.IsRoot exception: No tree exists for the current tab" + endif + return self.equals(t:NERDTreeRoot) +endfunction + +"FUNCTION: TreeFileNode.makeRoot() {{{3 +"Make this node the root of the tree +function! s:TreeFileNode.makeRoot() + if self.path.isDirectory + let t:NERDTreeRoot = self + else + call self.cacheParent() + let t:NERDTreeRoot = self.parent + endif + + call t:NERDTreeRoot.open() + + "change dir to the dir of the new root if instructed to + if g:NERDTreeChDirMode == 2 + exec "cd " . t:NERDTreeRoot.path.strForEditCmd() + endif +endfunction +"FUNCTION: TreeFileNode.New(path) {{{3 +"Returns a new TreeNode object with the given path and parent +" +"Args: +"path: a path object representing the full filesystem path to the file/dir that the node represents +function! s:TreeFileNode.New(path) + if a:path.isDirectory + return s:TreeDirNode.New(a:path) + else + let newTreeNode = {} + let newTreeNode = copy(self) + let newTreeNode.path = a:path + let newTreeNode.parent = {} + return newTreeNode + endif +endfunction + +"FUNCTION: TreeFileNode.refresh() {{{3 +function! s:TreeFileNode.refresh() + call self.path.refresh() +endfunction +"FUNCTION: TreeFileNode.rename() {{{3 +"Calls the rename method for this nodes path obj +function! s:TreeFileNode.rename(newName) + let newName = substitute(a:newName, '\(\\\|\/\)$', '', '') + call self.path.rename(newName) + call self.parent.removeChild(self) + + let parentPath = self.path.getPathTrunk() + let newParent = t:NERDTreeRoot.findNode(parentPath) + + if newParent != {} + call newParent.createChild(self.path, 1) + 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() +endfunction + +"CLASS: TreeDirNode {{{2 +"This class is a child of the TreeFileNode class and constitutes the +"'Composite' part of the composite design pattern between the treenode +"classes. +"============================================================ +let s:TreeDirNode = copy(s:TreeFileNode) +"FUNCTION: TreeDirNode.AbsoluteTreeRoot(){{{3 +"class method that returns the highest cached ancestor of the current root +function! s:TreeDirNode.AbsoluteTreeRoot() + let currentNode = t:NERDTreeRoot + while currentNode.parent != {} + let currentNode = currentNode.parent + endwhile + return currentNode +endfunction +"FUNCTION: TreeDirNode.addChild(treenode, inOrder) {{{3 +"Adds the given treenode to the list of children for this node +" +"Args: +"-treenode: the node to add +"-inOrder: 1 if the new node should be inserted in sorted order +function! s:TreeDirNode.addChild(treenode, inOrder) + call add(self.children, a:treenode) + let a:treenode.parent = self + + if a:inOrder + call self.sortChildren() + endif +endfunction + +"FUNCTION: TreeDirNode.close() {{{3 +"Closes this directory +function! s:TreeDirNode.close() + let self.isOpen = 0 +endfunction + +"FUNCTION: TreeDirNode.closeChildren() {{{3 +"Closes all the child dir nodes of this node +function! s:TreeDirNode.closeChildren() + for i in self.children + if i.path.isDirectory + call i.close() + call i.closeChildren() + endif + endfor +endfunction + +"FUNCTION: TreeDirNode.createChild(path, inOrder) {{{3 +"Instantiates a new child node for this node with the given path. The new +"nodes parent is set to this node. +" +"Args: +"path: a Path object that this node will represent/contain +"inOrder: 1 if the new node should be inserted in sorted order +" +"Returns: +"the newly created node +function! s:TreeDirNode.createChild(path, inOrder) + let newTreeNode = s:TreeFileNode.New(a:path) + call self.addChild(newTreeNode, a:inOrder) + return newTreeNode +endfunction + +"FUNCTION: TreeDirNode.findNode(path) {{{3 +"Will find one of the children (recursively) that has the given path +" +"Args: +"path: a path object +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 + return {} + endif + + if self.path.isDirectory + for i in self.children + let retVal = i.findNode(a:path) + if retVal != {} + return retVal + endif + endfor + endif + return {} +endfunction + +"FUNCTION: TreeDirNode.getChildCount() {{{3 +"Returns the number of children this node has +function! s:TreeDirNode.getChildCount() + return len(self.children) +endfunction + +"FUNCTION: TreeDirNode.getChild(path) {{{3 +"Returns child node of this node that has the given path or {} if no such node +"exists. +" +"This function doesnt not recurse into child dir nodes +" +"Args: +"path: a path object +function! s:TreeDirNode.getChild(path) + if stridx(a:path.str(1), self.path.str(1), 0) == -1 + return {} + endif + + let index = self.getChildIndex(a:path) + if index == -1 + return {} + else + return self.children[index] + endif + +endfunction + +"FUNCTION: TreeDirNode.getChildByIndex(indx, visible) {{{3 +"returns the child at the given index +"Args: +"indx: the index to get the child from +"visible: 1 if only the visible children array should be used, 0 if all the +"children should be searched. +function! s:TreeDirNode.getChildByIndex(indx, visible) + let array_to_search = a:visible? self.getVisibleChildren() : self.children + if a:indx > len(array_to_search) + throw "NERDTree.TreeDirNode.InvalidArguments exception. Index is out of bounds." + endif + return array_to_search[a:indx] +endfunction + +"FUNCTION: TreeDirNode.getChildIndex(path) {{{3 +"Returns the index of the child node of this node that has the given path or +"-1 if no such node exists. +" +"This function doesnt not recurse into child dir nodes +" +"Args: +"path: a path object +function! s:TreeDirNode.getChildIndex(path) + if stridx(a:path.str(1), self.path.str(1), 0) == -1 + return -1 + endif + + "do a binary search for the child + let a = 0 + let z = self.getChildCount() + while a < z + let mid = (a+z)/2 + let diff = a:path.compareTo(self.children[mid].path) + + if diff == -1 + let z = mid + elseif diff == 1 + let a = mid+1 + else + return mid + endif + endwhile + return -1 +endfunction + +"FUNCTION: TreeDirNode.getVisibleChildCount() {{{3 +"Returns the number of visible children this node has +function! s:TreeDirNode.getVisibleChildCount() + return len(self.getVisibleChildren()) +endfunction + +"FUNCTION: TreeDirNode.getVisibleChildren() {{{3 +"Returns a list of children to display for this node, in the correct order +" +"Return: +"an array of treenodes +function! s:TreeDirNode.getVisibleChildren() + let toReturn = [] + for i in self.children + if i.path.ignore() == 0 + call add(toReturn, i) + endif + endfor + return toReturn +endfunction + +"FUNCTION: TreeDirNode.hasVisibleChildren() {{{3 +"returns 1 if this node has any childre, 0 otherwise.. +function! s:TreeDirNode.hasVisibleChildren() + return self.getChildCount() != 0 +endfunction + +"FUNCTION: TreeDirNode._initChildren() {{{3 +"Removes all childen from this node and re-reads them +" +"Args: +"silent: 1 if the function should not echo any "please wait" messages for +"large directories +" +"Return: the number of child nodes read +function! s:TreeDirNode._initChildren(silent) + "remove all the current child nodes + let self.children = [] + + "get an array of all the files in the nodes dir + let dir = self.path + let filesStr = globpath(dir.strForGlob(), '*') . "\n" . globpath(dir.strForGlob(), '.*') + let files = split(filesStr, "\n") + + if !a:silent && len(files) > g:NERDTreeNotificationThreshold + call s:echo("Please wait, caching a large dir ...") + endif + + let invalidFilesFound = 0 + for i in files + + "filter out the .. and . directories + "Note: we must match .. AND ../ cos sometimes the globpath returns + "../ for path with strange chars (eg $) + if i !~ '\.\.\/\?$' && i !~ '\.\/\?$' + + "put the next file in a new node and attach it + try + let path = s:Path.New(i) + call self.createChild(path, 0) + catch /^NERDTree.Path.\(InvalidArguments\|InvalidFiletype\)/ + let invalidFilesFound += 1 + endtry + endif + endfor + + call self.sortChildren() + + if !a:silent && len(files) > g:NERDTreeNotificationThreshold + call s:echo("Please wait, caching a large dir ... DONE (". self.getChildCount() ." nodes cached).") + endif + + if invalidFilesFound + call s:echoWarning(invalidFilesFound . " file(s) could not be loaded into the NERD tree") + endif + return self.getChildCount() +endfunction +"FUNCTION: TreeDirNode.New(path) {{{3 +"Returns a new TreeNode object with the given path and parent +" +"Args: +"path: a path object representing the full filesystem path to the file/dir that the node represents +function! s:TreeDirNode.New(path) + if a:path.isDirectory != 1 + throw "NERDTree.TreeDirNode.InvalidArguments exception. A TreeDirNode object must be instantiated with a directory Path object." + endif + + let newTreeNode = copy(self) + let newTreeNode.path = a:path + + let newTreeNode.isOpen = 0 + let newTreeNode.children = [] + + let newTreeNode.parent = {} + + return newTreeNode +endfunction +"FUNCTION: TreeDirNode.open() {{{3 +"Reads in all this nodes children +" +"Return: the number of child nodes read +function! s:TreeDirNode.open() + let self.isOpen = 1 + if self.children == [] + return self._initChildren(0) + else + return 0 + endif +endfunction + +"FUNCTION: TreeDirNode.openRecursively() {{{3 +"Opens this treenode and all of its children whose paths arent 'ignored' +"because of the file filters. +" +"This method is actually a wrapper for the OpenRecursively2 method which does +"the work. +function! s:TreeDirNode.openRecursively() + call self._openRecursively2(1) +endfunction + +"FUNCTION: TreeDirNode._openRecursively2() {{{3 +"Opens this all children of this treenode recursively if either: +" *they arent filtered by file filters +" *a:forceOpen is 1 +" +"Args: +"forceOpen: 1 if this node should be opened regardless of file filters +function! s:TreeDirNode._openRecursively2(forceOpen) + if self.path.ignore() == 0 || a:forceOpen + let self.isOpen = 1 + if self.children == [] + call self._initChildren(1) + endif + + for i in self.children + if i.path.isDirectory == 1 + call i._openRecursively2(0) + endif + endfor + endif +endfunction + +"FUNCTION: TreeDirNode.refresh() {{{3 +function! s:TreeDirNode.refresh() + call self.path.refresh() + + "if this node was ever opened, refresh its children + if self.isOpen || !empty(self.children) + "go thru all the files/dirs under this node + let newChildNodes = [] + let invalidFilesFound = 0 + let dir = self.path + let filesStr = globpath(dir.strForGlob(), '*') . "\n" . globpath(dir.strForGlob(), '.*') + let files = split(filesStr, "\n") + for i in files + if i !~ '\.\.$' && i !~ '\.$' + + try + "create a new path and see if it exists in this nodes children + let path = s:Path.New(i) + let newNode = self.getChild(path) + if newNode != {} + call newNode.refresh() + call add(newChildNodes, newNode) + + "the node doesnt exist so create it + else + let newNode = s:TreeFileNode.New(path) + let newNode.parent = self + call add(newChildNodes, newNode) + endif + + + catch /^NERDTree.InvalidArguments/ + let invalidFilesFound = 1 + endtry + endif + endfor + + "swap this nodes children out for the children we just read/refreshed + let self.children = newChildNodes + call self.sortChildren() + + if invalidFilesFound + call s:echoWarning("some files could not be loaded into the NERD tree") + endif + endif +endfunction + +"FUNCTION: TreeDirNode.removeChild(treenode) {{{3 +" +"Removes the given treenode from this nodes set of children +" +"Args: +"treenode: the node to remove +" +"Throws a NERDTree.TreeDirNode exception if the given treenode is not found +function! s:TreeDirNode.removeChild(treenode) + for i in range(0, self.getChildCount()-1) + if self.children[i].equals(a:treenode) + call remove(self.children, i) + return + endif + endfor + + throw "NERDTree.TreeDirNode exception: child node was not found" +endfunction + +"FUNCTION: TreeDirNode.sortChildren() {{{3 +" +"Sorts the children of this node according to alphabetical order and the +"directory priority. +" +function! s:TreeDirNode.sortChildren() + let CompareFunc = function("s:compareNodes") + call sort(self.children, CompareFunc) +endfunction + +"FUNCTION: TreeDirNode.toggleOpen() {{{3 +"Opens this directory if it is closed and vice versa +function! s:TreeDirNode.toggleOpen() + if self.isOpen == 1 + call self.close() + else + call self.open() + endif +endfunction + +"FUNCTION: TreeDirNode.transplantChild(newNode) {{{3 +"Replaces the child of this with the given node (where the child node's full +"path matches a:newNode's fullpath). The search for the matching node is +"non-recursive +" +"Arg: +"newNode: the node to graft into the tree +function! s:TreeDirNode.transplantChild(newNode) + for i in range(0, self.getChildCount()-1) + if self.children[i].equals(a:newNode) + let self.children[i] = a:newNode + let a:newNode.parent = self + break + endif + endfor +endfunction +"============================================================ +"CLASS: Path {{{2 +"============================================================ +let s:Path = {} +"FUNCTION: Path.bookmarkNames() {{{3 +function! s:Path.bookmarkNames() + if !exists("self.bookmarkNames") + call self.cacheDisplayString() + endif + return self.bookmarkNames +endfunction +"FUNCTION: Path.cacheDisplayString() {{{3 +function! s:Path.cacheDisplayString() + let self.cachedDisplayString = self.getLastPathComponent(1) + + if self.isExecutable + let self.cachedDisplayString = self.cachedDisplayString . '*' + endif + + let self.bookmarkNames = [] + for i in s:Bookmark.Bookmarks() + if i.path.equals(self) + call add(self.bookmarkNames, i.name) + endif + endfor + if !empty(self.bookmarkNames) + let self.cachedDisplayString .= ' {' . join(self.bookmarkNames) . '}' + endif + + if self.isSymLink + let self.cachedDisplayString .= ' -> ' . self.symLinkDest + endif + + if self.isReadOnly + let self.cachedDisplayString .= ' [RO]' + endif +endfunction +"FUNCTION: Path.changeToDir() {{{3 +function! s:Path.changeToDir() + let dir = self.strForCd() + if self.isDirectory == 0 + let dir = self.getPathTrunk().strForCd() + endif + + try + execute "cd " . dir + call s:echo("CWD is now: " . getcwd()) + catch + throw "NERDTree.Path.Change exception: cannot change to " . dir + endtry +endfunction + +"FUNCTION: Path.compareTo() {{{3 +" +"Compares this Path to the given path and returns 0 if they are equal, -1 if +"this Path is "less than" the given path, or 1 if it is "greater". +" +"Args: +"path: the path object to compare this to +" +"Return: +"1, -1 or 0 +function! s:Path.compareTo(path) + let thisPath = self.getLastPathComponent(1) + let thatPath = a:path.getLastPathComponent(1) + + "if the paths are the same then clearly we return 0 + if thisPath == thatPath + return 0 + endif + + let thisSS = self.getSortOrderIndex() + let thatSS = a:path.getSortOrderIndex() + + "compare the sort sequences, if they are different then the return + "value is easy + if thisSS < thatSS + return -1 + elseif thisSS > thatSS + return 1 + else + "if the sort sequences are the same then compare the paths + "alphabetically + let pathCompare = g:NERDTreeCaseSensitiveSort ? thisPath <# thatPath : thisPath >> + +"FUNCTION: s:compareBookmarks(first, second) {{{2 +"Compares two bookmarks +function! s:compareBookmarks(first, second) + return a:first.compareTo(a:second) +endfunction + +" FUNCTION: s:completeBookmarks(A,L,P) {{{2 +" completion function for the bookmark commands +function! s:completeBookmarks(A,L,P) + return filter(s:Bookmark.BookmarkNames(), 'v:val =~ "^' . a:A . '"') +endfunction +"FUNCTION: s:initNerdTree(name) {{{2 +"Initialise the nerd tree for this tab. The tree will start in either the +"given directory, or the directory associated with the given bookmark +" +"Args: +"name: the name of a bookmark or a directory +function! s:initNerdTree(name) + let path = {} + if s:Bookmark.BookmarkExistsFor(a:name) + let path = s:Bookmark.BookmarkFor(a:name).path + else + let dir = a:name == '' ? expand('%:p:h') : a:name + let dir = resolve(dir) + try + let path = s:Path.New(dir) + catch /NERDTree.Path.InvalidArguments/ + call s:echo("No bookmark or directory found for: " . a:name) + return + endtry + endif + if !path.isDirectory + let path = path.getParent() + endif + + "if instructed to, then change the vim CWD to the dir the NERDTree is + "inited in + if g:NERDTreeChDirMode != 0 + exec 'cd ' . path.strForCd() + endif + + let t:treeShowHelp = 0 + let t:NERDTreeIgnoreEnabled = 1 + let t:NERDTreeShowFiles = g:NERDTreeShowFiles + let t:NERDTreeShowHidden = g:NERDTreeShowHidden + let t:NERDTreeShowBookmarks = g:NERDTreeShowBookmarks + + if s:treeExistsForTab() + if s:isTreeOpen() + call s:closeTree() + endif + unlet t:NERDTreeRoot + endif + + let t:NERDTreeRoot = s:TreeDirNode.New(path) + call t:NERDTreeRoot.open() + + call s:createTreeWin() + call s:renderView() + call s:putCursorOnNode(t:NERDTreeRoot, 0, 0) +endfunction +" Function: s:treeExistsForTab() {{{2 +" Returns 1 if a nerd tree root exists in the current tab +function! s:treeExistsForTab() + return exists("t:NERDTreeRoot") +endfunction +" SECTION: Public Functions {{{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.NoTreeForTab exception: there is no NERD tree open for the current tab" + endif + + let winnr = winnr() + if winnr != s:getTreeWinNum() + call s:putCursorInTreeWin() + endif + + let treenode = s:getSelectedNode() + + if winnr != winnr() + wincmd w + endif + + return treenode +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 +endfunction + +" SECTION: View Functions {{{1 +"============================================================ +"FUNCTION: s:centerView() {{{2 +"centers the nerd tree window around the cursor (provided the nerd tree +"options permit) +function! s:centerView() + if g:NERDTreeAutoCenter + let current_line = winline() + let lines_to_top = current_line + let lines_to_bottom = winheight(s:getTreeWinNum()) - current_line + if lines_to_top < g:NERDTreeAutoCenterThreshold || lines_to_bottom < g:NERDTreeAutoCenterThreshold + normal! zz + endif + endif +endfunction +"FUNCTION: s:closeTree() {{{2 +"Closes the NERD tree window +function! s:closeTree() + if !s:isTreeOpen() + throw "NERDTree.view.closeTree exception: no NERDTree is open" + endif + + if winnr("$") != 1 + execute s:getTreeWinNum() . " wincmd w" + close + execute "wincmd p" + else + :q + endif +endfunction + +"FUNCTION: s:closeTreeIfOpen() {{{2 +"Closes the NERD tree window if it is open +function! s:closeTreeIfOpen() + if s:isTreeOpen() + call s:closeTree() + endif +endfunction +"FUNCTION: s:closeTreeIfQuitOnOpen() {{{2 +"Closes the NERD tree window if the close on open option is set +function! s:closeTreeIfQuitOnOpen() + if g:NERDTreeQuitOnOpen + call s:closeTree() + endif +endfunction +"FUNCTION: s:createTreeWin() {{{2 +"Inits the NERD tree window. ie. opens it, sizes it, sets all the local +"options etc +function! s:createTreeWin() + "create the nerd tree window + let splitLocation = (g:NERDTreeWinPos == "top" || g:NERDTreeWinPos == "left") ? "topleft " : "botright " + let splitMode = s:shouldSplitVertically() ? "vertical " : "" + let splitSize = g:NERDTreeWinSize + let t:NERDTreeWinName = localtime() . s:NERDTreeWinName + let cmd = splitLocation . splitMode . splitSize . ' new ' . t:NERDTreeWinName + silent! execute cmd + + setlocal winfixwidth + + "throwaway buffer options + setlocal noswapfile + setlocal buftype=nofile + setlocal bufhidden=delete + setlocal nowrap + setlocal foldcolumn=0 + setlocal nobuflisted + setlocal nospell + if g:NERDTreeShowLineNumbers + setlocal nu + else + setlocal nonu + endif + + iabc + + if g:NERDTreeHighlightCursorline + setlocal cursorline + endif + + + " for line continuation + let cpo_save1 = &cpo + set cpo&vim + + call s:bindMappings() + setfiletype nerdtree + " syntax highlighting + if has("syntax") && exists("g:syntax_on") && !has("syntax_items") + call s:setupSyntaxHighlighting() + endif +endfunction + +"FUNCTION: s:drawTree {{{2 +"Draws the given node recursively +" +"Args: +"curNode: the node that is being rendered with this call +"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:drawTree(curNode, depth, drawText, vertMap, isLastChild) + 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 a:curNode.path.isDirectory + if a:curNode.isOpen + let treeParts = treeParts . '~' + else + let treeParts = treeParts . '+' + endif + else + let treeParts = treeParts . '-' + endif + let line = treeParts . a:curNode.strDisplay() + + call setline(line(".")+1, line) + call cursor(line(".")+1, col(".")) + endif + + "if the node is an open dir, draw its children + if a:curNode.path.isDirectory == 1 && a:curNode.isOpen == 1 + + let childNodesToDraw = a:curNode.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] + call s:drawTree(i, a:depth + 1, 1, add(copy(a:vertMap), 1), 0) + endfor + endif + + "draw the last child, indicating that it IS the last + call s:drawTree(childNodesToDraw[lastIndx], a:depth + 1, 1, add(copy(a:vertMap), 0), 1) + endif + endif +endfunction + + +"FUNCTION: s:dumpHelp {{{2 +"prints out the quick help +function! s:dumpHelp() + let old_h = @h + if t:treeShowHelp == 1 + let @h= "\" NERD tree (" . s:NERD_tree_version . ") quickhelp~\n" + let @h=@h."\" ============================\n" + let @h=@h."\" File node mappings~\n" + let @h=@h."\" ". (g:NERDTreeMouseMode == 3 ? "single" : "double") ."-click,\n" + let @h=@h."\" ". g:NERDTreeMapActivateNode .": open in prev window\n" + let @h=@h."\" ". g:NERDTreeMapPreview .": preview\n" + let @h=@h."\" ". g:NERDTreeMapOpenInTab.": open in new tab\n" + let @h=@h."\" ". g:NERDTreeMapOpenInTabSilent .": open in new tab silently\n" + let @h=@h."\" middle-click,\n" + let @h=@h."\" ". g:NERDTreeMapOpenSplit .": open split\n" + let @h=@h."\" ". g:NERDTreeMapPreviewSplit .": preview split\n" + let @h=@h."\" ". g:NERDTreeMapExecute.": Execute file\n" + + let @h=@h."\"\n\" ----------------------------\n" + let @h=@h."\" Directory node mappings~\n" + let @h=@h."\" ". (g:NERDTreeMouseMode == 1 ? "double" : "single") ."-click,\n" + let @h=@h."\" ". g:NERDTreeMapActivateNode .": open & close node\n" + let @h=@h."\" ". g:NERDTreeMapOpenRecursively .": recursively open node\n" + let @h=@h."\" ". g:NERDTreeMapCloseDir .": close parent of node\n" + let @h=@h."\" ". g:NERDTreeMapCloseChildren .": close all child nodes of\n" + let @h=@h."\" current node recursively\n" + let @h=@h."\" middle-click,\n" + let @h=@h."\" ". g:NERDTreeMapOpenExpl.": Open netrw for selected\n" + let @h=@h."\" node\n" + + let @h=@h."\"\n\" ----------------------------\n" + let @h=@h."\" Bookmark table mappings~\n" + let @h=@h."\" double-click,\n" + let @h=@h."\" ". g:NERDTreeMapActivateNode .": open bookmark\n" + let @h=@h."\" ". g:NERDTreeMapOpenInTab.": open in new tab\n" + let @h=@h."\" ". g:NERDTreeMapOpenInTabSilent .": open in new tab silently\n" + let @h=@h."\" ". g:NERDTreeMapDeleteBookmark .": delete bookmark\n" + + let @h=@h."\"\n\" ----------------------------\n" + let @h=@h."\" Tree navigation mappings~\n" + let @h=@h."\" ". g:NERDTreeMapJumpRoot .": go to root\n" + let @h=@h."\" ". g:NERDTreeMapJumpParent .": go to parent\n" + let @h=@h."\" ". g:NERDTreeMapJumpFirstChild .": go to first child\n" + let @h=@h."\" ". g:NERDTreeMapJumpLastChild .": go to last child\n" + let @h=@h."\" ". g:NERDTreeMapJumpNextSibling .": go to next sibling\n" + let @h=@h."\" ". g:NERDTreeMapJumpPrevSibling .": go to prev sibling\n" + + let @h=@h."\"\n\" ----------------------------\n" + let @h=@h."\" Filesystem mappings~\n" + let @h=@h."\" ". g:NERDTreeMapChangeRoot .": change tree root to the\n" + let @h=@h."\" selected dir\n" + let @h=@h."\" ". g:NERDTreeMapUpdir .": move tree root up a dir\n" + let @h=@h."\" ". g:NERDTreeMapUpdirKeepOpen .": move tree root up a dir\n" + let @h=@h."\" but leave old root open\n" + let @h=@h."\" ". g:NERDTreeMapRefresh .": refresh cursor dir\n" + let @h=@h."\" ". g:NERDTreeMapRefreshRoot .": refresh current root\n" + let @h=@h."\" ". g:NERDTreeMapFilesystemMenu .": Show filesystem menu\n" + let @h=@h."\" ". g:NERDTreeMapChdir .":change the CWD to the\n" + let @h=@h."\" selected dir\n" + + let @h=@h."\"\n\" ----------------------------\n" + let @h=@h."\" Tree filtering mappings~\n" + let @h=@h."\" ". g:NERDTreeMapToggleHidden .": hidden files (" . (t:NERDTreeShowHidden ? "on" : "off") . ")\n" + let @h=@h."\" ". g:NERDTreeMapToggleFilters .": file filters (" . (t:NERDTreeIgnoreEnabled ? "on" : "off") . ")\n" + let @h=@h."\" ". g:NERDTreeMapToggleFiles .": files (" . (t:NERDTreeShowFiles ? "on" : "off") . ")\n" + let @h=@h."\" ". g:NERDTreeMapToggleBookmarks .": bookmarks (" . (t:NERDTreeShowBookmarks ? "on" : "off") . ")\n" + + 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:NERDTreeMapHelp .": toggle help\n" + let @h=@h."\"\n\" ----------------------------\n" + let @h=@h."\" Bookmark commands~\n" + let @h=@h."\" :Bookmark \n" + let @h=@h."\" :BookmarkToRoot \n" + let @h=@h."\" :RevealBookmark \n" + let @h=@h."\" :OpenBookmark \n" + let @h=@h."\" :ClearBookmarks []\n" + let @h=@h."\" :ClearAllBookmarks\n" + else + let @h="\" Press ". g:NERDTreeMapHelp ." for help\n" + endif + + silent! put h + + let @h = old_h +endfunction +"FUNCTION: s:echo {{{2 +"A wrapper for :echo. Appends 'NERDTree:' on the front of all messages +" +"Args: +"msg: the message to echo +function! s:echo(msg) + redraw + echomsg "NERDTree: " . a:msg +endfunction +"FUNCTION: s:echoWarning {{{2 +"Wrapper for s:echo, sets the message type to warningmsg for this message +"Args: +"msg: the message to echo +function! s:echoWarning(msg) + echohl warningmsg + call s:echo(a:msg) + echohl normal +endfunction +"FUNCTION: s:echoError {{{2 +"Wrapper for s:echo, sets the message type to errormsg for this message +"Args: +"msg: the message to echo +function! s:echoError(msg) + echohl errormsg + call s:echo(a:msg) + echohl normal +endfunction +"FUNCTION: s:findNodeLineNumber(treenode){{{2 +"Finds the line number for the given tree node +" +"Args: +"treenode: the node to find the line no. for +function! s:findNodeLineNumber(treenode) + "if the node is the root then return the root line no. + if a:treenode.isRoot() + return s:findRootNodeLineNumber() + endif + + let totalLines = line("$") + + "the path components we have matched so far + let pathcomponents = [substitute(t:NERDTreeRoot.path.str(0), '/ *$', '', '')] + "the index of the component we are searching for + let curPathComponent = 1 + + let fullpath = a:treenode.path.str(0) + + + let lnum = s:findRootNodeLineNumber() + while lnum > 0 + let lnum = lnum + 1 + "have we reached the bottom of the tree? + if lnum == totalLines+1 + return -1 + endif + + let curLine = getline(lnum) + + let indent = match(curLine,s:tree_markup_reg_neg) / s:tree_wid + if indent == curPathComponent + let curLine = s:stripMarkupFromLine(curLine, 1) + + let curPath = join(pathcomponents, '/') . '/' . curLine + if stridx(fullpath, curPath, 0) == 0 + if fullpath == curPath || strpart(fullpath, len(curPath)-1,1) == '/' + let curLine = substitute(curLine, '/ *$', '', '') + call add(pathcomponents, curLine) + let curPathComponent = curPathComponent + 1 + + if fullpath == curPath + return lnum + endif + endif + endif + endif + endwhile + return -1 +endfunction + +"FUNCTION: s:findRootNodeLineNumber(){{{2 +"Finds the line number of the root node +function! s:findRootNodeLineNumber() + let rootLine = 1 + while getline(rootLine) !~ '^/' + let rootLine = rootLine + 1 + endwhile + return rootLine +endfunction + +"FUNCTION: s:getPath(ln) {{{2 +"Gets the full path to the node that is rendered on the given line number +" +"Args: +"ln: the line number to get the path for +" +"Return: +"A path if a node was selected, {} if nothing is selected. +"If the 'up a dir' line was selected then the path to the parent of the +"current root is returned +function! s:getPath(ln) + let line = getline(a:ln) + + "check to see if we have the root node + if line =~ '^\/' + return t:NERDTreeRoot.path + endif + + " in case called from outside the tree + if line !~ '^ *[|`]' || line =~ '^$' + return {} + endif + + if line == s:tree_up_dir_line + return t:NERDTreeRoot.path.getParent() + endif + + "get the indent level for the file (i.e. how deep in the tree it is) + let indent = match(line, s:tree_markup_reg_neg) / s:tree_wid + + + "remove the tree parts and the leading space + let curFile = s:stripMarkupFromLine(line, 0) + + let wasdir = 0 + if curFile =~ '/$' + let wasdir = 1 + let curFile = substitute(curFile, '/\?$', '/', "") + endif + + + let dir = "" + let lnum = a:ln + while lnum > 0 + let lnum = lnum - 1 + let curLine = getline(lnum) + let curLineStripped = s:stripMarkupFromLine(curLine, 1) + + "have we reached the top of the tree? + if curLine =~ '^/' + let dir = substitute (curLine, ' *$', "", "") . dir + break + endif + if curLineStripped =~ '/$' + let lpindent = match(curLine,s:tree_markup_reg_neg) / s:tree_wid + if lpindent < indent + let indent = indent - 1 + + let dir = substitute (curLineStripped,'^\\', "", "") . dir + continue + endif + endif + endwhile + let curFile = t:NERDTreeRoot.path.drive . dir . curFile + let toReturn = s:Path.New(curFile) + 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.BookmarkNotFound/ + return {} + endtry + endif + return {} +endfunction + +"FUNCTION: s:getSelectedDir() {{{2 +"Returns the current node if it is a dir node, or else returns the current +"nodes parent +function! s:getSelectedDir() + let currentDir = s:getSelectedNode() + if currentDir != {} && !currentDir.isRoot() + if currentDir.path.isDirectory == 0 + let currentDir = currentDir.parent + endif + endif + return currentDir +endfunction +"FUNCTION: s:getSelectedNode() {{{2 +"gets the treenode that the cursor is currently over +function! s:getSelectedNode() + try + let path = s:getPath(line(".")) + if path == {} + return {} + endif + return t:NERDTreeRoot.findNode(path) + catch /^NERDTree/ + return {} + endtry +endfunction +"FUNCTION: s:getTreeWinNum() {{{2 +"gets the nerd tree window number for this tab +function! s:getTreeWinNum() + if exists("t:NERDTreeWinName") + return bufwinnr(t:NERDTreeWinName) + else + return -1 + endif +endfunction + +"FUNCTION: s:isTreeOpen() {{{2 +function! s:isTreeOpen() + return s:getTreeWinNum() != -1 +endfunction + +" FUNCTION: s:jumpToChild(direction) {{{2 +" Args: +" direction: 0 if going to first child, 1 if going to last +function! s:jumpToChild(direction) + let currentNode = s:getSelectedNode() + if currentNode == {} || currentNode.isRoot() + call s:echo("cannot jump to " . (a:direction ? "last" : "first") . " child") + return + end + let dirNode = currentNode.parent + let childNodes = dirNode.getVisibleChildren() + + let targetNode = childNodes[0] + if a:direction + let targetNode = childNodes[len(childNodes) - 1] + endif + + if targetNode.equals(currentNode) + let siblingDir = currentNode.parent.findOpenDirSiblingWithChildren(a:direction) + if siblingDir != {} + let indx = a:direction ? siblingDir.getVisibleChildCount()-1 : 0 + let targetNode = siblingDir.getChildByIndex(indx, 1) + endif + endif + + call s:putCursorOnNode(targetNode, 1, 0) + + call s:centerView() +endfunction + + +"FUNCTION: s:openDirNodeSplit(treenode) {{{2 +"Open the file represented by the given node in a new window. +"No action is taken for file nodes +" +"ARGS: +"treenode: file node to open +function! s:openDirNodeSplit(treenode) + if a:treenode.path.isDirectory == 1 + call s:openNodeSplit(a:treenode) + endif +endfunction + +" FUNCTION: s:openExplorerFor(treenode) {{{2 +" opens a netrw window for the given dir treenode +function! s:openExplorerFor(treenode) + let oldwin = winnr() + wincmd p + if oldwin == winnr() || (&modified && s:bufInWindows(winbufnr(winnr())) < 2) + wincmd p + call s:openDirNodeSplit(a:treenode) + else + exec ("silent edit " . a:treenode.path.strForEditCmd()) + endif +endfunction +"FUNCTION: s:openFileNode(treenode) {{{2 +"Open the file represented by the given node in the current window, splitting +"the window if needed +" +"ARGS: +"treenode: file node to open +function! s:openFileNode(treenode) + call s:putCursorInTreeWin() + + "if the file is already open in this tab then just stick the cursor in it + let winnr = bufwinnr('^' . a:treenode.path.strForOS(0) . '$') + if winnr != -1 + exec winnr . "wincmd w" + + elseif s:shouldSplitToOpen(winnr("#")) + call s:openFileNodeSplit(a:treenode) + else + try + wincmd p + exec ("edit " . a:treenode.path.strForEditCmd()) + catch /^Vim\%((\a\+)\)\=:E37/ + call s:putCursorInTreeWin() + call s:echo("Cannot open file, it is already open and modified") + catch /^Vim\%((\a\+)\)\=:/ + echo v:exception + endtry + endif +endfunction + +"FUNCTION: s:openFileNodeSplit(treenode) {{{2 +"Open the file represented by the given node in a new window. +"No action is taken for dir nodes +" +"ARGS: +"treenode: file node to open +function! s:openFileNodeSplit(treenode) + if a:treenode.path.isDirectory == 0 + try + call s:openNodeSplit(a:treenode) + catch /^NERDTree.view.FileOpen/ + call s:echo("Cannot open file, it is already open and modified" ) + endtry + endif +endfunction + +"FUNCTION: s:openNodeSplit(treenode) {{{2 +"Open the file/dir represented by the given node in a new window +" +"ARGS: +"treenode: file node to open +function! s:openNodeSplit(treenode) + call s:putCursorInTreeWin() + + " Save the user's settings for splitbelow and splitright + let savesplitbelow=&splitbelow + let savesplitright=&splitright + + " Figure out how to do the split based on the user's preferences. + " We want to split to the (left,right,top,bottom) of the explorer + " window, but we want to extract the screen real-estate from the + " window next to the explorer if possible. + " + " 'there' will be set to a command to move from the split window + " back to the explorer window + " + " 'back' will be set to a command to move from the explorer window + " back to the newly split window + " + " 'right' and 'below' will be set to the settings needed for + " splitbelow and splitright IF the explorer is the only window. + " + if s:shouldSplitVertically() + let there= g:NERDTreeWinPos == "left" ? "wincmd h" : "wincmd l" + let back = g:NERDTreeWinPos == "left" ? "wincmd l" : "wincmd h" + let right= g:NERDTreeWinPos == "left" + let below=0 + else + let there= g:NERDTreeWinPos == "top" ? "wincmd k" : "wincmd j" + let back = g:NERDTreeWinPos == "top" ? "wincmd j" : "wincmd k" + let below= g:NERDTreeWinPos == "top" + let right=0 + endif + + " Attempt to go to adjacent window + exec(back) + + let onlyOneWin = (winnr() == s:getTreeWinNum()) + + " If no adjacent window, set splitright and splitbelow appropriately + if onlyOneWin + let &splitright=right + let &splitbelow=below + else + " found adjacent window - invert split direction + let &splitright=!right + let &splitbelow=!below + endif + + " Create a variable to use if splitting vertically + let splitMode = "" + if (onlyOneWin && s:shouldSplitVertically()) || (!onlyOneWin && !s:shouldSplitVertically()) + let splitMode = "vertical" + endif + + echomsg splitMode + + " Open the new window + try + exec(splitMode." sp " . a:treenode.path.strForEditCmd()) + catch /^Vim\%((\a\+)\)\=:E37/ + call s:putCursorInTreeWin() + throw "NERDTree.view.FileOpen exception: ". a:treenode.path.str(0) ." is already open and modified." + catch /^Vim\%((\a\+)\)\=:/ + "do nothing + endtry + + "resize the tree window if no other window was open before + if onlyOneWin + let size = exists("t:NERDTreeOldWindowSize") ? t:NERDTreeOldWindowSize : g:NERDTreeWinSize + exec(there) + exec("silent ". splitMode ." resize ". size) + wincmd p + endif + + " Restore splitmode settings + let &splitbelow=savesplitbelow + let &splitright=savesplitright +endfunction + +"FUNCTION: s:promptToDelBuffer(bufnum, msg){{{2 +"prints out the given msg and, if the user responds by pushing 'y' then the +"buffer with the given bufnum is deleted +" +"Args: +"bufnum: the buffer that may be deleted +"msg: a message that will be echoed to the user asking them if they wish to +" del the buffer +function! s:promptToDelBuffer(bufnum, msg) + echo a:msg + if nr2char(getchar()) == 'y' + exec "silent bdelete! " . a:bufnum + endif +endfunction + +"FUNCTION: s:putCursorOnBookmarkTable(){{{2 +"Places the cursor at the top of the bookmarks table +function! s:putCursorOnBookmarkTable() + if !t:NERDTreeShowBookmarks + throw "NERDTree.IllegalOperation exception: cant find bookmark table, bookmarks arent active" + endif + + let rootNodeLine = s:findRootNodeLineNumber() + + let line = 1 + while getline(line) !~ '^>-\+Bookmarks-\+$' + let line = line + 1 + if line >= rootNodeLine + throw "NERDTree.BookmarkTableNotFound exception: didnt find the bookmarks table" + endif + endwhile + call cursor(line, 0) +endfunction + +"FUNCTION: s:putCursorOnNode(treenode, isJump, recurseUpward){{{2 +"Places the cursor on the line number representing the given node +" +"Args: +"treenode: the node to put the cursor on +"isJump: 1 if this cursor movement should be counted as a jump by vim +"recurseUpward: try to put the cursor on the parent if the this node isnt +"visible +function! s:putCursorOnNode(treenode, isJump, recurseUpward) + let ln = s:findNodeLineNumber(a:treenode) + if ln != -1 + if a:isJump + mark ' + endif + call cursor(ln, col(".")) + else + if a:recurseUpward + let node = a:treenode + while s:findNodeLineNumber(node) == -1 && node != {} + let node = node.parent + call node.open() + endwhile + call s:renderView() + call s:putCursorOnNode(a:treenode, a:isJump, 0) + endif + endif +endfunction + +"FUNCTION: s:putCursorInTreeWin(){{{2 +"Places the cursor in the nerd tree window +function! s:putCursorInTreeWin() + if !s:isTreeOpen() + throw "NERDTree.view.InvalidOperation Exception: No NERD tree window exists" + endif + + exec s:getTreeWinNum() . "wincmd w" +endfunction + +"FUNCTION: s:renderBookmarks {{{2 +function! s:renderBookmarks() + + call setline(line(".")+1, ">----------Bookmarks----------") + call cursor(line(".")+1, col(".")) + + for i in s:Bookmark.Bookmarks() + call setline(line(".")+1, i.str()) + call cursor(line(".")+1, col(".")) + endfor + + call setline(line(".")+1, '') + call cursor(line(".")+1, col(".")) +endfunction +"FUNCTION: s:renderView {{{2 +"The entry function for rendering the tree. Renders the root then calls +"s:drawTree to draw the children of the root +" +"Args: +function! s:renderView() + execute s:getTreeWinNum() . "wincmd w" + + setlocal modifiable + + "remember the top line of the buffer and the current line so we can + "restore the view exactly how it was + let curLine = line(".") + let curCol = col(".") + let topLine = line("w0") + + "delete all lines in the buffer (being careful not to clobber a register) + silent 1,$delete _ + + call s:dumpHelp() + + "delete the blank line before the help and add one after it + call setline(line(".")+1, "") + call cursor(line(".")+1, col(".")) + + if t:NERDTreeShowBookmarks + call s:renderBookmarks() + endif + + "add the 'up a dir' line + call setline(line(".")+1, s:tree_up_dir_line) + call cursor(line(".")+1, col(".")) + + "draw the header line + call setline(line(".")+1, t:NERDTreeRoot.path.str(0)) + call cursor(line(".")+1, col(".")) + + "draw the tree + call s:drawTree(t:NERDTreeRoot, 0, 0, [], t:NERDTreeRoot.getChildCount() == 1) + + "delete the blank line at the top of the buffer + silent 1,1delete _ + + "restore the view + let old_scrolloff=&scrolloff + let &scrolloff=0 + call cursor(topLine, 1) + normal! zt + call cursor(curLine, curCol) + let &scrolloff = old_scrolloff + + setlocal nomodifiable +endfunction + +"FUNCTION: s:renderViewSavingPosition {{{2 +"Renders the tree and ensures the cursor stays on the current node or the +"current nodes parent if it is no longer available upon re-rendering +function! s:renderViewSavingPosition() + let currentNode = s:getSelectedNode() + + "go up the tree till we find a node that will be visible or till we run + "out of nodes + while currentNode != {} && !currentNode.isVisible() && !currentNode.isRoot() + let currentNode = currentNode.parent + endwhile + + call s:renderView() + + if currentNode != {} + call s:putCursorOnNode(currentNode, 0, 0) + endif +endfunction +"FUNCTION: s:restoreScreenState() {{{2 +" +"Sets the screen state back to what it was when s:saveScreenState was last +"called. +" +"Assumes the cursor is in the NERDTree window +function! s:restoreScreenState() + if !exists("t:NERDTreeOldTopLine") || !exists("t:NERDTreeOldPos") || !exists("t:NERDTreeOldWindowSize") + return + endif + exec("silent ". (s:shouldSplitVertically() ? "vertical" : "") ." resize ".t:NERDTreeOldWindowSize) + + let old_scrolloff=&scrolloff + let &scrolloff=0 + call cursor(t:NERDTreeOldTopLine, 0) + normal! zt + call setpos(".", t:NERDTreeOldPos) + let &scrolloff=old_scrolloff +endfunction + +"FUNCTION: s:saveScreenState() {{{2 +"Saves the current cursor position in the current buffer and the window +"scroll position +function! s:saveScreenState() + let win = winnr() + call s:putCursorInTreeWin() + let t:NERDTreeOldPos = getpos(".") + let t:NERDTreeOldTopLine = line("w0") + let t:NERDTreeOldWindowSize = s:shouldSplitVertically() ? winwidth("") : winheight("") + exec win . "wincmd w" +endfunction + +"FUNCTION: s:setupSyntaxHighlighting() {{{2 +function! s:setupSyntaxHighlighting() + "treeFlags are syntax items that should be invisible, but give clues as to + "how things should be highlighted + syn match treeFlag #\~# + syn match treeFlag #\[RO\]# + + "highlighting for the .. (up dir) line at the top of the tree + execute "syn match treeUp #". s:tree_up_dir_line ."#" + + "highlighting for the ~/+ symbols for the directory nodes + syn match treeClosable #\~\<# + syn match treeClosable #\~\.# + syn match treeOpenable #+\<# + syn match treeOpenable #+\.#he=e-1 + + "highlighting for the tree structural parts + syn match treePart #|# + syn match treePart #`# + syn match treePartFile #[|`]-#hs=s+1 contains=treePart + + "quickhelp syntax elements + syn match treeHelpKey #" \{1,2\}[^ ]*:#hs=s+2,he=e-1 + syn match treeHelpKey #" \{1,2\}[^ ]*,#hs=s+2,he=e-1 + syn match treeHelpTitle #" .*\~#hs=s+2,he=e-1 contains=treeFlag + syn match treeToggleOn #".*(on)#hs=e-2,he=e-1 contains=treeHelpKey + syn match treeToggleOff #".*(off)#hs=e-3,he=e-1 contains=treeHelpKey + syn match treeHelpCommand #" :.\{-}\>#hs=s+3 + syn match treeHelp #^".*# contains=treeHelpKey,treeHelpTitle,treeFlag,treeToggleOff,treeToggleOn,treeHelpCommand + + "highlighting for readonly files + syn match treeRO #[\/0-9a-zA-Z]\+.*\[RO\]# contains=treeFlag,treeBookmark + + "highlighting for sym links + syn match treeLink #[^-| `].* -> # contains=treeBookmark,treeOpenable,treeClosable,treeDirSlash + + "highlighing for directory nodes and file nodes + syn match treeDirSlash #/# + syn match treeDir #[^-| `].*/# contains=treeLink,treeDirSlash,treeOpenable,treeClosable + syn match treeExecFile #[|`]-.*\*\($\| \)# contains=treeLink,treePart,treeRO,treePartFile,treeBookmark + syn match treeFile #|-.*# contains=treeLink,treePart,treeRO,treePartFile,treeBookmark,treeExecFile + syn match treeFile #`-.*# contains=treeLink,treePart,treeRO,treePartFile,treeBookmark,treeExecFile + syn match treeCWD #^/.*$# + + "highlighting for bookmarks + syn match treeBookmark # {.*}#hs=s+1 + + "highlighting for the bookmarks table + syn match treeBookmarksLeader #^># + syn match treeBookmarksHeader #^>-\+Bookmarks-\+$# contains=treeBookmarksLeader + syn match treeBookmarkName #^>.\{-} #he=e-1 contains=treeBookmarksLeader + syn match treeBookmark #^>.*$# contains=treeBookmarksLeader,treeBookmarkName,treeBookmarksHeader + + if g:NERDChristmasTree + hi def link treePart Special + hi def link treePartFile Type + hi def link treeFile Normal + hi def link treeExecFile Title + hi def link treeDirSlash Identifier + hi def link treeClosable Type + else + hi def link treePart Normal + hi def link treePartFile Normal + hi def link treeFile Normal + hi def link treeClosable Title + endif + + hi def link treeBookmarksHeader statement + hi def link treeBookmarksLeader ignore + hi def link treeBookmarkName Identifier + hi def link treeBookmark normal + + hi def link treeHelp String + hi def link treeHelpKey Identifier + hi def link treeHelpCommand Identifier + hi def link treeHelpTitle Macro + hi def link treeToggleOn Question + hi def link treeToggleOff WarningMsg + + hi def link treeDir Directory + hi def link treeUp Directory + hi def link treeCWD Statement + hi def link treeLink Macro + hi def link treeOpenable Title + hi def link treeFlag ignore + hi def link treeRO WarningMsg + hi def link treeBookmark Statement + + hi def link NERDTreeCurrentNode Search +endfunction + +"FUNCTION: s:shouldSplitToOpen() {{{2 +"Returns 1 if opening a file from the tree in the given window requires it to +"be split +" +"Args: +"winnumber: the number of the window in question +function! s:shouldSplitToOpen(winnumber) + "gotta split if theres only one window (i.e. the NERD tree) + if winnr("$") == 1 + return 1 + endif + + let oldwinnr = winnr() + exec a:winnumber . "wincmd p" + let specialWindow = getbufvar("%", '&buftype') != '' || getwinvar('%', '&previewwindow') + let modified = &modified + exec oldwinnr . "wincmd p" + + "if its a special window e.g. quickfix or another explorer plugin then we + "have to split + if specialWindow + return 1 + endif + + if &hidden + return 0 + endif + + return modified && s:bufInWindows(winbufnr(a:winnumber)) < 2 +endfunction + +" Function: s:shouldSplitVertically() {{{2 +" Returns 1 if g:NERDTreeWinPos is 'left' or 'right' +function! s:shouldSplitVertically() + return g:NERDTreeWinPos == 'left' || g:NERDTreeWinPos == 'right' +endfunction +"FUNCTION: s:stripMarkupFromLine(line, removeLeadingSpaces){{{2 +"returns the given line with all the tree parts stripped off +" +"Args: +"line: the subject line +"removeLeadingSpaces: 1 if leading spaces are to be removed (leading spaces = +"any spaces before the actual text of the node) +function! s:stripMarkupFromLine(line, removeLeadingSpaces) + let line = a:line + "remove the tree parts and the leading space + let line = substitute (line,"^" . s:tree_markup_reg . "*","","") + + "strip off any read only flag + let line = substitute (line, ' \[RO\]', "","") + + "strip off any bookmark flags + let line = substitute (line, ' {[^}]*}', "","") + + "strip off any executable flags + let line = substitute (line, '*\ze\($\| \)', "","") + + let wasdir = 0 + if line =~ '/$' + let wasdir = 1 + endif + let line = substitute (line,' -> .*',"","") " remove link to + if wasdir == 1 + let line = substitute (line, '/\?$', '/', "") + endif + + if a:removeLeadingSpaces + let line = substitute (line, '^ *', '', '') + endif + + return line +endfunction + +"FUNCTION: s:toggle(dir) {{{2 +"Toggles the NERD tree. I.e the NERD tree is open, it is closed, if it is +"closed it is restored or initialized (if it doesnt exist) +" +"Args: +"dir: the full path for the root node (is only used if the NERD tree is being +"initialized. +function! s:toggle(dir) + if s:treeExistsForTab() + if !s:isTreeOpen() + call s:createTreeWin() + call s:renderView() + + call s:restoreScreenState() + else + call s:closeTree() + endif + else + call s:initNerdTree(a:dir) + endif +endfunction +"SECTION: Interface bindings {{{1 +"============================================================ +"FUNCTION: s:activateNode(forceKeepWindowOpen) {{{2 +"If the current node is a file, open it in the previous window (or a new one +"if the previous is modified). If it is a directory then it is opened. +" +"args: +"forceKeepWindowOpen - dont close the window even if NERDTreeQuitOnOpen is set +function! s:activateNode(forceKeepWindowOpen) + if getline(".") == s:tree_up_dir_line + return s:upDir(0) + endif + + let treenode = s:getSelectedNode() + if treenode != {} + if treenode.path.isDirectory + call treenode.toggleOpen() + call s:renderView() + call s:putCursorOnNode(treenode, 0, 0) + else + call s:openFileNode(treenode) + if !a:forceKeepWindowOpen + call s:closeTreeIfQuitOnOpen() + end + endif + else + let bookmark = s:getSelectedBookmark() + if !empty(bookmark) + if bookmark.path.isDirectory + call bookmark.toRoot() + else + if bookmark.validate() + call s:openFileNode(s:TreeFileNode.New(bookmark.path)) + endif + endif + endif + endif +endfunction + +"FUNCTION: s:bindMappings() {{{2 +function! s:bindMappings() + " set up mappings and commands for this buffer + nnoremap :call handleMiddleMouse() + nnoremap :call checkForActivate() + nnoremap <2-leftmouse> :call activateNode(0) + + exec "nnoremap ". g:NERDTreeMapActivateNode . " :call activateNode(0)" + exec "nnoremap ". g:NERDTreeMapOpenSplit ." :call openEntrySplit(0)" + + exec "nnoremap ". g:NERDTreeMapPreview ." :call previewNode(0)" + exec "nnoremap ". g:NERDTreeMapPreviewSplit ." :call previewNode(1)" + + + exec "nnoremap ". g:NERDTreeMapExecute ." :call executeNode()" + + exec "nnoremap ". g:NERDTreeMapOpenRecursively ." :call openNodeRecursively()" + + exec "nnoremap ". g:NERDTreeMapUpdirKeepOpen ." :call upDir(1)" + exec "nnoremap ". g:NERDTreeMapUpdir ." :call upDir(0)" + exec "nnoremap ". g:NERDTreeMapChangeRoot ." :call chRoot()" + + exec "nnoremap ". g:NERDTreeMapChdir ." :call chCwd()" + + exec "nnoremap ". g:NERDTreeMapQuit ." :NERDTreeToggle" + + exec "nnoremap ". g:NERDTreeMapRefreshRoot ." :call refreshRoot()" + exec "nnoremap ". g:NERDTreeMapRefresh ." :call refreshCurrent()" + + exec "nnoremap ". g:NERDTreeMapHelp ." :call displayHelp()" + exec "nnoremap ". g:NERDTreeMapToggleHidden ." :call toggleShowHidden()" + exec "nnoremap ". g:NERDTreeMapToggleFilters ." :call toggleIgnoreFilter()" + exec "nnoremap ". g:NERDTreeMapToggleFiles ." :call toggleShowFiles()" + exec "nnoremap ". g:NERDTreeMapToggleBookmarks ." :call toggleShowBookmarks()" + + exec "nnoremap ". g:NERDTreeMapCloseDir ." :call closeCurrentDir()" + exec "nnoremap ". g:NERDTreeMapCloseChildren ." :call closeChildren()" + + exec "nnoremap ". g:NERDTreeMapFilesystemMenu ." :call showFileSystemMenu()" + + exec "nnoremap ". g:NERDTreeMapJumpParent ." :call jumpToParent()" + exec "nnoremap ". g:NERDTreeMapJumpNextSibling ." :call jumpToSibling(1)" + exec "nnoremap ". g:NERDTreeMapJumpPrevSibling ." :call jumpToSibling(0)" + exec "nnoremap ". g:NERDTreeMapJumpFirstChild ." :call jumpToFirstChild()" + exec "nnoremap ". g:NERDTreeMapJumpLastChild ." :call jumpToLastChild()" + exec "nnoremap ". g:NERDTreeMapJumpRoot ." :call jumpToRoot()" + + exec "nnoremap ". g:NERDTreeMapOpenInTab ." :call openInNewTab(0)" + exec "nnoremap ". g:NERDTreeMapOpenInTabSilent ." :call openInNewTab(1)" + + exec "nnoremap ". g:NERDTreeMapOpenExpl ." :call openExplorer()" + + exec "nnoremap ". g:NERDTreeMapDeleteBookmark ." :call deleteBookmark()" + + 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('') + command! -buffer -complete=customlist,s:completeBookmarks -nargs=* ClearBookmarks call clearBookmarks('') + command! -buffer -complete=customlist,s:completeBookmarks -nargs=+ BookmarkToRoot call s:Bookmark.ToRoot('') + command! -buffer -nargs=0 ClearAllBookmarks call s:Bookmark.ClearAll() call renderView() + command! -buffer -nargs=0 ReadBookmarks call s:Bookmark.CacheBookmarks(0) call renderView() + command! -buffer -nargs=0 WriteBookmarks call s:Bookmark.Write() +endfunction + +" FUNCTION: s:bookmarkNode(name) {{{2 +" Associate the current node with the given name +function! s:bookmarkNode(name) + let currentNode = s:getSelectedNode() + if currentNode != {} + try + call currentNode.bookmark(a:name) + call s:renderView() + catch /NERDTree.IllegalBookmarkName/ + call s:echo("bookmark names must not contain spaces") + endtry + else + call s:echo("select a node first") + endif +endfunction +"FUNCTION: s:checkForActivate() {{{2 +"Checks if the click should open the current node, if so then activate() is +"called (directories are automatically opened if the symbol beside them is +"clicked) +function! s:checkForActivate() + let currentNode = s:getSelectedNode() + if currentNode != {} + let startToCur = strpart(getline(line(".")), 0, col(".")) + let char = strpart(startToCur, strlen(startToCur)-1, 1) + + "if they clicked a dir, check if they clicked on the + or ~ sign + "beside it + if currentNode.path.isDirectory + let reg = '^' . s:tree_markup_reg .'*[~+]$' + if startToCur =~ reg + call s:activateNode(0) + return + endif + endif + + if (g:NERDTreeMouseMode == 2 && currentNode.path.isDirectory) || g:NERDTreeMouseMode == 3 + if char !~ s:tree_markup_reg && startToCur !~ '\/$' + call s:activateNode(0) + return + endif + endif + endif +endfunction + +" FUNCTION: s:chCwd() {{{2 +function! s:chCwd() + let treenode = s:getSelectedNode() + if treenode == {} + call s:echo("Select a node first") + return + endif + + try + call treenode.path.changeToDir() + catch /^NERDTree.Path.Change/ + call s:echoWarning("could not change cwd") + endtry +endfunction + +" FUNCTION: s:chRoot() {{{2 +" changes the current root to the selected one +function! s:chRoot() + let treenode = s:getSelectedNode() + if treenode == {} + call s:echo("Select a node first") + return + endif + + call treenode.makeRoot() + call s:renderView() + call s:putCursorOnNode(t:NERDTreeRoot, 0, 0) +endfunction + +" FUNCTION: s:clearBookmarks(bookmarks) {{{2 +function! s:clearBookmarks(bookmarks) + if a:bookmarks == '' + let currentNode = s:getSelectedNode() + if currentNode != {} + call currentNode.clearBoomarks() + endif + else + for name in split(a:bookmarks, ' ') + let bookmark = s:Bookmark.BookmarkFor(name) + call bookmark.delete() + endfor + endif + call s:renderView() +endfunction +" FUNCTION: s:closeChildren() {{{2 +" closes all childnodes of the current node +function! s:closeChildren() + let currentNode = s:getSelectedDir() + if currentNode == {} + call s:echo("Select a node first") + return + endif + + call currentNode.closeChildren() + call s:renderView() + call s:putCursorOnNode(currentNode, 0, 0) +endfunction +" FUNCTION: s:closeCurrentDir() {{{2 +" closes the parent dir of the current node +function! s:closeCurrentDir() + let treenode = s:getSelectedNode() + if treenode == {} + call s:echo("Select a node first") + return + endif + + let parent = treenode.parent + if parent.isRoot() + call s:echo("cannot close tree root") + else + call treenode.parent.close() + call s:renderView() + call s:putCursorOnNode(treenode.parent, 0, 0) + endif +endfunction + +" FUNCTION: s:copyNode() {{{2 +function! s:copyNode() + let currentNode = s:getSelectedNode() + 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 s:putCursorOnNode(newNode, 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() + if bookmark == {} + call s:echo("Put the cursor on a bookmark") + return + endif + + echo "Are you sure you wish to delete the bookmark:\n\"" . bookmark.name . "\" (yN):" + + if nr2char(getchar()) == 'y' + try + call bookmark.delete() + call s:renderView() + redraw + catch /^NERDTree/ + call s:echoWarning("Could not remove bookmark") + endtry + else + call s:echo("delete aborted" ) + endif + +endfunction + +" FUNCTION: s: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:getSelectedNode() + 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() + let t:treeShowHelp = t:treeShowHelp ? 0 : 1 + call s:renderView() + call s:centerView() +endfunction + +" FUNCTION: s:executeNode() {{{2 +function! s:executeNode() + let treenode = s:getSelectedNode() + 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:getSelectedNode() + if curNode == {} + call s:echo("Put the cursor on a node first" ) + return + endif + + if curNode.path.isDirectory + call s:openExplorer() + else + call s:openEntrySplit(0) + endif +endfunction + + +" FUNCTION: s:insertNewNode() {{{2 +" Adds a new node to the filesystem and then into the tree +function! s:insertNewNode() + let curDirNode = s:getSelectedDir() + 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 = t: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 s:putCursorOnNode(newTreeNode, 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() + call s:jumpToChild(0) +endfunction + +" FUNCTION: s:jumpToLastChild() {{{2 +" wrapper for the jump to child method +function! s:jumpToLastChild() + call s:jumpToChild(1) +endfunction + +" FUNCTION: s:jumpToParent() {{{2 +" moves the cursor to the parent of the current node +function! s:jumpToParent() + let currentNode = s:getSelectedNode() + if !empty(currentNode) + if !empty(currentNode.parent) + call s:putCursorOnNode(currentNode.parent, 1, 0) + call s:centerView() + else + call s:echo("cannot jump to parent") + endif + else + call s:echo("put the cursor on a node first") + endif +endfunction + +" FUNCTION: s:jumpToRoot() {{{2 +" moves the cursor to the root node +function! s:jumpToRoot() + call s:putCursorOnNode(t:NERDTreeRoot, 1, 0) + call s:centerView() +endfunction + +" FUNCTION: s:jumpToSibling() {{{2 +" moves the cursor to the sibling of the current node in the given direction +" +" Args: +" forward: 1 if the cursor should move to the next sibling, 0 if it should +" move back to the previous sibling +function! s:jumpToSibling(forward) + let currentNode = s:getSelectedNode() + if !empty(currentNode) + let sibling = currentNode.findSibling(a:forward) + + if !empty(sibling) + call s:putCursorOnNode(sibling, 1, 0) + call s:centerView() + endif + else + call s:echo("put the cursor on a node first") + endif +endfunction + +" FUNCTION: s:openBookmark(name) {{{2 +" put the cursor on the given bookmark and, if its a file, open it +function! s:openBookmark(name) + try + let targetNode = s:Bookmark.GetNodeForName(a:name, 0) + call s:putCursorOnNode(targetNode, 0, 1) + redraw! + catch /NERDTree.BookmarkedNodeNotFound/ + call s:echo("note - target node is not cached") + let bookmark = s:Bookmark.BookmarkFor(a:name) + let targetNode = s:TreeFileNode.New(bookmark.path) + endtry + if targetNode.path.isDirectory + call s:openExplorerFor(targetNode) + else + call s:openFileNode(targetNode) + endif +endfunction +" FUNCTION: s:openEntrySplit(forceKeepWindowOpen) {{{2 +"Opens the currently selected file from the explorer in a +"new window +" +"args: +"forceKeepWindowOpen - dont close the window even if NERDTreeQuitOnOpen is set +function! s:openEntrySplit(forceKeepWindowOpen) + let treenode = s:getSelectedNode() + if treenode != {} + call s:openFileNodeSplit(treenode) + if !a:forceKeepWindowOpen + call s:closeTreeIfQuitOnOpen() + endif + else + call s:echo("select a node first") + endif +endfunction + +" FUNCTION: s:openExplorer() {{{2 +function! s:openExplorer() + let treenode = s:getSelectedDir() + if treenode != {} + call s:openExplorerFor(treenode) + else + call s:echo("select a node first") + endif +endfunction + +" FUNCTION: s:openInNewTab(stayCurrentTab) {{{2 +" Opens the selected node or bookmark in a new tab +" Args: +" stayCurrentTab: if 1 then vim will stay in the current tab, if 0 then vim +" will go to the tab where the new file is opened +function! s:openInNewTab(stayCurrentTab) + let currentTab = tabpagenr() + + let treenode = s:getSelectedNode() + 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 + endif + if a:stayCurrentTab + exec "tabnext " . currentTab + endif +endfunction + +" FUNCTION: s:openNodeRecursively() {{{2 +function! s:openNodeRecursively() + let treenode = s:getSelectedNode() + if treenode == {} || treenode.path.isDirectory == 0 + call s:echo("Select a directory node first" ) + else + call s:echo("Recursively opening node. Please wait...") + call treenode.openRecursively() + call s:renderView() + redraw + call s:echo("Recursively opening node. Please wait... DONE") + endif + +endfunction + +"FUNCTION: s:previewNode() {{{2 +function! s:previewNode(openNewWin) + if a:openNewWin + call s:openEntrySplit(1) + else + call s:activateNode(1) + end + call s:putCursorInTreeWin() +endfunction + +" FUNCTION: s:revealBookmark(name) {{{2 +" put the cursor on the node associate with the given name +function! s:revealBookmark(name) + try + let targetNode = s:Bookmark.GetNodeForName(a:name, 0) + call s:putCursorOnNode(targetNode, 0, 1) + catch /NERDTree.BookmarkDoesntExist/ + call s:echo("Bookmark isnt cached under the current root") + endtry +endfunction +" FUNCTION: s:refreshRoot() {{{2 +" Reloads the current root. All nodes below this will be lost and the root dir +" will be reloaded. +function! s:refreshRoot() + call s:echo("Refreshing the root node. This could take a while...") + call t:NERDTreeRoot.refresh() + call s:renderView() + redraw + call s:echo("Refreshing the root node. This could take a while... DONE") +endfunction + +" FUNCTION: s:refreshCurrent() {{{2 +" refreshes the root for the current node +function! s:refreshCurrent() + let treenode = s:getSelectedDir() + if treenode == {} + call s:echo("Refresh failed. Select a node first") + return + endif + + call s:echo("Refreshing node. This could take a while...") + call treenode.refresh() + call s:renderView() + redraw + call s:echo("Refreshing node. This could take a while... DONE") +endfunction +" FUNCTION: s:renameCurrent() {{{2 +" allows the user to rename the current node +function! s:renameCurrent() + let curNode = s:getSelectedNode() + 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 s:putCursorOnNode(curNode, 1, 0) + + redraw + catch /^NERDTree/ + call s:echoWarning("Node Not Renamed.") + endtry +endfunction + +" FUNCTION: s:showFileSystemMenu() {{{2 +function! s:showFileSystemMenu() + let curNode = s:getSelectedNode() + 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 +endfunction + +" FUNCTION: s:toggleIgnoreFilter() {{{2 +" toggles the use of the NERDTreeIgnore option +function! s:toggleIgnoreFilter() + let t:NERDTreeIgnoreEnabled = !t:NERDTreeIgnoreEnabled + call s:renderViewSavingPosition() + call s:centerView() +endfunction + +" FUNCTION: s:toggleShowBookmarks() {{{2 +" toggles the display of bookmarks +function! s:toggleShowBookmarks() + let t:NERDTreeShowBookmarks = !t:NERDTreeShowBookmarks + if t:NERDTreeShowBookmarks + call s:renderView() + call s:putCursorOnBookmarkTable() + else + call s:renderViewSavingPosition() + endif + call s:centerView() +endfunction +" FUNCTION: s:toggleShowFiles() {{{2 +" toggles the display of hidden files +function! s:toggleShowFiles() + let t:NERDTreeShowFiles = !t:NERDTreeShowFiles + call s:renderViewSavingPosition() + call s:centerView() +endfunction + +" FUNCTION: s:toggleShowHidden() {{{2 +" toggles the display of hidden files +function! s:toggleShowHidden() + let t:NERDTreeShowHidden = !t:NERDTreeShowHidden + call s:renderViewSavingPosition() + call s:centerView() +endfunction + +"FUNCTION: s:upDir(keepState) {{{2 +"moves the tree up a level +" +"Args: +"keepState: 1 if the current root should be left open when the tree is +"re-rendered +function! s:upDir(keepState) + let cwd = t:NERDTreeRoot.path.str(0) + if cwd == "/" || cwd =~ '^[^/]..$' + call s:echo("already at top dir") + else + if !a:keepState + call t:NERDTreeRoot.close() + endif + + let oldRoot = t:NERDTreeRoot + + if empty(t:NERDTreeRoot.parent) + let path = t:NERDTreeRoot.path.getPathTrunk() + let newRoot = s:TreeDirNode.New(path) + call newRoot.open() + call newRoot.transplantChild(t:NERDTreeRoot) + let t:NERDTreeRoot = newRoot + else + let t:NERDTreeRoot = t:NERDTreeRoot.parent + + endif + + call s:renderView() + call s:putCursorOnNode(oldRoot, 0, 0) + endif +endfunction + +" vim: set sw=4 sts=4 et fdm=marker: diff --git a/vim/syntax/python.vim b/vim/syntax/python.vim new file mode 100644 index 0000000..c9e6e24 --- /dev/null +++ b/vim/syntax/python.vim @@ -0,0 +1,357 @@ +" Vim syntax file +" Language: Python +" Maintainer: Dmitry Vasiliev +" URL: http://www.hlabs.spb.ru/vim/python3.0.vim +" Last Change: 2008-12-07 +" Filenames: *.py +" Version: 3.0.0 +" +" Based on python.vim (from Vim 6.1 distribution) +" by Neil Schemenauer +" +" Thanks: +" +" Jeroen Ruigrok van der Werven +" for the idea to highlight erroneous operators +" Pedro Algarvio +" for the patch to enable spell checking only for the right spots +" (strings and comments) +" John Eikenberry +" for the patch fixing small typo + +" +" Options: +" +" For set option do: let OPTION_NAME = 1 +" For clear option do: let OPTION_NAME = 0 +" +" Option names: +" +" For highlight builtin functions: +" python_highlight_builtins +" +" For highlight standard exceptions: +" python_highlight_exceptions +" +" For highlight string formatting: +" python_highlight_string_formatting +" +" For highlight str.format syntax: +" python_highlight_string_format +" +" For highlight string.Template syntax: +" python_highlight_string_templates +" +" For highlight indentation errors: +" python_highlight_indent_errors +" +" For highlight trailing spaces: +" python_highlight_space_errors +" +" For highlight doc-tests: +" python_highlight_doctests +" +" If you want all Python highlightings above: +" python_highlight_all +" (This option not override previously set options) +" +" For fast machines: +" python_slow_sync + +" For version 5.x: Clear all syntax items +" For version 6.x: Quit when a syntax file was already loaded +if version < 600 + syntax clear +elseif exists("b:current_syntax") + finish +endif + +if exists("python_highlight_all") && python_highlight_all != 0 + " Not override previously set options + if !exists("python_highlight_builtins") + let python_highlight_builtins = 1 + endif + if !exists("python_highlight_exceptions") + let python_highlight_exceptions = 1 + endif + if !exists("python_highlight_string_formatting") + let python_highlight_string_formatting = 1 + endif + if !exists("python_highlight_string_format") + let python_highlight_string_format = 1 + endif + if !exists("python_highlight_string_templates") + let python_highlight_string_templates = 1 + endif + if !exists("python_highlight_indent_errors") + let python_highlight_indent_errors = 1 + endif + if !exists("python_highlight_space_errors") + let python_highlight_space_errors = 1 + endif + if !exists("python_highlight_doctests") + let python_highlight_doctests = 1 + endif +endif + +" Keywords +syn keyword pythonStatement break continue del +syn keyword pythonStatement exec return as +syn keyword pythonStatement pass raise +syn keyword pythonStatement global assert +syn keyword pythonStatement lambda yield +syn keyword pythonStatement with nonlocal +syn keyword pythonStatement False None True +syn keyword pythonStatement def class nextgroup=pythonFunction skipwhite +syn match pythonFunction "\%([^[:cntrl:][:space:][:punct:][:digit:]]\|_\)\%([^[:cntrl:][:punct:][:space:]]\|_\)*" display contained +syn keyword pythonRepeat for while +syn keyword pythonConditional if elif else +syn keyword pythonImport import from +syn keyword pythonException try except finally +syn keyword pythonOperator and in is not or + +" Decorators (new in Python 2.4) +syn match pythonDecorator "@" display nextgroup=pythonFunction skipwhite + +" Comments +syn match pythonComment "#.*$" display contains=pythonTodo,@Spell +syn match pythonRun "\%^#!.*$" +syn match pythonCoding "\%^.*\%(\n.*\)\?#.*coding[:=]\s*[0-9A-Za-z-_.]\+.*$" +syn keyword pythonTodo TODO FIXME XXX contained + +" Errors +" syn match pythonError "\<\d\+\D\+\>" display +syn match pythonError "[$?]" display +syn match pythonError "[&|]\{2,}" display +syn match pythonError "[=]\{3,}" display + +syn match pythonError "^\s*def\s\+\w\+(.*)\s*$" display +syn match pythonError "^\s*class\s\+\w\+(.*)\s*$" display +syn match pythonError "^\s*for\s.*[^:]$" display +syn match pythonError "^\s*except\s*$" display +syn match pythonError "^\s*finally\s*$" display +syn match pythonError "^\s*try\s*$" display +syn match pythonError "^\s*else\s*$" display +syn match pythonError "^\s*else\s*[^:].*" display +syn match pythonError "^\s*if\s.*[^\:]$" display +syn match pythonError "^\s*except\s.*[^\:]$" display +syn match pythonError "[;]$" display +syn keyword pythonError do + +" TODO: Mixing spaces and tabs also may be used for pretty formatting multiline +" statements. For now I don't know how to work around this. +if exists("python_highlight_indent_errors") && python_highlight_indent_errors != 0 + syn match pythonIndentError "^\s*\%( \t\|\t \)\s*\S"me=e-1 display +endif + +" Trailing space errors +if exists("python_highlight_space_errors") && python_highlight_space_errors != 0 + syn match pythonSpaceError "\s\+$" display +endif + +" Strings +syn region pythonString start=+'+ skip=+\\\\\|\\'\|\\$+ excludenl end=+'+ end=+$+ keepend contains=pythonEscape,pythonEscapeError,@Spell +syn region pythonString start=+"+ skip=+\\\\\|\\"\|\\$+ excludenl end=+"+ end=+$+ keepend contains=pythonEscape,pythonEscapeError,@Spell +syn region pythonString start=+"""+ end=+"""+ keepend contains=pythonEscape,pythonEscapeError,pythonDocTest2,pythonSpaceError,@Spell +syn region pythonString start=+'''+ end=+'''+ keepend contains=pythonEscape,pythonEscapeError,pythonDocTest,pythonSpaceError,@Spell + +syn match pythonEscape +\\[abfnrtv'"\\]+ display contained +syn match pythonEscape "\\\o\o\=\o\=" display contained +syn match pythonEscapeError "\\\o\{,2}[89]" display contained +syn match pythonEscape "\\x\x\{2}" display contained +syn match pythonEscapeError "\\x\x\=\X" display contained +syn match pythonEscape "\\$" +syn match pythonEscape "\\u\x\{4}" display contained +syn match pythonEscapeError "\\u\x\{,3}\X" display contained +syn match pythonEscape "\\U\x\{8}" display contained +syn match pythonEscapeError "\\U\x\{,7}\X" display contained +syn match pythonEscape "\\N{[A-Z ]\+}" display contained +syn match pythonEscapeError "\\N{[^A-Z ]\+}" display contained + +" Raw strings +syn region pythonRawString start=+[rR]'+ skip=+\\\\\|\\'\|\\$+ excludenl end=+'+ end=+$+ keepend contains=pythonRawEscape,@Spell +syn region pythonRawString start=+[rR]"+ skip=+\\\\\|\\"\|\\$+ excludenl end=+"+ end=+$+ keepend contains=pythonRawEscape,@Spell +syn region pythonRawString start=+[rR]"""+ end=+"""+ keepend contains=pythonDocTest2,pythonSpaceError,@Spell +syn region pythonRawString start=+[rR]'''+ end=+'''+ keepend contains=pythonDocTest,pythonSpaceError,@Spell + +syn match pythonRawEscape +\\['"]+ display transparent contained + +" Bytes +syn region pythonBytes start=+[bB]'+ skip=+\\\\\|\\'\|\\$+ excludenl end=+'+ end=+$+ keepend contains=pythonBytesContent,pythonBytesError,pythonBytesEscape,pythonBytesEscapeError,@Spell +syn region pythonBytes start=+[bB]"+ skip=+\\\\\|\\"\|\\$+ excludenl end=+"+ end=+$+ keepend contains=pythonBytesContent,pythonBytesError,pythonBytesEscape,pythonBytesEscapeError,@Spell +syn region pythonBytes start=+[bB]"""+ end=+"""+ keepend contains=pythonBytesContent,pythonBytesError,pythonBytesEscape,pythonBytesEscapeError,pythonDocTest2,pythonSpaceError,@Spell +syn region pythonBytes start=+[bB]'''+ end=+'''+ keepend contains=pythonBytesContent,pythonBytesError,pythonBytesEscape,pythonBytesEscapeError,pythonDocTest,pythonSpaceError,@Spell + +syn match pythonBytesContent "[\u0001-\u007f]\+" display contained +syn match pythonBytesError "[^\u0001-\u007f]\+" display contained + +syn match pythonBytesEscape +\\[abfnrtv'"\\]+ display contained +syn match pythonBytesEscape "\\\o\o\=\o\=" display contained +syn match pythonBytesEscapeError "\\\o\{,2}[89]" display contained +syn match pythonBytesEscape "\\x\x\{2}" display contained +syn match pythonBytesEscapeError "\\x\x\=\X" display contained +syn match pythonBytesEscape "\\$" + +if exists("python_highlight_string_formatting") && python_highlight_string_formatting != 0 + " String formatting + syn match pythonStrFormatting "%\%(([^)]\+)\)\=[-#0 +]*\d*\%(\.\d\+\)\=[hlL]\=[diouxXeEfFgGcrs%]" contained containedin=pythonString,pythonRawString + syn match pythonStrFormatting "%[-#0 +]*\%(\*\|\d\+\)\=\%(\.\%(\*\|\d\+\)\)\=[hlL]\=[diouxXeEfFgGcrs%]" contained containedin=pythonString,pythonRawString +endif + +if exists("python_highlight_string_format") && python_highlight_string_format != 0 + " str.format syntax + syn match pythonStrFormat "{{\|}}" contained containedin=pythonString,pythonRawString + syn match pythonStrFormat "{\%(\%([^[:cntrl:][:space:][:punct:][:digit:]]\|_\)\%([^[:cntrl:][:punct:][:space:]]\|_\)*\|\d\+\)\%(\.\%([^[:cntrl:][:space:][:punct:][:digit:]]\|_\)\%([^[:cntrl:][:punct:][:space:]]\|_*\)\|\[\%(\d\+\|[^!:\}]\+\)\]\)*\%(![rsa]\)\=\%(:\%({\%(\%([^[:cntrl:][:space:][:punct:][:digit:]]\|_\)\%([^[:cntrl:][:punct:][:space:]]\|_\)*\|\d\+\)}\|\%([^}]\=[<>=^]\)\=[ +-]\=#\=0\=\d*\%(\.\d\+\)\=[bcdeEfFgGnoxX%]\=\)\=\)\=}" contained containedin=pythonString,pythonRawString +endif + +if exists("python_highlight_string_templates") && python_highlight_string_templates != 0 + " String templates + syn match pythonStrTemplate "\$\$" contained containedin=pythonString,pythonRawString + syn match pythonStrTemplate "\${[a-zA-Z_][a-zA-Z0-9_]*}" contained containedin=pythonString,pythonRawString + syn match pythonStrTemplate "\$[a-zA-Z_][a-zA-Z0-9_]*" contained containedin=pythonString,pythonRawString +endif + +if exists("python_highlight_doctests") && python_highlight_doctests != 0 + " DocTests + syn region pythonDocTest start="^\s*>>>" end=+'''+he=s-1 end="^\s*$" contained + syn region pythonDocTest2 start="^\s*>>>" end=+"""+he=s-1 end="^\s*$" contained +endif + +" Numbers (ints, longs, floats, complex) +syn match pythonHexError "\<0[xX]\x*[g-zG-Z]\x*\>" display + +syn match pythonHexNumber "\<0[xX]\x\+\>" display +syn match pythonOctNumber "\<0[oO]\o\+\>" display +syn match pythonBinNumber "\<0[bB][01]\+\>" display + +syn match pythonNumber "\<\d\>" display +syn match pythonNumber "\<[1-9]\d\+\>" display +syn match pythonNumber "\<\d\+[jJ]\>" display +syn match pythonNumberError "\<0\d\+\>" display + +syn match pythonFloat "\.\d\+\%([eE][+-]\=\d\+\)\=[jJ]\=\>" display +syn match pythonFloat "\<\d\+[eE][+-]\=\d\+[jJ]\=\>" display +syn match pythonFloat "\<\d\+\.\d*\%([eE][+-]\=\d\+\)\=[jJ]\=" display + +syn match pythonOctError "\<0[oO]\=\o*[8-9]\d*\>" display +syn match pythonBinError "\<0[bB][01]*[2-9]\d*\>" display + +if exists("python_highlight_builtins") && python_highlight_builtins != 0 + " Builtin functions, types and objects + syn keyword pythonBuiltinObj Ellipsis NotImplemented + syn keyword pythonBuiltinObj __debug__ __doc__ __file__ __name__ __package__ + + syn keyword pythonBuiltinFunc __import__ abs all any ascii + syn keyword pythonBuiltinFunc bin bool bytearray bytes + syn keyword pythonBuiltinFunc chr classmethod cmp compile complex + syn keyword pythonBuiltinFunc delattr dict dir divmod enumerate eval + syn keyword pythonBuiltinFunc exec filter float format frozenset getattr + syn keyword pythonBuiltinFunc globals hasattr hash hex id + syn keyword pythonBuiltinFunc input int isinstance + syn keyword pythonBuiltinFunc issubclass iter len list locals map max + syn keyword pythonBuiltinFunc memoryview min next object oct open ord + syn keyword pythonBuiltinFunc pow print property range + syn keyword pythonBuiltinFunc repr reversed round set setattr + syn keyword pythonBuiltinFunc slice sorted staticmethod str sum super tuple + syn keyword pythonBuiltinFunc type vars zip +endif + +if exists("python_highlight_exceptions") && python_highlight_exceptions != 0 + " Builtin exceptions and warnings + syn keyword pythonExClass BaseException + syn keyword pythonExClass Exception ArithmeticError + syn keyword pythonExClass LookupError EnvironmentError + + syn keyword pythonExClass AssertionError AttributeError BufferError EOFError + syn keyword pythonExClass FloatingPointError GeneratorExit IOError + syn keyword pythonExClass ImportError IndexError KeyError + syn keyword pythonExClass KeyboardInterrupt MemoryError NameError + syn keyword pythonExClass NotImplementedError OSError OverflowError + syn keyword pythonExClass ReferenceError RuntimeError StopIteration + syn keyword pythonExClass SyntaxError IndentationError TabError + syn keyword pythonExClass SystemError SystemExit TypeError + syn keyword pythonExClass UnboundLocalError UnicodeError + syn keyword pythonExClass UnicodeEncodeError UnicodeDecodeError + syn keyword pythonExClass UnicodeTranslateError ValueError VMSError + syn keyword pythonExClass WindowsError ZeroDivisionError + + syn keyword pythonExClass Warning UserWarning BytesWarning DeprecationWarning + syn keyword pythonExClass PendingDepricationWarning SyntaxWarning + syn keyword pythonExClass RuntimeWarning FutureWarning + syn keyword pythonExClass ImportWarning UnicodeWarning +endif + +if exists("python_slow_sync") && python_slow_sync != 0 + syn sync minlines=2000 +else + " This is fast but code inside triple quoted strings screws it up. It + " is impossible to fix because the only way to know if you are inside a + " triple quoted string is to start from the beginning of the file. + syn sync match pythonSync grouphere NONE "):$" + syn sync maxlines=200 +endif + +if version >= 508 || !exists("did_python_syn_inits") + if version <= 508 + let did_python_syn_inits = 1 + command -nargs=+ HiLink hi link + else + command -nargs=+ HiLink hi def link + endif + + HiLink pythonStatement Statement + HiLink pythonImport Statement + HiLink pythonFunction Function + HiLink pythonConditional Conditional + HiLink pythonRepeat Repeat + HiLink pythonException Exception + HiLink pythonOperator Operator + + HiLink pythonDecorator Define + + HiLink pythonComment Comment + HiLink pythonCoding Special + HiLink pythonRun Special + HiLink pythonTodo Todo + + HiLink pythonError Error + HiLink pythonIndentError Error + HiLink pythonSpaceError Error + + HiLink pythonString String + HiLink pythonRawString String + HiLink pythonEscape Special + HiLink pythonEscapeError Error + + HiLink pythonBytes String + HiLink pythonBytesContent String + HiLink pythonBytesError Error + HiLink pythonBytesEscape Special + HiLink pythonBytesEscapeError Error + + HiLink pythonStrFormatting Special + HiLink pythonStrFormat Special + HiLink pythonStrTemplate Special + + HiLink pythonDocTest Special + HiLink pythonDocTest2 Special + + HiLink pythonNumber Number + HiLink pythonHexNumber Number + HiLink pythonOctNumber Number + HiLink pythonBinNumber Number + HiLink pythonFloat Float + HiLink pythonNumberError Error + HiLink pythonOctError Error + HiLink pythonHexError Error + HiLink pythonBinError Error + + HiLink pythonBuiltinObj Structure + HiLink pythonBuiltinFunc Function + + HiLink pythonExClass Structure + + delcommand HiLink +endif + +let b:current_syntax = "python" diff --git a/vimrc b/vimrc new file mode 100644 index 0000000..2b2b6a1 --- /dev/null +++ b/vimrc @@ -0,0 +1,216 @@ +" .vimrc + +" Use Vim not vi settings +set nocompatible + +" gui appearence +if has("gui_running") + colorscheme slate + set guifont=Terminus\ 8 +endif + +" term appearence +set background=dark + +" always show ruler +set ruler + +" search related settings + +" show parial pattern matches in real time +set incsearch +" I like highlighted search pattern +set hlsearch +" search for upper and lowercase +set ignorecase +" but if user type uppercase - search exaclty +set smartcase + +" no backup, we got scm :) +set nobackup + +"use a scrollable menu for filename completions +set wildmenu + +"ignore class and object files +set wildignore=*.class,*.o,*.bak,*.swp,*.pyc + +"of course +syntax on + +" I work with buffers, when I open a buffer that is recently open in a window, +" don't open this buffer twice: switch to the already open one! Nice for :make, :cn, ... ;-) +set switchbuf=useopen +" title +set titlestring=%<%F\ %M%=%l/%L\ -\ %p%% titlelen=70 + +" display linenumber +set number + +if version >= 700 + " spelling files: + " http://ftp.vim.org/pub/vim/runtime/spell/ + " move de.latin1.spl and de.latin1.sug to RUNTIME/spell + set spelllang=de + set sps=best,10 + set omnifunc=ccomplete#Complete +map gT +map gt +else +" spell check for the folloging files + let spell_auto_type = "tex,mail,text,human" + let spell_markup_ft = ",tex,mail,text,human" + let spell_guess_language_ft = "" +endif + +"maximum mumber of undos +set undolevels=1000 + +" indent stuff, tab stuff +set autoindent +set smartindent +set tabstop=4 +set softtabstop=4 +set shiftwidth=4 + +" no swp file cluttering in workdir +set directory=~/.vimswp + +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +" TEXT FORMATING + + + + +if has("autocmd") + + filetype on + augroup filetype + filetype plugin indent on + autocmd BufNewFile,BufRead *.txt set filetype=human + augroup END + + "vim jumps always to the last edited line, if possible + "autocmd BufRead *,.* :normal '" + autocmd BufReadPost * + \ if line("'\"") > 0 && line("'\"") <= line("$") | + \ exe "normal g`\"" | + \ endif + + "in human-language files, automatically format everything at 78 chars: + autocmd FileType mail,human + \ set spelllang=de formatoptions+=t textwidth=78 nocindent dictionary=/usr/share/dict/words + + + "LaTeX to the fullest! ...dislike overlong lines: + autocmd FileType tex set formatoptions+=t textwidth=80 nocindent + autocmd FileType tex set makeprg=pdflatex\ % + + "for C-like programming, have automatic indentation: + autocmd FileType slang set cindent tabstop=4 shiftwidth=4 tw=78 + + + "for actual C programming where comments have explicit end + "characters, if starting a new line in the middle of a comment automatically + "insert the comment leader characters: + "for a more _weighty_ comments use: comments=sl:/*,mb:**,elx:*/ + autocmd FileType c,cpp set formatoptions+=ro dictionary=$HOME/.vim/c_dictionary + \ tw=78 tabstop=4 shiftwidth=4 noexpandtab cindent + + + " indent xml code + augroup xml + map ,mf !xmllint --format --recover - 2>/dev/null + " au! + " autocmd BufWrite *xml exe ":silent 1,$!xmllint --format --recover - 2>/dev/null" + augroup END + + "for both CSS and HTML, use genuine tab characters for indentation, to make + "files a few bytes smaller: + autocmd FileType html,css set noexpandtab tabstop=2 + + "in makefiles, don't expand tabs to spaces, since actual tab characters are + "needed, and have indentation at 8 chars to be sure that all indents are tabs + "(despite the mappings later): + autocmd FileType make set noexpandtab shiftwidth=8 + autocmd FileType automake set noexpandtab shiftwidth=8 + +endif " has("autocmd") + + + +"I need more information +set statusline=%<%F%=\ [%1*%M%*%n%R%H%Y]\ \ %-25(%3l,%c%03V\ \ %P\ (%L)%)%12o'%03b''%03B' +"always show statusline +set laststatus=2 + +"modus (insert,visual ...) +highlight modeMsg cterm=bold ctermfg=white ctermbg=blue +"active statusLine +highlight statusLine cterm=bold ctermfg=yellow ctermbg=red +"inactive statusLine +highlight statusLineNC cterm=bold ctermfg=black ctermbg=white +"visual mode +highlight visual cterm=bold ctermfg=yellow ctermbg=red +"cursor colors +highlight cursor cterm=bold +"vertical line on split screen +highlight VertSplit cterm=bold ctermfg=yellow ctermbg=yellow + +" highlight spell errors +highlight SpellErrors ctermfg=Red cterm=underline term=reverse + + +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +" MAPPINGS + +"" Function Keys Sector + +"write a changelog entry upon pressing F1 +"nnoremap :r !dateThomas Ruoff +"F2 -> F4 == misc +"search the current word under cursor in all files in working directory +nnoremap vawy:! grep -n -H " .* * + +nnoremap :NERDTreeToggle + +"compile, translate, ... +map :make + +" F9 F11 Shift-F11 and F12 are used in python mode + +set pastetoggle= + +"F11 -> F12 == resize window +"map :resize -5 +"map :resize +5 + +python << EOF +import os +import sys +import vim +for p in sys.path: + if os.path.isdir(p): + vim.command(r"set path+=%s" % (p.replace(" ", r"\ "))) +EOF +"use ctags +set tags+=$HOME/.vim/tags/python.ctags +"remap tag jumping +map +map +"Code Completion for python +autocmd FileType python set omnifunc=pythoncomplete#Complete +"remap code complete to ctrl space +inoremap +"tab nav with alt left or right +map :tabnext +map :tabprevious +filetype plugin indent on +python << EOL +import vim +def EvaluateCurrentRange(): + eval(compile('\n'.join(vim.current.range),'','exec'),globals()) +EOL +map :py EvaluateCurrentRange() + +" vim:set ts=2 tw=80: diff --git a/zsh/func/prompt_wunjo_setup b/zsh/func/prompt_wunjo_setup new file mode 100644 index 0000000..b34849c --- /dev/null +++ b/zsh/func/prompt_wunjo_setup @@ -0,0 +1,290 @@ +# wunjo prompt theme + +autoload -U zgitinit +zgitinit + +prompt_wunjo_help () { + cat <<'EOF' + + prompt wunjo + +EOF +} + + +coloratom() { + local off=$1 atom=$2 + if [[ $atom[1] == [[:upper:]] ]]; then + off=$(( $off + 60 )) + fi + echo $(( $off + $colorcode[${(L)atom}] )) +} +colorword() { + local fg=$1 bg=$2 att=$3 + local -a s + + if [ -n "$fg" ]; then + s+=$(coloratom 30 $fg) + fi + if [ -n "$bg" ]; then + s+=$(coloratom 40 $bg) + fi + if [ -n "$att" ]; then + s+=$attcode[$att] + fi + + echo "%{"$'\e['${(j:;:)s}m"%}" +} + +prompt_wunjo_setup() { + local verbose + if [[ $TERM == screen* ]] && [ -n "$STY" ]; then + verbose= + else + verbose=1 + fi + + typeset -A colorcode + colorcode[black]=0 + colorcode[red]=1 + colorcode[green]=2 + colorcode[yellow]=3 + colorcode[blue]=4 + colorcode[magenta]=5 + colorcode[cyan]=6 + colorcode[white]=7 + colorcode[default]=9 + colorcode[k]=$colorcode[black] + colorcode[r]=$colorcode[red] + colorcode[g]=$colorcode[green] + colorcode[y]=$colorcode[yellow] + colorcode[b]=$colorcode[blue] + colorcode[m]=$colorcode[magenta] + colorcode[c]=$colorcode[cyan] + colorcode[w]=$colorcode[white] + colorcode[.]=$colorcode[default] + + typeset -A attcode + attcode[none]=00 + attcode[bold]=01 + attcode[faint]=02 + attcode[standout]=03 + attcode[underline]=04 + attcode[blink]=05 + attcode[reverse]=07 + attcode[conceal]=08 + attcode[normal]=22 + attcode[no-standout]=23 + attcode[no-underline]=24 + attcode[no-blink]=25 + attcode[no-reverse]=27 + attcode[no-conceal]=28 + + local -A pc + pc[default]='default' + pc[date]='cyan' + pc[time]='Blue' + pc[host]='Green' + pc[user]='cyan' + pc[punc]='yellow' + pc[line]='magenta' + pc[hist]='green' + pc[path]='Cyan' + pc[shortpath]='default' + pc[rc]='red' + pc[scm_branch]='Cyan' + pc[scm_commitid]='Yellow' + pc[scm_status_dirty]='Red' + pc[scm_status_staged]='Green' + pc[#]='Yellow' + for cn in ${(k)pc}; do + pc[${cn}]=$(colorword $pc[$cn]) + done + pc[reset]=$(colorword . . 00) + + typeset -Ag wunjo_prompt_colors + wunjo_prompt_colors=(${(kv)pc}) + + local p_date p_line p_rc + + p_date="$pc[date]%D{%Y-%m-%d} $pc[time]%D{%T}$pc[reset]" + + p_line="$pc[line]%y$pc[reset]" + + PROMPT= + if [ $verbose ]; then + PROMPT+="$pc[host]%m$pc[reset] " + fi + PROMPT+="$pc[path]%(2~.%~.%/)$pc[reset]" + PROMPT+="\$(prompt_wunjo_scm_status)" + PROMPT+="%(?.. $pc[rc]exited %1v$pc[reset])" + PROMPT+=" +" + PROMPT+="$pc[hist]%h$pc[reset] " + PROMPT+="$pc[shortpath]%1~$pc[reset]" + PROMPT+="\$(prompt_wunjo_scm_branch)" + PROMPT+=" $pc[#]%#$pc[reset] " + + RPROMPT= + if [ $verbose ]; then + RPROMPT+="$p_date " + fi + RPROMPT+="$pc[user]%n$pc[reset]" + RPROMPT+=" $p_line" + + export PROMPT RPROMPT + precmd_functions+='prompt_wunjo_precmd' +} + +prompt_wunjo_precmd() { + local ex=$? + psvar=() + + if [[ $ex -ge 128 ]]; then + sig=$signals[$ex-127] + psvar[1]="sig${(L)sig}" + else + psvar[1]="$ex" + fi +} + +prompt_wunjo_scm_status() { + zgit_isgit || return + local -A pc + pc=(${(kv)wunjo_prompt_colors}) + + head=$(zgit_head) + gitcommit=$(git describe --always $head 2>/dev/null) + + local -a commits + + if zgit_rebaseinfo; then + orig_commit=$(git describe --always $zgit_info[rb_head]) + orig_name=$(git name-rev --name-only $zgit_info[rb_head]) + orig="$pc[scm_branch]$orig_name$pc[punc]($pc[scm_commitid]$orig_commit$pc[punc])" + onto_commit=$(git describe --always $zgit_info[rb_onto]) + onto_name=$(git name-rev --name-only $zgit_info[rb_onto]) + onto="$pc[scm_branch]$onto_name$pc[punc]($pc[scm_commitid]$onto_commit$pc[punc])" + + if [ -n "$zgit_info[rb_upstream]" ] && [ $zgit_info[rb_upstream] != $zgit_info[rb_onto] ]; then + upstream_commit=$(git describe --always $zgit_info[rb_upstream]) + upstream_name=$(git name-rev --name-only $zgit_info[rb_upstream]) + upstream="$pc[scm_branch]$upstream_name$pc[punc]($pc[scm_commitid]$upstream_commit$pc[punc])" + commits+="rebasing $upstream$pc[reset]..$orig$pc[reset] onto $onto$pc[reset]" + else + commits+="rebasing $onto$pc[reset]..$orig$pc[reset]" + fi + + local -a revs + revs=($(git rev-list $zgit_info[rb_onto]..HEAD)) + if [ $#revs -gt 0 ]; then + commits+="\n$#revs commits in" + fi + + if [ -f $zgit_info[dotest]/message ]; then + mess=$(head -n1 $zgit_info[dotest]/message) + commits+="on $mess" + fi + elif [ -n "$gitcommit" ]; then + commits+="on $pc[scm_branch]$head$pc[punc]($pc[scm_commitid]$gitcommit$pc[punc])$pc[reset]" + local track_merge=$(zgit_tracking_merge) + if [ -n "$track_merge" ]; then + if git rev-parse --verify -q $track_merge >/dev/null; then + local track_remote=$(zgit_tracking_remote) + local tracked=$(git describe --always $track_merge 2>/dev/null) + + local -a revs + revs=($(git rev-list --reverse $track_merge..HEAD)) + if [ $#revs -gt 0 ]; then + local base=$(git describe --always $revs[1]~1) + local base_name=$(git name-rev --name-only $base) + local base_short=$(git describe --always $base) + local word_commits + if [ $#revs -gt 1 ]; then + word_commits='commits' + else + word_commits='commit' + fi + + local conj="since" + if [[ "$base" == "$tracked" ]]; then + conj+=" tracked" + tracked= + fi + commits+="$#revs $word_commits $conj $pc[scm_branch]$base_name$pc[punc]($pc[scm_commitid]$base_short$pc[punc])$pc[reset]" + fi + + if [ -n "$tracked" ]; then + local track_name=$track_merge + if [[ $track_remote == "." ]]; then + track_name=${track_name##*/} + fi + tracked=$(git describe --always $tracked) + commits+="tracking $pc[scm_branch]$track_name$pc[punc]" + if [[ "$tracked" != "$gitcommit" ]]; then + commits[$#commits]+="($pc[scm_commitid]$tracked$pc[punc])" + fi + commits[$#commits]+="$pc[reset]" + fi + fi + fi + fi + + gitsvn=$(git rev-parse --verify -q --short git-svn) + if [ $? -eq 0 ]; then + gitsvnrev=$(zgit_svnhead $gitsvn) + gitsvn=$(git describe --always $gitsvn) + if [ -n "$gitsvnrev" ]; then + local svninfo='' + local -a revs + svninfo+="$pc[default]svn$pc[punc]:$pc[scm_branch]r$gitsvnrev" + revs=($(git rev-list git-svn..HEAD)) + if [ $#revs -gt 0 ]; then + svninfo+="$pc[punc]@$pc[default]HEAD~$#revs" + svninfo+="$pc[punc]($pc[scm_commitid]$gitsvn$pc[punc])" + fi + commits+=$svninfo + fi + fi + + if [ $#commits -gt 0 ]; then + echo -n " ${(j: :)commits}" + fi +} + +prompt_wunjo_scm_branch() { + zgit_isgit || return + local -A pc + pc=(${(kv)wunjo_prompt_colors}) + + echo -n "$pc[punc]:$pc[scm_branch]$(zgit_head)" + + if zgit_inworktree; then + if ! zgit_isindexclean; then + echo -n "$pc[scm_status_staged]+" + fi + + local -a dirty + if ! zgit_isworktreeclean; then + dirty+='!' + fi + + if zgit_hasunmerged; then + dirty+='*' + fi + + if zgit_hasuntracked; then + dirty+='?' + fi + + if [ $#dirty -gt 0 ]; then + echo -n "$pc[scm_status_dirty]${(j::)dirty}" + fi + fi + + echo $pc[reset] +} + +prompt_wunjo_setup "$@" + +# vim:set ft=zsh: diff --git a/zsh/func/zgitinit b/zsh/func/zgitinit new file mode 100644 index 0000000..ebc8bff --- /dev/null +++ b/zsh/func/zgitinit @@ -0,0 +1,248 @@ +## +## Load with `autoload -U zgitinit; zgitinit' +## + +typeset -gA zgit_info +zgit_info=() + +zgit_chpwd_hook() { + zgit_info_update +} + +zgit_preexec_hook() { + if [[ $2 == git\ * ]] || [[ $2 == *\ git\ * ]]; then + zgit_precmd_do_update=1 + fi +} + +zgit_precmd_hook() { + if [ $zgit_precmd_do_update ]; then + unset zgit_precmd_do_update + zgit_info_update + fi +} + +zgit_info_update() { + zgit_info=() + + local gitdir=$(git rev-parse --git-dir 2>/dev/null) + if [ $? -ne 0 ] || [ -z "$gitdir" ]; then + return + fi + + zgit_info[dir]=$gitdir + zgit_info[bare]=$(git rev-parse --is-bare-repository) + zgit_info[inwork]=$(git rev-parse --is-inside-work-tree) +} + +zgit_isgit() { + if [ -z "$zgit_info[dir]" ]; then + return 1 + else + return 0 + fi +} + +zgit_inworktree() { + zgit_isgit || return + if [ "$zgit_info[inwork]" = "true" ]; then + return 0 + else + return 1 + fi +} + +zgit_isbare() { + zgit_isgit || return + if [ "$zgit_info[bare]" = "true" ]; then + return 0 + else + return 1 + fi +} + +zgit_head() { + zgit_isgit || return 1 + + if [ -z "$zgit_info[head]" ]; then + local name='' + name=$(git symbolic-ref -q HEAD) + if [ $? -eq 0 ]; then + if [[ $name == refs/(heads|tags)/* ]]; then + name=${name#refs/(heads|tags)/} + fi + else + name=$(git name-rev --name-only --no-undefined --always HEAD) + if [ $? -ne 0 ]; then + return 1 + elif [[ $name == remotes/* ]]; then + name=${name#remotes/} + fi + fi + zgit_info[head]=$name + fi + + echo $zgit_info[head] +} + +zgit_branch() { + zgit_isgit || return 1 + zgit_isbare && return 1 + + if [ -z "$zgit_info[branch]" ]; then + local branch=$(git symbolic-ref HEAD 2>/dev/null) + if [ $? -eq 0 ]; then + branch=${branch##*/} + else + branch=$(git name-rev --name-only --always HEAD) + fi + zgit_info[branch]=$branch + fi + + echo $zgit_info[branch] + return 0 +} + +zgit_tracking_remote() { + zgit_isgit || return 1 + zgit_isbare && return 1 + + local branch + if [ -n "$1" ]; then + branch=$1 + elif [ -z "$zgit_info[branch]" ]; then + branch=$(zgit_branch) + [ $? -ne 0 ] && return 1 + else + branch=$zgit_info[branch] + fi + + local k="tracking_$branch" + local remote + if [ -z "$zgit_info[$k]" ]; then + remote=$(git config branch.$branch.remote) + zgit_info[$k]=$remote + fi + + echo $zgit_info[$k] + return 0 +} + +zgit_tracking_merge() { + zgit_isgit || return 1 + zgit_isbare && return 1 + + local branch + if [ -z "$zgit_info[branch]" ]; then + branch=$(zgit_branch) + [ $? -ne 0 ] && return 1 + else + branch=$zgit_info[branch] + fi + + local remote=$(zgit_tracking_remote $branch) + [ $? -ne 0 ] && return 1 + if [ -n "$remote" ]; then # tracking branch + local merge=$(git config branch.$branch.merge) + if [ $remote != "." ]; then + merge=$remote/$(basename $merge) + fi + echo $merge + return 0 + else + return 1 + fi +} + +zgit_isindexclean() { + zgit_isgit || return 1 + if git diff --quiet --cached 2>/dev/null; then + return 0 + else + return 1 + fi +} + +zgit_isworktreeclean() { + zgit_isgit || return 1 + if git diff --quiet 2>/dev/null; then + return 0 + else + return 1 + fi +} + +zgit_hasuntracked() { + zgit_isgit || return 1 + local -a flist + flist=($(git ls-files --others --exclude-standard)) + if [ $#flist -gt 0 ]; then + return 0 + else + return 1 + fi +} + +zgit_hasunmerged() { + zgit_isgit || return 1 + local -a flist + flist=($(git ls-files -u)) + if [ $#flist -gt 0 ]; then + return 0 + else + return 1 + fi +} + +zgit_svnhead() { + zgit_isgit || return 1 + + local commit=$1 + if [ -z "$commit" ]; then + commit='HEAD' + fi + + git show --raw $commit | \ + grep git-svn-id | \ + sed -re 's/^\s*git-svn-id: .*@([0-9]+).*$/\1/' +} + +zgit_rebaseinfo() { + zgit_isgit || return 1 + if [ -d $zgit_info[dir]/rebase-merge ]; then + dotest=$zgit_info[dir]/rebase-merge + elif [ -d $zgit_info[dir]/.dotest-merge ]; then + dotest=$zgit_info[dir]/.dotest-merge + elif [ -d .dotest ]; then + dotest=.dotest + else + return 1 + fi + + zgit_info[dotest]=$dotest + + zgit_info[rb_onto]=$(cat "$dotest/onto") + zgit_info[rb_upstream]=$(cat "$dotest/upstream") + if [ -f "$dotest/orig-head" ]; then + zgit_info[rb_head]=$(cat "$dotest/orig-head") + elif [ -f "$dotest/head" ]; then + zgit_info[rb_head]=$(cat "$dotest/head") + fi + zgit_info[rb_head_name]=$(cat "$dotest/head-name") + + return 0 +} + +zgitinit() { + typeset -ga chpwd_functions + typeset -ga preexec_functions + typeset -ga precmd_functions + chpwd_functions+='zgit_chpwd_hook' + preexec_functions+='zgit_preexec_hook' + precmd_functions+='zgit_precmd_hook' +} + +zgitinit +zgit_info_update + +# vim:set ft=zsh: diff --git a/zshenv b/zshenv new file mode 100644 index 0000000..c43e09e --- /dev/null +++ b/zshenv @@ -0,0 +1,25 @@ +# ignore globals because of bug +# http://ubuntuforums.org/showthread.php?t=240782 + +setopt noglobalrcs + +# copied from globals +if [[ -z "$PATH" || "$PATH" == "/bin:/usr/bin" ]] +then + export PATH="/usr/local/bin:/usr/bin:/bin:/usr/games" +fi + +# own environment adjustments +export PATH=$PATH:$HOME/bin + +export EDITOR="/usr/bin/vim" +export PAGER="/usr/bin/less" + +# add texlive path, so no confilicts with install-info + +PATH=/usr/local/texlive/2008/bin/i386-linux:$PATH; export PATH +MANPATH=/usr/local/texlive/2008/texmf/doc/man:$MANPATH; export MANPATH +INFOPATH=/usr/local/texlive/2008/texmf/doc/info:$INFOPATH; export INFOPATH + +fpath=($fpath $HOME/.zsh/func) +typeset -U fpath diff --git a/zshrc b/zshrc new file mode 100644 index 0000000..e04b697 --- /dev/null +++ b/zshrc @@ -0,0 +1,232 @@ +# copied from globals, that will be ignored + +if [[ "$TERM" != emacs ]]; then +[[ -z "$terminfo[kdch1]" ]] || bindkey -M emacs "$terminfo[kdch1]" delete-char +[[ -z "$terminfo[khome]" ]] || bindkey -M emacs "$terminfo[khome]" beginning-of-line +[[ -z "$terminfo[kend]" ]] || bindkey -M emacs "$terminfo[kend]" end-of-line +[[ -z "$terminfo[kich1]" ]] || bindkey -M emacs "$terminfo[kich1]" overwrite-mode +[[ -z "$terminfo[kdch1]" ]] || bindkey -M vicmd "$terminfo[kdch1]" vi-delete-char +[[ -z "$terminfo[khome]" ]] || bindkey -M vicmd "$terminfo[khome]" vi-beginning-of-line +[[ -z "$terminfo[kend]" ]] || bindkey -M vicmd "$terminfo[kend]" vi-end-of-line +[[ -z "$terminfo[kich1]" ]] || bindkey -M vicmd "$terminfo[kich1]" overwrite-mode + +[[ -z "$terminfo[cuu1]" ]] || bindkey -M viins "$terminfo[cuu1]" vi-up-line-or-history +[[ -z "$terminfo[cuf1]" ]] || bindkey -M viins "$terminfo[cuf1]" vi-forward-char +[[ -z "$terminfo[kcuu1]" ]] || bindkey -M viins "$terminfo[kcuu1]" vi-up-line-or-history +[[ -z "$terminfo[kcud1]" ]] || bindkey -M viins "$terminfo[kcud1]" vi-down-line-or-history +[[ -z "$terminfo[kcuf1]" ]] || bindkey -M viins "$terminfo[kcuf1]" vi-forward-char +[[ -z "$terminfo[kcub1]" ]] || bindkey -M viins "$terminfo[kcub1]" vi-backward-char + +# ncurses fogyatekos +#[[ "$terminfo[kcuu1]" == "O"* ]] && bindkey -M viins "${terminfo[kcuu1]/O/[}" vi-up-line-or-history +[[ "$terminfo[kcud1]" == "O"* ]] && bindkey -M viins "${terminfo[kcud1]/O/[}" vi-down-line-or-history +[[ "$terminfo[kcuf1]" == "O"* ]] && bindkey -M viins "${terminfo[kcuf1]/O/[}" vi-forward-char +[[ "$terminfo[kcub1]" == "O"* ]] && bindkey -M viins "${terminfo[kcub1]/O/[}" vi-backward-char +[[ "$terminfo[khome]" == "O"* ]] && bindkey -M viins "${terminfo[khome]/O/[}" beginning-of-line +[[ "$terminfo[kend]" == "O"* ]] && bindkey -M viins "${terminfo[kend]/O/[}" end-of-line +[[ "$terminfo[khome]" == "O"* ]] && bindkey -M emacs "${terminfo[khome]/O/[}" beginning-of-line +[[ "$terminfo[kend]" == "O"* ]] && bindkey -M emacs "${terminfo[kend]/O/[}" end-of-line +fi + +zstyle ':completion:*:sudo:*' command-path /usr/local/sbin /usr/local/bin \ + /usr/sbin /usr/bin /sbin /bin /usr/X11R6/bin + +autoload run-help + +# If you don't want compinit called here, place the line +# skip_global_compinit=1 +# in your $ZDOTDIR/.zshenv or $ZDOTDIR/.zprofice +if [[ -z "$skip_global_compinit" ]]; then + autoload -U compinit + compinit +fi + +zstyle ':completion:*:sudo:*' command-path /usr/local/sbin /usr/local/bin \ + /usr/sbin /usr/bin /sbin /bin /usr/X11R6/bin + +unalias run-help +autoload run-help + +# If you don't want compinit called here, place the line +# skip_global_compinit=1 +# in your $ZDOTDIR/.zshenv or $ZDOTDIR/.zprofice +if [[ -z "$skip_global_compinit" ]]; then + autoload -U compinit + compinit +fi + +################################################################## +# my own confs + +### check for DIST +if [ -f /etc/redhat-release ]; then + DIST="redhat" +elif [ -f /etc/debian_version ]; then + DIST="debian" +elif [ -f /etc/gentoo-release ] || [ -f /usr/bin/emerge ]; then + DIST="gentoo" +elif [ -f /etc/arch-release ]; then + DIST="arch" +fi + +### check for DOMAINNAME +DOMAINNAME=$(dnsdomainname 2>/dev/null || hostname -d) +case "${DOMAINNAME}" in + + stratoserver.net*) + ;; + + *) + ;; +esac + +### check for HOSTNAME +HOSTNAME=$(hostname 2>/dev/null || hostname -f) +case "${HOSTNAME}" in + + h1450889.stratoserver.net*) + ;; + igrats.de*) + ;; + *) + ;; + +esac + + +# vim keyset +bindkey -v + +## get keys working +# found at http://maxime.ritter.eu.org/stuff/zshrc +case $TERM in + linux) + bindkey "^[[2~" yank + bindkey "^[[3~" delete-char + bindkey "^[[5~" up-line-or-history ## PageUp + bindkey "^[[6~" down-line-or-history ## PageDown + bindkey "^[[1~" beginning-of-line + bindkey "^[[4~" end-of-line + bindkey "^[e" expand-cmd-path ## C-e for expanding path of typed command + bindkey "^[[A" up-line-or-search ## up arrow for back-history-search + bindkey "^[[B" down-line-or-search ## down arrow for fwd-history-search + bindkey " " magic-space ## do history expansion on space +;; + *xterm*|rxvt|(dt|k|E)term) + bindkey "^[[2~" yank + bindkey "^[[3~" delete-char + bindkey "^[[5~" up-line-or-history ## PageUp + bindkey "^[[6~" down-line-or-history ## PageDown + bindkey "^[[7~" beginning-of-line + bindkey "^[[8~" end-of-line + bindkey "^[e" expand-cmd-path ## C-e for expanding path of typed command + bindkey "^[[A" up-line-or-search ## up arrow for back-history-search + bindkey "^[[B" down-line-or-search ## down arrow for fwd-history-search + bindkey " " magic-space ## do history expansion on space +;; +esac + +# no freakin' beeeep +unsetopt beep + +# History +HISTFILE=~/.histfile +HISTSIZE=1000 +SAVEHIST=1000 + +setopt EXTENDED_HISTORY +setopt HIST_IGNORE_ALL_DUPS +setopt HIST_NO_FUNCTIONS +setopt HIST_REDUCE_BLANKS + +setopt INC_APPEND_HISTORY +setopt SHARE_HISTORY + +setopt HIST_VERIFY + +# Alias +alias ls="ls --color=auto -T 0" + +# Completion +zmodload -i zsh/complist + +# display colored directory entries +# display current dircolors with dircolors -p +if [ -f ${HOME}/.dir_colors ] +then + eval $(dircolors -b ${HOME}/.dir_colors) +elif [ -f /etc/DIR_COLORS ] +then + eval $(dircolors -b /etc/DIR_COLORS) +fi + +zstyle ':completion:*' list-colors "${(s.:.)LS_COLORS}" +zstyle ':completion:*:*:kill:*' list-colors '=%*=01;31' + +# Load the completion system +autoload -U compinit +compinit +zstyle ':completion:*:*:kill:*:jobs' verbose yes + +autoload -U sched + + +# From the zshwiki. Hide CVS files/directores from being completed. +zstyle ':completion:*:(all-|)files' ignored-patterns '(|*/)CVS' +zstyle ':completion:*:cd:*' ignored-patterns '(*/)#CVS' + +# insert all expansions for expand completer +zstyle ':completion:*:expand:*' tag-order all-expansions + +# formatting and messages +zstyle ':completion:*' verbose yes +zstyle ':completion:*:descriptions' format '%B%d%b' +zstyle ':completion:*:messages' format '%d' +zstyle ':completion:*:warnings' format 'No matches for: %d' +zstyle ':completion:*:corrections' format '%B%d (errors: %e)%b' +zstyle ':completion:*' group-name '' + +# turns off spelling correction for commands +setopt nocorrect +# ORRECTALL option turns on spelling correction for all arguments +setopt nocorrectall + +setopt interactivecomments + + +setopt extendedglob + +setopt EXTENDEDGLOB # file globbing is awesome +setopt AUTOMENU # Tab-completion should cycle. +setopt AUTOLIST # ... and list the possibilities. +setopt AUTO_PARAM_SLASH # Make directories pretty. +setopt ALWAYS_TO_END # Push that cursor on completions. +setopt AUTOCD # jump to the directory. +setopt NO_BEEP # self explanatory +setopt AUTO_NAME_DIRS # change directories to variable names +setopt CHASE_LINKS # if you pwd from a symlink, you get the actual path +setopt AUTO_CONTINUE # automatically sent a CONT signal by disown +setopt LONG_LIST_JOBS # List jobs in the long format by default + + +# prompt +if test -z $SSH_TTY +then + PROMPT=$'%{\e[01;32m%}\%j,%{\e[01;36m%}%m.%l,%{\e[01;34m%}%?,%{\e[01;33m%}\%1~ %{\e[01;32m%}$%{\e[0m%} ' + [ $UID = 0 ] && export PROMPT=$'%{\e[0;31m%}[%{\e[0m%}%n%{\e[0;31m%}@%{\e[0m%}%m%{\e[0;31m%}:%{\e[0m%}%~%{\e[0;31m%}]%{\e[0m%}%# ' +else + PROMPT=$'%{\e[01;32m%}\%j,%{\e[01;36m%}%m,%{\e[01;34m%}%?,%{\e[01;33m%}\%1~ %{\e[01;32m%}$%{\e[0m%} ' + [ $UID = 0 ] && export PROMPT=$'%{\e[0;31m%}[%{\e[0m%}%n%{\e[0;31m%}@%{\e[0m%}%m%{\e[0;31m%}:%{\e[0m%}%~%{\e[0;31m%}]%{\e[0m%}%# ' +fi + + +# zgitinit and prompt_wunjo_setup must be somewhere in your $fpath, see README for more. + +setopt promptsubst + +# Load the prompt theme system +autoload -U promptinit +promptinit + +# Use the wunjo prompt theme +prompt wunjo