mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
PY-22422 Properly unblock/commit document in PyTrailingBlankLinesPostFormatProcessor
Also, avoid unnecessary premature postprocessing in the PSI file, acquire document only when it's really needed. Simplify calculation of the result range when reformat is called on a text fragment.
This commit is contained in:
+18
-47
@@ -55,7 +55,6 @@ public class PyTrailingBlankLinesPostFormatProcessor implements PostFormatProces
|
||||
public PsiElement processElement(@NotNull PsiElement source, @NotNull CodeStyleSettings settings) {
|
||||
final PsiFile psiFile = source.getContainingFile();
|
||||
if (isApplicableTo(psiFile)) {
|
||||
applyPendingChangesToPsi(source);
|
||||
final TextRange whitespaceRange = findTrailingWhitespacesRange(psiFile);
|
||||
if (source.getTextRange().intersects(whitespaceRange)) {
|
||||
replaceOrDeleteTrailingWhitespaces(psiFile, whitespaceRange);
|
||||
@@ -70,38 +69,14 @@ public class PyTrailingBlankLinesPostFormatProcessor implements PostFormatProces
|
||||
if (!isApplicableTo(source)) {
|
||||
return rangeToReformat;
|
||||
}
|
||||
applyPendingChangesToPsi(source);
|
||||
final TextRange oldWhitespaceRange = findTrailingWhitespacesRange(source);
|
||||
if (rangeToReformat.intersects(oldWhitespaceRange)) {
|
||||
final TextRange newWhitespaceRange = replaceOrDeleteTrailingWhitespaces(source, oldWhitespaceRange);
|
||||
final int delta = newWhitespaceRange.getLength() - oldWhitespaceRange.getLength();
|
||||
if (oldWhitespaceRange.contains(rangeToReformat)) {
|
||||
return newWhitespaceRange;
|
||||
}
|
||||
else if (rangeToReformat.contains(oldWhitespaceRange)) {
|
||||
return rangeToReformat.grown(delta);
|
||||
}
|
||||
else if (oldWhitespaceRange.getEndOffset() > rangeToReformat.getEndOffset()) {
|
||||
return new TextRange(rangeToReformat.getStartOffset(),
|
||||
Math.min(rangeToReformat.getEndOffset(), newWhitespaceRange.getEndOffset()));
|
||||
}
|
||||
else if (oldWhitespaceRange.getStartOffset() < rangeToReformat.getStartOffset()) {
|
||||
final int unionLength = rangeToReformat.getEndOffset() - oldWhitespaceRange.getStartOffset();
|
||||
return TextRange.from(Math.max(oldWhitespaceRange.getStartOffset(), rangeToReformat.getStartOffset() + delta),
|
||||
Math.min(rangeToReformat.getLength(), unionLength + delta));
|
||||
}
|
||||
return rangeToReformat.grown(oldWhitespaceRange.getLength() - newWhitespaceRange.getLength());
|
||||
}
|
||||
return rangeToReformat;
|
||||
}
|
||||
|
||||
private static void applyPendingChangesToPsi(@NotNull PsiElement source) {
|
||||
final PsiDocumentManager documentManager = PsiDocumentManager.getInstance(source.getContainingFile().getProject());
|
||||
final Document document = documentManager.getDocument(source.getContainingFile());
|
||||
if (document != null) {
|
||||
documentManager.doPostponedOperationsAndUnblockDocument(document);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static TextRange findTrailingWhitespacesRange(@NotNull PsiFile file) {
|
||||
final CharSequence contents = file.getViewProvider().getContents();
|
||||
@@ -120,29 +95,25 @@ public class PyTrailingBlankLinesPostFormatProcessor implements PostFormatProces
|
||||
@NotNull
|
||||
private static TextRange replaceOrDeleteTrailingWhitespaces(@NotNull final PsiFile pyFile, @NotNull final TextRange whitespaceRange) {
|
||||
final Project project = pyFile.getProject();
|
||||
final PsiDocumentManager documentManager = PsiDocumentManager.getInstance(project);
|
||||
final Document document = documentManager.getDocument(pyFile);
|
||||
if (document != null) {
|
||||
final PyCodeStyleSettings customSettings = CodeStyleSettingsManager.getSettings(project).getCustomSettings(PyCodeStyleSettings.class);
|
||||
final boolean addLineFeed = customSettings.BLANK_LINE_AT_FILE_END || EditorSettingsExternalizable.getInstance().isEnsureNewLineAtEOF();
|
||||
try {
|
||||
final String text = addLineFeed ? "\n" : "";
|
||||
// Do not add extra blank line in empty file
|
||||
if (!text.isEmpty() && whitespaceRange.getStartOffset() != 0) {
|
||||
if (!whitespaceRange.isEmpty()) {
|
||||
document.replaceString(whitespaceRange.getStartOffset(), whitespaceRange.getEndOffset(), text);
|
||||
}
|
||||
else {
|
||||
document.insertString(document.getTextLength(), text);
|
||||
}
|
||||
final PyCodeStyleSettings customSettings = CodeStyleSettingsManager.getSettings(project).getCustomSettings(PyCodeStyleSettings.class);
|
||||
final boolean addLineFeed = customSettings.BLANK_LINE_AT_FILE_END || EditorSettingsExternalizable.getInstance().isEnsureNewLineAtEOF();
|
||||
|
||||
final String realWhitespace = whitespaceRange.substring(pyFile.getText());
|
||||
final String desiredWhitespace = addLineFeed ? "\n" : "";
|
||||
|
||||
// Do not add extra blank line in empty file
|
||||
if (!realWhitespace.equals(desiredWhitespace) && (desiredWhitespace.isEmpty() || whitespaceRange.getStartOffset() != 0)) {
|
||||
final PsiDocumentManager documentManager = PsiDocumentManager.getInstance(project);
|
||||
final Document document = documentManager.getDocument(pyFile);
|
||||
if (document != null) {
|
||||
documentManager.doPostponedOperationsAndUnblockDocument(document);
|
||||
try {
|
||||
document.replaceString(whitespaceRange.getStartOffset(), whitespaceRange.getEndOffset(), desiredWhitespace);
|
||||
return TextRange.from(whitespaceRange.getStartOffset(), desiredWhitespace.length());
|
||||
}
|
||||
else if (!whitespaceRange.isEmpty()) {
|
||||
document.deleteString(whitespaceRange.getStartOffset(), whitespaceRange.getEndOffset());
|
||||
finally {
|
||||
documentManager.commitDocument(document);
|
||||
}
|
||||
return TextRange.from(whitespaceRange.getStartOffset(), text.length());
|
||||
}
|
||||
finally {
|
||||
documentManager.commitDocument(document);
|
||||
}
|
||||
}
|
||||
return whitespaceRange;
|
||||
|
||||
Reference in New Issue
Block a user