Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Prepare for multi-mode maps

  • Loading branch information...
commit 422fa77c8e9e94f511fa76bbae497e1eaa30b9c1 1 parent cf04794
Tom Link authored

Showing 2 changed files with 164 additions and 73 deletions. Show diff stats Hide diff stats

  1. +22 15 autoload/tlib/World.vim
  2. +142 58 autoload/tlib/input.vim
37 autoload/tlib/World.vim
@@ -716,31 +716,36 @@ endf
716 716 " :nodoc:
717 717 function! s:prototype.DisplayHelp() dict "{{{3
718 718 " \ 'Help:',
  719 + let esc_help = self.key_mode == 'default' ? 'Abort' : 'Reset keymap'
719 720 let help = [
720   - \ self.FormatHelp('Enter, <cr>', 'Pick the current item', '<Esc>', 'Abort'),
  721 + \ self.FormatHelp('Enter, <cr>', 'Pick the current item', '<Esc>', esc_help),
721 722 \ self.FormatHelp('<m-Number>', 'Pick an item', '<bs>, <c-bs>', 'Reduce filter'),
722 723 \ self.FormatHelp('Mouse', 'Pick an item', 'Letter', 'Filter the list'),
723   - \ self.FormatHelp('<c|m-r>', 'Reset the display', 'Up/Down', 'Next/previous item'),
724   - \ self.FormatHelp('<c|m-q>', 'Edit top filter string', 'Page Up/Down', 'Scroll'),
725 724 \ ]
726 725
727   - if self.allow_suspend
728   - call add(help, self.FormatHelp('<c|m-z>', 'Suspend/Resume', '<c-o>', 'Switch to origin'))
729   - endif
730   -
731   - if stridx(self.type, 'm') != -1
  726 + if self.key_mode == 'default'
732 727 let help += [
733   - \ self.FormatHelp('<s-up/down>', '(Un)Select items', '#, <c-space>', '(Un)Select the current item'),
734   - \ self.FormatHelp('<c|m-a>', '(Un)Select all currently visible items')
735   - \ ]
736   - " \ '<c-\> ... Show only selected',
  728 + \ self.FormatHelp('<c|m-r>', 'Reset the display', 'Up/Down', 'Next/previous item'),
  729 + \ self.FormatHelp('<c|m-q>', 'Edit top filter string', 'Page Up/Down', 'Scroll'),
  730 + \ ]
  731 + if self.allow_suspend
  732 + call add(help, self.FormatHelp('<c|m-z>', 'Suspend/Resume', '<c-o>', 'Switch to origin'))
  733 + endif
  734 + if stridx(self.type, 'm') != -1
  735 + let help += [
  736 + \ self.FormatHelp('<s-up/down>', '(Un)Select items', '#, <c-space>', '(Un)Select the current item'),
  737 + \ self.FormatHelp('<c|m-a>', '(Un)Select all currently visible items')
  738 + \ ]
  739 + " \ '<c-\> ... Show only selected',
  740 + endif
737 741 endif
  742 +
738 743 let k0 = ''
739 744 let h0 = ''
740 745 let i0 = 0
741 746 let i = 0
742   - let nkey_handlers = len(self.key_handlers)
743   - for handler in self.key_handlers
  747 + let nkey_handlers = len(self.key_mode[self.key_mode])
  748 + for handler in values(self.key_map[self.key_mode])
744 749 let i += 1
745 750 let key = get(handler, 'key_name', '')
746 751 if !empty(key)
@@ -757,9 +762,11 @@ function! s:prototype.DisplayHelp() dict "{{{3
757 762 endif
758 763 endif
759 764 endfor
760   - if !empty(self.help_extra)
  765 +
  766 + if self.key_mode == 'default' && !empty(self.help_extra)
761 767 let help += self.help_extra
762 768 endif
  769 +
