commit d2989eb3e0b8d8faa2fd778778fa418a4c51f15e
parent 73be034d5ed3ce0ee2230def7c1f389147a64c2a
Author: Martin Grenfell <martin_grenfell@msn.com>
Date: Sun, 29 Jun 2008 00:23:02 +1200
huge refactor, add bookmark class
Diffstat:
| M | plugin/NERD_tree.vim | | | 340 | ++++++++++++++++++++++++++++++++++++++++++------------------------------------- |
1 file changed, 182 insertions(+), 158 deletions(-)
diff --git a/plugin/NERD_tree.vim b/plugin/NERD_tree.vim
@@ -54,7 +54,7 @@ call s:InitVariable("g:NERDTreeBookmarksFile", expand('$HOME') . '/.NERDTreeBook
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:NERDTreeShowBookmarks", 1)
call s:InitVariable("g:NERDTreeShowFiles", 1)
call s:InitVariable("g:NERDTreeShowHidden", 0)
call s:InitVariable("g:NERDTreeShowLineNumbers", 0)
@@ -143,22 +143,156 @@ endif
command! -n=? -complete=dir NERDTree :call s:InitNerdTree('<args>')
command! -n=? -complete=dir NERDTreeToggle :call s:Toggle('<args>')
command! -n=0 NERDTreeClose :call s:CloseTreeIfOpen()
-command! -n=1 -complete=customlist,s:FindBookmarks NERDTreeFromBookmark call s:InitNerdTree('<args>')
+command! -n=1 -complete=customlist,s:CompleteBookmarks NERDTreeFromBookmark call s:InitNerdTree('<args>')
" SECTION: Auto commands {{{1
"============================================================
"Save the cursor position whenever we close the nerd tree
exec "autocmd BufWinLeave *". s:NERDTreeWinName ."* :call <SID>SaveScreenState()"
"cache bookmarks when vim loads
-autocmd VimEnter * call <SID>ReadBookmarks()
+autocmd VimEnter * call s:oBookmark.CacheBookmarks()
"SECTION: Classes {{{1
"============================================================
+"CLASS: oBookmark {{{2
+"============================================================
+let s:oBookmark = {}
+"FUNCTION: oBookmark.AddBookmark(name, path) {{{3
+function! s:oBookmark.AddBookmark(name, path) dict
+ for i in s:oBookmark.Bookmarks()
+ if i.name == a:name
+ let i.path = a:path
+ return
+ endif
+ endfor
+ call add(s:oBookmark.Bookmarks(), s:oBookmark.New(a:name, a:path))
+endfunction
+"FUNCTION: oBookmark.CacheBookmarks() {{{3
+function! s:oBookmark.CacheBookmarks() dict
+ if filereadable(g:NERDTreeBookmarksFile)
+ let bookmarks = []
+ let bookmarkStrings = readfile(g:NERDTreeBookmarksFile)
+ let invalidBookmarksFound = 0
+ for i in bookmarkStrings
+ let name = substitute(i, '^\(\w\{-}\) .*$', '\1', '')
+ let path = substitute(i, '^\w\{-} \(.*\)$', '\1', '')
+
+ try
+ let bookmark = s:oBookmark.New(name, s:oPath.New(path))
+ catch /NERDTree.Path.InvalidArguments/
+ let invalidBookmarksFound += 1
+ endtry
+ call add(bookmarks, bookmark)
+ endfor
+ let g:NERDTreeBookmarks = bookmarks
+ if invalidBookmarksFound
+ call s:Echo(invalidBookmarksFound . " invalid bookmarks were read and discarded")
+ call s:WriteBookmarks()
+ endif
+ endif
+endfunction
+"FUNCTION: oBookmark.New(name, path) {{{3
+function! s:oBookmark.New(name, path) dict
+ if a:name !~ '^[0-9a-zA-Z_]*$'
+ 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: oBookmark.Write() {{{3
+function! s:oBookmark.Write() dict
+ let bookmarkStrings = []
+ for i in s:oBookmark.Bookmarks()
+ call add(bookmarkStrings, i.name . ' ' . i.path.StrForOS(0))
+ endfor
+ call writefile(bookmarkStrings, g:NERDTreeBookmarksFile)
+endfunction
+" Function: oBookmark.Bookmarks() {{{3
+function! s:oBookmark.Bookmarks() dict
+ if !exists("g:NERDTreeBookmarks")
+ let g:NERDTreeBookmarks = []
+ endif
+ return g:NERDTreeBookmarks
+endfunction
+" Function: oBookmark.BookmarkNames() {{{3
+function! s:oBookmark.BookmarkNames() dict
+ let names = []
+ for i in s:oBookmark.Bookmarks()
+ call add(names, i.name)
+ endfor
+ return names
+endfunction
+" Function: oBookmark.BookmarkFor(name) {{{3
+function! s:oBookmark.BookmarkFor(name) dict
+ for i in s:oBookmark.Bookmarks()
+ if i.name == a:name
+ return i
+ endif
+ endfor
+ return {}
+endfunction
+"FUNCTION: oBookmark.ClearAll() {{{3
+function! s:oBookmark.ClearAll() dict
+ for i in s:oBookmark.Bookmarks()
+ call i.Delete()
+ endfor
+ call s:oBookmark.Write()
+endfunction
+"FUNCTION: oBookmark.GetNode(searchFromAbsoluteRoot) {{{3
+"get the treenode this bookmark
+"
+"Args:
+"searchFromAbsoluteRoot: specifies wheather we should search from the current
+"tree root, or the highest cached node
+function! s:oBookmark.GetNode(searchFromAbsoluteRoot) dict
+ let searchRoot = a:searchFromAbsoluteRoot ? s:AbsoluteTreeRoot() : t:NERDTreeRoot
+ let targetNode = searchRoot.FindNode(self.path)
+ if empty(targetNode)
+ throw "NERDTree.BookmarkNodeNotFound no node was found for bookmark: " . self.name
+ endif
+ return targetNode
+endfunction
+"FUNCTION: oBookmark.GetNodeForName(name, searchFromAbsoluteRoot) {{{3
+function! s:oBookmark.GetNodeForName(name, searchFromAbsoluteRoot) dict
+ let bookmark = s:oBookmark.BookmarkFor(a:name)
+ if bookmark == {}
+ throw "NERDTree.BookmarkNotFound no node was found for bookmark: " . a:name
+ endif
+ return bookmark.GetNode(a:searchFromAbsoluteRoot)
+endfunction
+"FUNCTION: oBookmark.Delete() {{{3
+function! s:oBookmark.Delete() dict
+ let node = {}
+ try
+ let node = self.GetNode(1)
+ catch /NERDTree.BookmarkNodeNotFound/
+ endtry
+ call remove(s:oBookmark.Bookmarks(), index(s:oBookmark.Bookmarks(), self))
+ if !empty(node)
+ call node.path.CacheBookmarks()
+ endif
+endfunction
"CLASS: oTreeFileNode {{{2
"This class is the parent of the oTreeDirNode class and constitures the
"'Component' part of the composite design pattern between the treenode
"classes.
"============================================================
let s:oTreeFileNode = {}
+"FUNCTION: oTreeFileNode.Bookmark(name) {{{3
+"bookmark this node with a:name
+function! s:oTreeFileNode.Bookmark(name) dict
+ try
+ let oldMarkedNode = s:oBookmark.GetNodeForName(a:name, 1)
+ call oldMarkedNode.path.UncacheBookmark(a:name)
+ catch /NERDTree.Bookmark\(DoesntExist\|NotFound\)/
+ endtry
+
+ call s:oBookmark.AddBookmark(a:name, self.path)
+ call self.path.CacheBookmarks()
+ call s:oBookmark.Write()
+endfunction
"FUNCTION: oTreeFileNode.CacheParent {{{3
"initializes self.parent if it isnt already
function! s:oTreeFileNode.CacheParent() dict
@@ -184,13 +318,12 @@ endfunction
"FUNCTION: oTreeFileNode.ClearBookmarks() {{{3
function! s:oTreeFileNode.ClearBookmarks() dict
- let bookmarks = s:GetBookmarks()
- for i in keys(bookmarks)
- if bookmarks[i].Equals(self.path)
- call remove(bookmarks, i)
+ for i in s:oBookmark.Bookmarks()
+ if i.path.Equals(self.path)
+ call i.Delete()
end
endfor
- call self.path.CacheBookmarkNames()
+ call self.path.CacheBookmarks()
endfunction
"FUNCTION: oTreeFileNode.Copy(dest) {{{3
function! s:oTreeFileNode.Copy(dest) dict
@@ -816,18 +949,17 @@ endfunction
let s:oPath = {}
"FUNCTION: oPath.BookmarkNames() {{{3
function! s:oPath.BookmarkNames() dict
- if !exists("self.bookmarkNames")
- call self.CacheBookmarkNames()
+ if !exists("self.bookmark")
+ call self.CacheBookmarks()
endif
return self.bookmarkNames
endfunction
-"FUNCTION: oPath.CacheBookmarkNames() {{{3
-function! s:oPath.CacheBookmarkNames() dict
+"FUNCTION: oPath.CacheBookmarks() {{{3
+function! s:oPath.CacheBookmarks() dict
let self.bookmarkNames = []
- let bookmarks = s:GetBookmarks()
- for k in keys(bookmarks)
- if bookmarks[k].Equals(self)
- call add(self.bookmarkNames, k)
+ for i in s:oBookmark.Bookmarks()
+ if i.path.Equals(self)
+ call add(self.bookmarkNames, i.name)
endif
endfor
return self.bookmarkNames
@@ -1193,7 +1325,7 @@ endfunction
"FUNCTION: oPath.Refresh() {{{3
function! s:oPath.Refresh() dict
call self.ReadInfoFromDisk(self.StrForOS(0))
- call self.CacheBookmarkNames()
+ call self.CacheBookmarks()
endfunction
"FUNCTION: oPath.Rename() {{{3
@@ -1266,9 +1398,8 @@ function! s:oPath.StrDisplay() dict
let toReturn = toReturn . '*'
endif
- let bookmarks = self.BookmarkNames()
- if !empty(bookmarks)
- let toReturn .= ' {' . join(bookmarks, ',') . '}'
+ if !empty(self.BookmarkNames())
+ let toReturn .= ' {' . join(self.BookmarkNames(), ',') . '}'
endif
if self.isSymLink
@@ -1421,42 +1552,10 @@ function! s:BufInWindows(bnum)
return cnt
endfunction " >>>
-"FUNCTION: s:ClearAllBookmarks() {{{2
-"delete all bookmarks
-function! s:ClearAllBookmarks()
- for name in keys(g:NERDTreeBookmarks)
- let node = {}
- try
- let node = s:GetNodeForBookmark(name, 1)
- catch /NERDTree/
- endtry
- call remove(g:NERDTreeBookmarks, name)
- if !empty(node)
- call node.path.CacheBookmarkNames()
- endif
- endfor
- call s:WriteBookmarks()
-endfunction
-"FUNCTION: s:GetNodeForBookmark(name, searchFromAbsoluteRoot) {{{2
-"get the treenode for the bookmark with the given name
-"
-"Args:
-"name: name of bookmark
-"searchFromAbsoluteRoot: specifies wheather we should search from the current
-"tree root, or the highest cached node
-function! s:GetNodeForBookmark(name, searchFromAbsoluteRoot)
- try
- let bookmark = s:GetBookmarks()[a:name]
- catch /E716/ "key not in dictionary error
- throw "NERDTree.BookmarkDoesntExist no bookmark found with name: " . a:name
- endtry
-
- let searchRoot = a:searchFromAbsoluteRoot ? s:AbsoluteTreeRoot() : t:NERDTreeRoot
- let targetNode = searchRoot.FindNode(bookmark)
- if empty(targetNode)
- throw "NERDTree.BookmarkNotFound no node was found for bookmark: " . a:name
- endif
- return targetNode
+" FUNCTION: s:CompleteBookmarks(A,L,P) {{{2
+" completion function for the bookmark commands
+function! s:CompleteBookmarks(A,L,P)
+ return filter(s:oBookmark.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
@@ -1466,8 +1565,8 @@ endfunction
"name: the name of a bookmark or a directory
function! s:InitNerdTree(name)
let path = {}
- if count(keys(s:GetBookmarks()), a:name)
- let path = s:GetBookmarks()[a:name]
+ if s:oBookmark.BookmarkFor(a:name) != {}
+ let path = s:oBookmark.BookmarkFor(a:name).path
else
let dir = a:name == '' ? expand('%:p:h') : a:name
let dir = resolve(dir)
@@ -1505,43 +1604,11 @@ function! s:InitNerdTree(name)
call s:RenderView()
call s:PutCursorOnNode(t:NERDTreeRoot, 0, 0)
endfunction
-" Function: s:ReadBookmarks() {{{2
-function! s:ReadBookmarks()
- if filereadable(g:NERDTreeBookmarksFile)
- let bookmarks = s:GetBookmarks()
- let bookmarkStrings = readfile(g:NERDTreeBookmarksFile)
- let invalidBookmarksFound = 0
- for i in bookmarkStrings
- let key = substitute(i, '^\(\w\{-}\) .*$', '\1', '')
- let path = substitute(i, '^\w\{-} \(.*\)$', '\1', '')
-
- try
- let bookmarks[key] = s:oPath.New(path)
- catch /NERDTree.Path.InvalidArguments/
- let invalidBookmarksFound += 1
- endtry
- endfor
- if invalidBookmarksFound
- call s:Echo(invalidBookmarksFound . " invalid bookmarks were read and discarded")
- call s:WriteBookmarks()
- endif
- endif
-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
-" Function: s:WriteBookmarks() {{{2
-function! s:WriteBookmarks()
- let bookmarks = s:GetBookmarks()
- let bookmarkStrings = []
- for k in keys(bookmarks)
- call add(bookmarkStrings, k . ' ' . bookmarks[k].StrForOS(0))
- endfor
- call writefile(bookmarkStrings, g:NERDTreeBookmarksFile)
-endfunction
-
" SECTION: Public Functions {{{1
"============================================================
"Returns the node that the cursor is currently on.
@@ -1848,12 +1915,6 @@ function! s:EchoError(msg)
call s:Echo(a:msg)
echohl normal
endfunction
-" FUNCTION: s:FindBookmarks(A,L,P) {{{2
-" completion function for the bookmark commands
-function! s:FindBookmarks(A,L,P)
- let keys = keys(s:GetBookmarks())
- return filter(keys, 'v:val =~ "^' . a:A . '"')
-endfunction
"FUNCTION: s:FindNodeLineNumber(treenode){{{2
"Finds the line number for the given tree node
"
@@ -1916,14 +1977,6 @@ function! s:FindRootNodeLineNumber()
return rootLine
endfunction
-" FUNCTION: s:GetBookmarks(name) {{{2
-" getter/lazy initializer for the g:NERDTreeBookmarks hash
-function! s:GetBookmarks()
- if !exists("g:NERDTreeBookmarks")
- let g:NERDTreeBookmarks = {}
- endif
- return g:NERDTreeBookmarks
-endfunction
"FUNCTION: s:GetPath(ln) {{{2
"Gets the full path to the node that is rendered on the given line number
"
@@ -1999,7 +2052,7 @@ function! s:GetSelectedBookmark()
let line = getline(".")
let name = substitute(line, '^>\(.\{-}\) \[.*\]$', '\1', '')
if name != line
- return name
+ return s:oBookmark.BookmarkFor(name)
endif
endfunction
@@ -2293,23 +2346,20 @@ function! s:RenderBookmarks()
call setline(line(".")+1, ">----------Bookmarks----------")
call cursor(line(".")+1, col("."))
- let bookmarks = s:GetBookmarks()
- for i in keys(bookmarks)
+ for i in s:oBookmark.Bookmarks()
- let pathStrMaxLen = 26 - len(i)
- let pathStr = bookmarks[i].StrForOS(0)
+ let pathStrMaxLen = 26 - len(i.name)
+ let pathStr = i.path.StrForOS(0)
if len(pathStr) > pathStrMaxLen
let pathStr = '<' . strpart(pathStr, len(pathStr) - pathStrMaxLen)
endif
- "call setline(line(".")+1,'>' . i . ' [' . bookmarks[i].StrForOS(0) . ']')
- call setline(line(".")+1,'>' . i . ' [' . pathStr . ']')
+ call setline(line(".")+1,'>' . i.name . ' [' . pathStr . ']')
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
@@ -2618,8 +2668,8 @@ function! s:ActivateNode()
endif
else
let bookmark = s:GetSelectedBookmark()
- if bookmark != ""
- call s:BookmarkToRoot(bookmark)
+ if !empty(bookmark)
+ call s:BookmarkToRoot(bookmark.name)
endif
endif
endfunction
@@ -2677,36 +2727,21 @@ function! s:BindMappings()
exec "nnoremap <silent> <buffer> ". g:NERDTreeMapOpenExpl ." :call <SID>OpenExplorer()<cr>"
command! -buffer -nargs=1 Bookmark :call <SID>BookmarkNode('<args>')
- command! -buffer -complete=customlist,s:FindBookmarks -nargs=1 RevealBookmark :call <SID>RevealBookmark('<args>')
- command! -buffer -complete=customlist,s:FindBookmarks -nargs=1 OpenBookmark :call <SID>OpenBookmark('<args>')
- command! -buffer -complete=customlist,s:FindBookmarks -nargs=* ClearBookmarks call <SID>ClearBookmarks('<args>')
- command! -buffer -complete=customlist,s:FindBookmarks -nargs=+ BookmarkToRoot call <SID>BookmarkToRoot('<args>')
- command! -buffer -nargs=0 ClearAllBookmarks call <SID>ClearAllBookmarks() <bar> call <SID>RenderView()
- command! -buffer -nargs=0 ReadBookmarks call <SID>ReadBookmarks() <bar> call <SID>RenderView()
- command! -buffer -nargs=0 WriteBookmarks call <SID>WriteBookmarks()
+ command! -buffer -complete=customlist,s:CompleteBookmarks -nargs=1 RevealBookmark :call <SID>RevealBookmark('<args>')
+ command! -buffer -complete=customlist,s:CompleteBookmarks -nargs=1 OpenBookmark :call <SID>OpenBookmark('<args>')
+ command! -buffer -complete=customlist,s:CompleteBookmarks -nargs=* ClearBookmarks call <SID>ClearBookmarks('<args>')
+ command! -buffer -complete=customlist,s:CompleteBookmarks -nargs=+ BookmarkToRoot call <SID>BookmarkToRoot('<args>')
+ command! -buffer -nargs=0 ClearAllBookmarks call s:oBookmark.ClearAll() <bar> call <SID>RenderView()
+ command! -buffer -nargs=0 ReadBookmarks call s:oBookmark.CacheBookmarks() <bar> call <SID>RenderView()
+ command! -buffer -nargs=0 WriteBookmarks call s:oBookmark.Write()
endfunction
" FUNCTION: s:BookmarkNode(name) {{{2
" Associate the current node with the given name
function! s:BookmarkNode(name)
- if a:name !~ '^[0-9a-zA-Z_]*$'
- call s:Echo("Bookmarks must be named using numbers, letters and underscores only")
- return
- endif
-
let currentNode = s:GetSelectedNode()
if currentNode != {}
-
- try
- let oldMarkedNode = s:GetNodeForBookmark(a:name, 1)
- call oldMarkedNode.path.UncacheBookmark(a:name)
- catch /NERDTree.Bookmark\(DoesntExist\|NotFound\)/
- endtry
-
- let bookmarks = s:GetBookmarks()
- let bookmarks[a:name] = currentNode.path
- call currentNode.path.CacheBookmarkNames()
- call s:WriteBookmarks()
+ call currentNode.Bookmark(a:name)
call s:RenderView()
else
call s:Echo("select a node first")
@@ -2716,10 +2751,9 @@ endfunction
" Make the node for the given bookmark the new tree root
function! s:BookmarkToRoot(name)
try
- let targetNode = s:GetNodeForBookmark(a:name, 1)
- catch /NERDTree.BookmarkNotFound/
- let bookmarks = s:GetBookmarks()
- let targetNode = s:oTreeFileNode.New(bookmarks[a:name])
+ let targetNode = s:oBookmark.GetNodeForName(a:name, 1)
+ catch /NERDTree.BookmarkNodeNotFound/
+ let targetNode = s:oTreeFileNode.New(s:oBookmark.BookmarkFor(a:name).path)
endtry
call targetNode.MakeRoot()
call s:RenderView()
@@ -2785,7 +2819,6 @@ endfunction
" FUNCTION: s:ClearBookmarks(bookmarks) {{{2
function! s:ClearBookmarks(bookmarks)
- let bookmarks = s:GetBookmarks()
if a:bookmarks == ''
let currentNode = s:GetSelectedNode()
if currentNode != {}
@@ -2793,20 +2826,11 @@ function! s:ClearBookmarks(bookmarks)
endif
else
for name in split(a:bookmarks, ' ')
- if count(keys(bookmarks), name)
- let node = {}
- try
- let node = s:GetNodeForBookmark(name, 1)
- catch /NERDTree/
- endtry
- call remove(bookmarks, name)
- if !empty(node)
- call node.path.CacheBookmarkNames()
- endif
- endif
+ let bookmark = s:oBookmark.BookmarkFor(name)
+ call bookmark.Delete()
endfor
endif
- call s:WriteBookmarks()
+ call s:oBookmark.Write()
call s:RenderView()
endfunction
" FUNCTION: s:CloseChildren() {{{2
@@ -3068,13 +3092,13 @@ endfunction
" put the cursor on the given bookmark and, if its a file, open it
function! s:OpenBookmark(name)
try
- let targetNode = s:GetNodeForBookmark(a:name, 0)
+ let targetNode = s:oBookmark.GetNodeForName(a:name, 0)
call s:PutCursorOnNode(targetNode, 0, 1)
redraw!
catch /NERDTree.BookmarkNotFound/
call s:Echo("note - target node is not cached")
- let bookmarks = s:GetBookmarks()
- let targetNode = s:oTreeFileNode.New(bookmarks[a:name])
+ let bookmark = s:oBookmark.BookmarkFor(a:name)
+ let targetNode = s:oTreeFileNode.New(bookmark.path)
endtry
if targetNode.path.isDirectory
call s:OpenExplorerFor(targetNode)
@@ -3163,7 +3187,7 @@ endfunction
" put the cursor on the node associate with the given name
function! s:RevealBookmark(name)
try
- let targetNode = s:GetNodeForBookmark(a:name, 0)
+ let targetNode = s:oBookmark.GetNodeForName(a:name, 0)
call s:PutCursorOnNode(targetNode, 0, 1)
catch /NERDTree.BookmarkDoesntExist/
call s:Echo("Bookmark isnt cached under the current root")