Skip to content

Commit

Permalink
prettier: add explicit action to apply code style from config (WEB-32…
Browse files Browse the repository at this point in the history
…850)
  • Loading branch information
undeadcat committed Nov 26, 2018
1 parent b76003c commit fc799b4
Show file tree
Hide file tree
Showing 6 changed files with 105 additions and 43 deletions.
5 changes: 5 additions & 0 deletions prettierJS/resources/META-INF/plugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,11 @@ Please report any issues in the <a href="https://youtrack.jetbrains.com/issues/W
<keyboard-shortcut keymap="Mac OS X" first-keystroke="meta alt shift P" />
<keyboard-shortcut keymap="Mac OS X 10.5+" first-keystroke="meta alt shift P"/>
</action>
<action id="PrettierImportCodeStyleAction" class="com.intellij.prettierjs.PrettierImportCodeStyleAction"
text="Apply Prettier Code Style Rules">
<add-to-group group-id="EditorPopupMenu" anchor="last"/>
<add-to-group group-id="ProjectViewPopupMenu" anchor="last"/>
</action>
</actions>
<extensions defaultExtensionNs="JavaScript.JsonSchema">
<ProviderFactory implementation="com.intellij.prettierjs.config.PrettierConfigJsonSchemaProviderFactory"/>
Expand Down
3 changes: 2 additions & 1 deletion prettierJS/resources/PrettierBundle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,5 @@ command.name=Reformat code with Prettier
import.notification=Prettier: The project code style was updated
not.supported.file=File {0} has unsupported type
file.watcher.description=Runs Prettier, the code formatting tool
file.was.ignored=File {0} was ignored with .prettierIgnore
file.was.ignored=File {0} was ignored with .prettierIgnore
import.config.title=Apply Prettier Code Style Rules
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,7 @@
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

