use of com.intellij.openapi.util.text.CharFilter in project intellij-community by JetBrains.
the class CopyPasteIndentProcessor method processTransferableData.
@Override
public void processTransferableData(final Project project, final Editor editor, final RangeMarker bounds, final int caretOffset, final Ref<Boolean> indented, final List<IndentTransferableData> values) {
if (!CodeInsightSettings.getInstance().INDENT_TO_CARET_ON_PASTE) {
return;
}
assert values.size() == 1;
if (values.get(0).getOffset() == caretOffset)
return;
final Document document = editor.getDocument();
final PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(document);
if (psiFile == null || !acceptFileType(psiFile.getFileType())) {
return;
}
//System.out.println("--- before indent ---\n" + document.getText());
ApplicationManager.getApplication().runWriteAction(new Runnable() {
@Override
public void run() {
final boolean useTabs = CodeStyleSettingsManager.getSettings(project).useTabCharacter(psiFile.getFileType());
CharFilter NOT_INDENT_FILTER = new CharFilter() {
@Override
public boolean accept(char ch) {
return useTabs ? ch != '\t' : ch != ' ';
}
};
String pastedText = document.getText(TextRange.create(bounds));
int startLine = document.getLineNumber(bounds.getStartOffset());
int endLine = document.getLineNumber(bounds.getEndOffset());
//calculate from indent
int fromIndent = StringUtil.findFirst(pastedText, NOT_INDENT_FILTER);
if (fromIndent < 0)
fromIndent = 0;
//calculate to indent
String initialText = document.getText(TextRange.create(0, bounds.getStartOffset())) + document.getText(TextRange.create(bounds.getEndOffset(), document.getTextLength()));
int toIndent = 0;
if (initialText.length() > 0) {
final DocumentImpl initialDocument = new DocumentImpl(initialText);
int lineNumber = initialDocument.getTextLength() > caretOffset ? initialDocument.getLineNumber(caretOffset) : initialDocument.getLineCount() - 1;
final int offset = getLineStartSafeOffset(initialDocument, lineNumber);
if (bounds.getStartOffset() == offset) {
String toString = initialDocument.getText(TextRange.create(offset, initialDocument.getLineEndOffset(lineNumber)));
toIndent = StringUtil.findFirst(toString, NOT_INDENT_FILTER);
if (toIndent < 0 && StringUtil.isEmptyOrSpaces(toString)) {
toIndent = toString.length();
} else if ((toIndent < 0 || toString.startsWith("\n")) && initialText.length() >= caretOffset) {
toIndent = caretOffset - offset;
}
} else if (isNotApplicable(initialDocument, offset))
return;
else {
// selection
startLine += 1;
toIndent = Math.abs(bounds.getStartOffset() - offset);
}
}
// actual difference in indentation level
int indent = toIndent - fromIndent;
if (// indent is counted in tab units
useTabs)
indent *= CodeStyleSettingsManager.getSettings(project).getTabSize(psiFile.getFileType());
// don't indent single-line text
if (!StringUtil.startsWithWhitespace(pastedText) && !StringUtil.endsWithLineBreak(pastedText) && !(StringUtil.splitByLines(pastedText).length > 1))
return;
if (pastedText.endsWith("\n"))
endLine -= 1;
for (int i = startLine; i <= endLine; i++) {
EditorActionUtil.indentLine(project, editor, i, indent);
}
indented.set(Boolean.TRUE);
}
private boolean isNotApplicable(DocumentImpl initialDocument, int offset) {
return caretOffset < initialDocument.getTextLength() && !StringUtil.isEmptyOrSpaces(initialDocument.getText(TextRange.create(offset, caretOffset)));
}
});
//System.out.println("--- after indent ---\n" + document.getText());
}
Aggregations