Command map allows for ambiguous key pattern prefix matches.

If we have pattern 'da' and 'dad' both mapped, when 'da' is typed, the KeyMap waits for a given timeout for another character to be entered. If the time elapses, it goes ahead and executes the action for 'da'. But if a 'd' is subsequently entered, it executes 'dad'.
This commit is contained in:
Nathan Sobo
2012-01-06 18:05:45 -08:00
committed by Corey Johnson & Nathan Sobo
parent d0ff3c7d4a
commit 3a1d167a0f
2 changed files with 99 additions and 27 deletions

View File

@@ -20,6 +20,8 @@ class CommandMap
';': 186, '\'': 222,
'[': 219, ']': 221, '\\': 220
inputTimeout: 200
constructor: (@delegate) ->
@mappings = {}
@bufferedEvents = []
@@ -28,11 +30,24 @@ class CommandMap
@mappings[pattern] = action
handleKeyEvent: (event) ->
window.clearTimeout(@inputTimeoutHandle) if @inputTimeoutHandle
@bufferedEvents.push(event)
candidatePatterns =
(pattern for pattern of @mappings when @keyEventsMatchPatternPrefix(@bufferedEvents, pattern))
if candidatePatterns.length > 1
@inputTimeoutHandle = _.delay (=> @triggerActionForBufferedKeyEvents()), @inputTimeout
else if candidatePatterns.length == 1
@triggerActionForBufferedKeyEvents()
else
@clearBufferedEvents()
triggerActionForBufferedKeyEvents: ->
for pattern, action of @mappings
if @keyEventsMatchPattern(@bufferedEvents, pattern)
@delegate[action](event)
@clearBufferedEvents()
keyEventsMatchPattern: (events, pattern) ->
patternKeys = @parseKeyPattern(pattern)
@@ -40,6 +55,12 @@ class CommandMap
_.all(_.zip(events, patternKeys), ([event, pattern]) ->
event.which == pattern.which)
keyEventsMatchPatternPrefix: (events, pattern) ->
patternKeys = @parseKeyPattern(pattern)
return false if events.length > patternKeys.length
_.all(_.zip(events, patternKeys[0...events.length]), ([event, pattern]) ->
event.which == pattern.which)
parseKeyPattern: (pattern) ->
for char in pattern
{ which: char.toUpperCase().charCodeAt(0) }