@Override public void beforeCompletion(@NotNull final CompletionInitializationContext context) { final PsiFile file = context.getFile(); if (file instanceof PsiJavaFile) { JavaCompletionUtil.initOffsets(file, context.getOffsetMap()); autoImport(file, context.getStartOffset() - 1, context.getEditor()); if (context.getCompletionType() == CompletionType.BASIC) { if (semicolonNeeded(context.getEditor(), file, context.getStartOffset())) { context.setDummyIdentifier(CompletionInitializationContext.DUMMY_IDENTIFIER.trim() + ";"); return; } final PsiJavaCodeReferenceElement ref = PsiTreeUtil.findElementOfClassAtOffset( file, context.getStartOffset(), PsiJavaCodeReferenceElement.class, false); if (ref != null && !(ref instanceof PsiReferenceExpression)) { if (ref.getParent() instanceof PsiTypeElement) { context.setDummyIdentifier( CompletionInitializationContext.DUMMY_IDENTIFIER.trim() + ";"); } if (JavaSmartCompletionContributor.AFTER_NEW.accepts(ref)) { final PsiReferenceParameterList paramList = ref.getParameterList(); if (paramList != null && paramList.getTextLength() > 0) { context .getOffsetMap() .addOffset( ConstructorInsertHandler.PARAM_LIST_START, paramList.getTextRange().getStartOffset()); context .getOffsetMap() .addOffset( ConstructorInsertHandler.PARAM_LIST_END, paramList.getTextRange().getEndOffset()); } } return; } final PsiElement element = file.findElementAt(context.getStartOffset()); if (psiElement().inside(PsiAnnotation.class).accepts(element)) { return; } context.setDummyIdentifier(CompletionInitializationContext.DUMMY_IDENTIFIER_TRIMMED); } } }
public void beforeCompletion(@NotNull CompletionInitializationContext context) { boolean acceptPathSeparator = false; { final int offset = context.getEditor().getCaretModel().getOffset(); PsiElement element = context.getFile().findElementAt(offset); if (element != null) { int prefixLength = offset - element.getTextRange().getStartOffset(); BipartiteString caretBipartiteElementText = splitByPrefixLength(element.getText(), prefixLength); Character separator = extractDirectoryTrailingFileSeparator(caretBipartiteElementText); acceptPathSeparator = separator != null; } } final OffsetMap offsetMap = context.getOffsetMap(); int idEnd = offsetMap.getOffset(CompletionInitializationContext.IDENTIFIER_END_OFFSET); final String text = context.getFile().getText(); while (idEnd < text.length()) { final char ch = text.charAt(idEnd); if (acceptPathSeparator) { if (ch == JstdConfigFileUtils.UNIX_PATH_SEPARATOR || ch == JstdConfigFileUtils.WINDOWS_PATH_SEPARATOR) { idEnd++; break; } } boolean acceptedChar = Character.isJavaIdentifierPart(ch) || IDENTIFIER_END_PATTERN.indexOf(ch) >= 0; if (acceptedChar) { idEnd++; } else { break; } } offsetMap.addOffset(CompletionInitializationContext.IDENTIFIER_END_OFFSET, idEnd); }
private void insertDummyIdentifier( final CompletionInitializationContext initContext, final boolean hasModifiers, final int invocationCount) { final PsiFile originalFile = initContext.getFile(); InjectedLanguageManager manager = InjectedLanguageManager.getInstance(originalFile.getProject()); final PsiFile hostFile = manager.getTopLevelFile(originalFile); final Editor hostEditor = InjectedLanguageUtil.getTopLevelEditor(initContext.getEditor()); final OffsetMap hostMap = translateOffsetMapToHost(initContext, originalFile, hostFile, hostEditor); final PsiFile[] hostCopy = {null}; DocumentUtil.writeInRunUndoTransparentAction( new Runnable() { @Override public void run() { hostCopy[0] = createFileCopy( hostFile, initContext.getStartOffset(), initContext.getSelectionEndOffset()); } }); final Document copyDocument = hostCopy[0].getViewProvider().getDocument(); assert copyDocument != null : "no document"; final OffsetTranslator translator = new OffsetTranslator(hostEditor.getDocument(), initContext.getFile(), copyDocument); CompletionAssertions.checkEditorValid(initContext.getEditor()); CommandProcessor.getInstance() .runUndoTransparentAction( new Runnable() { @Override public void run() { ApplicationManager.getApplication() .runWriteAction( new Runnable() { @Override public void run() { String dummyIdentifier = initContext.getDummyIdentifier(); if (StringUtil.isEmpty(dummyIdentifier)) return; int startOffset = hostMap.getOffset(CompletionInitializationContext.START_OFFSET); int endOffset = hostMap.getOffset( CompletionInitializationContext.SELECTION_END_OFFSET); copyDocument.replaceString(startOffset, endOffset, dummyIdentifier); } }); } }); CompletionAssertions.checkEditorValid(initContext.getEditor()); final Project project = originalFile.getProject(); if (!synchronous) { if (CompletionServiceImpl.isPhase(CompletionPhase.NoCompletion.getClass()) || !CompletionServiceImpl.assertPhase(CompletionPhase.CommittingDocuments.class)) { Disposer.dispose(translator); return; } final CompletionPhase.CommittingDocuments phase = (CompletionPhase.CommittingDocuments) CompletionServiceImpl.getCompletionPhase(); CompletionAutoPopupHandler.runLaterWithCommitted( project, copyDocument, new Runnable() { @Override public void run() { if (phase.checkExpired()) { Disposer.dispose(translator); return; } doComplete( initContext, hasModifiers, invocationCount, hostCopy[0], hostMap, translator); } }); } else { PsiDocumentManager.getInstance(project).commitDocument(copyDocument); doComplete(initContext, hasModifiers, invocationCount, hostCopy[0], hostMap, translator); } }
private void doComplete( CompletionInitializationContext initContext, boolean hasModifiers, int invocationCount, PsiFile hostCopy, OffsetMap hostMap, OffsetTranslator translator) { final Editor editor = initContext.getEditor(); CompletionAssertions.checkEditorValid(editor); CompletionContext context = createCompletionContext( hostCopy, hostMap.getOffset(CompletionInitializationContext.START_OFFSET), hostMap, initContext.getFile()); LookupImpl lookup = obtainLookup(editor); CompletionParameters parameters = createCompletionParameters(invocationCount, context, editor); CompletionPhase phase = CompletionServiceImpl.getCompletionPhase(); if (phase instanceof CompletionPhase.CommittingDocuments) { if (phase.indicator != null) { phase.indicator.closeAndFinish(false); } ((CompletionPhase.CommittingDocuments) phase).replaced = true; } else { CompletionServiceImpl.assertPhase(CompletionPhase.NoCompletion.getClass()); } final Semaphore freezeSemaphore = new Semaphore(); freezeSemaphore.down(); final CompletionProgressIndicator indicator = new CompletionProgressIndicator( editor, parameters, this, freezeSemaphore, initContext.getOffsetMap(), hasModifiers, lookup); Disposer.register(indicator, hostMap); Disposer.register(indicator, context.getOffsetMap()); Disposer.register(indicator, translator); CompletionServiceImpl.setCompletionPhase( synchronous ? new CompletionPhase.Synchronous(indicator) : new CompletionPhase.BgCalculation(indicator)); final AtomicReference<LookupElement[]> data = indicator.startCompletion(initContext); if (!synchronous) { return; } if (freezeSemaphore.waitFor(2000)) { final LookupElement[] allItems = data.get(); if (allItems != null && !indicator.isRunning() && !indicator .isCanceled()) { // the completion is really finished, now we may auto-insert or show // lookup completionFinished( initContext.getStartOffset(), initContext.getSelectionEndOffset(), indicator, allItems, hasModifiers); checkNotSync(indicator, allItems); return; } } CompletionServiceImpl.setCompletionPhase(new CompletionPhase.BgCalculation(indicator)); indicator.showLookup(); }