211 lines
6 KiB
VimL
211 lines
6 KiB
VimL
"CLASS: MenuController
|
|
"============================================================
|
|
let s:MenuController = {}
|
|
let g:NERDTreeMenuController = s:MenuController
|
|
|
|
"FUNCTION: MenuController.New(menuItems) {{{1
|
|
"create a new menu controller that operates on the given menu items
|
|
function! s:MenuController.New(menuItems)
|
|
let newMenuController = copy(self)
|
|
if a:menuItems[0].isSeparator()
|
|
let newMenuController.menuItems = a:menuItems[1:-1]
|
|
else
|
|
let newMenuController.menuItems = a:menuItems
|
|
endif
|
|
return newMenuController
|
|
endfunction
|
|
|
|
" FUNCTION: s:MenuController.isMinimal() {{{1
|
|
function! s:MenuController.isMinimal()
|
|
return g:NERDTreeMinimalMenu
|
|
endfunction
|
|
|
|
" FUNCTION: MenuController.showMenu() {{{1
|
|
" Enter the main loop of the NERDTree menu, prompting the user to select
|
|
" a menu item.
|
|
function! s:MenuController.showMenu()
|
|
call self._saveOptions()
|
|
|
|
try
|
|
let self.selection = 0
|
|
let l:done = 0
|
|
|
|
while !l:done
|
|
if has('nvim')
|
|
mode
|
|
else
|
|
redraw!
|
|
endif
|
|
call self._echoPrompt()
|
|
|
|
let l:key = nr2char(getchar())
|
|
let l:done = self._handleKeypress(l:key)
|
|
endwhile
|
|
finally
|
|
call self._restoreOptions()
|
|
|
|
" Redraw when Ctrl-C or Esc is received.
|
|
if !l:done || self.selection ==# -1
|
|
redraw!
|
|
endif
|
|
endtry
|
|
|
|
if self.selection !=# -1
|
|
let l:m = self._current()
|
|
call l:m.execute()
|
|
endif
|
|
endfunction
|
|
|
|
"FUNCTION: MenuController._echoPrompt() {{{1
|
|
function! s:MenuController._echoPrompt()
|
|
let navHelp = 'Use ' . g:NERDTreeMenuDown . '/' . g:NERDTreeMenuUp . '/enter'
|
|
|
|
if self.isMinimal()
|
|
let selection = self.menuItems[self.selection].text
|
|
let keyword = matchstr(selection, '[^ ]*([^ ]*')
|
|
|
|
let shortcuts = map(copy(self.menuItems), "v:val['shortcut']")
|
|
let shortcuts[self.selection] = ' ' . keyword . ' '
|
|
|
|
echo 'Menu: [' . join(shortcuts, ',') . '] (' . navHelp . ' or shortcut): '
|
|
else
|
|
echo 'NERDTree Menu. ' . navHelp . ', or the shortcuts indicated'
|
|
echo '========================================================='
|
|
|
|
for i in range(0, len(self.menuItems)-1)
|
|
if self.selection ==# i
|
|
echo '> ' . self.menuItems[i].text
|
|
else
|
|
echo ' ' . self.menuItems[i].text
|
|
endif
|
|
endfor
|
|
endif
|
|
endfunction
|
|
|
|
"FUNCTION: MenuController._current(key) {{{1
|
|
"get the MenuItem that is currently selected
|
|
function! s:MenuController._current()
|
|
return self.menuItems[self.selection]
|
|
endfunction
|
|
|
|
"FUNCTION: MenuController._handleKeypress(key) {{{1
|
|
"change the selection (if appropriate) and return 1 if the user has made
|
|
"their choice, 0 otherwise
|
|
function! s:MenuController._handleKeypress(key)
|
|
if a:key ==# g:NERDTreeMenuDown
|
|
call self._cursorDown()
|
|
elseif a:key ==# g:NERDTreeMenuUp
|
|
call self._cursorUp()
|
|
elseif a:key ==# nr2char(27) "escape
|
|
let self.selection = -1
|
|
return 1
|
|
elseif a:key ==# "\r" || a:key ==# "\n" "enter and ctrl-j
|
|
return 1
|
|
else
|
|
let index = self._nextIndexFor(a:key)
|
|
if index !=# -1
|
|
let self.selection = index
|
|
if len(self._allIndexesFor(a:key)) ==# 1
|
|
return 1
|
|
endif
|
|
endif
|
|
endif
|
|
|
|
return 0
|
|
endfunction
|
|
|
|
"FUNCTION: MenuController._allIndexesFor(shortcut) {{{1
|
|
"get indexes to all menu items with the given shortcut
|
|
function! s:MenuController._allIndexesFor(shortcut)
|
|
let toReturn = []
|
|
|
|
for i in range(0, len(self.menuItems)-1)
|
|
if self.menuItems[i].shortcut ==# a:shortcut
|
|
call add(toReturn, i)
|
|
endif
|
|
endfor
|
|
|
|
return toReturn
|
|
endfunction
|
|
|
|
"FUNCTION: MenuController._nextIndexFor(shortcut) {{{1
|
|
"get the index to the next menu item with the given shortcut, starts from the
|
|
"current cursor location and wraps around to the top again if need be
|
|
function! s:MenuController._nextIndexFor(shortcut)
|
|
for i in range(self.selection+1, len(self.menuItems)-1)
|
|
if self.menuItems[i].shortcut ==# a:shortcut
|
|
return i
|
|
endif
|
|
endfor
|
|
|
|
for i in range(0, self.selection)
|
|
if self.menuItems[i].shortcut ==# a:shortcut
|
|
return i
|
|
endif
|
|
endfor
|
|
|
|
return -1
|
|
endfunction
|
|
|
|
"FUNCTION: MenuController._setCmdheight() {{{1
|
|
"sets &cmdheight to whatever is needed to display the menu
|
|
function! s:MenuController._setCmdheight()
|
|
if self.isMinimal()
|
|
let &cmdheight = 1
|
|
else
|
|
let &cmdheight = len(self.menuItems) + 3
|
|
endif
|
|
endfunction
|
|
|
|
"FUNCTION: MenuController._saveOptions() {{{1
|
|
"set any vim options that are required to make the menu work (saving their old
|
|
"values)
|
|
function! s:MenuController._saveOptions()
|
|
let self._oldLazyredraw = &lazyredraw
|
|
let self._oldCmdheight = &cmdheight
|
|
set nolazyredraw
|
|
call self._setCmdheight()
|
|
endfunction
|
|
|
|
"FUNCTION: MenuController._restoreOptions() {{{1
|
|
"restore the options we saved in _saveOptions()
|
|
function! s:MenuController._restoreOptions()
|
|
let &cmdheight = self._oldCmdheight
|
|
let &lazyredraw = self._oldLazyredraw
|
|
endfunction
|
|
|
|
"FUNCTION: MenuController._cursorDown() {{{1
|
|
"move the cursor to the next menu item, skipping separators
|
|
function! s:MenuController._cursorDown()
|
|
let done = 0
|
|
while !done
|
|
if self.selection < len(self.menuItems)-1
|
|
let self.selection += 1
|
|
else
|
|
let self.selection = 0
|
|
endif
|
|
|
|
if !self._current().isSeparator()
|
|
let done = 1
|
|
endif
|
|
endwhile
|
|
endfunction
|
|
|
|
"FUNCTION: MenuController._cursorUp() {{{1
|
|
"move the cursor to the previous menu item, skipping separators
|
|
function! s:MenuController._cursorUp()
|
|
let done = 0
|
|
while !done
|
|
if self.selection > 0
|
|
let self.selection -= 1
|
|
else
|
|
let self.selection = len(self.menuItems)-1
|
|
endif
|
|
|
|
if !self._current().isSeparator()
|
|
let done = 1
|
|
endif
|
|
endwhile
|
|
endfunction
|
|
|
|
" vim: set sw=4 sts=4 et fdm=marker:
|