Search in sources :

Example 6 with DocumentWindow

use of com.intellij.injected.editor.DocumentWindow in project intellij-community by JetBrains.

the class LookupImpl method insertLookupInDocumentWindowIfNeeded.

private int insertLookupInDocumentWindowIfNeeded(int caretOffset, int prefix, String lookupString) {
    DocumentWindow document = getInjectedDocument(caretOffset);
    if (document == null)
        return insertLookupInDocument(caretOffset, myEditor.getDocument(), prefix, lookupString);
    PsiFile file = PsiDocumentManager.getInstance(myProject).getPsiFile(document);
    int offset = document.hostToInjected(caretOffset);
    int lookupStart = Math.min(offset, Math.max(offset - prefix, 0));
    int diff = -1;
    if (file != null) {
        List<TextRange> ranges = InjectedLanguageManager.getInstance(myProject).intersectWithAllEditableFragments(file, TextRange.create(lookupStart, offset));
        if (!ranges.isEmpty()) {
            diff = ranges.get(0).getStartOffset() - lookupStart;
            if (ranges.size() == 1 && diff == 0)
                diff = -1;
        }
    }
    if (diff == -1)
        return insertLookupInDocument(caretOffset, myEditor.getDocument(), prefix, lookupString);
    return document.injectedToHost(insertLookupInDocument(offset, document, prefix - diff, diff == 0 ? lookupString : lookupString.substring(diff)));
}
Also used : DocumentWindow(com.intellij.injected.editor.DocumentWindow) PsiFile(com.intellij.psi.PsiFile) TextRange(com.intellij.openapi.util.TextRange) RelativePoint(com.intellij.ui.awt.RelativePoint)

Example 7 with DocumentWindow

use of com.intellij.injected.editor.DocumentWindow in project intellij-community by JetBrains.

the class TypedHandler method injectedEditorIfCharTypedIsSignificant.

@NotNull
public static Editor injectedEditorIfCharTypedIsSignificant(final int charTyped, @NotNull Editor editor, @NotNull PsiFile oldFile) {
    int offset = editor.getCaretModel().getOffset();
    // and thus we can use its lexer to insert closing braces etc
    for (DocumentWindow documentWindow : InjectedLanguageUtil.getCachedInjectedDocuments(oldFile)) {
        if (documentWindow.isValid() && documentWindow.containsRange(offset, offset)) {
            PsiFile injectedFile = PsiDocumentManager.getInstance(oldFile.getProject()).getPsiFile(documentWindow);
            if (injectedFile != null) {
                Editor injectedEditor = InjectedLanguageUtil.getInjectedEditorForInjectedFile(editor, injectedFile);
                // IDEA-52375/WEB-9105 fix: last quote in editable fragment should be handled by outer language quote handler
                TextRange hostRange = documentWindow.getHostRange(offset);
                CharSequence sequence = editor.getDocument().getCharsSequence();
                if (sequence.length() > offset && charTyped != Character.codePointAt(sequence, offset) || hostRange != null && hostRange.contains(offset)) {
                    return injectedEditor;
                }
            }
        }
    }
    return editor;
}
Also used : DocumentWindow(com.intellij.injected.editor.DocumentWindow) PsiFile(com.intellij.psi.PsiFile) TextRange(com.intellij.openapi.util.TextRange) NotNull(org.jetbrains.annotations.NotNull)

Example 8 with DocumentWindow

use of com.intellij.injected.editor.DocumentWindow in project intellij-community by JetBrains.

the class InjectedFileViewProvider method clone.

