public void produceChangedParts(List<LineExtensionInfo> result) { if (isArray(actual) && isArray(old)) { List<String> actualParts = getArrayParts(actual); List<String> oldParts = getArrayParts(old); result.add(new LineExtensionInfo("{", getNormalAttributes())); for (int i = 0; i < actualParts.size(); i++) { if (i < oldParts.size() && StringUtil.equals(actualParts.get(i), oldParts.get(i))) { result.add(new LineExtensionInfo(actualParts.get(i), getNormalAttributes())); } else { result.add(new LineExtensionInfo(actualParts.get(i), getChangedAttributes())); } if (i != actualParts.size() - 1) { result.add(new LineExtensionInfo(", ", getNormalAttributes())); } } result.add(new LineExtensionInfo("}", getNormalAttributes())); return; } result.add(new LineExtensionInfo(actual, getChangedAttributes())); }
private @Nullable PsiElement addExtensions(@NotNull List<LineExtensionInfo> res, @NotNull PsiElement element) { SchemaValueTypeRef valueTypeRef = PsiTreeUtil.getParentOfType(element, SchemaValueTypeRef.class); if (valueTypeRef == null) return PsiTreeUtil.nextVisibleLeaf(element); if (valueTypeRef.getRetroDecl() == null) { SchemaEntityTagDecl defaultTag = TypeMembers.getEffectiveRetro(valueTypeRef); if (defaultTag != null) { String defaultTagName = defaultTag.getQid().getText(); String defaultTagTypeName = getDefaultTagTypeName(defaultTag); String typeAux = defaultTagTypeName == null ? "" : " (" + defaultTagTypeName + ")"; String extension = " default " + defaultTagName + typeAux; res.add(new LineExtensionInfo(extension, getNormalAttributes())); } } return PsiTreeUtil.nextVisibleLeaf(valueTypeRef); }
private void validateMaxLineWithExtension() { if (myMaxLineWithExtensionWidth > 0) { Project project = myEditor.getProject(); VirtualFile virtualFile = myEditor.getVirtualFile(); if (project != null && virtualFile != null) { for (EditorLinePainter painter : EditorLinePainter.EP_NAME.getExtensions()) { Collection<LineExtensionInfo> extensions = painter.getLineExtensions(project, virtualFile, myWidestLineWithExtension); if (extensions != null && !extensions.isEmpty()) { return; } } } myMaxLineWithExtensionWidth = 0; } }
@Override public Collection<LineExtensionInfo> getLineExtensions(@NotNull Project project, @NotNull VirtualFile file, int lineNumber) { List<LineExtensionInfo> res = ContainerUtil.newSmartList(); PsiDocumentManager psiDocumentManager = PsiDocumentManager.getInstance(project); final Document doc = FileDocumentManager.getInstance().getDocument(file); if (doc != null && lineNumber < doc.getLineCount()) { PsiFile psiFile = psiDocumentManager.getPsiFile(doc); if (psiFile != null) { int offset = doc.getLineStartOffset(lineNumber); FileViewProvider viewProvider = psiFile.getViewProvider(); PsiElement element = viewProvider.findElementAt(offset); while (element != null) { int startOffset = element.getTextRange().getStartOffset(); if (startOffset >= doc.getTextLength()) break; int startOffsetLine = doc.getLineNumber(startOffset); if (startOffsetLine < lineNumber) { element = PsiTreeUtil.nextVisibleLeaf(element); continue; } if (startOffsetLine > lineNumber) break; try { element = addExtensions(res, element); } catch (IndexNotReadyException ignored) { element = null; } } } } return res; }
@Override public Collection<LineExtensionInfo> getLineExtensions(@NotNull Project project, @NotNull VirtualFile file, int lineNumber) { final Document document = FileDocumentManager.getInstance().getDocument(file); if (document == null) { return null; } Editor selectedTextEditor = FileEditorManager.getInstance(project).getSelectedTextEditor(); if (selectedTextEditor == null) { return null; } PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(document); LineNumbering lineNumbering = new LineNumbering(document.getCharsSequence()); Collection<PsiLet> letStatements = PsiTreeUtil.findChildrenOfType(psiFile, PsiLet.class); String inferredType = null; for (PsiLet letStatement : letStatements) { int letOffset = letStatement.getTextOffset(); // TODO: I'm using the LineNumbering class to avoid frequent exceptions about read access, // but I would prefer to use runReadAction method. MerlinPosition letPosition = lineNumbering.offsetToPosition(letOffset); // LogicalPosition letPosition = new LogicalPosition; // letPosition[0] = selectedTextEditor.offsetToLogicalPosition(letOffset); if (letPosition.line - 1 == lineNumber) { inferredType = letStatement.getInferredType(); break; } } /* Function<PsiLet, String> findInferredType = letStatement -> { // Found a let statement, try to get its type if in correct line number final int[] letOffset = new int[]{-1}; // ApplicationManager.getApplication().runReadAction(() -> { // Freezing pb ? letOffset[0] = letStatement.getTextOffset(); // }); // TODO: I'm using the LineNumbering class to avoid frequent exceptions about read access, // but I would prefer to use runReadAction method. MerlinPosition letPosition = lineNumbering.offsetToPosition(letOffset[0]); // LogicalPosition letPosition = new LogicalPosition; // ApplicationManager.getApplication().runReadAction(() -> { // letPosition[0] = selectedTextEditor.offsetToLogicalPosition(letOffset); // }); return letPosition.line - 1 == lineNumber ? letStatement.getInferredType() : null; }; String inferredType; inferredType = letStatements.parallelStream().map(findInferredType).filter(Objects::nonNull).findFirst().orElse(null); */ if (inferredType == null) { return null; } final TextAttributes attributes = getNormalAttributes(); LineExtensionInfo info = new LineExtensionInfo(" " + inferredType, attributes); return Collections.singletonList(info); }
void add(LineExtensionInfo info) { infos.add(info); length += info.getText().length(); }