Skip to content

Commit e2729cc

Browse files
committed
Search for configuration through the whole project root hierarchy (#423)
1 parent 51ae37a commit e2729cc

File tree

3 files changed

+161
-154
lines changed

3 files changed

+161
-154
lines changed

src/main/com/intellij/lang/jsgraphql/endpoint/ide/project/JSGraphQLEndpointNamedTypeRegistry.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,10 +102,11 @@ public GraphQLValidatedTypeDefinitionRegistry getTypesAsRegistry(PsiElement scop
102102
}
103103

104104
private GraphQLNamedScope getSchemaScope(PsiElement scopedElement) {
105-
VirtualFile virtualFile = scopedElement.getContainingFile().getVirtualFile();
105+
PsiFile containingFile = scopedElement.getContainingFile();
106+
VirtualFile virtualFile = containingFile.getVirtualFile();
106107
if (virtualFile == null) {
107108
// in memory PsiFile such as the completion PSI
108-
virtualFile = scopedElement.getContainingFile().getOriginalFile().getVirtualFile();
109+
virtualFile = containingFile.getOriginalFile().getVirtualFile();
109110
}
110111
return virtualFile != null ? graphQLConfigManager.getSchemaScope(virtualFile) : null;
111112
}

src/main/com/intellij/lang/jsgraphql/ide/actions/GraphQLEditConfigAction.java

Lines changed: 54 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,10 @@
77
*/
88
package com.intellij.lang.jsgraphql.ide.actions;
99

10-
import com.google.common.collect.Lists;
1110
import com.intellij.icons.AllIcons;
1211
import com.intellij.ide.util.DefaultPsiElementCellRenderer;
12+
import com.intellij.lang.jsgraphql.GraphQLFileType;
13+
import com.intellij.lang.jsgraphql.ide.notifications.GraphQLNotificationUtil;
1314
import com.intellij.lang.jsgraphql.ide.project.graphqlconfig.GraphQLConfigManager;
1415
import com.intellij.lang.jsgraphql.psi.GraphQLPsiUtil;
1516
import com.intellij.lang.jsgraphql.schema.GraphQLSchemaKeys;
@@ -21,22 +22,24 @@
2122
import com.intellij.openapi.actionSystem.CommonDataKeys;
2223
import com.intellij.openapi.fileEditor.FileEditorManager;
2324
import com.intellij.openapi.project.Project;
25+
import com.intellij.openapi.project.ProjectUtil;
2426
import com.intellij.openapi.ui.ComboBox;
2527
import com.intellij.openapi.ui.DialogWrapper;
2628
import com.intellij.openapi.vfs.VirtualFile;
2729
import com.intellij.psi.PsiDirectory;
2830
import com.intellij.psi.impl.file.PsiDirectoryFactory;
2931
import com.intellij.ui.CollectionComboBoxModel;
3032
import com.intellij.ui.components.panels.NonOpaquePanel;
33+
import com.intellij.util.CommonProcessors;
34+
import com.intellij.util.containers.ContainerUtil;
3135
import org.jetbrains.annotations.NotNull;
3236
import org.jetbrains.annotations.Nullable;
3337

3438
import javax.swing.*;
3539
import java.awt.*;
40+
import java.util.Collection;
3641
import java.util.Collections;
3742
import java.util.List;
38-
import java.util.Optional;
39-
import java.util.Set;
4043
import java.util.stream.Collectors;
4144

4245
public class GraphQLEditConfigAction extends AnAction {
@@ -58,53 +61,64 @@ public void update(@NotNull AnActionEvent e) {
5861

5962
@Override
6063
public void actionPerformed(AnActionEvent e) {
61-
final Project myProject = e.getData(CommonDataKeys.PROJECT);
64+
final Project project = e.getData(CommonDataKeys.PROJECT);
6265
final VirtualFile virtualFile = GraphQLPsiUtil.getVirtualFile(e.getData(CommonDataKeys.VIRTUAL_FILE));
63-
if (myProject != null && virtualFile != null) {
64-
final GraphQLConfigManager configManager = GraphQLConfigManager.getService(myProject);
65-
final VirtualFile configFile = configManager.getClosestConfigFile(virtualFile);
66-
if (configFile != null) {
67-
final FileEditorManager fileEditorManager = FileEditorManager.getInstance(myProject);
68-
fileEditorManager.openFile(configFile, true, true);
69-
} else {
70-
// no config associated, ask to create one
71-
String message = "Searched current and parent directories.<br><a href=\"create\">Create .graphqlconfig file</a>";
72-
Notifications.Bus.notify(new Notification("GraphQL", "No .graphqlconfig file found", message, NotificationType.INFORMATION, (notification, event) -> {
73-
final Set<VirtualFile> contentRoots = configManager.getContentRoots(virtualFile);
74-
VirtualFile directory = virtualFile.getParent();
75-
assert directory != null;
76-
final List<VirtualFile> configDirectoryCandidates = Lists.newArrayList(directory);
77-
while (!contentRoots.contains(directory)) {
78-
directory = directory.getParent();
79-
if (directory != null) {
80-
configDirectoryCandidates.add(directory);
81-
} else {
82-
break;
83-
}
84-
}
85-
if (configDirectoryCandidates.size() == 1) {
86-
configManager.createAndOpenConfigFile(configDirectoryCandidates.get(0), true);
87-
notification.expire();
88-
} else {
89-
final GraphQLConfigDirectoryDialog dialog = new GraphQLConfigDirectoryDialog(myProject, configDirectoryCandidates);
90-
if (dialog.showAndGet()) {
91-
if (dialog.getSelectedDirectory() != null) {
92-
configManager.createAndOpenConfigFile(dialog.getSelectedDirectory(), true);
93-
notification.expire();
94-
}
95-
}
96-
}
97-
}), myProject);
66+
if (project == null || virtualFile == null) {
67+
return;
68+
}
69+
70+
final GraphQLConfigManager configManager = GraphQLConfigManager.getService(project);
71+
final VirtualFile configFile = configManager.getClosestConfigFile(virtualFile);
72+
if (configFile != null) {
73+
final FileEditorManager fileEditorManager = FileEditorManager.getInstance(project);
74+
fileEditorManager.openFile(configFile, true, true);
75+
} else {
76+
// no config associated, ask to create one
77+
String message = "Searched current and parent directories.<br><a href=\"create\">Create .graphqlconfig file</a>";
78+
Notifications.Bus.notify(new Notification(
79+
GraphQLNotificationUtil.NOTIFICATION_GROUP_ID,
80+
"No .graphqlconfig file found",
81+
message,
82+
NotificationType.INFORMATION,
83+
(notification, event) -> createConfig(project, virtualFile, configManager, notification)
84+
), project);
85+
}
86+
}
87+
88+
private void createConfig(Project project, VirtualFile virtualFile, GraphQLConfigManager configManager, Notification notification) {
89+
Collection<VirtualFile> configDirectoryCandidates = getParentDirsUpToContentRoots(project, virtualFile);
90+
91+
if (configDirectoryCandidates.size() == 1) {
92+
configManager.createAndOpenConfigFile(ContainerUtil.getFirstItem(configDirectoryCandidates), true);
93+
notification.expire();
94+
} else {
95+
final GraphQLConfigDirectoryDialog dialog = new GraphQLConfigDirectoryDialog(project, configDirectoryCandidates);
96+
if (dialog.showAndGet() && dialog.getSelectedDirectory() != null) {
97+
configManager.createAndOpenConfigFile(dialog.getSelectedDirectory(), true);
98+
notification.expire();
9899
}
99100
}
100101
}
101102

103+
@NotNull
104+
private static Collection<VirtualFile> getParentDirsUpToContentRoots(@NotNull Project project, @NotNull VirtualFile virtualFile) {
105+
Collection<VirtualFile> configDirectoryCandidates;
106+
if (GraphQLFileType.isGraphQLScratchFile(project, virtualFile)) {
107+
configDirectoryCandidates = Collections.singletonList(ProjectUtil.guessProjectDir(project));
108+
} else {
109+
CommonProcessors.CollectProcessor<VirtualFile> directoriesProcessor = new CommonProcessors.CollectProcessor<>();
110+
GraphQLConfigManager.processDirectoriesUpToContentRoot(project, virtualFile, directoriesProcessor);
111+
configDirectoryCandidates = directoriesProcessor.getResults();
112+
}
113+
return configDirectoryCandidates;
114+
}
115+
102116
static class GraphQLConfigDirectoryDialog extends DialogWrapper {
103117

104118
private final List<PsiDirectory> configDirectoryCandidates;
105119
private ComboBox<PsiDirectory> comboBox;
106120

107-
GraphQLConfigDirectoryDialog(@NotNull Project project, List<VirtualFile> configDirectoryCandidates) {
121+
GraphQLConfigDirectoryDialog(@NotNull Project project, Collection<VirtualFile> configDirectoryCandidates) {
108122
super(project);
109123
final PsiDirectoryFactory factory = PsiDirectoryFactory.getInstance(project);
110124
this.configDirectoryCandidates = configDirectoryCandidates.stream().map(factory::createDirectory).collect(Collectors.toList());

0 commit comments

Comments
 (0)