From 7bb29bbed9966d770e4f13b3a82510dbcf575823 Mon Sep 17 00:00:00 2001 From: Alex Plate Date: Wed, 21 Nov 2018 18:27:58 +0300 Subject: [PATCH] Handle wrong lookup selection Some of lookup suggestions can have unwanted behaviour like additional imports. There wrong suggestions will be deleted and further lookup suggestions for this case will be ignored --- .../intellij/internal/retype/RetypeSession.kt | 33 +++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/internal/retype/RetypeSession.kt b/platform/lang-impl/src/com/intellij/internal/retype/RetypeSession.kt index 0b3f560e04fb..51a1a266a799 100644 --- a/platform/lang-impl/src/com/intellij/internal/retype/RetypeSession.kt +++ b/platform/lang-impl/src/com/intellij/internal/retype/RetypeSession.kt @@ -58,6 +58,9 @@ class RetypeSession( private val disposeLock = Any() private var typedRightBefore = false + private var skipLookupSuggestion = false + private var textBeforeLookupSelection: String? = null + init { if (editor.selectionModel.hasSelection()) { pos = editor.selectionModel.selectionStart @@ -128,8 +131,28 @@ class RetypeSession( private fun typeNext() { threadDumpAlarm.addRequest({ logThreadDump() }, threadDumpDelay) + if (document.text.take(pos) != originalText.take(pos)) { + // Unexpected changes before current cursor position + // (may be unwanted import) + if (textBeforeLookupSelection != null) { + // Unexpected changes was made by lookup. + // Restore previous text state and set flag to skip further suggestions until whitespace will be typed + WriteCommandAction.runWriteCommandAction(project) { + document.replaceText(textBeforeLookupSelection ?: return@runWriteCommandAction, document.modificationStamp + 1) + } + skipLookupSuggestion = true + } + else { + // There changes wasn't made by lookup, so we don't know how to handle them + // Restore text as it should be at this point without any intelligence + WriteCommandAction.runWriteCommandAction(project) { + document.replaceText(originalText.substring(0, pos) + originalText.substring(endPos), document.modificationStamp + 1) + } + } + } + if (editor.caretModel.offset > pos) { - // Editor movement has been preformed + // Caret movement has been preformed // Move the caret forward until the characters match while (pos < document.textLength - tailLength && originalText[pos] == document.text[pos] @@ -163,12 +186,13 @@ class RetypeSession( } val lookup = LookupManager.getActiveLookup(editor) as LookupImpl? - if (lookup != null) { + if (lookup != null && !skipLookupSuggestion) { val currentLookupElement = lookup.currentItem if (currentLookupElement?.shouldAccept(lookup.lookupStart) == true) { lookup.focusDegree = LookupImpl.FocusDegree.FOCUSED scriptBuilder?.append("${ActionCommand.PREFIX} ${IdeActions.ACTION_CHOOSE_LOOKUP_ITEM}\n") typedRightBefore = false + textBeforeLookupSelection = document.text executeEditorAction(IdeActions.ACTION_CHOOSE_LOOKUP_ITEM) queueNextOrStop() return @@ -177,6 +201,11 @@ class RetypeSession( val c = originalText[pos++] typedChars++ + + // Reset lookup related variables + textBeforeLookupSelection = null + if (c == ' ') skipLookupSuggestion = false // We expecting new lookup suggestions + if (c == '\n') { scriptBuilder?.append("${ActionCommand.PREFIX} ${IdeActions.ACTION_EDITOR_ENTER}\n") executeEditorAction(IdeActions.ACTION_EDITOR_ENTER)