@Override
public FileViewProvider clone() {
    final DocumentWindow oldDocumentWindow = ((VirtualFileWindow) getVirtualFile()).getDocumentWindow();
    Document hostDocument = oldDocumentWindow.getDelegate();
    final PsiDocumentManager documentManager = PsiDocumentManager.getInstance(getManager().getProject());
    PsiFile hostFile = documentManager.getPsiFile(hostDocument);
    Language language = getBaseLanguage();
    PsiFile file = getPsi(language);
    final Language hostFileLanguage = InjectedLanguageManager.getInstance(file.getProject()).getTopLevelFile(file).getLanguage();
    PsiFile hostPsiFileCopy = (PsiFile) hostFile.copy();
    Segment firstTextRange = oldDocumentWindow.getHostRanges()[0];
    PsiElement hostElementCopy = hostPsiFileCopy.getViewProvider().findElementAt(firstTextRange.getStartOffset(), hostFileLanguage);
    assert hostElementCopy != null;
    final Ref<FileViewProvider> provider = new Ref<>();
    PsiLanguageInjectionHost.InjectedPsiVisitor visitor = new PsiLanguageInjectionHost.InjectedPsiVisitor() {

        @Override
        public void visit(@NotNull PsiFile injectedPsi, @NotNull List<PsiLanguageInjectionHost.Shred> places) {
            Document document = documentManager.getCachedDocument(injectedPsi);
            if (document instanceof DocumentWindowImpl && oldDocumentWindow.areRangesEqual((DocumentWindowImpl) document)) {
                provider.set(injectedPsi.getViewProvider());
            }
        }
    };
    for (PsiElement current = hostElementCopy; current != null && current != hostPsiFileCopy; current = current.getParent()) {
        current.putUserData(LANGUAGE_FOR_INJECTED_COPY_KEY, language);
        try {
            InjectedLanguageUtil.enumerate(current, hostPsiFileCopy, false, visitor);
        } finally {
            current.putUserData(LANGUAGE_FOR_INJECTED_COPY_KEY, null);
        }
        if (provider.get() != null)
            break;
    }
    return provider.get();
}
Also used : VirtualFileWindow(com.intellij.injected.editor.VirtualFileWindow) Document(com.intellij.openapi.editor.Document) NotNull(org.jetbrains.annotations.NotNull) Segment(com.intellij.openapi.util.Segment) DocumentWindow(com.intellij.injected.editor.DocumentWindow) Ref(com.intellij.openapi.util.Ref) Language(com.intellij.lang.Language) FreeThreadedFileViewProvider(com.intellij.psi.impl.FreeThreadedFileViewProvider) DocumentWindowImpl(com.intellij.injected.editor.DocumentWindowImpl) List(java.util.List)

Example 9 with DocumentWindow

use of com.intellij.injected.editor.DocumentWindow in project intellij-community by JetBrains.

the class InjectedLanguageManagerImpl method startRunInjectors.

