Search in sources :

Example 1 with PerlHeredocOpener

use of com.perl5.lang.perl.psi.PerlHeredocOpener in project Perl5-IDEA by Camelcade.

the class PerlEnterHeredocClosingHandler method postProcessEnter.

@Override
public Result postProcessEnter(@NotNull PsiFile file, @NotNull Editor editor, @NotNull DataContext dataContext) {
    if (!file.getLanguage().is(PerlLanguage.INSTANCE)) {
        return Result.Continue;
    }
    final CaretModel caretModel = editor.getCaretModel();
    int offset = caretModel.getOffset();
    PsiElement currentElement = file.findElementAt(offset);
    if (currentElement != null && (!(currentElement.getParent() instanceof PerlHeredocElementImpl) || !Perl5CodeInsightSettings.getInstance().HEREDOC_AUTO_INSERTION)) {
        return Result.Continue;
    }
    LogicalPosition currentPosition = caretModel.getLogicalPosition();
    final int enterLine = currentPosition.line - 1;
    final int currentOffset = caretModel.getOffset();
    if (enterLine <= -1 || currentOffset <= 0) {
        return Result.Continue;
    }
    final Document document = editor.getDocument();
    final PsiDocumentManager manager = PsiDocumentManager.getInstance(file.getProject());
    manager.commitDocument(document);
    final int lineStartOffset = document.getLineStartOffset(enterLine);
    PsiElement firstLineElement = file.findElementAt(lineStartOffset);
    if (firstLineElement == null) {
        return Result.Continue;
    }
    HeredocCollector collector = new HeredocCollector(currentOffset - 1);
    PerlPsiUtil.iteratePsiElementsRight(firstLineElement, collector);
    SmartPsiElementPointer<PerlHeredocOpener> lastOpenerPointer = null;
    for (SmartPsiElementPointer<PerlHeredocOpener> currentOpenerPointer : collector.getResult()) {
        PerlHeredocOpener currentOpener = currentOpenerPointer.getElement();
        if (currentOpener == null) {
            // System.err.println("Opener invalidated on reparse");
            return Result.Continue;
        }
        String openerName = currentOpener.getName();
        boolean emptyOpener = StringUtil.isEmpty(openerName);
        PsiReference inboundReference = ReferencesSearch.search(currentOpener).findFirst();
        if (inboundReference != null) {
            boolean falseAlarm = false;
            PsiElement run = inboundReference.getElement().getPrevSibling();
            while (run instanceof PsiWhiteSpace) {
                run = run.getPrevSibling();
            }
            if (run instanceof PerlHeredocElementImpl) {
                Pattern openerPattern = EMPTY_OPENER_PATTERN;
                if (!emptyOpener) {
                    openerPattern = Pattern.compile("<<~?(\\s*)(?:" + "\"" + openerName + "\"" + "|" + "`" + openerName + "`" + "|" + "'" + openerName + "'" + "|" + "\\\\" + openerName + "|" + openerName + ")");
                }
                falseAlarm = openerPattern.matcher(run.getNode().getChars()).find();
            }
            if (// looks like overlapping heredocs
            falseAlarm) {
                inboundReference = null;
            } else {
                lastOpenerPointer = currentOpenerPointer;
            }
        }
        if (// disclosed marker
        inboundReference == null) {
            int addOffset;
            String closeMarker = "\n" + openerName + "\n";
            if (// first one
            lastOpenerPointer == null) {
                addOffset = currentOffset;
            } else // sequentional
            {
                PerlHeredocOpener lastOpener = lastOpenerPointer.getElement();
                if (lastOpener == null) {
                    return Result.Continue;
                }
                PsiReference lastOpenerReference = ReferencesSearch.search(lastOpener).findFirst();
                if (lastOpenerReference != null) {
                    PsiElement element = lastOpenerReference.getElement();
                    addOffset = element.getTextRange().getEndOffset();
                    if (!emptyOpener) {
                        closeMarker = "\n" + closeMarker;
                    }
                } else {
                    return Result.Continue;
                }
            }
            document.insertString(addOffset, closeMarker);
            manager.commitDocument(document);
            CodeStyleManager.getInstance(file.getProject()).reformatRange(file, addOffset, addOffset + closeMarker.length());
            currentOpener = currentOpenerPointer.getElement();
            if (currentOpener == null) {
                return Result.Continue;
            }
            inboundReference = ReferencesSearch.search(currentOpener).findFirst();
            if (inboundReference != null) {
                lastOpenerPointer = currentOpenerPointer;
            } else {
                return Result.Continue;
            }
        }
    }
    return Result.Continue;
}
Also used : LogicalPosition(com.intellij.openapi.editor.LogicalPosition) Pattern(java.util.regex.Pattern) CaretModel(com.intellij.openapi.editor.CaretModel) PerlHeredocOpener(com.perl5.lang.perl.psi.PerlHeredocOpener) Document(com.intellij.openapi.editor.Document) PerlHeredocElementImpl(com.perl5.lang.perl.psi.impl.PerlHeredocElementImpl)

Example 2 with PerlHeredocOpener

use of com.perl5.lang.perl.psi.PerlHeredocOpener in project Perl5-IDEA by Camelcade.

the class PerlDocUtil method getPerlOpDoc.

@Nullable
public static PsiElement getPerlOpDoc(@NotNull PsiElement element) {
    final Project project = element.getProject();
    String text = element.getText();
    String redirect = myOperatorsRedirections.get(text);
    if (redirect != null) {
        return resolveDocLink(redirect, element);
    }
    // fixme use map?
    PodDocumentPattern pattern = PodDocumentPattern.indexPattern(text);
    if (element instanceof PerlHeredocOpener || element instanceof PerlHeredocTerminatorElement || element instanceof PerlHeredocElementImpl) {
        // searches with X<>
        pattern.setIndexKey("heredoc");
    } else if (text.matches("-[rwxoRWXOeszfdlpSbctugkTBMAC]")) {
        pattern.setIndexKey("-X");
    } else if ("?".equals(text) || ":".equals(text)) {
        pattern.setIndexKey("?:");
    }
    return searchPodElementInFile(project, PodSearchHelper.PERL_OP_FILE_NAME, pattern);
}
Also used : PerlHeredocTerminatorElement(com.perl5.lang.perl.psi.PerlHeredocTerminatorElement) Project(com.intellij.openapi.project.Project) PerlHeredocOpener(com.perl5.lang.perl.psi.PerlHeredocOpener) PerlHeredocElementImpl(com.perl5.lang.perl.psi.impl.PerlHeredocElementImpl) Nullable(org.jetbrains.annotations.Nullable)

Aggregations

PerlHeredocOpener (com.perl5.lang.perl.psi.PerlHeredocOpener)2 PerlHeredocElementImpl (com.perl5.lang.perl.psi.impl.PerlHeredocElementImpl)2 CaretModel (com.intellij.openapi.editor.CaretModel)1 Document (com.intellij.openapi.editor.Document)1 LogicalPosition (com.intellij.openapi.editor.LogicalPosition)1 Project (com.intellij.openapi.project.Project)1 PerlHeredocTerminatorElement (com.perl5.lang.perl.psi.PerlHeredocTerminatorElement)1 Pattern (java.util.regex.Pattern)1 Nullable (org.jetbrains.annotations.Nullable)1