diff --git a/java/java-tests/testData/psi/formatter/java/FormatterOnOffTags.java b/java/java-tests/testData/psi/formatter/java/FormatterOnOffTags.java
new file mode 100644
index 000000000000..319b8eb82514
--- /dev/null
+++ b/java/java-tests/testData/psi/formatter/java/FormatterOnOffTags.java
@@ -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() + " ");
+ }
+ }
+}
diff --git a/java/java-tests/testData/psi/formatter/java/FormatterOnOffTagsWithRegexp.java b/java/java-tests/testData/psi/formatter/java/FormatterOnOffTagsWithRegexp.java
new file mode 100644
index 000000000000..2aefb59715b1
--- /dev/null
+++ b/java/java-tests/testData/psi/formatter/java/FormatterOnOffTagsWithRegexp.java
@@ -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() + " ");
+ }
+ }
+}
diff --git a/java/java-tests/testData/psi/formatter/java/FormatterOnOffTagsWithRegexp_after.java b/java/java-tests/testData/psi/formatter/java/FormatterOnOffTagsWithRegexp_after.java
new file mode 100644
index 000000000000..5290700e34f9
--- /dev/null
+++ b/java/java-tests/testData/psi/formatter/java/FormatterOnOffTagsWithRegexp_after.java
@@ -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() + " ");
+ }
+ }
+}
diff --git a/java/java-tests/testData/psi/formatter/java/FormatterOnOffTags_after.java b/java/java-tests/testData/psi/formatter/java/FormatterOnOffTags_after.java
new file mode 100644
index 000000000000..8e1abcb09d02
--- /dev/null
+++ b/java/java-tests/testData/psi/formatter/java/FormatterOnOffTags_after.java
@@ -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() + " ");
+ }
+ }
+}
diff --git a/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterTest.java b/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterTest.java
index 68dbf094a3da..4cedbc31e52f 100644
--- a/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterTest.java
+++ b/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterTest.java
@@ -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();
+ }
}
diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/CodeStyleSettings.java b/platform/lang-api/src/com/intellij/psi/codeStyle/CodeStyleSettings.java
index 836f5fcd2ae0..4300898ea57e 100644
--- a/platform/lang-api/src/com/intellij/psi/codeStyle/CodeStyleSettings.java
+++ b/platform/lang-api/src/com/intellij/psi/codeStyle/CodeStyleSettings.java
@@ -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;
diff --git a/platform/lang-impl/src/com/intellij/application/options/GeneralCodeStylePanel.form b/platform/lang-impl/src/com/intellij/application/options/GeneralCodeStylePanel.form
index 19e7f5241e3e..72d2e4e399f7 100644
--- a/platform/lang-impl/src/com/intellij/application/options/GeneralCodeStylePanel.form
+++ b/platform/lang-impl/src/com/intellij/application/options/GeneralCodeStylePanel.form
@@ -7,7 +7,7 @@
-
+
@@ -57,7 +57,7 @@
-
+
@@ -71,6 +71,67 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/platform/lang-impl/src/com/intellij/application/options/GeneralCodeStylePanel.java b/platform/lang-impl/src/com/intellij/application/options/GeneralCodeStylePanel.java
index 99692cd054eb..c434c670823d 100644
--- a/platform/lang-impl/src/com/intellij/application/options/GeneralCodeStylePanel.java
+++ b/platform/lang-impl/src/com/intellij/application/options/GeneralCodeStylePanel.java
@@ -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);
+ }
}
diff --git a/platform/lang-impl/src/com/intellij/formatting/FormatProcessor.java b/platform/lang-impl/src/com/intellij/formatting/FormatProcessor.java
index 4f8034a59384..28658229b472 100644
--- a/platform/lang-impl/src/com/intellij/formatting/FormatProcessor.java
+++ b/platform/lang-impl/src/com/intellij/formatting/FormatProcessor.java
@@ -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
);
}
diff --git a/platform/lang-impl/src/com/intellij/formatting/InitialInfoBuilder.java b/platform/lang-impl/src/com/intellij/formatting/InitialInfoBuilder.java
index 7274c79421aa..51ffbb977e78 100644
--- a/platform/lang-impl/src/com/intellij/formatting/InitialInfoBuilder.java
+++ b/platform/lang-impl/src/com/intellij/formatting/InitialInfoBuilder.java
@@ -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 myStates = new Stack();
+ 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.
diff --git a/platform/platform-resources-en/src/messages/ApplicationBundle.properties b/platform/platform-resources-en/src/messages/ApplicationBundle.properties
index ecf970302280..bee939b62427 100644
--- a/platform/platform-resources-en/src/messages/ApplicationBundle.properties
+++ b/platform/platform-resources-en/src/messages/ApplicationBundle.properties
@@ -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
\ No newline at end of file
+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
\ No newline at end of file