@Override
public void startRunInjectors(@NotNull final Document hostDocument, final boolean synchronously) {
    if (myProject.isDisposed())
        return;
    if (!synchronously && ApplicationManager.getApplication().isWriteAccessAllowed())
        return;
    // use cached to avoid recreate PSI in alien project
    final PsiDocumentManager documentManager = PsiDocumentManager.getInstance(myProject);
    final PsiFile hostPsiFile = documentManager.getCachedPsiFile(hostDocument);
    if (hostPsiFile == null)
        return;
    final ConcurrentList<DocumentWindow> injected = InjectedLanguageUtil.getCachedInjectedDocuments(hostPsiFile);
    if (injected.isEmpty())
        return;
    if (myProgress.isCanceled()) {
        myProgress = new DaemonProgressIndicator();
    }
    final Set<DocumentWindow> newDocuments = Collections.synchronizedSet(new THashSet<>());
    final Processor<DocumentWindow> commitProcessor = documentWindow -> {
        if (myProject.isDisposed())
            return false;
        ProgressIndicator indicator = ProgressManager.getInstance().getProgressIndicator();
        if (indicator != null && indicator.isCanceled())
            return false;
        if (documentManager.isUncommited(hostDocument) || !hostPsiFile.isValid())
            return false;
        InjectedLanguageUtil.enumerate(documentWindow, hostPsiFile, (injectedPsi, places) -> {
            DocumentWindow newDocument = (DocumentWindow) injectedPsi.getViewProvider().getDocument();
            if (newDocument != null) {
                PsiDocumentManagerBase.checkConsistency(injectedPsi, newDocument);
                newDocuments.add(newDocument);
            }
        });
        return true;
    };
    final Runnable commitInjectionsRunnable = () -> {
        if (myProgress.isCanceled())
            return;
        JobLauncher.getInstance().invokeConcurrentlyUnderProgress(new ArrayList<>(injected), myProgress, true, commitProcessor);
        synchronized (ourInjectionPsiLock) {
            injected.clear();
            injected.addAll(newDocuments);
        }
    };
    if (synchronously) {
        if (Thread.holdsLock(PsiLock.LOCK)) {
            // hack for the case when docCommit was called from within PSI modification, e.g. in formatter.
            // we can't spawn threads to do injections there, otherwise a deadlock is imminent
            ContainerUtil.process(new ArrayList<>(injected), commitProcessor);
        } else {
            commitInjectionsRunnable.run();
        }
    } else {
        JobLauncher.getInstance().submitToJobThread(() -> ApplicationManagerEx.getApplicationEx().tryRunReadAction(commitInjectionsRunnable), null);
    }
}
Also used : InjectedLanguageManager(com.intellij.lang.injection.InjectedLanguageManager) VirtualFileWindow(com.intellij.injected.editor.VirtualFileWindow) java.util(java.util) ArrayUtil(com.intellij.util.ArrayUtil) JobLauncher(com.intellij.concurrency.JobLauncher) VirtualFile(com.intellij.openapi.vfs.VirtualFile) EditorWindowImpl(com.intellij.injected.editor.EditorWindowImpl) Document(com.intellij.openapi.editor.Document) THashSet(gnu.trove.THashSet) DaemonCodeAnalyzer(com.intellij.codeInsight.daemon.DaemonCodeAnalyzer) ContainerUtil(com.intellij.util.containers.ContainerUtil) FileContextUtil(com.intellij.psi.impl.source.resolve.FileContextUtil) SmartList(com.intellij.util.SmartList) MultiHostInjector(com.intellij.lang.injection.MultiHostInjector) Project(com.intellij.openapi.project.Project) Segment(com.intellij.openapi.util.Segment) Logger(com.intellij.openapi.diagnostic.Logger) MultiHostRegistrar(com.intellij.lang.injection.MultiHostRegistrar) Extensions(com.intellij.openapi.extensions.Extensions) ProgressManager(com.intellij.openapi.progress.ProgressManager) DumbService(com.intellij.openapi.project.DumbService) DocumentWindow(com.intellij.injected.editor.DocumentWindow) ExtensionPoint(com.intellij.openapi.extensions.ExtensionPoint) ExtensionPointListener(com.intellij.openapi.extensions.ExtensionPointListener) DocumentWindowImpl(com.intellij.injected.editor.DocumentWindowImpl) TextRange(com.intellij.openapi.util.TextRange) Disposable(com.intellij.openapi.Disposable) TestOnly(org.jetbrains.annotations.TestOnly) Nullable(org.jetbrains.annotations.Nullable) ProgressIndicator(com.intellij.openapi.progress.ProgressIndicator) ExtensionPointImpl(com.intellij.openapi.extensions.impl.ExtensionPointImpl) ConcurrentList(com.intellij.util.containers.ConcurrentList) PsiDocumentManagerBase(com.intellij.psi.impl.PsiDocumentManagerBase) Processor(com.intellij.util.Processor) Pair(com.intellij.openapi.util.Pair) ApplicationManager(com.intellij.openapi.application.ApplicationManager) DaemonProgressIndicator(com.intellij.codeInsight.daemon.impl.DaemonProgressIndicator) ApplicationManagerEx(com.intellij.openapi.application.ex.ApplicationManagerEx) PluginDescriptor(com.intellij.openapi.extensions.PluginDescriptor) com.intellij.psi(com.intellij.psi) NotNull(org.jetbrains.annotations.NotNull) DaemonProgressIndicator(com.intellij.codeInsight.daemon.impl.DaemonProgressIndicator) DocumentWindow(com.intellij.injected.editor.DocumentWindow) ProgressIndicator(com.intellij.openapi.progress.ProgressIndicator) DaemonProgressIndicator(com.intellij.codeInsight.daemon.impl.DaemonProgressIndicator)

Example 10 with DocumentWindow

use of com.intellij.injected.editor.DocumentWindow in project intellij-community by JetBrains.

