From 49c82df9e56c9f37bab1e0ee68094f3c3280fdd4 Mon Sep 17 00:00:00 2001 From: Simon Lydell Date: Tue, 1 Oct 2013 13:35:13 +0200 Subject: [PATCH] Make command_Esc in charge of all "escaping" To be able to exit modes or blur text inputs, you _had_ to use Esc before. It was hard coded. Now, changing the shortcut for command_Esc works as expected. --- extension/packages/commands.coffee | 4 +++- extension/packages/events.coffee | 22 +++++++++---------- extension/packages/vim.coffee | 34 +++++++++++++++++++----------- 3 files changed, 35 insertions(+), 25 deletions(-) diff --git a/extension/packages/commands.coffee b/extension/packages/commands.coffee index 1566c48..3b8d609 100644 --- a/extension/packages/commands.coffee +++ b/extension/packages/commands.coffee @@ -364,8 +364,10 @@ commands = [ new Command('misc', 'find_prev', command_find_prev, ['N']) new Command('misc', 'insert_mode', command_insert_mode, ['i']) new Command('misc', 'help', command_help, ['?']) + escapeCommand = new Command('misc', 'Esc', command_Esc, ['Esc']) new Command('misc', 'dev', command_dev, [':']) ] -exports.commands = commands +exports.commands = commands +exports.escapeCommand = escapeCommand diff --git a/extension/packages/events.coffee b/extension/packages/events.coffee index 57dc613..6f7989c 100644 --- a/extension/packages/events.coffee +++ b/extension/packages/events.coffee @@ -4,7 +4,8 @@ keyUtils = require 'key-utils' { getPref } = require 'prefs' { updateToolbarButton } = require 'button' { unload } = require 'unload' -{ commands } = require 'commands' +{ commands +, escapeCommand } = require 'commands' { modes } = require 'modes' { interfaces: Ci } = Components @@ -16,8 +17,7 @@ keyUtils = require 'key-utils' # google causes its search bar to be focused. NEVER_SUPPRESS_IN_NORMAL_MODE = ['Esc'] -# TODO: Should 'Esc' be configurable? -newFunc = (window) -> new Vim({window, commands, modes, esc: 'Esc'}) +newFunc = (window) -> new Vim({window, commands, modes, escapeCommand}) vimBucket = new utils.Bucket(utils.getWindowId, newFunc) keyStrFromEvent = (event) -> @@ -52,17 +52,15 @@ keyListener = (event) -> return unless keyStr = keyStrFromEvent(event) + # This check must be done before `vim.onInput()` below, since that call might change the mode. + # We are interested in the mode at the beginning of the events, not whatever it might be + # afterwards. + suppressException = (vim.mode == Vim.MODE_NORMAL and keyStr in NEVER_SUPPRESS_IN_NORMAL_MODE) isEditable = utils.isElementEditable(event.originalTarget) - unless isEditable and keyStr != vim.esc - # This check must be done before `vim.onInput()` below, since that call might change the - # mode. We are interested in the mode at the beginning of the events, not whatever it might - # be afterwards. - suppressException = (vim.mode == Vim.MODE_NORMAL and keyStr in NEVER_SUPPRESS_IN_NORMAL_MODE) - - suppress = vim.onInput(keyStr, event) - if suppressException - suppress = false + suppress = vim.onInput(keyStr, event, {autoInsertMode: isEditable}) + if suppressException + suppress = false if suppress event.preventDefault() diff --git a/extension/packages/vim.coffee b/extension/packages/vim.coffee index b5fa18b..0f0afc9 100644 --- a/extension/packages/vim.coffee +++ b/extension/packages/vim.coffee @@ -1,7 +1,7 @@ MODE_NORMAL = {} class Vim - constructor: ({ @window, @commands, @modes, @esc }) -> + constructor: ({ @window, @commands, @modes, @escapeCommand }) -> @mode = MODE_NORMAL @keys = [] @@ -16,8 +16,7 @@ class Vim @storage.modes[name] = {} enterMode: (mode, args) -> - # Note: `args` is an array of arguments to be passed to the mode's `onEnter` method. We cannot - # use `args...`, since that destroys the `this` context for the mode's `onEnter` method. + # `args` is an array of arguments to be passed to the mode's `onEnter` method @mode = mode @modes[mode].onEnter?(this, @storage.modes[mode], args) @@ -27,39 +26,50 @@ class Vim @mode = MODE_NORMAL @keys.length = 0 - onInput: (keyStr, event) -> + onInput: (keyStr, event, options = {}) -> @keys.push(keyStr) + esc = @searchForMatchingCommand([@escapeCommand]).exact + + if options.autoInsertMode and not esc + return false + if @mode == MODE_NORMAL - { match, exact, command } = @searchForCommand(@commands) + if esc + return @runCommand(@escapeCommand, event) + + { match, exact, command, index } = @searchForMatchingCommand(@commands) if match - if exact then command.func(this, @storage.commands[command.name], event) + @keys = @keys[index..] + if exact then @runCommand(command, event) return true else + @keys.length = 0 return false else - if keyStr == @esc + if esc @enterNormalMode() return true else return @modes[@mode].onInput?(this, @storage.modes[@mode], keyStr, event) # Intentionally taking `commands` as a parameter (instead of simply using `@commands`), so that - # the method can be reused by custom modes. - searchForCommand: (commands) -> + # the method can be reused by custom modes (and by escape handling). + searchForMatchingCommand: (commands) -> for index in [0...@keys.length] by 1 str = @keys[index..].join(',') for command in commands for key in command.keys() if key.startsWith(str) and command.enabled() - @keys = @keys[index..] - return {match: true, exact: (key == str), command} + return {match: true, exact: (key == str), command, index} - @keys.length = 0 return {match: false} + runCommand: (command, event) -> + command.func(this, @storage.commands[command.name], event) + Vim.MODE_NORMAL = MODE_NORMAL # What is minimally required for a command -- 2.39.3