4 constructor: ({ @window, @commands, @modes, @esc }) ->
14 for { name } in @commands
15 @storage.commands[name] = {}
18 @storage.modes[name] = {}
20 enterMode: (mode, args...) ->
22 @modes[mode].enter(this, @storage.modes[mode], args...)
25 for name, mode of @modes
26 mode.onEnterNormalMode?(this, @storage.modes[name])
29 handleKeyDown: (event, keyStr) ->
31 if @mode == MODE_NORMAL or keyStr == @esc
34 if command = @findCommand(@keys)
35 command.func(this, @storage.commands[command.name])
36 return command.name != @esc
37 else if @maybeCommand(@keys)
41 else if not (event.ctrlKey or event.metaKey)
42 @modes[@mode].handleKeyDown(this, @storage.modes[@mode], event, keyStr)
48 handleKeyPress: (event) ->
49 return @lastKeyStr != @esc and @suppress
51 handleKeyUp: (event) ->
54 return @lastKeyStr != @esc and suppress
56 findCommand: (keys) ->
57 for i in [0...keys.length]
58 str = keys[i..].join(',')
59 for command in @commands
60 for key in command.keys()
61 if key == str and command.enabled()
64 maybeCommand: (keys) ->
65 for i in [0...keys.length]
66 str = keys[i..].join(',')
67 for command in @commands
68 for key in command.keys()
69 if key.indexOf(str) == 0 and command.enabled()
72 # What is minimally required for a command
74 constructor: (@keyValues, @name) ->
75 keys: -> return @keyValues
76 enabled: -> return true