]> git.gir.st - VimFx.git/blob - extension/packages/vim.coffee
Slight `Vim::handleKeyDown` refactor
[VimFx.git] / extension / packages / vim.coffee
1 MODE_NORMAL = {}
2
3 class Vim
4 constructor: ({ @window, @commands, @modes, @esc }) ->
5 @mode = MODE_NORMAL
6 @keys = []
7 @lastKeyStr = null
8 @suppress = false
9
10 @storage =
11 commands: {}
12 modes: {}
13
14 for { name } in @commands
15 @storage.commands[name] = {}
16
17 for name of @modes
18 @storage.modes[name] = {}
19
20 enterMode: (mode, args) ->
21 # Note: `args` is an array of arguments to be passed to the mode's `enter` method. We cannot use
22 # `args...`, since that destroys the `this` context for the mode's `enter` method.
23 @mode = mode
24 @modes[mode].enter(this, @storage.modes[mode], args)
25
26 enterNormalMode: ->
27 for name, mode of @modes
28 mode.onEnterNormalMode?(this, @storage.modes[name])
29 @mode = MODE_NORMAL
30
31 handleKeyDown: (event, @lastKeyStr) ->
32 @suppress = true
33 @keys.push(@lastKeyStr)
34 if @mode == MODE_NORMAL or @lastKeyStr == @esc
35 { match, exact, command, index } = @searchForCommand(@keys, @commands)
36 if match
37 @keys = @keys[index..]
38 command.func(this, @storage.commands[command.name]) if exact
39 return @lastKeyStr != @esc
40 else
41 ok = @modes[@mode].handleKeyDown(this, @storage.modes[@mode], event)
42 return true if ok
43
44 @suppress = false
45 @keys.length = 0
46 return false
47
48 handleKeyPress: (event) ->
49 return @lastKeyStr != @esc and @suppress
50
51 handleKeyUp: (event) ->
52 suppress = @suppress
53 @suppress = false
54 return @lastKeyStr != @esc and suppress
55
56 # Intentionally taking `keys` and `commands` as parameters (instead of simply using `@keys` and
57 # `@commands`), so that the method can be reused by custom modes.
58 searchForCommand: (keys, commands) ->
59 for index in [0...keys.length] by 1
60 str = keys[index..].join(',')
61 for command in commands
62 for key in command.keys()
63 if key.startsWith(str) and command.enabled()
64 return {match: true, exact: (key == str), command, index}
65 return {match: false}
66
67 # What is minimally required for a command
68 class Vim.Command
69 constructor: (@keyValues, @name) ->
70 keys: -> return @keyValues
71 enabled: -> return true
72
73 exports.Vim = Vim
Imprint / Impressum