mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEA-56995 Disable code formatting per region using comments
This commit is contained in:
@@ -0,0 +1,25 @@
|
||||
import java.util.*;
|
||||
|
||||
public class CollectionTest {
|
||||
public static void main(String[] args) {
|
||||
int size;
|
||||
HashSet collection = new HashSet();
|
||||
// @formatter:off
|
||||
String str1 = "Yellow",
|
||||
str2 = "White",
|
||||
str3 = "Green",
|
||||
str4 = "Blue";
|
||||
// @formatter:on
|
||||
Iterator iterator;
|
||||
// @formatter:off
|
||||
collection.add(str1);
|
||||
collection.add(str2);
|
||||
collection.add(str3);
|
||||
// @formatter:on
|
||||
collection.add(str4);
|
||||
iterator = collection.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
System.out.print(iterator.next() + " ");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
import java.util.*;
|
||||
|
||||
public class CollectionTest {
|
||||
public static void main(String[] args) {
|
||||
int size;
|
||||
HashSet collection = new HashSet();
|
||||
// The following fragement must not be formatteed
|
||||
String str1 = "Yellow",
|
||||
str2 = "White",
|
||||
str3 = "Green",
|
||||
str4 = "Blue";
|
||||
// end of fragment
|
||||
Iterator iterator;
|
||||
// do not format the following:
|
||||
collection.add( str1 );
|
||||
collection.add( str2 );
|
||||
collection.add( str3 );
|
||||
// end of fragment
|
||||
collection.add(str4);
|
||||
iterator = collection.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
System.out.print(iterator.next() + " ");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
import java.util.*;
|
||||
|
||||
public class CollectionTest {
|
||||
public static void main(String[] args) {
|
||||
int size;
|
||||
HashSet collection = new HashSet();
|
||||
// The following fragement must not be formatteed
|
||||
String str1 = "Yellow",
|
||||
str2 = "White",
|
||||
str3 = "Green",
|
||||
str4 = "Blue";
|
||||
// end of fragment
|
||||
Iterator iterator;
|
||||
// do not format the following:
|
||||
collection.add( str1 );
|
||||
collection.add( str2 );
|
||||
collection.add( str3 );
|
||||
// end of fragment
|
||||
collection.add(str4);
|
||||
iterator = collection.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
System.out.print(iterator.next() + " ");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
import java.util.*;
|
||||
|
||||
public class CollectionTest {
|
||||
public static void main(String[] args) {
|
||||
int size;
|
||||
HashSet collection = new HashSet();
|
||||
// @formatter:off
|
||||
String str1 = "Yellow",
|
||||
str2 = "White",
|
||||
str3 = "Green",
|
||||
str4 = "Blue";
|
||||
// @formatter:on
|
||||
Iterator iterator;
|
||||
// @formatter:off
|
||||
collection.add(str1);
|
||||
collection.add(str2);
|
||||
collection.add(str3);
|
||||
// @formatter:on
|
||||
collection.add(str4);
|
||||
iterator = collection.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
System.out.print(iterator.next() + " ");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3001,4 +3001,18 @@ public void testSCR260() throws Exception {
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void testFormatterOnOffTags() throws Exception {
|
||||
getSettings().getRootSettings().FORMATTER_TAGS_ENABLED = true;
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testFormatterOnOffTagsWithRegexp() throws Exception {
|
||||
CodeStyleSettings settings = getSettings().getRootSettings();
|
||||
settings.FORMATTER_TAGS_ENABLED = true;
|
||||
settings.FORMATTER_TAGS_ACCEPT_REGEXP = true;
|
||||
settings.FORMATTER_OFF_TAG = "not.*format";
|
||||
settings.FORMATTER_ON_TAG = "end.*fragment";
|
||||
doTest();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,6 +36,8 @@ import org.jetbrains.annotations.TestOnly;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.util.*;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.regex.PatternSyntaxException;
|
||||
|
||||
public class CodeStyleSettings extends CommonCodeStyleSettings implements Cloneable, JDOMExternalizable {
|
||||
|
||||
@@ -372,6 +374,55 @@ public class CodeStyleSettings extends CommonCodeStyleSettings implements Clonea
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
||||
// region Formatter control
|
||||
|
||||
public boolean FORMATTER_TAGS_ENABLED = false;
|
||||
public String FORMATTER_ON_TAG = "@formatter:on";
|
||||
public String FORMATTER_OFF_TAG = "@formatter:off";
|
||||
|
||||
public volatile boolean FORMATTER_TAGS_ACCEPT_REGEXP = false;
|
||||
private volatile Pattern myFormatterOffPattern = null;
|
||||
private volatile Pattern myFormatterOnPattern = null;
|
||||
|
||||
@Nullable
|
||||
public Pattern getFormatterOffPattern() {
|
||||
if (myFormatterOffPattern == null && FORMATTER_TAGS_ENABLED && FORMATTER_TAGS_ACCEPT_REGEXP) {
|
||||
myFormatterOffPattern = getPatternOrDisableRegexp(FORMATTER_OFF_TAG);
|
||||
}
|
||||
return myFormatterOffPattern;
|
||||
}
|
||||
|
||||
public void setFormatterOffPattern(@Nullable Pattern formatterOffPattern) {
|
||||
myFormatterOffPattern = formatterOffPattern;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Pattern getFormatterOnPattern() {
|
||||
if (myFormatterOffPattern == null && FORMATTER_TAGS_ENABLED && FORMATTER_TAGS_ACCEPT_REGEXP) {
|
||||
myFormatterOnPattern = getPatternOrDisableRegexp(FORMATTER_ON_TAG);
|
||||
}
|
||||
return myFormatterOnPattern;
|
||||
}
|
||||
|
||||
public void setFormatterOnPattern(@Nullable Pattern formatterOnPattern) {
|
||||
myFormatterOnPattern = formatterOnPattern;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private Pattern getPatternOrDisableRegexp(@NotNull String markerText) {
|
||||
try {
|
||||
return Pattern.compile(markerText);
|
||||
}
|
||||
catch (PatternSyntaxException pse) {
|
||||
LOG.error("Loaded regexp pattern is invalid: '" + markerText + "', error message: " + pse.getMessage());
|
||||
FORMATTER_TAGS_ACCEPT_REGEXP = false;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// endregion
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
||||
private CodeStyleSettings myParentSettings;
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<properties/>
|
||||
<border type="none"/>
|
||||
<children>
|
||||
<grid id="6a116" layout-manager="GridLayoutManager" row-count="5" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<grid id="6a116" layout-manager="GridLayoutManager" row-count="6" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<constraints border-constraint="West"/>
|
||||
<properties/>
|
||||
@@ -57,7 +57,7 @@
|
||||
</component>
|
||||
<vspacer id="f290d">
|
||||
<constraints>
|
||||
<grid row="4" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
|
||||
<grid row="5" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
</vspacer>
|
||||
<grid id="2586a" binding="myDefaultIndentOptionsPanel" layout-manager="BorderLayout" hgap="0" vgap="0">
|
||||
@@ -71,6 +71,67 @@
|
||||
<border type="none" title="Default Indent Options"/>
|
||||
<children/>
|
||||
</grid>
|
||||
<grid id="f6e61" layout-manager="GridLayoutManager" row-count="4" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<constraints>
|
||||
<grid row="4" column="0" row-span="1" col-span="2" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<clientProperties>
|
||||
<BorderFactoryClass class="java.lang.String" value="com.intellij.ui.IdeBorderFactory$PlainSmallWithIndent"/>
|
||||
</clientProperties>
|
||||
<border type="none" title-resource-bundle="messages/ApplicationBundle" title-key="settings.code.style.general.formatter.control"/>
|
||||
<children>
|
||||
<component id="1afd0" class="com.intellij.ui.components.JBLabel">
|
||||
<constraints>
|
||||
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text resource-bundle="messages/ApplicationBundle" key="settings.code.style.general.formatter.off.tag"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="a4d" class="javax.swing.JTextField" binding="myFormatterOffTagField">
|
||||
<constraints>
|
||||
<grid row="2" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
|
||||
<preferred-size width="150" height="-1"/>
|
||||
</grid>
|
||||
</constraints>
|
||||
<properties/>
|
||||
</component>
|
||||
<component id="66f0a" class="javax.swing.JTextField" binding="myFormatterOnTagField">
|
||||
<constraints>
|
||||
<grid row="3" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
|
||||
<preferred-size width="150" height="-1"/>
|
||||
</grid>
|
||||
</constraints>
|
||||
<properties/>
|
||||
</component>
|
||||
<component id="96c9" class="com.intellij.ui.components.JBLabel">
|
||||
<constraints>
|
||||
<grid row="3" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text resource-bundle="messages/ApplicationBundle" key="settings.code.style.general.formatter.on.tag"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="f7481" class="javax.swing.JCheckBox" binding="myAcceptRegularExpressionsCheckBox">
|
||||
<constraints>
|
||||
<grid row="1" column="0" row-span="1" col-span="2" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text resource-bundle="messages/ApplicationBundle" key="settings.code.style.general.formatter.marker.regexp"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="3b152" class="javax.swing.JCheckBox" binding="myEnableFormatterTags">
|
||||
<constraints>
|
||||
<grid row="0" column="0" row-span="1" col-span="2" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text resource-bundle="messages/ApplicationBundle" key="settings.code.style.general.enable.formatter.tags"/>
|
||||
</properties>
|
||||
</component>
|
||||
</children>
|
||||
</grid>
|
||||
</children>
|
||||
</grid>
|
||||
<hspacer id="b7fa6">
|
||||
|
||||
@@ -26,21 +26,33 @@ import com.intellij.openapi.extensions.Extensions;
|
||||
import com.intellij.openapi.fileTypes.FileType;
|
||||
import com.intellij.openapi.fileTypes.FileTypes;
|
||||
import com.intellij.openapi.fileTypes.LanguageFileType;
|
||||
import com.intellij.openapi.project.ProjectManager;
|
||||
import com.intellij.openapi.ui.MessageType;
|
||||
import com.intellij.openapi.ui.popup.Balloon;
|
||||
import com.intellij.openapi.ui.popup.BalloonBuilder;
|
||||
import com.intellij.openapi.ui.popup.JBPopupFactory;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettings;
|
||||
import com.intellij.psi.codeStyle.DisplayPriority;
|
||||
import com.intellij.psi.codeStyle.FileTypeIndentOptionsProvider;
|
||||
import com.intellij.psi.codeStyle.LanguageCodeStyleSettingsProvider;
|
||||
import com.intellij.ui.awt.RelativePoint;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.regex.PatternSyntaxException;
|
||||
|
||||
public class GeneralCodeStylePanel extends CodeStyleAbstractPanel {
|
||||
@SuppressWarnings("UnusedDeclaration")
|
||||
@@ -57,6 +69,10 @@ public class GeneralCodeStylePanel extends CodeStyleAbstractPanel {
|
||||
private JPanel myPanel;
|
||||
private JCheckBox myCbWrapWhenTypingReachesRightMargin;
|
||||
private JPanel myDefaultIndentOptionsPanel;
|
||||
private JCheckBox myEnableFormatterTags;
|
||||
private JTextField myFormatterOnTagField;
|
||||
private JTextField myFormatterOffTagField;
|
||||
private JCheckBox myAcceptRegularExpressionsCheckBox;
|
||||
private final SmartIndentOptionsEditor myIndentOptionsEditor;
|
||||
|
||||
|
||||
@@ -91,6 +107,16 @@ public class GeneralCodeStylePanel extends CodeStyleAbstractPanel {
|
||||
|
||||
myIndentOptionsEditor = new SmartIndentOptionsEditor();
|
||||
myDefaultIndentOptionsPanel.add(myIndentOptionsEditor.createPanel(), BorderLayout.CENTER);
|
||||
|
||||
myEnableFormatterTags.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
boolean tagsEnabled = myEnableFormatterTags.isSelected();
|
||||
myAcceptRegularExpressionsCheckBox.setEnabled(tagsEnabled);
|
||||
myFormatterOnTagField.setEnabled(tagsEnabled);
|
||||
myFormatterOffTagField.setEnabled(tagsEnabled);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -130,6 +156,36 @@ public class GeneralCodeStylePanel extends CodeStyleAbstractPanel {
|
||||
settings.WRAP_WHEN_TYPING_REACHES_RIGHT_MARGIN = myCbWrapWhenTypingReachesRightMargin.isSelected();
|
||||
myIndentOptionsEditor.setEnabled(true);
|
||||
myIndentOptionsEditor.apply(settings, settings.OTHER_INDENT_OPTIONS);
|
||||
|
||||
settings.FORMATTER_TAGS_ENABLED = myEnableFormatterTags.isSelected();
|
||||
settings.FORMATTER_TAGS_ACCEPT_REGEXP = myAcceptRegularExpressionsCheckBox.isSelected();
|
||||
|
||||
settings.FORMATTER_OFF_TAG = getTagText(myFormatterOffTagField, settings.FORMATTER_OFF_TAG);
|
||||
settings.setFormatterOffPattern(compilePattern(settings, myFormatterOffTagField, settings.FORMATTER_OFF_TAG));
|
||||
|
||||
settings.FORMATTER_ON_TAG = getTagText(myFormatterOnTagField, settings.FORMATTER_ON_TAG);
|
||||
settings.setFormatterOnPattern(compilePattern(settings, myFormatterOnTagField, settings.FORMATTER_ON_TAG));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static Pattern compilePattern(CodeStyleSettings settings, JTextField field, String patternText) {
|
||||
try {
|
||||
return Pattern.compile(patternText);
|
||||
}
|
||||
catch (PatternSyntaxException pse) {
|
||||
settings.FORMATTER_TAGS_ACCEPT_REGEXP = false;
|
||||
showError(field, ApplicationBundle.message("settings.code.style.general.formatter.marker.invalid.regexp"));
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static String getTagText(JTextField field, String defualtValue) {
|
||||
String fieldText = field.getText();
|
||||
if (StringUtil.isEmpty(field.getText())) {
|
||||
field.setText(defualtValue);
|
||||
return defualtValue;
|
||||
}
|
||||
return fieldText;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -159,6 +215,18 @@ public class GeneralCodeStylePanel extends CodeStyleAbstractPanel {
|
||||
|
||||
if (!Comparing.equal(myRightMarginSpinner.getValue(), settings.RIGHT_MARGIN)) return true;
|
||||
myIndentOptionsEditor.setEnabled(true);
|
||||
|
||||
if (myEnableFormatterTags.isSelected()) {
|
||||
if (
|
||||
!settings.FORMATTER_TAGS_ENABLED ||
|
||||
settings.FORMATTER_TAGS_ACCEPT_REGEXP != myAcceptRegularExpressionsCheckBox.isSelected() ||
|
||||
!StringUtil.equals(myFormatterOffTagField.getText(), settings.FORMATTER_OFF_TAG) ||
|
||||
!StringUtil.equals(myFormatterOnTagField.getText(), settings.FORMATTER_ON_TAG)) return true;
|
||||
}
|
||||
else {
|
||||
if (settings.FORMATTER_TAGS_ENABLED) return true;
|
||||
}
|
||||
|
||||
return myIndentOptionsEditor.isModified(settings, settings.OTHER_INDENT_OPTIONS);
|
||||
}
|
||||
|
||||
@@ -188,6 +256,16 @@ public class GeneralCodeStylePanel extends CodeStyleAbstractPanel {
|
||||
myCbWrapWhenTypingReachesRightMargin.setSelected(settings.WRAP_WHEN_TYPING_REACHES_RIGHT_MARGIN);
|
||||
myIndentOptionsEditor.reset(settings, settings.OTHER_INDENT_OPTIONS);
|
||||
myIndentOptionsEditor.setEnabled(true);
|
||||
|
||||
myAcceptRegularExpressionsCheckBox.setSelected(settings.FORMATTER_TAGS_ACCEPT_REGEXP);
|
||||
myAcceptRegularExpressionsCheckBox.setEnabled(settings.FORMATTER_TAGS_ENABLED);
|
||||
myEnableFormatterTags.setSelected(settings.FORMATTER_TAGS_ENABLED);
|
||||
|
||||
myFormatterOnTagField.setText(settings.FORMATTER_ON_TAG);
|
||||
myFormatterOnTagField.setEnabled(settings.FORMATTER_TAGS_ENABLED);
|
||||
|
||||
myFormatterOffTagField.setText(settings.FORMATTER_OFF_TAG);
|
||||
myFormatterOffTagField.setEnabled(settings.FORMATTER_TAGS_ENABLED);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -205,4 +283,16 @@ public class GeneralCodeStylePanel extends CodeStyleAbstractPanel {
|
||||
public Language getDefaultLanguage() {
|
||||
return null;
|
||||
}
|
||||
|
||||
private static void showError(final JTextField field, final String message) {
|
||||
BalloonBuilder balloonBuilder = JBPopupFactory.getInstance()
|
||||
.createHtmlTextBalloonBuilder(message, MessageType.ERROR.getDefaultIcon(), MessageType.ERROR.getPopupBackground(), null);
|
||||
balloonBuilder.setFadeoutTime(1500);
|
||||
final Balloon balloon = balloonBuilder.createBalloon();
|
||||
final Rectangle rect = field.getBounds();
|
||||
final Point p = new Point(0, rect.height);
|
||||
final RelativePoint point = new RelativePoint(field, p);
|
||||
balloon.show(point, Balloon.Position.below);
|
||||
Disposer.register(ProjectManager.getInstance().getDefaultProject(), balloon);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1285,7 +1285,7 @@ class FormatProcessor {
|
||||
super(FormattingStateId.WRAPPING_BLOCKS);
|
||||
myModel = model;
|
||||
myWrapper = InitialInfoBuilder.prepareToBuildBlocksSequentially(
|
||||
root, model, affectedRanges, myDefaultIndentOption, interestingOffset, myProgressCallback
|
||||
root, model, affectedRanges, mySettings, myDefaultIndentOption, interestingOffset, myProgressCallback
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -17,9 +17,14 @@
|
||||
package com.intellij.formatting;
|
||||
|
||||
import com.intellij.diagnostic.LogMessageEx;
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.PsiComment;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettings;
|
||||
import com.intellij.psi.codeStyle.CommonCodeStyleSettings;
|
||||
import com.intellij.psi.formatter.FormattingDocumentModelImpl;
|
||||
import com.intellij.psi.formatter.ReadOnlyBlockInformationProvider;
|
||||
@@ -33,6 +38,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* Allows to build {@link AbstractBlockWrapper formatting block wrappers} for the target {@link Block formatting blocks}.
|
||||
@@ -49,9 +55,12 @@ class InitialInfoBuilder {
|
||||
@NotNull
|
||||
private final FormattingProgressCallback myProgressCallback;
|
||||
private final CommonCodeStyleSettings.IndentOptions myOptions;
|
||||
private final CodeStyleSettings mySettings;
|
||||
|
||||
private final Stack<State> myStates = new Stack<State>();
|
||||
|
||||
private enum FormatterTag {ON, OFF, NONE}
|
||||
|
||||
private WhiteSpace myCurrentWhiteSpace;
|
||||
private CompositeBlockWrapper myRootBlockWrapper;
|
||||
private LeafBlockWrapper myPreviousBlock;
|
||||
@@ -59,11 +68,13 @@ class InitialInfoBuilder {
|
||||
private LeafBlockWrapper myLastTokenBlock;
|
||||
private SpacingImpl myCurrentSpaceProperty;
|
||||
private ReadOnlyBlockInformationProvider myReadOnlyBlockInformationProvider;
|
||||
private boolean myReadOnlyMode;
|
||||
|
||||
private static final boolean INLINE_TABS_ENABLED = "true".equalsIgnoreCase(System.getProperty("inline.tabs.enabled"));
|
||||
|
||||
private InitialInfoBuilder(final FormattingDocumentModel model,
|
||||
@Nullable final FormatTextRanges affectedRanges,
|
||||
@NotNull CodeStyleSettings settings,
|
||||
final CommonCodeStyleSettings.IndentOptions options,
|
||||
final int positionOfInterest,
|
||||
@NotNull FormattingProgressCallback progressCallback)
|
||||
@@ -74,16 +85,19 @@ class InitialInfoBuilder {
|
||||
myCurrentWhiteSpace = new WhiteSpace(0, true);
|
||||
myOptions = options;
|
||||
myPositionOfInterest = positionOfInterest;
|
||||
myReadOnlyMode = false;
|
||||
mySettings = settings;
|
||||
}
|
||||
|
||||
public static InitialInfoBuilder prepareToBuildBlocksSequentially(Block root,
|
||||
FormattingDocumentModel model,
|
||||
@Nullable final FormatTextRanges affectedRanges,
|
||||
@NotNull CodeStyleSettings settings,
|
||||
final CommonCodeStyleSettings.IndentOptions options,
|
||||
int interestingOffset,
|
||||
@NotNull FormattingProgressCallback progressCallback)
|
||||
{
|
||||
InitialInfoBuilder builder = new InitialInfoBuilder(model, affectedRanges, options, interestingOffset, progressCallback);
|
||||
InitialInfoBuilder builder = new InitialInfoBuilder(model, affectedRanges, settings, options, interestingOffset, progressCallback);
|
||||
builder.buildFrom(root, 0, null, null, null, true);
|
||||
return builder;
|
||||
}
|
||||
@@ -283,6 +297,17 @@ class InitialInfoBuilder {
|
||||
info.arrangeParentTextRange();
|
||||
}
|
||||
|
||||
switch (getFormatterTag(rootBlock)) {
|
||||
case ON:
|
||||
myReadOnlyMode = false;
|
||||
break;
|
||||
case OFF:
|
||||
myReadOnlyMode = true;
|
||||
break;
|
||||
case NONE:
|
||||
break;
|
||||
}
|
||||
|
||||
TextRange textRange = rootBlock.getTextRange();
|
||||
if (textRange.getLength() == 0) {
|
||||
assertInvalidRanges(
|
||||
@@ -309,6 +334,7 @@ class InitialInfoBuilder {
|
||||
|
||||
info.setSpaceProperty(myCurrentSpaceProperty);
|
||||
myCurrentWhiteSpace = new WhiteSpace(textRange.getEndOffset(), false);
|
||||
if (myReadOnlyMode) myCurrentWhiteSpace.setReadOnly(true);
|
||||
myPreviousBlock = info;
|
||||
|
||||
if (myPositionOfInterest != -1 && (textRange.contains(myPositionOfInterest) || textRange.getEndOffset() == myPositionOfInterest)) {
|
||||
@@ -390,6 +416,42 @@ class InitialInfoBuilder {
|
||||
LogMessageEx.error(LOG, messageBuffer.toString(), buffer.toString());
|
||||
}
|
||||
|
||||
private FormatterTag getFormatterTag(Block block) {
|
||||
if (mySettings.FORMATTER_TAGS_ENABLED &&
|
||||
!StringUtil.isEmpty(mySettings.FORMATTER_ON_TAG) &&
|
||||
!StringUtil.isEmpty(mySettings.FORMATTER_OFF_TAG) &&
|
||||
block instanceof ASTBlock) {
|
||||
ASTNode node = ((ASTBlock)block).getNode();
|
||||
PsiElement element = node.getPsi();
|
||||
if (element != null && element instanceof PsiComment) {
|
||||
CharSequence nodeChars = node.getChars();
|
||||
if (mySettings.FORMATTER_TAGS_ACCEPT_REGEXP) {
|
||||
Pattern onPattern = mySettings.getFormatterOnPattern();
|
||||
Pattern offPattern = mySettings.getFormatterOffPattern();
|
||||
if (onPattern != null && onPattern.matcher(nodeChars).find()) return FormatterTag.ON;
|
||||
if (offPattern != null && offPattern.matcher(nodeChars).find()) return FormatterTag.OFF;
|
||||
}
|
||||
else {
|
||||
for (int i = 0; i < nodeChars.length(); i++) {
|
||||
if (isFormatterTagAt(nodeChars, i, mySettings.FORMATTER_ON_TAG)) return FormatterTag.ON;
|
||||
if (isFormatterTagAt(nodeChars, i, mySettings.FORMATTER_OFF_TAG)) return FormatterTag.OFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return FormatterTag.NONE;
|
||||
}
|
||||
|
||||
private static boolean isFormatterTagAt(@NotNull CharSequence s, int pos, @NotNull String tagName) {
|
||||
if (!tagName.isEmpty() && tagName.charAt(0) == s.charAt(pos)) {
|
||||
int end = pos + tagName.length();
|
||||
if (end <= s.length()) {
|
||||
return StringUtil.equalsIgnoreCase(s.subSequence(pos, end), tagName);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* We want to wrap {@link Block code blocks} sequentially, hence, need to store a processing state and continue from the point
|
||||
* where we stopped the processing last time.
|
||||
|
||||
@@ -607,4 +607,10 @@ arrangement.settings.text.entry.type.xml.tag=tag
|
||||
arrangement.settings.text.entry.type.xml.attribute=attribute
|
||||
|
||||
checkbox.spaces.around.lambda.arrow=Lambda arrow
|
||||
checkbox.spaces.around.method.ref.dbl.colon.arrow=Method reference double colon
|
||||
checkbox.spaces.around.method.ref.dbl.colon.arrow=Method reference double colon
|
||||
settings.code.style.general.formatter.control=Formatter Control
|
||||
settings.code.style.general.enable.formatter.tags=Enable formatter markers in comments
|
||||
settings.code.style.general.formatter.off.tag="Formatter off" marker\:
|
||||
settings.code.style.general.formatter.on.tag="Formatter on" marker\:
|
||||
settings.code.style.general.formatter.marker.regexp=Accept regular expressions
|
||||
settings.code.style.general.formatter.marker.invalid.regexp=Invalid regular expression
|
||||
Reference in New Issue
Block a user