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;
}
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);
}
Aggregations