   handleKeyChar: (keyChar) ->
     bgLog "handle key #{keyChar} (#{@name})"
     # A count prefix applies only so long a keyChar is mapped in @keyState[0]; e.g. 7gj should be 1j.
-    @countPrefix = 0 unless keyChar of @keyState[0]
-    # Advance the key state.  The new key state is the current mappings of keyChar, plus @keyMapping.
-    @keyState = [(mapping[keyChar] for mapping in @keyState when keyChar of mapping)..., @keyMapping]
+    unless keyChar of @keyState[0]
+      @countPrefix = 0
+    # Advance the key state. The new key state is the current mappings of keyChar, plus @keyMapping.
+    state = (mapping[keyChar] for mapping in @keyState when keyChar of mapping)
+    state.push(@keyMapping)
+    @keyState = state
+
     if @keyState[0].command?
       command = @keyState[0]
-      count = if 0 < @countPrefix then @countPrefix else 1
+      count = if @countPrefix > 0 then @countPrefix else 1
       bgLog "  invoke #{command.command} count=#{count} "
       @reset()
       @commandHandler {command, count}
-      @exit() if @options.count? and --@options.count <= 0
+      if @options.count? and --@options.count <= 0
+        @exit()
     @suppressEvent
 
 root = exports ? (window.root ?= {})

            @suppressEvent
          else
            @continueBubbling

  onKeydown: (event) ->
    keyChar = KeyboardUtils.getKeyCharString event

    if isEscape and (@countPrefix != 0 or @keyState.length != 1)
      DomUtils.consumeKeyup event, => @reset()
    # If the help dialog loses the focus, then Escape should hide it; see point 2 in #2045.
    else if isEscape and HelpDialog and HelpDialog.isShowing()
      HelpDialog.toggle()
      @suppressEvent
    else if isEscape
