void (@NotNull Project project, @NotNull final Editor editor, @NotNull PsiFile file) { if (!EditorModificationUtil.requestWriting(editor)) { return; } int caretOffset = editor.getCaretModel().getOffset(); if (editor.isViewer() || editor.getDocument().getRangeGuard(caretOffset, caretOffset) != null) { editor.getDocument().fireReadOnlyModificationAttempt(); EditorModificationUtil.checkModificationAllowed(editor); return; } LookupManager.getInstance(project).hideActiveLookup(); final CharSequence charsSequence = editor.getDocument().getCharsSequence(); final CompletionData data = computeData(editor, charsSequence); final CompletionState completionState = getCompletionState(editor); String oldPrefix = completionState.oldPrefix; CompletionVariant lastProposedVariant = completionState.lastProposedVariant; boolean fromOtherFiles = completionState.fromOtherFiles; if (lastProposedVariant == null || oldPrefix == null || !completionState.caretOffsets.equals(getCaretOffsets(editor)) || completionState.lastModCount != editor.getDocument().getModificationStamp()) { //we are starting over oldPrefix = data.myPrefix; completionState.oldPrefix = oldPrefix; lastProposedVariant = null; fromOtherFiles = false; } else { data.startOffset = completionState.lastStartOffset; } CompletionVariant nextVariant = computeNextVariant(editor, oldPrefix, lastProposedVariant, data, file, fromOtherFiles, false); if (nextVariant == null) { insertStringForEachCaret(editor, oldPrefix, caretOffset - data.startOffset); editor.putUserData(KEY_STATE, null); return; } RangeMarker start = editor.getDocument().createRangeMarker(data.startOffset, data.startOffset); nextVariant.fastenBelts(); try { insertStringForEachCaret(editor, nextVariant.variant, caretOffset - data.startOffset); } finally { nextVariant.unfastenBelts(); } if (!start.isValid()) { editor.putUserData(KEY_STATE, null); return; } completionState.lastProposedVariant = nextVariant; completionState.lastStartOffset = start.getStartOffset(); completionState.lastModCount = editor.getDocument().getModificationStamp(); completionState.caretOffsets = getCaretOffsets(editor); completionState.fromOtherFiles = nextVariant.editor != editor; if (nextVariant.editor == editor) highlightWord(nextVariant, project); start.dispose(); }