private static CompletionContext createCompletionContext( PsiFile hostCopy, int hostStartOffset, OffsetMap hostMap, PsiFile originalFile) { CompletionAssertions.assertHostInfo(hostCopy, hostMap); InjectedLanguageManager injectedLanguageManager = InjectedLanguageManager.getInstance(hostCopy.getProject()); CompletionContext context; PsiFile injected = InjectedLanguageUtil.findInjectedPsiNoCommit(hostCopy, hostStartOffset); if (injected != null) { if (injected instanceof PsiFileImpl) { ((PsiFileImpl) injected).setOriginalFile(originalFile); } DocumentWindow documentWindow = InjectedLanguageUtil.getDocumentWindow(injected); CompletionAssertions.assertInjectedOffsets( hostStartOffset, injectedLanguageManager, injected, documentWindow); context = new CompletionContext(injected, translateOffsetMapToInjected(hostMap, documentWindow)); } else { context = new CompletionContext(hostCopy, hostMap); } CompletionAssertions.assertFinalOffsets(originalFile, context, injected); return context; }
@Override @Nullable public List<Pair<PsiElement, TextRange>> getInjectedPsiFiles(@NotNull final PsiElement host) { if (!(host instanceof PsiLanguageInjectionHost) || !((PsiLanguageInjectionHost) host).isValidHost()) { return null; } final PsiElement inTree = InjectedLanguageUtil.loadTree(host, host.getContainingFile()); final List<Pair<PsiElement, TextRange>> result = new SmartList<Pair<PsiElement, TextRange>>(); InjectedLanguageUtil.enumerate( inTree, new PsiLanguageInjectionHost.InjectedPsiVisitor() { @Override public void visit( @NotNull PsiFile injectedPsi, @NotNull List<PsiLanguageInjectionHost.Shred> places) { for (PsiLanguageInjectionHost.Shred place : places) { if (place.getHost() == inTree) { result.add( new Pair<PsiElement, TextRange>(injectedPsi, place.getRangeInsideHost())); } } } }); return result.isEmpty() ? null : result; }
@Nullable public static LookupEx getActiveLookup(@Nullable Editor editor) { if (editor == null) return null; final Project project = editor.getProject(); if (project == null || project.isDisposed()) return null; final LookupEx lookup = getInstance(project).getActiveLookup(); if (lookup == null) return null; return InjectedLanguageUtil.getTopLevelEditor(lookup.getEditor()) == InjectedLanguageUtil.getTopLevelEditor(editor) ? lookup : null; }
private void highlightInjectedSyntax( @NotNull PsiFile injectedPsi, @NotNull HighlightInfoHolder holder) { List<Trinity<IElementType, SmartPsiElementPointer<PsiLanguageInjectionHost>, TextRange>> tokens = InjectedLanguageUtil.getHighlightTokens(injectedPsi); if (tokens == null) return; final Language injectedLanguage = injectedPsi.getLanguage(); Project project = injectedPsi.getProject(); SyntaxHighlighter syntaxHighlighter = SyntaxHighlighterFactory.getSyntaxHighlighter( injectedLanguage, project, injectedPsi.getVirtualFile()); final TextAttributes defaultAttrs = myGlobalScheme.getAttributes(HighlighterColors.TEXT); for (Trinity<IElementType, SmartPsiElementPointer<PsiLanguageInjectionHost>, TextRange> token : tokens) { ProgressManager.checkCanceled(); IElementType tokenType = token.getFirst(); PsiLanguageInjectionHost injectionHost = token.getSecond().getElement(); if (injectionHost == null) continue; TextRange textRange = token.getThird(); TextAttributesKey[] keys = syntaxHighlighter.getTokenHighlights(tokenType); if (textRange.getLength() == 0) continue; TextRange annRange = textRange.shiftRight(injectionHost.getTextRange().getStartOffset()); // force attribute colors to override host' ones TextAttributes attributes = null; for (TextAttributesKey key : keys) { TextAttributes attrs2 = myGlobalScheme.getAttributes(key); if (attrs2 != null) { attributes = attributes == null ? attrs2 : TextAttributes.merge(attributes, attrs2); } } TextAttributes forcedAttributes; if (attributes == null || attributes.isEmpty() || attributes.equals(defaultAttrs)) { forcedAttributes = TextAttributes.ERASE_MARKER; } else { HighlightInfo info = HighlightInfo.newHighlightInfo(HighlightInfoType.INJECTED_LANGUAGE_FRAGMENT) .range(annRange) .textAttributes(TextAttributes.ERASE_MARKER) .createUnconditionally(); holder.add(info); forcedAttributes = new TextAttributes( attributes.getForegroundColor(), attributes.getBackgroundColor(), attributes.getEffectColor(), attributes.getEffectType(), attributes.getFontType()); } HighlightInfo info = HighlightInfo.newHighlightInfo(HighlightInfoType.INJECTED_LANGUAGE_FRAGMENT) .range(annRange) .textAttributes(forcedAttributes) .createUnconditionally(); holder.add(info); } }
@Override public boolean isInContext(@NotNull final PsiFile file, final int offset) { PsiElement at = file.findElementAt(offset); if (at == null && offset == file.getTextLength()) { at = file.findElementAt(offset - 1); } Language language = at != null ? at.getParent().getLanguage() : null; if (language instanceof XMLLanguage) { final PsiLanguageInjectionHost host = PsiTreeUtil.getParentOfType(at, PsiLanguageInjectionHost.class, false); if (host != null) { final Ref<Boolean> hasJsInjection = new Ref<Boolean>(Boolean.FALSE); InjectedLanguageUtil.enumerate( host, new JSResolveUtil.JSInjectedFilesVisitor() { @Override protected void process(final JSFile file) { hasJsInjection.set(Boolean.TRUE); } }); if (hasJsInjection.get()) { language = JavaScriptSupportLoader.JAVASCRIPT.getLanguage(); } } } return language != null && language.isKindOf(JavaScriptSupportLoader.JAVASCRIPT.getLanguage()); }
protected void restoreState(@NotNull final V psiField) { if (!ReadonlyStatusHandler.ensureDocumentWritable( myProject, InjectedLanguageUtil.getTopLevelEditor(myEditor).getDocument())) return; ApplicationManager.getApplication() .runWriteAction( () -> { final PsiFile containingFile = psiField.getContainingFile(); final RangeMarker exprMarker = getExprMarker(); if (exprMarker != null) { myExpr = restoreExpression(containingFile, psiField, exprMarker, myExprText); } if (myLocalMarker != null) { final PsiElement refVariableElement = containingFile.findElementAt(myLocalMarker.getStartOffset()); if (refVariableElement != null) { final PsiElement parent = refVariableElement.getParent(); if (parent instanceof PsiNamedElement) { ((PsiNamedElement) parent).setName(myLocalName); } } final V localVariable = getLocalVariable(); if (localVariable != null && localVariable.isPhysical()) { myLocalVariable = localVariable; final PsiElement nameIdentifier = localVariable.getNameIdentifier(); if (nameIdentifier != null) { myLocalMarker = createMarker(nameIdentifier); } } } final List<RangeMarker> occurrenceMarkers = getOccurrenceMarkers(); for (int i = 0, occurrenceMarkersSize = occurrenceMarkers.size(); i < occurrenceMarkersSize; i++) { RangeMarker marker = occurrenceMarkers.get(i); if (getExprMarker() != null && marker.getStartOffset() == getExprMarker().getStartOffset() && myExpr != null) { myOccurrences[i] = myExpr; continue; } final E psiExpression = restoreExpression( containingFile, psiField, marker, getLocalVariable() != null ? myLocalName : myExprText); if (psiExpression != null) { myOccurrences[i] = psiExpression; } } if (myExpr != null && myExpr.isPhysical()) { myExprMarker = createMarker(myExpr); } myOccurrenceMarkers = null; deleteTemplateField(psiField); }); }
public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) { final PsiLanguageInjectionHost host = findInjectionHost(editor, file); if (host == null) return false; final List<Pair<PsiElement, TextRange>> injectedPsi = InjectedLanguageUtil.getInstance().getInjectedPsiFiles(host); return injectedPsi == null || injectedPsi.isEmpty(); }
private void altCommitToOriginal(@NotNull DocumentEvent e) { final PsiFile origPsiFile = PsiDocumentManager.getInstance(myProject).getPsiFile(myOrigDocument); String newText = myNewDocument.getText(); // prepare guarded blocks LinkedHashMap<String, String> replacementMap = new LinkedHashMap<String, String>(); int count = 0; for (RangeMarker o : ContainerUtil.reverse(((DocumentEx) myNewDocument).getGuardedBlocks())) { String replacement = o.getUserData(REPLACEMENT_KEY); String tempText = "REPLACE" + (count++) + Long.toHexString(StringHash.calc(replacement)); newText = newText.substring(0, o.getStartOffset()) + tempText + newText.substring(o.getEndOffset()); replacementMap.put(tempText, replacement); } // run preformat processors final int hostStartOffset = myAltFullRange.getStartOffset(); myEditor.getCaretModel().moveToOffset(hostStartOffset); for (CopyPastePreProcessor preProcessor : Extensions.getExtensions(CopyPastePreProcessor.EP_NAME)) { newText = preProcessor.preprocessOnPaste(myProject, origPsiFile, myEditor, newText, null); } myOrigDocument.replaceString(hostStartOffset, myAltFullRange.getEndOffset(), newText); // replace temp strings for guarded blocks for (String tempText : replacementMap.keySet()) { int idx = CharArrayUtil.indexOf( myOrigDocument.getCharsSequence(), tempText, hostStartOffset, myAltFullRange.getEndOffset()); myOrigDocument.replaceString(idx, idx + tempText.length(), replacementMap.get(tempText)); } // JAVA: fix occasional char literal concatenation fixDocumentQuotes(myOrigDocument, hostStartOffset - 1); fixDocumentQuotes(myOrigDocument, myAltFullRange.getEndOffset()); // reformat PsiDocumentManager.getInstance(myProject).commitDocument(myOrigDocument); Runnable task = () -> { try { CodeStyleManager.getInstance(myProject) .reformatRange(origPsiFile, hostStartOffset, myAltFullRange.getEndOffset(), true); } catch (IncorrectOperationException e1) { // LOG.error(e); } }; DocumentUtil.executeInBulk(myOrigDocument, true, task); PsiElement newInjected = InjectedLanguageManager.getInstance(myProject) .findInjectedElementAt(origPsiFile, hostStartOffset); DocumentWindow documentWindow = newInjected == null ? null : InjectedLanguageUtil.getDocumentWindow(newInjected); if (documentWindow != null) { myEditor.getCaretModel().moveToOffset(documentWindow.injectedToHost(e.getOffset())); myEditor.getScrollingModel().scrollToCaret(ScrollType.MAKE_VISIBLE); } }
public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) { final int offset = editor.getCaretModel().getOffset(); final PsiFile psiFile = InjectedLanguageUtil.findInjectedPsiNoCommit(file, offset); if (psiFile == null) return false; final LanguageInjectionSupport support = psiFile.getUserData(LanguageInjectionSupport.INJECTOR_SUPPORT); return support != null; }
@Override public void tokenize(@NotNull T element, TokenConsumer consumer) { if (element instanceof PsiLanguageInjectionHost && InjectedLanguageUtil.hasInjections((PsiLanguageInjectionHost) element)) { return; } consumer.consumeToken(element, mySplitter); }
@Override public void enumerateEx( @NotNull PsiElement host, @NotNull PsiFile containingFile, boolean probeUp, @NotNull PsiLanguageInjectionHost.InjectedPsiVisitor visitor) { InjectedLanguageUtil.enumerate(host, containingFile, probeUp, visitor); }
@Override protected void revertStateOnFinish() { final Editor editor = InjectedLanguageUtil.getTopLevelEditor(myEditor); if (editor == FileEditorManager.getInstance(myProject).getSelectedTextEditor()) { ((EditorImpl) editor).startDumb(); } revertState(); }
@Nullable protected PsiFile getContainingFile() { final PsiFile file = InjectedLanguageUtil.getTopLevelFile(myElement.getContainingFile()); if (file == null) { LOG.error("Invalid element: " + myElement); } return file.getOriginalFile(); }
private void getInjectedPsiFiles( @NotNull final List<PsiElement> elements1, @NotNull final List<PsiElement> elements2, @NotNull final ProgressIndicator progress, @NotNull final Set<PsiFile> outInjected) { List<DocumentWindow> injected = InjectedLanguageUtil.getCachedInjectedDocuments(myFile); Collection<PsiElement> hosts = new THashSet<PsiElement>(elements1.size() + elements2.size() + injected.size()); // rehighlight all injected PSI regardless the range, // since change in one place can lead to invalidation of injected PSI in (completely) other // place. for (DocumentWindow documentRange : injected) { progress.checkCanceled(); if (!documentRange.isValid()) continue; PsiFile file = PsiDocumentManager.getInstance(myProject).getPsiFile(documentRange); if (file == null) continue; PsiElement context = InjectedLanguageManager.getInstance(file.getProject()).getInjectionHost(file); if (context != null && context.isValid() && !file.getProject().isDisposed() && (myUpdateAll || new ProperTextRange(myStartOffset, myEndOffset) .intersects(context.getTextRange()))) { hosts.add(context); } } hosts.addAll(elements1); hosts.addAll(elements2); final PsiLanguageInjectionHost.InjectedPsiVisitor visitor = new PsiLanguageInjectionHost.InjectedPsiVisitor() { @Override public void visit( @NotNull PsiFile injectedPsi, @NotNull List<PsiLanguageInjectionHost.Shred> places) { synchronized (outInjected) { outInjected.add(injectedPsi); } } }; if (!JobUtil.invokeConcurrentlyUnderProgress( new ArrayList<PsiElement>(hosts), progress, false, new Processor<PsiElement>() { @Override public boolean process(PsiElement element) { progress.checkCanceled(); InjectedLanguageUtil.enumerate(element, myFile, false, visitor); return true; } })) throw new ProcessCanceledException(); }
public static void disposeInvalidEditors() { ApplicationManager.getApplication().assertWriteAccessAllowed(); Iterator<EditorWindow> iterator = allEditors.iterator(); while (iterator.hasNext()) { EditorWindow editorWindow = iterator.next(); if (!editorWindow.isValid()) { editorWindow.dispose(); InjectedLanguageUtil.clearCaches(editorWindow.myInjectedFile, editorWindow.getDocument()); iterator.remove(); } } }
private static boolean defaultFunctionalityWorked(final PsiLanguageInjectionHost host) { final THashSet<String> languages = new THashSet<String>(); final List<Pair<PsiElement, TextRange>> files = InjectedLanguageUtil.getInjectedPsiFiles(host); if (files == null) return false; for (Pair<PsiElement, TextRange> pair : files) { for (Language lang = pair.first.getLanguage(); lang != null; lang = lang.getBaseLanguage()) { languages.add(lang.getID()); } } // todo there is a problem: host i.e. literal expression is confused with "target" i.e. // parameter // todo therefore this part doesn't work for java return Configuration.getInstance().setHostInjectionEnabled(host, languages, false); }
@Nullable public static Pair<PsiFile, Editor> chooseBetweenHostAndInjected( PsiFile hostFile, Editor hostEditor, PairProcessor<PsiFile, Editor> predicate) { Editor editorToApply = null; PsiFile fileToApply = null; int offset = hostEditor.getCaretModel().getOffset(); PsiFile injectedFile = InjectedLanguageUtil.findInjectedPsiNoCommit(hostFile, offset); if (injectedFile != null) { Editor injectedEditor = InjectedLanguageUtil.getInjectedEditorForInjectedFile(hostEditor, injectedFile); if (predicate.process(injectedFile, injectedEditor)) { editorToApply = injectedEditor; fileToApply = injectedFile; } } if (editorToApply == null && predicate.process(hostFile, hostEditor)) { editorToApply = hostEditor; fileToApply = hostFile; } if (editorToApply == null) return null; return Pair.create(fileToApply, editorToApply); }
/** * intersection may spread over several injected fragments * * @param rangeToEdit range in encoded(raw) PSI * @return list of ranges in encoded (raw) PSI */ @Override @SuppressWarnings({"ConstantConditions", "unchecked"}) @NotNull public List<TextRange> intersectWithAllEditableFragments( @NotNull PsiFile injectedPsi, @NotNull TextRange rangeToEdit) { Place shreds = InjectedLanguageUtil.getShreds(injectedPsi); if (shreds == null) return Collections.emptyList(); Object result = null; // optimization: TextRange or ArrayList int count = 0; int offset = 0; for (PsiLanguageInjectionHost.Shred shred : shreds) { TextRange encodedRange = TextRange.from( offset + shred.getPrefix().length(), shred.getRangeInsideHost().getLength()); TextRange intersection = encodedRange.intersection(rangeToEdit); if (intersection != null) { count++; if (count == 1) { result = intersection; } else if (count == 2) { TextRange range = (TextRange) result; if (range.isEmpty()) { result = intersection; count = 1; } else if (intersection.isEmpty()) { count = 1; } else { List<TextRange> list = new ArrayList<TextRange>(); list.add(range); list.add(intersection); result = list; } } else if (intersection.isEmpty()) { count--; } else { ((List<TextRange>) result).add(intersection); } } offset += shred.getPrefix().length() + shred.getRangeInsideHost().getLength() + shred.getSuffix().length(); } return count == 0 ? Collections.<TextRange>emptyList() : count == 1 ? Collections.singletonList((TextRange) result) : (List<TextRange>) result; }
@Override public void mouseMoved(final EditorMouseEvent e) { if (e.isConsumed() || !myProject.isInitialized() || myProject.isDisposed()) { return; } MouseEvent mouseEvent = e.getMouseEvent(); if (isMouseOverTooltip(mouseEvent.getLocationOnScreen()) || ScreenUtil.isMovementTowards( myPrevMouseLocation, mouseEvent.getLocationOnScreen(), getHintBounds())) { myPrevMouseLocation = mouseEvent.getLocationOnScreen(); return; } myPrevMouseLocation = mouseEvent.getLocationOnScreen(); Editor editor = e.getEditor(); if (editor.getProject() != null && editor.getProject() != myProject) return; PsiDocumentManager documentManager = PsiDocumentManager.getInstance(myProject); PsiFile psiFile = documentManager.getPsiFile(editor.getDocument()); Point point = new Point(mouseEvent.getPoint()); if (documentManager.isCommitted(editor.getDocument())) { // when document is committed, try to check injected stuff - it's fast int offset = editor.logicalPositionToOffset(editor.xyToLogicalPosition(point)); editor = InjectedLanguageUtil.getEditorForInjectedLanguageNoCommit(editor, psiFile, offset); } LogicalPosition pos = editor.xyToLogicalPosition(point); int offset = editor.logicalPositionToOffset(pos); int selStart = editor.getSelectionModel().getSelectionStart(); int selEnd = editor.getSelectionModel().getSelectionEnd(); myStoredModifiers = mouseEvent.getModifiers(); BrowseMode browseMode = getBrowseMode(myStoredModifiers); cancelPreviousTooltip(); if (browseMode == BrowseMode.None || offset >= selStart && offset < selEnd) { disposeHighlighter(); return; } myTooltipProvider = new TooltipProvider(editor, pos); myTooltipProvider.execute(browseMode); }
private static void invokeImpl(Project project, Editor editor, PsiFile file) { final PsiFile psiFile = InjectedLanguageUtil.findInjectedPsiNoCommit(file, editor.getCaretModel().getOffset()); if (psiFile == null) return; final PsiLanguageInjectionHost host = InjectedLanguageManager.getInstance(project).getInjectionHost(psiFile); if (host == null) return; final LanguageInjectionSupport support = psiFile.getUserData(LanguageInjectionSupport.INJECTOR_SUPPORT); if (support == null) return; try { if (!support.removeInjectionInPlace(host)) { defaultFunctionalityWorked(host); } } finally { FileContentUtil.reparseFiles(project, Collections.<VirtualFile>emptyList(), true); } }
public int getLineNumber() { if (myLineNumber == -1) { PsiElement psiElement = getPsiElement(); if (psiElement == null) return -1; if (!psiElement.isValid()) return -1; LOG.assertTrue(psiElement.isPhysical()); PsiFile containingFile = InjectedLanguageUtil.getTopLevelFile(psiElement); Document document = PsiDocumentManager.getInstance(psiElement.getProject()).getDocument(containingFile); if (document == null) return -1; TextRange textRange = getTextRange(); if (textRange == null) return -1; textRange = InjectedLanguageManager.getInstance(containingFile.getProject()) .injectedToHost(psiElement, textRange); myLineNumber = document.getLineNumber(textRange.getStartOffset()) + 1; } return myLineNumber; }
public void mouseMoved(final EditorMouseEvent e) { if (e.isConsumed() || !myProject.isInitialized()) { return; } MouseEvent mouseEvent = e.getMouseEvent(); Editor editor = e.getEditor(); if (editor.getProject() != null && editor.getProject() != myProject) return; PsiFile psiFile = PsiDocumentManager.getInstance(myProject).getPsiFile(editor.getDocument()); Point point = new Point(mouseEvent.getPoint()); if (!PsiDocumentManager.getInstance(myProject).isUncommited(editor.getDocument())) { // when document is committed, try to check injected stuff - it's fast editor = InjectedLanguageUtil.getEditorForInjectedLanguageNoCommit( editor, psiFile, editor.logicalPositionToOffset(editor.xyToLogicalPosition(point))); } LogicalPosition pos = editor.xyToLogicalPosition(point); int offset = editor.logicalPositionToOffset(pos); int selStart = editor.getSelectionModel().getSelectionStart(); int selEnd = editor.getSelectionModel().getSelectionEnd(); myStoredModifiers = mouseEvent.getModifiers(); BrowseMode browseMode = getBrowseMode(myStoredModifiers); if (myTooltipProvider != null) { myTooltipProvider.dispose(); } if (browseMode == BrowseMode.None || offset >= selStart && offset < selEnd) { disposeHighlighter(); myTooltipProvider = null; return; } myTooltipProvider = new TooltipProvider(editor, pos); myTooltipProvider.execute(browseMode); }
private static boolean shouldSkipAutoPopup(Editor editor, PsiFile psiFile) { int offset = editor.getCaretModel().getOffset(); int psiOffset = Math.max(0, offset - 1); PsiElement elementAt = InjectedLanguageUtil.findInjectedElementNoCommit(psiFile, psiOffset); if (elementAt == null) { elementAt = psiFile.findElementAt(psiOffset); } if (elementAt == null) return true; Language language = PsiUtilCore.findLanguageFromElement(elementAt); for (CompletionConfidence confidence : CompletionConfidenceEP.forLanguage(language)) { final ThreeState result = confidence.shouldSkipAutopopup(elementAt, psiFile, offset); if (result != ThreeState.UNSURE) { LOG.debug(confidence + " has returned shouldSkipAutopopup=" + result); return result == ThreeState.YES; } } return false; }
@Override public boolean containsWhiteSpaceSymbolsOnly(int startOffset, int endOffset) { WhiteSpaceFormattingStrategy strategy = myWhiteSpaceStrategy; if (strategy.check(myDocument.getCharsSequence(), startOffset, endOffset) >= endOffset) { return true; } PsiElement injectedElement = myFile != null ? InjectedLanguageUtil.findElementAtNoCommit(myFile, startOffset) : null; if (injectedElement != null) { Language injectedLanguage = injectedElement.getLanguage(); if (!injectedLanguage.equals(myFile.getLanguage())) { WhiteSpaceFormattingStrategy localStrategy = WhiteSpaceFormattingStrategyFactory.getStrategy(injectedLanguage); if (localStrategy != null) { return localStrategy.check(myDocument.getCharsSequence(), startOffset, endOffset) >= endOffset; } } } return false; }
@Override protected void performRefactoringRename(final String newName, final StartMarkAction markAction) { try { final PsiNamedElement variable = getVariable(); if (variable != null && !newName.equals(myOldName)) { if (isIdentifier(newName, variable.getLanguage())) { final PsiElement substituted = getSubstituted(); if (substituted == null) { return; } final String commandName = RefactoringBundle.message( "renaming.0.1.to.2", UsageViewUtil.getType(variable), UsageViewUtil.getDescriptiveName(variable), newName); CommandProcessor.getInstance() .executeCommand( myProject, new Runnable() { @Override public void run() { performRenameInner(substituted, newName); PsiDocumentManager.getInstance(myProject).commitAllDocuments(); } }, commandName, null); } } } finally { try { ((EditorImpl) InjectedLanguageUtil.getTopLevelEditor(myEditor)).stopDumbLater(); } finally { FinishMarkAction.finish(myProject, myEditor, markAction); } } }
@NotNull @Override public PsiReference[] getReferencesByElement( @NotNull PsiElement element, @NotNull ProcessingContext context) { if (XmlSchemaTagsProcessor.PROCESSING_FLAG.get() != null || context.get(SUPPRESS) != null) { return PsiReference.EMPTY_ARRAY; } @SuppressWarnings("unchecked") PsiElement host = getHost((T) element); if (host instanceof PsiLanguageInjectionHost && InjectedLanguageUtil.hasInjections((PsiLanguageInjectionHost) host)) { return PsiReference.EMPTY_ARRAY; } String unquotedValue = ElementManipulators.getValueText(element); if (XmlHighlightVisitor.skipValidation(element) || !XmlUtil.isSimpleValue(unquotedValue, element)) { return PsiReference.EMPTY_ARRAY; } @SuppressWarnings("unchecked") final Object descriptor = getDescriptor((T) element); if (descriptor instanceof XmlEnumerationDescriptor) { XmlEnumerationDescriptor enumerationDescriptor = (XmlEnumerationDescriptor) descriptor; if (enumerationDescriptor.isFixed() || enumerationDescriptor.isEnumerated((XmlElement) element)) { //noinspection unchecked return enumerationDescriptor.getValueReferences((XmlElement) element, unquotedValue); } else if (unquotedValue.equals( enumerationDescriptor.getDefaultValue())) { // todo case insensitive return ContainerUtil.map2Array( enumerationDescriptor.getValueReferences((XmlElement) element, unquotedValue), PsiReference.class, reference -> PsiDelegateReference.createSoft(reference, true)); } } return PsiReference.EMPTY_ARRAY; }
private void insertLookupString(LookupElement item, final int prefix) { final String lookupString = getCaseCorrectedLookupString(item); final Editor hostEditor = InjectedLanguageUtil.getTopLevelEditor(myEditor); hostEditor .getCaretModel() .runForEachCaret( new CaretAction() { @Override public void perform(Caret caret) { EditorModificationUtil.deleteSelectedText(hostEditor); final int caretOffset = hostEditor.getCaretModel().getOffset(); int lookupStart = Math.max(caretOffset - prefix, 0); int len = hostEditor.getDocument().getTextLength(); LOG.assertTrue( lookupStart >= 0 && lookupStart <= len, "ls: " + lookupStart + " caret: " + caretOffset + " prefix:" + prefix + " doc: " + len); LOG.assertTrue( caretOffset >= 0 && caretOffset <= len, "co: " + caretOffset + " doc: " + len); hostEditor.getDocument().replaceString(lookupStart, caretOffset, lookupString); int offset = lookupStart + lookupString.length(); hostEditor.getCaretModel().moveToOffset(offset); hostEditor.getSelectionModel().removeSelection(); } }); myEditor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE); }
@Override public Result preprocessEnter( @NotNull PsiFile file, @NotNull Editor editor, @NotNull Ref<Integer> caretOffset, @NotNull Ref<Integer> caretAdvance, @NotNull DataContext dataContext, EditorActionHandler originalHandler) { int offset = caretOffset.get(); if (editor instanceof EditorWindow) { file = InjectedLanguageManager.getInstance(file.getProject()).getTopLevelFile(file); editor = InjectedLanguageUtil.getTopLevelEditor(editor); offset = editor.getCaretModel().getOffset(); } if (!(file instanceof PyFile)) { return Result.Continue; } // honor dedent (PY-3009) if (BackspaceHandler.isWhitespaceBeforeCaret(editor)) { return Result.DefaultSkipIndent; } return Result.Continue; }
private static Runnable rememberDocumentState(final Editor _editor) { final Editor editor = InjectedLanguageUtil.getTopLevelEditor(_editor); final String documentText = editor.getDocument().getText(); final int caret = editor.getCaretModel().getOffset(); final int selStart = editor.getSelectionModel().getSelectionStart(); final int selEnd = editor.getSelectionModel().getSelectionEnd(); final int vOffset = editor.getScrollingModel().getVerticalScrollOffset(); final int hOffset = editor.getScrollingModel().getHorizontalScrollOffset(); return new Runnable() { @Override public void run() { DocumentEx document = (DocumentEx) editor.getDocument(); document.replaceString(0, document.getTextLength(), documentText); editor.getCaretModel().moveToOffset(caret); editor.getSelectionModel().setSelection(selStart, selEnd); editor.getScrollingModel().scrollHorizontally(hOffset); editor.getScrollingModel().scrollVertically(vOffset); } }; }
@Override public void addOccurrenceHighlights( @NotNull Editor editor, @NotNull PsiReference[] occurrences, @NotNull TextAttributes attributes, boolean hideByTextChange, Collection<RangeHighlighter> outHighlighters) { if (occurrences.length == 0) return; int flags = HIDE_BY_ESCAPE; if (hideByTextChange) { flags |= HIDE_BY_TEXT_CHANGE; } Color scrollmarkColor = getScrollMarkColor(attributes); int oldOffset = editor.getCaretModel().getOffset(); int horizontalScrollOffset = editor.getScrollingModel().getHorizontalScrollOffset(); int verticalScrollOffset = editor.getScrollingModel().getVerticalScrollOffset(); for (PsiReference occurrence : occurrences) { PsiElement element = occurrence.getElement(); int startOffset = element.getTextRange().getStartOffset(); int start = startOffset + occurrence.getRangeInElement().getStartOffset(); int end = startOffset + occurrence.getRangeInElement().getEndOffset(); PsiFile containingFile = element.getContainingFile(); Project project = element.getProject(); // each reference can reside in its own injected editor Editor textEditor = InjectedLanguageUtil.openEditorFor(containingFile, project); if (textEditor != null) { addOccurrenceHighlight( textEditor, start, end, attributes, flags, outHighlighters, scrollmarkColor); } } editor.getCaretModel().moveToOffset(oldOffset); editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE); editor.getScrollingModel().scrollHorizontally(horizontalScrollOffset); editor.getScrollingModel().scrollVertically(verticalScrollOffset); }