use of com.intellij.openapi.util.TextRange in project intellij-community by JetBrains.
the class VariableInlineHandler method invoke.
public static void invoke(@NotNull final XPathVariable variable, Editor editor) {
final String type = LanguageFindUsages.INSTANCE.forLanguage(variable.getLanguage()).getType(variable);
final Project project = variable.getProject();
final XmlTag tag = ((XsltElement) variable).getTag();
final String expression = tag.getAttributeValue("select");
if (expression == null) {
CommonRefactoringUtil.showErrorHint(project, editor, MessageFormat.format("{0} ''{1}'' has no value.", StringUtil.capitalize(type), variable.getName()), TITLE, null);
return;
}
final Collection<PsiReference> references = ReferencesSearch.search(variable, new LocalSearchScope(tag.getParentTag()), false).findAll();
if (references.size() == 0) {
CommonRefactoringUtil.showErrorHint(project, editor, MessageFormat.format("{0} ''{1}'' is never used.", variable.getName()), TITLE, null);
return;
}
boolean hasExternalRefs = false;
if (XsltSupport.isTopLevelElement(tag)) {
final Query<PsiReference> query = ReferencesSearch.search(variable, GlobalSearchScope.allScope(project), false);
hasExternalRefs = !query.forEach(new Processor<PsiReference>() {
int allRefs = 0;
public boolean process(PsiReference psiReference) {
if (++allRefs > references.size()) {
return false;
} else if (!references.contains(psiReference)) {
return false;
}
return true;
}
});
}
final HighlightManager highlighter = HighlightManager.getInstance(project);
final ArrayList<RangeHighlighter> highlighters = new ArrayList<>();
final PsiReference[] psiReferences = references.toArray(new PsiReference[references.size()]);
TextRange[] ranges = ContainerUtil.map2Array(psiReferences, TextRange.class, s -> {
final PsiElement psiElement = s.getElement();
final XmlAttributeValue context = PsiTreeUtil.getContextOfType(psiElement, XmlAttributeValue.class, true);
if (psiElement instanceof XPathElement && context != null) {
return XsltCodeInsightUtil.getRangeInsideHostingFile((XPathElement) psiElement).cutOut(s.getRangeInElement());
}
return psiElement.getTextRange().cutOut(s.getRangeInElement());
});
final Editor e = editor instanceof EditorWindow ? ((EditorWindow) editor).getDelegate() : editor;
for (TextRange range : ranges) {
final TextAttributes textAttributes = EditorColors.SEARCH_RESULT_ATTRIBUTES.getDefaultAttributes();
final Color color = getScrollmarkColor(textAttributes);
highlighter.addOccurrenceHighlight(e, range.getStartOffset(), range.getEndOffset(), textAttributes, HighlightManagerImpl.HIDE_BY_ESCAPE, highlighters, color);
}
highlighter.addOccurrenceHighlights(e, new PsiElement[] { ((XsltVariable) variable).getNameIdentifier() }, EditorColors.WRITE_SEARCH_RESULT_ATTRIBUTES.getDefaultAttributes(), false, highlighters);
if (!hasExternalRefs) {
if (!ApplicationManager.getApplication().isUnitTestMode() && Messages.showYesNoDialog(MessageFormat.format("Inline {0} ''{1}''? ({2} occurrence{3})", type, variable.getName(), String.valueOf(references.size()), references.size() > 1 ? "s" : ""), TITLE, Messages.getQuestionIcon()) != Messages.YES) {
return;
}
} else {
if (!ApplicationManager.getApplication().isUnitTestMode() && Messages.showYesNoDialog(MessageFormat.format("Inline {0} ''{1}''? ({2} local occurrence{3})\n" + "\nWarning: It is being used in external files. Its declaration will not be removed.", type, variable.getName(), String.valueOf(references.size()), references.size() > 1 ? "s" : ""), TITLE, Messages.getWarningIcon()) != Messages.YES) {
return;
}
}
final boolean hasRefs = hasExternalRefs;
new WriteCommandAction.Simple(project, "XSLT.Inline", tag.getContainingFile()) {
@Override
protected void run() throws Throwable {
try {
for (PsiReference psiReference : references) {
final PsiElement element = psiReference.getElement();
if (element instanceof XPathElement) {
final XPathElement newExpr = XPathChangeUtil.createExpression(element, expression);
element.replace(newExpr);
} else {
assert false;
}
}
if (!hasRefs) {
tag.delete();
}
} catch (IncorrectOperationException e) {
Logger.getInstance(VariableInlineHandler.class.getName()).error(e);
}
}
}.execute();
}
use of com.intellij.openapi.util.TextRange in project intellij-community by JetBrains.
the class XPathLanguageInjector method getLanguagesToInject.
public void getLanguagesToInject(@NotNull MultiHostRegistrar registrar, @NotNull PsiElement context) {
final XmlAttribute attribute = (XmlAttribute) context;
if (!XsltSupport.isXPathAttribute(attribute))
return;
XmlAttributeValueImpl value = (XmlAttributeValueImpl) attribute.getValueElement();
if (value == null)
return;
ASTNode type = value.findChildByType(XmlElementType.XML_ENTITY_REF);
// workaround for inability to inject into text with entity refs (e.g. IDEA-72972) TODO: fix it
if (type != null)
return;
final XsltChecker.LanguageLevel languageLevel = XsltSupport.getXsltLanguageLevel(attribute.getContainingFile());
final TextRange[] ranges = getInjectionRanges(attribute, languageLevel);
for (TextRange range : ranges) {
// workaround for http://www.jetbrains.net/jira/browse/IDEA-10096
TextRange rangeInsideHost;
String prefix;
if (range instanceof AVTRange) {
if (((AVTRange) range).myComplete) {
rangeInsideHost = range.shiftRight(2).grown(-2);
prefix = "";
} else {
// we need to keep the "'}' expected" parse error
rangeInsideHost = range.shiftRight(2).grown(-1);
prefix = "{";
}
} else {
rangeInsideHost = range;
prefix = "";
}
if (value.getTextRange().contains(rangeInsideHost.shiftRight(value.getTextRange().getStartOffset()))) {
registrar.startInjecting(languageLevel.getXPathVersion().getLanguage()).addPlace(prefix, "", value, rangeInsideHost).doneInjecting();
}
}
}
use of com.intellij.openapi.util.TextRange in project intellij-community by JetBrains.
the class PyStatementMover method getSelectionLenContainer.
private static SelectionContainer getSelectionLenContainer(@NotNull final Editor editor, @NotNull final MyLineRange toMove) {
final SelectionModel selectionModel = editor.getSelectionModel();
final PsiElement startToMove = toMove.myStartElement;
final PsiElement endToMove = toMove.myEndElement;
final int selectionStart = selectionModel.getSelectionStart();
final int selectionEnd = selectionModel.getSelectionEnd();
final TextRange range = startToMove.getTextRange();
final int column = editor.offsetToLogicalPosition(selectionStart).column;
final int additionalSelection = range.getStartOffset() > selectionStart ? range.getStartOffset() - selectionStart : 0;
if (startToMove == endToMove)
return new SelectionContainer(selectionEnd - range.getStartOffset(), additionalSelection, column == 0);
int len = range.getStartOffset() <= selectionStart ? range.getEndOffset() - selectionStart : startToMove.getTextLength();
PsiElement tmp = startToMove.getNextSibling();
while (tmp != endToMove && tmp != null) {
if (!(tmp instanceof PsiWhiteSpace))
len += tmp.getTextLength();
tmp = tmp.getNextSibling();
}
len = len + selectionEnd - endToMove.getTextOffset();
return new SelectionContainer(len, additionalSelection, column == 0);
}
use of com.intellij.openapi.util.TextRange in project intellij-community by JetBrains.
the class PyStatementMover method adjustLineIndents.
private static void adjustLineIndents(@NotNull final Editor editor, @NotNull final PsiElement scope, @NotNull final Project project, @NotNull final PsiElement addedElement, int size) {
final CodeStyleManager codeStyleManager = CodeStyleManager.getInstance(project);
final Document document = editor.getDocument();
if (!(scope instanceof PsiFile)) {
int line1 = editor.offsetToLogicalPosition(scope.getTextRange().getStartOffset()).line;
int line2 = editor.offsetToLogicalPosition(scope.getTextRange().getEndOffset()).line;
codeStyleManager.adjustLineIndent(scope.getContainingFile(), new TextRange(document.getLineStartOffset(line1), document.getLineEndOffset(line2)));
} else {
int line1 = editor.offsetToLogicalPosition(addedElement.getTextRange().getStartOffset()).line;
PsiElement end = addedElement;
while (size > 0) {
PsiElement tmp = end.getNextSibling();
if (tmp == null)
break;
size -= 1;
end = tmp;
}
int endOffset = end.getTextRange().getEndOffset();
int line2 = editor.offsetToLogicalPosition(endOffset).line;
codeStyleManager.adjustLineIndent(scope.getContainingFile(), new TextRange(document.getLineStartOffset(line1), document.getLineEndOffset(line2)));
}
}
use of com.intellij.openapi.util.TextRange in project intellij-community by JetBrains.
the class PyCodeBlockProvider method getCodeBlockRange.
@Nullable
@Override
public TextRange getCodeBlockRange(Editor editor, PsiFile psiFile) {
int caretOffset = editor.getCaretModel().getOffset();
PsiElement element = psiFile.findElementAt(caretOffset);
if (element == null) {
return null;
}
while (caretOffset > 0 && element instanceof PsiWhiteSpace) {
caretOffset--;
element = psiFile.findElementAt(caretOffset);
}
PyStatement statement = PsiTreeUtil.getParentOfType(element, PyStatement.class);
if (statement != null) {
PyStatementList statementList = PsiTreeUtil.findChildOfType(statement, PyStatementList.class);
// that statement list
if (statementList == null) {
statementList = PsiTreeUtil.getParentOfType(statement, PyStatementList.class);
if (statementList != null) {
statement = PsiTreeUtil.getParentOfType(statementList, PyStatement.class);
}
}
if (statement != null) {
// if we're in the beginning of the statement already, pressing Ctrl-[ again should move the caret one statement higher
final int statementStart = statement.getTextRange().getStartOffset();
int statementEnd = statement.getTextRange().getEndOffset();
while (statementEnd > statementStart && psiFile.findElementAt(statementEnd) instanceof PsiWhiteSpace) {
statementEnd--;
}
if (caretOffset == statementStart || caretOffset == statementEnd) {
final PyStatement statementAbove = PsiTreeUtil.getParentOfType(statement, PyStatement.class);
if (statementAbove != null) {
if (caretOffset == statementStart) {
return new TextRange(statementAbove.getTextRange().getStartOffset(), statementEnd);
} else {
return new TextRange(statementStart, statementAbove.getTextRange().getEndOffset());
}
}
}
return statement.getTextRange();
}
}
return null;
}
Aggregations