diff options
| author | Stephen Blott | 2016-02-27 14:20:12 +0000 |
|---|---|---|
| committer | Stephen Blott | 2016-03-05 05:37:40 +0000 |
| commit | 34b1fb0f4e2ce1696c17e703d0bc43463355d6ba (patch) | |
| tree | 0bf5797129ae1f212154b56aff86be0830073a29 | |
| parent | 7c5fb2c312b9140c2dd091f792535ae8f592ecdb (diff) | |
| download | vimium-34b1fb0f4e2ce1696c17e703d0bc43463355d6ba.tar.bz2 | |
Key bindings; initial partially-functioning version.
| -rw-r--r-- | background_scripts/commands.coffee | 20 | ||||
| -rw-r--r-- | background_scripts/main.coffee | 1 | ||||
| -rw-r--r-- | content_scripts/mode_key_handler.coffee | 43 | ||||
| -rw-r--r-- | content_scripts/vimium_frontend.coffee | 28 |
4 files changed, 46 insertions, 46 deletions
diff --git a/background_scripts/commands.coffee b/background_scripts/commands.coffee index ab9992b3..a1002929 100644 --- a/background_scripts/commands.coffee +++ b/background_scripts/commands.coffee @@ -94,6 +94,25 @@ Commands = @keyToCommandRegistry = {} @mapKeyToCommand { key, command } for own key, command of defaultKeyMappings + # Keys are either literal characters, or "named" - for example <a-b> (alt+b), <left> (left arrow) or <f12> + # This regular expression captures two groups: the first is a named key, the second is the remainder of the + # string. + namedKeyRegex: /^(<(?:[amc]-.|(?:[amc]-)?[a-z0-9]{2,5})>)(.*)$/ + + generateKeyStateStructure: -> + keyMapping = {} + for own keys, registryEntry of @keyToCommandRegistry + currentMapping = keyMapping + while 0 < keys.length + [key, rest] = if 0 == keys.search @namedKeyRegex then [RegExp.$1, RegExp.$2] else [keys[0], keys.slice(1)] + if 0 < rest.length + currentMapping[key] ?= {} + currentMapping = currentMapping[key] + else + currentMapping[key] = registryEntry + keys = rest + chrome.storage.local.set normalModeKeyStateMapping: keyMapping + # An ordered listing of all available commands, grouped by type. This is the order they will # be shown in the help page. commandGroups: @@ -375,6 +394,7 @@ Commands.init() Settings.postUpdateHooks["keyMappings"] = (value) -> Commands.clearKeyMappingsAndSetDefaults() Commands.parseCustomKeyMappings value + Commands.generateKeyStateStructure() refreshCompletionKeysAfterMappingSave() root = exports ? window diff --git a/background_scripts/main.coffee b/background_scripts/main.coffee index 7c970866..1838eb95 100644 --- a/background_scripts/main.coffee +++ b/background_scripts/main.coffee @@ -629,6 +629,7 @@ Commands.clearKeyMappingsAndSetDefaults() if Settings.has("keyMappings") Commands.parseCustomKeyMappings(Settings.get("keyMappings")) +Commands.generateKeyStateStructure() populateValidFirstKeys() populateSingleKeyCommands() diff --git a/content_scripts/mode_key_handler.coffee b/content_scripts/mode_key_handler.coffee index c79f1991..6e04addb 100644 --- a/content_scripts/mode_key_handler.coffee +++ b/content_scripts/mode_key_handler.coffee @@ -1,11 +1,4 @@ -# The important data structure here is the "keyState". The key state is a non-empty list of objects, the keys -# of which are key names, and the values are other key-mapping objects or commands (strings). Key-mapping -# objects can be arbitrarily nested; so we support any length of multi-key mapping. -# -# Whenever we consume a key, we append a new copy of the global key mapping to the key state (hence, the -# global mappings are always available, and the key state is always non-empty). - class KeyHandlerMode extends Mode useCount: true countPrefix: 0 @@ -15,8 +8,6 @@ class KeyHandlerMode extends Mode constructor: (options) -> # A function accepting a command name and a count; required. @commandHandler = options.commandHandler ? (->) - # A Key mapping structure; required. - @keyMapping = options.keyMapping ? {} @useCount = false if options.noCount @reset() @@ -31,6 +22,8 @@ class KeyHandlerMode extends Mode blur: (event) => @alwaysContinueBubbling => @keydownEvents = {} if event.target == window + setKeyMapping: (@keyMapping) -> @reset() + onKeydown: (event) -> keyChar = KeyboardUtils.getKeyCharString event @@ -65,7 +58,7 @@ class KeyHandlerMode extends Mode keyChar = KeyboardUtils.getKeyCharString event if keyChar and @keyCharIsKeyStatePrefix keyChar @advanceKeyState keyChar - commands = @keyState.filter (entry) -> "string" == typeof entry + commands = @keyState.filter (entry) -> entry.command @invokeCommand commands[0] if 0 < commands.length false # Suppress event. else if keyChar and @isCountKey keyChar @@ -124,35 +117,5 @@ class KeyHandlerMode extends Mode getEventCode: (event) -> event.keyCode -# Demo/test code. -# A (very) poor-man's normal mode. - -demoKeyMapping = - j: "scrollDown" - k: "scrollUp" - i: "enterInsertMode" - g: - g: "scrollToTop" - a: "scrollToTop" - z: "scrollToBottom" - i: "focusInput" - # A three-key binding. - a: - b: - c: "enterInsertMode" - # And this should override "j" on its own. - j: "enterInsertMode" - -demoCommandHandler = (command, count) -> - switch command - when "scrollDown" then scrollDown() - when "scrollUp" then scrollUp() - when "scrollToTop" then scrollToTop count - when "scrollToBottom" then scrollToBottom() - when "enterInsertMode" then enterInsertMode() - when "focusInput" then focusInput count - root = exports ? window root.KeyHandlerMode = KeyHandlerMode -root.demoKeyMapping = demoKeyMapping -root.demoCommandHandler = demoCommandHandler diff --git a/content_scripts/vimium_frontend.coffee b/content_scripts/vimium_frontend.coffee index bce5f632..b46175fb 100644 --- a/content_scripts/vimium_frontend.coffee +++ b/content_scripts/vimium_frontend.coffee @@ -101,19 +101,35 @@ handlerStack.push # Only exported for tests. window.initializeModes = -> - class NormalMode extends Mode + class NormalMode extends KeyHandlerMode constructor: -> super name: "normal" indicator: false # There is no mode indicator in normal mode. - keydown: (event) => onKeydown.call @, event - keypress: (event) => onKeypress.call @, event - keyup: (event) => onKeyup.call @, event + commandHandler: @commandHandler.bind this + keyMapping: {} + + chrome.storage.local.get "normalModeKeyStateMapping", (items) => + @setKeyMapping items.normalModeKeyStateMapping + + chrome.storage.onChanged.addListener (changes, area) => + if area == "local" and changes.normalModeKeyStateMapping?.newValue + @setKeyMapping changes.normalModeKeyStateMapping.newValue + + commandHandler: (registryEntry, count) -> + # TODO: Special handling of Vomnibar. + if registryEntry.isBackgroundCommand + true # Not yet implemnted. + else + count = 1 if registryEntry.noRepeat + if registryEntry.passCountToFunction + Utils.invokeCommandString registryEntry.command, [count] + else + Utils.invokeCommandString registryEntry.command for i in [0...count] # Install the permanent modes. The permanently-installed insert mode tracks focus/blur events, and # activates/deactivates itself accordingly. - # new NormalMode - new KeyHandlerMode commandHandler: demoCommandHandler, keyMapping: demoKeyMapping, indicator: "Demo mode." + new NormalMode new PassKeysMode new InsertMode permanent: true Scroller.init() |
