commit b7cdc191ca25aef5525a39acfdc938dee5a26674
parent 54fab2f2e55e9a413e2a1f5aec0f9129036d2168
Author: Martin Grenfell <martin.grenfell@gmail.com>
Date: Thu, 5 Jan 2012 10:54:21 +0000
refactor the TreeFileNode*open* methods
Make these all go through .open() and pass in args to control the
behaviour. Deprecate the old `openSplit`, `openVSplit` and
`openInNewTab` methods and make them private.
This makes the API a lot cleaner - it was getting pretty messy in this
regard.
Diffstat:
| M | plugin/NERD_tree.vim | | | 198 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------------- |
1 file changed, 140 insertions(+), 58 deletions(-)
diff --git a/plugin/NERD_tree.vim b/plugin/NERD_tree.vim
@@ -905,12 +905,9 @@ endfunction
"classes.
"============================================================
let s:TreeFileNode = {}
-"FUNCTION: TreeFileNode.activate(forceKeepWinOpen) {{{3
-function! s:TreeFileNode.activate(forceKeepWinOpen)
- call self.open()
- if !a:forceKeepWinOpen
- call s:closeTreeIfQuitOnOpen()
- end
+"FUNCTION: TreeFileNode.activate(...) {{{3
+function! s:TreeFileNode.activate(...)
+ call self.open(a:0 ? a:1 : {})
endfunction
"FUNCTION: TreeFileNode.bookmark(name) {{{3
"bookmark this node with a:name
@@ -1216,45 +1213,82 @@ function! s:TreeFileNode.New(path)
endfunction
"FUNCTION: TreeFileNode.open() {{{3
-"Open the file represented by the given node in the current window, splitting
-"the window if needed
+"Args:
+"A dictionary containing the following keys (all optional):
+" 'split': Specifies whether the node should be opened in new split/tab or in
+" the previous window. Can be either 'v' or 'h' or 't' (for open in
+" new tab)
+" 'reuse': if a window is displaying the file then jump the cursor there
+" 'keepopen': dont close the tree window
+" 'preview': open the file, but keep the cursor in the tree win
"
-"ARGS:
-"treenode: file node to open
-function! s:TreeFileNode.open()
+function! s:TreeFileNode.open(...)
+ let opts = a:0 ? a:1 : {}
+
+ let currentBuf = bufnr("")
+ let currentTab = tabpagenr()
+
+ if s:has_opt(opts, 'reuse') && self._putCursorInBufWin()
+ return
+ endif
+
+ if has_key(opts, 'split')
+ if opts['split'] == 'v'
+ call self._openVSplit()
+ elseif opts['split'] == 'h'
+ call self._openSplit()
+ else
+ call self._openInNewTab(opts)
+ endif
+ else
+ call self._open()
+ endif
+
+ if !s:has_opt(opts, 'forceKeepWinOpen')
+ call s:closeTreeIfQuitOnOpen()
+ endif
+
+ if s:has_opt(opts, 'preview')
+ call s:exec('normal ' . currentTab . 'gt')
+ call s:exec(bufwinnr(currentBuf) . 'wincmd w')
+ endif
+endfunction
+
+"FUNCTION: TreeFileNode._open() {{{3
+function! s:TreeFileNode._open()
+
if b:NERDTreeType ==# "secondary"
exec 'edit ' . self.path.str({'format': 'Edit'})
return
endif
- "if the file is already open in this tab then just stick the cursor in it
- let winnr = bufwinnr('^' . self.path.str() . '$')
- if winnr != -1
- call s:exec(winnr . "wincmd w")
-
+ if !s:isWindowUsable(winnr("#")) && s:firstUsableWindow() ==# -1
+ call self._openSplit()
else
- if !s:isWindowUsable(winnr("#")) && s:firstUsableWindow() ==# -1
- call self.openSplit()
- else
- try
- if !s:isWindowUsable(winnr("#"))
- call s:exec(s:firstUsableWindow() . "wincmd w")
- else
- call s:exec('wincmd p')
- endif
- exec ("edit " . self.path.str({'format': 'Edit'}))
- catch /^Vim\%((\a\+)\)\=:E37/
- call s:putCursorInTreeWin()
- throw "NERDTree.FileAlreadyOpenAndModifiedError: ". self.path.str() ." is already open and modified."
- catch /^Vim\%((\a\+)\)\=:/
- echo v:exception
- endtry
- endif
+ try
+ if !s:isWindowUsable(winnr("#"))
+ call s:exec(s:firstUsableWindow() . "wincmd w")
+ else
+ call s:exec('wincmd p')
+ endif
+ exec ("edit " . self.path.str({'format': 'Edit'}))
+ catch /^Vim\%((\a\+)\)\=:E37/
+ call s:putCursorInTreeWin()
+ throw "NERDTree.FileAlreadyOpenAndModifiedError: ". self.path.str() ." is already open and modified."
+ catch /^Vim\%((\a\+)\)\=:/
+ echo v:exception
+ endtry
endif
endfunction
"FUNCTION: TreeFileNode.openSplit() {{{3
"Open this node in a new window
function! s:TreeFileNode.openSplit()
+ call s:deprecated('TreeFileNode.openSplit', 'is deprecated, use .open() instead.')
+ call self.open({'split': 'h'})
+endfunction
+"FUNCTION: TreeFileNode._openSplit() {{{3
+"Open this node in a new window
+function! s:TreeFileNode._openSplit()
if b:NERDTreeType ==# "secondary"
exec "split " . self.path.str({'format': 'Edit'})
@@ -1321,6 +1355,12 @@ endfunction
"FUNCTION: TreeFileNode.openVSplit() {{{3
"Open this node in a new vertical window
function! s:TreeFileNode.openVSplit()
+ call s:deprecated('TreeFileNode.openVSplit', 'is deprecated, use .open() instead.')
+ call self.open({'split': 'v'})
+endfunction
+"FUNCTION: TreeFileNode._openVSplit() {{{3
+"Open this node in a new vertical window
+function! s:TreeFileNode._openVSplit()
if b:NERDTreeType ==# "secondary"
exec "vnew " . self.path.str({'format': 'Edit'})
return
@@ -1341,19 +1381,42 @@ function! s:TreeFileNode.openVSplit()
endfunction
"FUNCTION: TreeFileNode.openInNewTab(options) {{{3
function! s:TreeFileNode.openInNewTab(options)
+ echomsg 'TreeFileNode.openInNewTab is deprecated'
+ call self.open(extend({'split': 't'}, a:options))
+endfunction
+"FUNCTION: TreeFileNode._openInNewTab(options) {{{3
+function! s:TreeFileNode._openInNewTab(options)
let currentTab = tabpagenr()
-
- if !s:has_opt(a:options, 'keepTreeOpen')
- call s:closeTreeIfQuitOnOpen()
- endif
-
exec "tabedit " . self.path.str({'format': 'Edit'})
if s:has_opt(a:options, 'stayInCurrentTab')
exec "tabnext " . currentTab
endif
-
endfunction
+"FUNCTION: TreeFileNode._putCursorInBufWin(){{{3
+"put the cursor in the first window we find for this file
+"
+"return 1 if we were successful
+function! s:TreeFileNode._putCursorInBufWin(...)
+ "check the current tab for the window
+ let winnr = bufwinnr('^' . self.path.str() . '$')
+ if winnr != -1
+ call s:exec(winnr . "wincmd w")
+ return 1
+ else
+ "check other tabs
+ let tabnr = self.path.tabnr()
+ if tabnr
+ call s:exec('normal! ' . tabnr . 'gt')
+ let winnr = bufwinnr('^' . self.path.str() . '$')
+ call s:exec(winnr . "wincmd w")
+ return 1
+ endif
+ endif
+ return 0
+endfunction
+
+
"FUNCTION: TreeFileNode.putCursorHere(isJump, recurseUpward){{{3
"Places the cursor on the line number this node is rendered on
"
@@ -1778,7 +1841,7 @@ endfunction
"
"Return: the number of child nodes read
unlet s:TreeDirNode.open
-function! s:TreeDirNode.open()
+function! s:TreeDirNode.open(...)
let self.isOpen = 1
if self.children ==# []
return self._initChildren(0)
@@ -2603,6 +2666,21 @@ function! s:Path.strTrunk()
return self.drive . '/' . join(self.pathSegments[0:-2], '/')
endfunction
+" FUNCTION: Path.tabnr() {{{3
+" return the number of the first tab that is displaying this file
+"
+" return 0 if no tab was found
+function! s:Path.tabnr()
+ let str = self.str()
+ for t in range(tabpagenr('$'))
+ for b in tabpagebuflist(t+1)
+ if str == expand('#' . b . ':p')
+ return t+1
+ endif
+ endfor
+ endfor
+ return 0
+endfunction
"FUNCTION: Path.WinToUnixPath(pathstr){{{3
"Takes in a windows path and returns the unix equiv
"
@@ -2669,6 +2747,20 @@ endfunction
function! s:completeBookmarks(A,L,P)
return filter(s:Bookmark.BookmarkNames(), 'v:val =~# "^' . a:A . '"')
endfunction
+" FUNCTION: s:deprecated(func, [msg]) {{{2
+" Issue a deprecation warning for a:func. If a second arg is given, use this
+" as the deprecation message
+function! s:deprecated(func, ...)
+ let msg = a:0 ? a:func . ' ' . a:1 : a:func . ' is deprecated'
+
+ if !exists('s:deprecationWarnings')
+ let s:deprecationWarnings = {}
+ endif
+ if !has_key(s:deprecationWarnings, a:func)
+ let s:deprecationWarnings[a:func] = 1
+ echomsg msg
+ endif
+endfunction
" FUNCTION: s:exec(cmd) {{{2
" same as :exec cmd but eventignore=all is set for the duration
function! s:exec(cmd)
@@ -3388,16 +3480,6 @@ function! s:openEntrySplit(vertical, forceKeepWindowOpen)
endif
endfunction
-"FUNCTION: s:previewNode(node, openNewWin) {{{2
-function! s:previewNode(node, openNewWin)
- let currentBuf = bufnr("")
- if a:openNewWin > 0
- call s:openEntrySplit(a:openNewWin ==# 2,1)
- else
- call s:activateNode(a:node)
- end
- call s:exec(bufwinnr(currentBuf) . "wincmd w")
-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
@@ -3688,7 +3770,7 @@ endfunction
"FUNCTION: s:activateNode() {{{2
"handle the user activating a tree node
function! s:activateNode(node)
- call a:node.activate(0)
+ call a:node.activate({'reuse': 1})
endfunction
"FUNCTION: s:activateBookmark() {{{2
@@ -3994,12 +4076,12 @@ endfunction
" FUNCTION: s:openHSplit(node) {{{2
function! s:openHSplit(node)
- call a:node.openSplit()
+ call a:node.activate({'split': 'h'})
endfunction
" FUNCTION: s:openVSplit(node) {{{2
function! s:openVSplit(node)
- call a:node.openVSplit()
+ call a:node.activate({'split': 'v'})
endfunction
" FUNCTION: s:openExplorer(node) {{{2
@@ -4009,12 +4091,12 @@ endfunction
" FUNCTION: s:openInNewTab(target) {{{2
function! s:openInNewTab(target)
- call a:target.openInNewTab({})
+ call a:target.activate({'split': 't'})
endfunction
" FUNCTION: s:openInNewTabSilent(target) {{{2
function! s:openInNewTabSilent(target)
- call a:target.openInNewTab({'stayInCurrentTab': 1})
+ call a:target.activate({'split': 't', 'stayInCurrentTab': 1})
endfunction
" FUNCTION: s:openNodeRecursively(node) {{{2
@@ -4028,17 +4110,17 @@ endfunction
"FUNCTION: s:previewNodeCurrent(node) {{{2
function! s:previewNodeCurrent(node)
- call s:previewNode(a:node, 0)
+ call a:node.open({'preview': 1})
endfunction
"FUNCTION: s:previewNodeHSplit(node) {{{2
function! s:previewNodeHSplit(node)
- call s:previewNode(a:node, 1)
+ call a:node.open({'preview': 1, 'split': 'h'})
endfunction
"FUNCTION: s:previewNodeVSplit(node) {{{2
function! s:previewNodeVSplit(node)
- call s:previewNode(a:node, 2)
+ call a:node.open({'preview': 1, 'split': 'v'})
endfunction