public class PrettierCodeStyleEditorNotificationProvider
extends EditorNotifications.Provider<EditorNotificationPanel>
public class PrettierCodeStyleEditorNotificationProvider extends EditorNotifications.Provider<EditorNotificationPanel>
implements DumbAware {

private static final Key<EditorNotificationPanel> KEY = Key.create("prettier.codestyle.notification.panel");
Expand Down Expand Up @@ -67,7 +66,21 @@ public EditorNotificationPanel createNotificationPanel(@NotNull VirtualFile file
return null;
}

PrettierUtil.Config config = findConfigForFile(file, project);
PrettierUtil.Config config = null;
if (PrettierUtil.isConfigFile(file)) {
config = PrettierUtil.parseConfig(project, file);
}
if (PackageJsonUtil.isPackageJsonFile(file)) {
//if package.json is currently opened, but there is a neighboring config file
VirtualFile configVFile = PrettierUtil.findSingleConfigInDirectory(file.getParent());
if (configVFile != null) {
config = PrettierUtil.parseConfig(project, configVFile);
file = configVFile;
}
else {
config = PrettierUtil.parseConfig(project, file);
}
}
if (config == null) {
return null;
}
Expand All @@ -77,10 +90,11 @@ public EditorNotificationPanel createNotificationPanel(@NotNull VirtualFile file
final EditorNotificationPanel panel = new EditorNotificationPanel(EditorColors.GUTTER_BACKGROUND);
panel.setText(PrettierBundle.message("editor.notification.title"));

PrettierUtil.Config finalConfig = config;
VirtualFile finalFile = file;
panel.createActionLabel(PrettierBundle.message("editor.notification.yes.text"),
() -> {
PrettierCompatibleCodeStyleInstaller.install(project, config);
PrettierNotificationUtil.reportCodeStyleSettingsImported(project, file, null);
PrettierCompatibleCodeStyleInstaller.install(project, finalFile, finalConfig, false);
myEditorNotifications.updateAllNotifications();
});
panel.createActionLabel(PrettierBundle.message("editor.notification.no.text"), () -> {
Expand All @@ -91,22 +105,6 @@ public EditorNotificationPanel createNotificationPanel(@NotNull VirtualFile file
return panel;
}

@Nullable
private static PrettierUtil.Config findConfigForFile(@NotNull VirtualFile file, Project project) {
if (PrettierUtil.isConfigFile(file)) {
return PrettierUtil.parseConfig(project, file);
}
if (PackageJsonUtil.isPackageJsonFile(file)) {
//if package.json is currently opened, but there is a neighboring config file
VirtualFile config = PrettierUtil.findSingleConfigInDirectory(file.getParent());
if (config != null) {
return PrettierUtil.parseConfig(project, config);
}
return PrettierUtil.parseConfig(project, file);
}
return null;
}

private boolean alreadyDismissed() {
return myPropertiesComponent.getBoolean(NOTIFICATION_DISMISSED_KEY);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
import com.intellij.lang.Language;
import com.intellij.lang.javascript.JavaScriptSupportLoader;
import com.intellij.lang.javascript.JavascriptLanguage;
import com.intellij.lang.javascript.buildTools.npm.PackageJsonUtil;
import com.intellij.lang.javascript.formatter.JSCodeStyleSettings;
import com.intellij.lang.javascript.linter.JSLinterUtil;
import com.intellij.lang.typescript.formatter.TypeScriptCodeStyleSettings;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.DumbAwareRunnable;
Expand All @@ -19,7 +19,6 @@
import com.intellij.psi.codeStyle.CodeStyleSettings;
import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
import com.intellij.psi.codeStyle.CommonCodeStyleSettings;
import com.intellij.util.ObjectUtils;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;

Expand All @@ -34,23 +33,37 @@ public void configureProject(Project project, @NotNull VirtualFile baseDir, Ref<
}

private static void installCodeStyle(@NotNull Project project) {
VirtualFile aConfig = ObjectUtils.coalesce(PrettierUtil.findSingleConfigInContentRoots(project),
project.getBaseDir().findChild(PackageJsonUtil.FILE_NAME));
VirtualFile aConfig = PrettierUtil.findSingleConfigInContentRoots(project);
if (aConfig != null) {
PrettierUtil.Config config = PrettierUtil.parseConfig(project, aConfig);
if (config != null) {
Pair<CodeStyleSettings, Boolean> previousSettings = install(project, config);
PrettierNotificationUtil.reportCodeStyleSettingsImported(project, aConfig, () -> {
CodeStyleSettingsManager settingsManager = CodeStyleSettingsManager.getInstance(project);
settingsManager.setMainProjectCodeStyle(previousSettings.first);
settingsManager.USE_PER_PROJECT_SETTINGS = previousSettings.second;
});
install(project, aConfig, false);
}
}

public static void install(@NotNull Project project, @NotNull VirtualFile virtualFile, boolean reportAlreadyImported) {
PrettierUtil.Config config = PrettierUtil.parseConfig(project, virtualFile);
if (config != null) {
install(project, virtualFile, config, reportAlreadyImported);
}
}

public static void install(@NotNull Project project, @NotNull VirtualFile configFile,
@NotNull PrettierUtil.Config config, boolean reportAlreadyImported) {
if (isInstalled(project, config)) {
if (reportAlreadyImported) {
JSLinterUtil.reportCodeStyleSettingsAlreadyImported(project, "Prettier");
}
return;
}
Pair<CodeStyleSettings, Boolean> previousSettings = install(project, config);
PrettierNotificationUtil.reportCodeStyleSettingsImported(project, configFile, () -> {
CodeStyleSettingsManager settingsManager = CodeStyleSettingsManager.getInstance(project);
settingsManager.setMainProjectCodeStyle(previousSettings.first);
settingsManager.USE_PER_PROJECT_SETTINGS = previousSettings.second;
});
}

@NotNull
public static Pair<CodeStyleSettings, Boolean> install(@NotNull Project project, @NotNull PrettierUtil.Config config) {
private static Pair<CodeStyleSettings, Boolean> install(@NotNull Project project, @NotNull PrettierUtil.Config config) {
CodeStyleSettingsManager settingsManager = CodeStyleSettingsManager.getInstance(project);
boolean previousUsePerProjectSettings = settingsManager.USE_PER_PROJECT_SETTINGS;
CodeStyleSettings previousSettings = settingsManager.getCurrentSettings();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.prettierjs;

import com.intellij.lang.javascript.buildTools.npm.PackageJsonUtil;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiFile;
import org.jetbrains.annotations.NotNull;

public class PrettierImportCodeStyleAction extends AnAction {
public PrettierImportCodeStyleAction() {
}

@Override
public void update(@NotNull AnActionEvent e) {
final DataContext context = e.getDataContext();
final PsiFile psiFile = CommonDataKeys.PSI_FILE.getData(context);
Project project = CommonDataKeys.PROJECT.getData(context);
final boolean enabledAndVisible = project != null &&
psiFile != null
&& isConfigOrPackageJsonWithSection(psiFile);
e.getPresentation().setEnabledAndVisible(enabledAndVisible);
}

private static boolean isConfigOrPackageJsonWithSection(@NotNull PsiFile psiFile) {
VirtualFile virtualFile = psiFile.getVirtualFile();
return PrettierUtil.isConfigFile(virtualFile) ||
PackageJsonUtil.isPackageJsonWithTopLevelProperty(virtualFile, PrettierUtil.PACKAGE_NAME);
}

@Override
public void actionPerformed(@NotNull AnActionEvent e) {
final DataContext context = e.getDataContext();
Project project = e.getProject();
final PsiFile psiFile = CommonDataKeys.PSI_FILE.getData(context);
VirtualFile virtualFile = psiFile != null ? psiFile.getVirtualFile() : null;
if (virtualFile == null || project == null) {
return;
}
PrettierCompatibleCodeStyleInstaller.install(project, virtualFile, true);
}
}
15 changes: 7 additions & 8 deletions prettierJS/src/com/intellij/prettierjs/PrettierUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import com.intellij.javascript.nodejs.PackageJsonData;
import com.intellij.json.psi.JsonFile;
import com.intellij.lang.javascript.buildTools.npm.PackageJsonUtil;
import com.intellij.lang.javascript.linter.JSLinterConfigFileUtil;
import com.intellij.lang.javascript.linter.JSLinterConfigLangSubstitutor;
import com.intellij.openapi.application.ReadAction;
import com.intellij.openapi.diagnostic.Logger;
Expand Down Expand Up @@ -61,6 +62,7 @@ public class PrettierUtil {
public static final String END_OF_LINE = "endOfLine";
private static final String JSX_BRACKET_SAME_LINE = "jsxBracketSameLine";
private static final Gson OUR_GSON_SERIALIZER = new GsonBuilder().create();
private static final String CONFIG_SECTION_NAME = PACKAGE_NAME;

private PrettierUtil() {
}
Expand Down Expand Up @@ -135,15 +137,12 @@ private static void addPossibleConfigsForFile(@NotNull VirtualFile from, @NotNul

@Nullable
public static VirtualFile findSingleConfigInContentRoots(@NotNull Project project) {
List<VirtualFile> configs = ContainerUtil.newSmartList();
for (VirtualFile dir : ProjectRootManager.getInstance(project).getContentRoots()) {
VirtualFile found = findSingleConfigInDirectory(dir);
if (found != null) {
configs.add(found);
return JSLinterConfigFileUtil.findDistinctConfigInContentRoots(project, CONFIG_FILE_NAMES_WITH_PACKAGE_JSON, file -> {
if (PackageJsonUtil.isPackageJsonFile(file)) {
return PackageJsonUtil.getOrCreateData(file).getTopLevelProperties().contains(CONFIG_SECTION_NAME);
}
}

return configs.size() == 1 ? ContainerUtil.getFirstItem(configs) : null;
return true;
});
}

@Nullable
Expand Down

0 comments on commit fc799b4

Please sign in to comment.