package org.editorconfig.configmanagement;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.ex.EditorSettingsExternalizable;
import com.intellij.openapi.editor.impl.TrailingSpacesStripper;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.fileEditor.FileDocumentManagerAdapter;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.vfs.VirtualFile;
import org.editorconfig.Utils;
import org.editorconfig.core.EditorConfig;
import org.editorconfig.plugincomponents.SettingsProviderComponent;
import org.jetbrains.annotations.NotNull;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class EditorSettingsManager extends FileDocumentManagerAdapter {
// Handles the following EditorConfig settings:
private static final String trimTrailingWhitespaceKey = "trim_trailing_whitespace";
private static final String insertFinalNewlineKey = "insert_final_newline";
private static final Map<String, String> trimMap;
static {
Map<String, String> map = new HashMap<String, String>();
map.put("true", EditorSettingsExternalizable.STRIP_TRAILING_SPACES_WHOLE);
map.put("false", EditorSettingsExternalizable.STRIP_TRAILING_SPACES_NONE);
trimMap = Collections.unmodifiableMap(map);
}
private static final Map<String, Boolean> newlineMap;
static {
Map<String, Boolean> map = new HashMap<String, Boolean>();
map.put("true", Boolean.TRUE);
map.put("false", Boolean.FALSE);
newlineMap = Collections.unmodifiableMap(map);
}
private static final Logger LOG = Logger.getInstance("#org.editorconfig.configmanagement.EditorSettingsManager");
@Override
public void beforeDocumentSaving(@NotNull Document document) {
// This is fired when any document is saved, regardless of whether it is part of a save-all or
// a save-one operation
final VirtualFile file = FileDocumentManager.getInstance().getFile(document);
applySettings(file);
}
private static void applySettings(VirtualFile file) {
if (file == null || !file.isInLocalFileSystem()) return;
// Get editorconfig settings
final String filePath = file.getCanonicalPath();
final SettingsProviderComponent settingsProvider = SettingsProviderComponent.getInstance();
final List<EditorConfig.OutPair> outPairs = settingsProvider.getOutPairs(filePath);
// Apply trailing spaces setting
final String trimTrailingWhitespace = Utils.configValueForKey(outPairs, trimTrailingWhitespaceKey);
applyConfigValueToUserData(file, TrailingSpacesStripper.OVERRIDE_STRIP_TRAILING_SPACES_KEY,
trimTrailingWhitespaceKey, trimTrailingWhitespace, trimMap);
// Apply final newline setting
final String insertFinalNewline = Utils.configValueForKey(outPairs, insertFinalNewlineKey);
applyConfigValueToUserData(file, TrailingSpacesStripper.OVERRIDE_ENSURE_NEWLINE_KEY,
insertFinalNewlineKey, insertFinalNewline, newlineMap);
}
private static <T> void applyConfigValueToUserData(VirtualFile file, Key<T> userDataKey, String editorConfigKey,
String configValue, Map<String, T> configMap) {
if (configValue.isEmpty()) {
file.putUserData(userDataKey, null);
} else {
final T data = configMap.get(configValue);
if (data == null) {
LOG.warn(Utils.invalidConfigMessage(configValue, editorConfigKey, file.getCanonicalPath()));
} else {
file.putUserData(userDataKey, data);
LOG.debug("Applied " + editorConfigKey + " settings for: " + file.getCanonicalPath());
}
}
}
}