Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Prepare for multi-mode maps

  • Loading branch information...
commit 422fa77c8e9e94f511fa76bbae497e1eaa30b9c1 1 parent cf04794
@tomtom authored
Showing with 164 additions and 73 deletions.
  1. +22 −15 autoload/tlib/World.vim
  2. +142 −58 autoload/tlib/input.vim
View
37 autoload/tlib/World.vim
@@ -716,31 +716,36 @@ endf
" :nodoc:
function! s:prototype.DisplayHelp() dict "{{{3
" \ 'Help:',
+ let esc_help = self.key_mode == 'default' ? 'Abort' : 'Reset keymap'
let help = [
- \ self.FormatHelp('Enter, <cr>', 'Pick the current item', '<Esc>', 'Abort'),
+ \ self.FormatHelp('Enter, <cr>', 'Pick the current item', '<Esc>', esc_help),
\ self.FormatHelp('<m-Number>', 'Pick an item', '<bs>, <c-bs>', 'Reduce filter'),
\ self.FormatHelp('Mouse', 'Pick an item', 'Letter', 'Filter the list'),
- \ self.FormatHelp('<c|m-r>', 'Reset the display', 'Up/Down', 'Next/previous item'),
- \ self.FormatHelp('<c|m-q>', 'Edit top filter string', 'Page Up/Down', 'Scroll'),
\ ]
- if self.allow_suspend
- call add(help, self.FormatHelp('<c|m-z>', 'Suspend/Resume', '<c-o>', 'Switch to origin'))
- endif
-
- if stridx(self.type, 'm') != -1
+ if self.key_mode == 'default'
let help += [
- \ self.FormatHelp('<s-up/down>', '(Un)Select items', '#, <c-space>', '(Un)Select the current item'),
- \ self.FormatHelp('<c|m-a>', '(Un)Select all currently visible items')
- \ ]
- " \ '<c-\> ... Show only selected',
+ \ self.FormatHelp('<c|m-r>', 'Reset the display', 'Up/Down', 'Next/previous item'),
+ \ self.FormatHelp('<c|m-q>', 'Edit top filter string', 'Page Up/Down', 'Scroll'),
+ \ ]
+ if self.allow_suspend
+ call add(help, self.FormatHelp('<c|m-z>', 'Suspend/Resume', '<c-o>', 'Switch to origin'))
+ endif
+ if stridx(self.type, 'm') != -1
+ let help += [
+ \ self.FormatHelp('<s-up/down>', '(Un)Select items', '#, <c-space>', '(Un)Select the current item'),
+ \ self.FormatHelp('<c|m-a>', '(Un)Select all currently visible items')
+ \ ]
+ " \ '<c-\> ... Show only selected',
+ endif
endif
+
let k0 = ''
let h0 = ''
let i0 = 0
let i = 0
- let nkey_handlers = len(self.key_handlers)
- for handler in self.key_handlers
+ let nkey_handlers = len(self.key_mode[self.key_mode])
+ for handler in values(self.key_map[self.key_mode])
let i += 1
let key = get(handler, 'key_name', '')
if !empty(key)
@@ -757,9 +762,11 @@ function! s:prototype.DisplayHelp() dict "{{{3
endif
endif
endfor
- if !empty(self.help_extra)
+
+ if self.key_mode == 'default' && !empty(self.help_extra)
let help += self.help_extra
endif
+
let help += self.matcher.Help(self)
let help += [
\ '',
View
200 autoload/tlib/input.vim
@@ -3,8 +3,8 @@
" @Website: http://www.vim.org/account/profile.php?user_id=4037
" @License: GPL (see http://www.gnu.org/licenses/gpl.txt)
" @Created: 2007-06-30.
-" @Last Change: 2012-07-15.
-" @Revision: 0.0.883
+" @Last Change: 2012-09-17.
+" @Revision: 0.0.942
" :filedoc:
@@ -122,43 +122,19 @@ endf
" (an instance of tlib#World as returned by |tlib#World#New|).
function! tlib#input#ListW(world, ...) "{{{3
TVarArg 'cmd'
- if a:world.pick_last_item >= 1 && stridx(a:world.type, 'e') == -1 && len(a:world.base) <= 1
- let rv = get(a:world.base, 0, a:world.rv)
- if stridx(a:world.type, 'm') != -1
+ " let time0 = str2float(reltimestr(reltime())) " DBG
+ " TLogVAR time0
+ let world = a:world
+ if world.pick_last_item >= 1 && stridx(world.type, 'e') == -1 && len(world.base) <= 1
+ let rv = get(world.base, 0, world.rv)
+ if stridx(world.type, 'm') != -1
return [rv]
else
return rv
endif
endif
- let world = a:world
- let world.filetype = &filetype
- let world.fileencoding = &fileencoding
- call world.SetMatchMode(tlib#var#Get('tlib_inputlist_match', 'wb'))
call s:Init(world, cmd)
" TLogVAR world.state, world.sticky, world.initial_index
- let key_agents = copy(g:tlib_keyagents_InputList_s)
- if stridx(world.type, 'm') != -1
- call extend(key_agents, g:tlib_keyagents_InputList_m, 'force')
- endif
- if g:tlib#input#use_popup
- amenu ]TLibInputListPopupMenu.Pick\ selected\ item <cr>
- amenu ]TLibInputListPopupMenu.Select #
- amenu ]TLibInputListPopupMenu.Select\ all <c-a>
- amenu ]TLibInputListPopupMenu.Reset\ list <c-r>
- amenu ]TLibInputListPopupMenu.Cancel <esc>
- amenu ]TLibInputListPopupMenu.-StandardEntries- :
- endif
- for handler in world.key_handlers
- let k = get(handler, 'key', '')
- if !empty(k)
- let key_agents[k] = handler.agent
- if g:tlib#input#use_popup && has_key(handler, 'help') && !empty(handler.help)
- exec 'amenu ]TLibInputListPopupMenu.'. escape(handler.help, ' .\')
- \ .' '. handler.key_name
- let world.has_menu = 1
- endif
- endif
- endfor
" let statusline = &l:statusline
" let laststatus = &laststatus
let lastsearch = @/
@@ -167,27 +143,18 @@ function! tlib#input#ListW(world, ...) "{{{3
let @/ = ''
let dlist = []
" let &laststatus = 2
- let world.initial_display = 1
try
while !empty(world.state) && world.state !~ '^exit' && (world.show_empty || !empty(world.base))
" TLogDBG 'while'
" TLogVAR world.state
+ " let time01 = str2float(reltimestr(reltime())) " DBG
+ " TLogVAR time01, time01 - time0
try
- for handler in world.state_handlers
- let eh = get(handler, 'state', '')
- if !empty(eh) && world.state =~ eh
- let ea = get(handler, 'exec', '')
- if !empty(ea)
- exec ea
- else
- let agent = get(handler, 'agent', '')
- let world = call(agent, [world, world.GetSelectedItems(world.CurrentItem())])
- call s:CheckAgentReturnValue(agent, world)
- endif
- endif
- endfor
+ call s:RunStateHandlers(world)
+ " let time02 = str2float(reltimestr(reltime())) " DBG
+ " TLogVAR time02, time02 - time0
if world.state =~ '\<reset\>'
" TLogDBG 'reset'
" call world.Reset(world.state =~ '\<initial\>')
@@ -195,23 +162,21 @@ function! tlib#input#ListW(world, ...) "{{{3
continue
endif
- let llenw = len(world.base) - winheight(0) + 1
- if world.offset > llenw
- let world.offset = llenw
- endif
- if world.offset < 1
- let world.offset = 1
- endif
+ call s:SetOffset(world)
+ " let time02 = str2float(reltimestr(reltime())) " DBG
+ " TLogVAR time02, time02 - time0
" TLogDBG 1
" TLogVAR world.state
if world.state == 'scroll'
let world.prefidx = world.offset
let world.state = 'redisplay'
endif
+
if world.state =~ '\<sticky\>'
let world.sticky = 1
endif
+
" TLogVAR world.filter
" TLogVAR world.sticky
if world.state =~ '\<pick\>'
@@ -220,9 +185,15 @@ function! tlib#input#ListW(world, ...) "{{{3
throw 'pick'
elseif world.state =~ 'display'
if world.state =~ '^display'
+ " let time03 = str2float(reltimestr(reltime())) " DBG
+ " TLogVAR time03, time03 - time0
if world.IsValidFilter()
+ " let time1 = str2float(reltimestr(reltime())) " DBG
+ " TLogVAR time1, time1 - time0
call world.BuildTableList()
+ " let time2 = str2float(reltimestr(reltime())) " DBG
+ " TLogVAR time2, time2 - time0
" TLogDBG 2
" TLogDBG len(world.table)
" TLogVAR world.table
@@ -237,6 +208,8 @@ function! tlib#input#ListW(world, ...) "{{{3
let dindex = world.index_table
let world.index_width = len(max(dindex))
endif
+ " let time3 = str2float(reltimestr(reltime())) " DBG
+ " TLogVAR time3, time3 - time0
if world.llen == 0 && !world.show_empty
call world.ReduceFilter()
let world.offset = 1
@@ -255,6 +228,8 @@ function! tlib#input#ListW(world, ...) "{{{3
let world.last_item = ''
endif
endif
+ " let time4 = str2float(reltimestr(reltime())) " DBG
+ " TLogVAR time4, time4 - time0
" TLogDBG 4
" TLogVAR world.idx, world.llen, world.state
" TLogDBG world.FilterIsEmpty()
@@ -270,6 +245,8 @@ function! tlib#input#ListW(world, ...) "{{{3
let world.prefidx = 1
endif
endif
+ " let time5 = str2float(reltimestr(reltime())) " DBG
+ " TLogVAR time5, time5 - time0
" TLogVAR world.initial_index, world.prefidx
" TLogDBG 5
" TLogDBG len(world.list)
@@ -284,12 +261,18 @@ function! tlib#input#ListW(world, ...) "{{{3
endif
" TLogVAR world.prefidx
" TLogDBG 6
+ " let time6 = str2float(reltimestr(reltime())) " DBG
+ " TLogVAR time6, time6 - time0
if world.offset_horizontal > 0
call map(dlist, 'v:val[world.offset_horizontal:-1]')
endif
+ " let time7 = str2float(reltimestr(reltime())) " DBG
+ " TLogVAR time7, time7 - time0
" TLogVAR dindex
let dlist = map(range(0, world.llen - 1), 'printf("%0'. world.index_width .'d", dindex[v:val]) .": ". dlist[v:val]')
" TLogVAR dlist
+ " let time8 = str2float(reltimestr(reltime())) " DBG
+ " TLogVAR time8, time8 - time0
else
@@ -365,19 +348,26 @@ function! tlib#input#ListW(world, ...) "{{{3
let c = tlib#char#Get(world.timeout, world.timeout_resolution)
if world.state != ''
" continue
- elseif has_key(key_agents, c)
+ elseif has_key(world.key_map[world.key_mode], c)
let sr = @/
silent! let @/ = lastsearch
- " TLogVAR c, key_agents[c]
- " TLog "Agent: ". string(key_agents[c])
- let world = call(key_agents[c], [world, world.GetSelectedItems(world.CurrentItem())])
+ " TLogVAR c, world.key_map[world.key_mode][c]
+ " TLog "Agent: ". string(world.key_map[world.key_mode][c])
+ let handler = world.key_map[world.key_mode][c]
+ " TLogVAR handler
+ let world = call(handler.agent, [world, world.GetSelectedItems(world.CurrentItem())])
call s:CheckAgentReturnValue(c, world)
silent! let @/ = sr
" continue
elseif c == 13
throw 'pick'
elseif c == 27
- let world.state = 'exit empty'
+ if world.key_mode != 'default'
+ let world.key_mode = 'default'
+ let world.state = 'redisplay'
+ else
+ let world.state = 'exit empty'
+ endif
elseif c == "\<LeftMouse>"
let world.prefidx = world.GetLineIdx(v:mouse_lnum)
" let world.offset = world.prefidx
@@ -588,6 +578,7 @@ endf
function! s:Init(world, cmd) "{{{3
" TLogVAR a:cmd
+ let a:world.initial_display = 1
if a:cmd =~ '\<sticky\>'
let a:world.sticky = 1
endif
@@ -602,15 +593,97 @@ function! s:Init(world, cmd) "{{{3
endif
elseif !a:world.initialized
" TLogVAR a:world.initialized, a:world.win_wnr, a:world.bufnr
+ let a:world.filetype = &filetype
+ let a:world.fileencoding = &fileencoding
+ call a:world.SetMatchMode(tlib#var#Get('tlib_inputlist_match', 'wb'))
call a:world.Initialize()
+ let a:world.key_mode = 'default'
+ let a:world.key_map = {
+ \ a:world.key_mode : copy(g:tlib_keyagents_InputList_s)
+ \ }
+ if stridx(a:world.type, 'm') != -1
+ call extend(a:world.key_map[a:world.key_mode], g:tlib_keyagents_InputList_m, 'force')
+ endif
+ let a:world.key_map[a:world.key_mode] = map(a:world.key_map[a:world.key_mode], 'type(v:val) == 4 ? v:val : {"agent": v:val}')
+ if type(a:world.key_handlers) == 3
+ call s:ExtendKeyMap(a:world, a:world.key_mode, a:world.key_handlers)
+ elseif type(a:world.key_handlers) == 4
+ for [world_key_mode, world_key_handlers] in items(a:world.key_handlers)
+ call s:ExtendKeyMap(a:world, world_key_mode, world_key_handlers)
+ endfor
+ else
+ throw "tlib#input#ListW: key_handlers must be either a list or a dictionary"
+ endif
if !empty(a:cmd)
let a:world.state .= ' '. a:cmd
endif
endif
+ call s:BuildMenu(a:world)
" TLogVAR a:world.state, a:world.sticky
endf
+function! s:ExtendKeyMap(world, key_mode, key_handlers) "{{{3
+ for handler in a:key_handlers
+ let k = get(handler, 'key', '')
+ if !empty(k)
+ let a:world.key_map[a:key_mode][k] = handler
+ endif
+ endfor
+endf
+
+
+function! s:BuildMenu(world) "{{{3
+ if g:tlib#input#use_popup
+ if a:world.has_menu
+ silent! aunmenu ]TLibInputListPopupMenu
+ endif
+ amenu ]TLibInputListPopupMenu.Pick\ selected\ item <cr>
+ amenu ]TLibInputListPopupMenu.Select #
+ amenu ]TLibInputListPopupMenu.Select\ all <c-a>
+ amenu ]TLibInputListPopupMenu.Reset\ list <c-r>
+ amenu ]TLibInputListPopupMenu.Cancel <esc>
+ amenu ]TLibInputListPopupMenu.-StandardEntries- :
+ for [key_mode, key_handlers] in items(a:world.key_map)
+ let keys = sort(keys(key_handlers))
+ for key in keys
+ let handler = key_handlers[key]
+ let k = get(handler, 'key', '')
+ if !empty(k) && has_key(handler, 'help') && !empty(handler.help)
+ if empty(key_mode) || key_mode == 'default'
+ exec 'amenu ]TLibInputListPopupMenu.'. escape(handler.help, ' .\')
+ \ .' '. handler.key_name
+ else
+ exec 'amenu ]TLibInputListPopupMenu'.
+ \ '.'. escape(key_mode, ' .\')
+ \ '.'. escape(handler.help, ' .\')
+ \ .' '. handler.key_name
+ endif
+ let a:world.has_menu = 1
+ endif
+ endfor
+ endfor
+ endif
+endf
+
+
+function! s:RunStateHandlers(world) "{{{3
+ for handler in a:world.state_handlers
+ let eh = get(handler, 'state', '')
+ if !empty(eh) && a:world.state =~ eh
+ let ea = get(handler, 'exec', '')
+ if !empty(ea)
+ exec ea
+ else
+ let agent = get(handler, 'agent', '')
+ let a:world = call(agent, [a:world, a:world.GetSelectedItems(a:world.CurrentItem())])
+ call s:CheckAgentReturnValue(agent, a:world)
+ endif
+ endif
+ endfor
+endf
+
+
function! s:CheckAgentReturnValue(name, value) "{{{3
if type(a:value) != 4 && !has_key(a:value, 'state')
echoerr 'Malformed agent: '. a:name
@@ -619,6 +692,17 @@ function! s:CheckAgentReturnValue(name, value) "{{{3
endf
+function! s:SetOffset(world) "{{{3
+ let llenw = len(a:world.base) - winheight(0) + 1
+ if a:world.offset > llenw
+ let a:world.offset = llenw
+ endif
+ if a:world.offset < 1
+ let a:world.offset = 1
+ endif
+endf
+
+
" Functions related to tlib#input#EditList(type, ...) "{{{2
" :def: function! tlib#input#EditList(query, list, ?timeout=0)
Please sign in to comment.
Something went wrong with that request. Please try again.