summaryrefslogtreecommitdiff
path: root/plugins/editorconfig/src/org/editorconfig/configmanagement/CodeStyleManager.java
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/editorconfig/src/org/editorconfig/configmanagement/CodeStyleManager.java')
-rw-r--r--plugins/editorconfig/src/org/editorconfig/configmanagement/CodeStyleManager.java184
1 files changed, 184 insertions, 0 deletions
diff --git a/plugins/editorconfig/src/org/editorconfig/configmanagement/CodeStyleManager.java b/plugins/editorconfig/src/org/editorconfig/configmanagement/CodeStyleManager.java
new file mode 100644
index 000000000000..406e38456976
--- /dev/null
+++ b/plugins/editorconfig/src/org/editorconfig/configmanagement/CodeStyleManager.java
@@ -0,0 +1,184 @@
+package org.editorconfig.configmanagement;
+
+import com.intellij.lang.Language;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.editor.Document;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.editor.ex.EditorEx;
+import com.intellij.openapi.fileEditor.FileDocumentManager;
+import com.intellij.openapi.fileEditor.FileEditorManager;
+import com.intellij.openapi.fileEditor.FileEditorManagerAdapter;
+import com.intellij.openapi.fileEditor.FileEditorManagerEvent;
+import com.intellij.openapi.fileTypes.FileType;
+import com.intellij.openapi.fileTypes.LanguageFileType;
+import com.intellij.openapi.fileTypes.PlainTextLanguage;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.codeStyle.CodeStyleSettings;
+import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
+import com.intellij.psi.codeStyle.CommonCodeStyleSettings;
+import org.editorconfig.Utils;
+import org.editorconfig.core.EditorConfig.OutPair;
+import org.editorconfig.plugincomponents.SettingsProviderComponent;
+import org.jetbrains.annotations.NotNull;
+
+import java.awt.event.WindowEvent;
+import java.awt.event.WindowFocusListener;
+import java.util.List;
+
+public class CodeStyleManager extends FileEditorManagerAdapter implements WindowFocusListener {
+ // Handles the following EditorConfig settings:
+ private static final String indentSizeKey = "indent_size";
+ private static final String tabWidthKey = "tab_width";
+ private static final String indentStyleKey = "indent_style";
+
+ private static final Logger LOG = Logger.getInstance("#org.editorconfig.configmanagement.CodeStyleManager");
+ private final CodeStyleSettingsManager codeStyleSettingsManager;
+ private final Project project;
+
+ public CodeStyleManager(Project project) {
+ codeStyleSettingsManager = CodeStyleSettingsManager.getInstance(project);
+ this.project = project;
+ }
+
+ @Override
+ public void fileOpened(@NotNull FileEditorManager source, @NotNull VirtualFile file) {
+ applySettings(file);
+ }
+
+ @Override
+ public void selectionChanged(@NotNull FileEditorManagerEvent event) {
+ final VirtualFile file = event.getNewFile();
+ applySettings(file);
+ }
+
+ @Override
+ public void windowGainedFocus(WindowEvent e) {
+ final Editor currentEditor = FileEditorManager.getInstance(project).getSelectedTextEditor();
+ if (currentEditor != null) {
+ final Document currentDocument = currentEditor.getDocument();
+ final VirtualFile currentFile = FileDocumentManager.getInstance().getFile(currentDocument);
+ applySettings(currentFile);
+ }
+ }
+
+ @Override
+ public void windowLostFocus(WindowEvent e) {
+ }
+
+ private void applySettings(final VirtualFile file) {
+ if (file != null && file.isInLocalFileSystem()) {
+ // Always drop any current temporary settings so that the defaults will be applied if
+ // this is a non-editorconfig-managed file
+ codeStyleSettingsManager.dropTemporarySettings();
+ // Prepare a new settings object, which will maintain the standard settings if no
+ // editorconfig settings apply
+ final CodeStyleSettings currentSettings = codeStyleSettingsManager.getCurrentSettings();
+ final CodeStyleSettings newSettings = new CodeStyleSettings();
+ newSettings.copyFrom(currentSettings);
+ // Get editorconfig settings
+ final String filePath = file.getCanonicalPath();
+ final SettingsProviderComponent settingsProvider = SettingsProviderComponent.getInstance();
+ final List<OutPair> outPairs = settingsProvider.getOutPairs(filePath);
+ // Apply editorconfig settings for the current editor
+ applyCodeStyleSettings(outPairs, newSettings, file);
+ codeStyleSettingsManager.setTemporarySettings(newSettings);
+ final EditorEx currentEditor = (EditorEx)FileEditorManager.getInstance(project).getSelectedTextEditor();
+ if (currentEditor != null) {
+ currentEditor.reinitSettings();
+ }
+ }
+ }
+
+ private static void applyCodeStyleSettings(final List<OutPair> outPairs, final CodeStyleSettings codeStyleSettings,
+ final VirtualFile file) {
+ // Apply indent options
+ final String indentSize = Utils.configValueForKey(outPairs, indentSizeKey);
+ final String tabWidth = Utils.configValueForKey(outPairs, tabWidthKey);
+ final String indentStyle = Utils.configValueForKey(outPairs, indentStyleKey);
+ final FileType fileType = file.getFileType();
+ final Language language = fileType instanceof LanguageFileType ? ((LanguageFileType)fileType).getLanguage() :
+ PlainTextLanguage.INSTANCE;
+ final CommonCodeStyleSettings commonSettings = codeStyleSettings.getCommonSettings(language);
+ final CommonCodeStyleSettings.IndentOptions indentOptions = commonSettings.getIndentOptions();
+ applyIndentOptions(indentOptions, indentSize, tabWidth, indentStyle, file.getCanonicalPath());
+ }
+
+ private static void applyIndentOptions(CommonCodeStyleSettings.IndentOptions indentOptions,
+ String indentSize, String tabWidth, String indentStyle, String filePath) {
+ final String calculatedIndentSize = calculateIndentSize(tabWidth, indentSize);
+ final String calculatedTabWidth = calculateTabWidth(tabWidth, indentSize);
+ if (!calculatedIndentSize.isEmpty()) {
+ if (applyIndentSize(indentOptions, calculatedIndentSize)) {
+ LOG.debug(Utils.appliedConfigMessage(calculatedIndentSize, indentSizeKey, filePath));
+ }
+ else {
+ LOG.warn(Utils.invalidConfigMessage(calculatedIndentSize, indentSizeKey, filePath));
+ }
+ }
+ if (!calculatedTabWidth.isEmpty()) {
+ if (applyTabWidth(indentOptions, calculatedTabWidth)) {
+ LOG.debug(Utils.appliedConfigMessage(calculatedTabWidth, tabWidthKey, filePath));
+ }
+ else {
+ LOG.warn(Utils.invalidConfigMessage(calculatedTabWidth, tabWidthKey, filePath));
+ }
+ }
+ if (!indentStyle.isEmpty()) {
+ if (applyIndentStyle(indentOptions, indentStyle)) {
+ LOG.debug(Utils.appliedConfigMessage(indentStyle, indentStyleKey, filePath));
+ }
+ else {
+ LOG.warn(Utils.invalidConfigMessage(indentStyle, indentStyleKey, filePath));
+ }
+ }
+ }
+
+ private static String calculateIndentSize(final String tabWidth, final String indentSize) {
+ return indentSize.equals("tab") ? tabWidth : indentSize;
+ }
+
+ private static String calculateTabWidth(final String tabWidth, final String indentSize) {
+ if (tabWidth.isEmpty() && indentSize.equals("tab")) {
+ return "";
+ }
+ else if (tabWidth.isEmpty()) {
+ return indentSize;
+ }
+ else {
+ return tabWidth;
+ }
+ }
+
+ private static boolean applyIndentSize(final CommonCodeStyleSettings.IndentOptions indentOptions, final String indentSize) {
+ try {
+ int indent = Integer.parseInt(indentSize);
+ indentOptions.INDENT_SIZE = indent;
+ indentOptions.CONTINUATION_INDENT_SIZE = indent;
+ return true;
+ }
+ catch (NumberFormatException e) {
+ return false;
+ }
+ }
+
+ private static boolean applyTabWidth(final CommonCodeStyleSettings.IndentOptions indentOptions, final String tabWidth) {
+ try {
+ indentOptions.TAB_SIZE = Integer.parseInt(tabWidth);
+ return true;
+ }
+ catch (NumberFormatException e) {
+ return false;
+ }
+ }
+
+ private static boolean applyIndentStyle(CommonCodeStyleSettings.IndentOptions indentOptions, String indentStyle) {
+ if (indentStyle.equals("tab") || indentStyle.equals("space")) {
+ indentOptions.USE_TAB_CHARACTER = indentStyle.equals("tab");
+ return true;
+ }
+ else {
+ return false;
+ }
+ }
+}