From c6a4080de9e6b942fe7e982d0ac0351caa909627 Mon Sep 17 00:00:00 2001 From: Jacek Kopecky Date: Sun, 19 Jul 2015 00:45:40 +0100 Subject: [PATCH] beep on unrecognized commands to warn the user --- lib/utils.coffee | 8 ++++++++ lib/vim-state.coffee | 6 ++++++ spec/vim-state-spec.coffee | 41 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 55 insertions(+) diff --git a/lib/utils.coffee b/lib/utils.coffee index 5a26310a..59431727 100644 --- a/lib/utils.coffee +++ b/lib/utils.coffee @@ -1,5 +1,8 @@ {Range} = require 'atom' +# copied from atom/atom-keymap src/helpers.coffee +AtomModifierRegex = /(ctrl|alt|shift|cmd)$/ + module.exports = # Public: Determines if a string should be considered linewise or character # @@ -25,3 +28,8 @@ module.exports = newRange else oldRange.union(newRange) + + # copied and simplified from atom/atom-keymap src/helpers.coffee + # see atom/atom-keymap#97 + isAtomModifier: (keystroke) -> + AtomModifierRegex.test(keystroke) diff --git a/lib/vim-state.coffee b/lib/vim-state.coffee index db59ee51..61953ed5 100644 --- a/lib/vim-state.coffee +++ b/lib/vim-state.coffee @@ -44,6 +44,12 @@ class VimState else @activateNormalMode() + @subscriptions.add atom.keymaps.onDidFailToMatchBinding (e) => + return unless e.keyboardEventTarget is @editorElement + return if Utils.isAtomModifier(e.keystrokes) + if e.keystrokes.indexOf(' ') < 0 and @mode isnt "insert" + atom.beep() + destroy: -> unless @destroyed @destroyed = true diff --git a/spec/vim-state-spec.coffee b/spec/vim-state-spec.coffee index 8fd3fb01..50eb9c49 100644 --- a/spec/vim-state-spec.coffee +++ b/spec/vim-state-spec.coffee @@ -517,3 +517,44 @@ describe "VimState", -> keydown('`') normalModeInputKeydown('q') expect(editor.getCursorScreenPosition()).toEqual [1, 2] + + describe "unknown key bindings", -> + beforeEach -> + editor.setText "line one\n line two\n" + editor.setCursorBufferPosition [0, 0] + + describe "in operator-pending mode", -> + beforeEach -> + keydown 'c' + + it "beeps on unrecognized keybinding, ignores them", -> + keydown 'q' #cq doesn't work, q not implemented so will beep + expect(atom.beep).toHaveBeenCalled() + keydown 'w' + expect(editor.getCursorBufferPosition()).toEqual [0, 0] + expect(editor.getText()).toBe " one\n line two\n" + expect(vimState.mode).toEqual 'insert' + + it "replays long pending operations and beeps on short unrecognized keybinding", -> + keydown 'i' + keydown '3' # i3 is unrecognized, replays 'i' and beeps, replays '3' which is recognized + # FIXME for some reason, the replay of 'i' in specs doesn't go to the editor so the beep doesn't happen + # expect(atom.beep).toHaveBeenCalled() + keydown 'w' + expect(editor.getCursorBufferPosition()).toEqual [0, 0] + expect(editor.getText()).toBe "two\n" + expect(vimState.mode).toEqual 'insert' + + describe "in visual mode", -> + beforeEach -> + keydown 'v' + + it "cancels whole unrecognized keybinding", -> + keydown 'i' + keydown '3' # i3 is unrecognized, replays 'i' and beeps, replays '3' which is recognized + # FIXME for some reason, the replay of 'i' in specs doesn't go to the editor so the beep doesn't happen + # expect(atom.beep).toHaveBeenCalled() + keydown 'w' + expect(editor.getCursorBufferPosition()).toEqual [1, 7] + expect(editor.getSelectedText()).toBe "line one\n line t" + expect(vimState.mode).toEqual 'visual'