       if (LinkHints.hintMarkerContainingDiv)
         DomUtils.removeElement LinkHints.hintMarkerContainingDiv
       LinkHints.hintMarkerContainingDiv = null
+      @isActive = false
       @hintMode.exit()
       @onExit?()
       @onExit = null
-      @isActive = false
-
-    # we invoke the deactivate() function directly instead of using setTimeout(callback, 0) so that
-    # deactivateMode can be tested synchronously
-    if (!delay)
+
+    if delay
+      Utils.setTimeout delay, ->
+        deactivate()
+        callback?()
+    else
+      # We invoke deactivate() directly (instead of setting a timeout of 0) so that deactivateMode() can be
+      # tested synchronously.
       deactivate()
-      callback() if (callback)
-    else
-      setTimeout(->
-        deactivate()
-        callback() if callback
-      delay)
+      callback?()
 
 alphabetHints =
   hintKeystrokeQueue: []

      name: "hint/#{mode.name}"
      indicator: false
      passInitialKeyupEvents: true
      keydown: @onKeyDownInMode.bind this, hintMarkers
      # Trap all other key events.
      keypress: -> false
      keyup: -> false

    @setOpenLinkMode mode



  matchHintsByKey: (hintMarkers, event) ->
    # If a shifted-character is typed, treat it as lowerase for the purposes of matching hints.
    keyChar = String.fromCharCode(event.charCode).toLowerCase()

    if (event.keyCode == keyCodes.backspace || event.keyCode == keyCodes.deleteKey)
      if (!@hintKeystrokeQueue.pop())
