Refactor-simplify EditorCustomization & EditorFeature structure

* Merge EditorFeatures to EditorCustomizations, and remove the first.
  Motivation: EditorCustomization and EditorFeature serve the same
  purpose and thus introduce unnecessary duplication.

* Remove EditorCustomization extension point, since all customizations
  can be achieved via EditorTextFieldProvider#getEditorField.

* Let EditorCustomization be an interface.
  Extend on/off EditorCustomizations from SimpleEditorCustomization
  and provide ENABLED/DISABLED static instances to avoid creation
  of custom objects each time.

* This change introduces dependencies in vcs-impl and git4idea to
  the spellchecker module.
This commit is contained in:
Kirill Likhodedov
2013-02-14 19:04:52 +04:00
parent dc80819ac8
commit 1d93cacfc3
22 changed files with 160 additions and 200 deletions
@@ -22,7 +22,6 @@ import com.intellij.openapi.editor.EditorSettings;
import com.intellij.openapi.editor.actionSystem.EditorAction;
import com.intellij.openapi.editor.actions.TextComponentEditorAction;
import com.intellij.openapi.editor.ex.EditorEx;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.NotNull;
@@ -73,25 +72,18 @@ public class EditorTextFieldProviderImpl implements EditorTextFieldProvider {
@NotNull
@Override
public EditorTextField getEditorField(@NotNull Language language,
@NotNull Project project,
@NotNull final Iterable<EditorFeature> features) {
return new MyEditorTextField(language, project) {
@Override
protected void applyFeatures(@NotNull EditorCustomization[] customizations, @NotNull EditorEx editor) {
for (EditorFeature feature : features) {
for (EditorCustomization customization : customizations) {
customization.doProcessCustomization(editor, feature);
}
}
}
};
public EditorTextField getEditorField(@NotNull Language language, @NotNull Project project,
@NotNull final Iterable<EditorCustomization> features) {
return new MyEditorTextField(language, project, features);
}
private abstract static class MyEditorTextField extends LanguageTextField {
private static class MyEditorTextField extends LanguageTextField {
MyEditorTextField(Language language, @NotNull Project project) {
@NotNull private final Iterable<EditorCustomization> myCustomizations;
MyEditorTextField(@NotNull Language language, @NotNull Project project, @NotNull Iterable<EditorCustomization> customizations) {
super(language, project, "", false);
myCustomizations = customizations;
}
@Override
@@ -102,12 +94,15 @@ public class EditorTextFieldProviderImpl implements EditorTextFieldProvider {
EditorSettings settings = ex.getSettings();
settings.setAdditionalColumnsCount(3);
settings.setVirtualSpace(false);
EditorCustomization[] customizations = Extensions.getExtensions(EditorCustomization.EP_NAME, getProject());
applyFeatures(customizations, ex);
applyFeatures(ex);
return ex;
}
protected abstract void applyFeatures(@NotNull EditorCustomization[] customizations, @NotNull EditorEx editor);
private void applyFeatures(@NotNull EditorEx editor) {
for (EditorCustomization customization : myCustomizations) {
customization.customize(editor);
}
}
@Override
protected boolean isOneLineMode() {
@@ -22,15 +22,17 @@ import org.jetbrains.annotations.NotNull;
* @author Denis Zhdanov
* @since 1/21/11 4:06 PM
*/
public class AdditionalPageAtBottomEditorCustomization extends EditorCustomization {
public class AdditionalPageAtBottomEditorCustomization extends SimpleEditorCustomization {
@Override
protected Class<? extends EditorFeature> getFeatureClass() {
return AdditionalPageAtBottomEditorFeature.class;
public static final AdditionalPageAtBottomEditorCustomization ENABLED = new AdditionalPageAtBottomEditorCustomization(true);
public static final AdditionalPageAtBottomEditorCustomization DISABLED = new AdditionalPageAtBottomEditorCustomization(false);
private AdditionalPageAtBottomEditorCustomization(boolean enabled) {
super(enabled);
}
@Override
protected void customize(@NotNull EditorEx editor, @NotNull EditorFeature feature) {
editor.getSettings().setAdditionalPageAtBottom(feature.isEnabled());
public void customize(@NotNull EditorEx editor) {
editor.getSettings().setAdditionalPageAtBottom(isEnabled());
}
}
@@ -1,7 +0,0 @@
package com.intellij.ui;
public class AdditionalPageAtBottomEditorFeature extends EditorFeature {
public AdditionalPageAtBottomEditorFeature(boolean enabled) {
super(enabled);
}
}
@@ -15,55 +15,28 @@
*/
package com.intellij.ui;
import com.intellij.lang.Language;
import com.intellij.openapi.editor.ex.EditorEx;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.NotNull;
/**
* Defines contract for functionality that is able to customize editors.
* <p/>
* It's assumed that it works in terms of {@link EditorFeature features} that can be applied to editors, i.e. every
* customization implementation is assumed to have a corresponding {@link EditorFeature} implementation which
* enables/disables it and potentially provides some configuration. This indirection allows us to have customizer
* extensions provided by other modules (see {@link SpellCheckingEditorFeature} for example)
* Such customizations can be then passed to {@link EditorTextFieldProvider#getEditorField(Language, Project, Iterable)} to get editor
* with all necessary features applied or disabled.
*
* @author Denis Zhdanov
* @since Aug 20, 2010 4:26:04 PM
*/
public abstract class EditorCustomization {
public static ExtensionPointName<EditorCustomization> EP_NAME = ExtensionPointName.create("com.intellij.editorCustomization");
public interface EditorCustomization {
/**
* Apply the given feature to the given editor.
*
* Validates the given {@link EditorFeature} configures this customization, and hence can safely be
* called on all {@link EditorCustomization} extension points for any {@link EditorFeature}
* Applies this customization to the given editor.
* Subclasses should apply their customizations to the editor in this method.
*
* @param editor The editor to customize
* @param feature The feature configuration
*/
public void doProcessCustomization(@NotNull EditorEx editor, @NotNull EditorFeature feature) {
if (!getFeatureClass().isAssignableFrom(feature.getClass())) {
return;
}
void customize(@NotNull EditorEx editor);
customize(editor, feature);
}
/**
* All subclass must declare an {@link EditorFeature} class which configures them.
*
* @return The {@link EditorFeature} class which corresponds to this {@link EditorCustomization}
*/
protected abstract Class<? extends EditorFeature> getFeatureClass();
/**
* Subclasses should apply their customizations in this method. Parameter "feature" is
* guaranteed by {@link #doProcessCustomization} to match the type returned by {@link #getFeatureClass}
*
* @param editor The editor to customize
* @param feature The feature configuration
*/
protected abstract void customize(@NotNull EditorEx editor, @NotNull EditorFeature feature);
}
@@ -1,16 +0,0 @@
package com.intellij.ui;
/**
* Base class for editor feature configurations used by {@link EditorCustomization}
*/
public abstract class EditorFeature {
private boolean myEnabled;
public EditorFeature(boolean enabled) {
myEnabled = enabled;
}
public boolean isEnabled() {
return myEnabled;
}
}
@@ -28,16 +28,13 @@ import org.jetbrains.annotations.NotNull;
public interface EditorTextFieldProvider {
/**
* This factory method allows creation of an editor where some customizations are explicitly enabled and
* other customizations are explicitly disabled using the given {@link EditorFeature} objects.
* This factory method allows creation of an editor where the given customizations are applied to the editor.
*
* @param language target language used by document that will be displayed by returned editor
* @param project target project
* @param features {@link EditorFeature} objects which explicitly enable (and possibly configure) or disable features
* @return
*/
@NotNull
EditorTextField getEditorField(@NotNull Language language, @NotNull Project project,
@NotNull Iterable<EditorFeature> features);
EditorTextField getEditorField(@NotNull Language language, @NotNull Project project, @NotNull Iterable<EditorCustomization> features);
}
@@ -23,15 +23,17 @@ import org.jetbrains.annotations.NotNull;
* Date: 12/6/10
* Time: 10:18 AM
*/
public class HorizontalScrollBarEditorCustomization extends EditorCustomization {
public class HorizontalScrollBarEditorCustomization extends SimpleEditorCustomization {
@Override
protected Class<? extends EditorFeature> getFeatureClass() {
return HorizontalScrollBarEditorFeature.class;
public static final HorizontalScrollBarEditorCustomization ENABLED = new HorizontalScrollBarEditorCustomization(true);
public static final HorizontalScrollBarEditorCustomization DISABLED = new HorizontalScrollBarEditorCustomization(false);
private HorizontalScrollBarEditorCustomization(boolean enabled) {
super(enabled);
}
@Override
protected void customize(@NotNull EditorEx editor, @NotNull EditorFeature feature) {
editor.setHorizontalScrollbarVisible(feature.isEnabled());
public void customize(@NotNull EditorEx editor) {
editor.setHorizontalScrollbarVisible(isEnabled());
}
}
@@ -1,7 +0,0 @@
package com.intellij.ui;
public class HorizontalScrollBarEditorFeature extends EditorFeature {
public HorizontalScrollBarEditorFeature(boolean enabled) {
super(enabled);
}
}
@@ -21,15 +21,18 @@ import org.jetbrains.annotations.NotNull;
/**
* @author Kirill Likhodedov
*/
public class OneLineEditorCustomization extends EditorCustomization {
public class OneLineEditorCustomization extends SimpleEditorCustomization {
@Override
protected Class<? extends EditorFeature> getFeatureClass() {
return OneLineEditorFeature.class;
public static final OneLineEditorCustomization ENABLED = new OneLineEditorCustomization(true);
public static final OneLineEditorCustomization DISABLED = new OneLineEditorCustomization(false);
private OneLineEditorCustomization(boolean enabled) {
super(enabled);
}
@Override
protected void customize(@NotNull EditorEx editor, @NotNull EditorFeature feature) {
editor.setOneLineMode(feature.isEnabled());
public void customize(@NotNull EditorEx editor) {
editor.setOneLineMode(isEnabled());
}
}
@@ -1,7 +0,0 @@
package com.intellij.ui;
public class OneLineEditorFeature extends EditorFeature {
public OneLineEditorFeature(boolean enabled) {
super(enabled);
}
}
@@ -1,27 +1,42 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.ui;
import com.intellij.openapi.editor.colors.EditorColorsManager;
import com.intellij.openapi.editor.ex.EditorEx;
import org.jetbrains.annotations.NotNull;
public class RightMarginEditorCustomization extends EditorCustomization {
public class RightMarginEditorCustomization extends SimpleEditorCustomization {
@Override
protected Class<? extends EditorFeature> getFeatureClass() {
return RightMarginEditorFeature.class;
private int myRightMarginColumns;
public RightMarginEditorCustomization(boolean enabled, int rightMarginColumns) {
super(enabled);
myRightMarginColumns = rightMarginColumns;
}
public int getRightMarginColumns() {
return myRightMarginColumns;
}
@Override
protected void customize(@NotNull EditorEx editor, @NotNull EditorFeature feature) {
if (!(feature instanceof RightMarginEditorFeature)) {
return;
}
RightMarginEditorFeature rightMarginEditorFeature = (RightMarginEditorFeature)feature;
if (rightMarginEditorFeature.isEnabled()) {
public void customize(@NotNull EditorEx editor) {
if (isEnabled()) {
editor.getSettings().setRightMarginShown(true);
editor.getSettings().setRightMargin(rightMarginEditorFeature.getRightMarginColumns());
editor.getSettings().setRightMargin(getRightMarginColumns());
// ensure we've got a monospace font by loading up the global editor scheme
editor.setColorsScheme(EditorColorsManager.getInstance().getGlobalScheme());
} else {
@@ -1,14 +0,0 @@
package com.intellij.ui;
public class RightMarginEditorFeature extends EditorFeature {
private int myRightMarginColumns;
public RightMarginEditorFeature(boolean enabled, int rightMarginColumns) {
super(enabled);
myRightMarginColumns = rightMarginColumns;
}
public int getRightMarginColumns() {
return myRightMarginColumns;
}
}
@@ -0,0 +1,34 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.ui;
/**
* Editor customization that can be on (enabled) or off (disabled).
*
* @author Kirill Likhodedov
*/
public abstract class SimpleEditorCustomization implements EditorCustomization {
private final boolean myEnabled;
protected SimpleEditorCustomization(boolean enabled) {
myEnabled = enabled;
}
protected boolean isEnabled() {
return myEnabled;
}
}
@@ -26,15 +26,17 @@ import org.jetbrains.annotations.NotNull;
* @author Denis Zhdanov
* @since Aug 20, 2010 4:54:48 PM
*/
public class SoftWrapsEditorCustomization extends EditorCustomization {
public class SoftWrapsEditorCustomization extends SimpleEditorCustomization {
@Override
protected Class<? extends EditorFeature> getFeatureClass() {
return SoftWrapsEditorFeature.class;
public static final SoftWrapsEditorCustomization ENABLED = new SoftWrapsEditorCustomization(true);
public static final SoftWrapsEditorCustomization DISABLED = new SoftWrapsEditorCustomization(false);
private SoftWrapsEditorCustomization(boolean enabled) {
super(enabled);
}
@Override
protected void customize(@NotNull EditorEx editor, @NotNull EditorFeature feature) {
editor.getSettings().setUseSoftWraps(feature.isEnabled());
public void customize(@NotNull EditorEx editor) {
editor.getSettings().setUseSoftWraps(isEnabled());
}
}
@@ -1,7 +0,0 @@
package com.intellij.ui;
public class SoftWrapsEditorFeature extends EditorFeature {
public SoftWrapsEditorFeature(boolean enabled) {
super(enabled);
}
}
@@ -1,7 +0,0 @@
package com.intellij.ui;
public class SpellCheckingEditorFeature extends EditorFeature {
public SpellCheckingEditorFeature(boolean enabled) {
super(enabled);
}
}
@@ -25,6 +25,7 @@ import com.intellij.openapi.vcs.VcsBundle;
import com.intellij.openapi.vcs.VcsConfiguration;
import com.intellij.openapi.vcs.changes.ChangeListManager;
import com.intellij.openapi.vcs.changes.LocalChangeList;
import com.intellij.spellchecker.ui.SpellCheckingEditorCustomization;
import com.intellij.ui.*;
import com.intellij.util.Consumer;
@@ -162,14 +163,14 @@ public abstract class NewEditChangelistPanel extends JPanel {
final EditorTextFieldProvider service = ServiceManager.getService(project, EditorTextFieldProvider.class);
final EditorTextField editorField;
final Set<EditorFeature> editorFeatures = new HashSet<EditorFeature>();
editorFeatures.add(new SpellCheckingEditorFeature(true));
final Set<EditorCustomization> editorFeatures = new HashSet<EditorCustomization>();
editorFeatures.add(SpellCheckingEditorCustomization.ENABLED);
if (defaultLines == 1) {
editorFeatures.add(new HorizontalScrollBarEditorFeature(false));
editorFeatures.add(new OneLineEditorFeature(true));
editorFeatures.add(HorizontalScrollBarEditorCustomization.DISABLED);
editorFeatures.add(OneLineEditorCustomization.ENABLED);
} else {
editorFeatures.add(new SoftWrapsEditorFeature(true));
editorFeatures.add(SoftWrapsEditorCustomization.ENABLED);
}
editorField = service.getEditorField(FileTypes.PLAIN_TEXT.getLanguage(), project, editorFeatures);
final int height = editorField.getFontMetrics(editorField.getFont()).getHeight();
@@ -21,11 +21,11 @@ import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.ex.EditorEx;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.fileTypes.FileTypes;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.vcs.*;
import com.intellij.spellchecker.ui.SpellCheckingEditorCustomization;
import com.intellij.ui.*;
import com.intellij.util.Consumer;
import org.jetbrains.annotations.Nullable;
@@ -39,7 +39,6 @@ public class CommitMessage extends AbstractDataProviderPanel implements Disposab
public static final Key<DataContext> DATA_CONTEXT_KEY = Key.create("commit message data context");
private final EditorTextField myEditorField;
private final Project myProject;
private Consumer<String> myMessageConsumer;
private TitledSeparator mySeparator;
private boolean myCheckSpelling;
@@ -51,8 +50,7 @@ public class CommitMessage extends AbstractDataProviderPanel implements Disposab
public CommitMessage(Project project, final boolean withSeparator) {
super(new BorderLayout());
myEditorField = createEditorField(project);
myProject = project;
// Note that we assume here that editor used for commit message processing uses font family implied by LAF (in contrast,
// IJ code editor uses monospaced font). Hence, we don't need any special actions here
// (myEditorField.setFontInheritedFromLAF(true) should be used instead).
@@ -115,19 +113,20 @@ public class CommitMessage extends AbstractDataProviderPanel implements Disposab
* @return a commit message editor
*/
public static EditorTextField createCommitTextEditor(final Project project, boolean forceSpellCheckOn) {
Set<EditorFeature> features = new HashSet<EditorFeature>();
Set<EditorCustomization> features = new HashSet<EditorCustomization>();
VcsConfiguration configuration = VcsConfiguration.getInstance(project);
if (configuration != null) {
features.add(new SpellCheckingEditorFeature(forceSpellCheckOn || configuration.CHECK_COMMIT_MESSAGE_SPELLING));
features.add(new RightMarginEditorFeature(configuration.USE_COMMIT_MESSAGE_MARGIN, configuration.COMMIT_MESSAGE_MARGIN_SIZE));
boolean enableSpellChecking = forceSpellCheckOn || configuration.CHECK_COMMIT_MESSAGE_SPELLING;
features.add(SpellCheckingEditorCustomization.getInstance(enableSpellChecking));
features.add(new RightMarginEditorCustomization(configuration.USE_COMMIT_MESSAGE_MARGIN, configuration.COMMIT_MESSAGE_MARGIN_SIZE));
} else {
features.add(new SpellCheckingEditorFeature(true));
features.add(new RightMarginEditorFeature(false, -1));
features.add(SpellCheckingEditorCustomization.ENABLED);
features.add(new RightMarginEditorCustomization(false, -1));
}
features.add(new SoftWrapsEditorFeature(true));
features.add(new AdditionalPageAtBottomEditorFeature(false));
features.add(SoftWrapsEditorCustomization.ENABLED);
features.add(AdditionalPageAtBottomEditorCustomization.DISABLED);
EditorTextFieldProvider service = ServiceManager.getService(project, EditorTextFieldProvider.class);
return service.getEditorField(FileTypes.PLAIN_TEXT.getLanguage(), project, features);
@@ -176,16 +175,7 @@ public class CommitMessage extends AbstractDataProviderPanel implements Disposab
return;
}
EditorEx editorEx = (EditorEx)editor;
toggleEditorSpellchecking(myProject, editorEx, check);
}
private static void toggleEditorSpellchecking(Project project, EditorEx editorEx, boolean spellCheckingEnabled) {
EditorCustomization[] customizations = Extensions.getExtensions(EditorCustomization.EP_NAME, project);
SpellCheckingEditorFeature spellCheckFeature = new SpellCheckingEditorFeature(spellCheckingEnabled);
for (EditorCustomization customization : customizations) {
customization.doProcessCustomization(editorEx, spellCheckFeature);
}
SpellCheckingEditorCustomization.getInstance(check).customize(editorEx);
}
public void dispose() {
+1
View File
@@ -17,6 +17,7 @@
<orderEntry type="library" name="Guava" level="project" />
<orderEntry type="library" name="sqlite" level="project" />
<orderEntry type="module" module-name="lang-impl" />
<orderEntry type="module" module-name="spellchecker" />
</component>
</module>
+1
View File
@@ -66,6 +66,7 @@
<orderEntry type="library" scope="TEST" name="cucumber-jvm" level="project" />
<orderEntry type="library" scope="TEST" name="cucumber-java" level="project" />
<orderEntry type="library" name="JSch" level="project" />
<orderEntry type="module" module-name="spellchecker" />
</component>
</module>
@@ -30,7 +30,11 @@ import com.intellij.openapi.ui.popup.JBPopup;
import com.intellij.openapi.ui.popup.JBPopupFactory;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.ui.*;
import com.intellij.spellchecker.ui.SpellCheckingEditorCustomization;
import com.intellij.ui.EditorCustomization;
import com.intellij.ui.EditorTextField;
import com.intellij.ui.EditorTextFieldProvider;
import com.intellij.ui.SoftWrapsEditorCustomization;
import com.intellij.util.Consumer;
import com.intellij.util.TextFieldCompletionProvider;
import com.intellij.util.TextFieldCompletionProviderDumbAware;
@@ -168,9 +172,9 @@ public class UsersFilterAction extends BasePopupAction {
private void createPopup(Project project) {
final JPanel panel = new JPanel(new BorderLayout());
final EditorTextFieldProvider service = ServiceManager.getService(project, EditorTextFieldProvider.class);
Set<EditorFeature> features = new HashSet<EditorFeature>();
features.add(new SoftWrapsEditorFeature(true));
features.add(new SpellCheckingEditorFeature(false));
Set<EditorCustomization> features = new HashSet<EditorCustomization>();
features.add(SoftWrapsEditorCustomization.ENABLED);
features.add(SpellCheckingEditorCustomization.DISABLED);
myEditorField = service.getEditorField(FileTypes.PLAIN_TEXT.getLanguage(), project, features);
myEditorField.setBorder(new CompoundBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2), myEditorField.getBorder()));
myEditorField.setText("s");
@@ -27,9 +27,7 @@ import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.spellchecker.inspections.SpellCheckingInspection;
import com.intellij.ui.EditorCustomization;
import com.intellij.ui.EditorFeature;
import com.intellij.ui.SpellCheckingEditorFeature;
import com.intellij.ui.SimpleEditorCustomization;
import com.intellij.util.Function;
import com.intellij.util.containers.WeakHashMap;
import gnu.trove.THashSet;
@@ -46,14 +44,21 @@ import java.util.*;
* @author Denis Zhdanov
* @since Aug 20, 2010 3:54:42 PM
*/
public class SpellCheckingEditorCustomization extends EditorCustomization {
public class SpellCheckingEditorCustomization extends SimpleEditorCustomization {
public static final SpellCheckingEditorCustomization ENABLED = new SpellCheckingEditorCustomization(true);
public static final SpellCheckingEditorCustomization DISABLED = new SpellCheckingEditorCustomization(false);
private static final Set<LocalInspectionToolWrapper> SPELL_CHECK_TOOLS = new HashSet<LocalInspectionToolWrapper>();
private static final boolean READY = init();
@Override
protected Class<? extends EditorFeature> getFeatureClass() {
return SpellCheckingEditorFeature.class;
@NotNull
public static SpellCheckingEditorCustomization getInstance(boolean enabled) {
return enabled ? ENABLED : DISABLED;
}
private SpellCheckingEditorCustomization(boolean enabled) {
super(enabled);
}
@SuppressWarnings({"unchecked"})
@@ -75,8 +80,8 @@ public class SpellCheckingEditorCustomization extends EditorCustomization {
}
@Override
protected void customize(@NotNull EditorEx editor, @NotNull EditorFeature feature) {
boolean apply = feature.isEnabled();
public void customize(@NotNull EditorEx editor) {
boolean apply = isEnabled();
if (!READY) {
return;