From 9420a82f63dee3639b23c533ae478883a679747d Mon Sep 17 00:00:00 2001 From: Bilal Mahmoud Date: Mon, 10 Apr 2023 12:35:20 +0200 Subject: [PATCH] `intellij-plugin`: privot approach (#2353) * feat: create own PsiFile * feat: support renaming of modules * feat: remove unnecessary RenameHandler * feat: remove unused rename handler * feat: movement * fix: null exception on project switch * feat: debug * feat: radically simplify the plugin * chore: remove old stuff * Update apps/intellij-plugin/src/main/kotlin/ai/hash/rustextra/projectView/ModuleDirectoryNode.kt Co-authored-by: Tim Diekmann <21277928+TimDiekmann@users.noreply.github.com> * Update apps/intellij-plugin/src/main/resources/META-INF/plugin.xml * Update apps/intellij-plugin/build.gradle.kts * Update ModuleDirectoryNode.kt * chore: run `ktlint` --------- Co-authored-by: Tim Diekmann <21277928+TimDiekmann@users.noreply.github.com> --- .../projectView/ModuleDirectoryNode.kt | 38 ++++++++++++++ .../ModuleGroupTreeStructureProvider.kt | 4 +- .../hash/rustextra/projectView/ModuleNode.kt | 50 ------------------- .../ModuleNodeToolWindowListener.kt | 13 ----- .../ModuleNodeTreeExpansionListener.kt | 32 ------------ .../src/main/resources/META-INF/plugin.xml | 5 +- 6 files changed, 41 insertions(+), 101 deletions(-) create mode 100644 apps/intellij-plugin/src/main/kotlin/ai/hash/rustextra/projectView/ModuleDirectoryNode.kt delete mode 100644 apps/intellij-plugin/src/main/kotlin/ai/hash/rustextra/projectView/ModuleNode.kt delete mode 100644 apps/intellij-plugin/src/main/kotlin/ai/hash/rustextra/projectView/ModuleNodeToolWindowListener.kt delete mode 100644 apps/intellij-plugin/src/main/kotlin/ai/hash/rustextra/projectView/ModuleNodeTreeExpansionListener.kt diff --git a/apps/intellij-plugin/src/main/kotlin/ai/hash/rustextra/projectView/ModuleDirectoryNode.kt b/apps/intellij-plugin/src/main/kotlin/ai/hash/rustextra/projectView/ModuleDirectoryNode.kt new file mode 100644 index 00000000000..94b9071cef2 --- /dev/null +++ b/apps/intellij-plugin/src/main/kotlin/ai/hash/rustextra/projectView/ModuleDirectoryNode.kt @@ -0,0 +1,38 @@ +package ai.hash.rustextra.projectView + +import com.intellij.ide.projectView.NodeSortOrder +import com.intellij.ide.projectView.NodeSortSettings +import com.intellij.ide.projectView.ViewSettings +import com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode +import com.intellij.openapi.project.Project +import com.intellij.psi.PsiDirectory + +class ModuleDirectoryNode(project: Project?, value: PsiDirectory, viewSettings: ViewSettings?) : PsiDirectoryNode(project, value, viewSettings) { + // This is needed, as otherwise the `GroupByTypeComparator` won't fall back to the `AlphaComparator` + override fun getTypeSortWeight(sortByType: Boolean): Int = 0 + + // This value is taken from `PsiFileNode`, which assigns a static value of `20` + // we need to directly use the magic value of 20, as we're unable to invoke the method on `PsiFileNode` + // directly. + // This allows us to bypass the `AlphaComparator` and use the `FileNameComparator` for sorting. + override fun getWeight(): Int = 20 + + // this is the default `SortKey` of `RsFile`, using the same allows us to group those together + override fun getSortKey(): Int = 0 + + // taken from ProjectView, overwrites the directory sort order + @Suppress("UnstableApiUsage") + override fun getSortOrder(settings: NodeSortSettings): NodeSortOrder = + if (settings.isManualOrder) NodeSortOrder.MANUAL else NodeSortOrder.UNSPECIFIED + + // a bit of a hack, if the `SortKey` is the same the `GroupByTypeComparator` redirects to the `AlphaComparator`, + // if the weights of both files are the same, the `AlphaComparator` uses the `FileNameComparator` with the `toString` + // representation of a node. For the node to be able to be displayed above the directory we "emulate" the name of + // the file (and add `.mod` to ensure that we're always last). + // AFAIK `toString()` is not used anywhere else. + override fun toString(): String { + val name = super.toString() + + return "$name.rs.mod" + } +} diff --git a/apps/intellij-plugin/src/main/kotlin/ai/hash/rustextra/projectView/ModuleGroupTreeStructureProvider.kt b/apps/intellij-plugin/src/main/kotlin/ai/hash/rustextra/projectView/ModuleGroupTreeStructureProvider.kt index 73e848159fe..0e12ede09e9 100644 --- a/apps/intellij-plugin/src/main/kotlin/ai/hash/rustextra/projectView/ModuleGroupTreeStructureProvider.kt +++ b/apps/intellij-plugin/src/main/kotlin/ai/hash/rustextra/projectView/ModuleGroupTreeStructureProvider.kt @@ -64,8 +64,8 @@ class ModuleGroupTreeStructureProvider : TreeStructureProvider, DumbAware { // TODO: add a custom context menu val (file, directory) = modules[value.virtualFile.nameWithoutExtension]!! - nodes.add(ModuleNode.fromPsiFileNode(file, settings, directory.children)) - + nodes.add(file) + nodes.add(ModuleDirectoryNode(directory.project, directory.value, settings)) continue } diff --git a/apps/intellij-plugin/src/main/kotlin/ai/hash/rustextra/projectView/ModuleNode.kt b/apps/intellij-plugin/src/main/kotlin/ai/hash/rustextra/projectView/ModuleNode.kt deleted file mode 100644 index 4ad55138ca3..00000000000 --- a/apps/intellij-plugin/src/main/kotlin/ai/hash/rustextra/projectView/ModuleNode.kt +++ /dev/null @@ -1,50 +0,0 @@ -package ai.hash.rustextra.projectView - -import com.intellij.codeInsight.navigation.NavigationUtil -import com.intellij.ide.projectView.NodeSortOrder -import com.intellij.ide.projectView.NodeSortSettings -import com.intellij.ide.projectView.ProjectView -import com.intellij.ide.projectView.ViewSettings -import com.intellij.ide.projectView.impl.nodes.PsiFileNode -import com.intellij.ide.util.treeView.AbstractTreeNode -import com.intellij.openapi.project.Project -import com.intellij.openapi.vfs.VirtualFile -import com.intellij.psi.PsiFile -import com.intellij.ui.DoubleClickListener -import com.intellij.util.ui.tree.TreeUtil -import java.awt.event.MouseEvent -import java.awt.event.MouseListener -import javax.swing.JTree -import javax.swing.event.TreeExpansionEvent -import javax.swing.event.TreeExpansionListener -import javax.swing.event.TreeSelectionEvent -import javax.swing.event.TreeSelectionListener - -class ModuleNode( - project: Project, - value: PsiFile, - viewSettings: ViewSettings?, - private val children: Collection>, -) : - PsiFileNode(project, value, viewSettings) { - - - override fun getChildrenImpl(): Collection> = children - - override fun contains(file: VirtualFile): Boolean = children.any { child -> - val value = child.value - - if (value is PsiFile) { - value.virtualFile.equals(file) - } else { - false - } - } - - override fun expandOnDoubleClick(): Boolean = true - - companion object { - fun fromPsiFileNode(node: AbstractTreeNode, settings: ViewSettings?, children: Collection>) = - ModuleNode(node.project, node.value, settings, children) - } -} diff --git a/apps/intellij-plugin/src/main/kotlin/ai/hash/rustextra/projectView/ModuleNodeToolWindowListener.kt b/apps/intellij-plugin/src/main/kotlin/ai/hash/rustextra/projectView/ModuleNodeToolWindowListener.kt deleted file mode 100644 index 553c9c6ba3a..00000000000 --- a/apps/intellij-plugin/src/main/kotlin/ai/hash/rustextra/projectView/ModuleNodeToolWindowListener.kt +++ /dev/null @@ -1,13 +0,0 @@ -package ai.hash.rustextra.projectView - -import com.intellij.ide.projectView.ProjectView -import com.intellij.openapi.project.Project -import com.intellij.openapi.wm.ex.ToolWindowManagerListener - -class ModuleNodeToolWindowListener(project: Project) : ToolWindowManagerListener { - init { - ProjectView.getInstance(project).currentProjectViewPane.tree.addTreeExpansionListener( - ModuleNodeTreeExpansionListener() - ); - } -} diff --git a/apps/intellij-plugin/src/main/kotlin/ai/hash/rustextra/projectView/ModuleNodeTreeExpansionListener.kt b/apps/intellij-plugin/src/main/kotlin/ai/hash/rustextra/projectView/ModuleNodeTreeExpansionListener.kt deleted file mode 100644 index 066342d73e5..00000000000 --- a/apps/intellij-plugin/src/main/kotlin/ai/hash/rustextra/projectView/ModuleNodeTreeExpansionListener.kt +++ /dev/null @@ -1,32 +0,0 @@ -package ai.hash.rustextra.projectView - -import com.intellij.codeInsight.navigation.NavigationUtil -import com.intellij.openapi.application.invokeLater -import com.intellij.util.ui.tree.TreeUtil -import javax.swing.JTree -import javax.swing.event.TreeExpansionEvent -import javax.swing.event.TreeExpansionListener - -// https://intellij-support.jetbrains.com/hc/en-us/community/posts/360004324499-How-to-hook-into-click-select-event-of-the-project-view- -// TODO: we might want to add this as a setting instead -// TODO: is there a way to have a doubleClick listener? -class ModuleNodeTreeExpansionListener: TreeExpansionListener { - override fun treeExpanded(event: TreeExpansionEvent?) { - if (event != null && event.source is JTree) { - val source = event.source; - - if (source is JTree) { - val navi = TreeUtil.getNavigatable(source, event.path); - - if (navi is ModuleNode) { - invokeLater { - NavigationUtil.openFileWithPsiElement(navi.value, true, true) - } - } - } - } - } - - override fun treeCollapsed(event: TreeExpansionEvent?) { - } -} diff --git a/apps/intellij-plugin/src/main/resources/META-INF/plugin.xml b/apps/intellij-plugin/src/main/resources/META-INF/plugin.xml index 2789c09d17f..73f22fa0f21 100644 --- a/apps/intellij-plugin/src/main/resources/META-INF/plugin.xml +++ b/apps/intellij-plugin/src/main/resources/META-INF/plugin.xml @@ -25,9 +25,6 @@ - + - - -