diff --git a/src/main/kotlin/com/chylex/intellij/keyboardmaster/feature/vimNavigation/ComponentHolder.kt b/src/main/kotlin/com/chylex/intellij/keyboardmaster/feature/vimNavigation/ComponentHolder.kt
index ae6e084..0d38dd6 100644
--- a/src/main/kotlin/com/chylex/intellij/keyboardmaster/feature/vimNavigation/ComponentHolder.kt
+++ b/src/main/kotlin/com/chylex/intellij/keyboardmaster/feature/vimNavigation/ComponentHolder.kt
@@ -1,7 +1,11 @@
 package com.chylex.intellij.keyboardmaster.feature.vimNavigation
 
+import com.intellij.ui.popup.WizardPopup
 import javax.swing.JComponent
 
 internal interface ComponentHolder {
 	val component: JComponent
+	
+	val popup: WizardPopup?
+		get() = null
 }
diff --git a/src/main/kotlin/com/chylex/intellij/keyboardmaster/feature/vimNavigation/KeyStrokeNode.kt b/src/main/kotlin/com/chylex/intellij/keyboardmaster/feature/vimNavigation/KeyStrokeNode.kt
index 779d569..804815f 100644
--- a/src/main/kotlin/com/chylex/intellij/keyboardmaster/feature/vimNavigation/KeyStrokeNode.kt
+++ b/src/main/kotlin/com/chylex/intellij/keyboardmaster/feature/vimNavigation/KeyStrokeNode.kt
@@ -23,10 +23,10 @@ internal interface KeyStrokeNode<T> {
 		}
 		
 		fun getChild(keyEvent: KeyEvent): KeyStrokeNode<T> {
-			val keyStroke = when (keyEvent.id) {
-				KeyEvent.KEY_TYPED   -> KeyStroke.getKeyStroke(keyEvent.keyChar, keyEvent.modifiersEx and KeyEvent.SHIFT_DOWN_MASK.inv())
-				KeyEvent.KEY_PRESSED -> KeyStroke.getKeyStroke(keyEvent.keyCode, keyEvent.modifiersEx, false)
-				else                 -> return this
+			val keyStroke = when {
+				keyEvent.keyChar != KeyEvent.CHAR_UNDEFINED -> KeyStroke.getKeyStroke(keyEvent.keyChar, keyEvent.modifiersEx and KeyEvent.SHIFT_DOWN_MASK.inv())
+				keyEvent.id == KeyEvent.KEY_PRESSED         -> KeyStroke.getKeyStroke(keyEvent.keyCode, keyEvent.modifiersEx, false)
+				else                                        -> return this
 			}
 			
 			return keys[keyStroke] ?: this
@@ -71,7 +71,7 @@ internal interface KeyStrokeNode<T> {
 	}
 	
 	companion object {
-		fun <T> getAllShortcuts(root: Parent<T>, extra: Set<KeyStroke>? = null): CustomShortcutSet {
+		fun <T> getAllKeyStrokes(root: Parent<T>, extra: Set<KeyStroke>? = null): Set<KeyStroke> {
 			val allKeyStrokes = HashSet(root.allKeyStrokes)
 			
 			if (extra != null) {
@@ -82,7 +82,11 @@ internal interface KeyStrokeNode<T> {
 				allKeyStrokes.add(KeyStroke.getKeyStroke(c))
 			}
 			
-			return CustomShortcutSet(*allKeyStrokes.map2Array { KeyboardShortcut(it, null) })
+			return allKeyStrokes
+		}
+		
+		fun getAllShortcuts(keyStrokes: Set<KeyStroke>): CustomShortcutSet {
+			return CustomShortcutSet(*keyStrokes.map2Array { KeyboardShortcut(it, null) })
 		}
 	}
 }
diff --git a/src/main/kotlin/com/chylex/intellij/keyboardmaster/feature/vimNavigation/PopupInterceptor.kt b/src/main/kotlin/com/chylex/intellij/keyboardmaster/feature/vimNavigation/PopupInterceptor.kt
new file mode 100644
index 0000000..cd2ad22
--- /dev/null
+++ b/src/main/kotlin/com/chylex/intellij/keyboardmaster/feature/vimNavigation/PopupInterceptor.kt
@@ -0,0 +1,19 @@
+package com.chylex.intellij.keyboardmaster.feature.vimNavigation
+
+import com.chylex.intellij.keyboardmaster.feature.vimNavigation.components.VimListNavigation
+import com.intellij.ui.UiInterceptors.PersistentUiInterceptor
+import com.intellij.ui.awt.RelativePoint
+import com.intellij.ui.popup.AbstractPopup
+import com.intellij.ui.popup.list.ListPopupImpl
+
+internal object PopupInterceptor : PersistentUiInterceptor<AbstractPopup>(AbstractPopup::class.java) {
+	override fun shouldIntercept(component: AbstractPopup): Boolean {
+		if (component is ListPopupImpl) {
+			VimListNavigation.install(component.list, component)
+		}
+		
+		return false
+	}
+	
+	override fun doIntercept(component: AbstractPopup, owner: RelativePoint?) {}
+}
diff --git a/src/main/kotlin/com/chylex/intellij/keyboardmaster/feature/vimNavigation/VimNavigation.kt b/src/main/kotlin/com/chylex/intellij/keyboardmaster/feature/vimNavigation/VimNavigation.kt
index 0285869..957cbf2 100644
--- a/src/main/kotlin/com/chylex/intellij/keyboardmaster/feature/vimNavigation/VimNavigation.kt
+++ b/src/main/kotlin/com/chylex/intellij/keyboardmaster/feature/vimNavigation/VimNavigation.kt
@@ -5,6 +5,7 @@ import com.chylex.intellij.keyboardmaster.feature.vimNavigation.components.VimLi
 import com.chylex.intellij.keyboardmaster.feature.vimNavigation.components.VimTableNavigation
 import com.chylex.intellij.keyboardmaster.feature.vimNavigation.components.VimTreeNavigation
 import com.intellij.openapi.application.ApplicationManager
+import com.intellij.ui.UiInterceptors
 import com.intellij.util.ui.StartupUiUtil
 import java.awt.AWTEvent
 import java.awt.event.FocusEvent
@@ -17,7 +18,10 @@ object VimNavigation {
 	var isEnabled = false
 	
 	fun register() {
-		StartupUiUtil.addAwtListener(::handleEvent, AWTEvent.FOCUS_EVENT_MASK, ApplicationManager.getApplication().getService(PluginDisposableService::class.java))
+		val disposable = ApplicationManager.getApplication().getService(PluginDisposableService::class.java)
+		
+		StartupUiUtil.addAwtListener(::handleEvent, AWTEvent.FOCUS_EVENT_MASK, disposable)
+		UiInterceptors.registerPersistent(disposable, PopupInterceptor)
 	}
 	
 	private fun handleEvent(event: AWTEvent) {
diff --git a/src/main/kotlin/com/chylex/intellij/keyboardmaster/feature/vimNavigation/VimNavigationDispatcher.kt b/src/main/kotlin/com/chylex/intellij/keyboardmaster/feature/vimNavigation/VimNavigationDispatcher.kt
index c996695..f3f11a0 100644
--- a/src/main/kotlin/com/chylex/intellij/keyboardmaster/feature/vimNavigation/VimNavigationDispatcher.kt
+++ b/src/main/kotlin/com/chylex/intellij/keyboardmaster/feature/vimNavigation/VimNavigationDispatcher.kt
@@ -17,7 +17,7 @@ import java.util.concurrent.atomic.AtomicBoolean
 import javax.swing.JComponent
 import javax.swing.KeyStroke
 
-internal class VimNavigationDispatcher<T : JComponent>(override val component: T, private val rootNode: KeyStrokeNode.Parent<VimNavigationDispatcher<T>>) : DumbAwareAction(), ComponentHolder {
+internal open class VimNavigationDispatcher<T : JComponent>(final override val component: T, private val rootNode: KeyStrokeNode.Parent<VimNavigationDispatcher<T>>) : DumbAwareAction(), ComponentHolder {
 	companion object {
 		private val DISPOSABLE = ApplicationManager.getApplication().getService(PluginDisposableService::class.java)
 		private val EXTRA_SHORTCUTS = setOf(
@@ -35,16 +35,21 @@ internal class VimNavigationDispatcher<T : JComponent>(override val component: T
 	var isSearching = AtomicBoolean(false)
 	
 	init {
-		registerCustomShortcutSet(KeyStrokeNode.getAllShortcuts(rootNode, EXTRA_SHORTCUTS), component, DISPOSABLE)
+		registerCustomShortcutSet(KeyStrokeNode.getAllShortcuts(getAllKeyStrokes()), component, DISPOSABLE)
 		
-		SpeedSearchSupply.getSupply(component, true)?.addChangeListener {
-			if (it.propertyName == SpeedSearchSupply.ENTERED_PREFIX_PROPERTY_NAME && it.oldValue != null && it.newValue == null) {
+		val speedSearch = SpeedSearchSupply.getSupply(component, true)
+		speedSearch?.addChangeListener {
+			if (it.propertyName == SpeedSearchSupply.ENTERED_PREFIX_PROPERTY_NAME && !speedSearch.isPopupActive) {
 				isSearching.set(false)
 			}
 		}
 	}
 	
-	override fun actionPerformed(e: AnActionEvent) {
+	protected fun getAllKeyStrokes(): Set<KeyStroke> {
+		return KeyStrokeNode.getAllKeyStrokes(rootNode, EXTRA_SHORTCUTS)
+	}
+	
+	final override fun actionPerformed(e: AnActionEvent) {
 		val keyEvent = e.inputEvent as? KeyEvent ?: return
 		
 		if (keyEvent.id == KeyEvent.KEY_PRESSED && handleSpecialKeyPress(keyEvent, e.dataContext)) {
@@ -89,11 +94,11 @@ internal class VimNavigationDispatcher<T : JComponent>(override val component: T
 		}
 	}
 	
-	override fun update(e: AnActionEvent) {
+	final override fun update(e: AnActionEvent) {
 		e.presentation.isEnabled = !isSearching.get() || e.inputEvent.let { it is KeyEvent && it.id == KeyEvent.KEY_PRESSED && it.keyCode == KeyEvent.VK_ENTER }
 	}
 	
-	override fun getActionUpdateThread(): ActionUpdateThread {
+	final override fun getActionUpdateThread(): ActionUpdateThread {
 		return ActionUpdateThread.BGT
 	}
 }
diff --git a/src/main/kotlin/com/chylex/intellij/keyboardmaster/feature/vimNavigation/components/VimCommonNavigation.kt b/src/main/kotlin/com/chylex/intellij/keyboardmaster/feature/vimNavigation/components/VimCommonNavigation.kt
index 2c25481..cb4feb5 100644
--- a/src/main/kotlin/com/chylex/intellij/keyboardmaster/feature/vimNavigation/components/VimCommonNavigation.kt
+++ b/src/main/kotlin/com/chylex/intellij/keyboardmaster/feature/vimNavigation/components/VimCommonNavigation.kt
@@ -23,7 +23,7 @@ internal object VimCommonNavigation {
 			KeyStroke.getKeyStroke('m') to IdeaAction("ShowPopupMenu"),
 			KeyStroke.getKeyStroke('r') to IdeaAction("SynchronizeCurrentFile"),
 			KeyStroke.getKeyStroke('R') to IdeaAction("Synchronize"),
-			KeyStroke.getKeyStroke('q') to CloseParentToolWindow(),
+			KeyStroke.getKeyStroke('q') to CloseParentPopupOrToolWindow(),
 			KeyStroke.getKeyStroke('/') to StartSearch(),
 		)
 	)
@@ -40,8 +40,14 @@ internal object VimCommonNavigation {
 		}
 	}
 	
-	private class CloseParentToolWindow<T : JComponent> : ActionNode<VimNavigationDispatcher<T>> {
+	private class CloseParentPopupOrToolWindow<T : JComponent> : ActionNode<VimNavigationDispatcher<T>> {
 		override fun performAction(holder: VimNavigationDispatcher<T>, actionEvent: AnActionEvent, keyEvent: KeyEvent) {
+			val popup = holder.popup
+			if (popup != null) {
+				popup.cancel()
+				return
+			}
+			
 			val project = actionEvent.project ?: return
 			val toolWindowId = holder.component.getParentToolWindowId() ?: return
 			ToolWindowManagerEx.getInstanceEx(project).hideToolWindow(toolWindowId, true)
diff --git a/src/main/kotlin/com/chylex/intellij/keyboardmaster/feature/vimNavigation/components/VimListNavigation.kt b/src/main/kotlin/com/chylex/intellij/keyboardmaster/feature/vimNavigation/components/VimListNavigation.kt
index 07e3e96..ab3d63d 100644
--- a/src/main/kotlin/com/chylex/intellij/keyboardmaster/feature/vimNavigation/components/VimListNavigation.kt
+++ b/src/main/kotlin/com/chylex/intellij/keyboardmaster/feature/vimNavigation/components/VimListNavigation.kt
@@ -3,9 +3,16 @@ package com.chylex.intellij.keyboardmaster.feature.vimNavigation.components
 import com.chylex.intellij.keyboardmaster.feature.vimNavigation.KeyStrokeNode.IdeaAction
 import com.chylex.intellij.keyboardmaster.feature.vimNavigation.KeyStrokeNode.Parent
 import com.chylex.intellij.keyboardmaster.feature.vimNavigation.VimNavigationDispatcher
+import com.intellij.openapi.application.ApplicationManager
 import com.intellij.openapi.ui.getUserData
 import com.intellij.openapi.ui.putUserData
 import com.intellij.openapi.util.Key
+import com.intellij.ui.popup.WizardPopup
+import com.intellij.ui.speedSearch.SpeedSearch
+import com.intellij.ui.speedSearch.SpeedSearchSupply
+import java.awt.event.ActionEvent
+import java.awt.event.KeyEvent
+import javax.swing.AbstractAction
 import javax.swing.JList
 import javax.swing.KeyStroke
 
@@ -28,8 +35,53 @@ internal object VimListNavigation {
 	)
 	
 	fun install(component: JList<*>) {
-		if (component.getUserData(KEY) == null) {
+		if (component.getUserData(KEY) == null && component.javaClass.enclosingClass.let { it == null || !WizardPopup::class.java.isAssignableFrom(it) }) {
 			component.putUserData(KEY, VimNavigationDispatcher(component, ROOT_NODE))
 		}
 	}
+	
+	fun install(component: JList<*>, popup: WizardPopup) {
+		if (component.getUserData(KEY) == null) {
+			component.putUserData(KEY, VimPopupListNavigationDispatcher(component, popup))
+		}
+	}
+	
+	@Suppress("serial")
+	private class VimPopupListNavigationDispatcher(component: JList<*>, override val popup: WizardPopup) : VimNavigationDispatcher<JList<*>>(component, ROOT_NODE) {
+		init {
+			val speedSearch = SpeedSearchSupply.getSupply(component, true) as? SpeedSearch
+			if (speedSearch != null) {
+				installSpeedSearch(speedSearch, popup)
+			}
+		}
+		
+		private fun installSpeedSearch(speedSearch: SpeedSearch, popup: WizardPopup) {
+			val pauseAction = PauseSpeedSearchAction(this, speedSearch)
+			
+			for (keyStroke in getAllKeyStrokes()) {
+				if (keyStroke.keyEventType != KeyEvent.KEY_TYPED) {
+					continue
+				}
+				
+				val keyCode = KeyEvent.getExtendedKeyCodeForChar(keyStroke.keyChar.code)
+				if (keyCode != KeyEvent.VK_UNDEFINED) {
+					popup.registerAction("KeyboardMaster-VimListNavigation-PauseSpeedSearch", KeyStroke.getKeyStroke(keyCode, 0), pauseAction)
+					popup.registerAction("KeyboardMaster-VimListNavigation-PauseSpeedSearch", KeyStroke.getKeyStroke(keyCode, KeyEvent.SHIFT_DOWN_MASK), pauseAction)
+				}
+			}
+			
+			// WizardPopup only checks key codes against its input map, but key codes may be undefined for some characters.
+			popup.registerAction("KeyboardMaster-VimListNavigation-PauseSpeedSearch", KeyStroke.getKeyStroke(KeyEvent.CHAR_UNDEFINED, 0), pauseAction)
+			popup.registerAction("KeyboardMaster-VimListNavigation-PauseSpeedSearch", KeyStroke.getKeyStroke(KeyEvent.CHAR_UNDEFINED, KeyEvent.SHIFT_DOWN_MASK), pauseAction)
+		}
+		
+		private class PauseSpeedSearchAction(private val dispatcher: VimNavigationDispatcher<JList<*>>, private val speedSearch: SpeedSearch) : AbstractAction() {
+			override fun actionPerformed(e: ActionEvent) {
+				if (!dispatcher.isSearching.get()) {
+					speedSearch.setEnabled(false)
+					ApplicationManager.getApplication().invokeLater { speedSearch.setEnabled(true) }
+				}
+			}
+		}
+	}
 }