diff --git a/platform/lang-impl/src/com/intellij/ide/impl/ProjectViewSelectInTarget.java b/platform/lang-impl/src/com/intellij/ide/impl/ProjectViewSelectInTarget.java index def81820ed4c..ff169ebbfb63 100644 --- a/platform/lang-impl/src/com/intellij/ide/impl/ProjectViewSelectInTarget.java +++ b/platform/lang-impl/src/com/intellij/ide/impl/ProjectViewSelectInTarget.java @@ -11,8 +11,8 @@ import com.intellij.ide.projectView.SelectableTreeStructureProvider; import com.intellij.ide.projectView.TreeStructureProvider; import com.intellij.ide.projectView.impl.AbstractProjectViewPane; import com.intellij.ide.projectView.impl.ProjectViewPane; -import com.intellij.ide.scratch.ScratchFileType; import com.intellij.ide.scratch.ScratchProjectViewPane; +import com.intellij.ide.scratch.ScratchUtil; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.project.DumbService; @@ -118,7 +118,7 @@ public abstract class ProjectViewSelectInTarget extends SelectInTargetPsiWrapper index.isInLibraryClasses(vFile) || index.isInLibrarySource(vFile) || Comparing.equal(vFile.getParent(), myProject.getBaseDir()) || - ScratchProjectViewPane.isScratchesMergedIntoProjectTab() && vFile.getFileType() == ScratchFileType.INSTANCE; + ScratchProjectViewPane.isScratchesMergedIntoProjectTab() && ScratchUtil.isScratch(vFile); } public String getSubIdPresentableName(String subId) { diff --git a/platform/lang-impl/src/com/intellij/ide/projectView/ProjectViewPsiTreeChangeListener.java b/platform/lang-impl/src/com/intellij/ide/projectView/ProjectViewPsiTreeChangeListener.java index b8393940daea..268b6b092b8e 100644 --- a/platform/lang-impl/src/com/intellij/ide/projectView/ProjectViewPsiTreeChangeListener.java +++ b/platform/lang-impl/src/com/intellij/ide/projectView/ProjectViewPsiTreeChangeListener.java @@ -16,8 +16,8 @@ package com.intellij.ide.projectView; -import com.intellij.ide.scratch.RootType; import com.intellij.ide.scratch.ScratchProjectViewPane; +import com.intellij.ide.scratch.ScratchUtil; import com.intellij.ide.util.treeView.AbstractTreeUpdater; import com.intellij.openapi.fileTypes.FileTypes; import com.intellij.openapi.project.Project; @@ -102,7 +102,7 @@ public abstract class ProjectViewPsiTreeChangeListener extends PsiTreeChangeAdap } else if (parent instanceof PsiDirectory && ScratchProjectViewPane.isScratchesMergedIntoProjectTab() && - RootType.forFile(((PsiDirectory)parent).getVirtualFile()) != null) { + ScratchUtil.isScratch(((PsiDirectory)parent).getVirtualFile())) { addSubtreeToUpdateByRoot(); break; } diff --git a/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/AbstractProjectNode.java b/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/AbstractProjectNode.java index 91efdf0e0b64..a6f564b51cfa 100644 --- a/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/AbstractProjectNode.java +++ b/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/AbstractProjectNode.java @@ -19,8 +19,8 @@ import com.intellij.ide.projectView.PresentationData; import com.intellij.ide.projectView.ProjectViewNode; import com.intellij.ide.projectView.ViewSettings; import com.intellij.ide.projectView.impl.ModuleGroup; -import com.intellij.ide.scratch.RootType; import com.intellij.ide.scratch.ScratchProjectViewPane; +import com.intellij.ide.scratch.ScratchUtil; import com.intellij.ide.util.treeView.AbstractTreeNode; import com.intellij.openapi.module.*; import com.intellij.openapi.progress.ProcessCanceledException; @@ -147,6 +147,6 @@ public abstract class AbstractProjectNode extends ProjectViewNode { index.isInLibraryClasses(vFile) || index.isInLibrarySource(vFile) || Comparing.equal(vFile.getParent(), myProject.getBaseDir()) || - ScratchProjectViewPane.isScratchesMergedIntoProjectTab() && RootType.forFile(vFile) != null; + ScratchProjectViewPane.isScratchesMergedIntoProjectTab() && ScratchUtil.isScratch(vFile); } } diff --git a/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/ProjectViewProjectNode.java b/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/ProjectViewProjectNode.java index 0f1e3d7db397..1878dce2b39a 100644 --- a/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/ProjectViewProjectNode.java +++ b/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/ProjectViewProjectNode.java @@ -5,7 +5,6 @@ package com.intellij.ide.projectView.impl.nodes; import com.intellij.ide.projectView.ViewSettings; import com.intellij.ide.projectView.impl.ModuleGroup; import com.intellij.ide.projectView.impl.ProjectRootsUtil; -import com.intellij.ide.scratch.ScratchProjectViewPane; import com.intellij.ide.util.treeView.AbstractTreeNode; import com.intellij.openapi.module.*; import com.intellij.openapi.module.impl.LoadedModuleDescriptionImpl; @@ -70,10 +69,6 @@ public class ProjectViewProjectNode extends AbstractProjectNode { if (getSettings().isShowLibraryContents()) { nodes.add(new ExternalLibrariesNode(getProject(), getSettings())); } - if (ScratchProjectViewPane.isScratchesMergedIntoProjectTab()) { - nodes.add(ScratchProjectViewPane.createRootNode(getProject(), getSettings())); - } - return nodes; } diff --git a/platform/lang-impl/src/com/intellij/ide/scratch/ScratchProjectViewPane.java b/platform/lang-impl/src/com/intellij/ide/scratch/ScratchProjectViewPane.java index e8749545a830..c8f018604fe3 100644 --- a/platform/lang-impl/src/com/intellij/ide/scratch/ScratchProjectViewPane.java +++ b/platform/lang-impl/src/com/intellij/ide/scratch/ScratchProjectViewPane.java @@ -5,17 +5,15 @@ import com.intellij.icons.AllIcons; import com.intellij.ide.SelectInTarget; import com.intellij.ide.impl.ProjectViewSelectInTarget; import com.intellij.ide.projectView.*; +import com.intellij.ide.projectView.impl.AbstractProjectViewPane; import com.intellij.ide.projectView.impl.ProjectAbstractTreeStructureBase; -import com.intellij.ide.projectView.impl.ProjectTreeBuilder; import com.intellij.ide.projectView.impl.ProjectTreeStructure; import com.intellij.ide.projectView.impl.ProjectViewPane; -import com.intellij.ide.projectView.impl.nodes.BasePsiNode; -import com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode; -import com.intellij.ide.projectView.impl.nodes.PsiFileNode; -import com.intellij.ide.projectView.impl.nodes.PsiFileSystemItemFilter; +import com.intellij.ide.projectView.impl.nodes.*; import com.intellij.ide.util.treeView.AbstractTreeNode; import com.intellij.ide.util.treeView.AbstractTreeUi; import com.intellij.lang.Language; +import com.intellij.openapi.Disposable; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.PathManager; import com.intellij.openapi.fileTypes.LanguageFileType; @@ -25,11 +23,14 @@ import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.registry.Registry; import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.newvfs.BulkFileListener; +import com.intellij.openapi.vfs.newvfs.events.VFileEvent; import com.intellij.psi.*; import com.intellij.psi.search.PsiElementProcessor; import com.intellij.psi.util.PsiUtilCore; import com.intellij.util.ObjectUtils; import com.intellij.util.containers.ContainerUtil; +import com.intellij.util.containers.JBIterable; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -39,6 +40,8 @@ import java.util.Collection; import java.util.Collections; import java.util.List; +import static com.intellij.openapi.vfs.VirtualFileManager.VFS_CHANGES; + /** * @author gregsh */ @@ -53,6 +56,17 @@ public class ScratchProjectViewPane extends ProjectViewPane { public ScratchProjectViewPane(Project project) { super(project); + registerUpdaters(project, this, new Runnable() { + AbstractProjectViewPane updateTarget; + @Override + public void run() { + if (updateTarget == null) { + updateTarget = !isScratchesMergedIntoProjectTab() ? ScratchProjectViewPane.this : + ProjectView.getInstance(project).getProjectViewPaneById(ProjectViewPane.ID); + } + if (updateTarget != null) updateTarget.updateFromRoot(true); + } + }); } @Override @@ -81,29 +95,25 @@ public class ScratchProjectViewPane extends ProjectViewPane { return 11; } - @NotNull @Override protected BaseProjectTreeBuilder createBuilder(DefaultTreeModel treeModel) { - ProjectTreeBuilder builder = - new ProjectTreeBuilder(myProject, myTree, treeModel, null, (ProjectAbstractTreeStructureBase)myTreeStructure) { - @Override - protected ProjectViewPsiTreeChangeListener createPsiTreeChangeListener(Project project) { - return new ProjectTreeBuilderPsiListener(project) { - @Override - protected void childrenChanged(PsiElement parent, boolean stopProcessingForThisModificationCount) { - VirtualFile virtualFile = parent instanceof PsiFileSystemItem ? ((PsiFileSystemItem)parent).getVirtualFile() : null; - if (virtualFile != null && virtualFile.isValid() && ScratchFileService.getInstance().getRootType(virtualFile) != null) { - queueUpdateFrom(parent, true); - } - } - }; + return null; + } + + private static void registerUpdaters(@NotNull Project project, @NotNull Disposable disposable, @NotNull Runnable onUpdate) { + project.getMessageBus().connect(disposable).subscribe(VFS_CHANGES, new BulkFileListener() { + @Override + public void after(@NotNull List events) { + boolean update = JBIterable.from(events).find(e -> ScratchUtil.isScratch(e.getFile())) != null; + if (update) { + onUpdate.run(); } - }; + } + }); for (RootType rootId : RootType.getAllRootIds()) { if (rootId.isHidden()) continue; - rootId.registerTreeUpdater(myProject, builder, builder::queueUpdate); + rootId.registerTreeUpdater(project, disposable, onUpdate); } - return builder; } @Override @@ -159,9 +169,24 @@ public class ScratchProjectViewPane extends ProjectViewPane { return !isScratchesMergedIntoProjectTab(); } - @NotNull - public static AbstractTreeNode createRootNode(@NotNull Project project, @NotNull ViewSettings settings) { - return new MyProjectNode(project, settings); + public static class MyStructureProvider implements TreeStructureProvider { + @NotNull + @Override + public Collection modify(@NotNull AbstractTreeNode parent, + @NotNull Collection children, + ViewSettings settings) { + Project project = parent instanceof ProjectViewProjectNode? parent.getProject() : null; + if (project != null && isScratchesMergedIntoProjectTab()) { + children.add(new MyProjectNode(project, settings)); + } + return children; + } + + @Nullable + @Override + public Object getData(@NotNull Collection selected, String dataName) { + return null; + } } private static class MyTreeStructure extends ProjectTreeStructure { @@ -172,7 +197,7 @@ public class ScratchProjectViewPane extends ProjectViewPane { @Override protected AbstractTreeNode createRoot(Project project, ViewSettings settings) { - return createRootNode(project, settings); + return new MyProjectNode(project, settings); } @Nullable diff --git a/platform/platform-resources/src/META-INF/LangExtensions.xml b/platform/platform-resources/src/META-INF/LangExtensions.xml index f39c7e8e2530..903a4a2d9446 100644 --- a/platform/platform-resources/src/META-INF/LangExtensions.xml +++ b/platform/platform-resources/src/META-INF/LangExtensions.xml @@ -376,9 +376,10 @@ - + +