763 770 let help += self.matcher.Help(self)
764 771 let help += [
765 772 \ '',
200 autoload/tlib/input.vim
@@ -3,8 +3,8 @@
3 3 " @Website: http://www.vim.org/account/profile.php?user_id=4037
4 4 " @License: GPL (see http://www.gnu.org/licenses/gpl.txt)
5 5 " @Created: 2007-06-30.
6   -" @Last Change: 2012-07-15.
7   -" @Revision: 0.0.883
  6 +" @Last Change: 2012-09-17.
  7 +" @Revision: 0.0.942
8 8
9 9
10 10 " :filedoc:
@@ -122,43 +122,19 @@ endf
122 122 " (an instance of tlib#World as returned by |tlib#World#New|).
123 123 function! tlib#input#ListW(world, ...) "{{{3
124 124 TVarArg 'cmd'
125   - if a:world.pick_last_item >= 1 && stridx(a:world.type, 'e') == -1 && len(a:world.base) <= 1
126   - let rv = get(a:world.base, 0, a:world.rv)
127   - if stridx(a:world.type, 'm') != -1
  125 + " let time0 = str2float(reltimestr(reltime())) " DBG
  126 + " TLogVAR time0
  127 + let world = a:world
  128 + if world.pick_last_item >= 1 && stridx(world.type, 'e') == -1 && len(world.base) <= 1
  129 + let rv = get(world.base, 0, world.rv)
  130 + if stridx(world.type, 'm') != -1
128 131 return [rv]
129 132 else
130 133 return rv
131 134 endif
132 135 endif
133   - let world = a:world
134   - let world.filetype = &filetype
135   - let world.fileencoding = &fileencoding
136   - call world.SetMatchMode(tlib#var#Get('tlib_inputlist_match', 'wb'))
137 136 call s:Init(world, cmd)
138 137 " TLogVAR world.state, world.sticky, world.initial_index
139   - let key_agents = copy(g:tlib_keyagents_InputList_s)
140   - if stridx(world.type, 'm') != -1
141   - call extend(key_agents, g:tlib_keyagents_InputList_m, 'force')
142   - endif
143   - if g:tlib#input#use_popup
144   - amenu ]TLibInputListPopupMenu.Pick\ selected\ item <cr>
145   - amenu ]TLibInputListPopupMenu.Select #
146   - amenu ]TLibInputListPopupMenu.Select\ all <c-a>
147   - amenu ]TLibInputListPopupMenu.Reset\ list <c-r>
148   - amenu ]TLibInputListPopupMenu.Cancel <esc>
149   - amenu ]TLibInputListPopupMenu.-StandardEntries- :
150   - endif
151   - for handler in world.key_handlers
152   - let k = get(handler, 'key', '')
153   - if !empty(k)
154   - let key_agents[k] = handler.agent
155   - if g:tlib#input#use_popup && has_key(handler, 'help') && !empty(handler.help)
156   - exec 'amenu ]TLibInputListPopupMenu.'. escape(handler.help, ' .\')
157   - \ .' '. handler.key_name
158   - let world.has_menu = 1
159   - endif
160   - endif
161   - endfor
162 138 " let statusline = &l:statusline
163 139 " let laststatus = &laststatus
164 140 let lastsearch = @/
@@ -167,27 +143,18 @@ function! tlib#input#ListW(world, ...) "{{{3
167 143 let @/ = ''
168 144 let dlist = []
169 145 " let &laststatus = 2
170   - let world.initial_display = 1
171 146
172 147 try
173 148 while !empty(world.state) && world.state !~ '^exit' && (world.show_empty || !empty(world.base))
174 149 " TLogDBG 'while'
175 150 " TLogVAR world.state
  151 + " let time01 = str2float(reltimestr(reltime())) " DBG
  152 + " TLogVAR time01, time01 - time0
176 153 try
177   - for handler in world.state_handlers
178   - let eh = get(handler, 'state', '')
179   - if !empty(eh) && world.state =~ eh
180   - let ea = get(handler, 'exec', '')
181   - if !empty(ea)
182   - exec ea
183   - else
184   - let agent = get(handler, 'agent', '')
185   - let world = call(agent, [world, world.GetSelectedItems(world.CurrentItem())])
186   - call s:CheckAgentReturnValue(agent, world)
187   - endif
188   - endif
189   - endfor
  154 + call s:RunStateHandlers(world)
190 155
  156 + " let time02 = str2float(reltimestr(reltime())) " DBG
  157 + " TLogVAR time02, time02 - time0
191 158 if world.state =~ '\<reset\>'
192 159 " TLogDBG 'reset'
193 160 " call world.Reset(world.state =~ '\<initial\>')
@@ -195,23 +162,21 @@ function! tlib#input#ListW(world, ...) "{{{3
195 162 continue
196 163 endif
197 164
198   - let llenw = len(world.base) - winheight(0) + 1
199   - if world.offset > llenw
200   - let world.offset = llenw
201   - endif
202   - if world.offset < 1
203   - let world.offset = 1
204   - endif
  165 + call s:SetOffset(world)
205 166
  167 + " let time02 = str2float(reltimestr(reltime())) " DBG
  168 + " TLogVAR time02, time02 - time0
206 169 " TLogDBG 1
207 170 " TLogVAR world.state
208 171 if world.state == 'scroll'
209 172 let world.prefidx = world.offset
210 173 let world.state = 'redisplay'
211 174 endif
  175 +
212 176 if world.state =~ '\<sticky\>'
213 177 let world.sticky = 1
214 178 endif
  179 +
215 180 " TLogVAR world.filter
216 181 " TLogVAR world.sticky
217 182 if world.state =~ '\<pick\>'
@@ -220,9 +185,15 @@ function! tlib#input#ListW(world, ...) "{{{3
220 185 throw 'pick'
221 186 elseif world.state =~ 'display'
222 187 if world.state =~ '^display'
  188 + " let time03 = str2float(reltimestr(reltime())) " DBG
  189 + " TLogVAR time03, time03 - time0
223 190 if world.IsValidFilter()
224 191
  192 + " let time1 = str2float(reltimestr(reltime())) " DBG
  193 + " TLogVAR time1, time1 - time0
225 194 call world.BuildTableList()
  195 + " let time2 = str2float(reltimestr(reltime())) " DBG
  196 + " TLogVAR time2, time2 - time0
226 197 " TLogDBG 2
227 198 " TLogDBG len(world.table)
228 199 " TLogVAR world.table
@@ -237,6 +208,8 @@ function! tlib#input#ListW(world, ...) "{{{3
237 208 let dindex = world.index_table
238 209 let world.index_width = len(max(dindex))
239 210 endif
  211 + " let time3 = str2float(reltimestr(reltime())) " DBG
  212 + " TLogVAR time3, time3 - time0
240 213 if world.llen == 0 && !world.show_empty
241 214 call world.ReduceFilter()
242 215 let world.offset = 1
@@ -255,6 +228,8 @@ function! tlib#input#ListW(world, ...) "{{{3
255 228 let world.last_item = ''
256 229 endif
257 230 endif
  231 + " let time4 = str2float(reltimestr(reltime())) " DBG
  232 + " TLogVAR time4, time4 - time0
258 233 " TLogDBG 4
259 234 " TLogVAR world.idx, world.llen, world.state
260 235 " TLogDBG world.FilterIsEmpty()
@@ -270,6 +245,8 @@ function! tlib#input#ListW(world, ...) "{{{3
270 245 let world.prefidx = 1
271 246 endif
272 247 endif
  248 + " let time5 = str2float(reltimestr(reltime())) " DBG
  249 + " TLogVAR time5, time5 - time0
273 250 " TLogVAR world.initial_index, world.prefidx
274 251 " TLogDBG 5
275 252 " TLogDBG len(world.list)
@@ -284,12 +261,18 @@ function! tlib#input#ListW(world, ...) "{{{3
284 261 endif
285 262 " TLogVAR world.prefidx
286 263 " TLogDBG 6
  264 + " let time6 = str2float(reltimestr(reltime())) " DBG
  265 + " TLogVAR time6, time6 - time0
287 266 if world.offset_horizontal > 0
288 267 call map(dlist, 'v:val[world.offset_horizontal:-1]')
289 268 endif
  269 + " let time7 = str2float(reltimestr(reltime())) " DBG
  270 + " TLogVAR time7, time7 - time0
290 271 " TLogVAR dindex
291 272 let dlist = map(range(0, world.llen - 1), 'printf("%0'. world.index_width .'d", dindex[v:val]) .": ". dlist[v:val]')
292 273 " TLogVAR dlist
  274 + " let time8 = str2float(reltimestr(reltime())) " DBG
  275 + " TLogVAR time8, time8 - time0
293 276
294 277 else
295 278
@@ -365,19 +348,26 @@ function! tlib#input#ListW(world, ...) "{{{3
365 348 let c = tlib#char#Get(world.timeout, world.timeout_resolution)
366 349 if world.state != ''
367 350 " continue
368   - elseif has_key(key_agents, c)
  351 + elseif has_key(world.key_map[world.key_mode], c)
369 352 let sr = @/
370 353 silent! let @/ = lastsearch
371   - " TLogVAR c, key_agents[c]
372   - " TLog "Agent: ". string(key_agents[c])
373   - let world = call(key_agents[c], [world, world.GetSelectedItems(world.CurrentItem())])
  354 + " TLogVAR c, world.key_map[world.key_mode][c]
  355 + " TLog "Agent: ". string(world.key_map[world.key_mode][c])
  356 + let handler = world.key_map[world.key_mode][c]
  357 + " TLogVAR handler
  358 + let world = call(handler.agent, [world, world.GetSelectedItems(world.CurrentItem())])
374 359 call s:CheckAgentReturnValue(c, world)
375 360 silent! let @/ = sr
376 361 " continue
377 362 elseif c == 13
378 363 throw 'pick'
379 364 elseif c == 27
380   - let world.state = 'exit empty'
  365 + if world.key_mode != 'default'
  366 + let world.key_mode = 'default'
  367 + let world.state = 'redisplay'
  368 + else
  369 + let world.state = 'exit empty'
  370 + endif
381 371 elseif c == "\<LeftMouse>"
382 372 let world.prefidx = world.GetLineIdx(v:mouse_lnum)
383 373 " let world.offset = world.prefidx
@@ -588,6 +578,7 @@ endf
588 578
589 579 function! s:Init(world, cmd) "{{{3
590 580 " TLogVAR a:cmd
  581 + let a:world.initial_display = 1
591 582 if a:cmd =~ '\<sticky\>'
592 583 let a:world.sticky = 1
593 584 endif
@@ -602,15 +593,97 @@ function! s:Init(world, cmd) "{{{3
602 593 endif
603 594 elseif !a:world.initialized
604 595 " TLogVAR a:world.initialized, a:world.win_wnr, a:world.bufnr
  596 + let a:world.filetype = &filetype
  597 + let a:world.fileencoding = &fileencoding
  598 + call a:world.SetMatchMode(tlib#var#Get('tlib_inputlist_match', 'wb'))
605 599 call a:world.Initialize()
  600 + let a:world.key_mode = 'default'
  601 + let a:world.key_map = {
  602 + \ a:world.key_mode : copy(g:tlib_keyagents_InputList_s)
  603 + \ }
  604 + if stridx(a:world.type, 'm') != -1
  605 + call extend(a:world.key_map[a:world.key_mode], g:tlib_keyagents_InputList_m, 'force')
  606 + endif
  607 + 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}')
  608 + if type(a:world.key_handlers) == 3
  609 + call s:ExtendKeyMap(a:world, a:world.key_mode, a:world.key_handlers)
  610 + elseif type(a:world.key_handlers) == 4
  611 + for [world_key_mode, world_key_handlers] in items(a:world.key_handlers)
  612 + call s:ExtendKeyMap(a:world, world_key_mode, world_key_handlers)
  613 + endfor
  614 + else
  615 + throw "tlib#input#ListW: key_handlers must be either a list or a dictionary"
  616 + endif
606 617 if !empty(a:cmd)
607 618 let a:world.state .= ' '. a:cmd
608 619 endif
609 620 endif
  621 + call s:BuildMenu(a:world)
610 622 " TLogVAR a:world.state, a:world.sticky
611 623 endf
612 624
613 625
  626 +function! s:ExtendKeyMap(world, key_mode, key_handlers) "{{{3
  627 + for handler in a:key_handlers
  628 + let k = get(handler, 'key', '')
  629 + if !empty(k)
  630 + let a:world.key_map[a:key_mode][k] = handler
  631 + endif
  632 + endfor
  633 +endf
  634 +
  635 +
  636 +function! s:BuildMenu(world) "{{{3
  637 + if g:tlib#input#use_popup
  638 + if a:world.has_menu
  639 + silent! aunmenu ]TLibInputListPopupMenu
  640 + endif
  641 + amenu ]TLibInputListPopupMenu.Pick\ selected\ item <cr>
  642 + amenu ]TLibInputListPopupMenu.Select #
  643 + amenu ]TLibInputListPopupMenu.Select\ all <c-a>
  644 + amenu ]TLibInputListPopupMenu.Reset\ list <c-r>
  645 + amenu ]TLibInputListPopupMenu.Cancel <esc>
  646 + amenu ]TLibInputListPopupMenu.-StandardEntries- :
  647 + for [key_mode, key_handlers] in items(a:world.key_map)
  648 + let keys = sort(keys(key_handlers))
  649 + for key in keys
  650 + let handler = key_handlers[key]
  651 + let k = get(handler, 'key', '')
  652 + if !empty(k) && has_key(handler, 'help') && !empty(handler.help)
  653 + if empty(key_mode) || key_mode == 'default'
  654 + exec 'amenu ]TLibInputListPopupMenu.'. escape(handler.help, ' .\')
  655 + \ .' '. handler.key_name
  656 + else
  657 + exec 'amenu ]TLibInputListPopupMenu'.
  658 + \ '.'. escape(key_mode, ' .\')
  659 + \ '.'. escape(handler.help, ' .\')
  660 + \ .' '. handler.key_name
  661 + endif
  662 + let a:world.has_menu = 1
  663 + endif
  664 + endfor
  665 + endfor
  666 + endif
  667 +endf
  668 +
  669 +
  670 +function! s:RunStateHandlers(world) "{{{3
  671 + for handler in a:world.state_handlers
  672 + let eh = get(handler, 'state', '')
  673 + if !empty(eh) && a:world.state =~ eh
  674 + let ea = get(handler, 'exec', '')
  675 + if !empty(ea)
  676 + exec ea
  677 + else
  678 + let agent = get(handler, 'agent', '')
  679 + let a:world = call(agent, [a:world, a:world.GetSelectedItems(a:world.CurrentItem())])
  680 + call s:CheckAgentReturnValue(agent, a:world)
  681 + endif
  682 + endif
  683 + endfor
  684 +endf
  685 +
  686 +
614 687 function! s:CheckAgentReturnValue(name, value) "{{{3
615 688 if type(a:value) != 4 && !has_key(a:value, 'state')
616 689 echoerr 'Malformed agent: '. a:name
@@ -619,6 +692,17 @@ function! s:CheckAgentReturnValue(name, value) "{{{3
619 692 endf
620 693
621 694
  695 +function! s:SetOffset(world) "{{{3
  696 + let llenw = len(a:world.base) - winheight(0) + 1
  697 + if a:world.offset > llenw
  698 + let a:world.offset = llenw
  699 + endif
  700 + if a:world.offset < 1
  701 + let a:world.offset = 1
  702 + endif
  703 +endf
  704 +
  705 +
622 706 " Functions related to tlib#input#EditList(type, ...) "{{{2
623 707
624 708 " :def: function! tlib#input#EditList(query, list, ?timeout=0)

0 comments on commit 422fa77

Please sign in to comment.
Something went wrong with that request. Please try again.