nerdtree

A tree explorer plugin for vim.
Index Commits Files Refs
commit b5fd460560ca8fa3762f26aa6f57477623dac2d6
parent 205367ab3f46dcc88b6ebb819a276e793a21e995
Author: Martin Grenfell <martin.grenfell@gmail.com>
Date:   Thu, 29 Dec 2011 00:17:14 +0000

rework the keymap API

Add "scope" to it. This allows the user to specify that keymaps should
 apply to files/directories/bookmarks or everything. This will reduce
the amount of 'if empty(node)' checks that are done

Diffstat:
Mplugin/NERD_tree.vim | 106+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----
1 file changed, 101 insertions(+), 5 deletions(-)
diff --git a/plugin/NERD_tree.vim b/plugin/NERD_tree.vim
@@ -485,10 +485,21 @@ let s:KeyMap = {}
 function! s:KeyMap.All()
     if !exists("s:keyMaps")
         let s:keyMaps = []
+        let g:keyMaps = s:keyMaps
     endif
     return s:keyMaps
 endfunction
 
+"FUNCTION: KeyMap.FindFor(key, scope) {{{3
+function! s:KeyMap.FindFor(key, scope)
+    for i in s:KeyMap.All()
+        if i.key == a:key && i.scope == a:scope
+            return i
+        endif
+    endfor
+    return {}
+endfunction
+
 "FUNCTION: KeyMap.BindAll() {{{3
 function! s:KeyMap.BindAll()
     for i in s:KeyMap.All()
@@ -498,17 +509,102 @@ endfunction
 
 "FUNCTION: KeyMap.bind() {{{3
 function! s:KeyMap.bind()
-    exec "nnoremap <silent> <buffer> ". self.key ." :call ". self.callback ."()<cr>"
+    exec "nnoremap <buffer> <silent> ". self.key ." :call <SID>KeyMap_Invoke('". self.key ."')<cr>"
+endfunction
+
+"FUNCTION: KeyMap.bind() {{{3
+"Call the KeyMaps callback function
+function! s:KeyMap.invoke(...)
+    if a:0
+        call function(self.callback)(a:1)
+    else
+        call function(self.callback)()
+    endif
+endfunction
+
+
+"FUNCTION: KeyMap.Invoke() {{{3
+"Find a keymapping for a:key and the current scope invoke it.
+"
+"Scope is determined as follows:
+"   * if the cursor is on a dir node then "DirNode"
+"   * if the cursor is on a file node then "FileNode"
+"   * if the cursor is on a bookmark then "Bookmark"
+"
+"If a keymap has the scope of "all" then it will be called if no other keymap
+"is found for a:key and the scope.
+function! s:KeyMap.Invoke(key)
+    let node = s:TreeFileNode.GetSelected()
+    if !empty(node)
+
+        "try file node
+        if !node.path.isDirectory
+            let km = s:KeyMap.FindFor(a:key, "FileNode")
+            if !empty(km)
+                return km.invoke(node)
+            endif
+        endif
+
+        "try dir node
+        if node.path.isDirectory
+            let km = s:KeyMap.FindFor(a:key, "DirNode")
+            if !empty(km)
+                return km.invoke(node)
+            endif
+        endif
+
+        "try generic node
+        let km = s:KeyMap.FindFor(a:key, "Node")
+        if !empty(km)
+            return km.invoke(node)
+        endif
+
+    endif
+
+    "try bookmark
+    let bm = s:Bookmark.GetSelected()
+    if !empty(bm)
+        let km = s:KeyMap.FindFor(a:key, "Bookmark")
+        if !empty(km)
+            return km.invoke(bm)
+        endif
+    endif
+
+    "try all
+    let km = s:KeyMap.FindFor(a:key, "all")
+    if !empty(km)
+        return km.invoke()
+    endif
+endfunction
+
+"this is needed since I cant figure out how to invoke dict functions from a
+"key map
+function! s:KeyMap_Invoke(key)
+    call s:KeyMap.Invoke(a:key)
 endfunction
 
 "FUNCTION: KeyMap.Create(options) {{{3
 function! s:KeyMap.Create(options)
     let newKeyMap = copy(self)
-    let newKeyMap.key = a:options['key']
-    let newKeyMap.quickhelpText = a:options['quickhelpText']
-    let newKeyMap.callback = a:options['callback']
-    call add(s:KeyMap.All(), newKeyMap)
+    let opts = extend({'scope': 'all', 'quickhelpText': ''}, copy(a:options))
+    let newKeyMap.key = opts['key']
+    let newKeyMap.quickhelpText = opts['quickhelpText']
+    let newKeyMap.callback = opts['callback']
+    let newKeyMap.scope = opts['scope']
+
+    call s:KeyMap.Add(newKeyMap)
 endfunction
+
+"FUNCTION: KeyMap.Add(keymap) {{{3
+function! s:KeyMap.Add(keymap)
+    let oldmap = s:KeyMap.FindFor(a:keymap.key, a:keymap.scope)
+    if !empty(oldmap)
+        call remove(s:KeyMap.All(), index(s:KeyMap.All(), oldmap))
+    endif
+
+    call add(s:KeyMap.All(), a:keymap)
+endfunction
+
 "CLASS: MenuController {{{2
 "============================================================
 let s:MenuController = {}