       # simulate the text input event that was previously prevented to insert
       # the missing characters.
       @simulateTextInput(event) if event.defaultPrevented and event.type is 'keydown'
-      queuedKeystrokes = null
-
-    {keystroke, dispatchedBinding, exactMatch, partialMatches, queuedKeystrokes}
-
+
+    if hasPartialMatches and shouldUsePartialMatches
+      event.preventDefault()
+
+      enableTimeout = (
+        @pendingStateTimeoutHandle? or
+        dispatchedExactMatch? or
+        characterForKeyboardEvent(@queuedKeyboardEvents[0])?
+      )
+      enableTimeout = false if replay
+      @enterPendingState(partialMatches, enableTimeout)
+
+      @emitter.emit 'did-partially-match-binding', {
+        keystrokes,
+        eventType: event.type,
+        partiallyMatchedBindings: partialMatches,
+        keyboardEventTarget: target
+      }
+    else if not dispatchedExactMatch? and not hasPartialMatches and @pendingPartialMatches?
+      # There are partial matches from a previous event, but none from this
+      # event. This means the current event has removed any hope that the queued
+      # key events will ever match anything. So we will clear the state and
+      # start over after replaying the events in `terminatePendingState`.
+      @terminatePendingState()
+    else
+      @clearQueuedKeystrokes()
 
   # Public: Translate a keydown event to a keystroke string.
   #

        exactMatches = @findExactMatches(exactMatchCandidates, currentTarget)
        for exactMatchCandidate in exactMatches
          if exactMatchCandidate.command is 'native!'
            return {keystroke, queuedKeystrokes: null}

          if exactMatchCandidate.command is 'abort!'
            event.preventDefault()
            return {keystroke, queuedKeystrokes: null}

          if exactMatchCandidate.command is 'unset!'
            break

          exactMatch = exactMatchCandidate
          if partialMatches.length > 0
            # When there is a set of bindings like `'ctrl-y', 'ctrl-y ^ctrl'`,
            # and a `ctrl-y` comes in, this will allow the `ctrl-y` command to be
            # dispatched without waiting for any other keystrokes

              binding: exactMatchCandidate,
              keyboardEventTarget: target
            }
            dispatchedExactMatch = exactMatchCandidate
            eventHandled = true # Kicks it out of the parent loop
            break
        currentTarget = currentTarget.parentElement

    @bindingsToDisable.push(dispatchedExactMatch) if dispatchedExactMatch

    if not dispatchedExactMatch? and not hasPartialMatches
      @emitter.emit 'did-fail-to-match-binding', {
        keystrokes,
        eventType: event.type,