the class CodeFormatterFacade method doProcessRange.

private ASTNode doProcessRange(final ASTNode element, final int startOffset, final int endOffset, @Nullable RangeMarker rangeMarker) {
    final PsiElement psiElement = SourceTreeToPsiMap.treeElementToPsi(element);
    assert psiElement != null;
    final PsiFile file = psiElement.getContainingFile();
    final Document document = file.getViewProvider().getDocument();
    PsiElement elementToFormat = document instanceof DocumentWindow ? InjectedLanguageManager.getInstance(file.getProject()).getTopLevelFile(file) : psiElement;
    final PsiFile fileToFormat = elementToFormat.getContainingFile();
    final FormattingModelBuilder builder = LanguageFormatting.INSTANCE.forContext(fileToFormat);
    if (builder != null) {
        if (rangeMarker == null && document != null && endOffset < document.getTextLength()) {
            rangeMarker = document.createRangeMarker(startOffset, endOffset);
        }
        TextRange range = preprocess(element, TextRange.create(startOffset, endOffset));
        if (document instanceof DocumentWindow) {
            DocumentWindow documentWindow = (DocumentWindow) document;
            range = documentWindow.injectedToHost(range);
        }
        //final SmartPsiElementPointer pointer = SmartPointerManager.getInstance(psiElement.getProject()).createSmartPsiElementPointer(psiElement);
        final FormattingModel model = CoreFormatterUtil.buildModel(builder, elementToFormat, mySettings, FormattingMode.REFORMAT);
        if (file.getTextLength() > 0) {
            try {
                FormatterEx.getInstanceEx().format(model, mySettings, mySettings.getIndentOptionsByFile(fileToFormat, range), new FormatTextRanges(range, true));
                wrapLongLinesIfNecessary(file, document, startOffset, endOffset);
            } catch (IncorrectOperationException e) {
                LOG.error(e);
            }
        }
        if (!psiElement.isValid()) {
            if (rangeMarker != null) {
                final PsiElement at = file.findElementAt(rangeMarker.getStartOffset());
                final PsiElement result = PsiTreeUtil.getParentOfType(at, psiElement.getClass(), false);
                assert result != null;
                rangeMarker.dispose();
                return result.getNode();
            } else {
                assert false;
            }
        }
    //      return SourceTreeToPsiMap.psiElementToTree(pointer.getElement());
    }
    if (rangeMarker != null) {
        rangeMarker.dispose();
    }
    return element;
}
Also used : DocumentWindow(com.intellij.injected.editor.DocumentWindow) DocumentBasedFormattingModel(com.intellij.psi.formatter.DocumentBasedFormattingModel) TextRange(com.intellij.openapi.util.TextRange) IncorrectOperationException(com.intellij.util.IncorrectOperationException)

Aggregations

DocumentWindow (com.intellij.injected.editor.DocumentWindow)42 TextRange (com.intellij.openapi.util.TextRange)18 Document (com.intellij.openapi.editor.Document)17 NotNull (org.jetbrains.annotations.NotNull)11 Nullable (org.jetbrains.annotations.Nullable)9 Project (com.intellij.openapi.project.Project)8 VirtualFileWindow (com.intellij.injected.editor.VirtualFileWindow)6 VirtualFile (com.intellij.openapi.vfs.VirtualFile)6 PsiFile (com.intellij.psi.PsiFile)6 InjectedLanguageManager (com.intellij.lang.injection.InjectedLanguageManager)5 DocumentWindowImpl (com.intellij.injected.editor.DocumentWindowImpl)4 Language (com.intellij.lang.Language)4 Editor (com.intellij.openapi.editor.Editor)4 Segment (com.intellij.openapi.util.Segment)4 PsiFileImpl (com.intellij.psi.impl.source.PsiFileImpl)4 DaemonProgressIndicator (com.intellij.codeInsight.daemon.impl.DaemonProgressIndicator)3 ASTNode (com.intellij.lang.ASTNode)3 com.intellij.psi (com.intellij.psi)3 PsiElement (com.intellij.psi.PsiElement)3 PsiDocumentManagerBase (com.intellij.psi.impl.PsiDocumentManagerBase)3