huge refactor, add bookmark class

This commit is contained in:
Martin Grenfell
2008-06-29 00:23:02 +12:00
parent 73be034d5e
commit d2989eb3e0

View File

@@ -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")