From bc2adf7359ad1aa1a763bf1c2fff0fe88e559268 Mon Sep 17 00:00:00 2001 From: Ivan Donchevskii Date: Thu, 19 Dec 2019 10:52:58 +0100 Subject: [PATCH] IDEA-CR-56782: CPP-18466: Do not remove emty or new lines when formatting completions Code completions are often not complete code chunks which requires to format them considering the need to keep empty and new lines. GitOrigin-RevId: 8b6d1a23aed3e5bf86416b2055101af4d1b414e2 --- .../psi/codeStyle/CodeStyleManager.java | 10 +++++++ .../codeStyle/ExternalFormatProcessor.java | 14 ++++++---- .../codeStyle/CodeStyleManagerImpl.java | 27 +++++++++++++++---- .../actions/MockCodeStyleManager.java | 17 ++++++++++++ .../sh/formatter/ShExternalFormatter.java | 2 +- .../sh/formatter/ShPostFormatProcessor.java | 2 +- 6 files changed, 60 insertions(+), 12 deletions(-) diff --git a/platform/core-api/src/com/intellij/psi/codeStyle/CodeStyleManager.java b/platform/core-api/src/com/intellij/psi/codeStyle/CodeStyleManager.java index 48bc8e98ec51..26d31ee99bc2 100644 --- a/platform/core-api/src/com/intellij/psi/codeStyle/CodeStyleManager.java +++ b/platform/core-api/src/com/intellij/psi/codeStyle/CodeStyleManager.java @@ -84,6 +84,10 @@ public abstract class CodeStyleManager { */ @NotNull public abstract PsiElement reformat(@NotNull PsiElement element, boolean canChangeWhiteSpacesOnly) throws IncorrectOperationException; + @NotNull + public abstract PsiElement reformat(@NotNull PsiElement element, boolean canChangeWhiteSpacesOnly, boolean keepLineBreaks) + throws IncorrectOperationException; + /** * Reformats part of the contents of the specified PSI element, enforces braces * and splits import statements according to the user's code style. @@ -117,6 +121,12 @@ public abstract class CodeStyleManager { int endOffset, boolean canChangeWhiteSpacesOnly) throws IncorrectOperationException; + public abstract PsiElement reformatRange(@NotNull PsiElement element, + int startOffset, + int endOffset, + boolean canChangeWhiteSpacesOnly, + boolean keepLineBreaks) throws IncorrectOperationException; + /** * Delegates to the {@link #reformatText(PsiFile, Collection)} with the single range defined by the given offsets. * diff --git a/platform/lang-impl/src/com/intellij/psi/codeStyle/ExternalFormatProcessor.java b/platform/lang-impl/src/com/intellij/psi/codeStyle/ExternalFormatProcessor.java index f80f1592c767..209dc08dc586 100644 --- a/platform/lang-impl/src/com/intellij/psi/codeStyle/ExternalFormatProcessor.java +++ b/platform/lang-impl/src/com/intellij/psi/codeStyle/ExternalFormatProcessor.java @@ -35,7 +35,7 @@ public interface ExternalFormatProcessor { * @return the range after formatting or null, if external format procedure cannot be applied to the source */ @Nullable - TextRange format(@NotNull PsiFile source, @NotNull TextRange range, boolean canChangeWhiteSpacesOnly); + TextRange format(@NotNull PsiFile source, @NotNull TextRange range, boolean canChangeWhiteSpacesOnly, boolean keepLineBreaks); /** * Indents the line. @@ -96,9 +96,12 @@ public interface ExternalFormatProcessor { * @return the range after formatting or null, if external format procedure was not found or inactive (disabled) */ @Nullable - static TextRange formatRangeInFile(@NotNull PsiFile source, @NotNull TextRange range, boolean canChangeWhiteSpacesOnly) { + static TextRange formatRangeInFile(@NotNull PsiFile source, + @NotNull TextRange range, + boolean canChangeWhiteSpacesOnly, + boolean keepLineBreaks) { ExternalFormatProcessor efp = activeExternalFormatProcessor(source); - return efp != null ? efp.format(source, range, canChangeWhiteSpacesOnly) : null; + return efp != null ? efp.format(source, range, canChangeWhiteSpacesOnly, keepLineBreaks) : null; } /** @@ -110,11 +113,12 @@ public interface ExternalFormatProcessor { @NotNull static PsiElement formatElement(@NotNull PsiElement elementToFormat, @NotNull TextRange range, - boolean canChangeWhiteSpacesOnly) { + boolean canChangeWhiteSpacesOnly, + boolean keepLineBreaks) { final PsiFile file = elementToFormat.getContainingFile(); final Document document = file.getViewProvider().getDocument(); if (document != null) { - final TextRange rangeAfterFormat = formatRangeInFile(file, range, canChangeWhiteSpacesOnly); + final TextRange rangeAfterFormat = formatRangeInFile(file, range, canChangeWhiteSpacesOnly, keepLineBreaks); if (rangeAfterFormat != null) { PsiDocumentManager.getInstance(file.getProject()).commitDocument(document); if (!elementToFormat.isValid()) { diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeStyleManagerImpl.java b/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeStyleManagerImpl.java index fe35e31e02e6..21d2f2fdf68a 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeStyleManagerImpl.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeStyleManagerImpl.java @@ -73,6 +73,13 @@ public class CodeStyleManagerImpl extends CodeStyleManager implements Formatting @Override @NotNull public PsiElement reformat(@NotNull PsiElement element, boolean canChangeWhiteSpacesOnly) throws IncorrectOperationException { + return reformat(element, canChangeWhiteSpacesOnly, false); + } + + @Override + @NotNull + public PsiElement reformat(@NotNull PsiElement element, boolean canChangeWhiteSpacesOnly, boolean keepLineBreaks) + throws IncorrectOperationException { CheckUtil.checkWritable(element); if( !SourceTreeToPsiMap.hasTreeElement( element ) ) { @@ -82,7 +89,7 @@ public class CodeStyleManagerImpl extends CodeStyleManager implements Formatting ASTNode treeElement = element.getNode(); final PsiFile file = element.getContainingFile(); if (ExternalFormatProcessor.useExternalFormatter(file)) { - return ExternalFormatProcessor.formatElement(element, element.getTextRange(), canChangeWhiteSpacesOnly); + return ExternalFormatProcessor.formatElement(element, element.getTextRange(), canChangeWhiteSpacesOnly, keepLineBreaks); } final PsiElement formatted = @@ -128,18 +135,27 @@ public class CodeStyleManagerImpl extends CodeStyleManager implements Formatting } } + @Override + public PsiElement reformatRange(@NotNull PsiElement element, + int startOffset, + int endOffset, + boolean canChangeWhiteSpacesOnly, + boolean keepLineBreaks) throws IncorrectOperationException { + return reformatRangeImpl(element, startOffset, endOffset, canChangeWhiteSpacesOnly, keepLineBreaks); + } + @Override public PsiElement reformatRange(@NotNull PsiElement element, int startOffset, int endOffset, boolean canChangeWhiteSpacesOnly) throws IncorrectOperationException { - return reformatRangeImpl(element, startOffset, endOffset, canChangeWhiteSpacesOnly); + return reformatRangeImpl(element, startOffset, endOffset, canChangeWhiteSpacesOnly, false); } @Override public PsiElement reformatRange(@NotNull PsiElement element, int startOffset, int endOffset) throws IncorrectOperationException { - return reformatRangeImpl(element, startOffset, endOffset, false); + return reformatRangeImpl(element, startOffset, endOffset, false, false); } @@ -284,7 +300,8 @@ public class CodeStyleManagerImpl extends CodeStyleManager implements Formatting private static PsiElement reformatRangeImpl(final @NotNull PsiElement element, final int startOffset, final int endOffset, - boolean canChangeWhiteSpacesOnly) throws IncorrectOperationException { + boolean canChangeWhiteSpacesOnly, + boolean keepLineBreaks) throws IncorrectOperationException { LOG.assertTrue(element.isValid()); CheckUtil.checkWritable(element); if( !SourceTreeToPsiMap.hasTreeElement( element ) ) @@ -295,7 +312,7 @@ public class CodeStyleManagerImpl extends CodeStyleManager implements Formatting ASTNode treeElement = element.getNode(); final PsiFile file = element.getContainingFile(); if (ExternalFormatProcessor.useExternalFormatter(file)) { - return ExternalFormatProcessor.formatElement(element, TextRange.create(startOffset, endOffset), canChangeWhiteSpacesOnly); + return ExternalFormatProcessor.formatElement(element, TextRange.create(startOffset, endOffset), canChangeWhiteSpacesOnly, keepLineBreaks); } final CodeFormatterFacade codeFormatter = new CodeFormatterFacade(getSettings(file), element.getLanguage()); diff --git a/platform/platform-tests/testSrc/com/intellij/codeInsight/actions/MockCodeStyleManager.java b/platform/platform-tests/testSrc/com/intellij/codeInsight/actions/MockCodeStyleManager.java index f32382f7a9f7..36bd2005adcb 100644 --- a/platform/platform-tests/testSrc/com/intellij/codeInsight/actions/MockCodeStyleManager.java +++ b/platform/platform-tests/testSrc/com/intellij/codeInsight/actions/MockCodeStyleManager.java @@ -86,6 +86,13 @@ public class MockCodeStyleManager extends CodeStyleManager { return reformat(element); } + @NotNull + @Override + public PsiElement reformat(@NotNull PsiElement element, boolean canChangeWhiteSpacesOnly, boolean keepLineBreaks) + throws IncorrectOperationException { + return reformat(element); + } + @Override public PsiElement reformatRange(@NotNull PsiElement element, int startOffset, int endOffset) throws IncorrectOperationException { reformatText(element.getContainingFile(), startOffset, endOffset); @@ -99,6 +106,16 @@ public class MockCodeStyleManager extends CodeStyleManager { return element; } + @Override + public PsiElement reformatRange(@NotNull PsiElement element, + int startOffset, + int endOffset, + boolean canChangeWhiteSpacesOnly, + boolean keepLineBreaks) throws IncorrectOperationException { + reformatText(element.getContainingFile(), startOffset, endOffset); + return element; + } + @Override public void reformatText(@NotNull PsiFile file, int startOffset, int endOffset) throws IncorrectOperationException { reformatText(file, Collections.singletonList(new TextRange(startOffset, endOffset))); diff --git a/plugins/sh/src/com/intellij/sh/formatter/ShExternalFormatter.java b/plugins/sh/src/com/intellij/sh/formatter/ShExternalFormatter.java index b696d2ec015e..fb0706595c5a 100644 --- a/plugins/sh/src/com/intellij/sh/formatter/ShExternalFormatter.java +++ b/plugins/sh/src/com/intellij/sh/formatter/ShExternalFormatter.java @@ -53,7 +53,7 @@ public class ShExternalFormatter implements ExternalFormatProcessor { @Nullable @Override - public TextRange format(@NotNull PsiFile source, @NotNull TextRange range, boolean canChangeWhiteSpacesOnly) { + public TextRange format(@NotNull PsiFile source, @NotNull TextRange range, boolean canChangeWhiteSpacesOnly, boolean keepLineBreaks) { doFormat(source.getProject(), source.getVirtualFile()); return range; } diff --git a/plugins/sh/src/com/intellij/sh/formatter/ShPostFormatProcessor.java b/plugins/sh/src/com/intellij/sh/formatter/ShPostFormatProcessor.java index f5e5fd4d095b..647eea2f91bc 100644 --- a/plugins/sh/src/com/intellij/sh/formatter/ShPostFormatProcessor.java +++ b/plugins/sh/src/com/intellij/sh/formatter/ShPostFormatProcessor.java @@ -21,7 +21,7 @@ final class ShPostFormatProcessor implements PostFormatProcessor { @Override public TextRange processText(@NotNull PsiFile source, @NotNull TextRange rangeToReformat, @NotNull CodeStyleSettings settings) { if (!(source instanceof ShFile)) return rangeToReformat; - TextRange range = ExternalFormatProcessor.formatRangeInFile(source, rangeToReformat, false); + TextRange range = ExternalFormatProcessor.formatRangeInFile(source, rangeToReformat, false, false); return range != null ? range : rangeToReformat; } }